resources list

master
Tudor Stanciu 2022-12-09 18:38:01 +02:00
parent 0814d09533
commit 94839a746b
4 changed files with 115 additions and 17 deletions

View File

@ -37,5 +37,15 @@
"IncorrectCredentials": "Incorrect credentials.",
"Hello": "Hi, {{username}}",
"AuthenticationDate": "Authentication date"
},
"Resource": {
"Code": "Code",
"Name": "Name",
"Category": "Category",
"Secured": "Secured",
"CodeContains": "Code contains: {{value}}",
"NameContains": "Name contains: {{value}}",
"CategoryChip": "Category: {{value}}",
"ListTitle": "Resource management"
}
}

View File

@ -0,0 +1,48 @@
import React from "react";
import PropTypes from "prop-types";
import grey from "@material-ui/core/colors/grey";
import { Paper, makeStyles } from "@material-ui/core";
const styles = {
cover: {
width: "100%"
},
bar: {
backgroundColor: grey[200],
height: 10,
margin: 20,
"&:nth-child(2n)": {
marginRight: "20%"
}
},
paper: {
padding: "10px",
borderRadius: "6px"
}
};
const useStyles = makeStyles(styles);
const LoadingText = ({ lines = 4, onPaper = false, ...props }) => {
const classes = useStyles();
const loadingText = (
<div className={classes.cover} {...props}>
{[...Array(lines)].map((_e, i) => (
<div className={classes.bar} key={i}></div>
))}
</div>
);
if (onPaper) {
return <Paper className={classes.paper}>{loadingText}</Paper>;
}
return loadingText;
};
LoadingText.propTypes = {
lines: PropTypes.number,
onPaper: PropTypes.bool
};
export default LoadingText;

3
src/components/index.js Normal file
View File

@ -0,0 +1,3 @@
import LoadingText from "./LoadingContent/LoadingText";
export { LoadingText };

View File

@ -1,12 +1,14 @@
import React, { useState, useEffect, useMemo, useCallback } from "react";
import { Checkbox, FormLabel } from "@material-ui/core";
import MUIDataTable, { debounceSearchRender } from "mui-datatables";
import Skeleton from "@material-ui/lab/Skeleton";
import { LoadingText } from "../../../components";
import PageTitle from "../../../components/PageTitle";
import { useResourcesApi, useDictionariesApi } from "../../../api";
import { defaultResourcesFilters } from "../../../constants/resourcesConstants";
import { useTranslation } from "react-i18next";
const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100];
const __RESOURCE_NAME_MAX_LENGTH = 35;
const ResourcesContainer = () => {
const [state, setState] = useState({
@ -18,6 +20,7 @@ const ResourcesContainer = () => {
const [filters, setFilters] = useState({ ...defaultResourcesFilters });
const [resourceCategories, setResourceCategories] = useState([]);
const { t } = useTranslation();
const { getResources } = useResourcesApi();
const { getResourceCategories } = useDictionariesApi();
@ -52,10 +55,15 @@ const ResourcesContainer = () => {
});
}, [getResources, filters]);
const categoryFilterOptions = useMemo(
() => resourceCategories.map((z) => z.categoryName),
[resourceCategories]
);
const columns = useMemo(
() => [
{
label: "Code",
label: t("Resource.Code"),
name: "resourceCode",
options: {
display: true,
@ -65,7 +73,7 @@ const ResourcesContainer = () => {
searchable: true,
sort: true,
customFilterListOptions: {
render: (v) => (v ? `Code contains: ${v}` : [])
render: (v) => (v ? t("Resource.CodeContains", { value: v }) : [])
},
filter: true,
filterType: "textField",
@ -77,7 +85,7 @@ const ResourcesContainer = () => {
}
},
{
label: "Name",
label: t("Resource.Name"),
name: "resourceName",
options: {
display: true,
@ -86,8 +94,17 @@ const ResourcesContainer = () => {
print: false,
searchable: true,
sort: true,
customBodyRenderLite: (dataIndex, _rowIndex) => {
if (loading) return;
const value = state.values[dataIndex].resourceName;
const formattedValue =
value.length > __RESOURCE_NAME_MAX_LENGTH
? `${value.substring(0, __RESOURCE_NAME_MAX_LENGTH + 1)}[...]`
: value;
return formattedValue;
},
customFilterListOptions: {
render: (v) => (v ? `Name contains: ${v}` : [])
render: (v) => (v ? t("Resource.NameContains", { value: v }) : [])
},
filter: true,
filterType: "textField",
@ -99,7 +116,7 @@ const ResourcesContainer = () => {
}
},
{
label: "Category",
label: t("Resource.Category"),
name: "categoryName",
options: {
display: true,
@ -109,16 +126,19 @@ const ResourcesContainer = () => {
searchable: true,
sort: true,
filter: true,
customFilterListOptions: {
render: (v) => t("Resource.CategoryChip", { value: v })
},
filterType: "dropdown",
filterOptions: {
names: categoryFilterOptions,
logic: (_prop, _filterValue, _row) => false
},
filterList: [],
hint: undefined
}
},
{
label: "Secured",
label: t("Resource.Secured"),
name: "secured",
options: {
display: true,
@ -140,7 +160,7 @@ const ResourcesContainer = () => {
customFilterListOptions: {
render: (v) => {
const checked = v[0];
return checked ? <span>Secured</span> : [];
return checked ? <span>{t("Resource.Secured")}</span> : [];
}
},
filter: true,
@ -150,7 +170,7 @@ const ResourcesContainer = () => {
display: (filterList, onChange, index, column) => {
return (
<div>
<FormLabel>Secured</FormLabel>
<FormLabel>{t("Resource.Secured")}</FormLabel>
<Checkbox
color="primary"
checked={filterList[index][0] || false}
@ -163,12 +183,11 @@ const ResourcesContainer = () => {
);
}
},
filterList: undefined,
hint: undefined
}
}
],
[]
[loading, state.values, categoryFilterOptions, t]
);
const changeFilters = useCallback((obj) => {
@ -182,21 +201,39 @@ const ResourcesContainer = () => {
setFilters((prev) => ({ ...prev, ...obj }));
}, []);
const getCategoryId = useCallback(
(name) => {
const category = resourceCategories.find((z) => z.categoryName === name);
return category?.categoryId;
},
[resourceCategories]
);
const handleFilterChange = useCallback(
(changedColumn, filterList, type, changedColumnIndex, displayData) => {
(changedColumn, filterList, type, changedColumnIndex, _displayData) => {
if (type === "reset") {
changeFilters(defaultResourcesFilters);
return;
}
const filterValue = filterList[changedColumnIndex][0];
if (changedColumn === "categoryName") {
const categoryId = filterValue
? getCategoryId(filterValue)
: filterValue;
changeFilters({ categoryId });
return;
}
changeFilters({ [changedColumn]: filterValue });
},
[changeFilters]
[changeFilters, getCategoryId]
);
return (
<>
<PageTitle title="Resources adminstration" />
<PageTitle title={t("Resource.ListTitle")} />
<MUIDataTable
title="Resources"
@ -233,9 +270,9 @@ const ResourcesContainer = () => {
textLabels: {
body: {
noMatch: loading ? (
<Skeleton variant="text" />
<LoadingText lines={15} />
) : (
"Sorry, there is no matching data to display"
"Sorry, no matching records found"
)
}
}