/* 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 . */ import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData"; import {Skeleton} from "@mui/material"; import Box from "@mui/material/Box"; import Grid from "@mui/material/Grid"; import parse from "html-react-parser"; import React, {useContext, useEffect, useReducer, useState} from "react"; import {useLocation} from "react-router-dom"; import QContext from "QContext"; import MDTypography from "qqq/components/legacy/MDTypography"; import BarChart from "qqq/components/widgets/charts/barchart/BarChart"; import HorizontalBarChart from "qqq/components/widgets/charts/barchart/HorizontalBarChart"; import DefaultLineChart from "qqq/components/widgets/charts/linechart/DefaultLineChart"; import SmallLineChart from "qqq/components/widgets/charts/linechart/SmallLineChart"; import PieChart from "qqq/components/widgets/charts/piechart/PieChart"; import StackedBarChart from "qqq/components/widgets/charts/StackedBarChart"; import DataBagViewer from "qqq/components/widgets/misc/DataBagViewer"; import DividerWidget from "qqq/components/widgets/misc/Divider"; import FieldValueListWidget from "qqq/components/widgets/misc/FieldValueListWidget"; import QuickSightChart from "qqq/components/widgets/misc/QuickSightChart"; import RecordGridWidget from "qqq/components/widgets/misc/RecordGridWidget"; import ScriptViewer from "qqq/components/widgets/misc/ScriptViewer"; import StepperCard from "qqq/components/widgets/misc/StepperCard"; import USMapWidget from "qqq/components/widgets/misc/USMapWidget"; import ParentWidget from "qqq/components/widgets/ParentWidget"; import MultiStatisticsCard from "qqq/components/widgets/statistics/MultiStatisticsCard"; import StatisticsCard from "qqq/components/widgets/statistics/StatisticsCard"; import TableCard from "qqq/components/widgets/tables/TableCard"; import Widget, {WIDGET_DROPDOWN_SELECTION_LOCAL_STORAGE_KEY_ROOT} from "qqq/components/widgets/Widget"; import ProcessRun from "qqq/pages/processes/ProcessRun"; import Client from "qqq/utils/qqq/Client"; const qController = Client.getInstance(); interface Props { widgetMetaDataList: QWidgetMetaData[]; tableName?: string; entityPrimaryKey?: string; omitWrappingGridContainer: boolean; areChildren?: boolean childUrlParams?: string parentWidgetMetaData?: QWidgetMetaData } DashboardWidgets.defaultProps = { widgetMetaDataList: null, tableName: null, entityPrimaryKey: null, omitWrappingGridContainer: false, areChildren: false, childUrlParams: "", parentWidgetMetaData: null }; function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omitWrappingGridContainer, areChildren, childUrlParams, parentWidgetMetaData}: Props): JSX.Element { const location = useLocation(); const [widgetData, setWidgetData] = useState([] as any[]); const [widgetCounter, setWidgetCounter] = useState(0); const [, forceUpdate] = useReducer((x) => x + 1, 0); const [currentUrlParams, setCurrentUrlParams] = useState(null as string); const [haveLoadedParams, setHaveLoadedParams] = useState(false); const {accentColor} = useContext(QContext); useEffect(() => { setWidgetData([]); for (let i = 0; i < widgetMetaDataList.length; i++) { const widgetMetaData = widgetMetaDataList[i]; const urlParams = getQueryParams(widgetMetaData, null); setCurrentUrlParams(urlParams); setHaveLoadedParams(true); widgetData[i] = {}; (async () => { widgetData[i] = await qController.widget(widgetMetaData.name, urlParams); setWidgetData(widgetData); setWidgetCounter(widgetCounter + 1); forceUpdate(); })(); } }, [widgetMetaDataList]); const reloadWidget = async (index: number, data: string) => { (async() => { widgetData[index] = await qController.widget(widgetMetaDataList[index].name, getQueryParams(null, data)); setWidgetData(widgetData); forceUpdate(); })(); }; function getQueryParams(widgetMetaData: QWidgetMetaData, extraParams: string): string { let ampersand = ""; let params = ""; if(entityPrimaryKey) { params += `${ampersand}id=${entityPrimaryKey}`; ampersand = "&"; } if(tableName) { params += `${ampersand}tableName=${tableName}`; ampersand = "&"; } if(extraParams) { params += `${ampersand}${extraParams}`; ampersand = "&"; } if(childUrlParams) { params += `${ampersand}${childUrlParams}`; ampersand = "&"; } ///////////////////////////////////////////////////////////////////////////// // see if local storage is used for any widget dropdowns, if so, look them // // up and append to the query string // ///////////////////////////////////////////////////////////////////////////// if(params === "") { let thisWidgetHasDropdowns = widgetMetaData && widgetMetaData.storeDropdownSelections && widgetMetaData.dropdowns; let parentWidgetHasDropdowns = parentWidgetMetaData && parentWidgetMetaData.storeDropdownSelections && parentWidgetMetaData.dropdowns; if (thisWidgetHasDropdowns || parentWidgetHasDropdowns) { const metaDataToUse = (thisWidgetHasDropdowns) ? widgetMetaData : parentWidgetMetaData; for (let i = 0; i < metaDataToUse.dropdowns.length; i++) { const dropdownName = metaDataToUse.dropdowns[i].possibleValueSourceName; const localStorageKey = `${WIDGET_DROPDOWN_SELECTION_LOCAL_STORAGE_KEY_ROOT}.${metaDataToUse.name}.${dropdownName}`; const json = JSON.parse(localStorage.getItem(localStorageKey)); if (json) { params += `${ampersand}${dropdownName}=${json.id}`; ampersand = "&"; } } } } return params; } const widgetCount = widgetMetaDataList ? widgetMetaDataList.length : 0; const renderWidget = (widgetMetaData: QWidgetMetaData, i: number): JSX.Element => { return ( { haveLoadedParams && widgetMetaData.type === "parentWidget" && ( ) } { widgetMetaData.type === "usaMap" && ( ) } { widgetMetaData.type === "table" && ( reloadWidget(i, data)} isChild={areChildren} > ) } { widgetMetaData.type === "stackedBarChart" && ( reloadWidget(i, data)} isChild={areChildren} > ) } { widgetMetaData.type === "process" && widgetData[i]?.processMetaData && ( reloadWidget(i, data)}>
) } { widgetMetaData.type === "stepper" && ( ) } { widgetMetaData.type === "html" && ( { widgetData && widgetData[i] && widgetData[i].html ? ( parse(widgetData[i].html) ) : } ) } { widgetMetaData.type === "smallLineChart" && ( ) } { widgetMetaData.type === "statistics" && ( reloadWidget(i, data)} > ) } { widgetMetaData.type === "multiStatistics" && ( ) } { widgetMetaData.type === "quickSightChart" && ( ) } { widgetMetaData.type === "barChart" && ( ) } { widgetMetaData.type === "pieChart" && (
) } { widgetMetaData.type === "divider" && ( ) } { widgetMetaData.type === "horizontalBarChart" && ( ) } { widgetMetaData.type === "lineChart" && ( ) } { widgetMetaData.type === "childRecordList" && ( widgetData && widgetData[i] && ) } { widgetMetaData.type === "fieldValueList" && ( widgetData && widgetData[i] && reloadWidget(i, data)} /> ) } { widgetMetaData.type === "dataBagViewer" && ( widgetData && widgetData[i] && widgetData[i].queryParams && ) } { widgetMetaData.type === "scriptViewer" && ( widgetData && widgetData[i] && widgetData[i].queryParams && ) }
); } const body: JSX.Element = ( <> { widgetMetaDataList.map((widgetMetaData, i) => ( omitWrappingGridContainer ? widgetMetaData && renderWidget(widgetMetaData, i) : widgetMetaData && {renderWidget(widgetMetaData, i)} )) } ); return ( widgetCount > 0 ? ( omitWrappingGridContainer ? body : ( {body} ) ) : null ); } export default DashboardWidgets;