mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +00:00
Some final adjustments for widget reload & export
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
"@auth0/auth0-react": "1.10.2",
|
||||
"@emotion/react": "11.7.1",
|
||||
"@emotion/styled": "11.6.0",
|
||||
"@kingsrook/qqq-frontend-core": "1.0.64",
|
||||
"@kingsrook/qqq-frontend-core": "1.0.65",
|
||||
"@mui/icons-material": "5.4.1",
|
||||
"@mui/material": "5.11.1",
|
||||
"@mui/styles": "5.11.1",
|
||||
|
@ -26,10 +26,12 @@ import Button from "@mui/material/Button";
|
||||
import Card from "@mui/material/Card";
|
||||
import Icon from "@mui/material/Icon";
|
||||
import LinearProgress from "@mui/material/LinearProgress";
|
||||
import Tooltip from "@mui/material/Tooltip/Tooltip";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import parse from "html-react-parser";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {Link, useNavigate, NavigateFunction} from "react-router-dom";
|
||||
import {bool} from "yup";
|
||||
import colors from "qqq/components/legacy/colors";
|
||||
import DropdownMenu, {DropdownOption} from "qqq/components/widgets/components/DropdownMenu";
|
||||
|
||||
@ -166,8 +168,8 @@ export class ExportDataButton extends LabelComponent
|
||||
render = (args: LabelComponentRenderArgs): JSX.Element =>
|
||||
{
|
||||
return (
|
||||
<Typography variant="body2" py={2} px={1} display="inline" position="relative" top="-0.25rem">
|
||||
<Button sx={{px: 1}} onClick={() => this.callbackToExport()} disabled={this.isDisabled}><Icon>save_alt</Icon> {this.label}</Button>
|
||||
<Typography variant="body2" py={2} px={0} display="inline" position="relative" top="-0.375rem">
|
||||
<Tooltip title="Export"><Button sx={{px: 1, py: 0, minWidth: "initial"}} onClick={() => this.callbackToExport()} disabled={this.isDisabled}><Icon>save_alt</Icon></Button></Tooltip>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@ -231,8 +233,8 @@ export class ReloadControl extends LabelComponent
|
||||
render = (args: LabelComponentRenderArgs): JSX.Element =>
|
||||
{
|
||||
return (
|
||||
<Typography variant="body2" py={2} px={1} display="inline" position="relative" top="-0.25rem">
|
||||
<Button sx={{px: 1}} onClick={() => this.callback()}><Icon>refresh</Icon> Refresh</Button>
|
||||
<Typography variant="body2" py={2} px={0} display="inline" position="relative" top="-0.375rem">
|
||||
<Tooltip title="Refresh"><Button sx={{px: 1, py:0, minWidth: "initial"}} onClick={() => this.callback()}><Icon>refresh</Icon></Button></Tooltip>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@ -283,16 +285,15 @@ function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
||||
}, [props.widgetData]);
|
||||
|
||||
const effectiveLabelAdditionalComponentsLeft: LabelComponent[] = [];
|
||||
if(props.reloadWidgetCallback && props.widgetData && props.showReloadControl && props.widgetMetaData.showReloadButton)
|
||||
{
|
||||
effectiveLabelAdditionalComponentsLeft.push(new ReloadControl(doReload))
|
||||
}
|
||||
if(props.labelAdditionalComponentsLeft)
|
||||
{
|
||||
props.labelAdditionalComponentsLeft.map((component) => effectiveLabelAdditionalComponentsLeft.push(component));
|
||||
}
|
||||
|
||||
if(props.reloadWidgetCallback && props.widgetData && props.showReloadControl)
|
||||
{
|
||||
effectiveLabelAdditionalComponentsLeft.push(new ReloadControl(doReload))
|
||||
}
|
||||
|
||||
function handleDataChange(dropdownLabel: string, changedData: any)
|
||||
{
|
||||
if(dropdownData)
|
||||
@ -380,8 +381,29 @@ function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
||||
}
|
||||
|
||||
const hasPermission = props.widgetData?.hasPermission === undefined || props.widgetData?.hasPermission === true;
|
||||
|
||||
const isSet = (v: any): boolean =>
|
||||
{
|
||||
return(v !== null && v !== undefined);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// to avoid taking up the space of the Box with the label and icon and label-components (since it has a height), only output that box if we need any of the components //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
let needLabelBox = false;
|
||||
if(hasPermission)
|
||||
{
|
||||
needLabelBox ||= (effectiveLabelAdditionalComponentsLeft && effectiveLabelAdditionalComponentsLeft.length > 0);
|
||||
needLabelBox ||= (effectiveLabelAdditionalComponentsRight && effectiveLabelAdditionalComponentsRight.length > 0);
|
||||
needLabelBox ||= isSet(props.widgetMetaData?.icon);
|
||||
needLabelBox ||= isSet(props.widgetData?.label);
|
||||
needLabelBox ||= isSet(props.widgetMetaData?.label);
|
||||
}
|
||||
|
||||
const widgetContent =
|
||||
<Box sx={{width: "100%", height: "100%", minHeight: props.widgetMetaData?.minHeight ? props.widgetMetaData?.minHeight : "initial"}}>
|
||||
{
|
||||
needLabelBox &&
|
||||
<Box pr={2} display="flex" justifyContent="space-between" alignItems="flex-start" sx={{width: "100%"}} height={"3.5rem"}>
|
||||
<Box pt={2} pb={1}>
|
||||
{
|
||||
@ -468,6 +490,7 @@ function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
||||
}
|
||||
</Box>
|
||||
</Box>
|
||||
}
|
||||
{
|
||||
props.widgetMetaData?.isCard && (reloading ? <LinearProgress color="info" sx={{overflow: "hidden", borderRadius: "0"}} /> : <Box height="0.375rem"/>)
|
||||
}
|
||||
|
@ -56,9 +56,22 @@ function download(filename: string, text: string)
|
||||
|
||||
function TableWidget(props: Props): JSX.Element
|
||||
{
|
||||
const [isExportDisabled, setIsExportDisabled] = useState(true);
|
||||
|
||||
const rows = props.widgetData?.rows;
|
||||
const columns = props.widgetData?.columns;
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
let isExportDisabled = true;
|
||||
if (props.widgetData && columns && rows && rows.length > 0)
|
||||
{
|
||||
isExportDisabled = false;
|
||||
}
|
||||
setIsExportDisabled(isExportDisabled);
|
||||
|
||||
}, [props.widgetMetaData, props.widgetData]);
|
||||
|
||||
const exportCallback = () =>
|
||||
{
|
||||
if (props.widgetData && rows && columns)
|
||||
@ -101,40 +114,15 @@ function TableWidget(props: Props): JSX.Element
|
||||
|
||||
console.log(csv);
|
||||
|
||||
const fileName = props.widgetData.label + "-" + ValueUtils.formatDateTimeISO8601(new Date()) + ".csv";
|
||||
const fileName = (props.widgetData.label ?? props.widgetMetaData.label) + " " + ValueUtils.formatDateTimeForFileName(new Date()) + ".csv";
|
||||
download(fileName, csv);
|
||||
}
|
||||
else
|
||||
{
|
||||
alert("Error exporting widget data.");
|
||||
alert("There is no data available to export.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const [exportDataButton, setExportDataButton] = useState(new ExportDataButton(() => exportCallback(), true));
|
||||
const [isExportDisabled, setIsExportDisabled] = useState(true);
|
||||
const [componentLeft, setComponentLeft] = useState([exportDataButton])
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if (props.widgetData && columns && rows && rows.length > 0)
|
||||
{
|
||||
console.log("Setting export disabled false")
|
||||
setIsExportDisabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("Setting export disabled true")
|
||||
setIsExportDisabled(true);
|
||||
}
|
||||
}, [props.widgetData])
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
console.log("Setting new export button with disabled=" + isExportDisabled)
|
||||
setComponentLeft([new ExportDataButton(() => exportCallback(), isExportDisabled)]);
|
||||
}, [isExportDisabled])
|
||||
|
||||
return (
|
||||
<Widget
|
||||
widgetMetaData={props.widgetMetaData}
|
||||
@ -142,7 +130,7 @@ function TableWidget(props: Props): JSX.Element
|
||||
reloadWidgetCallback={(data) => props.reloadWidgetCallback(data)}
|
||||
footerHTML={props.widgetData?.footerHTML}
|
||||
isChild={props.isChild}
|
||||
labelAdditionalComponentsLeft={componentLeft}
|
||||
labelAdditionalComponentsLeft={props.widgetMetaData?.showExportButton ? [new ExportDataButton(() => exportCallback(), isExportDisabled)] : []}
|
||||
>
|
||||
<TableCard
|
||||
noRowsFoundHTML={props.widgetData?.noRowsFoundHTML}
|
||||
|
@ -273,6 +273,14 @@ class ValueUtils
|
||||
return (`${date.toString("yyyy-MM-ddTHH:mm:ssZ")}`);
|
||||
}
|
||||
|
||||
public static formatDateTimeForFileName(date: Date)
|
||||
{
|
||||
const zp = (value: number): string => (value < 10 ? `0${value}` : `${value}`);
|
||||
const d = new Date();
|
||||
const dateString = `${d.getFullYear()}-${zp(d.getMonth() + 1)}-${zp(d.getDate())} ${zp(d.getHours())}${zp(d.getMinutes())}`;
|
||||
return (date);
|
||||
}
|
||||
|
||||
public static getFullWeekday(date: Date)
|
||||
{
|
||||
if (!(date instanceof Date))
|
||||
|
Reference in New Issue
Block a user