Przeglądaj źródła

Categories & deleting files changed

FE_dev
bronjaermin 2 lat temu
rodzic
commit
8f0548bdf6

+ 52
- 7
src/assets/styles/components/_files.scss Wyświetl plik

@@ -6,8 +6,8 @@
}

.files-page-card {
margin-bottom: 1.5rem;
}
margin-bottom: 1.5rem;
}

.files-page-card-title {
margin-bottom: 1rem;
@@ -32,9 +32,9 @@
}

.files-page-card-add-button {
padding-bottom: 36px;
display: flex;
justify-content: space-between;
padding-bottom: 36px;
display: flex;
justify-content: space-between;
}

.files-page-drag-and-drop {
@@ -45,11 +45,56 @@
padding-right: 35px !important;
}

.search-field{
.search-field {
margin-right: 30px;
margin-left: 0px;
}

.filesPage{
.filesPage {
align-self: flex-end;
}

.files-page-categories {
display: flex;
flex-wrap: wrap;
}

.files-page-categories-category {
width: calc(100% / 4) !important;
margin: 0 !important;
padding: 16px;
}

.files-page-category-button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 18px 72px;
gap: 10px;
width: 100%;
height: 100%;
background: #226cb0;
border-radius: 9px;
@include media-below($bp-xl) {
width: 147px;
}
}

.add-file-message {
display: flex;
align-items: center !important;
justify-content: center !important;
margin: 16px 0;
}

.add-file-message p {
color: green;
font-weight: bold;
font-size: 1.25rem;
letter-spacing: 2px;
}

.files-view-page-delete-btn {
margin: 0 auto !important;
}

+ 11
- 10
src/components/Docs/DocsFilters.js Wyświetl plik

@@ -12,12 +12,12 @@ import x from "../../assets/images/x.png";
import { useDispatch, useSelector } from "react-redux";
import {
getFilesReq,
updateFileFilterCat,
// updateFileFilterCat,
updateFileFilterExt,
updateFileFilterTag,
} from "../../store/actions/files/fileActions";

const DocsFilters = ({ open, handleClose, setPage }) => {
const DocsFilters = ({ open, handleClose, setPage, category }) => {
const dispatch = useDispatch();
const { filters } = useSelector((s) => s.fileFilters);

@@ -25,16 +25,16 @@ const DocsFilters = ({ open, handleClose, setPage }) => {
dispatch(updateFileFilterExt(e.target.value));
const handleCheckboxesTags = (e) =>
dispatch(updateFileFilterTag(e.target.value));
const handleCheckboxesCat = (e) =>
dispatch(updateFileFilterCat(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 catFilters = [category && category];
// filters.categories
// ?.filter((n) => n.isChecked)
// .forEach((m) => catFilters.push(m.name));

var extFilters = [];
filters.extensions
@@ -138,7 +138,7 @@ const DocsFilters = ({ open, handleClose, setPage }) => {
))}
</FormGroup>
</div>
<div
{/* <div
style={{ paddingTop: "10px" }}
className="custom-drawer-sub-card-label"
>
@@ -161,7 +161,7 @@ const DocsFilters = ({ open, handleClose, setPage }) => {
/>
))}
</FormGroup>
</div>
</div> */}
</div>
<div className="custom-drawer-submit">
<button
@@ -195,6 +195,7 @@ DocsFilters.propTypes = {
open: PropType.any,
handleClose: PropType.func,
setPage: PropType.func,
category: PropType.string
};

export default DocsFilters;

+ 25
- 3
src/pages/FilesPage/AddFile.js Wyświetl plik

@@ -17,10 +17,11 @@ import { uploadFileReq } from "../../store/actions/uploadFile/uploadFileActions"
import { FILES_VIEW_PAGE } from "../../constants/pages";
import PropTypes from "prop-types";

const AddFile = ({history}) => {
const AddFile = ({ history }) => {
const [dropzoneActive, setDropzoneActive] = useState(false);
const [pdfFile, setPdfFile] = useState(null);
const [title, setTitle] = useState("");
const [showMessage, setShowMessage] = useState(false);
const dispatch = useDispatch();
const categories = useSelector(selectCategories);
const tags = useSelector(selectTags);
@@ -35,9 +36,18 @@ const AddFile = ({history}) => {
const onSuccessUploadFile = () => {
dispatch(resetIsCheckedTagsValue());
setPdfFile(null);
setTitle("")
setTitle("");
setShowMessage(true);
};

useEffect(() => {
if (showMessage === true) {
setTimeout(() => {
setShowMessage(false);
}, 1000);
}
}, [showMessage]);

const handleDrop = (e) => {
e.preventDefault();
const selectedFile = e.dataTransfer.files[0];
@@ -75,6 +85,8 @@ const AddFile = ({history}) => {

return (
<div className="files-page">
<div className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div>
<div className="files-page-card">
<div className="files-page-card-title">
<h1>Title</h1>
@@ -200,8 +212,18 @@ const AddFile = ({history}) => {
</div>
</div>

<div
className="add-file-message"
style={showMessage === false ? { display: "none" } : { display: "flex" }}
>
<p>Uspesno dodat fajl</p>
</div>

<div className="files-page-card">
<div className="files-page-card-add-button" style={{alignItems:'center'}}>
<div
className="files-page-card-add-button"
style={{ alignItems: "center" }}
>
<p
className="applicant-ads-back-button"
onClick={() => history.push(FILES_VIEW_PAGE)}

+ 57
- 13
src/pages/FilesPage/FilesPage.js Wyświetl plik

@@ -1,21 +1,65 @@
import React, { useEffect } from 'react'
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import { useSelector, useDispatch } from "react-redux";
import IconButton from "../../components/IconButton/IconButton";
import { setCategoriesReq } from "../../store/actions/categories/categoriesAction";
import { selectCategories } from "../../store/selectors/categoriesSelector";
import { useDispatch, useSelector } from 'react-redux';
import table from "../../assets/images/table.png";
import { FILES_VIEW_PAGE } from "../../constants/pages";

const FilesPage = () => {
const dispatch = useDispatch()
const FilesPage = ({ history }) => {
const categories = useSelector(selectCategories);
const dispatch = useDispatch();

useEffect(() => {
dispatch(setCategoriesReq());
})
}, []);

return (
<div>
{categories.map((category,index) => (
<p key={index}>{category.name}</p>
)) }
</div>
)
}
<>
<div className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div>
<div className="pl-144" style={{ paddingTop: "36px" }}>
<div style={{ marginBottom: "39px" }}>
<h1 className="page-heading">Kategorije</h1>
</div>
<div className="files-page-categories">
{categories &&
categories.map((category) => (
<div className="files-page-categories-category" key={category.id}>
<IconButton
className="c-btn c-btn--primary-outlined files-page-category-button"
data-testid="pattern-details-send-email"
onClick={() =>
history.push(FILES_VIEW_PAGE, { category: category.name })
}
>
<img
style={{
marginRight: "5px",
width: "12px",
height: "12px",
}}
src={table}
/>
{category.name}
</IconButton>
</div>
))}
</div>
</div>
</>
);
};

FilesPage.propTypes = {
history: PropTypes.shape({
replace: PropTypes.func,
push: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
}),
}),
};

export default FilesPage
export default FilesPage;

+ 40
- 15
src/pages/FilesPage/FilesViewPage.js Wyświetl plik

@@ -8,6 +8,7 @@ import FilterButton from "../../components/Button/FilterButton";
import DocsFilters from "../../components/Docs/DocsFilters";
import { FETCH_FILES_LOADING } from "../../store/actions/files/fileActionConstants";
import {
deleteFileReq,
getFileFiltersReq,
getFilesReq,
} from "../../store/actions/files/fileActions";
@@ -17,20 +18,27 @@ import Fade from "@mui/material/Fade";
import { useTranslation } from "react-i18next";
import searchImage from "../../assets/images/search.png";
import IconButton from "../../components/IconButton/IconButton";
import { ADD_FILE } from "../../constants/pages";
import { ADD_FILE, FILES_PAGE } from "../../constants/pages";
import PropTypes from "prop-types";
import { useLocation } from "react-router";
import deleteIcon from "../../assets/images/delete.png";

const FilesViewPage = ({history}) => {
const FilesViewPage = ({ history }) => {
const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false);
const [page, setPage] = useState(1);
const { filters } = useSelector((s) => s.fileFilters);
const { data } = useSelector((s) => s.files);
const { t } = useTranslation();
const [isSearchFieldVisible, setIsSearchFieldVisible] = useState(false);
const { state } = useLocation();
// const [timer, setTimer] = useState(null);

const dispatch = useDispatch();

if (state === undefined) {
history.replace(FILES_PAGE);
}

const handleToggleFiltersDrawer = () => {
setToggleFiltersDrawer((oldState) => !oldState);
};
@@ -42,7 +50,7 @@ const FilesViewPage = ({history}) => {
payload: {
pageSize: 6,
currentPage: page,
categories: [],
categories: [state && state.category],
extensions: [],
tags: [],
content: "",
@@ -52,10 +60,10 @@ const FilesViewPage = ({history}) => {
}, []);

const handleChange = (_, value) => {
var catFilters = [];
filters.categories
?.filter((n) => n.isChecked)
.forEach((m) => catFilters.push(m.name));
var catFilters = [state && state.category];
// filters.categories
// ?.filter((n) => n.isChecked)
// .forEach((m) => catFilters.push(m.name));

var extFilters = [];
filters.extensions
@@ -98,13 +106,13 @@ const FilesViewPage = ({history}) => {
dispatch(setContent(value));
};

const deleteFileHandler = (stream_id) => {
dispatch(deleteFileReq({ id: stream_id }));
};

const handleKeyDown = (event) => {
console.log(filters.content);
if (event.key === "Enter" && filters.content !== "") {
var catFilters = [];
filters.categories
?.filter((n) => n.isChecked)
.forEach((m) => catFilters.push(m.name));
var catFilters = [state && state.category];

var extFilters = [];
filters.extensions
@@ -161,9 +169,9 @@ const FilesViewPage = ({history}) => {
open={toggleFiltersDrawer}
handleClose={handleToggleFiltersDrawer}
setPage={setPage}
category={state && state.category}
/>
<div
// onClick={() => setIsSearchFieldVisible(false)}
className="pl-144 flex-center"
style={{
paddingTop: "36px",
@@ -193,7 +201,6 @@ const FilesViewPage = ({history}) => {
</Fade>
</div>
<div className="flex-center">
{/* <button></button> */}
<IconButton
className="c-btn c-btn--primary-outlined candidate-btn search-field userPageBtn ml-20px no-padding custom-filter-button"
onClick={handleChangeVisibility}
@@ -206,7 +213,6 @@ const FilesViewPage = ({history}) => {
</div>
<div
className="pl-144"
// onClick={() => setIsSearchFieldVisible(false)}
style={{
display: "flex",
marginTop: "39px",
@@ -243,6 +249,11 @@ const FilesViewPage = ({history}) => {
{/* Document size (MB) */}
Veličina dokumenta
</th>
<th>
{/* {t("users.position")} */}
{/* Document size (MB) */}
Obriši dokument
</th>
{/* <th> */}
{/* {t("users.position")} */}
{/* Document size (MB) */}
@@ -261,6 +272,20 @@ const FilesViewPage = ({history}) => {
<td className="docs-name">{n.title}</td>
<td>{n.file_type && n.file_type}</td>
<td className="profession">{n.cached_file_size}kB</td>
<td className="profession">
<IconButton
className="c-btn c-btn--primary-outlined files-view-page-delete-btn"
onClick={() => deleteFileHandler(n.stream_id)}
>
<img
style={{
width: "12px",
height: "12px",
}}
src={deleteIcon}
/>
</IconButton>
</td>
</tr>
))}
</tbody>

+ 1
- 0
src/request/apiEndpoints.js Wyświetl plik

@@ -83,5 +83,6 @@ export default {
files: {
uploadFile: base + "/files",
all: base + "/files/filtered",
deleteFile: base + "/files/delete-file",
},
};

+ 3
- 1
src/request/filesRequest.js Wyświetl plik

@@ -1,5 +1,7 @@
import { postRequest } from ".";
import { deleteRequest, postRequest } from ".";
import apiEndpoints from "./apiEndpoints";

export const uploadFileRequest = (payload) =>
postRequest(apiEndpoints.files.uploadFile, payload);
export const deleteFileRequest = (id) =>
deleteRequest(apiEndpoints.files.deleteFile + "/" + id);

+ 5
- 0
src/store/actions/files/fileActionConstants.js Wyświetl plik

@@ -20,3 +20,8 @@ export const FETCH_FILES_REQ = createFetchType(FETCH_FILES_SCOPE);
export const FETCH_FILES_ERR = createErrorType(FETCH_FILES_SCOPE);
export const FETCH_FILES_SUCCESS = createSuccessType(FETCH_FILES_SCOPE);
export const FETCH_FILES_LOADING = createLoadingType(FETCH_FILES_SCOPE);

const DELETE_FILE_SCOPE = "DELETE_FILE"
export const DELETE_FILE_REQ = createFetchType(DELETE_FILE_SCOPE)
export const DELETE_FILE_ERR = createErrorType(DELETE_FILE_SCOPE)
export const DELETE_FILE_SUCCESS = createSuccessType(DELETE_FILE_SCOPE)

+ 20
- 2
src/store/actions/files/fileActions.js Wyświetl plik

@@ -8,7 +8,10 @@ import {
UPDATE_FILTERS_CATEGORY,
UPDATE_FILTERS_EXTENSION,
UPDATE_FILTERS_TAG,
SET_CONTENT
SET_CONTENT,
DELETE_FILE_REQ,
DELETE_FILE_ERR,
DELETE_FILE_SUCCESS
} from "./fileActionConstants";

export const getFileFiltersReq = () => ({
@@ -56,4 +59,19 @@ export const getFileSuccess = (payload) => ({
export const setContent = (payload) => ({
type:SET_CONTENT,
payload
})
})

export const deleteFileReq = (payload) => ({
type: DELETE_FILE_REQ,
payload
});

export const deleteFileError = (payload) => ({
type: DELETE_FILE_ERR,
payload,
});

export const deleteFileAction = (payload) => ({
type: DELETE_FILE_SUCCESS,
payload
});

+ 18
- 0
src/store/reducers/files/getFilesReducer.js Wyświetl plik

@@ -3,6 +3,10 @@ import {
FETCH_FILES_ERR,
FETCH_FILES_SUCCESS,
} from "../../actions/files/fileActionConstants";
import {
DELETE_FILE_ERR,
DELETE_FILE_SUCCESS,
} from "../../actions/files/fileActionConstants";

const initialState = {
data: {},
@@ -13,6 +17,8 @@ export default createReducer(
{
[FETCH_FILES_SUCCESS]: setFiles,
[FETCH_FILES_ERR]: setFilesErrorMessage,
[DELETE_FILE_SUCCESS]: deleteFileReducer,
[DELETE_FILE_ERR]: deleteFileReducerError,
},
initialState
);
@@ -30,3 +36,15 @@ function setFilesErrorMessage(state, action) {
fetchFilesErrorMessage: action.payload,
};
}

function deleteFileReducer(state, action) {
const newArr = state.data.data.filter(x => x.stream_id !== action.payload)
return { ...state, data: {...state.data, data: newArr} };
}

function deleteFileReducerError(state, action) {
return {
...state,
fetchFilesErrorMessage: action.payload,
};
}

+ 1
- 1
src/store/reducers/index.js Wyświetl plik

@@ -78,5 +78,5 @@ export default combineReducers({
categories: categoriesReducer,
tags: tagsReducer,
fileFilters: fileFiltersReducer,
files: getFilesReducer
files: getFilesReducer,
});

+ 19
- 3
src/store/saga/filesSaga.js Wyświetl plik

@@ -8,10 +8,10 @@ import { JWT_TOKEN } from "../../constants/localStorage";
import { addHeaderToken } from "../../request";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";
import { UPLOAD_FILE_REQ } from "../actions/uploadFile/uploadFileActionConstants";
import { uploadFileRequest } from "../../request/filesRequest";
import { deleteFileRequest, 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 { DELETE_FILE_REQ, FETCH_FILES_REQ } from "../actions/files/fileActionConstants";
import { deleteFileAction, deleteFileError, getFileError, getFileSuccess } from "../actions/files/fileActions";

export function* uploadFileSaga({ payload }) {
try {
@@ -46,7 +46,23 @@ export function* getAll({ payload }) {
}
}
}

export function* deleteFileSaga({ payload }) {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
yield call(deleteFileRequest, payload.id);
yield put(deleteFileAction(payload.id))
} catch (error) {
if (error.response && error.response.data) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(deleteFileError(errorMessage));
}
}
}

export default function* filesSaga() {
yield all([takeLatest(UPLOAD_FILE_REQ, uploadFileSaga)]);
yield all([takeEvery(FETCH_FILES_REQ, getAll)]);
yield all([takeLatest(DELETE_FILE_REQ, deleteFileSaga)]);
}

Ładowanie…
Anuluj
Zapisz