Sfoglia il codice sorgente

Merge branch 'feature/file_filtering' of safet.purkovic/DocumentOrganizer into FE_dev

FE_dev
merisahm 3 anni fa
parent
commit
5b85ce5e01

+ 50
- 17
src/components/Docs/DocsFilters.js Vedi File

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

+ 80
- 9
src/pages/FilesPage/FilesViewPage.js Vedi File

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={{

+ 1
- 1
src/request/apiEndpoints.js Vedi File

}, },
files:{ files:{
uploadFile: base + "/files", uploadFile: base + "/files",
all: base + "/files"
all: base + "/files/filtered"
} }
}; };

+ 27
- 1
src/request/fileRequests.js Vedi File

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
);
};

+ 3
- 0
src/store/actions/files/fileActionConstants.js Vedi File

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);

+ 21
- 4
src/store/actions/files/fileActions.js Vedi File

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) => ({

+ 46
- 1
src/store/reducers/files/fileFiltersReducer.js Vedi File

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
),
},
};
}

+ 2
- 2
src/store/reducers/files/getFilesReducer.js Vedi File

} 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,
}; };
} }



+ 6
- 8
src/store/saga/filesSaga.js Vedi File

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);

Loading…
Annulla
Salva