Explorar el Código

tag can now be added from frontend

FE_dev
Dzenis Hadzifejzovic hace 2 años
padre
commit
24630b1949

+ 5
- 1
src/assets/styles/components/_files.scss Ver fichero



.files-button-responsive { .files-button-responsive {
gap: 5px; gap: 5px;
width: 105px;
width: 85px;
height: 31px; height: 31px;
} }


.add-categories-files > button:first-child {
margin-left: 0px !important;
}

.file-viewer-close-btn { .file-viewer-close-btn {
width: 100px; width: 100px;
align-self: flex-end; align-self: flex-end;

+ 13
- 7
src/components/MUI/NavbarComponent.js Ver fichero

import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import LogoutIcon from "@mui/icons-material/Logout"; import LogoutIcon from "@mui/icons-material/Logout";
import UserProfile from "../Profile/UserProfile"; import UserProfile from "../Profile/UserProfile";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
//import { userSelector } from "../../store/selectors/userSelectors"; //import { userSelector } from "../../store/selectors/userSelectors";
import { Link, useLocation } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import rs from "../../assets/images/rs.png"; import rs from "../../assets/images/rs.png";
import en from "../../assets/images/en.png"; import en from "../../assets/images/en.png";
import { logoutUser } from "../../store/actions/login/loginActions";


const NavbarComponent = () => { const NavbarComponent = () => {
const navItems = [
"users",
"files"
];
const navItems = ["users", "files"];
const { pathname } = useLocation(); const { pathname } = useLocation();
const [openDrawer, setOpenDrawer] = useState(false); const [openDrawer, setOpenDrawer] = useState(false);
const [preview, setPreview] = useState(false); const [preview, setPreview] = useState(false);
const theme = useTheme(); const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down("sm")); const matches = useMediaQuery(theme.breakpoints.down("sm"));
const dispatch = useDispatch();
// const toggleColorMode = useContext(ColorModeContext); // const toggleColorMode = useContext(ColorModeContext);


const logout = () => {
dispatch(logoutUser());
};

let userRef = useRef(); let userRef = useRef();
let btnRef = useRef(); let btnRef = useRef();


}; };


const filterNavItems = () => { const filterNavItems = () => {
return navItems.filter(n => ((n === "users" && user.role === "SuperAdmin") || n !== "users"))
}
return navItems.filter(
(n) => (n === "users" && user.role === "SuperAdmin") || n !== "users"
);
};


useEffect(() => { useEffect(() => {
let handler = (e) => { let handler = (e) => {
{/* <Typography>s</Typography> */} {/* <Typography>s</Typography> */}
<div className="flex-center"> <div className="flex-center">
<Button <Button
onClick={logout}
sx={{ sx={{
padding: "18px 72px", padding: "18px 72px",
border: "1px solid #226cb0", border: "1px solid #226cb0",

+ 5
- 1
src/i18n/resources/en.js Ver fichero

addFileSuccessfullyAddedFile: "Successfully added file", addFileSuccessfullyAddedFile: "Successfully added file",
addFileGoBackToFiles: "Go back to all files", addFileGoBackToFiles: "Go back to all files",
createCategoryModalTitle: "Create category", createCategoryModalTitle: "Create category",
createTagModalTitle: "Create tag",
createCategoryModalPlaceholder: "Category name", createCategoryModalPlaceholder: "Category name",
createTagModalPlaceholder: "Tag name",
close: "Close", close: "Close",
createCategoryModalSubmitButton: "Create category", createCategoryModalSubmitButton: "Create category",
createTagModalSubmitButton: "Create tag",
folders: "Folders", folders: "Folders",
file: "File", file: "File",
files: "Files", files: "Files",
documents: "| Documents", documents: "| Documents",
extension: "Extension", extension: "Extension",
tags: "Tags", tags: "Tags",
search: "Search"
search: "Search",
tag:"Tag"
} }
}; };

+ 5
- 1
src/i18n/resources/rs.js Ver fichero

addFileSuccessfullyAddedFile: "Uspešno dodat fajl", addFileSuccessfullyAddedFile: "Uspešno dodat fajl",
addFileGoBackToFiles: "Nazad na sve fajlove", addFileGoBackToFiles: "Nazad na sve fajlove",
createCategoryModalTitle: "Napravite kategoriju", createCategoryModalTitle: "Napravite kategoriju",
createTagModalTitle: "Napravite tag",
createCategoryModalPlaceholder: "Naziv kategorije", createCategoryModalPlaceholder: "Naziv kategorije",
createTagModalPlaceholder: "Naziv taga",
close: "Izađite", close: "Izađite",
createCategoryModalSubmitButton: "Napravite kategoriju", createCategoryModalSubmitButton: "Napravite kategoriju",
createTagModalSubmitButton: "Napravite tag",
folders: "Folderi", folders: "Folderi",
file: "Fajl", file: "Fajl",
files: "Fajlovi", files: "Fajlovi",
documents: "| Dokumenti", documents: "| Dokumenti",
extension: "Ekstenzija", extension: "Ekstenzija",
tags: "Tagovi", tags: "Tagovi",
search: "Pretraži"
search: "Pretraži",
tag:"Tag"
}, },
}; };

+ 88
- 3
src/pages/FilesPage/FilesPage.js Ver fichero

createCategoryReq, createCategoryReq,
setCategoriesReq, setCategoriesReq,
} from "../../store/actions/categories/categoriesAction"; } from "../../store/actions/categories/categoriesAction";
import { createTagReq } from "../../store/actions/tags/tagsAction";
import { import {
selectCategories, selectCategories,
selectChildParentRelations, selectChildParentRelations,
const dispatch = useDispatch(); const dispatch = useDispatch();
const [trigger, setTrigger] = useState(0); const [trigger, setTrigger] = useState(0);
const [openCreateCategoryModal, setOpenCreateCategoryModal] = useState(false); const [openCreateCategoryModal, setOpenCreateCategoryModal] = useState(false);
const [openCreateTagModal, setOpenCreateTagModal] = useState(false);
const [createCategoryName, setCreateCategoryName] = useState(""); const [createCategoryName, setCreateCategoryName] = useState("");
const [createTagName, setCreateTagName] = useState("");
let { id } = useParams(); let { id } = useParams();
const theme = useTheme(); const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down("370")); const matches = useMediaQuery(theme.breakpoints.down("370"));
setOpenCreateCategoryModal((oldState) => !oldState); setOpenCreateCategoryModal((oldState) => !oldState);
}; };


