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

@ -1,93 +1,100 @@
{ {
"env": { "env": {
"browser": true, "browser": true,
"es2021": true "es2021": true
}, },
"extends": [ "extends": [
"plugin:react/recommended", "plugin:react/recommended",
"airbnb" "airbnb"
], ],
"globals": { "globals": {
"JSX": true "JSX": true
}, },
"ignorePatterns": [ "ignorePatterns": [
"src/assets", "src/assets",
"src/components", "src/components",
"src/context", "src/context",
"src/examples", "src/examples",
"src/layouts" "src/layouts"
], ],
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"ecmaFeatures": { "ecmaFeatures": {
"jsx": true "jsx": true
}, },
"ecmaVersion": "latest", "ecmaVersion": "latest",
"sourceType": "module" "sourceType": "module"
}, },
"plugins": [ "plugins": [
"react", "react",
"@typescript-eslint" "@typescript-eslint"
], ],
"rules": { "rules": {
"brace-style": [ "brace-style": [
2, 2,
"allman" "allman"
], ],
"indent": [ "indent": [
"error", "error",
3 3,
], {
"import/extensions": [ "SwitchCase": 1
"error", }
"ignorePackages", ],
{ "import/extensions": [
"ts": "never", "error",
"tsx": "never", "ignorePackages",
"js": "never" {
"ts": "never",
"tsx": "never",
"js": "never"
}
],
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"max-len": "off",
"no-console": "off",
"no-constant-condition": "off",
"no-shadow": "off",
"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": [
"warn",
{
"extensions": [
".tsx"
]
}
],
"react/jsx-indent": [
"error",
3
],
"react/jsx-indent-props": [
"error",
3
],
"react/jsx-props-no-spreading": "off",
"react/react-in-jsx-scope": "off",
"quotes": [
"error",
"double"
]
},
"settings": {
"import/resolver": {
"typescript": {}
} }
], }
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"max-len": "off",
"no-console": "off",
"no-constant-condition": "off",
"no-shadow": "off",
"no-unused-vars": "off",
"no-plusplus": "off",
"spaced-comment": "off",
"object-shorthand": "off",
"react/prop-types": "off",
"react/jsx-filename-extension": [
"warn",
{
"extensions": [
".tsx"
]
}
],
"react/jsx-indent": [
"error",
3
],
"react/jsx-indent-props": [
"error",
3
],
"react/jsx-props-no-spreading": "off",
"react/react-in-jsx-scope": "off",
"quotes": [
"error",
"double"
]
},
"settings": {
"import/resolver": {
"typescript": {}
}
}
} }

145
package-lock.json generated
View File

