feature/upload_pdf_fe във FE_dev преди 3 години
| @@ -69,7 +69,6 @@ const ApplyForAdFourthStage = ({ | |||
| value={pdfFile} | |||
| data-testid="apply-for-ad-modal-fourth-stage-pdf-input" | |||
| onChange={(e) => { | |||
| console.log("Ovde smo"); | |||
| setPdfFile(e.target.files[0]); | |||
| }} | |||
| /> | |||
| @@ -17,8 +17,6 @@ const PatternFilters = ({ | |||
| const dispatch = useDispatch(); | |||
| const { t } = useTranslation(); | |||
| console.log("OVDE", selectionLevelFilter); | |||
| const submitFiltersHandler = (e) => { | |||
| e.preventDefault(); | |||
| @@ -3,65 +3,69 @@ import { Checkbox, FormControlLabel, MenuItem, Select } from "@mui/material"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import uploadIcon from "../../assets/images/upload.png"; | |||
| import IconButton from "../../components/IconButton/IconButton"; | |||
| import { useSelector, useDispatch } from "react-redux"; | |||
| import { selectCategories } from "../../store/selectors/categoriesSelector"; | |||
| import { useEffect } from "react"; | |||
| import { setCategoriesReq } from "../../store/actions/categories/categoriesAction"; | |||
| import { | |||
| changeTagIsCheckedValue, | |||
| resetIsCheckedTagsValue, | |||
| setTagsReq, | |||
| } from "../../store/actions/tags/tagsAction"; | |||
| import { selectTags } from "../../store/selectors/tagsSelector"; | |||
| import { uploadFileReq } from "../../store/actions/uploadFile/uploadFileActions"; | |||
| const FilesPage = () => { | |||
| const [dropzoneActive, setDropzoneActive] = useState(false); | |||
| const [pdfFile, setPdfFile] = useState(null); | |||
| const [categories, setCategories] = useState([ | |||
| { id: 1, value: "a" }, | |||
| { id: 2, value: "b" }, | |||
| { id: 3, value: "c" }, | |||
| { id: 4, value: "d" }, | |||
| { id: 5, value: "e" }, | |||
| { id: 6, value: "f" }, | |||
| { id: 7, value: "g" }, | |||
| { id: 8, value: "h" }, | |||
| ]); | |||
| const [tags, setTags] = useState([ | |||
| { id: 1, value: "a", isChecked: false }, | |||
| { id: 2, value: "a", isChecked: false }, | |||
| { id: 3, value: "a", isChecked: false }, | |||
| { id: 4, value: "a", isChecked: false }, | |||
| { id: 5, value: "a", isChecked: false }, | |||
| { id: 6, value: "a", isChecked: false }, | |||
| { id: 7, value: "a", isChecked: false }, | |||
| { id: 8, value: "a", isChecked: false }, | |||
| ]); | |||
| const dispatch = useDispatch(); | |||
| const categories = useSelector(selectCategories); | |||
| const tags = useSelector(selectTags); | |||
| const [selectedCategory, setSelectedCategory] = useState(null); | |||
| const { t } = useTranslation(); | |||
| console.log(selectedCategory); | |||
| useEffect(() => { | |||
| dispatch(setCategoriesReq()); | |||
| dispatch(setTagsReq()); | |||
| }, []); | |||
| const onSuccessUploadFile = () => { | |||
| dispatch(resetIsCheckedTagsValue()) | |||
| setPdfFile(null) | |||
| } | |||
| const handleDrop = (e) => { | |||
| e.preventDefault(); | |||
| const selectedFile = e.dataTransfer.files[0]; | |||
| const fileName = selectedFile.name; | |||
| const fileExtension = selectedFile.name.split(".").pop(); | |||
| const fileSize = selectedFile.size; | |||
| console.log(fileName, fileExtension, fileSize); | |||
| setPdfFile(selectedFile); | |||
| }; | |||
| const handleChangeInputFile = (e) => { | |||
| const selectedFile = e.target.files[0]; | |||
| const fileName = selectedFile.name; | |||
| const fileExtension = selectedFile.name.split(".").pop(); | |||
| const fileSize = selectedFile.size; | |||
| console.log(fileName, fileExtension, fileSize); | |||
| setPdfFile(selectedFile); | |||
| }; | |||
| const selectCategoryHandler = (e) => { | |||
| setSelectedCategory(e.target.value); | |||
| setCategories((oldState) => [...oldState]); | |||
| }; | |||
| const onChangeTagsCheckbox = (id) => { | |||
| const newArr = tags.map((x) => | |||
| x.id === id ? { ...x, isChecked: !x.isChecked } : x | |||
| ); | |||
| dispatch(changeTagIsCheckedValue(id)); | |||
| }; | |||
| const uploadFileHandler = () => { | |||
| const tagsIds = tags | |||
| .filter((tag) => tag.isChecked === true) | |||
| .map((tag) => Number(tag.id)); | |||
| setTags(newArr); | |||
| dispatch( | |||
| uploadFileReq({ | |||
| categoryId: selectedCategory, | |||
| tagsIds, | |||
| fileToUpload: pdfFile, | |||
| onSuccessUploadFile | |||
| }) | |||
| ); | |||
| }; | |||
| return ( | |||
| @@ -83,9 +87,9 @@ const FilesPage = () => { | |||
| <MenuItem | |||
| key={index} | |||
| sx={{ textAlign: "left" }} | |||
| value={category.value} | |||
| value={category.id} | |||
| > | |||
| {category.value} | |||
| {category.name} | |||
| </MenuItem> | |||
| ))} | |||
| </Select> | |||
| @@ -98,20 +102,21 @@ const FilesPage = () => { | |||
| </div> | |||
| <div className="files-page-card-content"> | |||
| <div className="files-page-card-content-checkboxes"> | |||
| {tags.map((x) => ( | |||
| <FormControlLabel | |||
| key={x.id} | |||
| control={ | |||
| <Checkbox | |||
| value={x.value} | |||
| checked={x.isChecked} | |||
| onChange={onChangeTagsCheckbox.bind(this, x.id)} | |||
| className="create-ad-second-step-checkbox" | |||
| /> | |||
| } | |||
| label={x.value} | |||
| /> | |||
| ))} | |||
| {tags && | |||
| tags.map((tag) => ( | |||
| <FormControlLabel | |||
| key={tag.id} | |||
| control={ | |||
| <Checkbox | |||
| value={tag.name} | |||
| checked={tag.isChecked} | |||
| onChange={onChangeTagsCheckbox.bind(this, tag.id)} | |||
| className="create-ad-second-step-checkbox" | |||
| /> | |||
| } | |||
| label={tag.name} | |||
| /> | |||
| ))} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -177,7 +182,10 @@ const FilesPage = () => { | |||
| <div className="files-page-card"> | |||
| <div className="files-page-card-add-button"> | |||
| <IconButton className="c-btn ads-page-btn c-btn--primary add-ad-btn"> | |||
| <IconButton | |||
| className="c-btn ads-page-btn c-btn--primary add-ad-btn" | |||
| onClick={uploadFileHandler} | |||
| > | |||
| + {t("files.addFile")} | |||
| </IconButton> | |||
| </div> | |||
| @@ -69,10 +69,17 @@ export default { | |||
| allTests: base + "/screeningtest", | |||
| createTest: base + "/screeningtest", | |||
| }, | |||
| categories: { | |||
| allCategories: base + "/categories/names", | |||
| }, | |||
| tags: { | |||
| allTags: base + "/tags/names", | |||
| }, | |||
| fileTags: { | |||
| filters: base + "/tags", | |||
| }, | |||
| files:{ | |||
| uploadFile: base + "/files", | |||
| all: base + "/files" | |||
| } | |||
| }; | |||
| @@ -0,0 +1,5 @@ | |||
| import { getRequest } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const getAllCategories = () => | |||
| getRequest(apiEndpoints.categories.allCategories); | |||
| @@ -0,0 +1,5 @@ | |||
| import { postRequest } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const uploadFileRequest = (payload) => | |||
| postRequest(apiEndpoints.files.uploadFile, payload); | |||
| @@ -2,3 +2,5 @@ import { getRequest } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const getFileFilters = () => getRequest(apiEndpoints.fileTags.filters); | |||
| export const getAllTags = () => | |||
| getRequest(apiEndpoints.tags.allTags); | |||
| @@ -0,0 +1,19 @@ | |||
| import { | |||
| FETCH_CATEGORIES_REQ, | |||
| FETCH_CATEGORIES_SUCCESS, | |||
| FETCH_CATEGORIES_ERR, | |||
| } from "./categoriesActionConstants"; | |||
| export const setCategoriesReq = () => ({ | |||
| type: FETCH_CATEGORIES_REQ, | |||
| }); | |||
| export const setCategoriesError = (payload) => ({ | |||
| type: FETCH_CATEGORIES_ERR, | |||
| payload, | |||
| }); | |||
| export const setCategories = (payload) => ({ | |||
| type: FETCH_CATEGORIES_SUCCESS, | |||
| payload, | |||
| }); | |||
| @@ -0,0 +1,11 @@ | |||
| import { | |||
| createFetchType, | |||
| createSuccessType, | |||
| createErrorType, | |||
| } from "../actionHelpers"; | |||
| const FETCH_CATEGORIES_SCOPE = "FETCH_CATEGORIES"; | |||
| export const FETCH_CATEGORIES_REQ = createFetchType(FETCH_CATEGORIES_SCOPE); | |||
| export const FETCH_CATEGORIES_ERR = createErrorType(FETCH_CATEGORIES_SCOPE); | |||
| export const FETCH_CATEGORIES_SUCCESS = createSuccessType(FETCH_CATEGORIES_SCOPE); | |||
| @@ -0,0 +1,30 @@ | |||
| import { | |||
| FETCH_TAGS_REQ, | |||
| FETCH_TAGS_SUCCESS, | |||
| FETCH_TAGS_ERR, | |||
| CHANGE_TAG_ISCHECKED_VALUE, | |||
| RESET_CHECKED_TAGS, | |||
| } from "./tagsActionConstants"; | |||
| export const setTagsReq = () => ({ | |||
| type: FETCH_TAGS_REQ, | |||
| }); | |||
| export const setTagsError = (payload) => ({ | |||
| type: FETCH_TAGS_ERR, | |||
| payload, | |||
| }); | |||
| export const setTags = (payload) => ({ | |||
| type: FETCH_TAGS_SUCCESS, | |||
| payload, | |||
| }); | |||
| export const changeTagIsCheckedValue = (payload) => ({ | |||
| type: CHANGE_TAG_ISCHECKED_VALUE, | |||
| payload, | |||
| }); | |||
| export const resetIsCheckedTagsValue = () => ({ | |||
| type: RESET_CHECKED_TAGS, | |||
| }); | |||
| @@ -0,0 +1,14 @@ | |||
| import { | |||
| createFetchType, | |||
| createSuccessType, | |||
| createErrorType, | |||
| } from "../actionHelpers"; | |||
| const FETCH_TAGS_SCOPE = "FETCH_TAGS"; | |||
| export const FETCH_TAGS_REQ = createFetchType(FETCH_TAGS_SCOPE); | |||
| export const FETCH_TAGS_ERR = createErrorType(FETCH_TAGS_SCOPE); | |||
| export const FETCH_TAGS_SUCCESS = createSuccessType(FETCH_TAGS_SCOPE); | |||
| export const CHANGE_TAG_ISCHECKED_VALUE = "CHANGE_TAG_ISCHECKED_VALUE"; | |||
| export const RESET_CHECKED_TAGS = "RESET_CHECKED_TAGS"; | |||
| @@ -0,0 +1,12 @@ | |||
| import { | |||
| createFetchType, | |||
| createSuccessType, | |||
| createErrorType, | |||
| } from "../actionHelpers"; | |||
| const UPLOAD_FILE_SCOPE = "UPLOAD_FILE"; | |||
| export const UPLOAD_FILE_REQ = createFetchType(UPLOAD_FILE_SCOPE); | |||
| export const UPLOAD_FILE_ERR = createErrorType(UPLOAD_FILE_SCOPE); | |||
| export const UPLOAD_FILE_SUCCESS = createSuccessType(UPLOAD_FILE_SCOPE); | |||
| @@ -0,0 +1,20 @@ | |||
| import { | |||
| UPLOAD_FILE_REQ, | |||
| UPLOAD_FILE_SUCCESS, | |||
| UPLOAD_FILE_ERR, | |||
| } from "./uploadFileActionConstants"; | |||
| export const uploadFileReq = (payload) => ({ | |||
| type: UPLOAD_FILE_REQ, | |||
| payload, | |||
| }); | |||
| export const uploadFileError = (payload) => ({ | |||
| type: UPLOAD_FILE_ERR, | |||
| payload, | |||
| }); | |||
| export const uploadFile = (payload) => ({ | |||
| type: UPLOAD_FILE_SUCCESS, | |||
| payload, | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import { | |||
| FETCH_CATEGORIES_ERR, | |||
| FETCH_CATEGORIES_SUCCESS, | |||
| } from "../../actions/categories/categoriesActionConstants"; | |||
| import createReducer from "../../utils/createReducer"; | |||
| const initialState = { | |||
| categories: [], | |||
| errorMessage: "", | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [FETCH_CATEGORIES_SUCCESS]: setStateCategories, | |||
| [FETCH_CATEGORIES_ERR]: setCategoriesErrorMessage, | |||
| }, | |||
| initialState | |||
| ); | |||
| function setStateCategories(state, action) { | |||
| return { | |||
| ...state, | |||
| categories: action.payload, | |||
| }; | |||
| } | |||
| function setCategoriesErrorMessage(state, action) { | |||
| return { | |||
| ...state, | |||
| errorMessage: action.payload, | |||
| }; | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| import { | |||
| UPLOAD_FILE_SUCCESS, | |||
| UPLOAD_FILE_ERR, | |||
| } from "../../actions/uploadFile/uploadFileActionConstants"; | |||
| import createReducer from "../../utils/createReducer"; | |||
| const initialState = { | |||
| file: null, | |||
| errorMessage: "", | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [UPLOAD_FILE_SUCCESS]: setStateFile, | |||
| [UPLOAD_FILE_ERR]: setFileErrorMessage, | |||
| }, | |||
| initialState | |||
| ); | |||
| function setStateFile(state, action) { | |||
| return { | |||
| ...state, | |||
| file: action.payload, | |||
| }; | |||
| } | |||
| function setFileErrorMessage(state, action) { | |||
| return { | |||
| ...state, | |||
| errorMessage: action.payload, | |||
| }; | |||
| } | |||
| @@ -33,6 +33,9 @@ import applyForAdReducer from "./applicants/applyForAdReducer"; | |||
| import statusUpdateReducer from "./processes/statusUpdateReducer"; | |||
| import interviewerUpdateReducer from "./processes/interviewerUpdateReducer"; | |||
| import screeningTestsReducer from "./screeningTests/screeningTestsReducer"; | |||
| import uploadFileReducer from "./file/uploadFileReducer"; | |||
| import categoriesReducer from "./category/categoriesReducer"; | |||
| import tagsReducer from "./tag/tagsReducer"; | |||
| import fileFiltersReducer from "./files/fileFiltersReducer"; | |||
| import getFilesReducer from "./files/getFilesReducer"; | |||
| @@ -70,7 +73,10 @@ export default combineReducers({ | |||
| applyForAd: applyForAdReducer, | |||
| statusUpdate: statusUpdateReducer, | |||
| interviewerUpdate: interviewerUpdateReducer, | |||
| screeningTests:screeningTestsReducer, | |||
| screeningTests: screeningTestsReducer, | |||
| uploadFile: uploadFileReducer, | |||
| categories: categoriesReducer, | |||
| tags: tagsReducer, | |||
| fileFilters: fileFiltersReducer, | |||
| files: getFilesReducer | |||
| }); | |||
| @@ -0,0 +1,60 @@ | |||
| import { | |||
| FETCH_TAGS_ERR, | |||
| FETCH_TAGS_SUCCESS, | |||
| CHANGE_TAG_ISCHECKED_VALUE, | |||
| RESET_CHECKED_TAGS, | |||
| } from "../../actions/tags/tagsActionConstants"; | |||
| import createReducer from "../../utils/createReducer"; | |||
| const initialState = { | |||
| tags: [], | |||
| errorMessage: "", | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [FETCH_TAGS_SUCCESS]: setStateTags, | |||
| [FETCH_TAGS_ERR]: setTagsErrorMessage, | |||
| [CHANGE_TAG_ISCHECKED_VALUE]: setIsCheckedTags, | |||
| [RESET_CHECKED_TAGS]: resetIsCheckedTags, | |||
| }, | |||
| initialState | |||
| ); | |||
| function setStateTags(state, action) { | |||
| return { | |||
| ...state, | |||
| tags: action.payload, | |||
| }; | |||
| } | |||
| function setTagsErrorMessage(state, action) { | |||
| return { | |||
| ...state, | |||
| errorMessage: action.payload, | |||
| }; | |||
| } | |||
| function setIsCheckedTags(state, action) { | |||
| const tmpIndex = state.tags.findIndex( | |||
| (x) => x.id === action.payload | |||
| ); | |||
| if (tmpIndex === -1) { | |||
| return state; | |||
| } | |||
| return { | |||
| ...state, | |||
| tags: state.tags.map((tag, index) => | |||
| tmpIndex === index ? { ...tag, isChecked: !tag.isChecked } : tag | |||
| ), | |||
| }; | |||
| } | |||
| function resetIsCheckedTags(state) { | |||
| return { | |||
| ...state, | |||
| tags: state.tags.map((tag) => ({ ...tag, isChecked: false })), | |||
| }; | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| import { all, call, put, takeLatest } from "redux-saga/effects"; | |||
| import { setCategories, setCategoriesError } from "../actions/categories/categoriesAction"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { JWT_TOKEN } from "../../constants/localStorage"; | |||
| import { addHeaderToken } from "../../request"; | |||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | |||
| import { FETCH_CATEGORIES_REQ } from "../actions/categories/categoriesActionConstants"; | |||
| import { getAllCategories } from "../../request/categoriesRequest"; | |||
| export function* getCategories() { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| const result = yield call(getAllCategories); | |||
| yield put(setCategories(result.data)); | |||
| } catch (error) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(setCategoriesError(errorMessage)); | |||
| } | |||
| } | |||
| export default function* categoriesSaga() { | |||
| yield all([ | |||
| takeLatest(FETCH_CATEGORIES_REQ, getCategories), | |||
| ]); | |||
| } | |||
| @@ -1,15 +1,39 @@ | |||
| import { all, call, put, takeEvery } from "redux-saga/effects"; | |||
| import { all, call, put, takeLatest, takeEvery } from "redux-saga/effects"; | |||
| import { | |||
| uploadFile, | |||
| uploadFileError, | |||
| } from "../actions/uploadFile/uploadFileActions"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { JWT_TOKEN } from "../../constants/localStorage"; | |||
| import { addHeaderToken } from "../../request"; | |||
| import { getAllFilesReq } from "../../request/fileRequests"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | |||
| 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"; | |||
| export function* uploadFileSaga({ payload }) { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| 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]); | |||
| formData.append("fileToUpload", payload.fileToUpload); | |||
| const result = yield call(uploadFileRequest, formData); | |||
| yield put(uploadFile(result.data)); | |||
| payload.onSuccessUploadFile(); | |||
| } catch (error) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(uploadFileError(errorMessage)); | |||
| } | |||
| } | |||
| export function* getAll() { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| @@ -24,5 +48,6 @@ export function* getAll() { | |||
| } | |||
| } | |||
| export default function* filesSaga() { | |||
| yield all([takeLatest(UPLOAD_FILE_REQ, uploadFileSaga)]); | |||
| yield all([takeEvery(FETCH_FILES_REQ, getAll)]); | |||
| } | |||
| @@ -11,6 +11,7 @@ import scheduleSaga from "./scheduleSaga"; | |||
| import registerSaga from "./registerSaga"; | |||
| import applicantsSaga from "./applicantsSaga"; | |||
| import screeningTestsSaga from "./screeningTestsSaga"; | |||
| import categoriesSaga from "./categoriesSaga"; | |||
| import tagsSaga from "./tagsSaga"; | |||
| import filesSaga from "./filesSaga"; | |||
| @@ -28,7 +29,8 @@ export default function* rootSaga() { | |||
| registerSaga(), | |||
| applicantsSaga(), | |||
| screeningTestsSaga(), | |||
| filesSaga(), | |||
| categoriesSaga(), | |||
| tagsSaga(), | |||
| filesSaga() | |||
| ]); | |||
| } | |||
| @@ -1,15 +1,31 @@ | |||
| import { all, call, put, takeEvery } from "redux-saga/effects"; | |||
| import { all, call, put, takeLatest, takeEvery } from "redux-saga/effects"; | |||
| import { setTags, setTagsError } from "../actions/tags/tagsAction"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { JWT_TOKEN } from "../../constants/localStorage"; | |||
| import { addHeaderToken } from "../../request"; | |||
| import { getFileFilters } from "../../request/tagsRequest"; | |||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | |||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | |||
| import { FETCH_TAGS_REQ } from "../actions/tags/tagsActionConstants"; | |||
| import { getAllTags } from "../../request/tagsRequest"; | |||
| import { getFileFilters } from "../../request/tagsRequest"; | |||
| import { FILE_FILTERS_REQ } from "../actions/files/fileActionConstants"; | |||
| import { | |||
| getFileFiltersError, | |||
| getFileFiltersSuccess, | |||
| } from "../actions/files/fileActions"; | |||
| export function* getTags() { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| yield call(addHeaderToken, JwtToken); | |||
| const result = yield call(getAllTags); | |||
| const resultData = result.data.map((tag) => ({ ...tag, isChecked: false })); | |||
| yield put(setTags(resultData)); | |||
| } catch (error) { | |||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||
| yield put(setTagsError(errorMessage)); | |||
| } | |||
| } | |||
| export function* getFileFiltersGen() { | |||
| try { | |||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||
| @@ -24,5 +40,6 @@ export function* getFileFiltersGen() { | |||
| } | |||
| } | |||
| export default function* tagsSaga() { | |||
| yield all([takeLatest(FETCH_TAGS_REQ, getTags)]); | |||
| yield all([takeEvery(FILE_FILTERS_REQ, getFileFiltersGen)]); | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| import { createSelector } from "@reduxjs/toolkit"; | |||
| export const categoriesSelector = (state) => state.categories; | |||
| export const selectCategories = createSelector( | |||
| categoriesSelector, | |||
| (state) => state.categories | |||
| ); | |||
| export const selectCategoriesError = createSelector( | |||
| categoriesSelector, | |||
| (state) => state.errorMessage | |||
| ); | |||
| @@ -0,0 +1,10 @@ | |||
| import { createSelector } from "@reduxjs/toolkit"; | |||
| export const tagsSelector = (state) => state.tags; | |||
| export const selectTags = createSelector(tagsSelector, (state) => state.tags); | |||
| export const selectTagsError = createSelector( | |||
| tagsSelector, | |||
| (state) => state.errorMessage | |||
| ); | |||