diff --git a/package-lock.json b/package-lock.json index e38594d..4d6de1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.45", + "@kingsrook/qqq-frontend-core": "1.0.48", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", @@ -3354,9 +3354,9 @@ } }, "node_modules/@kingsrook/qqq-frontend-core": { - "version": "1.0.45", - "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.45/adee99b089456ae72ee9a311d35f6def5d308486", - "integrity": "sha512-eT/Kp+Y69926DLVTvaRwyeGHPjWYuYOCR2CqwUf4UMrbtZC4tHsrI8uKisZ/ulZeNxm/6N/m0A+ElrXAnt5+mA==", + "version": "1.0.48", + "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.48/27c1a09d17eccc82cf07c76db8c74ee89a92161e", + "integrity": "sha512-781sx4RxIh6x5azNh+Nh5wtP5dPZ8nprTYVPNrBH0XsPB397bxgF3+bjfdtDFpaBkRAWuCiKoVEcz5eJZtT9dg==", "license": "ISC", "dependencies": { "axios": "0.27.2", @@ -6529,9 +6529,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001447", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", - "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==", + "version": "1.0.30001448", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", + "integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==", "funding": [ { "type": "opencollective", @@ -23098,9 +23098,9 @@ } }, "@kingsrook/qqq-frontend-core": { - "version": "1.0.45", - "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.45/adee99b089456ae72ee9a311d35f6def5d308486", - "integrity": "sha512-eT/Kp+Y69926DLVTvaRwyeGHPjWYuYOCR2CqwUf4UMrbtZC4tHsrI8uKisZ/ulZeNxm/6N/m0A+ElrXAnt5+mA==", + "version": "1.0.48", + "resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.48/27c1a09d17eccc82cf07c76db8c74ee89a92161e", + "integrity": "sha512-781sx4RxIh6x5azNh+Nh5wtP5dPZ8nprTYVPNrBH0XsPB397bxgF3+bjfdtDFpaBkRAWuCiKoVEcz5eJZtT9dg==", "requires": { "axios": "0.27.2", "form-data": "4.0.0" @@ -25390,9 +25390,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001447", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", - "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==" + "version": "1.0.30001448", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", + "integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", diff --git a/package.json b/package.json index 6243b51..1f1ae80 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.45", + "@kingsrook/qqq-frontend-core": "1.0.48", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index 54a3e17..b64e2e8 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -47,7 +47,7 @@ import MultiStatisticsCard from "qqq/components/widgets/statistics/MultiStatisti import SimpleStatisticsCard from "qqq/components/widgets/statistics/SimpleStatisticsCard"; import StatisticsCard from "qqq/components/widgets/statistics/StatisticsCard"; import TableCard from "qqq/components/widgets/tables/TableCard"; -import Widget from "qqq/components/widgets/Widget"; +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"; @@ -81,6 +81,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit const [widgetCounter, setWidgetCounter] = useState(0); const [, forceUpdate] = useReducer((x) => x + 1, 0); + const [currentUrlParams, setCurrentUrlParams] = useState(null as string); + const [haveLoadedParams, setHaveLoadedParams] = useState(false); + useEffect(() => { (async () => @@ -92,24 +95,23 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit useEffect(() => { - if (!qInstance) - { - return; - } - - forceUpdate(); 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(widgetMetaDataList[i].name, getQueryParams(null)); + widgetData[i] = await qController.widget(widgetMetaData.name, urlParams); setWidgetCounter(widgetCounter + 1); forceUpdate(); })(); } setWidgetData(widgetData); - }, [qInstance, widgetMetaDataList]); + }, [widgetMetaDataList]); useEffect(() => { @@ -120,16 +122,15 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit { setTimeout(async () => { - widgetData[index] = await qController.widget(widgetMetaDataList[index].name, getQueryParams(data)); + widgetData[index] = await qController.widget(widgetMetaDataList[index].name, getQueryParams(null, data)); setWidgetCounter(widgetCounter + 1); }, 1); }; - function getQueryParams(extraParams: string): string + function getQueryParams(widgetMetaData: QWidgetMetaData, extraParams: string): string { let ampersand = ""; let params = ""; - let foundParam = false; if(entityPrimaryKey) { params += `${ampersand}id=${entityPrimaryKey}`; @@ -148,6 +149,26 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit 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(widgetMetaData && widgetMetaData.storeDropdownSelections && widgetMetaData.dropdowns) + { + for(let i = 0; i< widgetMetaData.dropdowns.length; i++) + { + const dropdownName = widgetMetaData.dropdowns[i].possibleValueSourceName; + const localStorageKey = `${WIDGET_DROPDOWN_SELECTION_LOCAL_STORAGE_KEY_ROOT}.${widgetMetaData.name}.${dropdownName}`; + const json = JSON.parse(localStorage.getItem(localStorageKey)); + if(json) + { + params += `${ampersand}${dropdownName}=${json.id}`; + ampersand = "&"; + } + } } return params; @@ -160,8 +181,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit return ( { - widgetMetaData.type === "parentWidget" && ( + haveLoadedParams && widgetMetaData.type === "parentWidget" && ( { @@ -98,16 +99,18 @@ function ParentWidget({widgetMetaData, widgetIndex, data, reloadWidgetCallback, // @ts-ignore return ( - - - - - + qInstance && data ? ( + + + + + + ) : null ); } diff --git a/src/qqq/components/widgets/Widget.tsx b/src/qqq/components/widgets/Widget.tsx index 022872b..c49ed2f 100644 --- a/src/qqq/components/widgets/Widget.tsx +++ b/src/qqq/components/widgets/Widget.tsx @@ -33,6 +33,7 @@ import DropdownMenu, {DropdownOption} from "qqq/components/widgets/components/Dr export interface WidgetData { + label?: string; dropdownLabelList?: string[]; dropdownNameList?: string[]; dropdownDataList?: { @@ -120,7 +121,7 @@ export class Dropdown extends LabelComponent } -const WIDGET_DROPDOWN_SELECTION_LOCAL_STORAGE_KEY_ROOT = "qqq.widgets.dropdownData"; +export const WIDGET_DROPDOWN_SELECTION_LOCAL_STORAGE_KEY_ROOT = "qqq.widgets.dropdownData"; function Widget(props: React.PropsWithChildren): JSX.Element @@ -254,7 +255,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element useEffect(() => { - if(dropdownData) + if(dropdownData && counter > 0) { let params = ""; for (let i = 0; i < dropdownData.length; i++) @@ -311,10 +312,19 @@ function Widget(props: React.PropsWithChildren): JSX.Element ) } { - props.widgetMetaData?.label && ( + ////////////////////////////////////////////////////////////////////////////////////////// + // first look for a label in the widget data, which would override that in the metadata // + ////////////////////////////////////////////////////////////////////////////////////////// + props.widgetData?.label? ( - {props.widgetMetaData.label} + {props.widgetData.label} + ) : ( + props.widgetMetaData?.label && ( + + {props.widgetMetaData.label} + + ) ) } { diff --git a/src/qqq/components/widgets/charts/DefaultChartData.tsx b/src/qqq/components/widgets/charts/DefaultChartData.tsx index c4e6ee4..00fcd3b 100644 --- a/src/qqq/components/widgets/charts/DefaultChartData.tsx +++ b/src/qqq/components/widgets/charts/DefaultChartData.tsx @@ -28,6 +28,7 @@ export const chartColors = ["info", "warning", "primary", "success", "error", "s export interface DefaultChartData { labels: string[]; + urls?: string[]; datasets: [ { label: string; diff --git a/src/qqq/components/widgets/charts/StackedBarChart.tsx b/src/qqq/components/widgets/charts/StackedBarChart.tsx index bb771a1..18bcaf0 100644 --- a/src/qqq/components/widgets/charts/StackedBarChart.tsx +++ b/src/qqq/components/widgets/charts/StackedBarChart.tsx @@ -22,8 +22,9 @@ import Box from "@mui/material/Box"; import {BarElement, CategoryScale, Chart as ChartJS, Legend, LinearScale, Title, Tooltip,} from "chart.js"; -import React from "react"; +import React, {useEffect} from "react"; import {Bar} from "react-chartjs-2"; +import {useNavigate} from "react-router-dom"; import colors from "qqq/assets/theme/base/colors"; import {chartColors, DefaultChartData} from "qqq/components/widgets/charts/DefaultChartData"; @@ -56,29 +57,36 @@ interface Props const {gradients} = colors; function StackedBarChart({data}: Props): JSX.Element { + const navigate = useNavigate(); + const handleClick = (e: Array<{}>) => { - /* - if(e && e.length > 0 && data?.dataset?.urls && data?.dataset?.urls.length) + if(e && e.length > 0 && data?.urls && data?.urls.length) { // @ts-ignore - navigate(chartData.dataset.urls[e[0]["index"]]); - + navigate(data.urls[e[0]["index"]]); } - - */ console.log(e); } - data?.datasets.forEach((dataset: any, index: number) => + useEffect(() => { - if(! dataset.backgroundColor) + if(data) { - dataset.backgroundColor = gradients[chartColors[index]].state; + data?.datasets.forEach((dataset: any, index: number) => + { + if (!dataset.backgroundColor) + { + dataset.backgroundColor = gradients[chartColors[index]].state; + } + }); } - }); + }, [data]); - return ; + + return data ? ( + + ) : null; } export default StackedBarChart; diff --git a/src/qqq/components/widgets/charts/piechart/PieChart.tsx b/src/qqq/components/widgets/charts/piechart/PieChart.tsx index d0930c1..9d93c65 100644 --- a/src/qqq/components/widgets/charts/piechart/PieChart.tsx +++ b/src/qqq/components/widgets/charts/piechart/PieChart.tsx @@ -27,7 +27,6 @@ import parse from "html-react-parser"; import React, {useMemo} from "react"; import {Pie} from "react-chartjs-2"; import {useNavigate} from "react-router-dom"; -import MDBadgeDot from "qqq/components/legacy/MDBadgeDot"; import MDTypography from "qqq/components/legacy/MDTypography"; import {chartColors} from "qqq/components/widgets/charts/DefaultChartData"; import configs from "qqq/components/widgets/charts/piechart/PieChartConfigs"; @@ -56,6 +55,7 @@ interface Props [key: string]: any; } + function PieChart({description, chartData}: Props): JSX.Element { const navigate = useNavigate(); @@ -80,9 +80,8 @@ function PieChart({description, chartData}: Props): JSX.Element - - - + + {useMemo( () => ( @@ -91,19 +90,6 @@ function PieChart({description, chartData}: Props): JSX.Element )} - - - { - data && data.labels ? ( - (data.labels.map((label: string, index: number) => ( - - - - ) - ))) : null - } - - { diff --git a/src/qqq/components/widgets/charts/piechart/PieChartConfigs.ts b/src/qqq/components/widgets/charts/piechart/PieChartConfigs.ts index 5902920..39f825e 100644 --- a/src/qqq/components/widgets/charts/piechart/PieChartConfigs.ts +++ b/src/qqq/components/widgets/charts/piechart/PieChartConfigs.ts @@ -58,11 +58,12 @@ function configs(labels: any, datasets: any) ], }, options: { - responsive: true, maintainAspectRatio: true, + responsive: true, + aspectRatio: 2, plugins: { legend: { - display: false, + position: "bottom", }, }, scales: { diff --git a/src/qqq/components/widgets/components/DropdownMenu.tsx b/src/qqq/components/widgets/components/DropdownMenu.tsx index a49efc5..7361b48 100644 --- a/src/qqq/components/widgets/components/DropdownMenu.tsx +++ b/src/qqq/components/widgets/components/DropdownMenu.tsx @@ -23,7 +23,7 @@ import {Theme} from "@mui/material"; import Autocomplete from "@mui/material/Autocomplete"; import TextField from "@mui/material/TextField"; import {SxProps} from "@mui/system"; -import React, {useEffect} from "react"; +import React from "react"; export interface DropdownOption @@ -47,15 +47,6 @@ interface Props function DropdownMenu({localStorageKey, defaultValue, label, dropdownOptions, onChangeCallback, sx}: Props): JSX.Element { - useEffect(() => - { - if(defaultValue) - { - console.log("CALLING CALLBACK...") - onChangeCallback(label, JSON.parse(localStorage.getItem(localStorageKey))); - } - }, []); - const handleOnChange = (event: any, value: any, reason: string) => { onChangeCallback(label, value);