diff --git a/src/api/useHttpRequest.js b/src/api/useHttpRequest.js
index 5758548..94d2698 100644
--- a/src/api/useHttpRequest.js
+++ b/src/api/useHttpRequest.js
@@ -14,6 +14,7 @@ const useHttpRequest = () => {
const defaultOptions = useMemo(
() => ({
+ onStart: () => {},
onCompleted: () => {},
onError: handleError
}),
@@ -23,9 +24,10 @@ const useHttpRequest = () => {
const exec = useCallback(
async (request, options) => {
const internalOptions = { ...defaultOptions, ...options };
- const { onCompleted, onError } = internalOptions;
+ const { onStart, onCompleted, onError } = internalOptions;
try {
+ onStart();
const result = await request();
onCompleted(result);
return result;
diff --git a/src/api/useResourcesApi.js b/src/api/useResourcesApi.js
index 885e5f1..5906cc6 100644
--- a/src/api/useResourcesApi.js
+++ b/src/api/useResourcesApi.js
@@ -1,21 +1,10 @@
import { useCallback } from "react";
import useHttpRequest from "./useHttpRequest";
import { get } from "../utils/axios";
+import { defaultResourcesFilters } from "../constants/resourcesConstants";
const cdn = process.env.REACT_APP_CDN_URL;
-const defaultResourcesInput = {
- page: 1,
- pageSize: 10,
- sortBy: null,
- sortDirection: 0,
- fullTextSearch: null,
- resourceCode: null,
- resourceName: null,
- categoryId: null,
- secured: null
-};
-
const getResourcesEndpoint = (filters) => {
const {
page,
@@ -28,11 +17,12 @@ const getResourcesEndpoint = (filters) => {
categoryId,
secured
} = filters;
- let endpoint = `${cdn}/admin/resources?Page=${page}&PageSize=${pageSize}&SortDirection=${sortDirection}`;
+ let endpoint = `${cdn}/admin/resources?Page=${page}&PageSize=${pageSize}`;
if (sortBy) endpoint += `&SortBy=${sortBy}`;
+ if (sortDirection) endpoint += `&SortDirection=${sortDirection}`;
if (fullTextSearch) endpoint += `&FullTextSearch=${fullTextSearch}`;
if (resourceCode) endpoint += `&ResourceCode=${resourceCode}`;
- if (resourceCode) endpoint += `&ResourceName=${resourceName}`;
+ if (resourceName) endpoint += `&ResourceName=${resourceName}`;
if (categoryId) endpoint += `&CategoryId=${categoryId}`;
if (secured) endpoint += `&Secured=${secured}`;
return endpoint;
@@ -43,7 +33,7 @@ const useResourcesApi = () => {
const getResources = useCallback(
(filters, options) => {
- const input = { ...defaultResourcesInput, ...filters };
+ const input = { ...defaultResourcesFilters, ...filters };
const endpoint = getResourcesEndpoint(input);
const promise = exec(() => get(endpoint), options);
return promise;
diff --git a/src/components/Layout/Content.js b/src/components/Layout/Content.js
index e9038c9..138f563 100644
--- a/src/components/Layout/Content.js
+++ b/src/components/Layout/Content.js
@@ -33,7 +33,7 @@ const Content = () => {
[classes.contentShift]: layoutState.isSidebarOpened
})}
>
-
+
diff --git a/src/components/PageTitle/styles.js b/src/components/PageTitle/styles.js
index cc6f3ee..fd2a4bd 100644
--- a/src/components/PageTitle/styles.js
+++ b/src/components/PageTitle/styles.js
@@ -1,20 +1,20 @@
import { makeStyles } from "@material-ui/styles";
-export default makeStyles(theme => ({
+export default makeStyles((theme) => ({
pageTitleContainer: {
display: "flex",
justifyContent: "space-between",
- marginBottom: theme.spacing(4),
- marginTop: theme.spacing(5),
+ marginBottom: theme.spacing(2),
+ marginTop: theme.spacing(0)
},
typo: {
- color: theme.palette.text.hint,
+ color: theme.palette.text.hint
},
button: {
boxShadow: theme.customShadows.widget,
textTransform: "none",
"&:active": {
- boxShadow: theme.customShadows.widgetWide,
- },
- },
+ boxShadow: theme.customShadows.widgetWide
+ }
+ }
}));
diff --git a/src/constants/resourcesConstants.js b/src/constants/resourcesConstants.js
new file mode 100644
index 0000000..e857a64
--- /dev/null
+++ b/src/constants/resourcesConstants.js
@@ -0,0 +1,13 @@
+const defaultResourcesFilters = Object.freeze({
+ page: 1,
+ pageSize: 10,
+ sortBy: null,
+ sortDirection: null,
+ fullTextSearch: null,
+ resourceCode: null,
+ resourceName: null,
+ categoryId: null,
+ secured: null
+});
+
+export { defaultResourcesFilters };
diff --git a/src/features/resources/components/ResourcesContainer.js b/src/features/resources/components/ResourcesContainer.js
index e749c0d..9d563b1 100644
--- a/src/features/resources/components/ResourcesContainer.js
+++ b/src/features/resources/components/ResourcesContainer.js
@@ -1,24 +1,34 @@
-import React, { useState, useEffect, useMemo } from "react";
-import { Grid, CircularProgress, Checkbox } from "@material-ui/core";
-import MUIDataTable from "mui-datatables";
+import React, { useState, useEffect, useMemo, useCallback } from "react";
+import { Grid, Checkbox, CircularProgress, FormLabel } from "@material-ui/core";
+import MUIDataTable, { debounceSearchRender } from "mui-datatables";
import PageTitle from "../../../components/PageTitle";
import { useResourcesApi } from "../../../api";
+import { defaultResourcesFilters } from "../../../constants/resourcesConstants";
+
+const __ROWS_PER_PAGE_OPTIONS = [10, 20, 50, 100];
const ResourcesContainer = () => {
- const [list, setList] = useState({ loaded: false });
+ const [state, setState] = useState({ loaded: false, loadedPages: null });
+ const [filters, setFilters] = useState({ ...defaultResourcesFilters });
const { getResources } = useResourcesApi();
useEffect(() => {
- getResources(
- {},
- {
- onCompleted: (resources) => {
- const data = Object.assign(resources, { loaded: true });
- setList(data);
- }
+ if (state.loadedPages && state.loadedPages.includes(filters.page)) return;
+
+ 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]
+ }));
}
- );
- }, [getResources]);
+ });
+ }, [getResources, filters, state.loadedPages]);
const columns = useMemo(
() => [
@@ -32,8 +42,14 @@ const ResourcesContainer = () => {
print: false,
searchable: true,
sort: true,
+ customFilterListOptions: {
+ render: (v) => (v ? `Code contains: ${v}` : [])
+ },
filter: true,
filterType: "textField",
+ filterOptions: {
+ logic: (_prop, _filterValue, _row) => false
+ },
filterList: undefined,
hint: undefined
}
@@ -48,8 +64,14 @@ const ResourcesContainer = () => {
print: false,
searchable: true,
sort: true,
+ customFilterListOptions: {
+ render: (v) => (v ? `Name contains: ${v}` : [])
+ },
filter: true,
filterType: "textField",
+ filterOptions: {
+ logic: (_prop, _filterValue, _row) => false
+ },
filterList: undefined,
hint: undefined
}
@@ -66,6 +88,9 @@ const ResourcesContainer = () => {
sort: true,
filter: true,
filterType: "dropdown",
+ filterOptions: {
+ logic: (_prop, _filterValue, _row) => false
+ },
filterList: [],
hint: undefined
}
@@ -80,11 +105,7 @@ const ResourcesContainer = () => {
print: false,
searchable: true,
sort: true,
- filter: true,
- filterType: "checkbox",
- filterList: undefined,
- hint: undefined,
- customBodyRender: (value, tableMeta, updateValue) => {
+ customBodyRender: (value, _tableMeta, _updateValue) => {
return (
{
style={{ padding: "0" }}
/>
);
- }
+ },
+ customFilterListOptions: {
+ render: (v) => {
+ const checked = v[0];
+ return checked ? Secured : [];
+ }
+ },
+ filter: true,
+ filterType: "custom",
+ filterOptions: {
+ logic: (_prop, _filterValue, _row) => false,
+ display: (filterList, onChange, index, column) => {
+ return (
+
+ Secured
+ {
+ filterList[index][0] = event.target.checked;
+ onChange(filterList[index], index, column);
+ }}
+ />
+
+ );
+ }
+ },
+ filterList: undefined,
+ hint: undefined
}
}
],
[]
);
+ const handleResetFilters = useCallback(() => {
+ setFilters((prev) => ({ ...prev, ...defaultResourcesFilters }));
+ }, [setFilters]);
+
+ const handleFilterChange = useCallback(
+ (changedColumn, filterList, type, changedColumnIndex, displayData) => {
+ if (type === "reset") {
+ handleResetFilters();
+ return;
+ }
+ const filterValue = filterList[changedColumnIndex][0];
+ setFilters((prev) => ({
+ ...prev,
+ [changedColumn]: filterValue
+ }));
+ },
+ [handleResetFilters]
+ );
+
return (
<>
- {list.loaded === false ? (
+ {state.loaded === false ? (
) : (
@@ -111,14 +179,39 @@ const ResourcesContainer = () => {
{
+ 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"
+ };
+ }
}}
/>