| } from "@mui/material"; | } from "@mui/material"; | ||||
| import filterIcon from "../../assets/images/filter_vector.png"; | import filterIcon from "../../assets/images/filter_vector.png"; | ||||
| import x from "../../assets/images/x.png"; | import x from "../../assets/images/x.png"; | ||||
| import { useSelector } from "react-redux"; | |||||
| // const tags = [ | |||||
| // { name: ".txt", isChecked: false }, | |||||
| // { name: ".pdf", isChecked: true }, | |||||
| // { name: ".docx", isChecked: true }, | |||||
| // ]; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { | |||||
| getFilesReq, | |||||
| updateFileFilterCat, | |||||
| updateFileFilterExt, | |||||
| updateFileFilterTag, | |||||
| } from "../../store/actions/files/fileActions"; | |||||
| const DocsFilters = ({ open, handleClose }) => { | |||||
| const DocsFilters = ({ open, handleClose, setPage }) => { | |||||
| const dispatch = useDispatch(); | |||||
| const { filters } = useSelector((s) => s.fileFilters); | const { filters } = useSelector((s) => s.fileFilters); | ||||
| const handleCheckboxes = (e) => { | |||||
| const { value } = e.target; | |||||
| console.log(value); | |||||
| }; | |||||
| const handleCheckboxesExt = (e) => | |||||
| dispatch(updateFileFilterExt(e.target.value)); | |||||
| const handleCheckboxesTags = (e) => | |||||
| dispatch(updateFileFilterTag(e.target.value)); | |||||
| const handleCheckboxesCat = (e) => | |||||
| dispatch(updateFileFilterCat(e.target.value)); | |||||
| const submitFiltersHandler = (e) => { | |||||
| e.preventDefault(); | |||||
| var catFilters = []; | |||||
| filters.categories | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => catFilters.push(m.name)); | |||||
| var extFilters = []; | |||||
| filters.extensions | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => extFilters.push(m.name)); | |||||
| var tagFilters = []; | |||||
| filters.tags | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => tagFilters.push(m.name)); | |||||
| const submitFiltersHandler = () => { | |||||
| alert("Pamet u glavu"); | |||||
| dispatch( | |||||
| getFilesReq({ | |||||
| payload: { | |||||
| pageSize: 6, | |||||
| currentPage: 1, | |||||
| categories: catFilters, | |||||
| extensions: extFilters, | |||||
| tags: tagFilters, | |||||
| }, | |||||
| apiSuccess: handleClose, | |||||
| }) | |||||
| ); | |||||
| setPage(1); | |||||
| }; | }; | ||||
| const list = () => ( | const list = () => ( | ||||
| key={index} | key={index} | ||||
| control={ | control={ | ||||
| <Checkbox | <Checkbox | ||||
| onChange={handleCheckboxes} | |||||
| onChange={handleCheckboxesExt} | |||||
| value={tag.name} | value={tag.name} | ||||
| checked={tag.isChecked} | checked={tag.isChecked} | ||||
| className="ad-filters-checkbox" | className="ad-filters-checkbox" | ||||
| key={index} | key={index} | ||||
| control={ | control={ | ||||
| <Checkbox | <Checkbox | ||||
| onChange={handleCheckboxes} | |||||
| onChange={handleCheckboxesTags} | |||||
| value={tag.name} | value={tag.name} | ||||
| checked={tag.isChecked} | checked={tag.isChecked} | ||||
| className="ad-filters-checkbox" | className="ad-filters-checkbox" | ||||
| key={index} | key={index} | ||||
| control={ | control={ | ||||
| <Checkbox | <Checkbox | ||||
| onChange={handleCheckboxes} | |||||
| onChange={handleCheckboxesCat} | |||||
| value={tag.name} | value={tag.name} | ||||
| checked={tag.isChecked} | checked={tag.isChecked} | ||||
| className="ad-filters-checkbox" | className="ad-filters-checkbox" | ||||
| DocsFilters.propTypes = { | DocsFilters.propTypes = { | ||||
| open: PropType.any, | open: PropType.any, | ||||
| handleClose: PropType.func, | handleClose: PropType.func, | ||||
| setPage: PropType.func, | |||||
| }; | }; | ||||
| export default DocsFilters; | export default DocsFilters; |
| import { Pagination } from "@mui/material"; | |||||
| import React from "react"; | import React from "react"; | ||||
| import { useEffect } from "react"; | import { useEffect } from "react"; | ||||
| import { useState } from "react"; | import { useState } from "react"; | ||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import FilterButton from "../../components/Button/FilterButton"; | import FilterButton from "../../components/Button/FilterButton"; | ||||
| import DocsFilters from "../../components/Docs/DocsFilters"; | import DocsFilters from "../../components/Docs/DocsFilters"; | ||||
| import { getFileFiltersReq, getFilesReq } from "../../store/actions/files/fileActions"; | |||||
| import { FETCH_FILES_LOADING } from "../../store/actions/files/fileActionConstants"; | |||||
| import { | |||||
| getFileFiltersReq, | |||||
| getFilesReq, | |||||
| } from "../../store/actions/files/fileActions"; | |||||
| import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; | |||||
| const FilesViewPage = () => { | const FilesViewPage = () => { | ||||
| const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | ||||
| const {files} = useSelector(s => s.files) | |||||
| const [page, setPage] = useState(1) | |||||
| const { filters } = useSelector((s) => s.fileFilters); | |||||
| const { data } = useSelector((s) => s.files); | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(getFileFiltersReq()); | dispatch(getFileFiltersReq()); | ||||
| dispatch( | |||||
| getFilesReq({ | |||||
| payload: { | |||||
| pageSize: 6, | |||||
| currentPage: page, | |||||
| categories: [], | |||||
| extensions: [], | |||||
| tags: [], | |||||
| }, | |||||
| }) | |||||
| ); | |||||
| }, []); | }, []); | ||||
| // disjoin the effect because we want the metods to trigger on different occassions | |||||
| useEffect(() => { | |||||
| dispatch(getFilesReq()); | |||||
| }, []); | |||||
| const handleChange = (_, value) => { | |||||
| var catFilters = []; | |||||
| filters.categories | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => catFilters.push(m.name)); | |||||
| var extFilters = []; | |||||
| filters.extensions | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => extFilters.push(m.name)); | |||||
| var tagFilters = []; | |||||
| filters.tags | |||||
| ?.filter((n) => n.isChecked) | |||||
| .forEach((m) => tagFilters.push(m.name)); | |||||
| return ( | |||||
| dispatch( | |||||
| getFilesReq({ | |||||
| payload: { | |||||
| pageSize: 6, | |||||
| currentPage: value, | |||||
| categories: catFilters, | |||||
| extensions: extFilters, | |||||
| tags: tagFilters, | |||||
| }, | |||||
| }) | |||||
| ); | |||||
| setPage(value); | |||||
| }; | |||||
| const isLoading = useSelector( | |||||
| selectIsLoadingByActionType(FETCH_FILES_LOADING) | |||||
| ); | |||||
| return isLoading ? ( | |||||
| <div> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <div className="loader-container h-withHeader"> | |||||
| <span>Loading</span> | |||||
| </div> | |||||
| </div> | |||||
| ) : ( | |||||
| <div> | <div> | ||||
| <div className="l-t-rectangle"></div> | <div className="l-t-rectangle"></div> | ||||
| <div className="r-b-rectangle"></div> | <div className="r-b-rectangle"></div> | ||||
| <DocsFilters | <DocsFilters | ||||
| open={toggleFiltersDrawer} | open={toggleFiltersDrawer} | ||||
| handleClose={handleToggleFiltersDrawer} | handleClose={handleToggleFiltersDrawer} | ||||
| setPage = {setPage} | |||||
| /> | /> | ||||
| <div | <div | ||||
| // onClick={() => setIsSearchFieldVisible(false)} | // onClick={() => setIsSearchFieldVisible(false)} | ||||
| </thead> | </thead> | ||||
| <tbody> | <tbody> | ||||
| {files?.map((n) => ( | |||||
| <tr key={n.id} className="secondaryRow"> | |||||
| {data.data?.length > 0 && data.data?.map((n) => ( | |||||
| <tr key={n.id + n.name} className="secondaryRow"> | |||||
| <td className="docs-name">{n.name}</td> | <td className="docs-name">{n.name}</td> | ||||
| <td>{n.extension}</td> | <td>{n.extension}</td> | ||||
| <td className="profession">{n.size}kB</td> | <td className="profession">{n.size}kB</td> | ||||
| ))} | ))} | ||||
| </tbody> | </tbody> | ||||
| </table> | </table> | ||||
| <Pagination | |||||
| // size={matches ? "small" : "medium"} | |||||
| size={"small"} | |||||
| count={ | |||||
| parseInt(data.total) <= 6 | |||||
| ? 1 | |||||
| : Math.ceil(parseInt(data.total) / 6) | |||||
| } | |||||
| color="primary" | |||||
| className="candidates-pagination" | |||||
| onChange={handleChange} | |||||
| shape="rounded" | |||||
| page={page} | |||||
| /> | |||||
| </div> | </div> | ||||
| <div | <div | ||||
| style={{ | style={{ |
| }, | }, | ||||
| files:{ | files:{ | ||||
| uploadFile: base + "/files", | uploadFile: base + "/files", | ||||
| all: base + "/files" | |||||
| all: base + "/files/filtered" | |||||
| } | } | ||||
| }; | }; |
| import { getRequest } from "."; | import { getRequest } from "."; | ||||
| import apiEndpoints from "./apiEndpoints"; | import apiEndpoints from "./apiEndpoints"; | ||||
| export const getAllFilesReq = () => getRequest(apiEndpoints.files.all); | |||||
| export const getAllFilesReq = (payload) => { | |||||
| let categoryQuery = ""; | |||||
| for (let i = 0; i < payload.categories.length; i++) { | |||||
| categoryQuery += `&categories=${payload.categories[i]}`; | |||||
| } | |||||
| let tagQuery = ""; | |||||
| for (let i = 0; i < payload.tags.length; i++) { | |||||
| tagQuery += `&tags=${payload.tags[i]}&`; | |||||
| } | |||||
| let extQuery = ""; | |||||
| for (let i = 0; i < payload.extensions.length; i++) { | |||||
| extQuery += `&extensions=${payload.extensions[i]}`; | |||||
| } | |||||
| return getRequest( | |||||
| apiEndpoints.files.all + | |||||
| "?currentPage=" + | |||||
| payload.currentPage + | |||||
| "&pageSize=" + | |||||
| payload.pageSize + | |||||
| categoryQuery + | |||||
| extQuery + | |||||
| tagQuery | |||||
| ); | |||||
| }; |
| export const FILE_FILTERS_ERR = createErrorType(FILE_FILTERS_SCOPE); | export const FILE_FILTERS_ERR = createErrorType(FILE_FILTERS_SCOPE); | ||||
| export const FILE_FILTERS_SUCCESS = createSuccessType(FILE_FILTERS_SCOPE); | export const FILE_FILTERS_SUCCESS = createSuccessType(FILE_FILTERS_SCOPE); | ||||
| export const FILE_FILTERS_LOADING = createLoadingType(FILE_FILTERS_SCOPE); | export const FILE_FILTERS_LOADING = createLoadingType(FILE_FILTERS_SCOPE); | ||||
| export const UPDATE_FILTERS_EXTENSION = 'UPDATE_FILTERS_EXTENSION'; | |||||
| export const UPDATE_FILTERS_TAG = 'UPDATE_FILTERS_TAG'; | |||||
| export const UPDATE_FILTERS_CATEGORY = 'UPDATE_FILTERS_CATEGORY'; | |||||
| const FETCH_FILES_SCOPE = "FETCH_FILES"; | const FETCH_FILES_SCOPE = "FETCH_FILES"; | ||||
| export const FETCH_FILES_REQ = createFetchType(FETCH_FILES_SCOPE); | export const FETCH_FILES_REQ = createFetchType(FETCH_FILES_SCOPE); |
| import { | import { | ||||
| FETCH_FILES_ERR, | |||||
| FETCH_FILES_REQ, | |||||
| FETCH_FILES_SUCCESS, | |||||
| FETCH_FILES_ERR, | |||||
| FETCH_FILES_REQ, | |||||
| FETCH_FILES_SUCCESS, | |||||
| FILE_FILTERS_ERR, | FILE_FILTERS_ERR, | ||||
| FILE_FILTERS_REQ, | FILE_FILTERS_REQ, | ||||
| FILE_FILTERS_SUCCESS, | FILE_FILTERS_SUCCESS, | ||||
| UPDATE_FILTERS_CATEGORY, | |||||
| UPDATE_FILTERS_EXTENSION, | |||||
| UPDATE_FILTERS_TAG, | |||||
| } from "./fileActionConstants"; | } from "./fileActionConstants"; | ||||
| export const getFileFiltersReq = () => ({ | export const getFileFiltersReq = () => ({ | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const getFilesReq = () => ({ | |||||
| export const updateFileFilterExt = (payload) => ({ | |||||
| type: UPDATE_FILTERS_EXTENSION, | |||||
| payload, | |||||
| }); | |||||
| export const updateFileFilterTag = (payload) => ({ | |||||
| type: UPDATE_FILTERS_TAG, | |||||
| payload, | |||||
| }); | |||||
| export const updateFileFilterCat = (payload) => ({ | |||||
| type: UPDATE_FILTERS_CATEGORY, | |||||
| payload, | |||||
| }); | |||||
| export const getFilesReq = (payload) => ({ | |||||
| type: FETCH_FILES_REQ, | type: FETCH_FILES_REQ, | ||||
| payload | |||||
| }); | }); | ||||
| export const getFileError = (payload) => ({ | export const getFileError = (payload) => ({ |
| import { | import { | ||||
| FILE_FILTERS_ERR, | FILE_FILTERS_ERR, | ||||
| FILE_FILTERS_SUCCESS, | FILE_FILTERS_SUCCESS, | ||||
| UPDATE_FILTERS_CATEGORY, | |||||
| UPDATE_FILTERS_EXTENSION, | |||||
| UPDATE_FILTERS_TAG, | |||||
| } from "../../actions/files/fileActionConstants"; | } from "../../actions/files/fileActionConstants"; | ||||
| const initialState = { | const initialState = { | ||||
| { | { | ||||
| [FILE_FILTERS_SUCCESS]: setFileFilters, | [FILE_FILTERS_SUCCESS]: setFileFilters, | ||||
| [FILE_FILTERS_ERR]: setFileFiltersErrorMessage, | [FILE_FILTERS_ERR]: setFileFiltersErrorMessage, | ||||
| [UPDATE_FILTERS_EXTENSION]: updateFileFilterExtension, | |||||
| [UPDATE_FILTERS_TAG]: updateFileFilterTag, | |||||
| [UPDATE_FILTERS_CATEGORY]: updateFileFilterCategory, | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| isChecked: false, | isChecked: false, | ||||
| })), | })), | ||||
| tags: action.payload.tags.map((n) => ({ ...n, isChecked: false })), | tags: action.payload.tags.map((n) => ({ ...n, isChecked: false })), | ||||
| extensions: action.payload.extensions.map((n) => ({ name: n, isChecked: false })), | |||||
| extensions: action.payload.extensions.map((n) => ({ | |||||
| name: n, | |||||
| isChecked: false, | |||||
| })), | |||||
| }, | }, | ||||
| }; | }; | ||||
| } | } | ||||
| fetchFileFiltersErrorMessage: action.payload, | fetchFileFiltersErrorMessage: action.payload, | ||||
| }; | }; | ||||
| } | } | ||||
| function updateFileFilterExtension(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| filters: { | |||||
| ...state.filters, | |||||
| extensions: state.filters.extensions?.map((n) => | |||||
| n.name === action.payload ? { ...n, isChecked: !n.isChecked } : n | |||||
| ), | |||||
| }, | |||||
| }; | |||||
| } | |||||
| function updateFileFilterTag(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| filters: { | |||||
| ...state.filters, | |||||
| tags: state.filters.tags?.map((n) => | |||||
| n.name === action.payload ? { ...n, isChecked: !n.isChecked } : n | |||||
| ), | |||||
| }, | |||||
| }; | |||||
| } | |||||
| function updateFileFilterCategory(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| filters: { | |||||
| ...state.filters, | |||||
| categories: state.filters.categories?.map((n) => | |||||
| n.name === action.payload ? { ...n, isChecked: !n.isChecked } : n | |||||
| ), | |||||
| }, | |||||
| }; | |||||
| } |
| } from "../../actions/files/fileActionConstants"; | } from "../../actions/files/fileActionConstants"; | ||||
| const initialState = { | const initialState = { | ||||
| files: [], | |||||
| data: {}, | |||||
| fetchFilesErrorMessage: "", | fetchFilesErrorMessage: "", | ||||
| }; | }; | ||||
| function setFiles(state, action) { | function setFiles(state, action) { | ||||
| return { | return { | ||||
| ...state, | ...state, | ||||
| files: action.payload, | |||||
| data: action.payload, | |||||
| }; | }; | ||||
| } | } | ||||
| import { uploadFileRequest } from "../../request/filesRequest"; | import { uploadFileRequest } from "../../request/filesRequest"; | ||||
| import { getAllFilesReq } from "../../request/fileRequests"; | import { getAllFilesReq } from "../../request/fileRequests"; | ||||
| import { FETCH_FILES_REQ } from "../actions/files/fileActionConstants"; | import { FETCH_FILES_REQ } from "../actions/files/fileActionConstants"; | ||||
| import { | |||||
| getFileError, | |||||
| getFileSuccess, | |||||
| } from "../actions/files/fileActions"; | |||||
| import { getFileError, getFileSuccess } from "../actions/files/fileActions"; | |||||
| export function* uploadFileSaga({ payload }) { | export function* uploadFileSaga({ payload }) { | ||||
| try { | try { | ||||
| yield call(addHeaderToken, JwtToken); | yield call(addHeaderToken, JwtToken); | ||||
| const formData = new FormData(); | const formData = new FormData(); | ||||
| formData.append("categoryId", payload.categoryId); | formData.append("categoryId", payload.categoryId); | ||||
| for(let i = 0; i < payload.tagsIds.length; i++) | |||||
| formData.append("tagsIds[]", payload.tagsIds[i]); | |||||
| for (let i = 0; i < payload.tagsIds.length; i++) | |||||
| formData.append("tagsIds[]", payload.tagsIds[i]); | |||||
| formData.append("fileToUpload", payload.fileToUpload); | formData.append("fileToUpload", payload.fileToUpload); | ||||
| const result = yield call(uploadFileRequest, formData); | const result = yield call(uploadFileRequest, formData); | ||||
| yield put(uploadFile(result.data)); | yield put(uploadFile(result.data)); | ||||
| } | } | ||||
| } | } | ||||
| export function* getAll() { | |||||
| export function* getAll({ payload }) { | |||||
| try { | try { | ||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | ||||
| yield call(addHeaderToken, JwtToken); | yield call(addHeaderToken, JwtToken); | ||||
| const result = yield call(getAllFilesReq); | |||||
| const result = yield call(getAllFilesReq, payload.payload); | |||||
| yield put(getFileSuccess(result.data)); | yield put(getFileSuccess(result.data)); | ||||
| if (payload.apiSuccess) yield call(payload.apiSuccess); | |||||
| } catch (error) { | } catch (error) { | ||||
| if (error.response && error.response.data) { | if (error.response && error.response.data) { | ||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | const errorMessage = yield call(rejectErrorCodeHelper, error); |