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

Implemented add category & added new design

FE_dev
bronjaermin 2 лет назад
Родитель
Сommit
663d0d9435

+ 89
- 1257
package-lock.json
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 35
- 0
src/assets/styles/components/_files.scss Просмотреть файл

@@ -169,3 +169,38 @@
.files-file-routing:hover {
background-color: #f0f0f0;
}

.add-categories-files {
display: flex;
}

.add-categories-files > * {
margin-left: 6px !important;
}

.files-page-card-input {
display: flex;
}

.add-category-input input,
.files-page-card-input input {
width: 100%;
border: 1px solid #e4e4e4 !important;
padding: 16.5px 20px !important;
border-radius: 4px;
outline: none;
}

.files-page-card-input > button {
margin-left: 6px;
}

.files-category-custom-modal-buttons {
display: flex;
justify-content: flex-end;
margin-top: 12px;
}

.files-category-custom-modal-buttons button {
margin-left: 8px;
}

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

@@ -16,6 +16,7 @@ import {
updateFileFilterTag,
} from "../../store/actions/files/fileActions";
import { useParams } from "react-router-dom";
import { PAGE_SIZE_FILES } from "../../constants/keyCodeConstants";

const DocsFilters = ({ open, handleClose, setPage, setFile }) => {
const dispatch = useDispatch();
@@ -43,7 +44,7 @@ const DocsFilters = ({ open, handleClose, setPage, setFile }) => {
dispatch(
getFilesReq({
payload: {
pageSize: 6,
pageSize: PAGE_SIZE_FILES,
currentPage: 1,
categoryId: id,
extensions: extFilters,

+ 12
- 2
src/components/Files/TreeViewFiles.js Просмотреть файл

@@ -6,8 +6,9 @@ import TreeItem from "@mui/lab/TreeItem";
import { useDispatch, useSelector } from "react-redux";
import { setAllCategoriesReq } from "../../store/actions/categories/categoriesAction";
import { selectAllCategories } from "../../store/selectors/categoriesSelector";
import PropTypes from "prop-types";

function TreeViewFiles() {
function TreeViewFiles({ onSelectCategory }) {
const dispatch = useDispatch();
const categories = useSelector(selectAllCategories);
useEffect(() => {
@@ -15,7 +16,12 @@ function TreeViewFiles() {
}, []);

const renderTree = (nodes) => (
<TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.name}>
<TreeItem
key={nodes.id}
nodeId={nodes.id}
label={nodes.name}
onClick={() => onSelectCategory({ id: nodes.id, name: nodes.name })}
>
{Array.isArray(nodes.treeViewCategories)
? nodes.treeViewCategories.map((node) => renderTree(node))
: null}
@@ -38,4 +44,8 @@ function TreeViewFiles() {
);
}

TreeViewFiles.propTypes = {
onSelectCategory: PropTypes.func,
};

export default TreeViewFiles;

+ 36
- 14
src/pages/FilesPage/AddFile.js Просмотреть файл

@@ -14,9 +14,10 @@ import {
} from "../../store/actions/tags/tagsAction";
import { selectTags } from "../../store/selectors/tagsSelector";
import { uploadFileReq } from "../../store/actions/uploadFile/uploadFileActions";
import { FILES_VIEW_PAGE } from "../../constants/pages";
import { FILES_PAGE } from "../../constants/pages";
import PropTypes from "prop-types";
import TreeViewFiles from "../../components/Files/TreeViewFiles";
import Button from "../../components/Button/Button";

const AddFile = ({ history }) => {
const [dropzoneActive, setDropzoneActive] = useState(false);
@@ -26,7 +27,10 @@ const AddFile = ({ history }) => {
const dispatch = useDispatch();
// const categories = useSelector(selectCategories);
const tags = useSelector(selectTags);
// const [selectedCategory, setSelectedCategory] = useState(null);
const [selectedCategory, setSelectedCategory] = useState({
id: -1,
name: "",
});
const { t } = useTranslation();

useEffect(() => {
@@ -39,6 +43,7 @@ const AddFile = ({ history }) => {
setPdfFile(null);
setTitle("");
setShowMessage(true);
setSelectedCategory({ id: -1, name: "" });
};

useEffect(() => {
@@ -61,9 +66,9 @@ const AddFile = ({ history }) => {
setPdfFile(selectedFile);
};

// const selectCategoryHandler = (e) => {
// setSelectedCategory(e.target.value);
// };
const selectCategoryHandler = (category) => {
setSelectedCategory(category);
};

const onChangeTagsCheckbox = (id) => {
dispatch(changeTagIsCheckedValue(id));
@@ -74,17 +79,12 @@ const AddFile = ({ history }) => {
.filter((tag) => tag.isChecked === true)
.map((tag) => Number(tag.id));

if (
title === "" ||
tagsIds.length === 0 ||
pdfFile === null
)
return;
if (title === "" || tagsIds.length === 0 || pdfFile === null) return;

dispatch(
uploadFileReq({
title,
categoryId: -1,
categoryId: selectedCategory.id,
tagsIds,
fileToUpload: pdfFile,
onSuccessUploadFile,
@@ -120,7 +120,29 @@ const AddFile = ({ history }) => {
</MenuItem>
))}
</Select> */}
<TreeViewFiles/>
<TreeViewFiles onSelectCategory={selectCategoryHandler} />
</div>
</div>

<div className="files-page-card">
<div className="files-page-card-title">
<h1>Selected Category</h1>
</div>
<div className="files-page-card-input">
<input
type="text"
disabled={true}
value={selectedCategory.id !== -1 ? selectedCategory.name : "null"}
/>
<Button
type="button"
variant="contained"
className="c-btn c-btn--primary"
onClick={() => setSelectedCategory({ id: -1, name: "" })}
disabled={selectedCategory.id === -1}
>
Set root
</Button>
</div>
</div>

@@ -224,7 +246,7 @@ const AddFile = ({ history }) => {
>
<p
className="applicant-ads-back-button"
onClick={() => history.push(FILES_VIEW_PAGE)}
onClick={() => history.push(FILES_PAGE)}
>
Nazad na sve fajlove
</p>

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

@@ -2,7 +2,10 @@ import React, { useEffect, useState } 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 {
createCategoryReq,
setCategoriesReq,
} from "../../store/actions/categories/categoriesAction";
import {
selectCategories,
selectChildParentRelations,
@@ -12,12 +15,18 @@ import { FILES_PAGE } from "../../constants/pages";
import FileTable from "./FileTable";
import { useParams } from "react-router-dom";
import { ADD_FILE } from "../../constants/pages";
import CustomModal from "../../components/UI/CustomModal";
import xIcon from "../../assets/images/x.png";
import plusIcon from "../../assets/images/plus.png";
import Button from "../../components/Button/Button";

const FilesPage = ({ history }) => {
const categories = useSelector(selectCategories);
const childParentRelations = useSelector(selectChildParentRelations);
const dispatch = useDispatch();
const [trigger, setTrigger] = useState(0);
const [openCreateCategoryModal, setOpenCreateCategoryModal] = useState(false);
const [createCategoryName, setCreateCategoryName] = useState("");
let { id } = useParams();

useEffect(() => {
@@ -28,11 +37,33 @@ const FilesPage = ({ history }) => {
}
}, [id]);

const changeOpenCreateCategoryModal = () => {
setOpenCreateCategoryModal((oldState) => !oldState);
};

const getNameHandler = (name) => {
if (name.length > 15) return name.substr(0, 15) + "...";
return name;
};

const onSuccessCreatingCategoryHandler = () => {
dispatch(
setCategoriesReq(id === undefined ? undefined : { parentCategoryId: id })
);
setOpenCreateCategoryModal(false);
};

const createCategoryHandler = () => {
dispatch(
createCategoryReq({
name: createCategoryName,
parentId: id !== undefined ? id : null,
onSuccess: onSuccessCreatingCategoryHandler,
})
);
setCreateCategoryName("");
};

const ColoredLine = () => (
<hr
style={{
@@ -47,6 +78,54 @@ const FilesPage = ({ history }) => {
<>
<div className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div>
<CustomModal
classes="files-custom-modal"
open={openCreateCategoryModal}
onCloseModal={changeOpenCreateCategoryModal}
>
<div className="add-pattern-modal-header">
<div className="add-pattern-modal-header-title">
<div className="add-pattern-modal-header-title-image">
<img src={plusIcon} alt="plus" />
</div>
<div className="add-pattern-modal-header-title-title">
<p>Create category</p>
</div>
</div>
<div
className="add-pattern-modal-header-close"
onClick={changeOpenCreateCategoryModal}
>
<img src={xIcon} alt="close" />
</div>
</div>
<div className="add-category-input">
<input
type="text"
placeholder="Category name"
value={createCategoryName}
onChange={(e) => setCreateCategoryName(e.target.value)}
/>
</div>
<div className="files-category-custom-modal-buttons">
<Button
type="button"
variant="contained"
className="c-btn c-btn--primary-outlined"
onClick={changeOpenCreateCategoryModal}
>
Close
</Button>
<Button
type="button"
variant="contained"
className="c-btn c-btn--primary"
onClick={createCategoryHandler}
>
Create category
</Button>
</div>
</CustomModal>
<div
className="pl-144"
style={{ paddingTop: "36px" }}
@@ -64,7 +143,7 @@ const FilesPage = ({ history }) => {
}}
>
<h1 className="page-heading">Folderi</h1>
<div style={{ display: "flex" }}>
<div className="add-categories-files">
<IconButton
className="c-btn ads-page-btn c-btn--primary add-ad-btn filesPage"
onClick={() => history.push(ADD_FILE)}
@@ -73,7 +152,7 @@ const FilesPage = ({ history }) => {
</IconButton>
<IconButton
className="c-btn ads-page-btn c-btn--primary add-ad-btn filesPage"
onClick={() => history.push(ADD_FILE)}
onClick={changeOpenCreateCategoryModal}
>
+ Kategorija
</IconButton>

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

@@ -28,6 +28,7 @@ import editIcon from "../../assets/images/edit.png";
import xIcon from "../../assets/images/x.png";
import ConfirmDialog from "../../components/MUI/ConfirmDialog";
import CustomModal from "../../components/UI/CustomModal";
import { PAGE_SIZE_FILES } from "../../constants/keyCodeConstants";

const FilesViewPage = ({ history }) => {
const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false);
@@ -68,7 +69,7 @@ const FilesViewPage = ({ history }) => {
dispatch(
getFilesReq({
payload: {
pageSize: 6,
pageSize: PAGE_SIZE_FILES,
currentPage: page,
categories: [state && state.category],
extensions: [],
@@ -100,7 +101,7 @@ const FilesViewPage = ({ history }) => {
dispatch(
getFilesReq({
payload: {
pageSize: 6,
pageSize: PAGE_SIZE_FILES,
currentPage: value,
categories: catFilters,
extensions: extFilters,
@@ -151,7 +152,7 @@ const FilesViewPage = ({ history }) => {
dispatch(
getFilesReq({
payload: {
pageSize: 6,
pageSize: PAGE_SIZE_FILES,
currentPage: page,
categories: catFilters,
extensions: extFilters,

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

@@ -73,7 +73,8 @@ export default {
rootCategories: base + "/categories/root-categories",
isCategoriesChecked: base + "/categories/granted-categories",
grantCategory: base + "/users/grant-category",
allCategories:base + "/categories/all-categories"
allCategories: base + "/categories/all-categories",
createCategory: base + "/categories",
},
tags: {
allTags: base + "/tags/names",

+ 3
- 0
src/request/categoriesRequest.js Просмотреть файл

@@ -15,3 +15,6 @@ export const grantCategoryRequest = (payload) =>

export const getAllCategories = () =>
getRequest(apiEndpoints.categories.allCategories);

export const createCategoryRequest = (payload) =>
postRequest(apiEndpoints.categories.createCategory, payload);

+ 17
- 0
src/store/actions/categories/categoriesAction.js Просмотреть файл

@@ -12,6 +12,9 @@ import {
FETCH_ALL_CATEGORIES_ERR,
FETCH_ALL_CATEGORIES_REQ,
FETCH_ALL_CATEGORIES_SUCCESS,
CREATE_CATEGORY_REQ,
CREATE_CATEGORY_ERR,
CREATE_CATEGORY_SUCCESS,
} from "./categoriesActionConstants";

export const setCategoriesReq = (payload) => ({
@@ -77,3 +80,17 @@ export const setAllCategories = (payload) => ({
type: FETCH_ALL_CATEGORIES_SUCCESS,
payload,
});

export const createCategoryReq = (payload) => ({
type: CREATE_CATEGORY_REQ,
payload,
});

export const createCategoryError = () => ({
type: CREATE_CATEGORY_ERR
});

export const setCreateCategory = (payload) => ({
type: CREATE_CATEGORY_SUCCESS,
payload,
});

+ 5
- 0
src/store/actions/categories/categoriesActionConstants.js Просмотреть файл

@@ -8,6 +8,7 @@ const FETCH_ROOT_CATEGORIES_SCOPE = "FETCH_ROOT_CATEGORIES";
const FETCH_IS_CATEGORIES_CHECKED_SCOPE = "FETCH_IS_CATEGORIES_CHECKED";
const GRANT_CATEGORY_SCOPE = "GRANT_CATEGORY";
const FETCH_ALL_CATEGORIES_SCOPE = "FETCH_ALL_CATEGORIES";
const CREATE_CATEGORY_SCOPE = "CREATE_CATEGORY";

export const FETCH_ROOT_CATEGORIES_REQ = createFetchType(
FETCH_ROOT_CATEGORIES_SCOPE
@@ -36,4 +37,8 @@ export const FETCH_ALL_CATEGORIES_REQ = createFetchType(FETCH_ALL_CATEGORIES_SCO
export const FETCH_ALL_CATEGORIES_ERR = createErrorType(FETCH_ALL_CATEGORIES_SCOPE);
export const FETCH_ALL_CATEGORIES_SUCCESS = createSuccessType(FETCH_ALL_CATEGORIES_SCOPE);

export const CREATE_CATEGORY_REQ = createFetchType(CREATE_CATEGORY_SCOPE);
export const CREATE_CATEGORY_ERR = createErrorType(CREATE_CATEGORY_SCOPE);
export const CREATE_CATEGORY_SUCCESS = createSuccessType(CREATE_CATEGORY_SCOPE);

export const CHANGE_IC_CHECKED_CATEGORY = "CHANGE_IC_CHECKED_CATEGORY";

+ 22
- 5
src/store/reducers/category/categoriesReducer.js Просмотреть файл

@@ -7,14 +7,16 @@ import {
GRANT_CATEGORY_ERR,
GRANT_CATEGORY_SUCCESS,
FETCH_ALL_CATEGORIES_ERR,
FETCH_ALL_CATEGORIES_SUCCESS
FETCH_ALL_CATEGORIES_SUCCESS,
CREATE_CATEGORY_SUCCESS,
CREATE_CATEGORY_ERR,
} from "../../actions/categories/categoriesActionConstants";
import createReducer from "../../utils/createReducer";

const initialState = {
categories: [],
childParentRelations: [],
allCategories:[],
allCategories: [],
isCategoriesChecked: [],
changedCategories: [],
errorMessage: "",
@@ -31,6 +33,8 @@ export default createReducer(
[GRANT_CATEGORY_ERR]: setGrantCategoriesErrorMessage,
[FETCH_ALL_CATEGORIES_SUCCESS]: setStateAllCategories,
[FETCH_ALL_CATEGORIES_ERR]: setStateAllCategoriesErrorMessage,
[CREATE_CATEGORY_SUCCESS]: setCreateCategoryReducer,
[CREATE_CATEGORY_ERR]: setCreateCategoryErrorMessage,
},
initialState
);
@@ -39,7 +43,7 @@ function setStateCategories(state, action) {
return {
...state,
categories: action.payload.categories,
childParentRelations: action.payload.childParentRelations
childParentRelations: action.payload.childParentRelations,
};
}

@@ -101,7 +105,7 @@ function setIsCheckedCategory(state, action) {
function setStateGrantCategories(state) {
return {
...state,
changedCategories: []
changedCategories: [],
};
}

@@ -115,7 +119,7 @@ function setGrantCategoriesErrorMessage(state, action) {
function setStateAllCategories(state, action) {
return {
...state,
allCategories:action.payload
allCategories: action.payload,
};
}

@@ -125,3 +129,16 @@ function setStateAllCategoriesErrorMessage(state, action) {
errorMessage: action.payload,
};
}

function setCreateCategoryReducer(state) {
return {
...state,
};
}

function setCreateCategoryErrorMessage(state, action) {
return {
...state,
errorMessage: action.payload,
};
}

+ 29
- 4
src/store/saga/categoriesSaga.js Просмотреть файл

@@ -7,7 +7,8 @@ import {
setGrantCategories,
setGrantCategoriesError,
setAllCategories,
setAllCategoriesError
setAllCategoriesError,
setCreateCategory,
} from "../actions/categories/categoriesAction";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { JWT_TOKEN } from "../../constants/localStorage";
@@ -17,14 +18,16 @@ import {
FETCH_ROOT_CATEGORIES_REQ,
FETCH_IS_CATEGORIES_CHECKED_REQ,
GRANT_CATEGORY_REQ,
FETCH_ALL_CATEGORIES_REQ
FETCH_ALL_CATEGORIES_REQ,
CREATE_CATEGORY_REQ,
} from "../actions/categories/categoriesActionConstants";
import {
getRootCategories,
getIsCategoriesChecked,
grantCategoryRequest,
getRootCategories2,
getAllCategories
getAllCategories,
createCategoryRequest,
} from "../../request/categoriesRequest";

export function* getRootCategoriesSaga({ payload }) {
@@ -37,7 +40,12 @@ export function* getRootCategoriesSaga({ payload }) {
} else {
result = yield call(getRootCategories2, payload.parentCategoryId);
}
yield put(setCategories({categories: result.data.categories, childParentRelations: result.data.childParentRelations}));
yield put(
setCategories({
categories: result.data.categories,
childParentRelations: result.data.childParentRelations,
})
);
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(setCategoriesError(errorMessage));
@@ -80,11 +88,28 @@ export function* getAllCategoriesSaga() {
}
}

export function* createCategorySaga({ payload }) {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
yield call(createCategoryRequest, {
name: payload.name,
parentId: payload.parentId,
});
yield put(setCreateCategory());
if (payload.onSuccess) yield call(payload.onSuccess);
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(setGrantCategoriesError(errorMessage));
}
}

export default function* categoriesSaga() {
yield all([
takeLatest(FETCH_ROOT_CATEGORIES_REQ, getRootCategoriesSaga),
takeLatest(FETCH_IS_CATEGORIES_CHECKED_REQ, getIsCategoriesCheckedSaga),
takeLatest(GRANT_CATEGORY_REQ, grantCategoriesCheckedSaga),
takeLatest(FETCH_ALL_CATEGORIES_REQ, getAllCategoriesSaga),
takeLatest(CREATE_CATEGORY_REQ, createCategorySaga),
]);
}

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

@@ -50,6 +50,7 @@ export function* getAll({ payload }) {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);

const result = yield call(getAllFilesReq, payload.payload);
yield put(getFileSuccess(result.data));
if (payload.payload.onSuccess) {

+ 12590
- 12993
yarn.lock
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


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