Просмотр исходного кода

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

FE_dev
merisahm 3 лет назад
Родитель
Сommit
5b85ce5e01

+ 50
- 17
src/components/Docs/DocsFilters.js Просмотреть файл

@@ -9,24 +9,56 @@ import {
} from "@mui/material";
import filterIcon from "../../assets/images/filter_vector.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 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 = () => (
@@ -69,7 +101,7 @@ const DocsFilters = ({ open, handleClose }) => {
key={index}
control={
<Checkbox
onChange={handleCheckboxes}
onChange={handleCheckboxesExt}
value={tag.name}
checked={tag.isChecked}
className="ad-filters-checkbox"
@@ -93,7 +125,7 @@ const DocsFilters = ({ open, handleClose }) => {
key={index}
control={
<Checkbox
onChange={handleCheckboxes}
onChange={handleCheckboxesTags}
value={tag.name}
checked={tag.isChecked}
className="ad-filters-checkbox"
@@ -117,7 +149,7 @@ const DocsFilters = ({ open, handleClose }) => {
key={index}
control={
<Checkbox
onChange={handleCheckboxes}
onChange={handleCheckboxesCat}
value={tag.name}
checked={tag.isChecked}
className="ad-filters-checkbox"
@@ -160,6 +192,7 @@ const DocsFilters = ({ open, handleClose }) => {
DocsFilters.propTypes = {
open: PropType.any,
handleClose: PropType.func,
setPage: PropType.func,
};

export default DocsFilters;

+ 80
- 9
src/pages/FilesPage/FilesViewPage.js Просмотреть файл

@@ -1,3 +1,4 @@
import { Pagination } from "@mui/material";
import React from "react";
import { useEffect } from "react";
import { useState } from "react";
@@ -5,11 +6,18 @@ import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import FilterButton from "../../components/Button/FilterButton";
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 [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();

@@ -19,20 +27,69 @@ const FilesViewPage = () => {

useEffect(() => {
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 className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div>
<DocsFilters
open={toggleFiltersDrawer}
handleClose={handleToggleFiltersDrawer}
setPage = {setPage}
/>
<div
// onClick={() => setIsSearchFieldVisible(false)}
@@ -96,8 +153,8 @@ const FilesViewPage = () => {
</thead>

<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>{n.extension}</td>
<td className="profession">{n.size}kB</td>
@@ -106,6 +163,20 @@ const FilesViewPage = () => {
))}
</tbody>
</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
style={{

+ 1
- 1
src/request/apiEndpoints.js Просмотреть файл

@@ -80,6 +80,6 @@ export default {
},
files:{
uploadFile: base + "/files",
all: base + "/files"
all: base + "/files/filtered"
}
};

+ 27
- 1
src/request/fileRequests.js Просмотреть файл

@@ -1,4 +1,30 @@
import { getRequest } from ".";
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 Просмотреть файл

@@ -10,6 +10,9 @@ export const FILE_FILTERS_REQ = createFetchType(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_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";
export const FETCH_FILES_REQ = createFetchType(FETCH_FILES_SCOPE);

+ 21
- 4
src/store/actions/files/fileActions.js Просмотреть файл

@@ -1,10 +1,13 @@
import {
FETCH_FILES_ERR,
FETCH_FILES_REQ,
FETCH_FILES_SUCCESS,
FETCH_FILES_ERR,
FETCH_FILES_REQ,
FETCH_FILES_SUCCESS,
FILE_FILTERS_ERR,
FILE_FILTERS_REQ,
FILE_FILTERS_SUCCESS,
UPDATE_FILTERS_CATEGORY,
UPDATE_FILTERS_EXTENSION,
UPDATE_FILTERS_TAG,
} from "./fileActionConstants";

export const getFileFiltersReq = () => ({
@@ -21,8 +24,22 @@ export const getFileFiltersSuccess = (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,
payload
});

export const getFileError = (payload) => ({

+ 46
- 1
src/store/reducers/files/fileFiltersReducer.js Просмотреть файл

@@ -2,6 +2,9 @@ import createReducer from "../../utils/createReducer";
import {
FILE_FILTERS_ERR,
FILE_FILTERS_SUCCESS,
UPDATE_FILTERS_CATEGORY,
UPDATE_FILTERS_EXTENSION,
UPDATE_FILTERS_TAG,
} from "../../actions/files/fileActionConstants";

const initialState = {
@@ -13,6 +16,9 @@ export default createReducer(
{
[FILE_FILTERS_SUCCESS]: setFileFilters,
[FILE_FILTERS_ERR]: setFileFiltersErrorMessage,
[UPDATE_FILTERS_EXTENSION]: updateFileFilterExtension,
[UPDATE_FILTERS_TAG]: updateFileFilterTag,
[UPDATE_FILTERS_CATEGORY]: updateFileFilterCategory,
},
initialState
);
@@ -26,7 +32,10 @@ function setFileFilters(state, action) {
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,
})),
},
};
}
@@ -37,3 +46,39 @@ function setFileFiltersErrorMessage(state, action) {
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 Просмотреть файл

@@ -5,7 +5,7 @@ import {
} from "../../actions/files/fileActionConstants";

const initialState = {
files: [],
data: {},
fetchFilesErrorMessage: "",
};

@@ -20,7 +20,7 @@ export default createReducer(
function setFiles(state, action) {
return {
...state,
files: action.payload,
data: action.payload,
};
}


+ 6
- 8
src/store/saga/filesSaga.js Просмотреть файл

@@ -11,10 +11,7 @@ import { UPLOAD_FILE_REQ } from "../actions/uploadFile/uploadFileActionConstants
import { uploadFileRequest } from "../../request/filesRequest";
import { getAllFilesReq } from "../../request/fileRequests";
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 }) {
try {
@@ -22,8 +19,8 @@ export function* uploadFileSaga({ payload }) {
yield call(addHeaderToken, JwtToken);
const formData = new FormData();
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);
const result = yield call(uploadFileRequest, formData);
yield put(uploadFile(result.data));
@@ -34,12 +31,13 @@ export function* uploadFileSaga({ payload }) {
}
}

export function* getAll() {
export function* getAll({ payload }) {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
const result = yield call(getAllFilesReq);
const result = yield call(getAllFilesReq, payload.payload);
yield put(getFileSuccess(result.data));
if (payload.apiSuccess) yield call(payload.apiSuccess);
} catch (error) {
if (error.response && error.response.data) {
const errorMessage = yield call(rejectErrorCodeHelper, error);

Загрузка…
Отмена
Сохранить