| @@ -1,78 +1,59 @@ | |||
| h1, | |||
| h3 { | |||
| margin: 0; | |||
| padding: 0; | |||
| } | |||
| .ads { | |||
| .selections { | |||
| margin-top: 36px; | |||
| padding-left: 3rem; | |||
| padding-left: 72px; | |||
| } | |||
| .active-ads-header { | |||
| .level-header { | |||
| padding-left: 81px; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| } | |||
| .activee{ | |||
| /* Blue 4 */ | |||
| background : #E8F7FF; | |||
| border : 1px solid #226CB0; | |||
| } | |||
| .active-ads | |||
| { | |||
| .selection-levels { | |||
| overflow-x: scroll; | |||
| padding-bottom: 100px; | |||
| } | |||
| .active-ads-subheader { | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 24px; | |||
| line-height: 36px; | |||
| padding-left: 0.3rem; | |||
| /* identical to box height, or 100% */ | |||
| color:#226CB0; | |||
| letter-spacing: 0.02em; | |||
| } | |||
| .active-ads-subheader-spliter { | |||
| .level-header-subheader { | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 24px; | |||
| line-height: 36px; | |||
| padding-left: 0.3rem; | |||
| /* identical to box height, or 100% */ | |||
| color:#272727; | |||
| letter-spacing: 0.02em; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 24px; | |||
| line-height: 36px; | |||
| padding-left: 0.3rem; | |||
| color: #226CB0; | |||
| letter-spacing: 0.02em; | |||
| } | |||
| .filter-vector { | |||
| margin-left: 0.5rem !important; | |||
| .level-header-spliter { | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 24px; | |||
| line-height: 36px; | |||
| padding-left: 0.3rem; | |||
| color: #272727; | |||
| letter-spacing: 0.02em; | |||
| } | |||
| .active-ads-ads { | |||
| .selection-levels-processes { | |||
| display: flex; | |||
| margin-top: 39px; | |||
| position: relative; | |||
| } | |||
| .active-ads-ads-ad { | |||
| .selection-levels-processes-process { | |||
| padding-left: 81px; | |||
| display: flex; | |||
| } | |||
| .selection-card { | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: start; | |||
| align-items: left; | |||
| // width: 550px; | |||
| height: fit-content; | |||
| padding: 36px; | |||
| background: #F4F4F4; | |||
| @@ -82,10 +63,14 @@ letter-spacing: 0.02em; | |||
| margin-right: 36px; | |||
| } | |||
| .bg-danger{ | |||
| .bg-danger { | |||
| background-color: #272727; | |||
| } | |||
| .grey { | |||
| color: #e4e4e4 | |||
| } | |||
| .selection-item { | |||
| display: flex; | |||
| flex-direction: row; | |||
| @@ -93,7 +78,6 @@ letter-spacing: 0.02em; | |||
| vertical-align: top; | |||
| align-items: left; | |||
| width: 400px; | |||
| // height: 400px; | |||
| padding: 18px 36px; | |||
| background: #FFFFFF; | |||
| border: 1px solid #e4e4e4; | |||
| @@ -128,41 +112,22 @@ letter-spacing: 0.02em; | |||
| flex-grow: 0; | |||
| } | |||
| .ad-card-logo img { | |||
| width: 61px; | |||
| height: 49px; | |||
| flex: none; | |||
| order: 2; | |||
| flex-grow: 0; | |||
| } | |||
| .selection-item-name, .selection-item-date{ | |||
| margin: auto 0 !important; | |||
| .selection-item-name, | |||
| .selection-item-date { | |||
| margin: auto 0 !important; | |||
| } | |||
| .selection-item-name p { | |||
| height: 20px; | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| text-align: right; | |||
| color: #226CB0; | |||
| flex: none; | |||
| order: 2; | |||
| flex-grow: 0; | |||
| } | |||
| .ad-card-buttons { | |||
| display: flex; | |||
| flex-direction: row; | |||
| align-items: flex-start; | |||
| justify-content: center; | |||
| padding: 0px; | |||
| gap: 18px; | |||
| width: 281px; | |||
| height: 38px; | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| text-align: right; | |||
| color: #226CB0; | |||
| flex: none; | |||
| order: 0; | |||
| order: 2; | |||
| flex-grow: 0; | |||
| } | |||
| @@ -184,176 +149,53 @@ flex-grow: 0; | |||
| flex-grow: 0; | |||
| } | |||
| .add-ad { | |||
| margin-top: 49px; | |||
| display: flex; | |||
| justify-content: flex-end; | |||
| align-items: center; | |||
| padding-right: 5rem !important; | |||
| padding-bottom: 49px; | |||
| } | |||
| .add-ad-btn { | |||
| .sel-item { | |||
| display: flex; | |||
| flex-direction: row; | |||
| justify-content: center; | |||
| align-items: center; | |||
| padding: 18px 72px; | |||
| gap: 10px; | |||
| width: 201px; | |||
| height: 51px; | |||
| background: #226cb0; | |||
| border-radius: 9px; | |||
| } | |||
| .ad-filters-header-container { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| } | |||
| .ad-filters-header { | |||
| display: flex; | |||
| align-items: center; | |||
| } | |||
| .ad-filters-header-close { | |||
| cursor: pointer; | |||
| } | |||
| .ad-filters-header > * { | |||
| margin-right: 0.25rem; | |||
| } | |||
| .ad-filters-header img { | |||
| width: 18px; | |||
| height: 15.75px; | |||
| } | |||
| .ad-filters-header sub { | |||
| color: #226cb0; | |||
| padding: 18px 36px; | |||
| gap: 18px; | |||
| width: 458px; | |||
| background: #FFFFFF; | |||
| border: 1px solid #E4E4E4; | |||
| border-radius: 18px; | |||
| } | |||
| .ad-filters-sub-title { | |||
| font-family: "Source Sans Pro"; | |||
| .sel-item .status { | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-weight: 400; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| color: #272727; | |||
| flex: none; | |||
| order: 0; | |||
| flex-grow: 0; | |||
| } | |||
| .ad-filters-experience { | |||
| margin-top: 18px; | |||
| box-sizing: border-box; | |||
| } | |||
| .ad-filters-experience-slider { | |||
| margin-top: 5px; | |||
| } | |||
| .ad-filters-technologies { | |||
| margin-top: 18px; | |||
| } | |||
| .ad-filters-employment-type { | |||
| display: flex; | |||
| } | |||
| .ad-filters-employment-type > button { | |||
| margin-right: 0.5rem; | |||
| margin-top: 18px; | |||
| } | |||
| .ad-filters-search { | |||
| margin-top: 18px; | |||
| padding-bottom: 18px; | |||
| } | |||
| .ad-filters-search > * { | |||
| width: 100%; | |||
| } | |||
| .sel-item{ | |||
| display: flex; | |||
| flex-direction: row; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 18px 36px; | |||
| gap: 18px; | |||
| width: 458px; | |||
| /* White */ | |||
| background: #FFFFFF; | |||
| /* Gray E4 */ | |||
| border: 1px solid #E4E4E4; | |||
| border-radius: 18px; | |||
| } | |||
| .sel-item .p{ | |||
| /* Paragraph */ | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 400; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| /* Main Black */ | |||
| color: #272727; | |||
| /* Inside auto layout */ | |||
| flex: none; | |||
| order: 0; | |||
| flex-grow: 0; | |||
| } | |||
| .sel-item .date{ | |||
| /* 22.07. | 14:10h */ | |||
| /* Paragraph */ | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 400; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| /* Main Black */ | |||
| color: #272727; | |||
| .sel-item .date { | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 400; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| color: #272727; | |||
| } | |||
| .sel-item .rig{ | |||
| height: 20px; | |||
| /* Bold Paragraph */ | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 16px; | |||
| line-height: 20px; | |||
| text-align: right; | |||
| /* Main Blue */ | |||
| color: #226CB0; | |||
| /* Inside auto layout */ | |||
| flex: none; | |||
| order: 1; | |||
| flex-grow: 0; | |||
| .sel-item .full-name { | |||
| height: 20px; | |||
| font-family: 'Source Sans Pro'; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| font-size: 16px; | |||
| text-align: right; | |||
| color: #226CB0; | |||
| flex: 3 0 auto; | |||
| order: 1; | |||
| } | |||
| .sel-item .p button { | |||
| .sel-item .status button { | |||
| box-sizing: border-box; | |||
| display: flex; | |||
| flex-direction: row; | |||
| @@ -365,6 +207,7 @@ flex-grow: 0; | |||
| min-width: 76px; | |||
| height: 38px; | |||
| border: 1px solid #e4e4e4; | |||
| background: white; | |||
| border-radius: 9px; | |||
| flex: none; | |||
| order: 0; | |||
| @@ -1,37 +1,50 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { selectDoneProcessError } from "../../store/selectors/processesSelectors"; | |||
| import { setDoneProcessReq } from "../../store/actions/processes/processesAction"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import { formatDateSrb, formatTimeSrb } from "../../util/helpers/dateHelpers"; | |||
| const dragStart = (e, applicant) => { | |||
| // e.dataTransfer.setData("applicant", applicant.id); | |||
| e.dataTransfer.setData("text/plain",JSON.stringify(applicant)); | |||
| } | |||
| const dragOver = (e) => { | |||
| e.preventDefault(); | |||
| } | |||
| const dropItem = (e,selId) =>{ | |||
| var data = e.dataTransfer.getData("text/plain"); | |||
| const applicant = JSON.parse(data); | |||
| if(applicant.currentSelection !== selId){ | |||
| // SEND REQUEST TO BACKEND TO STORE NEW SELECTION | |||
| console.log('jup') | |||
| } | |||
| } | |||
| const Selection = (props) => { | |||
| console.log(props.selection); | |||
| const applicants = props.selection.applicants; | |||
| const renderList = applicants.map((item, index) => { | |||
| const applicants = props.selection.selectionProcesses; | |||
| const errorMessage = useSelector(selectDoneProcessError); | |||
| const dispatch = useDispatch(); | |||
| const dragStart = (e, applicant) => { | |||
| e.dataTransfer.setData("text/plain",JSON.stringify(applicant)); | |||
| } | |||
| const dragOver = (e) => { | |||
| e.preventDefault(); | |||
| } | |||
| const dropItem = (e,selId) =>{ | |||
| var data = e.dataTransfer.getData("text/plain"); | |||
| const selectionProcess = JSON.parse(data); | |||
| console.log(selectionProcess) | |||
| if(selectionProcess.selectionLevelId !== selId){ | |||
| dispatch(setDoneProcessReq({id: selectionProcess.id})); | |||
| } | |||
| if(errorMessage) | |||
| { | |||
| console.log(errorMessage) | |||
| } | |||
| } | |||
| const renderList = applicants?.map((item, index) => { | |||
| return <div draggable key={index} className="sel-item" onDragStart={e => dragStart(e,item)}> | |||
| <div className="p"> | |||
| <div className="status"> | |||
| <button>{item.status}</button> | |||
| </div> | |||
| <div className="date"> | |||
| <p>{item.date}</p> | |||
| <p>{formatDateSrb(item.date)} <span className="grey">|</span> {formatTimeSrb(item.date)}</p> | |||
| </div> | |||
| <div className="rig"> | |||
| <p>{item.name}</p> | |||
| <div className="full-name"> | |||
| <p>{item.applicant.firstName + " " + item.applicant.lastName}</p> | |||
| </div> | |||
| </div> | |||
| } | |||
| @@ -46,7 +59,12 @@ const Selection = (props) => { | |||
| <h3>{props.selection.name}</h3> | |||
| </div> | |||
| {renderList} | |||
| {applicants.length > 0 && renderList} | |||
| {applicants.length === 0 && <div className="sel-item"> | |||
| <div className="date"> | |||
| <p>Nema kandidata u selekciji</p> | |||
| </div> | |||
| </div>} | |||
| </div> | |||
| ); | |||
| }; | |||
| @@ -55,13 +73,17 @@ Selection.propTypes = { | |||
| selection: PropTypes.shape({ | |||
| id: PropTypes.number, | |||
| name : PropTypes.string, | |||
| applicants: PropTypes.arrayOf(PropTypes.shape({ | |||
| selectionProcesses: PropTypes.arrayOf(PropTypes.shape({ | |||
| id: PropTypes.number, | |||
| name: PropTypes.string, | |||
| date: PropTypes.string, | |||
| status: PropTypes.string, | |||
| currentSelection: PropTypes.number, | |||
| map: PropTypes.func | |||
| map: PropTypes.func, | |||
| applicant: PropTypes.shape({ | |||
| firstName: PropTypes.string, | |||
| lastName: PropTypes.string | |||
| }) | |||
| })) | |||
| }), | |||
| }; | |||
| @@ -1,15 +1,35 @@ | |||
| import React, { useState } from "react"; | |||
| import React, { useState, useEffect } from "react"; | |||
| import { useSelector} from 'react-redux'; | |||
| import Selection from "../../components/Selection/Selection"; | |||
| import IconButton from "../../components/IconButton/IconButton"; | |||
| import filterVector from "../../assets/images/filter_vector.png"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import AddAdModal from "../../components/Ads/AddAdModal"; | |||
| import { useDispatch } from "react-redux"; | |||
| import AdFilters from "../../components/Ads/AdFilters"; | |||
| import { setProcessesReq } from "../../store/actions/processes/processesAction"; | |||
| import { selectProcesses, selectDoneProcess } from "../../store/selectors/processesSelectors"; | |||
| const SelectionProcessPage = () => { | |||
| const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | |||
| const [toggleModal, setToggleModal] = useState(false); | |||
| // const errorMessage = useSelector(selectProcessesError); | |||
| const processes = useSelector(selectProcesses); | |||
| // const doneErrorMessage = useSelector(selectDoneProcessError); | |||
| const doneProcess = useSelector(selectDoneProcess); | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| useEffect(() => { | |||
| dispatch(setProcessesReq()); | |||
| }, []); | |||
| useEffect(() => { | |||
| dispatch(setProcessesReq()); | |||
| },[doneProcess]) | |||
| // console.log(errorMessage); | |||
| // console.log(doneErrorMessage); | |||
| const handleToggleFiltersDrawer = () => { | |||
| setToggleFiltersDrawer((oldState) => !oldState); | |||
| @@ -19,100 +39,8 @@ const SelectionProcessPage = () => { | |||
| setToggleModal((oldState) => !oldState); | |||
| }; | |||
| const selections = [ | |||
| { | |||
| id: 1, | |||
| name: "HR interview", | |||
| applicants: [ | |||
| { | |||
| id: 1, | |||
| name: "Stefan Petrovic", | |||
| status: "Zakazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 1 | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: "Stefan Petrovic", | |||
| status: "Otkazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 1 | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: "Stefan Petrovic", | |||
| status: "Ceka na zakazivanje", | |||
| currentSelection: 1 | |||
| }] | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: "Screening test", | |||
| applicants: [ | |||
| { | |||
| id: 1, | |||
| name: "Stefan Petrovic", | |||
| status: "Zakazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 2 | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: "Stefan Petrovic", | |||
| status: "Otkazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 2 | |||
| }] | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: "Technical interview", | |||
| applicants: [ | |||
| { | |||
| id: 1, | |||
| name: "Stefan Petrovic", | |||
| status: "Zakazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 3 | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: "Stefan Petrovic", | |||
| status: "Otkazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 3 | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: "Stefan Petrovic", | |||
| status: "Ceka na zakazivanje", | |||
| currentSelection: 3 | |||
| }] | |||
| }, | |||
| { | |||
| id: 4, | |||
| name: "Final decision", | |||
| applicants: [ | |||
| { | |||
| id: 1, | |||
| name: "Stefan Petrovic", | |||
| status: "Zakazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 4 | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: "Stefan Petrovic", | |||
| status: "Otkazan", | |||
| date: "01.01.2022 11:00", | |||
| currentSelection: 4 | |||
| }] | |||
| } | |||
| ] | |||
| const renderList = selections.map((item, index) => { | |||
| const renderList = processes.map((item, index) => { | |||
| return <Selection selection={item} key={index}/> | |||
| } | |||
| ); | |||
| @@ -127,14 +55,14 @@ const SelectionProcessPage = () => { | |||
| handleClose={handleToggleFiltersDrawer} | |||
| /> | |||
| <AddAdModal open={toggleModal} handleClose={handleToggleModal} /> | |||
| <div className="ads"> | |||
| <div className="active-ads"> | |||
| <div className="active-ads-header"> | |||
| <div className="selections"> | |||
| <div className="selection-levels"> | |||
| <div className="level-header"> | |||
| <h1>{t("selection.title")} | |||
| <span className="active-ads-subheader-spliter"> | |||
| <span className="level-header-spliter"> | |||
| | | |||
| </span> | |||
| <span className="active-ads-subheader"> | |||
| <span className="level-header-subheader"> | |||
| Svi kandidati | |||
| </span> | |||
| </h1> | |||
| @@ -147,8 +75,8 @@ const SelectionProcessPage = () => { | |||
| <img src={filterVector} alt="filter" className="filter-vector" /> | |||
| </IconButton> | |||
| </div> | |||
| <div className="active-ads-ads"> | |||
| <div className="active-ads-ads-ad"> | |||
| <div className="selection-levels-processes"> | |||
| <div className="selection-levels-processes-process"> | |||
| {renderList} | |||
| </div> | |||
| </div> | |||
| @@ -24,5 +24,10 @@ export default { | |||
| }, | |||
| comments:{ | |||
| addComment:base + '/comments' | |||
| } | |||
| }, | |||
| processes: { | |||
| allLevels: base + "/selectionlevels", | |||
| doneProcess: base + "/selectionprocesses", | |||
| // allProcesses: base + "/selectionprocesses", | |||
| }, | |||
| }; | |||
| @@ -0,0 +1,5 @@ | |||
| import { getRequest } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const getAllLevels = () => getRequest(apiEndpoints.processes.allLevels); | |||
| export const doneProcess = (id) => getRequest(`${apiEndpoints.processes.doneProcess}/${id}`); | |||
| @@ -0,0 +1,37 @@ | |||
| import { | |||
| FETCH_PROCESSES_REQ, | |||
| FETCH_PROCESSES_ERR, | |||
| FETCH_PROCESSES_SUCCESS, | |||
| PUT_PROCESS_ERR, | |||
| PUT_PROCESS_REQ, | |||
| PUT_PROCESS_SUCCESS | |||
| } from "./processesActionConstants"; | |||
| export const setProcessesReq = () => ({ | |||
| type: FETCH_PROCESSES_REQ, | |||
| }); | |||
| export const setProcessesError = (payload) => ({ | |||
| type: FETCH_PROCESSES_ERR, | |||
| payload, | |||
| }); | |||
| export const setProcesses = (payload) => ({ | |||
| type: FETCH_PROCESSES_SUCCESS, | |||
| payload, | |||
| }); | |||
| export const setDoneProcessReq = (payload) => ({ | |||
| type: PUT_PROCESS_REQ, | |||
| payload | |||
| }); | |||
| export const setDoneProcessError = (payload) => ({ | |||
| type: PUT_PROCESS_ERR, | |||
| payload, | |||
| }); | |||
| export const setDoneProcess = (payload) => ({ | |||
| type: PUT_PROCESS_SUCCESS, | |||
| payload | |||
| }); | |||
| @@ -0,0 +1,6 @@ | |||
| export const FETCH_PROCESSES_REQ = 'FETCH_PROCESSES_REQ'; | |||
| export const FETCH_PROCESSES_ERR = 'FETCH_PROCESSES_ERR'; | |||
| export const FETCH_PROCESSES_SUCCESS = 'FETCH_PROCESSES_SUCCESS'; | |||
| export const PUT_PROCESS_REQ = 'PUT_PROCESS_REQ'; | |||
| export const PUT_PROCESS_ERR = 'PUT_PROCESS_ERR'; | |||
| export const PUT_PROCESS_SUCCESS = 'PUT_PROCESS_SUCCESS'; | |||
| @@ -9,6 +9,9 @@ import candidateReducer from './candidate/candidateReducer'; | |||
| import adsReducer from "./ad/adsReducer"; | |||
| import adReducer from "./ad/adReducer"; | |||
| import archiveAdsReducer from "./ad/archiveAdsReducer"; | |||
| import candidatesReducer from "./candidates/candidatesReducer"; | |||
| import candidatesReducer from './candidates/candidatesReducer'; | |||
| import processesReducer from './processes/processesReducer'; | |||
| export default combineReducers({ | |||
| login: loginReducer, | |||
| @@ -21,4 +24,6 @@ export default combineReducers({ | |||
| ads: adsReducer, | |||
| ad: adReducer, | |||
| archiveAds: archiveAdsReducer, | |||
| candidates: candidatesReducer, | |||
| processes: processesReducer | |||
| }); | |||
| @@ -0,0 +1,51 @@ | |||
| import { | |||
| FETCH_PROCESSES_ERR, | |||
| FETCH_PROCESSES_SUCCESS, | |||
| PUT_PROCESS_ERR, | |||
| PUT_PROCESS_SUCCESS | |||
| } from "../../actions/processes/processesActionConstants"; | |||
| import createReducer from "../../utils/createReducer"; | |||
| const initialState = { | |||
| processes: [], | |||
| doneProcess: false, | |||
| errorMessage: "", | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [FETCH_PROCESSES_SUCCESS]: setStateProcesses, | |||
| [FETCH_PROCESSES_ERR]: setProcessesErrorMessage, | |||
| [PUT_PROCESS_SUCCESS]: setStateDoneProcess, | |||
| [PUT_PROCESS_ERR]: setDoneProcessErrorMessage, | |||
| }, | |||
| initialState | |||
| ); | |||
| function setStateProcesses(state, action) { | |||
| return { | |||
| ...state, | |||
| processes: action.payload, | |||
| }; | |||
| } | |||
| function setProcessesErrorMessage(state, action) { | |||
| return { | |||
| ...state, | |||
| errorMessage: action.payload, | |||
| }; | |||
| } | |||
| function setStateDoneProcess(state, action) { | |||
| return { | |||
| ...state, | |||
| doneProcess: action.payload, | |||
| }; | |||
| } | |||
| function setDoneProcessErrorMessage(state, action) { | |||
| return { | |||
| ...state, | |||
| errorMessage: action.payload, | |||
| }; | |||
| } | |||
| @@ -3,12 +3,14 @@ import adsSaga from "./adsSaga"; | |||
| import candidatesSaga from './candidatesSaga'; | |||
| import loginSaga from "./loginSaga"; | |||
| import usersSaga from "./usersSaga"; | |||
| import processesSaga from "./processSaga"; | |||
| export default function* rootSaga() { | |||
| yield all([ | |||
| loginSaga(), | |||
| usersSaga(), | |||
| adsSaga(), | |||
| candidatesSaga() | |||
| candidatesSaga(), | |||
| processesSaga(), | |||
| ]); | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| import { all, call, put, takeLatest } from "redux-saga/effects"; | |||
| import { getAllLevels, doneProcess } from "../../request/processesReguest"; | |||
| import { setProcesses, setProcessesError, setDoneProcess, setDoneProcessError } from "../actions/processes/processesAction"; | |||
| import { FETCH_PROCESSES_REQ, PUT_PROCESS_REQ } from "../actions/processes/processesActionConstants"; | |||
| export function* getProcesses() { | |||
| try { | |||
| const result = yield call(getAllLevels); | |||
| yield put(setProcesses(result.data)); | |||
| } catch (error) { | |||
| yield put(setProcessesError(error)); | |||
| } | |||
| } | |||
| export function* finishProcess(payload) { | |||
| try { | |||
| const id = payload.payload.id; | |||
| const done = yield call(doneProcess,id); | |||
| yield put(setDoneProcess(done)); | |||
| } catch (error) { | |||
| yield put(setDoneProcessError(error)); | |||
| } | |||
| } | |||
| export default function* processesSaga() { | |||
| yield all([takeLatest(FETCH_PROCESSES_REQ, getProcesses)]); | |||
| yield all([takeLatest(PUT_PROCESS_REQ, finishProcess)]); | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| import { createSelector } from "@reduxjs/toolkit"; | |||
| export const processesSelector = (state) => state.processes; | |||
| export const selectProcesses = createSelector(processesSelector, (state) => state.processes); | |||
| export const selectProcessesError = createSelector( | |||
| processesSelector, | |||
| (state) => state.errorMessage | |||
| ); | |||
| export const doneProcessSelector = (state) => state.processes; | |||
| export const selectDoneProcess = createSelector(doneProcessSelector, (state) => state.processes); | |||
| export const selectDoneProcessError = createSelector( | |||
| doneProcessSelector, | |||
| (state) => state.errorMessage | |||
| ); | |||
| @@ -38,3 +38,13 @@ export function formatDateRange(dates) { | |||
| const end = formatDate(dates.end); | |||
| return i18next.t('common.date.range', { start, end }); | |||
| } | |||
| export function formatDateSrb(date) { | |||
| const dt = new Date(date); | |||
| return format(dt, 'dd.MM.'); | |||
| } | |||
| export function formatTimeSrb(date) { | |||
| const dt = new Date(date); | |||
| return format(dt, 'HH.mm.'); | |||
| } | |||