diff --git a/src/constants/index.js b/src/constants/index.js index e65c089b..1a35867b 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -86,34 +86,40 @@ export const CANDIDATE_STATUS = { SELECTED: "selected", SHORTLIST: "shortlist", REJECTED: "rejected", + INTERVIEW: "interview", }; /** - * Mapping between candidate status "server value" and human readable value + * Candidate status filters keys */ -export const CANDIDATE_STATUS_TO_TEXT = { - [CANDIDATE_STATUS.OPEN]: "To Review", - [CANDIDATE_STATUS.SELECTED]: "Selected", - [CANDIDATE_STATUS.SHORTLIST]: "Interested", - [CANDIDATE_STATUS.REJECTED]: "Not Interested", +export const CANDIDATE_STATUS_FILTER_KEY = { + TO_REVIEW: "TO_REVIEW", + INTERESTED: "INTERESTED", + NOT_INTERESTED: "NOT_INTERESTED", }; /** - * Mapping between candidate status "server value" and list title text - */ -export const CANDIDATE_STATUS_TO_TITLE_TEXT = { - [CANDIDATE_STATUS.OPEN]: "Candidates to Review", - [CANDIDATE_STATUS.SHORTLIST]: "Interested Candidates", - [CANDIDATE_STATUS.REJECTED]: "Not Interested Candidates", -}; - -/** - * Which candidate status filters to show on the open position details page + * Candidate status filters */ export const CANDIDATE_STATUS_FILTERS = [ - CANDIDATE_STATUS.OPEN, - CANDIDATE_STATUS.SHORTLIST, - CANDIDATE_STATUS.REJECTED, + { + key: CANDIDATE_STATUS_FILTER_KEY.TO_REVIEW, + buttonText: "To Review", + title: "Candidates to Review", + statuses: [CANDIDATE_STATUS.OPEN], + }, + { + key: CANDIDATE_STATUS_FILTER_KEY.INTERESTED, + buttonText: "Interested", + title: "Interested Candidates", + statuses: [CANDIDATE_STATUS.SHORTLIST, CANDIDATE_STATUS.INTERVIEW], + }, + { + key: CANDIDATE_STATUS_FILTER_KEY.NOT_INTERESTED, + buttonText: "Not Interested", + title: "Not Interested Candidates", + statuses: [CANDIDATE_STATUS.REJECTED], + }, ]; /** diff --git a/src/routes/PositionDetails/components/CandidatesStatusFilter/index.jsx b/src/routes/PositionDetails/components/CandidatesStatusFilter/index.jsx index 6b9f0a70..70605c86 100644 --- a/src/routes/PositionDetails/components/CandidatesStatusFilter/index.jsx +++ b/src/routes/PositionDetails/components/CandidatesStatusFilter/index.jsx @@ -9,20 +9,20 @@ import Button from "components/Button"; import { CANDIDATE_STATUS, CANDIDATE_STATUS_FILTERS, - CANDIDATE_STATUS_TO_TEXT, + CANDIDATE_STATUS_FILTER_KEY, } from "constants"; -const CandidatesStatusFilter = ({ currentStatus, onChange, candidates }) => { +const CandidatesStatusFilter = ({ statusFilterKey, onChange, candidates }) => { return (
- {CANDIDATE_STATUS_FILTERS.map((status) => ( + {CANDIDATE_STATUS_FILTERS.map((statusFilter) => ( ))}
@@ -30,7 +30,7 @@ const CandidatesStatusFilter = ({ currentStatus, onChange, candidates }) => { }; CandidatesStatusFilter.propTypes = { - currentStatus: PT.oneOf(Object.values(CANDIDATE_STATUS)), + statusFilterKey: PT.oneOf(Object.values(CANDIDATE_STATUS_FILTER_KEY)), onChange: PT.func, candidates: PT.arrayOf( PT.shape({ diff --git a/src/routes/PositionDetails/components/PositionCandidates/index.jsx b/src/routes/PositionDetails/components/PositionCandidates/index.jsx index 6b893b39..975f36c7 100644 --- a/src/routes/PositionDetails/components/PositionCandidates/index.jsx +++ b/src/routes/PositionDetails/components/PositionCandidates/index.jsx @@ -10,7 +10,8 @@ import CardHeader from "components/CardHeader"; import "./styles.module.scss"; import Select from "components/Select"; import { - CANDIDATE_STATUS_TO_TITLE_TEXT, + CANDIDATE_STATUS_FILTERS, + CANDIDATE_STATUS_FILTER_KEY, CANDIDATES_SORT_OPTIONS, CANDIDATES_SORT_BY, CANDIDATE_STATUS, @@ -54,19 +55,20 @@ const populateSkillsMatched = (position, candidate) => ({ skillsMatched: _.intersectionBy(position.skills, candidate.skills, "id"), }); -const PositionCandidates = ({ position, candidateStatus, updateCandidate }) => { +const PositionCandidates = ({ position, statusFilterKey, updateCandidate }) => { const { candidates } = position; const [sortBy, setSortBy] = useState(CANDIDATES_SORT_BY.SKILL_MATCHED); + const statusFilter = useMemo(() => + _.find(CANDIDATE_STATUS_FILTERS, { key: statusFilterKey }) + , [statusFilterKey]); const filteredCandidates = useMemo( () => _.chain(candidates) .map((candidate) => populateSkillsMatched(position, candidate)) - .filter({ - status: candidateStatus, - }) + .filter((candidate) => statusFilter.statuses.includes(candidate.status)) .value() .sort(createSortCandidatesMethod(sortBy)), - [candidates, candidateStatus, sortBy, position] + [candidates, statusFilter, sortBy, position] ); const onSortByChange = useCallback( @@ -139,7 +141,7 @@ const PositionCandidates = ({ position, candidateStatus, updateCandidate }) => { return (
{ {filteredCandidates.length === 0 && (
- No {CANDIDATE_STATUS_TO_TITLE_TEXT[candidateStatus]} + No {statusFilter.title}
)} {filteredCandidates.length > 0 && ( @@ -186,7 +188,7 @@ const PositionCandidates = ({ position, candidateStatus, updateCandidate }) => { )}
- {candidateStatus === CANDIDATE_STATUS.OPEN && ( + {statusFilterKey === CANDIDATE_STATUS_FILTER_KEY.TO_REVIEW && ( <> Interested in this candidate?
@@ -239,7 +241,7 @@ const PositionCandidates = ({ position, candidateStatus, updateCandidate }) => { PositionCandidates.propType = { position: PT.object, - candidateStatus: PT.oneOf(Object.values(CANDIDATE_STATUS)), + statusFilterKey: PT.oneOf(Object.values(CANDIDATE_STATUS_FILTER_KEY)), }; export default PositionCandidates; diff --git a/src/routes/PositionDetails/index.jsx b/src/routes/PositionDetails/index.jsx index cb9d3ae6..6e8a2ee5 100644 --- a/src/routes/PositionDetails/index.jsx +++ b/src/routes/PositionDetails/index.jsx @@ -8,7 +8,7 @@ import PT from "prop-types"; import LayoutContainer from "components/LayoutContainer"; import LoadingIndicator from "components/LoadingIndicator"; import PageHeader from "components/PageHeader"; -import { CANDIDATE_STATUS } from "constants"; +import { CANDIDATE_STATUS_FILTER_KEY } from "constants"; import withAuthentication from "../../hoc/withAuthentication"; import PositionCandidates from "./components/PositionCandidates"; import CandidatesStatusFilter from "./components/CandidatesStatusFilter"; @@ -16,17 +16,17 @@ import { useTeamPositionsState } from "./hooks/useTeamPositionsState"; import "./styles.module.scss"; const PositionDetails = ({ teamId, positionId }) => { - const [candidateStatus, setCandidateStatus] = useState(CANDIDATE_STATUS.OPEN); + const [candidateStatusFilterKey, setCandidateStatusFilterKey] = useState(CANDIDATE_STATUS_FILTER_KEY.TO_REVIEW); const { state: { position, error }, updateCandidate, } = useTeamPositionsState(teamId, positionId); const onCandidateStatusChange = useCallback( - (status) => { - setCandidateStatus(status); + (statusFilter) => { + setCandidateStatusFilterKey(statusFilter.key); }, - [setCandidateStatus] + [setCandidateStatusFilterKey] ); return ( @@ -41,14 +41,14 @@ const PositionDetails = ({ teamId, positionId }) => { aside={ } />