added pro grid, minor updates from demo

This commit is contained in:
Tim Chamberlain
2022-07-14 13:24:36 -05:00
parent a9777a6a3b
commit 86adca86dc
6 changed files with 368 additions and 202 deletions

View File

@ -36,7 +36,10 @@
],
"indent": [
"error",
3
3,
{
"SwitchCase": 1
}
],
"import/extensions": [
"error",
@ -60,6 +63,10 @@
"no-unused-vars": "off",
"no-plusplus": "off",
"spaced-comment": "off",
"object-curly-spacing": [
"error",
"never"
],
"object-shorthand": "off",
"react/prop-types": "off",
"react/jsx-filename-extension": [

145
package-lock.json generated
View File

@ -20,7 +20,8 @@
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
"@mui/x-data-grid": "5.13.0",
"@mui/x-data-grid-pro": "5.13.0",
"@mui/x-license-pro": "5.12.3",
"@react-jvectormap/core": "1.0.1",
"@react-jvectormap/world": "1.0.0",
"@testing-library/jest-dom": "5.16.2",
@ -73,7 +74,7 @@
}
},
".yalc/@kingsrook/qqq-frontend-core": {
"version": "1.0.2",
"version": "1.0.3",
"license": "ISC",
"dependencies": {
"axios": "0.27.2"
@ -3315,6 +3316,76 @@
"react-dom": "^17.0.2 || ^18.0.0"
}
},
"node_modules/@mui/x-data-grid-pro": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.13.0.tgz",
"integrity": "sha512-iyXGZUMHDP/QIiFQMsRBInQdajwZ8qBv6dUnJjd+ev4ioKZMoARYNMglbNFnzJ69lVsuGucRHyUe6qH8RjkGaQ==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.1",
"@mui/x-data-grid": "5.13.0",
"@mui/x-license-pro": "5.12.3",
"@types/format-util": "^1.0.2",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"reselect": "^4.1.6"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"@mui/material": "^5.4.1",
"@mui/system": "^5.4.1",
"react": "^17.0.2 || ^18.0.0",
"react-dom": "^17.0.2 || ^18.0.0"
}
},
"node_modules/@mui/x-license-pro": {
"version": "5.12.3",
"resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.12.3.tgz",
"integrity": "sha512-52LOmjhNVCb1oUuVl04XK5tXOQV49LJ4+NCxjo8bdFrQPVcan5dZ76adgMRbN15mFMKswDAzpXfk+vHmqMt4hQ==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.1",
"esm": "^3.2.25",
"yargs": "^17.5.1"
},
"bin": {
"licensedecode": "bin/license-decode-script.js",
"licensegen": "bin/license-gen-script.js"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"react": "^17.0.2 || ^18.0.0"
}
},
"node_modules/@mui/x-license-pro/node_modules/yargs": {
"version": "17.5.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@mui/x-license-pro/node_modules/yargs-parser": {
"version": "21.0.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
"integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
"engines": {
"node": ">=12"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -4113,6 +4184,11 @@
"@types/range-parser": "*"
}
},
"node_modules/@types/format-util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/format-util/-/format-util-1.0.2.tgz",
"integrity": "sha512-9SrLCpgzWo2yHHhiMOX0WwgDh37nSbDbWUsRc1ss++o8O97E3tB6SJiyUQM21UeUsKvZNuhDCmkRaINZ4uJAfg=="
},
"node_modules/@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@ -8124,6 +8200,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
"engines": {
"node": ">=6"
}
},
"node_modules/espree": {
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
@ -19244,6 +19328,53 @@
"reselect": "^4.1.6"
}
},
"@mui/x-data-grid-pro": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-5.13.0.tgz",
"integrity": "sha512-iyXGZUMHDP/QIiFQMsRBInQdajwZ8qBv6dUnJjd+ev4ioKZMoARYNMglbNFnzJ69lVsuGucRHyUe6qH8RjkGaQ==",
"requires": {
"@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.1",
"@mui/x-data-grid": "5.13.0",
"@mui/x-license-pro": "5.12.3",
"@types/format-util": "^1.0.2",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"reselect": "^4.1.6"
}
},
"@mui/x-license-pro": {
"version": "5.12.3",
"resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-5.12.3.tgz",
"integrity": "sha512-52LOmjhNVCb1oUuVl04XK5tXOQV49LJ4+NCxjo8bdFrQPVcan5dZ76adgMRbN15mFMKswDAzpXfk+vHmqMt4hQ==",
"requires": {
"@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.1",
"esm": "^3.2.25",
"yargs": "^17.5.1"
},
"dependencies": {
"yargs": {
"version": "17.5.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
}
},
"yargs-parser": {
"version": "21.0.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
"integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg=="
}
}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -19801,6 +19932,11 @@
"@types/range-parser": "*"
}
},
"@types/format-util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/format-util/-/format-util-1.0.2.tgz",
"integrity": "sha512-9SrLCpgzWo2yHHhiMOX0WwgDh37nSbDbWUsRc1ss++o8O97E3tB6SJiyUQM21UeUsKvZNuhDCmkRaINZ4uJAfg=="
},
"@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@ -22778,6 +22914,11 @@
}
}
},
"esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
},
"espree": {
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",

View File

@ -16,7 +16,8 @@
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
"@mui/x-data-grid": "5.13.0",
"@mui/x-data-grid-pro": "5.13.0",
"@mui/x-license-pro": "5.12.3",
"@react-jvectormap/core": "1.0.1",
"@react-jvectormap/world": "1.0.0",
"@testing-library/jest-dom": "5.16.2",

View File

@ -12,6 +12,7 @@ import {
} from "react-router-dom";
// @mui material components
import { LicenseInfo } from "@mui/x-license-pro";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import Icon from "@mui/material/Icon";
@ -112,6 +113,8 @@ function getStaticRoutes()
];
}
LicenseInfo.setLicenseKey("4ef48a0226ec7b5fb49d99f14c6b3170Tz00NzI0NyxFPTE2ODkyODU1NzUxMDYsUz1wcm8sTE09c3Vic2NyaXB0aW9uLEtWPTI=");
export default function App()
{
const [controller, dispatch] = useMaterialUIController();

View File

@ -22,9 +22,10 @@ import MenuItem from "@mui/material/MenuItem";
import Link from "@mui/material/Link";
import {Alert} from "@mui/material";
import {
DataGrid,
DataGridPro,
GridCallbackDetails,
GridColDef,
GridColumnOrderChangeParams,
GridColumnVisibilityModel,
GridFilterModel,
GridRowId,
@ -38,13 +39,14 @@ import {
GridToolbarDensitySelector,
GridToolbarExport,
GridToolbarFilterButton,
} from "@mui/x-data-grid";
} from "@mui/x-data-grid-pro";
// Material Dashboard 2 PRO React TS components
import DashboardLayout from "examples/LayoutContainers/DashboardLayout";
import DashboardNavbar from "examples/Navbars/DashboardNavbar";
import MDBox from "components/MDBox";
import MDButton from "components/MDButton";
import MDAlert from "components/MDAlert";
// QQQ
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
@ -55,7 +57,6 @@ import { QFilterCriteria } from "@kingsrook/qqq-frontend-core/lib/model/query/QF
import {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator";
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
import QClient from "qqq/utils/QClient";
import MDAlert from "components/MDAlert";
import Footer from "../../components/Footer";
import QProcessUtils from "../../utils/QProcessUtils";
@ -74,10 +75,28 @@ function EntityList({ table }: Props): JSX.Element
{
const tableNameParam = useParams().tableName;
const tableName = table === null ? tableNameParam : table.name;
const [searchParams] = useSearchParams();
////////////////////////////////////////////
// look for defaults in the local storage //
////////////////////////////////////////////
const sortLocalStorageKey = `${COLUMN_SORT_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
const columnVisibilityLocalStorageKey = `${COLUMN_VISIBILITY_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
let defaultSort = [] as GridSortItem[];
let defaultVisibility = {};
if (localStorage.getItem(sortLocalStorageKey))
{
defaultSort = JSON.parse(localStorage.getItem(sortLocalStorageKey));
}
if (localStorage.getItem(columnVisibilityLocalStorageKey))
{
defaultVisibility = JSON.parse(localStorage.getItem(columnVisibilityLocalStorageKey));
}
const [buttonText, setButtonText] = useState("");
const [tableState, setTableState] = useState("");
const [filtersMenu, setFiltersMenu] = useState(null);
const [, setFiltersMenu] = useState(null);
const [actionsMenu, setActionsMenu] = useState(null);
const [tableProcesses, setTableProcesses] = useState([] as QProcessMetaData[]);
const [pageNumber, setPageNumber] = useState(0);
@ -88,22 +107,16 @@ function EntityList({ table }: Props): JSX.Element
const [columns, setColumns] = useState([] as GridColDef[]);
const [rows, setRows] = useState([] as GridRowsProp[]);
const [loading, setLoading] = useState(true);
const [columnVisibilityModel, setColumnVisibilityModel] = useState({});
const [sortModel, setSortModel] = useState([] as GridSortItem[]);
const [filterModel, setFilterModel] = useState(null as GridFilterModel);
const [alertContent, setAlertContent] = useState("");
const [tableLabel, setTableLabel] = useState("");
const [columnSortModel, setColumnSortModel] = useState(defaultSort);
const [columnVisibilityModel, setColumnVisibilityModel] = useState(defaultVisibility);
const [searchParams, setSearchParams] = useSearchParams();
const [, forceUpdate] = useReducer((x) => x + 1, 0);
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
const closeActionsMenu = () => setActionsMenu(null);
const openFiltersMenu = (event: any) => setFiltersMenu(event.currentTarget);
const closeFiltersMenu = () => setFiltersMenu(null);
let columnVisibilityLocalStorageKey = "";
let columnSortLocalStorageKey = "";
const translateCriteriaOperator = (operator: string) =>
{
@ -148,9 +161,9 @@ function EntityList({ table }: Props): JSX.Element
const buildQFilter = () =>
{
const qFilter = new QQueryFilter();
if (sortModel)
if (columnSortModel)
{
sortModel.forEach((gridSortItem) =>
columnSortModel.forEach((gridSortItem) =>
{
qFilter.addOrderBy(new QFilterOrderBy(gridSortItem.field, gridSortItem.sort === "asc"));
});
@ -176,25 +189,23 @@ function EntityList({ table }: Props): JSX.Element
{
(async () =>
{
const qFilter = buildQFilter();
const tableMetaData = await QClient.loadTableMetaData(tableName);
const count = await QClient.count(tableName, qFilter);
setTotalRecords(count);
setButtonText(`new ${tableMetaData.label}`);
columnSortLocalStorageKey = `${COLUMN_SORT_LOCAL_STORAGE_KEY_ROOT}.${tableMetaData.name}`;
columnVisibilityLocalStorageKey = `${COLUMN_VISIBILITY_LOCAL_STORAGE_KEY_ROOT}.${tableMetaData.name}`;
setTableLabel(tableMetaData.label);
if (sortModel.length === 0)
if (columnSortModel.length === 0)
{
sortModel.push({
columnSortModel.push({
field: tableMetaData.primaryKeyField,
sort: "desc",
});
setSortModel(sortModel);
setColumnSortModel(columnSortModel);
}
const qFilter = buildQFilter();
const count = await QClient.count(tableName, qFilter);
setTotalRecords(count);
setButtonText(`new ${tableMetaData.label}`);
setTableLabel(tableMetaData.label);
const columns = [] as GridColDef[];
const results = await QClient.query(
@ -265,13 +276,6 @@ function EntityList({ table }: Props): JSX.Element
}
});
const columnVisibilityModel = localStorage.getItem(columnVisibilityLocalStorageKey);
if (columnVisibilityModel)
{
setColumnVisibilityModel(
JSON.parse(localStorage.getItem(columnVisibilityLocalStorageKey)),
);
}
setColumns(columns);
setRows(rows);
setLoading(false);
@ -321,16 +325,29 @@ function EntityList({ table }: Props): JSX.Element
const handleColumnVisibilityChange = (columnVisibilityModel: GridColumnVisibilityModel) =>
{
setColumnVisibilityModel(columnVisibilityModel);
if (columnVisibilityLocalStorageKey)
{
localStorage.setItem(
columnVisibilityLocalStorageKey,
JSON.stringify(columnVisibilityModel),
);
}
};
const handleColumnOrderChange = (columnOrderChangeParams: GridColumnOrderChangeParams) =>
{
// TODO: make local storaged
console.log(JSON.stringify(columns));
console.log(columnOrderChangeParams);
};
const handleSortChange = (gridSort: GridSortModel) =>
{
setSortModel(gridSort);
localStorage.setItem(columnSortLocalStorageKey, JSON.stringify(gridSort));
if (gridSort && gridSort.length > 0)
{
setColumnSortModel(gridSort);
localStorage.setItem(sortLocalStorageKey, JSON.stringify(gridSort));
}
};
if (tableName !== tableState)
@ -338,8 +355,6 @@ function EntityList({ table }: Props): JSX.Element
(async () =>
{
setTableState(tableName);
setSortModel([] as GridSortItem[]);
setColumnVisibilityModel({});
setFilterModel(null);
setFiltersMenu(null);
const metaData = await QClient.loadMetaData();
@ -441,9 +456,8 @@ function EntityList({ table }: Props): JSX.Element
useEffect(() =>
{
console.log("UPDATING");
updateTable();
}, [pageNumber, rowsPerPage, tableState, sortModel, filterModel]);
}, [pageNumber, rowsPerPage, tableState, columnSortModel, filterModel]);
return (
<DashboardLayout>
@ -492,7 +506,7 @@ function EntityList({ table }: Props): JSX.Element
</MDBox>
<Card>
<MDBox height="100%">
<DataGrid
<DataGridPro
components={{Toolbar: CustomToolbar}}
paginationMode="server"
sortingMode="server"
@ -515,10 +529,11 @@ function EntityList({ table }: Props): JSX.Element
onFilterModelChange={handleFilterChange}
columnVisibilityModel={columnVisibilityModel}
onColumnVisibilityModelChange={handleColumnVisibilityChange}
onColumnOrderChange={handleColumnOrderChange}
onSelectionModelChange={selectionChanged}
onSortModelChange={handleSortChange}
sortingOrder={["asc", "desc"]}
sortModel={sortModel}
sortModel={columnSortModel}
getRowClassName={(params) => (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")}
/>
</MDBox>

View File

@ -22,7 +22,6 @@ import Grid from "@mui/material/Grid";
import MDBox from "components/MDBox";
// Settings page components
// import CreateForm from "qqq/pages/entity-create/components/CreateForm";
import BaseLayout from "qqq/components/BaseLayout";
import ViewContents from "./components/ViewContents";