@ -20,7 +20,8 @@
"@mui/icons-material": "5.4.1", "@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1", "@mui/material": "5.4.1",
"@mui/styled-engine": "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/core": "1.0.1",
"@react-jvectormap/world": "1.0.0", "@react-jvectormap/world": "1.0.0",
"@testing-library/jest-dom": "5.16.2", "@testing-library/jest-dom": "5.16.2",
@ -73,7 +74,7 @@
} }
}, },
".yalc/@kingsrook/qqq-frontend-core": { ".yalc/@kingsrook/qqq-frontend-core": {
"version": "1.0.2", "version": "1.0.3",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "0.27.2" "axios": "0.27.2"
@ -3315,6 +3316,76 @@
"react-dom": "^17.0.2 || ^18.0.0" "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": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -4113,6 +4184,11 @@
"@types/range-parser": "*" "@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": { "node_modules/@types/graceful-fs": {
"version": "4.1.5", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", "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": "^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": { "node_modules/espree": {
"version": "9.3.2", "version": "9.3.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
@ -19244,6 +19328,53 @@
"reselect": "^4.1.6" "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": { "@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -19801,6 +19932,11 @@
"@types/range-parser": "*" "@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": { "@types/graceful-fs": {
"version": "4.1.5", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", "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": { "espree": {
"version": "9.3.2", "version": "9.3.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",

View File

@ -16,7 +16,8 @@
"@mui/icons-material": "5.4.1", "@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1", "@mui/material": "5.4.1",
"@mui/styled-engine": "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/core": "1.0.1",
"@react-jvectormap/world": "1.0.0", "@react-jvectormap/world": "1.0.0",
"@testing-library/jest-dom": "5.16.2", "@testing-library/jest-dom": "5.16.2",

View File

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

View File

@ -11,8 +11,8 @@
*/ */
/* eslint-disable react/no-unstable-nested-components */ /* eslint-disable react/no-unstable-nested-components */
import React, { useEffect, useReducer, useState } from "react"; import React, {useEffect, useReducer, useState} from "react";
import { useParams, useSearchParams } from "react-router-dom"; import {useParams, useSearchParams} from "react-router-dom";
// @mui material components // @mui material components
import Card from "@mui/material/Card"; import Card from "@mui/material/Card";
@ -20,11 +20,12 @@ import Icon from "@mui/material/Icon";
import Menu from "@mui/material/Menu"; import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import { Alert } from "@mui/material"; import {Alert} from "@mui/material";
import { import {
DataGrid, DataGridPro,
GridCallbackDetails, GridCallbackDetails,
GridColDef, GridColDef,
GridColumnOrderChangeParams,
GridColumnVisibilityModel, GridColumnVisibilityModel,
GridFilterModel, GridFilterModel,
GridRowId, GridRowId,
@ -38,24 +39,24 @@ import {
GridToolbarDensitySelector, GridToolbarDensitySelector,
GridToolbarExport, GridToolbarExport,
GridToolbarFilterButton, GridToolbarFilterButton,
} from "@mui/x-data-grid"; } from "@mui/x-data-grid-pro";
// Material Dashboard 2 PRO React TS components // Material Dashboard 2 PRO React TS components
import DashboardLayout from "examples/LayoutContainers/DashboardLayout"; import DashboardLayout from "examples/LayoutContainers/DashboardLayout";
import DashboardNavbar from "examples/Navbars/DashboardNavbar"; import DashboardNavbar from "examples/Navbars/DashboardNavbar";
import MDBox from "components/MDBox"; import MDBox from "components/MDBox";
import MDButton from "components/MDButton"; import MDButton from "components/MDButton";
import MDAlert from "components/MDAlert";
// QQQ // QQQ
import { QProcessMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData"; import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import { QQueryFilter } from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
import { QFilterOrderBy } from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy"; import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
import { QFilterCriteria } from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria"; import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
import { QCriteriaOperator } from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator"; import {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator";
import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType"; import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
import QClient from "qqq/utils/QClient"; import QClient from "qqq/utils/QClient";
import MDAlert from "components/MDAlert";
import Footer from "../../components/Footer"; import Footer from "../../components/Footer";
import QProcessUtils from "../../utils/QProcessUtils"; import QProcessUtils from "../../utils/QProcessUtils";
@ -67,17 +68,35 @@ const COLUMN_SORT_LOCAL_STORAGE_KEY_ROOT = "qqq.columnSort";
// Declaring props types for DefaultCell // Declaring props types for DefaultCell
interface Props interface Props
{ {
table?: QTableMetaData; table?: QTableMetaData;
} }
function EntityList({ table }: Props): JSX.Element function EntityList({table}: Props): JSX.Element
{ {
const tableNameParam = useParams().tableName; const tableNameParam = useParams().tableName;
const tableName = table === null ? tableNameParam : table.name; 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 [buttonText, setButtonText] = useState("");
const [tableState, setTableState] = useState(""); const [tableState, setTableState] = useState("");
const [filtersMenu, setFiltersMenu] = useState(null); const [, setFiltersMenu] = useState(null);
const [actionsMenu, setActionsMenu] = useState(null); const [actionsMenu, setActionsMenu] = useState(null);
const [tableProcesses, setTableProcesses] = useState([] as QProcessMetaData[]); const [tableProcesses, setTableProcesses] = useState([] as QProcessMetaData[]);
const [pageNumber, setPageNumber] = useState(0); const [pageNumber, setPageNumber] = useState(0);
@ -88,69 +107,63 @@ function EntityList({ table }: Props): JSX.Element
const [columns, setColumns] = useState([] as GridColDef[]); const [columns, setColumns] = useState([] as GridColDef[]);
const [rows, setRows] = useState([] as GridRowsProp[]); const [rows, setRows] = useState([] as GridRowsProp[]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [columnVisibilityModel, setColumnVisibilityModel] = useState({});
const [sortModel, setSortModel] = useState([] as GridSortItem[]);
const [filterModel, setFilterModel] = useState(null as GridFilterModel); const [filterModel, setFilterModel] = useState(null as GridFilterModel);
const [alertContent, setAlertContent] = useState(""); const [alertContent, setAlertContent] = useState("");
const [tableLabel, setTableLabel] = 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 [, forceUpdate] = useReducer((x) => x + 1, 0);
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget); const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
const closeActionsMenu = () => setActionsMenu(null); const closeActionsMenu = () => setActionsMenu(null);
const openFiltersMenu = (event: any) => setFiltersMenu(event.currentTarget);
const closeFiltersMenu = () => setFiltersMenu(null);
let columnVisibilityLocalStorageKey = "";
let columnSortLocalStorageKey = "";
const translateCriteriaOperator = (operator: string) => const translateCriteriaOperator = (operator: string) =>
{ {
switch (operator) switch (operator)
{ {
case "contains": case "contains":
return QCriteriaOperator.CONTAINS; return QCriteriaOperator.CONTAINS;
case "startsWith": case "startsWith":
return QCriteriaOperator.STARTS_WITH; return QCriteriaOperator.STARTS_WITH;
case "endsWith": case "endsWith":
return QCriteriaOperator.ENDS_WITH; return QCriteriaOperator.ENDS_WITH;
case "is": case "is":
case "equals": case "equals":
case "=": case "=":
return QCriteriaOperator.EQUALS; return QCriteriaOperator.EQUALS;
case "isNot": case "isNot":
case "!=": case "!=":
return QCriteriaOperator.NOT_EQUALS; return QCriteriaOperator.NOT_EQUALS;
case "after": case "after":
case ">": case ">":
return QCriteriaOperator.GREATER_THAN; return QCriteriaOperator.GREATER_THAN;
case "onOrAfter": case "onOrAfter":
case ">=": case ">=":
return QCriteriaOperator.GREATER_THAN_OR_EQUALS; return QCriteriaOperator.GREATER_THAN_OR_EQUALS;
case "before": case "before":
case "<": case "<":
return QCriteriaOperator.LESS_THAN; return QCriteriaOperator.LESS_THAN;
case "onOrBefore": case "onOrBefore":
case "<=": case "<=":
return QCriteriaOperator.LESS_THAN_OR_EQUALS; return QCriteriaOperator.LESS_THAN_OR_EQUALS;
case "isEmpty": case "isEmpty":
return QCriteriaOperator.IS_BLANK; return QCriteriaOperator.IS_BLANK;
case "isNotEmpty": case "isNotEmpty":
return QCriteriaOperator.IS_NOT_BLANK; return QCriteriaOperator.IS_NOT_BLANK;
// case "is any of": // case "is any of":
// TODO: handle this case // TODO: handle this case
default: default:
return QCriteriaOperator.EQUALS; return QCriteriaOperator.EQUALS;
} }
}; };
const buildQFilter = () => const buildQFilter = () =>
{ {
const qFilter = new QQueryFilter(); const qFilter = new QQueryFilter();
if (sortModel) if (columnSortModel)
{ {
sortModel.forEach((gridSortItem) => columnSortModel.forEach((gridSortItem) =>
{ {
qFilter.addOrderBy(new QFilterOrderBy(gridSortItem.field, gridSortItem.sort === "asc")); qFilter.addOrderBy(new QFilterOrderBy(gridSortItem.field, gridSortItem.sort === "asc"));
}); });
@ -176,25 +189,23 @@ function EntityList({ table }: Props): JSX.Element
{ {
(async () => (async () =>
{ {
const qFilter = buildQFilter();
const tableMetaData = await QClient.loadTableMetaData(tableName); const tableMetaData = await QClient.loadTableMetaData(tableName);
const count = await QClient.count(tableName, qFilter); if (columnSortModel.length === 0)
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)
{ {
sortModel.push({ columnSortModel.push({
field: tableMetaData.primaryKeyField, field: tableMetaData.primaryKeyField,
sort: "desc", 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 columns = [] as GridColDef[];
const results = await QClient.query( const results = await QClient.query(
@ -230,21 +241,21 @@ function EntityList({ table }: Props): JSX.Element
let columnType = "string"; let columnType = "string";
switch (field.type) switch (field.type)
{ {
case QFieldType.DECIMAL: case QFieldType.DECIMAL:
case QFieldType.INTEGER: case QFieldType.INTEGER:
columnType = "number"; columnType = "number";
break; break;
case QFieldType.DATE: case QFieldType.DATE:
columnType = "date"; columnType = "date";
break; break;
case QFieldType.DATE_TIME: case QFieldType.DATE_TIME:
columnType = "dateTime"; columnType = "dateTime";
break; break;
case QFieldType.BOOLEAN: case QFieldType.BOOLEAN:
columnType = "boolean"; columnType = "boolean";
break; break;
default: default:
// noop // noop
} }
const column = { const column = {
@ -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); setColumns(columns);
setRows(rows); setRows(rows);
setLoading(false); setLoading(false);
@ -321,16 +325,29 @@ function EntityList({ table }: Props): JSX.Element
const handleColumnVisibilityChange = (columnVisibilityModel: GridColumnVisibilityModel) => const handleColumnVisibilityChange = (columnVisibilityModel: GridColumnVisibilityModel) =>
{ {
setColumnVisibilityModel(columnVisibilityModel); setColumnVisibilityModel(columnVisibilityModel);
localStorage.setItem( if (columnVisibilityLocalStorageKey)
columnVisibilityLocalStorageKey, {
JSON.stringify(columnVisibilityModel), 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) => const handleSortChange = (gridSort: GridSortModel) =>
{ {
setSortModel(gridSort); if (gridSort && gridSort.length > 0)
localStorage.setItem(columnSortLocalStorageKey, JSON.stringify(gridSort)); {
setColumnSortModel(gridSort);
localStorage.setItem(sortLocalStorageKey, JSON.stringify(gridSort));
}
}; };
if (tableName !== tableState) if (tableName !== tableState)
@ -338,8 +355,6 @@ function EntityList({ table }: Props): JSX.Element
(async () => (async () =>
{ {
setTableState(tableName); setTableState(tableName);
setSortModel([] as GridSortItem[]);
setColumnVisibilityModel({});
setFilterModel(null); setFilterModel(null);
setFiltersMenu(null); setFiltersMenu(null);
const metaData = await QClient.loadMetaData(); const metaData = await QClient.loadMetaData();
@ -441,9 +456,8 @@ function EntityList({ table }: Props): JSX.Element
useEffect(() => useEffect(() =>
{ {
console.log("UPDATING");
updateTable(); updateTable();
}, [pageNumber, rowsPerPage, tableState, sortModel, filterModel]); }, [pageNumber, rowsPerPage, tableState, columnSortModel, filterModel]);
return ( return (
<DashboardLayout> <DashboardLayout>
@ -492,8 +506,8 @@ function EntityList({ table }: Props): JSX.Element
</MDBox> </MDBox>
<Card> <Card>
<MDBox height="100%"> <MDBox height="100%">
<DataGrid <DataGridPro
components={{ Toolbar: CustomToolbar }} components={{Toolbar: CustomToolbar}}
paginationMode="server" paginationMode="server"
sortingMode="server" sortingMode="server"
filterMode="server" filterMode="server"
@ -515,10 +529,11 @@ function EntityList({ table }: Props): JSX.Element
onFilterModelChange={handleFilterChange} onFilterModelChange={handleFilterChange}
columnVisibilityModel={columnVisibilityModel} columnVisibilityModel={columnVisibilityModel}
onColumnVisibilityModelChange={handleColumnVisibilityChange} onColumnVisibilityModelChange={handleColumnVisibilityChange}
onColumnOrderChange={handleColumnOrderChange}
onSelectionModelChange={selectionChanged} onSelectionModelChange={selectionChanged}
onSortModelChange={handleSortChange} onSortModelChange={handleSortChange}
sortingOrder={["asc", "desc"]} sortingOrder={["asc", "desc"]}
sortModel={sortModel} sortModel={columnSortModel}
getRowClassName={(params) => (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")} getRowClassName={(params) => (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")}
/> />
</MDBox> </MDBox>

View File

@ -13,7 +13,7 @@
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/ */
import { useParams } from "react-router-dom"; import {useParams} from "react-router-dom";
// @mui material components // @mui material components
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
@ -22,13 +22,12 @@ import Grid from "@mui/material/Grid";
import MDBox from "components/MDBox"; import MDBox from "components/MDBox";
// Settings page components // Settings page components
// import CreateForm from "qqq/pages/entity-create/components/CreateForm";
import BaseLayout from "qqq/components/BaseLayout"; import BaseLayout from "qqq/components/BaseLayout";
import ViewContents from "./components/ViewContents"; import ViewContents from "./components/ViewContents";
function EntityView(): JSX.Element function EntityView(): JSX.Element
{ {
const { id } = useParams(); const {id} = useParams();
return ( return (
<BaseLayout> <BaseLayout>