From ed17a311afaeb6ff5d57b6a5c940dcfbd364d125 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 3 Mar 2023 10:07:29 -0600 Subject: [PATCH] Checkpoint - nearing releasable! --- src/qqq/pages/records/query/ColumnStats.tsx | 167 +++++++++++++------- src/qqq/utils/DataGridUtils.tsx | 7 + 2 files changed, 116 insertions(+), 58 deletions(-) diff --git a/src/qqq/pages/records/query/ColumnStats.tsx b/src/qqq/pages/records/query/ColumnStats.tsx index 1c94cfd..088de5b 100644 --- a/src/qqq/pages/records/query/ColumnStats.tsx +++ b/src/qqq/pages/records/query/ColumnStats.tsx @@ -28,13 +28,16 @@ import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord"; import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; import {TablePagination} from "@mui/material"; import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import Grid from "@mui/material/Grid"; import LinearProgress from "@mui/material/LinearProgress"; import Typography from "@mui/material/Typography"; -import {DataGridPro} from "@mui/x-data-grid-pro"; +import {DataGridPro, GridSortModel} from "@mui/x-data-grid-pro"; import FormData from "form-data"; import React, {useEffect, useState} from "react"; import DataGridUtils from "qqq/utils/DataGridUtils"; import Client from "qqq/utils/qqq/Client"; +import ValueUtils from "qqq/utils/qqq/ValueUtils"; interface Props { @@ -51,33 +54,62 @@ const qController = Client.getInstance(); function ColumnStats({tableMetaData, fieldMetaData, filter}: Props): JSX.Element { const [statusString, setStatusString] = useState("Calculating statistics..."); - const [isLoaded, setIsLoaded] = useState(false); + const [loading, setLoading] = useState(true); const [valueCounts, setValueCounts] = useState(null as QRecord[]); + const [statsRecord, setStatsRecord] = useState(null as QRecord); + const [orderBy, setOrderBy] = useState(null as string); + const [statsFields, setStatsFields] = useState([] as QFieldMetaData[]); const [countDistinct, setCountDistinct] = useState(null as number); const [rows, setRows] = useState([]); const [columns, setColumns] = useState([]); useEffect(() => { + if(!loading) + { + return; + } + (async () => { const formData = new FormData(); formData.append("tableName", tableMetaData.name); formData.append("fieldName", fieldMetaData.name); formData.append("filterJSON", JSON.stringify(filter)); + if(orderBy) + { + formData.append("orderBy", orderBy); + } const processResult = await qController.processRun("tableStats", formData); setStatusString(null) if (processResult instanceof QJobError) { const jobError = processResult as QJobError; - // todo setErrorAlert(); - console.error("Error fetching column stats" + jobError.error); + setStatusString("Error fetching column stats: " + jobError.error); + setLoading(false); } else { const result = processResult as QJobComplete; - setCountDistinct(result.values.countDistinct); + + const statFieldObjects = result.values.statsFields; + if(statFieldObjects && statFieldObjects.length) + { + const newStatsFields = [] as QFieldMetaData[]; + for(let i = 0; i - { - const n1 = parseInt(v1.replaceAll(",", "")); - const n2 = parseInt(v2.replaceAll(",", "")); - return (n1 - n2); - } + columns[0].width = 200; + columns[1].width = 200; setRows(rows); setColumns(columns); - - setIsLoaded(true); + setLoading(false); } })(); - }, []); - - // @ts-ignore - const defaultLabelDisplayedRows = ({from, to, count}) => - { - // todo - not done - return ("Showing stuff"); - }; + }, [loading]); function CustomPagination() { return ( - + + {rows && rows.length && countDistinct && rows.length < countDistinct ? Showing the first {rows.length.toLocaleString()} of {countDistinct.toLocaleString()} values : <>} + {rows && rows.length && countDistinct && rows.length >= countDistinct && rows.length == 1 ? Showing the only value : <>} + {rows && rows.length && countDistinct && rows.length >= countDistinct && rows.length > 1 ? Showing all {rows.length.toLocaleString()} values : <>} + ); } + const refresh = () => + { + setLoading(true) + setStatusString("Refreshing...") + } + function Loading() { return ( @@ -139,43 +161,72 @@ function ColumnStats({tableMetaData, fieldMetaData, filter}: Props): JSX.Element ); } + const handleSortChange = (gridSort: GridSortModel) => + { + if (gridSort && gridSort.length > 0) + { + console.log("Sort: ", gridSort[0]); + setOrderBy(`${gridSort[0].field}.${gridSort[0].sort}`); + refresh(); + } + }; + return ( - Column Statistics for {tableMetaData.label}: {fieldMetaData.label} + Column Statistics for {fieldMetaData.label} - {statusString} + {statusString ?? <> } + - -
-
Distinct Values:
{Number(countDistinct).toLocaleString()}
-
-
- - - (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")} - initialState={{ - sorting: { - sortModel: [ - { - field: "count", - sort: "desc", + + + + (params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")} + sortingMode={"server"} + onSortModelChange={handleSortChange} + sortingOrder={["desc", "asc"]} + pagination={true} + paginationMode={"server"} + initialState={{ + sorting: { + sortModel: [ + { + field: "count", + sort: "desc", + }, + ], }, - ], - }, - }} - /> - + }} + /> + + + + + { + statsFields && statsFields.map((field) => + ( + +
{field.label}:
+
{ValueUtils.getValueForDisplay(field, statsRecord?.values.get(field.name), statsRecord?.displayValues.get(field.name))}
+
+ )) + } +
+
+
); } diff --git a/src/qqq/utils/DataGridUtils.tsx b/src/qqq/utils/DataGridUtils.tsx index 319eaca..99c5d72 100644 --- a/src/qqq/utils/DataGridUtils.tsx +++ b/src/qqq/utils/DataGridUtils.tsx @@ -57,6 +57,13 @@ export default class DataGridUtils if(!row["id"]) { row["id"] = record.values.get(tableMetaData.primaryKeyField) ?? row[tableMetaData.primaryKeyField]; + if(row["id"] === null || row["id"] === undefined) + { + ///////////////////////////////////////////////////////////////////////////////////////// + // DataGrid gets very upset about a null or undefined here, so, try to make it happier // + ///////////////////////////////////////////////////////////////////////////////////////// + row["id"] = "--"; + } } rows.push(row);