diff --git a/notes/todo.txt b/notes/todo.txt index 5bbcaff..4d00e5c 100644 --- a/notes/todo.txt +++ b/notes/todo.txt @@ -1,2 +1,5 @@ - schimbare limba din setari -- salvare configurari - pozitie toast \ No newline at end of file +- salvare configurari - pozitie toast + +# Resources list +- comenzi pe fiecare rand: - creion edit + ... care deschide meniu cu alte comenzi (copy - copiaza link-ul, open - deschide link-ul public in tab nou) \ No newline at end of file diff --git a/src/api/useDictionariesApi.js b/src/api/useDictionariesApi.js index 1e00f5b..361e9f3 100644 --- a/src/api/useDictionariesApi.js +++ b/src/api/useDictionariesApi.js @@ -4,7 +4,8 @@ import { get } from "../utils/axios"; const cdn = process.env.REACT_APP_CDN_URL; const endpoints = { - mimeTypes: `${cdn}/admin/mime-types` + mimeTypes: `${cdn}/admin/mime-types`, + resourceCategories: `${cdn}/admin/resource-categories` }; const useDictionariesApi = () => { @@ -18,8 +19,17 @@ const useDictionariesApi = () => { [exec] ); + const getResourceCategories = useCallback( + (options) => { + const promise = exec(() => get(endpoints.resourceCategories), options); + return promise; + }, + [exec] + ); + return { - getMimeTypes + getMimeTypes, + getResourceCategories }; }; diff --git a/src/constants/resourcesConstants.js b/src/constants/resourcesConstants.js index e857a64..a14ab16 100644 --- a/src/constants/resourcesConstants.js +++ b/src/constants/resourcesConstants.js @@ -1,6 +1,7 @@ const defaultResourcesFilters = Object.freeze({ page: 1, pageSize: 10, + loadedPages: null, sortBy: null, sortDirection: null, fullTextSearch: null, diff --git a/src/features/resources/components/ResourcesContainer.js b/src/features/resources/components/ResourcesContainer.js index d64c605..a3e1197 100644 --- a/src/features/resources/components/ResourcesContainer.js +++ b/src/features/resources/components/ResourcesContainer.js @@ -1,34 +1,56 @@ import React, { useState, useEffect, useMemo, useCallback } from "react"; -import { Grid, Checkbox, CircularProgress, FormLabel } from "@material-ui/core"; +import { Checkbox, FormLabel } from "@material-ui/core"; import MUIDataTable, { debounceSearchRender } from "mui-datatables"; +import Skeleton from "@material-ui/lab/Skeleton"; import PageTitle from "../../../components/PageTitle"; -import { useResourcesApi } from "../../../api"; +import { useResourcesApi, useDictionariesApi } from "../../../api"; import { defaultResourcesFilters } from "../../../constants/resourcesConstants"; const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100]; const ResourcesContainer = () => { - const [state, setState] = useState({ loaded: false, loadedPages: null }); + const [state, setState] = useState({ + pageSize: 10, + totalCount: 0, + values: [] + }); + const [loading, setLoading] = useState(false); const [filters, setFilters] = useState({ ...defaultResourcesFilters }); + const [resourceCategories, setResourceCategories] = useState([]); + const { getResources } = useResourcesApi(); + const { getResourceCategories } = useDictionariesApi(); useEffect(() => { - if (state.loadedPages && state.loadedPages.includes(filters.page)) return; + getResourceCategories().then((r) => setResourceCategories(r)); + }, [getResourceCategories]); + useEffect(() => { + if (filters.loadedPages && filters.loadedPages.includes(filters.page)) + return; + + setLoading(true); getResources(filters, { onCompleted: (resources) => { - const data = { ...resources, loaded: true }; setState((prev) => ({ ...prev, - ...data, - values: prev?.values ? [...prev.values, ...data.values] : data.values, - loadedPages: prev?.loadedPages - ? [...prev.loadedPages, data.page] - : [data.page] + ...resources, + values: filters.loadedPages + ? [...prev.values, ...resources.values] + : resources.values })); + + setFilters((prev) => ({ + ...prev, + loadedPages: prev?.loadedPages + ? [...prev.loadedPages, resources.page] + : [resources.page] + })); + + setLoading(false); } }); - }, [getResources, filters, state.loadedPages]); + }, [getResources, filters]); const columns = useMemo( () => [ @@ -38,7 +60,7 @@ const ResourcesContainer = () => { options: { display: true, draggable: true, - download: false, + download: true, print: false, searchable: true, sort: true, @@ -60,7 +82,7 @@ const ResourcesContainer = () => { options: { display: true, draggable: true, - download: false, + download: true, print: false, searchable: true, sort: true, @@ -78,11 +100,11 @@ const ResourcesContainer = () => { }, { label: "Category", - name: "categoryId", + name: "categoryName", options: { display: true, draggable: true, - download: false, + download: true, print: false, searchable: true, sort: true, @@ -101,7 +123,7 @@ const ResourcesContainer = () => { options: { display: true, draggable: true, - download: false, + download: true, print: false, searchable: true, sort: true, @@ -149,70 +171,76 @@ const ResourcesContainer = () => { [] ); - const handleResetFilters = useCallback(() => { - setFilters((prev) => ({ ...prev, ...defaultResourcesFilters })); - }, [setFilters]); + const changeFilters = useCallback((obj) => { + const keys = Object.keys(obj); + const isPageChange = keys.length === 1 && keys[0] === "page"; + if (!isPageChange) { + const { page, loadedPages } = defaultResourcesFilters; + obj = { ...obj, page, loadedPages }; + } + + setFilters((prev) => ({ ...prev, ...obj })); + }, []); const handleFilterChange = useCallback( (changedColumn, filterList, type, changedColumnIndex, displayData) => { if (type === "reset") { - handleResetFilters(); + changeFilters(defaultResourcesFilters); return; } const filterValue = filterList[changedColumnIndex][0]; - setFilters((prev) => ({ - ...prev, - [changedColumn]: filterValue - })); + changeFilters({ [changedColumn]: filterValue }); }, - [handleResetFilters] + [changeFilters] ); return ( <> - - {state.loaded === false ? ( - - ) : ( - { - setFilters((prev) => ({ ...prev, page: currentPage + 1 })); - }, - onChangeRowsPerPage: (numberOfRows) => { - setFilters((prev) => ({ ...prev, pageSize: numberOfRows })); - }, - onColumnSortChange: (changedColumn, direction) => - setFilters((prev) => ({ - ...prev, - sortBy: changedColumn, - sortDirection: direction - })), - onFilterChange: handleFilterChange, - onSearchChange: (text) => - setFilters((prev) => ({ ...prev, fullTextSearch: text })), - customSort: (data) => data, - customSearch: () => true, - setFilterChipProps: (_colIndex, _colName, _data) => { - return { - color: "primary", - variant: "outlined" - }; + + + + changeFilters({ page: currentPage + 1 }), + onChangeRowsPerPage: (numberOfRows) => + changeFilters({ pageSize: numberOfRows }), + onColumnSortChange: (changedColumn, direction) => + changeFilters({ + sortBy: changedColumn, + sortDirection: direction + }), + onFilterChange: handleFilterChange, + onSearchChange: (text) => changeFilters({ fullTextSearch: text }), + customSort: (data) => data, + customSearch: () => true, + setFilterChipProps: (_colIndex, _colName, _data) => { + return { + color: "primary", + variant: "outlined" + }; + }, + textLabels: { + body: { + noMatch: loading ? ( + + ) : ( + "Sorry, there is no matching data to display" + ) } - }} - /> - )} + } + }} + /> ); };