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