const changeOpenCreateTagModal = () => {
setOpenCreateTagModal((oldState) => !oldState);
};

const getNameHandler = (name) => { const getNameHandler = (name) => {
if (matches) { if (matches) {
if (name.length > 7) return name.substr(0, 7) + "..."; if (name.length > 7) return name.substr(0, 7) + "...";
setOpenCreateCategoryModal(false); setOpenCreateCategoryModal(false);
}; };


const onSuccessCreatingTagHandler = () => {
setOpenCreateTagModal(false);
};

const createCategoryHandler = () => { const createCategoryHandler = () => {
dispatch( dispatch(
createCategoryReq({ createCategoryReq({
setCreateCategoryName(""); setCreateCategoryName("");
}; };


const createTagHandler = () => {
dispatch(
createTagReq({
name: createTagName,
onSuccess: onSuccessCreatingTagHandler,
})
);
setCreateTagName("");
};

const ColoredLine = () => ( const ColoredLine = () => (
<hr <hr
style={{ style={{


return ( return (
<> <>
<div className="l-t-rectangle"></div>
<div className="r-b-rectangle" style={{width:matches ? 100 : 180}}></div>
<div
className="l-t-rectangle"
style={{ height: matches ? 140 : 180 }}
></div>
<div
className="r-b-rectangle"
style={{ width: matches ? 100 : 180 }}
></div>
<CustomModal <CustomModal
classes="files-custom-modal" classes="files-custom-modal"
open={openCreateCategoryModal} open={openCreateCategoryModal}
</Button> </Button>
</div> </div>
</CustomModal> </CustomModal>
<CustomModal
classes="files-custom-modal"
open={openCreateTagModal}
onCloseModal={changeOpenCreateTagModal}
>
<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>{t("files.createTagModalTitle")}</p>
</div>
</div>
<div
className="add-pattern-modal-header-close"
onClick={changeOpenCreateTagModal}
>
<img src={xIcon} alt="close" />
</div>
</div>
<div className="add-category-input">
<input
type="text"
placeholder={t("files.createTagModalPlaceholder")}
value={createTagName}
onChange={(e) => setCreateTagName(e.target.value)}
/>
</div>
<div className="files-category-custom-modal-buttons">
<Button
type="button"
variant="contained"
className="c-btn c-btn--primary-outlined"
onClick={changeOpenCreateTagModal}
>
{t("files.close")}
</Button>
<Button
type="button"
variant="contained"
className="c-btn c-btn--primary"
onClick={createTagHandler}
>
{t("files.createTagModalSubmitButton")}
</Button>
</div>
</CustomModal>
<div <div
className="pl-144" className="pl-144"
style={{ paddingTop: "36px" }} style={{ paddingTop: "36px" }}
<div <div
style={{ style={{
display: "flex", display: "flex",
alignItems: "center",
alignItems: matches ? "flex-start" : "center",
flexDirection: matches ? "column" : "row",
justifyContent: "space-between", justifyContent: "space-between",
marginBottom: "15px", marginBottom: "15px",
}} }}
> >
+ {t("files.category")} + {t("files.category")}
</IconButton> </IconButton>
<IconButton
className={
`c-btn ads-page-btn c-btn--primary filesPage ` +
(matches ? "files-button-responsive" : "add-ad-btn")
}
onClick={changeOpenCreateTagModal}
>
+ {t("files.tag")}
</IconButton>
</div> </div>
</div> </div>
<ColoredLine /> <ColoredLine />

+ 4
- 3
src/request/tagsRequest.js Ver fichero

import { getRequest } from ".";
import { getRequest, postRequest } from ".";
import apiEndpoints from "./apiEndpoints"; import apiEndpoints from "./apiEndpoints";


export const getFileFilters = () => getRequest(apiEndpoints.fileTags.filters); export const getFileFilters = () => getRequest(apiEndpoints.fileTags.filters);
export const getAllTags = () =>
getRequest(apiEndpoints.tags.allTags);
export const getAllTags = () => getRequest(apiEndpoints.tags.allTags);
export const createTagRequest = (payload) =>
postRequest(apiEndpoints.fileTags.filters, payload);

+ 17
- 0
src/store/actions/tags/tagsAction.js Ver fichero

FETCH_TAGS_ERR, FETCH_TAGS_ERR,
CHANGE_TAG_ISCHECKED_VALUE, CHANGE_TAG_ISCHECKED_VALUE,
RESET_CHECKED_TAGS, RESET_CHECKED_TAGS,
CREATE_TAG_ERR,
CREATE_TAG_REQ,
CREATE_TAG_SUCCESS,
} from "./tagsActionConstants"; } from "./tagsActionConstants";


export const setTagsReq = () => ({ export const setTagsReq = () => ({
export const resetIsCheckedTagsValue = () => ({ export const resetIsCheckedTagsValue = () => ({
type: RESET_CHECKED_TAGS, type: RESET_CHECKED_TAGS,
}); });

export const createTagReq = (payload) => ({
type: CREATE_TAG_REQ,
payload,
});

export const createTagError = () => ({
type: CREATE_TAG_ERR,
});

export const setCreateTag = (payload) => ({
type: CREATE_TAG_SUCCESS,
payload,
});

+ 5
- 0
src/store/actions/tags/tagsActionConstants.js Ver fichero

} from "../actionHelpers"; } from "../actionHelpers";


const FETCH_TAGS_SCOPE = "FETCH_TAGS"; const FETCH_TAGS_SCOPE = "FETCH_TAGS";
const CREATE_TAG_SCOPE = "CREATE_TAG";


export const FETCH_TAGS_REQ = createFetchType(FETCH_TAGS_SCOPE); export const FETCH_TAGS_REQ = createFetchType(FETCH_TAGS_SCOPE);
export const FETCH_TAGS_ERR = createErrorType(FETCH_TAGS_SCOPE); export const FETCH_TAGS_ERR = createErrorType(FETCH_TAGS_SCOPE);


export const CHANGE_TAG_ISCHECKED_VALUE = "CHANGE_TAG_ISCHECKED_VALUE"; export const CHANGE_TAG_ISCHECKED_VALUE = "CHANGE_TAG_ISCHECKED_VALUE";
export const RESET_CHECKED_TAGS = "RESET_CHECKED_TAGS"; export const RESET_CHECKED_TAGS = "RESET_CHECKED_TAGS";

export const CREATE_TAG_REQ = createFetchType(CREATE_TAG_SCOPE);
export const CREATE_TAG_ERR = createErrorType(CREATE_TAG_SCOPE);
export const CREATE_TAG_SUCCESS = createSuccessType(CREATE_TAG_SCOPE);

+ 18
- 3
src/store/reducers/tag/tagsReducer.js Ver fichero

FETCH_TAGS_SUCCESS, FETCH_TAGS_SUCCESS,
CHANGE_TAG_ISCHECKED_VALUE, CHANGE_TAG_ISCHECKED_VALUE,
RESET_CHECKED_TAGS, RESET_CHECKED_TAGS,
CREATE_TAG_ERR,
CREATE_TAG_SUCCESS,
} from "../../actions/tags/tagsActionConstants"; } from "../../actions/tags/tagsActionConstants";
import createReducer from "../../utils/createReducer"; import createReducer from "../../utils/createReducer";


[FETCH_TAGS_ERR]: setTagsErrorMessage, [FETCH_TAGS_ERR]: setTagsErrorMessage,
[CHANGE_TAG_ISCHECKED_VALUE]: setIsCheckedTags, [CHANGE_TAG_ISCHECKED_VALUE]: setIsCheckedTags,
[RESET_CHECKED_TAGS]: resetIsCheckedTags, [RESET_CHECKED_TAGS]: resetIsCheckedTags,
[CREATE_TAG_SUCCESS]: setCreateTagReducer,
[CREATE_TAG_ERR]: setCreateTagErrorMessage,
}, },
initialState initialState
); );
} }


function setIsCheckedTags(state, action) { function setIsCheckedTags(state, action) {
const tmpIndex = state.tags.findIndex(
(x) => x.id === action.payload
);
const tmpIndex = state.tags.findIndex((x) => x.id === action.payload);


if (tmpIndex === -1) { if (tmpIndex === -1) {
return state; return state;
tags: state.tags.map((tag) => ({ ...tag, isChecked: false })), tags: state.tags.map((tag) => ({ ...tag, isChecked: false })),
}; };
} }

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

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

+ 26
- 3
src/store/saga/tagsSaga.js Ver fichero

import { all, call, put, takeLatest, takeEvery } from "redux-saga/effects"; import { all, call, put, takeLatest, takeEvery } from "redux-saga/effects";
import { setTags, setTagsError } from "../actions/tags/tagsAction";
import {
setTags,
setTagsError,
setCreateTag,
createTagError,
} from "../actions/tags/tagsAction";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { JWT_TOKEN } from "../../constants/localStorage"; import { JWT_TOKEN } from "../../constants/localStorage";
import { addHeaderToken } from "../../request"; import { addHeaderToken } from "../../request";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";
import { FETCH_TAGS_REQ } from "../actions/tags/tagsActionConstants";
import { FETCH_TAGS_REQ,CREATE_TAG_REQ } from "../actions/tags/tagsActionConstants";
import { getAllTags } from "../../request/tagsRequest"; import { getAllTags } from "../../request/tagsRequest";
import { getFileFilters } from "../../request/tagsRequest";
import { getFileFilters, createTagRequest } from "../../request/tagsRequest";
import { FILE_FILTERS_REQ } from "../actions/files/fileActionConstants"; import { FILE_FILTERS_REQ } from "../actions/files/fileActionConstants";
import { import {
getFileFiltersError, getFileFiltersError,
} }
} }
} }

export function* createTagSaga({ payload }) {
console.log("Payload je to",payload)
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
yield call(createTagRequest, {
name: payload.name,
});
yield put(setCreateTag());
if (payload.onSuccess) yield call(payload.onSuccess);
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(createTagError(errorMessage));
}
}

export default function* tagsSaga() { export default function* tagsSaga() {
yield all([takeLatest(FETCH_TAGS_REQ, getTags)]); yield all([takeLatest(FETCH_TAGS_REQ, getTags)]);
yield all([takeEvery(FILE_FILTERS_REQ, getFileFiltersGen)]); yield all([takeEvery(FILE_FILTERS_REQ, getFileFiltersGen)]);
yield all([takeEvery(CREATE_TAG_REQ, createTagSaga)]);
} }

Cargando…
Cancelar
Guardar