mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-21 22:58:43 +00:00
246 lines
9.1 KiB
TypeScript
246 lines
9.1 KiB
TypeScript
/*
|
|
* QQQ - Low-code Application Framework for Engineers.
|
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
|
* contact@kingsrook.com
|
|
* https://github.com/Kingsrook/
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
|
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 {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
|
import {ListItem} from "@mui/material";
|
|
import Box from "@mui/material/Box";
|
|
import Icon from "@mui/material/Icon";
|
|
import IconButton from "@mui/material/IconButton";
|
|
import ListItemText from "@mui/material/ListItemText";
|
|
import Tooltip from "@mui/material/Tooltip";
|
|
import React from "react";
|
|
import {Link} from "react-router-dom";
|
|
import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
|
|
|
/*******************************************************************************
|
|
** Entity that corresponds to qqq backend's ProcessSummaryLine - with methods
|
|
** to help display properly in a process review screen.
|
|
*******************************************************************************/
|
|
export class ProcessSummaryLine
|
|
{
|
|
status: "OK" | "INFO" | "WARNING" | "ERROR";
|
|
|
|
count: number;
|
|
message: string;
|
|
primaryKeys: any[];
|
|
|
|
tableName: string;
|
|
recordId: any;
|
|
filter: any;
|
|
linkPreText: string;
|
|
linkText: string;
|
|
linkPostText: string;
|
|
|
|
bulletsOfText: any[];
|
|
|
|
constructor(processSummaryLine: any)
|
|
{
|
|
this.status = processSummaryLine.status;
|
|
this.count = processSummaryLine.count;
|
|
this.message = processSummaryLine.message;
|
|
this.primaryKeys = processSummaryLine.primaryKeys;
|
|
|
|
this.tableName = processSummaryLine.tableName;
|
|
this.recordId = processSummaryLine.recordId;
|
|
this.linkPreText = processSummaryLine.linkPreText;
|
|
this.linkText = processSummaryLine.linkText;
|
|
this.linkPostText = processSummaryLine.linkPostText;
|
|
|
|
this.bulletsOfText = processSummaryLine.bulletsOfText;
|
|
|
|
this.filter = processSummaryLine.filter;
|
|
}
|
|
|
|
getProcessSummaryListItem(i: number, table: QTableMetaData, qInstance: QInstance, isResultScreen: boolean = false): JSX.Element
|
|
{
|
|
if (this.tableName != undefined && (this.recordId != undefined || this.filter != undefined))
|
|
{
|
|
return (this.getProcessSummaryListItemForTableRecordOrFilterLink(i, table, qInstance, isResultScreen));
|
|
}
|
|
|
|
return (this.getProcessSummaryListItemForCountAndMessage(i, table, qInstance, isResultScreen));
|
|
}
|
|
|
|
private getProcessSummaryListItemForTableRecordOrFilterLink(i: number, table: QTableMetaData, qInstance: QInstance, isResultScreen: boolean = false): JSX.Element
|
|
{
|
|
const tablePath = qInstance.getTablePathByName(this.tableName);
|
|
|
|
return (
|
|
<ListItem key={i} sx={{pl: 4, my: 2}}>
|
|
<Box display="flex" alignItems="top">
|
|
<Icon fontSize="medium" sx={{mr: 1}} color={this.getColor()}>{this.getIcon(isResultScreen)}</Icon>
|
|
<ListItemText primaryTypographyProps={{fontSize: 16}}>
|
|
{this.linkPreText ?? ""}
|
|
{
|
|
this.recordId
|
|
? <Link to={`${tablePath}/${this.recordId}`}>{this.linkText}</Link>
|
|
: <Link to={`${tablePath}?filter=${JSON.stringify(this.filter)}`}>{this.linkText}</Link>
|
|
}
|
|
{this.linkPostText ?? ""}
|
|
</ListItemText>
|
|
</Box>
|
|
</ListItem>
|
|
);
|
|
}
|
|
|
|
private getProcessSummaryListItemForCountAndMessage(i: number, table: QTableMetaData, qInstance: QInstance, isResultScreen: boolean = false): JSX.Element
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// split up the message into words - then we'll display the last word by itself with a non-breaking space, no-wrap-glued to the button. //
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const messageWords = this.message ? this.message.split(" ") : [];
|
|
const lastWord = messageWords.length > 1 ? messageWords[messageWords.length - 1] : "";
|
|
if (messageWords.length > 1)
|
|
{
|
|
messageWords.splice(messageWords.length - 1, 1);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
// try to get a link to the records - but note, it may come back null for various reasons - //
|
|
// if it's null, then don't output a link tag. //
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
const linkToRecords = this.getLinkToRecords(table, qInstance);
|
|
let linkTag = null;
|
|
if(linkToRecords)
|
|
{
|
|
linkTag = <Link target="_blank" to={linkToRecords}>
|
|
<Tooltip title="See these records in a new tab" sx={{py: 0}}>
|
|
<IconButton sx={{py: 0}}><Icon fontSize="small">open_in_new</Icon></IconButton>
|
|
</Tooltip>
|
|
</Link>
|
|
}
|
|
|
|
return (
|
|
<ListItem key={i} sx={{pl: 4, my: 2}}>
|
|
<Box display="flex" alignItems="top">
|
|
<Icon fontSize="medium" sx={{mr: 1}} color={this.getColor()}>{this.getIcon(isResultScreen)}</Icon>
|
|
<ListItemText primaryTypographyProps={{fontSize: 16}}>
|
|
{/* work hard to prevent the icon from falling down to the next line by itself... */}
|
|
{`${ValueUtils.getFormattedNumber(this.count)} ${messageWords.join(" ")} `}
|
|
{
|
|
(linkTag) ? (
|
|
<span style={{whiteSpace: "nowrap"}}>
|
|
{lastWord} {linkTag}
|
|
</span>
|
|
) : <span>{lastWord}</span>
|
|
}
|
|
{
|
|
this.bulletsOfText && <ul style={{marginLeft: "2rem"}}>
|
|
{
|
|
this.bulletsOfText.map((bullet, index) => <li key={index}>{bullet}</li>)
|
|
}
|
|
</ul>
|
|
}
|
|
</ListItemText>
|
|
</Box>
|
|
</ListItem>
|
|
);
|
|
}
|
|
|
|
private getColor(): "success" | "info" | "warning" | "error" | "secondary"
|
|
{
|
|
if (this.status === "OK")
|
|
{
|
|
return "success";
|
|
}
|
|
else if (this.status === "INFO")
|
|
{
|
|
return "info";
|
|
}
|
|
else if (this.status === "WARNING")
|
|
{
|
|
return "warning";
|
|
}
|
|
else if (this.status === "ERROR")
|
|
{
|
|
return "error";
|
|
}
|
|
else
|
|
{
|
|
return "secondary";
|
|
}
|
|
}
|
|
|
|
private getIcon(isResultScreen: boolean): string
|
|
{
|
|
if (this.status === "OK")
|
|
{
|
|
return isResultScreen ? "check" : "arrow_forward";
|
|
}
|
|
else if (this.status === "INFO")
|
|
{
|
|
return "info";
|
|
}
|
|
else if (this.status === "WARNING")
|
|
{
|
|
return "warning_amber";
|
|
}
|
|
else if (this.status === "ERROR")
|
|
{
|
|
return "report";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private getLinkToRecords(table: QTableMetaData, qInstance: QInstance): string | null
|
|
{
|
|
if(!table)
|
|
{
|
|
console.log("No table, so not returning a link to records");
|
|
return (null);
|
|
}
|
|
|
|
if(!table.primaryKeyField)
|
|
{
|
|
console.log("No table.primaryKeyField, so not returning a link to records");
|
|
return (null);
|
|
}
|
|
|
|
const tablePath = qInstance.getTablePath(table);
|
|
if(!tablePath)
|
|
{
|
|
console.log("No tablePath, so not returning a link to records");
|
|
return (null);
|
|
}
|
|
|
|
if(!this.primaryKeys)
|
|
{
|
|
console.log("No primaryKeys, so not returning a link to records");
|
|
return (null);
|
|
}
|
|
|
|
const filter = new QQueryFilter([new QFilterCriteria(table.primaryKeyField, QCriteriaOperator.IN, this.primaryKeys)]);
|
|
const path = `${tablePath}?filter=${JSON.stringify(filter)}`;
|
|
|
|
if(path.length > 2048)
|
|
{
|
|
console.log(`Path is too long [${path.length}], so not returning a link to records.`);
|
|
return (null);
|
|
}
|
|
|
|
return (path);
|
|
}
|
|
}
|