diff --git a/.eslintrc.json b/.eslintrc.json index 2684097..86d3b2b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,93 +1,100 @@ { - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "plugin:react/recommended", - "airbnb" - ], - "globals": { - "JSX": true - }, - "ignorePatterns": [ - "src/assets", - "src/components", - "src/context", - "src/examples", - "src/layouts" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "react", - "@typescript-eslint" - ], - "rules": { - "brace-style": [ - 2, - "allman" - ], - "indent": [ - "error", - 3 - ], - "import/extensions": [ - "error", - "ignorePackages", - { - "ts": "never", - "tsx": "never", - "js": "never" + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "plugin:react/recommended", + "airbnb" + ], + "globals": { + "JSX": true + }, + "ignorePatterns": [ + "src/assets", + "src/components", + "src/context", + "src/examples", + "src/layouts" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": { + "brace-style": [ + 2, + "allman" + ], + "indent": [ + "error", + 3, + { + "SwitchCase": 1 + } + ], + "import/extensions": [ + "error", + "ignorePackages", + { + "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": {} - } - } + } } diff --git a/package-lock.json b/package-lock.json index c2721f3..11ad173 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 64363f0..04865c6 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.tsx b/src/App.tsx index 132755c..9891839 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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(); diff --git a/src/qqq/pages/entity-list/index.tsx b/src/qqq/pages/entity-list/index.tsx index 48d06f7..876fb81 100644 --- a/src/qqq/pages/entity-list/index.tsx +++ b/src/qqq/pages/entity-list/index.tsx @@ -11,8 +11,8 @@ */ /* eslint-disable react/no-unstable-nested-components */ -import React, { useEffect, useReducer, useState } from "react"; -import { useParams, useSearchParams } from "react-router-dom"; +import React, {useEffect, useReducer, useState} from "react"; +import {useParams, useSearchParams} from "react-router-dom"; // @mui material components import Card from "@mui/material/Card"; @@ -20,11 +20,12 @@ import Icon from "@mui/material/Icon"; import Menu from "@mui/material/Menu"; import MenuItem from "@mui/material/MenuItem"; import Link from "@mui/material/Link"; -import { Alert } from "@mui/material"; +import {Alert} from "@mui/material"; import { - DataGrid, + DataGridPro, GridCallbackDetails, GridColDef, + GridColumnOrderChangeParams, GridColumnVisibilityModel, GridFilterModel, GridRowId, @@ -38,24 +39,24 @@ 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"; -import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; -import { QQueryFilter } from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; -import { QFilterOrderBy } from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy"; -import { QFilterCriteria } from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria"; -import { QCriteriaOperator } from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator"; -import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType"; +import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData"; +import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; +import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; +import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy"; +import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria"; +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"; @@ -67,17 +68,35 @@ const COLUMN_SORT_LOCAL_STORAGE_KEY_ROOT = "qqq.columnSort"; // Declaring props types for DefaultCell interface Props { - table?: QTableMetaData; + table?: QTableMetaData; } -function EntityList({ table }: Props): JSX.Element +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,69 +107,63 @@ 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) => { switch (operator) { - case "contains": - return QCriteriaOperator.CONTAINS; - case "startsWith": - return QCriteriaOperator.STARTS_WITH; - case "endsWith": - return QCriteriaOperator.ENDS_WITH; - case "is": - case "equals": - case "=": - return QCriteriaOperator.EQUALS; - case "isNot": - case "!=": - return QCriteriaOperator.NOT_EQUALS; - case "after": - case ">": - return QCriteriaOperator.GREATER_THAN; - case "onOrAfter": - case ">=": - return QCriteriaOperator.GREATER_THAN_OR_EQUALS; - case "before": - case "<": - return QCriteriaOperator.LESS_THAN; - case "onOrBefore": - case "<=": - return QCriteriaOperator.LESS_THAN_OR_EQUALS; - case "isEmpty": - return QCriteriaOperator.IS_BLANK; - case "isNotEmpty": - return QCriteriaOperator.IS_NOT_BLANK; - // case "is any of": - // TODO: handle this case - default: - return QCriteriaOperator.EQUALS; + case "contains": + return QCriteriaOperator.CONTAINS; + case "startsWith": + return QCriteriaOperator.STARTS_WITH; + case "endsWith": + return QCriteriaOperator.ENDS_WITH; + case "is": + case "equals": + case "=": + return QCriteriaOperator.EQUALS; + case "isNot": + case "!=": + return QCriteriaOperator.NOT_EQUALS; + case "after": + case ">": + return QCriteriaOperator.GREATER_THAN; + case "onOrAfter": + case ">=": + return QCriteriaOperator.GREATER_THAN_OR_EQUALS; + case "before": + case "<": + return QCriteriaOperator.LESS_THAN; + case "onOrBefore": + case "<=": + return QCriteriaOperator.LESS_THAN_OR_EQUALS; + case "isEmpty": + return QCriteriaOperator.IS_BLANK; + case "isNotEmpty": + return QCriteriaOperator.IS_NOT_BLANK; + // case "is any of": + // TODO: handle this case + default: + return QCriteriaOperator.EQUALS; } }; 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( @@ -230,21 +241,21 @@ function EntityList({ table }: Props): JSX.Element let columnType = "string"; switch (field.type) { - case QFieldType.DECIMAL: - case QFieldType.INTEGER: - columnType = "number"; - break; - case QFieldType.DATE: - columnType = "date"; - break; - case QFieldType.DATE_TIME: - columnType = "dateTime"; - break; - case QFieldType.BOOLEAN: - columnType = "boolean"; - break; - default: - // noop + case QFieldType.DECIMAL: + case QFieldType.INTEGER: + columnType = "number"; + break; + case QFieldType.DATE: + columnType = "date"; + break; + case QFieldType.DATE_TIME: + columnType = "dateTime"; + break; + case QFieldType.BOOLEAN: + columnType = "boolean"; + break; + default: + // noop } 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); setRows(rows); setLoading(false); @@ -321,16 +325,29 @@ function EntityList({ table }: Props): JSX.Element const handleColumnVisibilityChange = (columnVisibilityModel: GridColumnVisibilityModel) => { setColumnVisibilityModel(columnVisibilityModel); - localStorage.setItem( - columnVisibilityLocalStorageKey, - JSON.stringify(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 ( @@ -492,8 +506,8 @@ function EntityList({ table }: Props): JSX.Element - (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")} /> diff --git a/src/qqq/pages/entity-view/index.tsx b/src/qqq/pages/entity-view/index.tsx index d5639c2..7a85816 100644 --- a/src/qqq/pages/entity-view/index.tsx +++ b/src/qqq/pages/entity-view/index.tsx @@ -13,7 +13,7 @@ * 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 import Grid from "@mui/material/Grid"; @@ -22,13 +22,12 @@ 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"; function EntityView(): JSX.Element { - const { id } = useParams(); + const {id} = useParams(); return (