Selaa lähdekoodia

Merge branch 'feature/fix_bugs-fe' of Neca/HRCenter into FE_dev

pull/184/head
safet.purkovic 3 vuotta sitten
vanhempi
commit
48277448e1

+ 1
- 1
package.json Näytä tiedosto

@@ -49,7 +49,7 @@
"yup": "^0.32.9"
},
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",

+ 25
- 0
src/__tests__/ReduxTests/Reducers/loadingReducer.test.js Näytä tiedosto

@@ -0,0 +1,25 @@
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,
});
});
});

+ 18
- 1
src/__tests__/ReduxTests/tableViewPageReducer.test.js Näytä tiedosto

@@ -18,10 +18,27 @@ import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants";
import * as helper from "../../util/helpers/rejectErrorCodeHelper";

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 = (
<redux.Provider store={store}>
<Router history={history}>
<TableViewPage page={1} search="" />
<TableViewPage {...props} />
</Router>
</redux.Provider>
);

+ 3
- 3
src/__tests__/UITests/adsCandidatesPageUI.test.js Näytä tiedosto

@@ -78,14 +78,14 @@ describe("TableViewPage render tests", () => {
expect(
container
.getElementsByClassName("ads-candidates")[0]
.getElementsByClassName("slick-active")[3]
.getElementsByClassName("slick-active")[0]
.getElementsByClassName("candidate-card-container")[0]
.getElementsByClassName("candidate-card-applicant-name")[0]
.textContent
).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
)
);
});

+ 3
- 10
src/__tests__/UITests/candidateFilterUI.test.js Näytä tiedosto

@@ -22,6 +22,9 @@ describe("Add ad modals ui tests", () => {
isChecked: true,
},
],
startingDate: "",
endingDate: "",
typesOfEmployments: [],
};

const cont = (
@@ -66,14 +69,4 @@ describe("Add ad modals ui tests", () => {
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();
});
});
});

+ 20
- 47
src/__tests__/UITests/tableViewPageUI.test.js Näytä tiedosto

@@ -6,8 +6,6 @@ import { Router } from "react-router-dom";
import history from "../../store/utils/history";
import TableViewPage from "../../pages/CandidatesPage/TableViewPage";
import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants";
import axios from "axios";
// import mockAxios from "jest-mock-axios";
import { getCV } from "../../request/candidatesRequest";

describe("TableViewPage render tests", () => {
@@ -20,6 +18,12 @@ describe("TableViewPage render tests", () => {
},
},
setPage: jest.fn(),
sliderValue: [0, 2],
startingDate: "",
endingDate: "",
typesOfEmployments: [],
technologie: [],
page: 1,
};

const cont = (
@@ -110,51 +114,20 @@ describe("TableViewPage render tests", () => {
).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 () => {
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")
.then(() => basse64Pdf)
.catch(catchFn);
@@ -167,10 +140,10 @@ describe("TableViewPage render tests", () => {
.getElementsByTagName("span")[0]
);

waitFor(() =>
waitFor(() => {
expect(
container.getElementsByClassName("candidates-cv")[0].style.opacity
).toBe("1")
);
).toBe("1");
});
});
});

+ 1
- 4
src/assets/styles/components/_candidatesPage.scss Näytä tiedosto

@@ -270,6 +270,7 @@
.candidates-pagination {
margin-top: 20px;
margin-left: 350px;
padding-bottom: 20px;
}

.candidates-cv {
@@ -316,8 +317,4 @@
.left-move-candidateAd-page {
margin-left: -12px;
}

.candidates-pagination {
margin-left: 55px;
}
}

+ 77
- 60
src/components/Candidates/CandidateFilters.js Näytä tiedosto

@@ -10,11 +10,14 @@ import filterIcon from "../../assets/images/filter_vector.png";
import x from "../../assets/images/x.png";
import {
filterCandidates,
fetchAdsCandidates
fetchAdsCandidates,
} from "../../store/actions/candidates/candidatesActions";
import { useDispatch } from "react-redux";
import { formatDateInput } from "../../util/helpers/dateHelpers";
import { changeIsCheckedValue,resetIsCheckedValue } from "../../store/actions/technologies/technologiesActions";
import {
changeIsCheckedValue,
resetIsCheckedValue,
} from "../../store/actions/technologies/technologiesActions";

