feature/fix_bugs-fe into FE_dev 3 years ago
| "yup": "^0.32.9" | "yup": "^0.32.9" | ||||
| }, | }, | ||||
| "scripts": { | "scripts": { | ||||
| "start": "react-scripts --openssl-legacy-provider start", | |||||
| "start": "react-scripts start", | |||||
| "build": "react-scripts build", | "build": "react-scripts build", | ||||
| "test": "react-scripts test", | "test": "react-scripts test", | ||||
| "eject": "react-scripts eject", | "eject": "react-scripts eject", |
| import reducer from "../../../store/reducers/loading/loadingReducer"; | |||||
| import expect from "expect"; | |||||
| import { setAppReady } from "../../../store/actions/app/appActions"; | |||||
| import { APP_LOADING } from "../../../store/actions/app/appActionConstants"; | |||||
| import { resetLoginState } from "../../../store/actions/login/loginActions"; | |||||
| describe("loading reducer", () => { | |||||
| it("should return the initial state", () => { | |||||
| expect(reducer(undefined, {})).toEqual({ | |||||
| [APP_LOADING]: true, | |||||
| }); | |||||
| }); | |||||
| it("should set loader to true", () => { | |||||
| expect(reducer(false, resetLoginState())).toEqual({ | |||||
| [APP_LOADING]: true, | |||||
| }); | |||||
| }); | |||||
| it("should set loader to false", () => { | |||||
| expect(reducer(true, setAppReady())).toEqual({ | |||||
| [APP_LOADING]: false, | |||||
| }); | |||||
| }); | |||||
| }); |
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | ||||
| describe("TableViewPage render tests", () => { | describe("TableViewPage render tests", () => { | ||||
| var props = { | |||||
| history: { | |||||
| replace: jest.fn(), | |||||
| push: jest.fn(), | |||||
| location: { | |||||
| pathname: "/candidates", | |||||
| }, | |||||
| }, | |||||
| setPage: jest.fn(), | |||||
| sliderValue: [0, 2], | |||||
| startingDate: "", | |||||
| endingDate: "", | |||||
| typesOfEmployments: [], | |||||
| technologie: [], | |||||
| page: 1, | |||||
| search: "", | |||||
| }; | |||||
| const cont = ( | const cont = ( | ||||
| <redux.Provider store={store}> | <redux.Provider store={store}> | ||||
| <Router history={history}> | <Router history={history}> | ||||
| <TableViewPage page={1} search="" /> | |||||
| <TableViewPage {...props} /> | |||||
| </Router> | </Router> | ||||
| </redux.Provider> | </redux.Provider> | ||||
| ); | ); |
| expect( | expect( | ||||
| container | container | ||||
| .getElementsByClassName("ads-candidates")[0] | .getElementsByClassName("ads-candidates")[0] | ||||
| .getElementsByClassName("slick-active")[3] | |||||
| .getElementsByClassName("slick-active")[0] | |||||
| .getElementsByClassName("candidate-card-container")[0] | .getElementsByClassName("candidate-card-container")[0] | ||||
| .getElementsByClassName("candidate-card-applicant-name")[0] | .getElementsByClassName("candidate-card-applicant-name")[0] | ||||
| .textContent | .textContent | ||||
| ).toBe( | ).toBe( | ||||
| mockState.candidates.adsCandidates[0].applicants[4].firstName + | |||||
| mockState.candidates.adsCandidates[0].applicants[3].firstName + | |||||
| " " + | " " + | ||||
| mockState.candidates.adsCandidates[0].applicants[4].lastName | |||||
| mockState.candidates.adsCandidates[0].applicants[3].lastName | |||||
| ) | ) | ||||
| ); | ); | ||||
| }); | }); |
| isChecked: true, | isChecked: true, | ||||
| }, | }, | ||||
| ], | ], | ||||
| startingDate: "", | |||||
| endingDate: "", | |||||
| typesOfEmployments: [], | |||||
| }; | }; | ||||
| const cont = ( | const cont = ( | ||||
| expect(btn).toBeDefined(); | expect(btn).toBeDefined(); | ||||
| }); | }); | ||||
| }); | }); | ||||
| it("Should change ending date", async () => { | |||||
| render(cont); | |||||
| const input = screen.getByTestId("filter-date-container-ending-date"); | |||||
| waitFor(() => { | |||||
| fireEvent.change(input, { target: { value: "2024-05-24" } }); | |||||
| expect(input).toBeDefined(); | |||||
| }); | |||||
| }); | |||||
| }); | }); |
| import history from "../../store/utils/history"; | import history from "../../store/utils/history"; | ||||
| import TableViewPage from "../../pages/CandidatesPage/TableViewPage"; | import TableViewPage from "../../pages/CandidatesPage/TableViewPage"; | ||||
| import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | ||||
| import axios from "axios"; | |||||
| // import mockAxios from "jest-mock-axios"; | |||||
| import { getCV } from "../../request/candidatesRequest"; | import { getCV } from "../../request/candidatesRequest"; | ||||
| describe("TableViewPage render tests", () => { | describe("TableViewPage render tests", () => { | ||||
| }, | }, | ||||
| }, | }, | ||||
| setPage: jest.fn(), | setPage: jest.fn(), | ||||
| sliderValue: [0, 2], | |||||
| startingDate: "", | |||||
| endingDate: "", | |||||
| typesOfEmployments: [], | |||||
| technologie: [], | |||||
| page: 1, | |||||
| }; | }; | ||||
| const cont = ( | const cont = ( | ||||
| ).toBe("0"); | ).toBe("0"); | ||||
| }); | }); | ||||
| it("When user change table page function for fetching users should be called", async () => { | |||||
| const { container } = render(cont); | |||||
| const pag = container | |||||
| .getElementsByClassName("MuiPagination-ul")[0] | |||||
| .getElementsByTagName("li")[1] | |||||
| .querySelector("button"); | |||||
| fireEvent.click(pag); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(2)); | |||||
| }); | |||||
| // How to mock constant? | |||||
| // it("When user change table page, function for fetching users should be called", async () => { | |||||
| // const { container } = render(cont); | |||||
| // const pag = container | |||||
| // .getElementsByClassName("MuiPagination-ul")[0] | |||||
| // .getElementsByTagName("li")[1] | |||||
| // .querySelector("button"); | |||||
| // fireEvent.click(pag); | |||||
| // await waitFor(() => expect(mockDispatch).toBeCalledTimes(2)); | |||||
| // }); | |||||
| it("Should render CV of candidate after clicking on CV name", async () => { | it("Should render CV of candidate after clicking on CV name", async () => { | ||||
| let catchFn = jest.fn(); | let catchFn = jest.fn(); | ||||
| const basse64Pdf = `JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHl | |||||
| wZSAvQ2F0YWxvZw0KL091dGxpbmVzIDIgMCBSDQovUGFnZXMgMyAwIFINCj4+DQplbmRvYmoNCg0KMiAwIG9iag0KPDwNCi9UeXBlIC9PdXR | |||||
| saW5lcw0KL0NvdW50IDANCj4+DQplbmRvYmoNCg0KMyAwIG9iag0KPDwNCi9UeXBlIC9QYWdlcw0KL0NvdW50IDINCi9LaWRzIFsgNCAwIFIgNi | |||||
| AwIFIgXSANCj4+DQplbmRvYmoNCg0KNCAwIG9iag0KPDwNCi9UeXBlIC9QYWdlDQovUGFyZW50IDMgMCBSDQovUmVzb3VyY2VzIDw8DQovRm9udCA8PA0KL0YxID | |||||
| kgMCBSIA0KPj4NCi9Qcm9jU2V0IDggMCBSDQo+Pg0KL01lZGlhQm94IFswIDAgNjEyLjAwMDAgNzkyLjAwMDBdDQovQ29udGVudHMgNSAwIFINCj4+DQplbmRvYmo | |||||
| NCg0KNSAwIG9iag0KPDwgL0xlbmd0aCAxMDc0ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0K | |||||
| KCBBIFNpbXBsZSBQREYgRmlsZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIFRoaXMgaXMgYSBzbWFsbCBkZW1vbnN0cm | |||||
| F0aW9uIC5wZGYgZmlsZSAtICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjY0LjcwNDAgVGQNCigganVzdCBmb3IgdXNlIGluIHRoZSBWaXJ0dWFs | |||||
| IE1lY2hhbmljcyB0dXRvcmlhbHMuIE1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NTIuNzUyMCBUZA0KKCB0ZXh | |||||
| 0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDYyOC44NDgwIFRkDQ | |||||
| ooIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgV | |||||
| GYNCjY5LjI1MDAgNjE2Ljg5NjAgVGQNCiggdGV4dC4gQW5kIG1vcmUgdGV4dC4gQm9yaW5nLCB6enp6ei4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5 | |||||
| kICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjA0Ljk0NDAgVGQNCiggbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbm | |||||
| QgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDU5Mi45OTIwIFRkDQooIEFuZCBtb3JlIHRleHQuIEFu | |||||
| ZCBtb3JlIHRleHQuICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNTY5LjA4ODAgVGQNCiggQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW | |||||
| 5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA1NTcuMTM2MCBUZA0KKCB0ZXh0LiB | |||||
| BbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBFdmVuIG1vcmUuIENvbnRpbnVlZCBvbiBwYWdlIDIgLi4uKSBUag0KRVQNCmVuZHN0cmVhbQ0KZW5kb2JqDQoNC | |||||
| jYgMCBvYmoNCjw8DQovVHlwZSAvUGFnZQ0KL1BhcmVudCAzIDAgUg0KL1Jlc291cmNlcyA8PA0KL0ZvbnQgPDwNCi9GMSA5IDAgUiANCj4+DQovUHJvY1NldCA4IDA | |||||
| gUg0KPj4NCi9NZWRpYUJveCBbMCAwIDYxMi4wMDAwIDc5Mi4wMDAwXQ0KL0NvbnRlbnRzIDcgMCBSDQo+Pg0KZW5kb2JqDQoNCjcgMCBvYmoNCjw8IC9MZW5ndGggN | |||||
| jc2ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0KKCBTaW1wbGUgUERGIEZpbGUgMiApIFRqDQp | |||||
| FVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIC4uLmNvbnRpbnVlZCBmcm9tIHBhZ2UgMS4gWWV0IG1vcmUgdGV4dC4gQW5kIG1vcmUgd | |||||
| GV4dC4gQW5kIG1vcmUgdGV4dC4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NzYuNjU2MCBUZA0KKCBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB | |||||
| 0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY2NC43MDQwIFRkDQooIH | |||||
| RleHQuIE9oLCBob3cgYm9yaW5nIHR5cGluZyB0aGlzIHN0dWZmLiBCdXQgbm90IGFzIGJvcmluZyBhcyB3YXRjaGluZyApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRm | |||||
| DQo2OS4yNTAwIDY1Mi43NTIwIFRkDQooIHBhaW50IGRyeS4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC | |||||
| 4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NDAuODAwMCBUZA0KKCBCb3JpbmcuICBNb3JlLCBhIGxpdHRsZSBtb3JlIHRleHQuIFRoZSBlbmQs | |||||
| IGFuZCBqdXN0IGFzIHdlbGwuICkgVGoNCkVUDQplbmRzdHJlYW0NCmVuZG9iag0KDQo4IDAgb2JqDQpbL1BERiAvVGV4dF0NCmVuZG9iag0KDQo5IDAgb2JqDQo8PA0 | |||||
| KL1R5cGUgL0ZvbnQNCi9TdWJ0eXBlIC9UeXBlMQ0KL05hbWUgL0YxDQovQmFzZUZvbnQgL0hlbHZldGljYQ0KL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcNCj4+D | |||||
| QplbmRvYmoNCg0KMTAgMCBvYmoNCjw8DQovQ3JlYXRvciAoUmF2ZSBcKGh0dHA6Ly93d3cubmV2cm9uYS5jb20vcmF2ZVwpKQ0KL1Byb2R1Y2VyIChOZXZyb25hIER | |||||
| lc2lnbnMpDQovQ3JlYXRpb25EYXRlIChEOjIwMDYwMzAxMDcyODI2KQ0KPj4NCmVuZG9iag0KDQp4cmVmDQowIDExDQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwM | |||||
| DAwMTkgMDAwMDAgbg0KMDAwMDAwMDA5MyAwMDAwMCBuDQowMDAwMDAwMTQ3IDAwMDAwIG4NCjAwMDAwMDAyMjIgMDAwMDAgbg0KMDAwMDAwMDM5MCAwMDAwMCBuDQow | |||||
| MDAwMDAxNTIyIDAwMDAwIG4NCjAwMDAwMDE2OTAgMDAwMDAgbg0KMDAwMDAwMjQyMyAwMDAwMCBuDQowMDAwMDAyNDU2IDAwMDAwIG4NCjAwMDAwMDI1NzQgMDAwMD | |||||
| Agbg0KDQp0cmFpbGVyDQo8PA0KL1NpemUgMTENCi9Sb290IDEgMCBSDQovSW5mbyAxMCAwIFINCj4+DQoNCnN0YXJ0eHJlZg0KMjcxNA0KJSVFT0YNCg==`; | |||||
| const basse64Pdf = "some base64 string"; | |||||
| getCV("name od pdf file") | getCV("name od pdf file") | ||||
| .then(() => basse64Pdf) | .then(() => basse64Pdf) | ||||
| .catch(catchFn); | .catch(catchFn); | ||||
| .getElementsByTagName("span")[0] | .getElementsByTagName("span")[0] | ||||
| ); | ); | ||||
| waitFor(() => | |||||
| waitFor(() => { | |||||
| expect( | expect( | ||||
| container.getElementsByClassName("candidates-cv")[0].style.opacity | container.getElementsByClassName("candidates-cv")[0].style.opacity | ||||
| ).toBe("1") | |||||
| ); | |||||
| ).toBe("1"); | |||||
| }); | |||||
| }); | }); | ||||
| }); | }); |
| .candidates-pagination { | .candidates-pagination { | ||||
| margin-top: 20px; | margin-top: 20px; | ||||
| margin-left: 350px; | margin-left: 350px; | ||||
| padding-bottom: 20px; | |||||
| } | } | ||||
| .candidates-cv { | .candidates-cv { | ||||
| .left-move-candidateAd-page { | .left-move-candidateAd-page { | ||||
| margin-left: -12px; | margin-left: -12px; | ||||
| } | } | ||||
| .candidates-pagination { | |||||
| margin-left: 55px; | |||||
| } | |||||
| } | } |
| import x from "../../assets/images/x.png"; | import x from "../../assets/images/x.png"; | ||||
| import { | import { | ||||
| filterCandidates, | filterCandidates, | ||||
| fetchAdsCandidates | |||||
| fetchAdsCandidates, | |||||
| } from "../../store/actions/candidates/candidatesActions"; | } from "../../store/actions/candidates/candidatesActions"; | ||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { formatDateInput } from "../../util/helpers/dateHelpers"; | import { formatDateInput } from "../../util/helpers/dateHelpers"; | ||||
| import { changeIsCheckedValue,resetIsCheckedValue } from "../../store/actions/technologies/technologiesActions"; | |||||
| import { | |||||
| changeIsCheckedValue, | |||||
| resetIsCheckedValue, | |||||
| } from "../../store/actions/technologies/technologiesActions"; | |||||
| const CandidateFilters = ({ | const CandidateFilters = ({ | ||||
| open, | open, | ||||
| currentPage, | currentPage, | ||||
| isTableView, | isTableView, | ||||
| technologies, | technologies, | ||||
| sliderValue, | |||||
| startingDate, | |||||
| endingDate, | |||||
| typesOfEmployments, | |||||
| setSliderValue, | |||||
| setStartingDate, | |||||
| setEndingDate, | |||||
| setTypesOfEmployments, | |||||
| }) => { | }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const [sliderValue, setSliderValue] = useState([0, 0]); | |||||
| const [startingDate, setStartingDate] = useState(""); | |||||
| const [endingDate, setEndingDate] = useState(""); | |||||
| const [typesOfEmployments, setTypesOfEmployments] = useState([ | |||||
| { name: "Posao", isChecked: false }, | |||||
| { name: "Intership", isChecked: false }, | |||||
| ]); | |||||
| const [isInitial, setIsInitial] = useState(true) | |||||
| const [isInitial, setIsInitial] = useState(true); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| // console.log(isTableView); | |||||
| }, [isTableView]); | }, [isTableView]); | ||||
| const handleSliderChange = (_, newValue) => { | const handleSliderChange = (_, newValue) => { | ||||
| { name: "Posao", isChecked: false }, | { name: "Posao", isChecked: false }, | ||||
| { name: "Intership", isChecked: false }, | { name: "Intership", isChecked: false }, | ||||
| ]); | ]); | ||||
| setSliderValue([0,0]) | |||||
| setEndingDate("") | |||||
| setStartingDate("") | |||||
| setSliderValue([0, 0]); | |||||
| setEndingDate(""); | |||||
| setStartingDate(""); | |||||
| }; | }; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if(isInitial) { | |||||
| setIsInitial(false) | |||||
| if (isInitial) { | |||||
| setIsInitial(false); | |||||
| return; | return; | ||||
| } | } | ||||
| dispatch(resetIsCheckedValue()) | |||||
| dispatch(resetIsCheckedValue()); | |||||
| resetFilters(); | resetFilters(); | ||||
| }, [isTableView]) | |||||
| }, [isTableView]); | |||||
| const updateTypeState = (name, value) => { | const updateTypeState = (name, value) => { | ||||
| const newState = typesOfEmployments.map((obj) => { | const newState = typesOfEmployments.map((obj) => { | ||||
| }; | }; | ||||
| const isThereSelectedFilter = () => { | const isThereSelectedFilter = () => { | ||||
| let tech = technologies.filter(t => t.isChecked === true); | |||||
| if(tech && tech.length > 0){ | |||||
| let tech = technologies.filter((t) => t.isChecked === true); | |||||
| if (tech && tech.length > 0) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| let k = typesOfEmployments.filter(te => te.isChecked === true) | |||||
| if(k && k.length > 0){ | |||||
| return true | |||||
| let k = typesOfEmployments.filter((te) => te.isChecked === true); | |||||
| if (k && k.length > 0) { | |||||
| return true; | |||||
| } | } | ||||
| if(sliderValue[0] !== 0 || sliderValue[1] !== 0) { | |||||
| return true | |||||
| if (sliderValue[0] !== 0 || sliderValue[1] !== 0) { | |||||
| return true; | |||||
| } | } | ||||
| if(startingDate !== "" || endingDate !== ""){ | |||||
| if (startingDate !== "" || endingDate !== "") { | |||||
| return true; | return true; | ||||
| } | } | ||||
| return false | |||||
| } | |||||
| return false; | |||||
| }; | |||||
| const fiterItems = () => { | const fiterItems = () => { | ||||
| const tech = technologies | const tech = technologies | ||||
| const selectedEmploymentType = getSelectedEmploymentType(); | const selectedEmploymentType = getSelectedEmploymentType(); | ||||
| isTableView ? | |||||
| dispatch( | |||||
| filterCandidates({ | |||||
| pageSize, | |||||
| currentPage, | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType:selectedEmploymentType && selectedEmploymentType.length === 0 ? "" : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ) : | |||||
| dispatch( | |||||
| fetchAdsCandidates({ | |||||
| pageSize, | |||||
| currentPage, | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType:selectedEmploymentType && selectedEmploymentType.length === 0 ? "" : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| isTableView | |||||
| ? dispatch( | |||||
| filterCandidates({ | |||||
| pageSize, | |||||
| currentPage, | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType: | |||||
| selectedEmploymentType && selectedEmploymentType.length === 0 | |||||
| ? "" | |||||
| : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ) | |||||
| : dispatch( | |||||
| fetchAdsCandidates({ | |||||
| pageSize, | |||||
| currentPage, | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType: | |||||
| selectedEmploymentType && selectedEmploymentType.length === 0 | |||||
| ? "" | |||||
| : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| }; | }; | ||||
| const handleChangeStartingDate = (event) => { | const handleChangeStartingDate = (event) => { | ||||
| // console.log(event); | |||||
| setStartingDate(event.target.value); | setStartingDate(event.target.value); | ||||
| }; | }; | ||||
| const handleChangeEndingDate = (event) => { | const handleChangeEndingDate = (event) => { | ||||
| // console.log(event); | |||||
| setEndingDate(event.target.value); | setEndingDate(event.target.value); | ||||
| }; | }; | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div className="ad-filters-search" style={{ marginTop: "45px" }}> | <div className="ad-filters-search" style={{ marginTop: "45px" }}> | ||||
| <button className="c-btn c-btn--primary" onClick={fiterItems} disabled={!isThereSelectedFilter()}> | |||||
| <button | |||||
| className="c-btn c-btn--primary" | |||||
| onClick={fiterItems} | |||||
| disabled={!isThereSelectedFilter()} | |||||
| > | |||||
| Pretrazi | Pretrazi | ||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| pageSize: PropType.number, | pageSize: PropType.number, | ||||
| isTableView: PropType.bool, | isTableView: PropType.bool, | ||||
| technologies: PropType.array, | technologies: PropType.array, | ||||
| sliderValue: PropType.array, | |||||
| startingDate: PropType.string, | |||||
| endingDate: PropType.string, | |||||
| typesOfEmployments: PropType.array, | |||||
| setSliderValue: PropType.func, | |||||
| setStartingDate: PropType.func, | |||||
| setEndingDate: PropType.func, | |||||
| setTypesOfEmployments: PropType.func, | |||||
| }; | }; | ||||
| export default CandidateFilters; | export default CandidateFilters; |
| /* istanbul ignore file */ | /* istanbul ignore file */ | ||||
| export const PAGE_SIZE_CANDIDATES = 9; | |||||
| export const PAGE_SIZE_CANDIDATES = 12; |
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| { | |||||
| applicantId: 66, | |||||
| firstName: "dasd", | |||||
| lastName: "dasdas", | |||||
| dateOfApplication: "2022-02-11T00:00:00", | |||||
| cv: "link", | |||||
| experience: 1, | |||||
| technologyApplicants: [ | |||||
| { | |||||
| technology: { | |||||
| technologyId: 1, | |||||
| technologyType: "Backend", | |||||
| name: ".NET", | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| ], | ], | ||||
| nubmerOfApplicants: 5, | |||||
| nubmerOfApplicants: 6, | |||||
| }, | }, | ||||
| { | { | ||||
| id: 2, | id: 2, |
| dots: false, | dots: false, | ||||
| infinite: false, | infinite: false, | ||||
| speed: 400, | speed: 400, | ||||
| slidesToShow: 4, | |||||
| slidesToScroll: 4, | |||||
| slidesToShow: 3, | |||||
| slidesToScroll: 3, | |||||
| initialSlide: 0, | initialSlide: 0, | ||||
| arrows: true, | arrows: true, | ||||
| variableWidth: true, | variableWidth: true, | ||||
| { | { | ||||
| breakpoint: 1024, | breakpoint: 1024, | ||||
| settings: { | settings: { | ||||
| slidesToShow: 3, | |||||
| slidesToScroll: 3, | |||||
| slidesToShow: 2, | |||||
| slidesToScroll: 2, | |||||
| infinite: true, | infinite: true, | ||||
| dots: false, | dots: false, | ||||
| }, | }, | ||||
| { | { | ||||
| breakpoint: 900, | breakpoint: 900, | ||||
| settings: { | settings: { | ||||
| slidesToShow: 2, | |||||
| slidesToScroll: 2, | |||||
| slidesToShow: 1, | |||||
| slidesToScroll: 1, | |||||
| initialSlide: 0, | initialSlide: 0, | ||||
| }, | }, | ||||
| }, | }, | ||||
| <button onClick={() => activeAdsArrowLeftHandler(index)}> | <button onClick={() => activeAdsArrowLeftHandler(index)}> | ||||
| <img src={arrow_left} alt="arrow-left" /> | <img src={arrow_left} alt="arrow-left" /> | ||||
| </button> | </button> | ||||
| <button onClick={() => activeAdsArrowRightHandler(index)} className="kp"> | |||||
| <button | |||||
| onClick={() => activeAdsArrowRightHandler(index)} | |||||
| className="kp" | |||||
| > | |||||
| <img src={arrow_right} alt="arrow-right" /> | <img src={arrow_right} alt="arrow-right" /> | ||||
| </button> | </button> | ||||
| </div> | </div> |
| const [search, setSearch] = useState(""); | const [search, setSearch] = useState(""); | ||||
| const [isSearchFieldVisible, setIsSearchFieldVisible] = useState(false); | const [isSearchFieldVisible, setIsSearchFieldVisible] = useState(false); | ||||
| const [sliderValue, setSliderValue] = useState([0, 0]); | |||||
| const [startingDate, setStartingDate] = useState(""); | |||||
| const [endingDate, setEndingDate] = useState(""); | |||||
| const [typesOfEmployments, setTypesOfEmployments] = useState([ | |||||
| { name: "Posao", isChecked: false }, | |||||
| { name: "Intership", isChecked: false }, | |||||
| ]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(setTechnologiesReq()); | dispatch(setTechnologiesReq()); | ||||
| }, []); | }, []); | ||||
| currentPage={page} | currentPage={page} | ||||
| isTableView={isTableView} | isTableView={isTableView} | ||||
| technologies={technologies} | technologies={technologies} | ||||
| sliderValue={sliderValue} | |||||
| startingDate={startingDate} | |||||
| endingDate={endingDate} | |||||
| typesOfEmployments={typesOfEmployments} | |||||
| setSliderValue={setSliderValue} | |||||
| setStartingDate={setStartingDate} | |||||
| setEndingDate={setEndingDate} | |||||
| setTypesOfEmployments={setTypesOfEmployments} | |||||
| /> | /> | ||||
| <div className="l-t-rectangle"></div> | <div className="l-t-rectangle"></div> | ||||
| <div className="r-b-rectangle"></div> | <div className="r-b-rectangle"></div> | ||||
| page={page} | page={page} | ||||
| setPage={setPage} | setPage={setPage} | ||||
| search={search} | search={search} | ||||
| sliderValue={sliderValue} | |||||
| startingDate={startingDate} | |||||
| endingDate={endingDate} | |||||
| typesOfEmployments={typesOfEmployments} | |||||
| technologies={technologies} | |||||
| /> | /> | ||||
| ) : ( | ) : ( | ||||
| <AdsCandidatesPage history={history} search={search} /> | <AdsCandidatesPage history={history} search={search} /> |
| } from "../../store/selectors/candidatesSelectors"; | } from "../../store/selectors/candidatesSelectors"; | ||||
| import { getCV } from "../../request/candidatesRequest"; | import { getCV } from "../../request/candidatesRequest"; | ||||
| import Fade from "@mui/material/Fade"; | import Fade from "@mui/material/Fade"; | ||||
| const TableViewPage = ({ | const TableViewPage = ({ | ||||
| history, | history, | ||||
| setPage, | setPage, | ||||
| page, | page, | ||||
| search, | search, | ||||
| sliderValue, | |||||
| startingDate, | |||||
| endingDate, | |||||
| typesOfEmployments, | |||||
| technologies, | |||||
| }) => { | }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const candidates = useSelector(selectCandidates); | const candidates = useSelector(selectCandidates); | ||||
| ); | ); | ||||
| }, [dispatch]); | }, [dispatch]); | ||||
| const getSelectedEmploymentType = () => { | |||||
| return typesOfEmployments.filter((e) => e.isChecked === true); | |||||
| }; | |||||
| const selectedEmploymentType = getSelectedEmploymentType(); | |||||
| const handleChange = (_, value) => { | const handleChange = (_, value) => { | ||||
| dispatch( | dispatch( | ||||
| filterCandidates({ | filterCandidates({ | ||||
| currentPage: value, | currentPage: value, | ||||
| pageSize: PAGE_SIZE_CANDIDATES, | pageSize: PAGE_SIZE_CANDIDATES, | ||||
| minExperience: 0, | |||||
| maxExperience: 0, | |||||
| employmentType: "", | |||||
| minDateOfApplication: "", | |||||
| maxDateOfApplication: "", | |||||
| technologies: [], | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType: | |||||
| selectedEmploymentType && selectedEmploymentType.length === 0 | |||||
| ? "" | |||||
| : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: technologies | |||||
| .filter((tech) => tech.isChecked === true) | |||||
| .map((tech) => tech.name), | |||||
| }) | }) | ||||
| ); | ); | ||||
| setPage(value); | setPage(value); | ||||
| }); | }); | ||||
| }; | }; | ||||
| const filterCandidatesByName = () => { | |||||
| return candidates.filter((n) => | |||||
| (n.firstName + " " + n.lastName) | |||||
| .toLowerCase() | |||||
| .includes(search.toLowerCase()) | |||||
| ); | |||||
| }; | |||||
| return ( | return ( | ||||
| <div className="candidates-table"> | <div className="candidates-table"> | ||||
| <div | <div | ||||
| overflowX: "auto", | overflowX: "auto", | ||||
| marginLeft: matches ? 36 : 72, | marginLeft: matches ? 36 : 72, | ||||
| display: "flex", | display: "flex", | ||||
| justifyContent:'space-between' | |||||
| justifyContent: "space-between", | |||||
| }} | }} | ||||
| > | > | ||||
| <table | <table | ||||
| className="usersTable" | className="usersTable" | ||||
| style={{ width: isCVDisplayed ? "784px" : "914px" }} | |||||
| style={{ | |||||
| width: isCVDisplayed ? "784px" : "914px", | |||||
| height: "fit-content", | |||||
| }} | |||||
| > | > | ||||
| <thead> | <thead> | ||||
| <tr className="headingRow"> | <tr className="headingRow"> | ||||
| </thead> | </thead> | ||||
| <tbody> | <tbody> | ||||
| {candidates && | {candidates && | ||||
| candidates | |||||
| .filter((n) => | |||||
| (n.firstName + " " + n.lastName) | |||||
| .toLowerCase() | |||||
| .includes(search.toLowerCase()) | |||||
| ) | |||||
| .map((candidate, index) => ( | |||||
| <tr | |||||
| key={index} | |||||
| className="secondaryRow cadidate-row" | |||||
| style={{ | |||||
| cursor: "pointer", | |||||
| }} | |||||
| onClick={() => | |||||
| navigateToCandidateDetailsPage(candidate.applicantId) | |||||
| } | |||||
| > | |||||
| <td> | |||||
| {( | |||||
| candidate.firstName + | |||||
| " " + | |||||
| candidate.lastName | |||||
| ).includes(search) ? ( | |||||
| formatLabel( | |||||
| candidate.firstName + " " + candidate.lastName, | |||||
| search | |||||
| ) | |||||
| ) : ( | |||||
| <span> | |||||
| {candidate.firstName + " " + candidate.lastName} | |||||
| </span> | |||||
| )} | |||||
| </td> | |||||
| {!isCVDisplayed && ( | |||||
| <td style={{ paddingLeft: 80 }}> | |||||
| {candidate.experience} | |||||
| </td> | |||||
| )} | |||||
| <td style={{ paddingLeft: 55 }}> | |||||
| {formatDate(candidate.dateOfApplication)} | |||||
| </td> | |||||
| <td>{candidate.position}</td> | |||||
| <td> | |||||
| <span | |||||
| onClick={(e) => onClickCV(e, candidate.cv)} | |||||
| className="cvLink" | |||||
| > | |||||
| {candidate.firstName} | |||||
| {candidate.lastName}.pdf | |||||
| filterCandidatesByName().map((candidate, index) => ( | |||||
| <tr | |||||
| key={index} | |||||
| className="secondaryRow cadidate-row" | |||||
| style={{ | |||||
| cursor: "pointer", | |||||
| }} | |||||
| onClick={() => | |||||
| navigateToCandidateDetailsPage(candidate.applicantId) | |||||
| } | |||||
| > | |||||
| <td> | |||||
| {(candidate.firstName + " " + candidate.lastName).includes( | |||||
| search | |||||
| ) ? ( | |||||
| formatLabel( | |||||
| candidate.firstName + " " + candidate.lastName, | |||||
| search | |||||
| ) | |||||
| ) : ( | |||||
| <span> | |||||
| {candidate.firstName + " " + candidate.lastName} | |||||
| </span> | </span> | ||||
| </td> | |||||
| </tr> | |||||
| ))} | |||||
| )} | |||||
| </td> | |||||
| {!isCVDisplayed && ( | |||||
| <td style={{ paddingLeft: 80 }}>{candidate.experience}</td> | |||||
| )} | |||||
| <td style={{ paddingLeft: 55 }}> | |||||
| {formatDate(candidate.dateOfApplication)} | |||||
| </td> | |||||
| <td>{candidate.position}</td> | |||||
| <td> | |||||
| <span | |||||
| onClick={(e) => onClickCV(e, candidate.cv)} | |||||
| className="cvLink" | |||||
| > | |||||
| {candidate.firstName} | |||||
| {candidate.lastName}.pdf | |||||
| </span> | |||||
| </td> | |||||
| </tr> | |||||
| ))} | |||||
| </tbody> | </tbody> | ||||
| </table> | </table> | ||||
| <Fade in={isCVDisplayed} timeout={400}> | <Fade in={isCVDisplayed} timeout={400}> | ||||
| <embed src={`data:application/pdf;base64,${linkToCV}`} className="candidates-cv"/> | |||||
| <embed | |||||
| src={`data:application/pdf;base64,${linkToCV}`} | |||||
| className="candidates-cv" | |||||
| /> | |||||
| </Fade> | </Fade> | ||||
| </div> | </div> | ||||
| <Pagination | |||||
| size={matches ? "small" : "medium"} | |||||
| count={ | |||||
| parseInt(pagination) <= PAGE_SIZE_CANDIDATES | |||||
| ? 1 | |||||
| : Math.ceil(parseInt(pagination) / PAGE_SIZE_CANDIDATES) | |||||
| } | |||||
| color="primary" | |||||
| className="candidates-pagination" | |||||
| onChange={handleChange} | |||||
| shape="rounded" | |||||
| /> | |||||
| {search.length > 0 ? ( | |||||
| "" | |||||
| ) : ( | |||||
| <Pagination | |||||
| size={matches ? "small" : "medium"} | |||||
| count={ | |||||
| parseInt(pagination) <= PAGE_SIZE_CANDIDATES | |||||
| ? 1 | |||||
| : Math.ceil(parseInt(pagination) / PAGE_SIZE_CANDIDATES) | |||||
| } | |||||
| color="primary" | |||||
| className="candidates-pagination" | |||||
| onChange={handleChange} | |||||
| shape="rounded" | |||||
| /> | |||||
| )} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| }; | }; | ||||
| setPage: PropTypes.func, | setPage: PropTypes.func, | ||||
| page: PropTypes.number, | page: PropTypes.number, | ||||
| search: PropTypes.string, | search: PropTypes.string, | ||||
| sliderValue: PropTypes.array, | |||||
| startingDate: PropTypes.string, | |||||
| endingDate: PropTypes.string, | |||||
| typesOfEmployments: PropTypes.array, | |||||
| technologies: PropTypes.array, | |||||
| }; | }; | ||||
| export default TableViewPage; | export default TableViewPage; |
| }; | }; | ||||
| const goForwardOneMonth = () => { | const goForwardOneMonth = () => { | ||||
| // console.log(currentMonth) | |||||
| console.log(currentMonth); | |||||
| console.log(currentYear); | |||||
| dispatch( | dispatch( | ||||
| fetchSchedule({ | fetchSchedule({ | ||||
| month: currentMonth - 1 === -1 ? 12 : currentMonth + 2, | |||||
| year: currentMonth - 1 === -1 ? currentYear - 1 : currentYear, | |||||
| month: currentMonth + 1 === 12 ? 1 : currentMonth + 2, | |||||
| year: currentMonth + 1 === 12 ? currentYear + 1 : currentYear, | |||||
| }) | }) | ||||
| ); | ); | ||||
| setNumberOfDaysInMonth( | setNumberOfDaysInMonth( |
| import { | |||||
| deleteRequest, | |||||
| getRequest, | |||||
| patchRequest, | |||||
| replaceInUrl, | |||||
| postRequest, | |||||
| } from './index'; | |||||
| import apiEndpoints from './apiEndpoints'; | |||||
| export const getAccount = (accountUid) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.get, { accountUid })); | |||||
| export const getAccountUsers = (accountUid) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getUsers, { accountUid })); | |||||
| export const getUserPermissions = (currentAccountUid, currentUserUid) => | |||||
| getRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.getCurrentUserPermissions, { | |||||
| currentAccountUid, | |||||
| currentUserUid, | |||||
| }), | |||||
| ); | |||||
| export const getAccountAddresses = (accountUid) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getAddresses, { accountUid })); | |||||
| export const getAccountSettingsRequest = (accountUid) => | |||||
| getRequest(replaceInUrl(apiEndpoints.accounts.getSettings, { accountUid })); | |||||
| export const updateAccountAddressRequest = (accountUid, addressUid, data) => | |||||
| patchRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.updateAddress, { | |||||
| accountUid, | |||||
| addressUid, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const deleteAccountAddressRequest = (accountUid, addressUid) => | |||||
| deleteRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.deleteAddress, { | |||||
| accountUid, | |||||
| addressUid, | |||||
| }), | |||||
| ); | |||||
| export const postNewAccountUserRequest = (accountUid, data) => | |||||
| postRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.createUser, { | |||||
| accountUid, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const updateAccountUserRequest = ( | |||||
| accountUid, | |||||
| userUid, | |||||
| actionType, | |||||
| data, | |||||
| ) => | |||||
| patchRequest( | |||||
| replaceInUrl(apiEndpoints.accounts.updateUser, { | |||||
| accountUid, | |||||
| userUid, | |||||
| actionType, | |||||
| }), | |||||
| data, | |||||
| ); | |||||
| export const postAgreementRequest = (data) => | |||||
| postRequest(apiEndpoints.accounts.agreement, data); |