| @@ -496,6 +496,21 @@ h3 { | |||
| flex-grow: 0; | |||
| z-index: 6; | |||
| } | |||
| .change-interbtn{ | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| padding-left: 35px; | |||
| } | |||
| .interbtn{ | |||
| height: 27.5px; | |||
| background-color: $mainBlue !important; | |||
| color: white !important; | |||
| font-size: 12px !important; | |||
| border-radius: 7.5px !important; | |||
| font-weight: 500 !important; | |||
| text-transform: capitalize !important; | |||
| } | |||
| .active-process-card-buttons { | |||
| overflow: hidden; | |||
| @@ -106,7 +106,7 @@ const ConfirmDialog = ({ | |||
| className={`c-btn--primary-outlined c-btn dialog-btn`} | |||
| onClick={onClose} | |||
| > | |||
| Cancel | |||
| Otkaži | |||
| </IconButton> | |||
| ) : ( | |||
| "" | |||
| @@ -116,7 +116,7 @@ const ConfirmDialog = ({ | |||
| className={`c-btn--primary-outlined sm-full c-btn dialog-btn`} | |||
| onClick={onConfirm} | |||
| > | |||
| Confirm | |||
| Potvrdi | |||
| </IconButton> | |||
| </DialogActions> | |||
| </div> | |||
| @@ -41,7 +41,6 @@ const InterviewDialog = ({ | |||
| const { options } = useSelector((n) => n.options); | |||
| const { users } = useSelector((n) => n.users); | |||
| // const { user } = useSelector((s) => s.user); | |||
| const { isSuccess } = useSelector((s) => s.initProcess); | |||
| const dispatch = useDispatch(); | |||
| @@ -68,7 +67,6 @@ const InterviewDialog = ({ | |||
| onClose(); | |||
| }; | |||
| console.log(selectedInterviewer) | |||
| const submitHandler = () => { | |||
| dispatch( | |||
| fetchInitProcess({ | |||
| @@ -217,7 +215,7 @@ const InterviewDialog = ({ | |||
| className={`c-btn--primary-outlined interview-btn c-btn dialog-btn`} | |||
| onClick={onClose} | |||
| > | |||
| Cancel | |||
| Otkaži | |||
| </IconButton> | |||
| ) : ( | |||
| "" | |||
| @@ -227,7 +225,7 @@ const InterviewDialog = ({ | |||
| className={`c-btn--primary-outlined sm-full interview-btn c-btn dialog-btn`} | |||
| onClick={submitHandler} | |||
| > | |||
| Confirm | |||
| Potvrdi | |||
| </IconButton> | |||
| </DialogActions> | |||
| </div> | |||
| @@ -0,0 +1,220 @@ | |||
| import React, { useContext, useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import x from "../../assets/images/x.png"; | |||
| import { | |||
| Dialog, | |||
| DialogTitle, | |||
| DialogActions, | |||
| useMediaQuery, | |||
| useTheme, | |||
| DialogContent, | |||
| FormControl, | |||
| InputLabel, | |||
| Select, | |||
| MenuItem, | |||
| // TextField, | |||
| // TextField, | |||
| } from "@mui/material"; | |||
| import IconButton from "../IconButton/IconButton"; | |||
| // import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| // import { format, isValid } from "date-fns"; | |||
| // import { fetchInitProcess } from "../../store/actions/candidates/candidatesActions"; | |||
| import { useEffect } from "react"; | |||
| import { SelectionContext } from "../../context/SelectionContext"; | |||
| import { setUpdateInterviewerReq } from "../../store/actions/processes/processAction"; | |||
| // import { setUpdateStatusReq } from "../../store/actions/processes/processAction"; | |||
| const InterviewerDialog = ({ | |||
| title, | |||
| subtitle, | |||
| imgSrc, | |||
| onClose, | |||
| open, | |||
| maxWidth, | |||
| fullWidth, | |||
| responsive, | |||
| }) => { | |||
| const { | |||
| activeInterview, | |||
| setActiveInterview | |||
| } = useContext(SelectionContext); | |||
| const [selected, setSelected] = useState(""); | |||
| const theme = useTheme(); | |||
| const fullScreen = useMediaQuery(theme.breakpoints.down("md")); | |||
| const { users } = useSelector((s) => s.users); | |||
| const { isSuccess } = useSelector((s) => s.interviewerUpdate); | |||
| const dispatch = useDispatch(); | |||
| useEffect(() => { | |||
| handleClose(); | |||
| }, [dispatch, isSuccess]); | |||
| useEffect(() => { | |||
| setSelected(""); | |||
| }, [onClose]); | |||
| const handleClose = () => { | |||
| onClose(); | |||
| }; | |||
| const submitHandler = () => { | |||
| dispatch( | |||
| setUpdateInterviewerReq({ | |||
| data: { | |||
| schedulerId: selected, | |||
| processId: activeInterview.id, | |||
| }, | |||
| responseHandler: apiSuccess, | |||
| }) | |||
| ); | |||
| }; | |||
| const apiSuccess = () => { | |||
| setActiveInterview(null) | |||
| // console.log("ok"); | |||
| }; | |||
| return ( | |||
| <Dialog | |||
| maxWidth={maxWidth} | |||
| keepMounted={false} | |||
| fullWidth={fullWidth} | |||
| fullScreen={responsive && fullScreen} | |||
| onClose={handleClose} | |||
| open={open} | |||
| style={{ | |||
| padding: "36px", | |||
| }} | |||
| > | |||
| {/* {activeInterview?.id} */} | |||
| <div style={{ padding: "36px" }}> | |||
| <DialogTitle style={{ padding: 0 }}> | |||
| {fullScreen ? ( | |||
| <> | |||
| <div className="flex-center" style={{ justifyContent: "start" }}> | |||
| <img | |||
| style={{ | |||
| position: "relative", | |||
| top: -0.25, | |||
| paddingRight: "10px", | |||
| }} | |||
| src={imgSrc} | |||
| /> | |||
| <h5 style={{ textAlign: "start" }}>{title}</h5> | |||
| <div style={{ justifySelf: "stretch", flex: "1" }}></div> | |||
| <IconButton onClick={onClose}> | |||
| <img | |||
| style={{ | |||
| position: "relative", | |||
| top: -0.25, | |||
| }} | |||
| src={x} | |||
| /> | |||
| </IconButton> | |||
| </div> | |||
| <p | |||
| className="dialog-subtitle" | |||
| style={{ paddingLeft: "23px", marginTop: "-10px" }} | |||
| > | |||
| | {subtitle} | |||
| </p> | |||
| </> | |||
| ) : ( | |||
| <div | |||
| className="flex-center" | |||
| style={{ justifyContent: "space-between" }} | |||
| > | |||
| <div className="flex-center" style={{ justifyContent: "start" }}> | |||
| <img | |||
| style={{ | |||
| position: "relative", | |||
| top: -0.25, | |||
| paddingRight: "10px", | |||
| }} | |||
| src={imgSrc} | |||
| /> | |||
| <h5>{title}</h5> | |||
| <div className="vr"></div> | |||
| <p className="dialog-subtitle">{subtitle}</p> | |||
| </div> | |||
| </div> | |||
| )} | |||
| </DialogTitle> | |||
| <DialogContent> | |||
| <form className="modal-content interviewDialog"> | |||
| <FormControl fullWidth> | |||
| <InputLabel id="demo-simple-select-label"> | |||
| Ime intervjuera | |||
| </InputLabel> | |||
| <Select | |||
| labelId="demo-simple-select-label" | |||
| id="demo-simple-select" | |||
| value={ | |||
| selected | |||
| ? selected | |||
| : activeInterview | |||
| ? activeInterview.scheduler.id | |||
| : "" | |||
| } | |||
| label="Ime intervjuera" | |||
| onChange={(e) => { | |||
| setSelected(e.target.value); | |||
| }} | |||
| > | |||
| {users | |||
| ? users.map(({ id, firstName, lastName }, index) => ( | |||
| <MenuItem | |||
| key={index} | |||
| sx={{ textAlign: "left" }} | |||
| value={id} | |||
| > | |||
| {firstName} {lastName} | |||
| </MenuItem> | |||
| )) | |||
| : ""} | |||
| </Select> | |||
| </FormControl> | |||
| {/* {activeProcess.process && activeProcess.process.date ? <p>Proces ima zakazan termin</p> : ''} */} | |||
| </form> | |||
| </DialogContent> | |||
| <DialogActions style={{ padding: 0, justifyContent: "space-between" }}> | |||
| {!fullScreen ? ( | |||
| <IconButton | |||
| data-testid="editbtn" | |||
| className={`c-btn--primary-outlined interview-btn c-btn dialog-btn`} | |||
| onClick={onClose} | |||
| > | |||
| Otkaži | |||
| </IconButton> | |||
| ) : ( | |||
| "" | |||
| )} | |||
| <IconButton | |||
| data-testid="editbtn" | |||
| className={`c-btn--primary-outlined sm-full interview-btn c-btn dialog-btn`} | |||
| onClick={submitHandler} | |||
| > | |||
| Potvrdi | |||
| </IconButton> | |||
| </DialogActions> | |||
| </div> | |||
| </Dialog> | |||
| ); | |||
| }; | |||
| InterviewerDialog.propTypes = { | |||
| title: PropTypes.any, | |||
| subtitle: PropTypes.any, | |||
| imgSrc: PropTypes.any, | |||
| open: PropTypes.bool.isRequired, | |||
| onClose: PropTypes.func.isRequired, | |||
| maxWidth: PropTypes.oneOf(["xs", "sm", "md", "lg", "xl"]), | |||
| fullWidth: PropTypes.bool, | |||
| responsive: PropTypes.bool, | |||
| }; | |||
| export default InterviewerDialog; | |||
| @@ -1,10 +1,14 @@ | |||
| import React, { useContext, useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { formatDateSrb, formatTimeSrb } from "../../util/helpers/dateHelpers"; | |||
| import { FormControl, InputLabel, MenuItem, Select } from "@mui/material"; | |||
| import { Button, FormControl, InputLabel, MenuItem, Select } from "@mui/material"; | |||
| import { SelectionContext } from "../../context/SelectionContext"; | |||
| import { useDispatch} from "react-redux"; | |||
| import { setDoneProcessReq, setUpdateStatusReq } from "../../store/actions/processes/processAction"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { | |||
| setDoneProcessReq, | |||
| setUpdateStatusReq, | |||
| } from "../../store/actions/processes/processAction"; | |||
| // import Button from "../Button/Button"; | |||
| const options = ["Zakazan", "Odrađen", "Čeka na zakazivanje"]; | |||
| @@ -12,43 +16,42 @@ const SelectionCard = (props) => { | |||
| const [showForm, setShowForm] = useState(false); | |||
| const [selected, setSelected] = useState(props.item.status); | |||
| const { setActiveProcess } = useContext(SelectionContext); | |||
| const { setActiveProcess, setActiveInterview } = useContext(SelectionContext); | |||
| const dispatch = useDispatch(); | |||
| // const { success } = useSelector(s => s.statusUpdate) | |||
| const statusChange = (e) => { | |||
| if(props.item.status !== "Odrađen"){ | |||
| e.stopPropagation(); | |||
| setShowForm(true); | |||
| if (props.item.status !== "Odrađen") { | |||
| e.stopPropagation(); | |||
| setShowForm(true); | |||
| } | |||
| }; | |||
| const select = (e) => { | |||
| e.stopPropagation(); | |||
| if (e.target.value === "Zakazan") { | |||
| setActiveProcess({process:props.item, status:'Zakazan'}); | |||
| setActiveProcess({ process: props.item, status: "Zakazan" }); | |||
| } else if (e.target.value === "Odrađen") { | |||
| if (props.item.selectionLevelId !== 4) | |||
| dispatch( | |||
| setDoneProcessReq({ | |||
| id: props.item.id, | |||
| name: "Some random name", | |||
| applicantId: props.item.applicant.applicantId | |||
| applicantId: props.item.applicant.applicantId, | |||
| }) | |||
| ); | |||
| else { | |||
| // pozvati nasu custom metodu za promenu statusa bez prebacivanja u veci nivo | |||
| // promeni status u odradjeno | |||
| dispatch( | |||
| setUpdateStatusReq({ | |||
| data: { | |||
| // schedulerId: selected, | |||
| // appointment: value, | |||
| newStatus: "Odrađen", | |||
| processId: props.item.id, | |||
| } | |||
| })) | |||
| setUpdateStatusReq({ | |||
| data: { | |||
| // schedulerId: selected, | |||
| // appointment: value, | |||
| newStatus: "Odrađen", | |||
| processId: props.item.id, | |||
| }, | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| setSelected(e.target.value); | |||
| @@ -61,9 +64,10 @@ const SelectionCard = (props) => { | |||
| } else props.click(); | |||
| }; | |||
| // useEffect(()=>{ | |||
| // setShowForm(false) | |||
| // },[success]) | |||
| const changeInterviewerHandler = (e) => { | |||
| e.stopPropagation(); | |||
| setActiveInterview(props.item) | |||
| }; | |||
| return ( | |||
| <div | |||
| @@ -126,7 +130,14 @@ const SelectionCard = (props) => { | |||
| </div> | |||
| {props.item.scheduler ? ( | |||
| <div className="sel-item-scheduler"> | |||
| <div></div> | |||
| <div className="change-interbtn"> | |||
| <Button | |||
| className="interbtn" | |||
| onClick={(e) => changeInterviewerHandler(e)} | |||
| > | |||
| Promeni | |||
| </Button> | |||
| </div> | |||
| <p> | |||
| Intervjuer: {props.item.scheduler.firstName}{" "} | |||
| {props.item.scheduler.lastName} | |||
| @@ -5,10 +5,11 @@ export const SelectionContext = createContext(); | |||
| export const SelectionProvider = ({children}) => { | |||
| const [activeProcess, setActiveProcess] = useState(null); | |||
| const [activeInterview, setActiveInterview] = useState(null); | |||
| return ( | |||
| <SelectionContext.Provider | |||
| value={{ activeProcess, setActiveProcess }} | |||
| value={{ activeProcess, setActiveProcess, activeInterview, setActiveInterview }} | |||
| > | |||
| {children} | |||
| </SelectionContext.Provider> | |||
| @@ -15,12 +15,13 @@ import PropTypes from "prop-types"; | |||
| import SelectionFilter from "../../components/Selection/SelectionFilter"; | |||
| import InterviewDialog from "../../components/MUI/InterviewDialog"; | |||
| import plus from "../../assets/images/plus.png"; | |||
| import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; | |||
| import { LocalizationProvider } from '@mui/x-date-pickers'; | |||
| import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; | |||
| import { LocalizationProvider } from "@mui/x-date-pickers"; | |||
| import { fetchCandidateOptions } from "../../store/actions/candidates/candidatesActions"; | |||
| import { SelectionContext } from "../../context/SelectionContext"; | |||
| import { setUsersReq } from "../../store/actions/users/usersActions"; | |||
| import StatusDialog from "../../components/MUI/StatusDialog"; | |||
| import InterviewerDialog from "../../components/MUI/InterviewerDialog"; | |||
| const SelectionProcessPage = ({ history }) => { | |||
| const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | |||
| @@ -33,10 +34,16 @@ const SelectionProcessPage = ({ history }) => { | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const statuses = useSelector(selecStatuses); | |||
| const {isSuccess} = useSelector(s => s.initProcess); | |||
| const {success} = useSelector(s => s.statusUpdate); | |||
| const { isSuccess } = useSelector((s) => s.initProcess); | |||
| const { success } = useSelector((s) => s.statusUpdate); | |||
| const { updateSuccess } = useSelector((s) => s.interviewerUpdate); | |||
| const {activeProcess,setActiveProcess} = useContext(SelectionContext) | |||
| const { | |||
| activeProcess, | |||
| setActiveProcess, | |||
| activeInterview, | |||
| setActiveInterview, | |||
| } = useContext(SelectionContext); | |||
| useEffect(() => { | |||
| dispatch(fetchCandidateOptions()); | |||
| @@ -49,13 +56,13 @@ const SelectionProcessPage = ({ history }) => { | |||
| { isChecked: false, name: "Čeka se odgovor" }, | |||
| ]; | |||
| dispatch(setStatuses(s)); | |||
| }, [isSuccess,success]); | |||
| }, [isSuccess, success, updateSuccess]); | |||
| useEffect(() => { | |||
| dispatch(setUsersReq()); | |||
| dispatch(setProcessesReq()); | |||
| dispatch(setDoneProcess(false)); | |||
| }, [process.process.doneProcess, success]); | |||
| }, [process.process.doneProcess, success, updateSuccess]); | |||
| const handleToggleFiltersDrawer = () => { | |||
| setToggleFiltersDrawer((oldState) => !oldState); | |||
| @@ -69,7 +76,7 @@ const SelectionProcessPage = ({ history }) => { | |||
| return ( | |||
| <Selection | |||
| modalEvent={() => { | |||
| setToggleInitModal(true) | |||
| setToggleInitModal(true); | |||
| }} | |||
| selection={item} | |||
| order={index} | |||
| @@ -79,49 +86,59 @@ const SelectionProcessPage = ({ history }) => { | |||
| ); | |||
| }); | |||
| return (<LocalizationProvider dateAdapter={AdapterDateFns}> | |||
| <div data-testid="selections-page"> | |||
| <div className="l-t-rectangle"></div> | |||
| <div className="r-b-rectangle"></div> | |||
| <SelectionFilter /> | |||
| <SelectionFilter | |||
| open={toggleFiltersDrawer} | |||
| handleClose={handleToggleFiltersDrawer} | |||
| statuses={statuses} | |||
| /> | |||
| <StatusDialog | |||
| open={activeProcess !== null} | |||
| title={"Dodavanje intervjuera"} | |||
| subtitle={'Selekcija'} | |||
| imgSrc={plus} | |||
| onClose={() => { | |||
| setActiveProcess(null); | |||
| }} | |||
| /> | |||
| <InterviewDialog | |||
| open={toggleInitModal} | |||
| title={"Dodavanje kandidata"} | |||
| subtitle={'HR intervju'} | |||
| imgSrc={plus} | |||
| onClose={() => { | |||
| setToggleInitModal(false); | |||
| }} | |||
| /> | |||
| <AddAdModal open={toggleModal} handleClose={handleToggleModal} /> | |||
| <div className="selections"> | |||
| <div className="level-header"> | |||
| <h1> | |||
| {t("selection.title")} | |||
| <span className="level-header-spliter">|</span> | |||
| <span className="level-header-subheader"> | |||
| {t("selection.subtitle")} | |||
| </span> | |||
| </h1> | |||
| <FilterButton onShowFilters={handleToggleFiltersDrawer} /> | |||
| </div> | |||
| <div className="selection-levels"> | |||
| <div> | |||
| {/* <IconButton | |||
| return ( | |||
| <LocalizationProvider dateAdapter={AdapterDateFns}> | |||
| <div data-testid="selections-page"> | |||
| <div className="l-t-rectangle"></div> | |||
| <div className="r-b-rectangle"></div> | |||
| <SelectionFilter /> | |||
| <SelectionFilter | |||
| open={toggleFiltersDrawer} | |||
| handleClose={handleToggleFiltersDrawer} | |||
| statuses={statuses} | |||
| /> | |||
| <StatusDialog | |||
| open={activeProcess !== null} | |||
| title={"Dodavanje intervjuera"} | |||
| subtitle={"Selekcija"} | |||
| imgSrc={plus} | |||
| onClose={() => { | |||
| setActiveProcess(null); | |||
| }} | |||
| /> | |||
| <InterviewerDialog | |||
| open={activeInterview !== null} | |||
| title={"Promena intervjuera"} | |||
| subtitle={"Selekcija"} | |||
| imgSrc={plus} | |||
| onClose={() => { | |||
| setActiveInterview(null); | |||
| }} | |||
| /> | |||
| <InterviewDialog | |||
| open={toggleInitModal} | |||
| title={"Dodavanje kandidata"} | |||
| subtitle={"HR intervju"} | |||
| imgSrc={plus} | |||
| onClose={() => { | |||
| setToggleInitModal(false); | |||
| }} | |||
| /> | |||
| <AddAdModal open={toggleModal} handleClose={handleToggleModal} /> | |||
| <div className="selections"> | |||
| <div className="level-header"> | |||
| <h1> | |||
| {t("selection.title")} | |||
| <span className="level-header-spliter">|</span> | |||
| <span className="level-header-subheader"> | |||
| {t("selection.subtitle")} | |||
| </span> | |||
| </h1> | |||
| <FilterButton onShowFilters={handleToggleFiltersDrawer} /> | |||
| </div> | |||
| <div className="selection-levels"> | |||
| <div> | |||
| {/* <IconButton | |||
| sx={{ marginLeft: "15px" }} | |||
| className="c-btn c-btn--primary-outlined fixed-right" | |||
| onClick={handleToggleFiltersDrawer} | |||
| @@ -129,15 +146,16 @@ const SelectionProcessPage = ({ history }) => { | |||
| Filteri{" "} | |||
| <img src={filterVector} alt="filter" className="filter-vector" /> | |||
| </IconButton> */} | |||
| <div className="selection-levels-processes"> | |||
| <div className="selection-levels-processes-process"> | |||
| {renderList} | |||
| <div className="selection-levels-processes"> | |||
| <div className="selection-levels-processes-process"> | |||
| {renderList} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div></LocalizationProvider> | |||
| </LocalizationProvider> | |||
| ); | |||
| }; | |||
| @@ -41,7 +41,8 @@ export default { | |||
| filteredLevels: base + "/selectionlevels/filtered", | |||
| doneProcess: base + "/selectionprocesses", | |||
| getApplicantProcesses: base + "/applicants/processes", | |||
| changeStatus: base + "/selectionprocesses/status-update" | |||
| changeStatus: base + "/selectionprocesses/status-update", | |||
| changeInterviewer: base + "/selectionprocesses/interviewer-update" | |||
| // allProcesses: base + "/selectionprocesses", | |||
| }, | |||
| patterns: { | |||
| @@ -4,6 +4,7 @@ import apiEndpoints from "./apiEndpoints"; | |||
| export const getAllLevels = () => getRequest(apiEndpoints.processes.allLevels); | |||
| export const doneProcess = (data) => postRequest(apiEndpoints.processes.doneProcess,data); | |||
| export const updateStatus = (data) => postRequest(apiEndpoints.processes.changeStatus,data); | |||
| export const updateInterviewer = (data) => postRequest(apiEndpoints.processes.changeInterviewer,data); | |||
| export const getProcessesOfApplicant = (id) => getRequest(`${apiEndpoints.processes.getApplicantProcesses}/${id}`); | |||
| export const getAllFilteredProcessesReq = (payload) => { | |||
| let statusesQuery = ""; | |||
| @@ -1,4 +1,7 @@ | |||
| import { | |||
| FETCH_INTERVIEWER_CHANGE_ERR, | |||
| FETCH_INTERVIEWER_CHANGE_REQ, | |||
| FETCH_INTERVIEWER_CHANGE_SUCCESS, | |||
| FETCH_STATUS_CHANGE_ERR, | |||
| FETCH_STATUS_CHANGE_REQ, | |||
| FETCH_STATUS_CHANGE_SUCCESS, | |||
| @@ -36,4 +39,19 @@ import { | |||
| export const setUpdateStatusSucc = () => ({ | |||
| type: FETCH_STATUS_CHANGE_SUCCESS, | |||
| }); | |||
| // | |||
| export const setUpdateInterviewerReq = (payload) => ({ | |||
| type: FETCH_INTERVIEWER_CHANGE_REQ, | |||
| payload | |||
| }); | |||
| export const setUpdateInterviewerErr = (payload) => ({ | |||
| type: FETCH_INTERVIEWER_CHANGE_ERR, | |||
| payload, | |||
| }); | |||
| export const setUpdateInterviewerSucc = () => ({ | |||
| type: FETCH_INTERVIEWER_CHANGE_SUCCESS, | |||
| }); | |||
| @@ -31,4 +31,8 @@ export const CHANGE_STATUS_ISCHECKED_VALUE = 'CHANGE_STATUS_ISCHECKED_VALUE'; | |||
| export const FETCH_STATUS_CHANGE_REQ = 'FETCH_STATUS_CHANGE_REQ'; | |||
| export const FETCH_STATUS_CHANGE_ERR = 'FETCH_STATUS_CHANGE_ERR'; | |||
| export const FETCH_STATUS_CHANGE_SUCCESS = 'FETCH_STATUS_CHANGE_SUCCESS'; | |||
| export const FETCH_STATUS_CHANGE_SUCCESS = 'FETCH_STATUS_CHANGE_SUCCESS'; | |||
| export const FETCH_INTERVIEWER_CHANGE_REQ = 'FETCH_INTERVIEWER_CHANGE_REQ'; | |||
| export const FETCH_INTERVIEWER_CHANGE_ERR = 'FETCH_INTERVIEWER_CHANGE_ERR'; | |||
| export const FETCH_INTERVIEWER_CHANGE_SUCCESS = 'FETCH_INTERVIEWER_CHANGE_SUCCESS'; | |||
| @@ -32,6 +32,7 @@ import candidateOptionsReducer from "./candidates/candidateOptionsReducer"; | |||
| import initProcessReducer from "./candidates/initProcessReducer"; | |||
| import applyForAdReducer from "./applicants/applyForAdReducer"; | |||
| import statusUpdateReducer from "./processes/statusUpdateReducer"; | |||
| import interviewerUpdateReducer from "./processes/interviewerUpdateReducer"; | |||
| export default combineReducers({ | |||
| login: loginReducer, | |||
| @@ -66,5 +67,6 @@ export default combineReducers({ | |||
| scheduleAppointment: scheduleAppointmentReducer, | |||
| patternApplicants: patternApplicantsReducer, | |||
| applyForAd: applyForAdReducer, | |||
| statusUpdate: statusUpdateReducer | |||
| statusUpdate: statusUpdateReducer, | |||
| interviewerUpdate: interviewerUpdateReducer | |||
| }); | |||
| @@ -0,0 +1,31 @@ | |||
| import createReducer from "../../utils/createReducer"; | |||
| import { | |||
| FETCH_INTERVIEWER_CHANGE_ERR, | |||
| FETCH_INTERVIEWER_CHANGE_REQ, | |||
| FETCH_INTERVIEWER_CHANGE_SUCCESS, | |||
| } from "../../actions/processes/processesActionConstants"; | |||
| const initialState = { | |||
| updateSuccess: false, | |||
| errorMessage: "", | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [FETCH_INTERVIEWER_CHANGE_REQ]: interviewerUpdateRequest, | |||
| [FETCH_INTERVIEWER_CHANGE_ERR]: setStateErrorMessage, | |||
| [FETCH_INTERVIEWER_CHANGE_SUCCESS]: interviewerUpdateSuccess, | |||
| }, | |||
| initialState | |||
| ); | |||
| function interviewerUpdateSuccess(state) { | |||
| return { ...state, updateSuccess: true }; | |||
| } | |||
| function interviewerUpdateRequest(state) { | |||
| return { ...state, updateSuccess: false }; | |||
| } | |||
| function setStateErrorMessage(state, action) { | |||
| return { ...state, errorMessage: action.payload }; | |||
| } | |||
| @@ -1,12 +1,39 @@ | |||
| import { all, call, put, takeLatest } from "redux-saga/effects"; | |||
| import { getAllLevels, doneProcess, getProcessesOfApplicant, getAllFilteredProcessesReq, updateStatus } from "../../request/processesReguest"; | |||
| import { setProcesses, setProcessesError } from "../actions/processes/processesAction"; | |||
| import { | |||
| getAllLevels, | |||
| doneProcess, | |||
| getProcessesOfApplicant, | |||
| getAllFilteredProcessesReq, | |||
| updateStatus, | |||
| updateInterviewer, | |||
| } from "../../request/processesReguest"; | |||
| import { | |||
| setProcesses, | |||
| setProcessesError, | |||
| } from "../actions/processes/processesAction"; | |||
| import { addHeaderToken } from "../../request"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { JWT_TOKEN } from "../../constants/localStorage"; | |||
| import { setDoneProcess, setDoneProcessError, setUpdateStatusErr, setUpdateStatusSucc } from "../actions/processes/processAction"; | |||
| import { setApplicant, setApplicantError } from "../actions/processes/applicantAction"; | |||
| import { FETCH_PROCESSES_REQ, FETCH_FILTERED_PROCESSES_REQ ,PUT_PROCESS_REQ, FETCH_APPLICANT_PROCESSES_REQ, FETCH_STATUS_CHANGE_REQ } from "../actions/processes/processesActionConstants"; | |||
| import { | |||
| setDoneProcess, | |||
| setDoneProcessError, | |||
| setUpdateStatusErr, | |||
| setUpdateStatusSucc, | |||
| setUpdateInterviewerSucc, | |||
| setUpdateInterviewerErr, | |||
| } from "../actions/processes/processAction"; | |||
| import { | |||
| setApplicant, | |||
| setApplicantError, | |||
| } from "../actions/processes/applicantAction"; | |||
| import { | |||
| FETCH_PROCESSES_REQ, | |||
| FETCH_FILTERED_PROCESSES_REQ, | |||
| PUT_PROCESS_REQ, | |||
| FETCH_APPLICANT_PROCESSES_REQ, | |||
| FETCH_STATUS_CHANGE_REQ, | |||
| FETCH_INTERVIEWER_CHANGE_REQ, | |||
| } from "../actions/processes/processesActionConstants"; | |||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | |||
| export function* getProcesses() { | |||
| @@ -43,12 +70,13 @@ export function* finishProcess(payload) { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| const model = payload.payload; | |||
| const result = yield call(doneProcess,model); | |||
| const result = yield call(doneProcess, model); | |||
| yield put(setDoneProcess(result.data)); | |||
| } catch (error) { if (error.response && error.response.data) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(setDoneProcessError(errorMessage)); | |||
| } | |||
| } catch (error) { | |||
| if (error.response && error.response.data) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(setDoneProcessError(errorMessage)); | |||
| } | |||
| } | |||
| } | |||
| @@ -57,7 +85,7 @@ export function* getApplicantProcesses(payload) { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| const id = payload.payload; | |||
| const {data} = yield call(getProcessesOfApplicant,id); | |||
| const { data } = yield call(getProcessesOfApplicant, id); | |||
| yield put(setApplicant(data)); | |||
| } catch (error) { | |||
| if (error.response && error.response.data) { | |||
| @@ -66,14 +94,15 @@ export function* getApplicantProcesses(payload) { | |||
| } | |||
| } | |||
| } | |||
| export function* changeStatus({payload}) { | |||
| export function* changeStatus({ payload }) { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| yield call(updateStatus,payload.data); | |||
| yield call(updateStatus, payload.data); | |||
| yield put(setUpdateStatusSucc()); | |||
| if(payload.responseHandler){ | |||
| yield call(payload.responseHandler) | |||
| if (payload.responseHandler) { | |||
| yield call(payload.responseHandler); | |||
| } | |||
| } catch (error) { | |||
| if (error.response && error.response.data) { | |||
| @@ -83,8 +112,26 @@ export function* changeStatus({payload}) { | |||
| } | |||
| } | |||
| export function* changeInterviewer({ payload }) { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| yield call(updateInterviewer, payload.data); | |||
| yield put(setUpdateInterviewerSucc()); | |||
| if (payload.responseHandler) { | |||
| yield call(payload.responseHandler); | |||
| } | |||
| } catch (error) { | |||
| if (error.response && error.response.data) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(setUpdateInterviewerErr(errorMessage)); | |||
| } | |||
| } | |||
| } | |||
| export default function* processesSaga() { | |||
| yield all([takeLatest(FETCH_PROCESSES_REQ, getProcesses)]); | |||
| yield all([takeLatest(FETCH_INTERVIEWER_CHANGE_REQ, changeInterviewer)]); | |||
| yield all([takeLatest(FETCH_STATUS_CHANGE_REQ, changeStatus)]); | |||
| yield all([takeLatest(FETCH_FILTERED_PROCESSES_REQ, getFilteredProcesses)]); | |||
| yield all([takeLatest(PUT_PROCESS_REQ, finishProcess)]); | |||