resources page fixes

master
Tudor Stanciu 2022-12-08 02:31:03 +02:00
parent f96fe1164b
commit 0814d09533
4 changed files with 112 additions and 70 deletions

View File

@ -1,2 +1,5 @@
- schimbare limba din setari - schimbare limba din setari
- salvare configurari - pozitie toast - 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)

View File

@ -4,7 +4,8 @@ import { get } from "../utils/axios";
const cdn = process.env.REACT_APP_CDN_URL; const cdn = process.env.REACT_APP_CDN_URL;
const endpoints = { const endpoints = {
mimeTypes: `${cdn}/admin/mime-types` mimeTypes: `${cdn}/admin/mime-types`,
resourceCategories: `${cdn}/admin/resource-categories`
}; };
const useDictionariesApi = () => { const useDictionariesApi = () => {
@ -18,8 +19,17 @@ const useDictionariesApi = () => {
[exec] [exec]
); );
const getResourceCategories = useCallback(
(options) => {
const promise = exec(() => get(endpoints.resourceCategories), options);
return promise;
},
[exec]
);
return { return {
getMimeTypes getMimeTypes,
getResourceCategories
}; };
}; };

View File

@ -1,6 +1,7 @@
const defaultResourcesFilters = Object.freeze({ const defaultResourcesFilters = Object.freeze({
page: 1, page: 1,
pageSize: 10, pageSize: 10,
loadedPages: null,
sortBy: null, sortBy: null,
sortDirection: null, sortDirection: null,
fullTextSearch: null, fullTextSearch: null,

View File

@ -1,34 +1,56 @@
import React, { useState, useEffect, useMemo, useCallback } from "react"; 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 MUIDataTable, { debounceSearchRender } from "mui-datatables";
import Skeleton from "@material-ui/lab/Skeleton";
import PageTitle from "../../../components/PageTitle"; import PageTitle from "../../../components/PageTitle";
import { useResourcesApi } from "../../../api"; import { useResourcesApi, useDictionariesApi } from "../../../api";
import { defaultResourcesFilters } from "../../../constants/resourcesConstants"; import { defaultResourcesFilters } from "../../../constants/resourcesConstants";
const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100]; const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100];
const ResourcesContainer = () => { 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 [filters, setFilters] = useState({ ...defaultResourcesFilters });
const [resourceCategories, setResourceCategories] = useState([]);
const { getResources } = useResourcesApi(); const { getResources } = useResourcesApi();
const { getResourceCategories } = useDictionariesApi();
useEffect(() => { 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, { getResources(filters, {
onCompleted: (resources) => { onCompleted: (resources) => {
const data = { ...resources, loaded: true };
setState((prev) => ({ setState((prev) => ({
...prev, ...prev,
...data, ...resources,
values: prev?.values ? [...prev.values, ...data.values] : data.values, values: filters.loadedPages
loadedPages: prev?.loadedPages ? [...prev.values, ...resources.values]
? [...prev.loadedPages, data.page] : resources.values
: [data.page]
})); }));
setFilters((prev) => ({
...prev,
loadedPages: prev?.loadedPages
? [...prev.loadedPages, resources.page]
: [resources.page]
}));
setLoading(false);
} }
}); });
}, [getResources, filters, state.loadedPages]); }, [getResources, filters]);
const columns = useMemo( const columns = useMemo(
() => [ () => [
@ -38,7 +60,7 @@ const ResourcesContainer = () => {
options: { options: {
display: true, display: true,
draggable: true, draggable: true,
download: false, download: true,
print: false, print: false,
searchable: true, searchable: true,
sort: true, sort: true,
@ -60,7 +82,7 @@ const ResourcesContainer = () => {
options: { options: {
display: true, display: true,
draggable: true, draggable: true,
download: false, download: true,
print: false, print: false,
searchable: true, searchable: true,
sort: true, sort: true,
@ -78,11 +100,11 @@ const ResourcesContainer = () => {
}, },
{ {
label: "Category", label: "Category",
name: "categoryId", name: "categoryName",
options: { options: {
display: true, display: true,
draggable: true, draggable: true,
download: false, download: true,
print: false, print: false,
searchable: true, searchable: true,
sort: true, sort: true,
@ -101,7 +123,7 @@ const ResourcesContainer = () => {
options: { options: {
display: true, display: true,
draggable: true, draggable: true,
download: false, download: true,
print: false, print: false,
searchable: true, searchable: true,
sort: true, sort: true,
@ -149,70 +171,76 @@ const ResourcesContainer = () => {
[] []
); );
const handleResetFilters = useCallback(() => { const changeFilters = useCallback((obj) => {
setFilters((prev) => ({ ...prev, ...defaultResourcesFilters })); const keys = Object.keys(obj);
}, [setFilters]); 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( const handleFilterChange = useCallback(
(changedColumn, filterList, type, changedColumnIndex, displayData) => { (changedColumn, filterList, type, changedColumnIndex, displayData) => {
if (type === "reset") { if (type === "reset") {
handleResetFilters(); changeFilters(defaultResourcesFilters);
return; return;
} }
const filterValue = filterList[changedColumnIndex][0]; const filterValue = filterList[changedColumnIndex][0];
setFilters((prev) => ({ changeFilters({ [changedColumn]: filterValue });
...prev,
[changedColumn]: filterValue
}));
}, },
[handleResetFilters] [changeFilters]
); );
return ( return (
<> <>
<PageTitle title="ResourcesX" /> <PageTitle title="Resources adminstration" />
{state.loaded === false ? (
<CircularProgress size={26} /> <MUIDataTable
) : ( title="Resources"
<MUIDataTable columns={columns}
title="Resources" data={state.values}
columns={columns} options={{
data={state.values ?? []} filterType: "textField",
options={{ expandableRows: false,
filterType: "textField", print: false,
expandableRows: false, selectableRows: "none",
print: false, rowsPerPage: state.pageSize,
selectableRows: "none", rowsPerPageOptions: __ROWS_PER_PAGE_OPTIONS,
rowsPerPage: state.pageSize, count: state.totalCount,
rowsPerPageOptions: __ROWS_PER_PAGE_OPTIONS, customSearchRender: debounceSearchRender(500),
count: state.totalCount, onChangePage: (currentPage) =>
customSearchRender: debounceSearchRender(500), changeFilters({ page: currentPage + 1 }),
onChangePage: (currentPage) => { onChangeRowsPerPage: (numberOfRows) =>
setFilters((prev) => ({ ...prev, page: currentPage + 1 })); changeFilters({ pageSize: numberOfRows }),
}, onColumnSortChange: (changedColumn, direction) =>
onChangeRowsPerPage: (numberOfRows) => { changeFilters({
setFilters((prev) => ({ ...prev, pageSize: numberOfRows })); sortBy: changedColumn,
}, sortDirection: direction
onColumnSortChange: (changedColumn, direction) => }),
setFilters((prev) => ({ onFilterChange: handleFilterChange,
...prev, onSearchChange: (text) => changeFilters({ fullTextSearch: text }),
sortBy: changedColumn, customSort: (data) => data,
sortDirection: direction customSearch: () => true,
})), setFilterChipProps: (_colIndex, _colName, _data) => {
onFilterChange: handleFilterChange, return {
onSearchChange: (text) => color: "primary",
setFilters((prev) => ({ ...prev, fullTextSearch: text })), variant: "outlined"
customSort: (data) => data, };
customSearch: () => true, },
setFilterChipProps: (_colIndex, _colName, _data) => { textLabels: {
return { body: {
color: "primary", noMatch: loading ? (
variant: "outlined" <Skeleton variant="text" />
}; ) : (
"Sorry, there is no matching data to display"
)
} }
}} }
/> }}
)} />
</> </>
); );
}; };