const CandidateFilters = ({
open,
@@ -23,19 +26,19 @@ const CandidateFilters = ({
currentPage,
isTableView,
technologies,
sliderValue,
startingDate,
endingDate,
typesOfEmployments,
setSliderValue,
setStartingDate,
setEndingDate,
setTypesOfEmployments,
}) => {
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(() => {
// console.log(isTableView);
}, [isTableView]);

const handleSliderChange = (_, newValue) => {
@@ -47,19 +50,19 @@ const CandidateFilters = ({
{ name: "Posao", isChecked: false },
{ name: "Intership", isChecked: false },
]);
setSliderValue([0,0])
setEndingDate("")
setStartingDate("")
setSliderValue([0, 0]);
setEndingDate("");
setStartingDate("");
};

useEffect(() => {
if(isInitial) {
setIsInitial(false)
if (isInitial) {
setIsInitial(false);
return;
}
dispatch(resetIsCheckedValue())
dispatch(resetIsCheckedValue());
resetFilters();
}, [isTableView])
}, [isTableView]);

const updateTypeState = (name, value) => {
const newState = typesOfEmployments.map((obj) => {
@@ -91,24 +94,24 @@ const CandidateFilters = ({
};

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;
}
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 false
}
return false;
};

const fiterItems = () => {
const tech = technologies
@@ -117,44 +120,46 @@ const CandidateFilters = ({

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) => {
// console.log(event);
setStartingDate(event.target.value);
};

const handleChangeEndingDate = (event) => {
// console.log(event);
setEndingDate(event.target.value);
};

@@ -272,7 +277,11 @@ const CandidateFilters = ({
</div>
</div>
<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
</button>
</div>
@@ -297,6 +306,14 @@ CandidateFilters.propTypes = {
pageSize: PropType.number,
isTableView: PropType.bool,
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;

+ 1
- 1
src/constants/keyCodeConstants.js Näytä tiedosto

@@ -1,2 +1,2 @@
/* istanbul ignore file */
export const PAGE_SIZE_CANDIDATES = 9;
export const PAGE_SIZE_CANDIDATES = 12;

+ 18
- 1
src/mockState.js Näytä tiedosto

@@ -583,8 +583,25 @@ export const mockState = {
},
],
},
{
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,

+ 10
- 7
src/pages/CandidatesPage/AdsCandidatesPage.js Näytä tiedosto

@@ -38,8 +38,8 @@ const AdsCandidatesPage = ({ history, search }) => {
dots: false,
infinite: false,
speed: 400,
slidesToShow: 4,
slidesToScroll: 4,
slidesToShow: 3,
slidesToScroll: 3,
initialSlide: 0,
arrows: true,
variableWidth: true,
@@ -47,8 +47,8 @@ const AdsCandidatesPage = ({ history, search }) => {
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
slidesToShow: 2,
slidesToScroll: 2,
infinite: true,
dots: false,
},
@@ -56,8 +56,8 @@ const AdsCandidatesPage = ({ history, search }) => {
{
breakpoint: 900,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
slidesToShow: 1,
slidesToScroll: 1,
initialSlide: 0,
},
},
@@ -120,7 +120,10 @@ const AdsCandidatesPage = ({ history, search }) => {
<button onClick={() => activeAdsArrowLeftHandler(index)}>
<img src={arrow_left} alt="arrow-left" />
</button>
<button onClick={() => activeAdsArrowRightHandler(index)} className="kp">
<button
onClick={() => activeAdsArrowRightHandler(index)}
className="kp"
>
<img src={arrow_right} alt="arrow-right" />
</button>
</div>

+ 21
- 0
src/pages/CandidatesPage/CandidatesPage.js Näytä tiedosto

@@ -26,6 +26,14 @@ const CandidatesPage = ({ history }) => {
const [search, setSearch] = useState("");
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(() => {
dispatch(setTechnologiesReq());
}, []);
@@ -73,6 +81,14 @@ const CandidatesPage = ({ history }) => {
currentPage={page}
isTableView={isTableView}
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="r-b-rectangle"></div>
@@ -192,6 +208,11 @@ const CandidatesPage = ({ history }) => {
page={page}
setPage={setPage}
search={search}
sliderValue={sliderValue}
startingDate={startingDate}
endingDate={endingDate}
typesOfEmployments={typesOfEmployments}
technologies={technologies}
/>
) : (
<AdsCandidatesPage history={history} search={search} />

+ 102
- 74
src/pages/CandidatesPage/TableViewPage.js Näytä tiedosto

@@ -14,12 +14,16 @@ import {
} from "../../store/selectors/candidatesSelectors";
import { getCV } from "../../request/candidatesRequest";
import Fade from "@mui/material/Fade";

const TableViewPage = ({
history,
setPage,
page,
search,
sliderValue,
startingDate,
endingDate,
typesOfEmployments,
technologies,
}) => {
const dispatch = useDispatch();
const candidates = useSelector(selectCandidates);
@@ -44,17 +48,28 @@ const TableViewPage = ({
);
}, [dispatch]);

const getSelectedEmploymentType = () => {
return typesOfEmployments.filter((e) => e.isChecked === true);
};

const selectedEmploymentType = getSelectedEmploymentType();

const handleChange = (_, value) => {
dispatch(
filterCandidates({
currentPage: value,
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);
@@ -98,6 +113,14 @@ const TableViewPage = ({
});
};

const filterCandidatesByName = () => {
return candidates.filter((n) =>
(n.firstName + " " + n.lastName)
.toLowerCase()
.includes(search.toLowerCase())
);
};

return (
<div className="candidates-table">
<div
@@ -105,12 +128,15 @@ const TableViewPage = ({
overflowX: "auto",
marginLeft: matches ? 36 : 72,
display: "flex",
justifyContent:'space-between'
justifyContent: "space-between",
}}
>
<table
className="usersTable"
style={{ width: isCVDisplayed ? "784px" : "914px" }}
style={{
width: isCVDisplayed ? "784px" : "914px",
height: "fit-content",
}}
>
<thead>
<tr className="headingRow">
@@ -123,77 +149,74 @@ const TableViewPage = ({
</thead>
<tbody>
{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>
</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>
</table>
<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>
</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>
);
};
@@ -209,6 +232,11 @@ TableViewPage.propTypes = {
setPage: PropTypes.func,
page: PropTypes.number,
search: PropTypes.string,
sliderValue: PropTypes.array,
startingDate: PropTypes.string,
endingDate: PropTypes.string,
typesOfEmployments: PropTypes.array,
technologies: PropTypes.array,
};

export default TableViewPage;

+ 4
- 3
src/pages/SchedulePage/SchedulePage.js Näytä tiedosto

@@ -91,11 +91,12 @@ const SchedulePage = ({ history }) => {
};

const goForwardOneMonth = () => {
// console.log(currentMonth)
console.log(currentMonth);
console.log(currentYear);
dispatch(
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(

+ 0
- 71
src/request/accountRequest.js Näytä tiedosto

@@ -1,71 +0,0 @@
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);

Loading…
Peruuta
Tallenna