From ef47f76593c246c818f8d1164e4801d5c6489966 Mon Sep 17 00:00:00 2001 From: yoution Date: Tue, 29 Jun 2021 21:16:46 +0800 Subject: [PATCH] Role Skills Intake Tweaks and Bugs --- src/constants/index.js | 6 +++ src/routes/CreateNewTeam/actions/index.js | 19 +++++++ .../Completeness/styles.module.scss | 12 ++++- .../components/InputContainer/index.jsx | 53 +++++++++++++++++++ .../InputContainer/styles.module.scss | 14 +++++ .../components/ItemList/index.jsx | 2 +- .../components/ItemList/styles.module.scss | 5 +- .../components/SearchAndSubmit/index.jsx | 42 +++++++++++---- .../components/SearchContainer/index.jsx | 5 +- .../components/SubmitContainer/index.jsx | 7 ++- .../components/TeamDetailsModal/index.jsx | 8 +-- .../TeamDetailsModal/styles.module.scss | 5 +- src/routes/CreateNewTeam/index.jsx | 7 ++- .../pages/InputJobDescription/index.jsx | 9 ++-- .../InputJobDescription/styles.module.scss | 6 ++- .../CreateNewTeam/pages/InputSkills/index.jsx | 1 + .../CreateNewTeam/pages/SelectRole/index.jsx | 1 + src/routes/CreateNewTeam/reducers/index.js | 11 ++++ src/routes/CreateNewTeam/styles.module.scss | 3 ++ src/services/skills.js | 5 ++ 20 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 src/routes/CreateNewTeam/components/InputContainer/index.jsx create mode 100644 src/routes/CreateNewTeam/components/InputContainer/styles.module.scss create mode 100644 src/routes/CreateNewTeam/styles.module.scss diff --git a/src/constants/index.js b/src/constants/index.js index 46a60d98..f1c5b67c 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -258,6 +258,12 @@ export const ACTION_TYPE = { ADD_SEARCHED_ROLE: "ADD_SEARCHED_ROLE", ADD_ROLE_SEARCH_ID: "ADD_ROLE_SEARCH_ID", DELETE_SEARCHED_ROLE: "DELETE_SEARCHED_ROLE", + + /* + * matching role + */ + ADD_MATCHING_ROLE: "ADD_MATCHING_ROLE", + DELETE_MATCHING_ROLE: "DELETE_MATCHING_ROLE", }; /** diff --git a/src/routes/CreateNewTeam/actions/index.js b/src/routes/CreateNewTeam/actions/index.js index a67e6569..b90aae4e 100644 --- a/src/routes/CreateNewTeam/actions/index.js +++ b/src/routes/CreateNewTeam/actions/index.js @@ -27,6 +27,15 @@ const deleteRole = (id) => ({ payload: id, }); +const addMatchingRole = (matchingRole) => ({ + type: ACTION_TYPE.ADD_MATCHING_ROLE, + payload: matchingRole, +}); + +const deleteMatchingRole = (matchingRole) => ({ + type: ACTION_TYPE.DELETE_MATCHING_ROLE, +}); + export const clearSearchedRoles = () => (dispatch, getState) => { dispatch(clearRoles()); updateLocalStorage(getState().searchedRoles); @@ -46,3 +55,13 @@ export const deleteSearchedRole = (id) => (dispatch, getState) => { dispatch(deleteRole(id)); updateLocalStorage(getState().searchedRoles); }; + +export const saveMatchingRole = (matchingRole) => (dispatch, getState) => { + dispatch(addMatchingRole(matchingRole)); + updateLocalStorage(getState().searchedRoles); +}; + +export const clearMatchingRole = (matchingRole) => (dispatch, getState) => { + dispatch(deleteMatchingRole()); + updateLocalStorage(getState().searchedRoles); +}; diff --git a/src/routes/CreateNewTeam/components/Completeness/styles.module.scss b/src/routes/CreateNewTeam/components/Completeness/styles.module.scss index 6e12427f..3438d020 100644 --- a/src/routes/CreateNewTeam/components/Completeness/styles.module.scss +++ b/src/routes/CreateNewTeam/components/Completeness/styles.module.scss @@ -2,6 +2,7 @@ .completeness { @include rounded-card; + overflow: hidden; padding: 12px; position: relative; width: 250px; @@ -25,12 +26,19 @@ .list { margin-bottom: 55px; + & + button[disabled] { + background-color: #E9E9E9; + color: #FFF; + opacity: 1; + filter: none; + } } .list-item { margin-bottom: 14px; font-size: 14px; line-height: 16px; + font-weight: 400; &:before { content: ""; @@ -45,14 +53,14 @@ } &.active { - font-weight: 700; + font-weight: 500; &:before { background-color: #fff; } } &.done { - font-weight: 700; + font-weight: 400; color: rgba(255, 255, 255, 0.6); &:before { content: "✓"; diff --git a/src/routes/CreateNewTeam/components/InputContainer/index.jsx b/src/routes/CreateNewTeam/components/InputContainer/index.jsx new file mode 100644 index 00000000..af03d23c --- /dev/null +++ b/src/routes/CreateNewTeam/components/InputContainer/index.jsx @@ -0,0 +1,53 @@ +/** + * InputContainer + * + * A container component for the different + * input pages. Contains logic and supporting + * components for selecting for roles. + */ +import React, { useCallback } from "react"; +import PT from "prop-types"; +import AddedRolesAccordion from "../AddedRolesAccordion"; +import Completeness from "../Completeness"; +import SearchCard from "../SearchCard"; +import ResultCard from "../ResultCard"; +import NoMatchingProfilesResultCard from "../NoMatchingProfilesResultCard"; +import { isCustomRole } from "utils/helpers"; +import "./styles.module.scss"; + +function InputContainer({ + stages, + isCompletenessDisabled, + toRender, + search, + completenessStyle, + addedRoles, +}) { + return ( +
+ {toRender(search)} +
+ + +
+
+ ); +} + +InputContainer.propTypes = { + stages: PT.array, + isCompletenessDisabled: PT.bool, + search: PT.func, + toRender: PT.func, + completenessStyle: PT.string, + addedRoles: PT.array, +}; + +export default InputContainer; diff --git a/src/routes/CreateNewTeam/components/InputContainer/styles.module.scss b/src/routes/CreateNewTeam/components/InputContainer/styles.module.scss new file mode 100644 index 00000000..99cec905 --- /dev/null +++ b/src/routes/CreateNewTeam/components/InputContainer/styles.module.scss @@ -0,0 +1,14 @@ +.page { + display: flex; + flex-direction: row; + justify-content: center; + align-items: flex-start; + margin: 42px 35px; + .right-side { + display: flex; + flex-direction: column; + & > div:not(:first-child) { + margin-top: 16px; + } + } +} \ No newline at end of file diff --git a/src/routes/CreateNewTeam/components/ItemList/index.jsx b/src/routes/CreateNewTeam/components/ItemList/index.jsx index 56b6496a..1305eae6 100644 --- a/src/routes/CreateNewTeam/components/ItemList/index.jsx +++ b/src/routes/CreateNewTeam/components/ItemList/index.jsx @@ -36,7 +36,7 @@ function ItemList({ return (
{title}
} backTo="/taas/createnewteam" aside={ <> diff --git a/src/routes/CreateNewTeam/components/ItemList/styles.module.scss b/src/routes/CreateNewTeam/components/ItemList/styles.module.scss index 6e41531e..cf201197 100644 --- a/src/routes/CreateNewTeam/components/ItemList/styles.module.scss +++ b/src/routes/CreateNewTeam/components/ItemList/styles.module.scss @@ -9,6 +9,9 @@ height: 80vh; overflow-y: auto; + .title { + font-weight: 500; + } > header { padding: 16px 24px; } @@ -67,4 +70,4 @@ input:not([type="checkbox"]).filter-input { justify-content: flex-start; flex-wrap: wrap; margin-right: 24px; -} \ No newline at end of file +} diff --git a/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx b/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx index 778fd984..339d725a 100644 --- a/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx +++ b/src/routes/CreateNewTeam/components/SearchAndSubmit/index.jsx @@ -1,29 +1,44 @@ -import { Router } from "@reach/router"; +import { Router, navigate } from "@reach/router"; import _ from "lodash"; -import React, { useCallback, useState } from "react"; +import React, { useCallback, useState, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { searchRoles } from "services/teams"; import { isCustomRole, setCurrentStage } from "utils/helpers"; -import { addRoleSearchId, addSearchedRole } from "../../actions"; +import { clearMatchingRole, saveMatchingRole, addRoleSearchId, addSearchedRole } from "../../actions"; +import InputContainer from "../InputContainer"; import SearchContainer from "../SearchContainer"; import SubmitContainer from "../SubmitContainer"; function SearchAndSubmit(props) { - const { stages, setStages, searchObject, onClick } = props; + const { stages, setStages, searchObject, onClick, page } = props; const [searchState, setSearchState] = useState(null); - const [matchingRole, setMatchingRole] = useState(null); - const { addedRoles, previousSearchId } = useSelector( + const { matchingRole } = useSelector( (state) => state.searchedRoles ); + useEffect(()=> { + const isFromInputPage = searchObject.role || searchObject.skills && searchObject.skills.length + || searchObject.jobDescription + // refresh in search page directly + if (matchingRole && !isFromInputPage) { + setCurrentStage(2, stages, setStages); + setSearchState("done"); + } + }, []) + const dispatch = useDispatch(); + const { addedRoles, previousSearchId } = useSelector( + (state) => state.searchedRoles + ); + const search = useCallback(() => { + navigate(`${page}/search`); setCurrentStage(1, stages, setStages); setSearchState("searching"); - setMatchingRole(null); + dispatch(clearMatchingRole()); const searchObjectCopy = { ...searchObject }; if (previousSearchId) { searchObjectCopy.previousRoleSearchRequestId = previousSearchId; @@ -37,7 +52,9 @@ function SearchAndSubmit(props) { } else if (searchId) { dispatch(addRoleSearchId(searchId)); } - setMatchingRole(res.data); + // setMatchingRole(res.data); + + dispatch(saveMatchingRole(res.data)); }) .catch((err) => { console.error(err); @@ -51,11 +68,18 @@ function SearchAndSubmit(props) { return ( - + { - navigate("result"); + navigate("../result"); }, [navigate]); const renderLeftSide = () => { - if (!searchState) return toRender(search); if (searchState === "searching") return ; if (!isCustomRole(matchingRole)) return ; return ; }; const getPercentage = useCallback(() => { - if (!searchState) return "26"; if (searchState === "searching") return "52"; if (matchingRole) return "98"; return "88"; @@ -52,7 +50,6 @@ function SearchContainer({ { - dispatch(clearSearchedRoles()); - navigate("/taas/myteams"); + setTimeout(() => { + dispatch(clearSearchedRoles()); + // Backend api create project has sync issue, so delay 2 seconds + navigate("/taas/myteams"); + }, 2000) }) .catch((err) => { setRequestLoading(false); diff --git a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx index 11802f60..16215341 100644 --- a/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx +++ b/src/routes/CreateNewTeam/components/TeamDetailsModal/index.jsx @@ -100,6 +100,8 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { return errors; }; + const validateRequired = value => (value ? undefined : 'Please enter a positive integer') + return (
undefined); }, }} - initialValues={{ teamName: "My Great Team" }} + initialValues={{ teamName: "" }} validate={validator} > {({ @@ -181,7 +183,7 @@ function TeamDetailsModal({ open, onClose, submitForm, addedRoles }) { {name} - + {({ input, meta }) => ( - + {({ input, meta }) => ( { + dispatch(clearMatchingRole()); navigate(path); }; return ( - + Create New Team} />

Please select how you want to find members that match your requirements.

diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx index 2ba16303..10e1809b 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/index.jsx @@ -56,14 +56,15 @@ function InputJobDescription() { 255} + isCompletenessDisabled={jdString.length < 10 || jdString.length > 2000} completenessStyle="input-job-description" searchObject={searchObject} + page="jd" onClick={onClick} toRender={(searchFunc) => (
Input Job Description
} backTo="/taas/createnewteam" />
@@ -80,8 +81,8 @@ function InputJobDescription() { placeholder="input job description" onChange={onEditChange} errorMessage={ - jdString.length > 255 - ? "Maximum of 255 characters. Please reduce job description length." + jdString.length > 2000 + ? "Maximum of 2000 characters. Please reduce job description length." : "" } /> diff --git a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss index 892befbe..6b3f1a38 100644 --- a/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss +++ b/src/routes/CreateNewTeam/pages/InputJobDescription/styles.module.scss @@ -8,6 +8,10 @@ flex: 1; } +.title { + font-weight: 500; +} + .job-title { margin-bottom: 15px; @@ -15,4 +19,4 @@ line-height: normal; padding: 8px 15px; } -} \ No newline at end of file +} diff --git a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx index ac0a7b2b..5e520cb2 100644 --- a/src/routes/CreateNewTeam/pages/InputSkills/index.jsx +++ b/src/routes/CreateNewTeam/pages/InputSkills/index.jsx @@ -50,6 +50,7 @@ function InputSkills() { setStages={setStages} isCompletenessDisabled={selectedSkills.length < 1} searchObject={{ skills: selectedSkills }} + page="skills" completenessStyle="input-skills" toRender={() => ( ( diff --git a/src/routes/CreateNewTeam/reducers/index.js b/src/routes/CreateNewTeam/reducers/index.js index d90316bf..2180d81d 100644 --- a/src/routes/CreateNewTeam/reducers/index.js +++ b/src/routes/CreateNewTeam/reducers/index.js @@ -7,6 +7,7 @@ const loadState = () => { const defaultState = { previousSearchId: undefined, addedRoles: [], + matchingRole: undefined, }; try { const state = localStorage.getItem("rolesState"); @@ -38,6 +39,16 @@ const reducer = (state = initialState, action) => { addedRoles: [], }; + case ACTION_TYPE.ADD_MATCHING_ROLE: + return { + ...state, + matchingRole: action.payload, + }; + case ACTION_TYPE.DELETE_MATCHING_ROLE: + return { + ...state, + matchingRole: null, + }; case ACTION_TYPE.ADD_SEARCHED_ROLE: return { ...state, diff --git a/src/routes/CreateNewTeam/styles.module.scss b/src/routes/CreateNewTeam/styles.module.scss new file mode 100644 index 00000000..379eb6ff --- /dev/null +++ b/src/routes/CreateNewTeam/styles.module.scss @@ -0,0 +1,3 @@ +.title { + font-weight: 500; +} diff --git a/src/services/skills.js b/src/services/skills.js index 36a91af8..6d733350 100644 --- a/src/services/skills.js +++ b/src/services/skills.js @@ -37,6 +37,11 @@ function getAllSkills() { page++; loop(page); } else { + skills.sort((a, b) => { + if (a.name.toLowerCase() < b.name.toLowerCase()) return -1; + if (a.name.toLowerCase() > b.name.toLowerCase()) return 1; + return 0; + }); resolve({ data: skills, });