Merge branch 'feature/sprint-10' into feature/QQQ-38-app-home-widgets

This commit is contained in:
Tim Chamberlain
2022-09-01 16:28:31 -05:00
15 changed files with 1274 additions and 185 deletions

View File

@ -22,7 +22,6 @@
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 {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator";
import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria";
import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy";
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
@ -33,9 +32,9 @@ import Icon from "@mui/material/Icon";
import LinearProgress from "@mui/material/LinearProgress";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnOrderChangeParams, GridColumnVisibilityModel, GridFilterModel, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, GridExportMenuItemProps, MuiEvent,} from "@mui/x-data-grid-pro";
import React, {useCallback, useEffect, useReducer, useRef, useState,} from "react";
import {Link, useNavigate, useParams, useSearchParams,} from "react-router-dom";
import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnOrderChangeParams, GridColumnVisibilityModel, GridFilterModel, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, GridExportMenuItemProps, MuiEvent} from "@mui/x-data-grid-pro";
import React, {useCallback, useEffect, useReducer, useRef, useState} from "react";
import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom";
import DashboardLayout from "qqq/components/DashboardLayout";
import Footer from "qqq/components/Footer";
import Navbar from "qqq/components/Navbar";
@ -43,6 +42,7 @@ import {QActionsMenuButton, QCreateNewButton} from "qqq/components/QButtons";
import MDAlert from "qqq/components/Temporary/MDAlert";
import MDBox from "qqq/components/Temporary/MDBox";
import QClient from "qqq/utils/QClient";
import QFilterUtils from "qqq/utils/QFilterUtils";
import QProcessUtils from "qqq/utils/QProcessUtils";
import QValueUtils from "qqq/utils/QValueUtils";
@ -55,6 +55,52 @@ interface Props
table?: QTableMetaData;
}
/*******************************************************************************
** Get the default filter to use on the page - either from query string, or
** local storage, or a default (empty).
*******************************************************************************/
function getDefaultFilter(searchParams: URLSearchParams, filterLocalStorageKey: string): GridFilterModel
{
if (searchParams.has("filter"))
{
try
{
const qQueryFilter = JSON.parse(searchParams.get("filter")) as QQueryFilter;
console.log(`Got a filter from the query string: ${JSON.stringify(qQueryFilter)}`);
//////////////////////////////////////////////////////////////////
// translate from a qqq-style filter to one that the grid wants //
//////////////////////////////////////////////////////////////////
const defaultFilter = {items: []} as GridFilterModel;
let id = 1;
qQueryFilter.criteria.forEach((criteria) =>
{
defaultFilter.items.push({
columnField: criteria.fieldName,
operatorValue: QFilterUtils.qqqCriteriaOperatorToGrid(criteria.operator),
value: QFilterUtils.qqqCriteriaValuesToGrid(criteria.operator, criteria.values),
id: id++, // not sure what this id is!!
});
});
return (defaultFilter);
}
catch (e)
{
console.warn("Error parsing filter from query string", e);
}
}
if (localStorage.getItem(filterLocalStorageKey))
{
const defaultFilter = JSON.parse(localStorage.getItem(filterLocalStorageKey));
console.log(`Got default from LS: ${JSON.stringify(defaultFilter)}`);
return (defaultFilter);
}
return ({items: []});
}
function EntityList({table}: Props): JSX.Element
{
const tableNameParam = useParams().tableName;
@ -70,7 +116,7 @@ function EntityList({table}: Props): JSX.Element
const filterLocalStorageKey = `${FILTER_LOCAL_STORAGE_KEY_ROOT}.${tableName}`;
let defaultSort = [] as GridSortItem[];
let defaultVisibility = {};
let _defaultFilter = {items: []} as GridFilterModel;
const _defaultFilter = getDefaultFilter(searchParams, filterLocalStorageKey);
if (localStorage.getItem(sortLocalStorageKey))
{
@ -80,11 +126,6 @@ function EntityList({table}: Props): JSX.Element
{
defaultVisibility = JSON.parse(localStorage.getItem(columnVisibilityLocalStorageKey));
}
if (localStorage.getItem(filterLocalStorageKey))
{
_defaultFilter = JSON.parse(localStorage.getItem(filterLocalStorageKey));
console.log(`Got default from LS: ${JSON.stringify(_defaultFilter)}`);
}
const [filterModel, setFilterModel] = useState(_defaultFilter);
const [columnSortModel, setColumnSortModel] = useState(defaultSort);
@ -124,46 +165,6 @@ function EntityList({table}: Props): JSX.Element
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
const closeActionsMenu = () => setActionsMenu(null);
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;
}
};
const buildQFilter = () =>
{
const qFilter = new QQueryFilter();
@ -178,13 +179,9 @@ function EntityList({table}: Props): JSX.Element
{
filterModel.items.forEach((item) =>
{
const operator = translateCriteriaOperator(item.operatorValue);
let criteria = new QFilterCriteria(item.columnField, operator, [item.value]);
if (operator === QCriteriaOperator.IS_BLANK || operator === QCriteriaOperator.IS_NOT_BLANK)
{
criteria = new QFilterCriteria(item.columnField, operator, null);
}
qFilter.addCriteria(criteria);
const operator = QFilterUtils.gridCriteriaOperatorToQQQ(item.operatorValue);
const values = QFilterUtils.gridCriteriaValueToQQQ(operator, item.value);
qFilter.addCriteria(new QFilterCriteria(item.columnField, operator, values));
});
}