Add field adornments

This commit is contained in:
2022-09-23 17:09:12 -05:00
parent 67e65de66b
commit d1841b038f
3 changed files with 110 additions and 10 deletions

View File

@ -13,7 +13,7 @@
"@fullcalendar/interaction": "5.10.0", "@fullcalendar/interaction": "5.10.0",
"@fullcalendar/react": "5.10.0", "@fullcalendar/react": "5.10.0",
"@fullcalendar/timegrid": "5.10.0", "@fullcalendar/timegrid": "5.10.0",
"@kingsrook/qqq-frontend-core": "1.0.21", "@kingsrook/qqq-frontend-core": "1.0.22",
"@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",

View File

@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType"; import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
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";
@ -33,7 +34,27 @@ import Icon from "@mui/material/Icon";
import LinearProgress from "@mui/material/LinearProgress"; import LinearProgress from "@mui/material/LinearProgress";
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 {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 {
DataGridPro,
GridCallbackDetails,
GridColDef,
GridColumnOrderChangeParams,
GridColumnVisibilityModel,
GridExportMenuItemProps,
GridFilterModel,
GridRowId,
GridRowParams,
GridRowsProp,
GridSelectionModel,
GridSortItem,
GridSortModel,
GridToolbarColumnsButton,
GridToolbarContainer,
GridToolbarDensitySelector,
GridToolbarExportContainer,
GridToolbarFilterButton,
MuiEvent
} from "@mui/x-data-grid-pro";
import React, {useCallback, useEffect, useReducer, useRef, useState} from "react"; import React, {useCallback, useEffect, useReducer, useRef, useState} from "react";
import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom"; import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom";
import DashboardLayout from "qqq/components/DashboardLayout"; import DashboardLayout from "qqq/components/DashboardLayout";
@ -324,12 +345,18 @@ function EntityList({table}: Props): JSX.Element
const fields = [...tableMetaData.fields.values()]; const fields = [...tableMetaData.fields.values()];
const rows = [] as any[]; const rows = [] as any[];
const columnsToRender = {} as any;
results.forEach((record: QRecord) => results.forEach((record: QRecord) =>
{ {
const row: any = {}; const row: any = {};
fields.forEach((field) => fields.forEach((field) =>
{ {
row[field.name] = QValueUtils.getDisplayValue(field, record); const value = QValueUtils.getDisplayValue(field, record)
if(typeof value !== "string")
{
columnsToRender[field.name] = true;
}
row[field.name] = value;
}); });
rows.push(row); rows.push(row);
@ -386,6 +413,39 @@ function EntityList({table}: Props): JSX.Element
} }
} }
if(field.hasAdornment(AdornmentType.SIZE))
{
const sizeAdornment = field.getAdornment(AdornmentType.SIZE)
const width = sizeAdornment.getValue("width")
switch(width)
{
case "small":
{
columnWidth = 100;
break;
}
case "medium":
{
columnWidth = 200;
break;
}
case "large":
{
columnWidth = 400;
break;
}
case "xlarge":
{
columnWidth = 600;
break;
}
default:
{
console.log("Unrecognized size.width adornment value: " + width)
}
}
}
const column = { const column = {
field: field.name, field: field.name,
type: columnType, type: columnType,
@ -394,6 +454,13 @@ function EntityList({table}: Props): JSX.Element
renderCell: null as any, renderCell: null as any,
}; };
if(columnsToRender[field.name])
{
column.renderCell = (cellValues: any) => (
(cellValues.value)
);
}
if (key === tableMetaData.primaryKeyField) if (key === tableMetaData.primaryKeyField)
{ {
columns.splice(0, 0, column); columns.splice(0, 0, column);
@ -705,7 +772,7 @@ function EntityList({table}: Props): JSX.Element
{ {
if(count === 0) if(count === 0)
{ {
return ("No rows"); return (loading ? "Counting records..." : "No rows");
} }
return (`Showing ${from.toLocaleString()} to ${to.toLocaleString()} of ${count !== -1 ? `${count.toLocaleString()} records` : `more than ${to.toLocaleString()} records`}`); return (`Showing ${from.toLocaleString()} to ${to.toLocaleString()} of ${count !== -1 ? `${count.toLocaleString()} records` : `more than ${to.toLocaleString()} records`}`);
} }
@ -720,7 +787,7 @@ function EntityList({table}: Props): JSX.Element
return ( return (
<TablePagination <TablePagination
component="div" component="div"
count={totalRecords} count={totalRecords === null ? 0 : totalRecords}
page={pageNumber} page={pageNumber}
rowsPerPageOptions={[10, 25, 50, 100, 250]} rowsPerPageOptions={[10, 25, 50, 100, 250]}
rowsPerPage={rowsPerPage} rowsPerPage={rowsPerPage}
@ -895,7 +962,7 @@ function EntityList({table}: Props): JSX.Element
rows={rows} rows={rows}
columns={columns} columns={columns}
rowBuffer={10} rowBuffer={10}
rowCount={totalRecords} rowCount={totalRecords === null ? 0 : totalRecords}
onPageSizeChange={handleRowsPerPageChange} onPageSizeChange={handleRowsPerPageChange}
onRowClick={handleRowClick} onRowClick={handleRowClick}
density="standard" density="standard"

View File

@ -19,11 +19,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData"; import {QFieldMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType"; import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord"; import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
import "datejs"; import "datejs";
import {Chip, Icon} from "@mui/material";
import React, {Fragment} from "react"; import React, {Fragment} from "react";
import {Link} from "react-router-dom";
/******************************************************************************* /*******************************************************************************
** Utility class for working with QQQ Values ** Utility class for working with QQQ Values
@ -31,7 +34,38 @@ import React, {Fragment} from "react";
*******************************************************************************/ *******************************************************************************/
class QValueUtils class QValueUtils
{ {
public static getDisplayValue(field: QFieldMetaData, record: QRecord): string public static getDisplayValue(field: QFieldMetaData, record: QRecord): string | JSX.Element
{
const displayValue = record.displayValues ? record.displayValues.get(field.name) : undefined;
const rawValue = record.values ? record.values.get(field.name) : undefined;
if (field.hasAdornment(AdornmentType.LINK))
{
const adornment = field.getAdornment(AdornmentType.LINK);
return (<a target={adornment.getValue("target") ?? "_self"} href={rawValue} onClick={(e) =>
{
e.stopPropagation();
}}>{rawValue}</a>)
}
if (field.hasAdornment(AdornmentType.CHIP))
{
if(!displayValue)
{
return (<span/>);
}
const adornment = field.getAdornment(AdornmentType.CHIP);
const color = adornment.getValue("color." + rawValue) ?? "default"
const iconName = adornment.getValue("icon." + rawValue) ?? null;
const iconElement = iconName ? <Icon>{iconName}</Icon> : null;
return (<Chip label={displayValue} color={color} icon={iconElement} size="small" variant="outlined" sx={{fontWeight: 500}} />);
}
return (QValueUtils._getDisplayValueString(field, record));
}
private static _getDisplayValueString(field: QFieldMetaData, record: QRecord): string
{ {
const displayValue = record.displayValues ? record.displayValues.get(field.name) : undefined; const displayValue = record.displayValues ? record.displayValues.get(field.name) : undefined;
const rawValue = record.values ? record.values.get(field.name) : undefined; const rawValue = record.values ? record.values.get(field.name) : undefined;
@ -68,7 +102,7 @@ class QValueUtils
{ {
try try
{ {
if(n !== null && n !== undefined) if (n !== null && n !== undefined)
{ {
return (n.toLocaleString()); return (n.toLocaleString());
} }
@ -77,14 +111,13 @@ class QValueUtils
return (""); return ("");
} }
} }
catch(e) catch (e)
{ {
return (String(n)); return (String(n));
} }
} }
public static breakTextIntoLines(value: string): JSX.Element public static breakTextIntoLines(value: string): JSX.Element
{ {
return ( return (