diff --git a/README.md b/README.md
index 6a9716bc..47540cab 100644
--- a/README.md
+++ b/README.md
@@ -39,8 +39,6 @@ npm install
1. copy the environment file in docs/dev.env to /.env
-1. add `127.0.0.1 local.topcoder-dev.com` to your /etc/hosts file
-
1. If you are using local instances of the API's, change the DEV_API_HOSTNAME in configs/constants/development.js to match your local api endpoint.
- For example change it to 'http://localhost:3000/',
@@ -50,7 +48,7 @@ npm install
npm run dev
```
-You can access the app from [http://local.topcoder-dev.com:3001/](http://local.topcoder-dev.com:3001/)
+You can access the app from [http://localhost:3000/](http://localhost:3000/)
The page will reload if you make edits.
diff --git a/config/constants/development.js b/config/constants/development.js
index 7043e5b0..2a79c4c3 100644
--- a/config/constants/development.js
+++ b/config/constants/development.js
@@ -7,7 +7,6 @@ module.exports = {
COMMUNITY_APP_URL: `https://www.${DOMAIN}`,
MEMBER_API_URL: `${DEV_API_HOSTNAME}/v4/members`,
MEMBER_API_V3_URL: `${DEV_API_HOSTNAME}/v3/members`,
- DEV_APP_URL: `http://local.${DOMAIN}`,
CHALLENGE_API_URL: `${DEV_API_HOSTNAME}/v5/challenges`,
CHALLENGE_TIMELINE_TEMPLATES_URL: `${DEV_API_HOSTNAME}/v5/timeline-templates`,
CHALLENGE_TYPES_URL: `${DEV_API_HOSTNAME}/v5/challenge-types`,
diff --git a/config/constants/production.js b/config/constants/production.js
index e690824d..b5bd162e 100644
--- a/config/constants/production.js
+++ b/config/constants/production.js
@@ -7,7 +7,6 @@ module.exports = {
COMMUNITY_APP_URL: `https://www.${DOMAIN}`,
MEMBER_API_URL: `${PROD_API_HOSTNAME}/v4/members`,
MEMBER_API_V3_URL: `${PROD_API_HOSTNAME}/v3/members`,
- DEV_APP_URL: `https://submission-review.${DOMAIN}`,
CHALLENGE_API_URL: `${PROD_API_HOSTNAME}/v5/challenges`,
CHALLENGE_TIMELINE_TEMPLATES_URL: `${PROD_API_HOSTNAME}/v5/timeline-templates`,
CHALLENGE_TYPES_URL: `${PROD_API_HOSTNAME}/v5/challenge-types`,
diff --git a/package-lock.json b/package-lock.json
index b0c37594..57be0c21 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1018,6 +1018,87 @@
"resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
"integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw=="
},
+ "@emotion/cache": {
+ "version": "10.0.29",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
+ "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
+ "requires": {
+ "@emotion/sheet": "0.9.4",
+ "@emotion/stylis": "0.8.5",
+ "@emotion/utils": "0.11.3",
+ "@emotion/weak-memoize": "0.2.5"
+ }
+ },
+ "@emotion/core": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz",
+ "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "@emotion/cache": "^10.0.27",
+ "@emotion/css": "^10.0.27",
+ "@emotion/serialize": "^0.11.15",
+ "@emotion/sheet": "0.9.4",
+ "@emotion/utils": "0.11.3"
+ }
+ },
+ "@emotion/css": {
+ "version": "10.0.27",
+ "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
+ "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
+ "requires": {
+ "@emotion/serialize": "^0.11.15",
+ "@emotion/utils": "0.11.3",
+ "babel-plugin-emotion": "^10.0.27"
+ }
+ },
+ "@emotion/hash": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
+ },
+ "@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
+ },
+ "@emotion/serialize": {
+ "version": "0.11.16",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
+ "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
+ "requires": {
+ "@emotion/hash": "0.8.0",
+ "@emotion/memoize": "0.7.4",
+ "@emotion/unitless": "0.7.5",
+ "@emotion/utils": "0.11.3",
+ "csstype": "^2.5.7"
+ }
+ },
+ "@emotion/sheet": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
+ "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
+ },
+ "@emotion/stylis": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
+ },
+ "@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+ },
+ "@emotion/utils": {
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
+ "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
+ },
+ "@emotion/weak-memoize": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
+ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
+ },
"@fortawesome/fontawesome-common-types": {
"version": "0.2.28",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz",
@@ -2157,6 +2238,23 @@
"object.assign": "^4.1.0"
}
},
+ "babel-plugin-emotion": {
+ "version": "10.0.33",
+ "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz",
+ "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@emotion/hash": "0.8.0",
+ "@emotion/memoize": "0.7.4",
+ "@emotion/serialize": "^0.11.16",
+ "babel-plugin-macros": "^2.0.0",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^1.0.5",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7"
+ }
+ },
"babel-plugin-istanbul": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
@@ -2187,6 +2285,11 @@
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz",
"integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA=="
},
+ "babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
+ },
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@@ -4165,6 +4268,11 @@
}
}
},
+ "csstype": {
+ "version": "2.6.14",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
+ "integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A=="
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -4542,6 +4650,22 @@
"utila": "~0.4"
}
},
+ "dom-helpers": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz",
+ "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ },
+ "dependencies": {
+ "csstype": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz",
+ "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw=="
+ }
+ }
+ },
"dom-serializer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -5923,8 +6047,7 @@
"find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
- "dev": true
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
},
"find-up": {
"version": "2.1.0",
@@ -9342,6 +9465,11 @@
}
}
},
+ "memoize-one": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
+ "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
+ },
"memory-fs": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@@ -14723,13 +14851,18 @@
}
},
"react-select": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/react-select/-/react-select-1.3.0.tgz",
- "integrity": "sha512-g/QAU1HZrzSfxkwMAo/wzi6/ezdWye302RGZevsATec07hI/iSxcpB1hejFIp7V63DJ8mwuign6KmB3VjdlinQ==",
- "requires": {
- "classnames": "^2.2.4",
- "prop-types": "^15.5.8",
- "react-input-autosize": "^2.1.2"
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.1.tgz",
+ "integrity": "sha512-HjC6jT2BhUxbIbxMZWqVcDibrEpdUJCfGicN0MMV+BQyKtCaPTgFekKWiOizSCy4jdsLMGjLqcFGJMhVGWB0Dg==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@emotion/cache": "^10.0.9",
+ "@emotion/core": "^10.0.9",
+ "@emotion/css": "^10.0.9",
+ "memoize-one": "^5.0.0",
+ "prop-types": "^15.6.0",
+ "react-input-autosize": "^2.2.2",
+ "react-transition-group": "^4.3.0"
}
},
"react-side-effect": {
@@ -14768,6 +14901,17 @@
"prop-types": "^15.5.0"
}
},
+ "react-transition-group": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -17127,8 +17271,8 @@
}
},
"tc-auth-lib": {
- "version": "github:topcoder-platform/tc-auth-lib#fbd62f7c65f0e7eecccf2c131b07e84104505754",
- "from": "github:topcoder-platform/tc-auth-lib#1.0.1",
+ "version": "github:topcoder-platform/tc-auth-lib#68fdc22464810c51b703a33e529cdbd6d09437de",
+ "from": "github:topcoder-platform/tc-auth-lib#1.0.4",
"requires": {
"lodash": "^4.17.19"
},
diff --git a/package.json b/package.json
index 1f0c041e..a4b659bd 100644
--- a/package.json
+++ b/package.json
@@ -79,7 +79,7 @@
"react-redux": "^6.0.0",
"react-redux-toastr": "^7.5.1",
"react-router-dom": "^4.3.1",
- "react-select": "^1.2.0",
+ "react-select": "^3.1.1",
"react-stickynode": "^2.1.1",
"react-svg": "^4.1.1",
"react-tabs": "^3.0.0",
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 00000000..74a52100
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/scripts/start.js b/scripts/start.js
index b7aaf362..71d668f7 100644
--- a/scripts/start.js
+++ b/scripts/start.js
@@ -99,7 +99,7 @@ checkBrowsers(paths.appPath, isInteractive)
clearConsole()
}
console.log(chalk.cyan('Starting the development server...\n'))
- openBrowser(constants.DEV_APP_URL ? `${constants.DEV_APP_URL}:${process.env.PORT || 3000}` : urls.localUrlForBrowser)
+ openBrowser(urls.localUrlForBrowser)
})
const SIGNALS = ['SIGINT', 'SIGTERM']
diff --git a/src/actions/challenges.js b/src/actions/challenges.js
index eca362f6..d9aafda0 100644
--- a/src/actions/challenges.js
+++ b/src/actions/challenges.js
@@ -13,8 +13,10 @@ import {
fetchResourceRoles,
fetchChallengeTimelines,
fetchChallengeTracks,
+ fetchGroupDetail,
updateChallenge,
patchChallenge,
+ deleteChallenge as deleteChallengeAPI,
createChallenge as createChallengeAPI,
createResource as createResourceAPI,
deleteResource as deleteResourceAPI
@@ -38,6 +40,9 @@ import {
CREATE_CHALLENGE_PENDING,
CREATE_CHALLENGE_SUCCESS,
CREATE_CHALLENGE_FAILURE,
+ DELETE_CHALLENGE_PENDING,
+ DELETE_CHALLENGE_SUCCESS,
+ DELETE_CHALLENGE_FAILURE,
LOAD_CHALLENGE_RESOURCES
} from '../config/constants'
import { loadProject } from './projects'
@@ -182,6 +187,14 @@ export function loadChallengeDetails (projectId, challengeId) {
}
}
+/**
+ * Loads group details
+ */
+export function loadGroupDetails (groupIds) {
+ const promiseAll = groupIds.map(id => fetchGroupDetail(id))
+ return Promise.all(promiseAll)
+}
+
/**
* Update challenge details
*
@@ -267,6 +280,26 @@ export function partiallyUpdateChallengeDetails (challengeId, partialChallengeDe
}
}
+export function deleteChallenge (challengeId) {
+ return async (dispatch) => {
+ dispatch({
+ type: DELETE_CHALLENGE_PENDING
+ })
+
+ return deleteChallengeAPI(challengeId).then((challenge) => {
+ return dispatch({
+ type: DELETE_CHALLENGE_SUCCESS,
+ challengeDetails: challenge
+ })
+ }).catch((error) => {
+ dispatch({
+ type: DELETE_CHALLENGE_FAILURE
+ })
+ throw error
+ })
+ }
+}
+
export function loadTimelineTemplates () {
return async (dispatch) => {
const timelineTemplates = await fetchTimelineTemplates()
diff --git a/src/components/ChallengeEditor/AssignedMember-Field/AssignedMember-Field.module.scss b/src/components/ChallengeEditor/AssignedMember-Field/AssignedMember-Field.module.scss
index 4f22fc27..33eea080 100644
--- a/src/components/ChallengeEditor/AssignedMember-Field/AssignedMember-Field.module.scss
+++ b/src/components/ChallengeEditor/AssignedMember-Field/AssignedMember-Field.module.scss
@@ -45,5 +45,10 @@
.readOnlyValue {
margin-bottom: 0.5rem; // the same like `label` to be aligned
}
+
+ .assignSelfField {
+ margin-left: 20px;
+ padding-top: 6px;
+ }
}
diff --git a/src/components/ChallengeEditor/AssignedMember-Field/index.js b/src/components/ChallengeEditor/AssignedMember-Field/index.js
index 4731518d..cf52873f 100644
--- a/src/components/ChallengeEditor/AssignedMember-Field/index.js
+++ b/src/components/ChallengeEditor/AssignedMember-Field/index.js
@@ -7,12 +7,13 @@ import cn from 'classnames'
import styles from './AssignedMember-Field.module.scss'
import SelectUserAutocomplete from '../../SelectUserAutocomplete'
-const AssignedMemberField = ({ challenge, onChange, assignedMemberDetails, readOnly }) => {
+const AssignedMemberField = ({ challenge, onAssignSelf, onChange, assignedMemberDetails, readOnly }) => {
const value = assignedMemberDetails ? {
// if we know assigned member details, then show user `handle`, otherwise fallback to `userId`
label: assignedMemberDetails.handle,
value: assignedMemberDetails.userId + ''
} : null
+
return (
@@ -28,6 +29,15 @@ const AssignedMemberField = ({ challenge, onChange, assignedMemberDetails, readO
/>
)}
+ {
+ !readOnly &&
+
+ }
)
}
@@ -41,7 +51,8 @@ AssignedMemberField.propTypes = {
challenge: PropTypes.shape().isRequired,
onChange: PropTypes.func,
assignedMemberDetails: PropTypes.shape(),
- readOnly: PropTypes.bool
+ readOnly: PropTypes.bool,
+ onAssignSelf: PropTypes.func
}
export default AssignedMemberField
diff --git a/src/components/ChallengeEditor/BillingAccount-Field/index.js b/src/components/ChallengeEditor/BillingAccount-Field/index.js
index 6b376899..80576bad 100644
--- a/src/components/ChallengeEditor/BillingAccount-Field/index.js
+++ b/src/components/ChallengeEditor/BillingAccount-Field/index.js
@@ -13,14 +13,12 @@ const BillingAccountField = ({ accounts, onUpdateSelect, challenge }) => {
diff --git a/src/components/ChallengeEditor/ChallengeEditor.module.scss b/src/components/ChallengeEditor/ChallengeEditor.module.scss
index 4d7f5b24..cac38dd5 100644
--- a/src/components/ChallengeEditor/ChallengeEditor.module.scss
+++ b/src/components/ChallengeEditor/ChallengeEditor.module.scss
@@ -241,7 +241,7 @@
.actionButtons {
position: absolute;
top: 30px;
- a {
+ a,button {
height: 40px;
}
}
@@ -251,7 +251,13 @@
}
.actionButtonsRight {
+ display: flex;
+ align-items: center;
right: 20px;
+
+ button {
+ margin-right: 20px;
+ }
}
.buttonContainer {
diff --git a/src/components/ChallengeEditor/ChallengeSchedule-Field/index.js b/src/components/ChallengeEditor/ChallengeSchedule-Field/index.js
index d0a4e5c8..8fca8678 100644
--- a/src/components/ChallengeEditor/ChallengeSchedule-Field/index.js
+++ b/src/components/ChallengeEditor/ChallengeSchedule-Field/index.js
@@ -331,12 +331,10 @@ class ChallengeScheduleField extends Component {
) : (