| import React, { useState } from "react"; | |||||
| import CustomDrawer from "../UI/CustomDrawer"; | |||||
| import { Checkbox, FormControlLabel, FormGroup } from "@mui/material"; | |||||
| import PropTypes from "prop-types"; | |||||
| import { useDispatch } from "react-redux"; | |||||
| import { setFilteredPatternsReq } from "../../store/actions/patterns/patternsActions"; | |||||
| const PatternFilters = ({ | |||||
| openFilterDrawer, | |||||
| handleClose, | |||||
| selectionLevelFilter, | |||||
| onChangeFilterCheckboxes, | |||||
| }) => { | |||||
| const [fromDate, setFromDate] = useState(""); | |||||
| const [toDate, setToDate] = useState(""); | |||||
| const dispatch = useDispatch(); | |||||
| const submitFiltersHandler = (e) => { | |||||
| e.preventDefault(); | |||||
| const selectionLevels = selectionLevelFilter | |||||
| .filter((level) => level.isChecked === true) | |||||
| .map((level) => level.id); | |||||
| dispatch( | |||||
| setFilteredPatternsReq({ | |||||
| fromDate: fromDate === "" ? null : fromDate, | |||||
| toDate: toDate === "" ? null : toDate, | |||||
| selectionLevels, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| }; | |||||
| const handleApiResponseSuccess = () => { | |||||
| handleClose(); | |||||
| }; | |||||
| const hasSelectedFilters = () => { | |||||
| const checked = selectionLevelFilter.filter( | |||||
| (level) => level.isChecked === true | |||||
| ); | |||||
| if (checked.length > 0) { | |||||
| return true; | |||||
| } | |||||
| if (fromDate !== "") { | |||||
| return true; | |||||
| } | |||||
| if (toDate !== "") { | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| }; | |||||
| return ( | |||||
| <CustomDrawer | |||||
| title="Šabloni" | |||||
| open={openFilterDrawer} | |||||
| onCloseDrawer={handleClose} | |||||
| > | |||||
| <form onSubmit={submitFiltersHandler}> | |||||
| <div className="custom-drawer"> | |||||
| <div> | |||||
| <div className="custom-drawer-sub-card"> | |||||
| <div className="custom-drawer-sub-card-label"> | |||||
| <p>Kategorija</p> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card-content"> | |||||
| <FormGroup> | |||||
| {selectionLevelFilter.map((process) => ( | |||||
| <FormControlLabel | |||||
| key={process.id} | |||||
| control={ | |||||
| <Checkbox | |||||
| value={process.name} | |||||
| checked={process.isChecked} | |||||
| onChange={() => onChangeFilterCheckboxes(process.id)} | |||||
| /> | |||||
| } | |||||
| label={process.name} | |||||
| /> | |||||
| ))} | |||||
| </FormGroup> | |||||
| </div> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card"> | |||||
| <div className="custom-drawer-sub-card-label"> | |||||
| <p>Datum kreiranja</p> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card-content"> | |||||
| <FormGroup style={{ marginBottom: "9px" }}> | |||||
| <label className="custom-drawer-sub-card-content-sub-label"> | |||||
| Od | |||||
| </label> | |||||
| <input | |||||
| type="date" | |||||
| onChange={(e) => setFromDate(e.target.value)} | |||||
| value={fromDate} | |||||
| /> | |||||
| </FormGroup> | |||||
| <FormGroup> | |||||
| <label className="custom-drawer-sub-card-content-sub-label"> | |||||
| Do | |||||
| </label> | |||||
| <input | |||||
| type="date" | |||||
| onChange={(e) => setToDate(e.target.value)} | |||||
| value={toDate} | |||||
| /> | |||||
| </FormGroup> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className="custom-drawer-submit"> | |||||
| <button | |||||
| className="c-btn c-btn--primary" | |||||
| disabled={!hasSelectedFilters()} | |||||
| > | |||||
| Pretrazi | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </CustomDrawer> | |||||
| ); | |||||
| }; | |||||
| PatternFilters.propTypes = { | |||||
| openFilterDrawer: PropTypes.bool, | |||||
| handleClose: PropTypes.func, | |||||
| selectionLevelFilter: PropTypes.any, | |||||
| onChangeFilterCheckboxes: PropTypes.func, | |||||
| }; | |||||
| export default PatternFilters; |
| <button onClick={archiveAdsArrowLeftHandler}> | <button onClick={archiveAdsArrowLeftHandler}> | ||||
| <img src={arrow_left} alt="arrow-left" /> | <img src={arrow_left} alt="arrow-left" /> | ||||
| </button> | </button> | ||||
| <button onClick={archiveAdsArrowRightHandler}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| {ad.applicants.length > 3 && ( | |||||
| <button onClick={archiveAdsArrowRightHandler}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| )} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| )} | )} | ||||
| <button onClick={archiveAdsArrowLeftHandler}> | <button onClick={archiveAdsArrowLeftHandler}> | ||||
| <img src={arrow_left} alt="arrow-left" /> | <img src={arrow_left} alt="arrow-left" /> | ||||
| </button> | </button> | ||||
| <button onClick={archiveAdsArrowRightHandler}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| {ad.applicants.length > 3 && ( | |||||
| <button onClick={archiveAdsArrowRightHandler}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| )} | |||||
| </div> | </div> | ||||
| )} | )} | ||||
| </div> | </div> |
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import FilterButton from "../../components/Button/FilterButton"; | import FilterButton from "../../components/Button/FilterButton"; | ||||
| import { useTheme } from "@mui/system"; | import { useTheme } from "@mui/system"; | ||||
| import { | |||||
| Checkbox, | |||||
| FormControlLabel, | |||||
| FormGroup, | |||||
| IconButton, | |||||
| useMediaQuery, | |||||
| } from "@mui/material"; | |||||
| import { IconButton, useMediaQuery } from "@mui/material"; | |||||
| import userPageBtnIcon from "../../assets/images/userPageBtnIcon.png"; | import userPageBtnIcon from "../../assets/images/userPageBtnIcon.png"; | ||||
| import PatternCard from "../../components/Patterns/PatternCard"; | import PatternCard from "../../components/Patterns/PatternCard"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| import { setProcessesReq } from "../../store/actions/processes/processesAction"; | import { setProcessesReq } from "../../store/actions/processes/processesAction"; | ||||
| import { createPatternReq } from "../../store/actions/createPattern/createPatternActions"; | import { createPatternReq } from "../../store/actions/createPattern/createPatternActions"; | ||||
| import { updatePatternReq } from "../../store/actions/updatePattern/updatePatternActions"; | import { updatePatternReq } from "../../store/actions/updatePattern/updatePatternActions"; | ||||
| import CustomDrawer from "../../components/UI/CustomDrawer"; | |||||
| import PatternFilters from "../../components/Patterns/PatternFilters"; | |||||
| const PatternsPage = ({ history }) => { | const PatternsPage = ({ history }) => { | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const [addPatternTitle, setAddPatternTitle] = useState(""); | const [addPatternTitle, setAddPatternTitle] = useState(""); | ||||
| const [addPatternCategory, setAddPatternCategory] = useState(1); | const [addPatternCategory, setAddPatternCategory] = useState(1); | ||||
| const [addPatternMessage, setAddPatternMessage] = useState(""); | const [addPatternMessage, setAddPatternMessage] = useState(""); | ||||
| const [selectionLevelFilter, setSelectionLevelFilter] = useState([]); | |||||
| const patterns = useSelector(selectPatterns); | const patterns = useSelector(selectPatterns); | ||||
| const processes = useSelector(selectProcesses); | const processes = useSelector(selectProcesses); | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (processes.length > 0) { | if (processes.length > 0) { | ||||
| setAddPatternCategory(processes[0].id); | setAddPatternCategory(processes[0].id); | ||||
| const tmpSelectionLevelFilter = processes.map((level) => ({ | |||||
| ...level, | |||||
| isChecked: false, | |||||
| })); | |||||
| setSelectionLevelFilter([...tmpSelectionLevelFilter]); | |||||
| } | } | ||||
| }, [processes]); | }, [processes]); | ||||
| setOpenEditPatternModal(false); | setOpenEditPatternModal(false); | ||||
| }; | }; | ||||
| const handleFilterCheckboxes = (id) => { | |||||
| const tmpSelectionLevelFilter = selectionLevelFilter.map((level) => | |||||
| level.id === id ? { ...level, isChecked: !level.isChecked } : level | |||||
| ); | |||||
| setSelectionLevelFilter(tmpSelectionLevelFilter); | |||||
| }; | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <CustomDrawer | |||||
| <PatternFilters | |||||
| openFilterDrawer={openFilterDrawer} | |||||
| handleClose={closeFilterDrawerHandler} | |||||
| selectionLevelFilter={selectionLevelFilter} | |||||
| onChangeFilterCheckboxes={handleFilterCheckboxes} | |||||
| /> | |||||
| {/* <CustomDrawer | |||||
| title="Šabloni" | title="Šabloni" | ||||
| open={openFilterDrawer} | open={openFilterDrawer} | ||||
| onCloseDrawer={closeFilterDrawerHandler} | onCloseDrawer={closeFilterDrawerHandler} | ||||
| > | > | ||||
| <form> | |||||
| <form onSubmit={submitFiltersHandler}> | |||||
| <div className="custom-drawer"> | <div className="custom-drawer"> | ||||
| <div> | <div> | ||||
| <div className="custom-drawer-sub-card"> | <div className="custom-drawer-sub-card"> | ||||
| </div> | </div> | ||||
| <div className="custom-drawer-sub-card-content"> | <div className="custom-drawer-sub-card-content"> | ||||
| <FormGroup> | <FormGroup> | ||||
| {processes.map((process) => ( | |||||
| {selectionLevelFilter.map((process) => ( | |||||
| <FormControlLabel | <FormControlLabel | ||||
| key={process.id} | key={process.id} | ||||
| control={<Checkbox value={process.name} />} | |||||
| control={ | |||||
| <Checkbox | |||||
| value={process.name} | |||||
| checked={process.isChecked} | |||||
| onChange={handleFilterCheckboxes.bind( | |||||
| this, | |||||
| process.id | |||||
| )} | |||||
| /> | |||||
| } | |||||
| label={process.name} | label={process.name} | ||||
| /> | /> | ||||
| ))} | ))} | ||||
| <label className="custom-drawer-sub-card-content-sub-label"> | <label className="custom-drawer-sub-card-content-sub-label"> | ||||
| Od | Od | ||||
| </label> | </label> | ||||
| <input type="date" /> | |||||
| <input | |||||
| type="date" | |||||
| onChange={(e) => setFromDate(e.target.value)} | |||||
| value={fromDate} | |||||
| /> | |||||
| </FormGroup> | </FormGroup> | ||||
| <FormGroup> | <FormGroup> | ||||
| <label className="custom-drawer-sub-card-content-sub-label"> | <label className="custom-drawer-sub-card-content-sub-label"> | ||||
| Do | Do | ||||
| </label> | </label> | ||||
| <input type="date" /> | |||||
| <input | |||||
| type="date" | |||||
| onChange={(e) => setToDate(e.target.value)} | |||||
| value={toDate} | |||||
| /> | |||||
| </FormGroup> | </FormGroup> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| </CustomDrawer> | |||||
| </CustomDrawer> */} | |||||
| <CustomModal | <CustomModal | ||||
| open={openAddPatternModal} | open={openAddPatternModal} | ||||
| onCloseModal={closeAddPatternModalHandler} | onCloseModal={closeAddPatternModalHandler} |
| patterns: { | patterns: { | ||||
| allPatterns: base + "/patterns", | allPatterns: base + "/patterns", | ||||
| patternById: base + "/patterns/:id", | patternById: base + "/patterns/:id", | ||||
| filteredPatterns: base + "/patterns/filter", | |||||
| createPattern: base + "/patterns", | createPattern: base + "/patterns", | ||||
| updatePattern: base + "/patterns/:id", | updatePattern: base + "/patterns/:id", | ||||
| }, | }, |
| getRequest(apiEndpoints.patterns.allPatterns); | getRequest(apiEndpoints.patterns.allPatterns); | ||||
| export const getPatternById = (id) => | export const getPatternById = (id) => | ||||
| getRequest(apiEndpoints.patterns.patternById.replace(":id", id)); | getRequest(apiEndpoints.patterns.patternById.replace(":id", id)); | ||||
| export const getFilteredPatterns = (payload) => { | |||||
| let selectionLevelsQuery = ""; | |||||
| for (let i = 0; i < payload.selectionLevels.length; i++) { | |||||
| selectionLevelsQuery += `selectionLevels=${payload.selectionLevels[i]}&`; | |||||
| } | |||||
| return getRequest( | |||||
| apiEndpoints.patterns.filteredPatterns + | |||||
| `?fromDate=${ | |||||
| payload.fromDate === null ? "" : new Date(payload.fromDate).toISOString() | |||||
| }&toDate=${ | |||||
| payload.toDate === null ? "" : new Date(payload.toDate).toISOString() | |||||
| }&${selectionLevelsQuery}` | |||||
| ); | |||||
| }; | |||||
| export const createPatternRequest = (payload) => | export const createPatternRequest = (payload) => | ||||
| postRequest(apiEndpoints.patterns.createPattern, payload); | postRequest(apiEndpoints.patterns.createPattern, payload); | ||||
| export const updatePatternRequest = (payload) => | export const updatePatternRequest = (payload) => |
| } from "../actionHelpers"; | } from "../actionHelpers"; | ||||
| const FETCH_PATTERNS_SCOPE = "FETCH_PATTERNS"; | const FETCH_PATTERNS_SCOPE = "FETCH_PATTERNS"; | ||||
| const FILTER_PATTERNS_SCOPE = "FILTER_PATTERNS"; | |||||
| export const FETCH_PATTERNS_REQ = createFetchType(FETCH_PATTERNS_SCOPE); | export const FETCH_PATTERNS_REQ = createFetchType(FETCH_PATTERNS_SCOPE); | ||||
| export const FETCH_PATTERNS_ERR = createErrorType(FETCH_PATTERNS_SCOPE); | export const FETCH_PATTERNS_ERR = createErrorType(FETCH_PATTERNS_SCOPE); | ||||
| export const FETCH_PATTERNS_SUCCESS = createSuccessType(FETCH_PATTERNS_SCOPE); | export const FETCH_PATTERNS_SUCCESS = createSuccessType(FETCH_PATTERNS_SCOPE); | ||||
| export const FETCH_FILTERED_PATTERNS_REQ = createFetchType( | |||||
| FILTER_PATTERNS_SCOPE | |||||
| ); | |||||
| export const FETCH_FILTERED_PATTERNS_ERR = createErrorType( | |||||
| FILTER_PATTERNS_SCOPE | |||||
| ); | |||||
| export const FETCH_FILTERED_PATTERNS_SUCCESS = createSuccessType( | |||||
| FILTER_PATTERNS_SCOPE | |||||
| ); |
| FETCH_PATTERNS_REQ, | FETCH_PATTERNS_REQ, | ||||
| FETCH_PATTERNS_ERR, | FETCH_PATTERNS_ERR, | ||||
| FETCH_PATTERNS_SUCCESS, | FETCH_PATTERNS_SUCCESS, | ||||
| FETCH_FILTERED_PATTERNS_REQ, | |||||
| FETCH_FILTERED_PATTERNS_SUCCESS, | |||||
| FETCH_FILTERED_PATTERNS_ERR, | |||||
| } from "./patternsActionConstants"; | } from "./patternsActionConstants"; | ||||
| export const setPatternsReq = () => ({ | export const setPatternsReq = () => ({ | ||||
| type: FETCH_PATTERNS_SUCCESS, | type: FETCH_PATTERNS_SUCCESS, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const setFilteredPatternsReq = (payload) => ({ | |||||
| type: FETCH_FILTERED_PATTERNS_REQ, | |||||
| payload, | |||||
| }); | |||||
| export const setFilteredPatternsError = (payload) => ({ | |||||
| type: FETCH_FILTERED_PATTERNS_ERR, | |||||
| payload, | |||||
| }); | |||||
| export const setFilteredPatterns = (payload) => ({ | |||||
| type: FETCH_FILTERED_PATTERNS_SUCCESS, | |||||
| payload, | |||||
| }); |
| import { | import { | ||||
| FETCH_FILTERED_PATTERNS_ERR, | |||||
| FETCH_FILTERED_PATTERNS_SUCCESS, | |||||
| FETCH_PATTERNS_ERR, | FETCH_PATTERNS_ERR, | ||||
| FETCH_PATTERNS_SUCCESS, | FETCH_PATTERNS_SUCCESS, | ||||
| } from "../../actions/patterns/patternsActionConstants"; | } from "../../actions/patterns/patternsActionConstants"; | ||||
| { | { | ||||
| [FETCH_PATTERNS_SUCCESS]: setStatePatterns, | [FETCH_PATTERNS_SUCCESS]: setStatePatterns, | ||||
| [FETCH_PATTERNS_ERR]: setPatternsErrorMessage, | [FETCH_PATTERNS_ERR]: setPatternsErrorMessage, | ||||
| [FETCH_FILTERED_PATTERNS_SUCCESS]: setStateFilteredPatterns, | |||||
| [FETCH_FILTERED_PATTERNS_ERR]: setFilteredPatternsErrorMessage, | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| errorMessage: action.payload, | errorMessage: action.payload, | ||||
| }; | }; | ||||
| } | } | ||||
| function setStateFilteredPatterns(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| patterns: action.payload, | |||||
| }; | |||||
| } | |||||
| function setFilteredPatternsErrorMessage(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } |
| import { | import { | ||||
| createPatternRequest, | createPatternRequest, | ||||
| getAllPatterns, | getAllPatterns, | ||||
| getFilteredPatterns, | |||||
| getPatternById, | getPatternById, | ||||
| updatePatternRequest, | updatePatternRequest, | ||||
| } from "../../request/patternsRequest"; | } from "../../request/patternsRequest"; | ||||
| import { | import { | ||||
| setFilteredPatterns, | |||||
| setFilteredPatternsError, | |||||
| setPatterns, | setPatterns, | ||||
| setPatternsError, | setPatternsError, | ||||
| } from "../actions/patterns/patternsActions"; | } from "../actions/patterns/patternsActions"; | ||||
| createPattern, | createPattern, | ||||
| createPatternError, | createPatternError, | ||||
| } from "../actions/createPattern/createPatternActions"; | } from "../actions/createPattern/createPatternActions"; | ||||
| import { FETCH_PATTERNS_REQ } from "../actions/patterns/patternsActionConstants"; | |||||
| import { | |||||
| FETCH_FILTERED_PATTERNS_REQ, | |||||
| FETCH_PATTERNS_REQ, | |||||
| } from "../actions/patterns/patternsActionConstants"; | |||||
| import { FETCH_PATTERN_REQ } from "../actions/pattern/patternActionConstants"; | import { FETCH_PATTERN_REQ } from "../actions/pattern/patternActionConstants"; | ||||
| import { CREATE_PATTERN_REQ } from "../actions/createPattern/createPatternActionConstants"; | import { CREATE_PATTERN_REQ } from "../actions/createPattern/createPatternActionConstants"; | ||||
| import { UPDATE_PATTERN_REQ } from "../actions/updatePattern/updatePatternActionConstants"; | import { UPDATE_PATTERN_REQ } from "../actions/updatePattern/updatePatternActionConstants"; | ||||
| updatePattern, | updatePattern, | ||||
| updatePatternError, | updatePatternError, | ||||
| } from "../actions/updatePattern/updatePatternActions"; | } from "../actions/updatePattern/updatePatternActions"; | ||||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||||
| import { JWT_TOKEN } from "../../constants/localStorage"; | |||||
| import { addHeaderToken } from "../../request"; | |||||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | |||||
| export function* getPatterns() { | export function* getPatterns() { | ||||
| try { | try { | ||||
| } | } | ||||
| } | } | ||||
| export function* filterPatterns({ payload }) { | |||||
| try { | |||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||||
| yield call(addHeaderToken, JwtToken); | |||||
| const { data } = yield call(getFilteredPatterns, payload); | |||||
| yield put(setFilteredPatterns(data)); | |||||
| if (payload.handleApiResponseSuccess) { | |||||
| yield call(payload.handleApiResponseSuccess); | |||||
| } | |||||
| } catch (error) { | |||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||||
| yield put(setFilteredPatternsError(errorMessage)); | |||||
| } | |||||
| } | |||||
| export function* createPatternSaga({ payload }) { | export function* createPatternSaga({ payload }) { | ||||
| try { | try { | ||||
| const result = yield call(createPatternRequest, payload); | const result = yield call(createPatternRequest, payload); | ||||
| yield all([ | yield all([ | ||||
| takeLatest(FETCH_PATTERNS_REQ, getPatterns), | takeLatest(FETCH_PATTERNS_REQ, getPatterns), | ||||
| takeLatest(FETCH_PATTERN_REQ, getPattern), | takeLatest(FETCH_PATTERN_REQ, getPattern), | ||||
| takeLatest(FETCH_FILTERED_PATTERNS_REQ, filterPatterns), | |||||
| takeLatest(CREATE_PATTERN_REQ, createPatternSaga), | takeLatest(CREATE_PATTERN_REQ, createPatternSaga), | ||||
| takeLatest(UPDATE_PATTERN_REQ, updatePatternSaga), | takeLatest(UPDATE_PATTERN_REQ, updatePatternSaga), | ||||
| ]); | ]); |