mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +00:00
SPRINT-19: upped core frontend version, updates to pie charts and stacked charts
This commit is contained in:
26
package-lock.json
generated
26
package-lock.json
generated
@ -11,7 +11,7 @@
|
|||||||
"@auth0/auth0-react": "1.10.2",
|
"@auth0/auth0-react": "1.10.2",
|
||||||
"@emotion/react": "11.7.1",
|
"@emotion/react": "11.7.1",
|
||||||
"@emotion/styled": "11.6.0",
|
"@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/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.11.1",
|
"@mui/material": "5.11.1",
|
||||||
"@mui/styles": "5.11.1",
|
"@mui/styles": "5.11.1",
|
||||||
@ -3354,9 +3354,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@kingsrook/qqq-frontend-core": {
|
"node_modules/@kingsrook/qqq-frontend-core": {
|
||||||
"version": "1.0.45",
|
"version": "1.0.48",
|
||||||
"resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.45/adee99b089456ae72ee9a311d35f6def5d308486",
|
"resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.48/27c1a09d17eccc82cf07c76db8c74ee89a92161e",
|
||||||
"integrity": "sha512-eT/Kp+Y69926DLVTvaRwyeGHPjWYuYOCR2CqwUf4UMrbtZC4tHsrI8uKisZ/ulZeNxm/6N/m0A+ElrXAnt5+mA==",
|
"integrity": "sha512-781sx4RxIh6x5azNh+Nh5wtP5dPZ8nprTYVPNrBH0XsPB397bxgF3+bjfdtDFpaBkRAWuCiKoVEcz5eJZtT9dg==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
@ -6529,9 +6529,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001447",
|
"version": "1.0.30001448",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz",
|
||||||
"integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==",
|
"integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -23098,9 +23098,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@kingsrook/qqq-frontend-core": {
|
"@kingsrook/qqq-frontend-core": {
|
||||||
"version": "1.0.45",
|
"version": "1.0.48",
|
||||||
"resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.45/adee99b089456ae72ee9a311d35f6def5d308486",
|
"resolved": "https://npm.pkg.github.com/download/@Kingsrook/qqq-frontend-core/1.0.48/27c1a09d17eccc82cf07c76db8c74ee89a92161e",
|
||||||
"integrity": "sha512-eT/Kp+Y69926DLVTvaRwyeGHPjWYuYOCR2CqwUf4UMrbtZC4tHsrI8uKisZ/ulZeNxm/6N/m0A+ElrXAnt5+mA==",
|
"integrity": "sha512-781sx4RxIh6x5azNh+Nh5wtP5dPZ8nprTYVPNrBH0XsPB397bxgF3+bjfdtDFpaBkRAWuCiKoVEcz5eJZtT9dg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"form-data": "4.0.0"
|
"form-data": "4.0.0"
|
||||||
@ -25390,9 +25390,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001447",
|
"version": "1.0.30001448",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz",
|
||||||
"integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw=="
|
"integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA=="
|
||||||
},
|
},
|
||||||
"case-sensitive-paths-webpack-plugin": {
|
"case-sensitive-paths-webpack-plugin": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"@auth0/auth0-react": "1.10.2",
|
"@auth0/auth0-react": "1.10.2",
|
||||||
"@emotion/react": "11.7.1",
|
"@emotion/react": "11.7.1",
|
||||||
"@emotion/styled": "11.6.0",
|
"@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/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.11.1",
|
"@mui/material": "5.11.1",
|
||||||
"@mui/styles": "5.11.1",
|
"@mui/styles": "5.11.1",
|
||||||
|
@ -47,7 +47,7 @@ import MultiStatisticsCard from "qqq/components/widgets/statistics/MultiStatisti
|
|||||||
import SimpleStatisticsCard from "qqq/components/widgets/statistics/SimpleStatisticsCard";
|
import SimpleStatisticsCard from "qqq/components/widgets/statistics/SimpleStatisticsCard";
|
||||||
import StatisticsCard from "qqq/components/widgets/statistics/StatisticsCard";
|
import StatisticsCard from "qqq/components/widgets/statistics/StatisticsCard";
|
||||||
import TableCard from "qqq/components/widgets/tables/TableCard";
|
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 ProcessRun from "qqq/pages/processes/ProcessRun";
|
||||||
import Client from "qqq/utils/qqq/Client";
|
import Client from "qqq/utils/qqq/Client";
|
||||||
|
|
||||||
@ -81,6 +81,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
|
|||||||
const [widgetCounter, setWidgetCounter] = useState(0);
|
const [widgetCounter, setWidgetCounter] = useState(0);
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
|
const [currentUrlParams, setCurrentUrlParams] = useState(null as string);
|
||||||
|
const [haveLoadedParams, setHaveLoadedParams] = useState(false);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
(async () =>
|
(async () =>
|
||||||
@ -92,24 +95,23 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
|
|||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if (!qInstance)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceUpdate();
|
|
||||||
for (let i = 0; i < widgetMetaDataList.length; i++)
|
for (let i = 0; i < widgetMetaDataList.length; i++)
|
||||||
{
|
{
|
||||||
|
const widgetMetaData = widgetMetaDataList[i];
|
||||||
|
const urlParams = getQueryParams(widgetMetaData, null);
|
||||||
|
setCurrentUrlParams(urlParams);
|
||||||
|
setHaveLoadedParams(true);
|
||||||
|
|
||||||
widgetData[i] = {};
|
widgetData[i] = {};
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
widgetData[i] = await qController.widget(widgetMetaDataList[i].name, getQueryParams(null));
|
widgetData[i] = await qController.widget(widgetMetaData.name, urlParams);
|
||||||
setWidgetCounter(widgetCounter + 1);
|
setWidgetCounter(widgetCounter + 1);
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
setWidgetData(widgetData);
|
setWidgetData(widgetData);
|
||||||
}, [qInstance, widgetMetaDataList]);
|
}, [widgetMetaDataList]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -120,16 +122,15 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
|
|||||||
{
|
{
|
||||||
setTimeout(async () =>
|
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);
|
setWidgetCounter(widgetCounter + 1);
|
||||||
}, 1);
|
}, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getQueryParams(extraParams: string): string
|
function getQueryParams(widgetMetaData: QWidgetMetaData, extraParams: string): string
|
||||||
{
|
{
|
||||||
let ampersand = "";
|
let ampersand = "";
|
||||||
let params = "";
|
let params = "";
|
||||||
let foundParam = false;
|
|
||||||
if(entityPrimaryKey)
|
if(entityPrimaryKey)
|
||||||
{
|
{
|
||||||
params += `${ampersand}id=${entityPrimaryKey}`;
|
params += `${ampersand}id=${entityPrimaryKey}`;
|
||||||
@ -148,6 +149,26 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
|
|||||||
if(childUrlParams)
|
if(childUrlParams)
|
||||||
{
|
{
|
||||||
params += `${ampersand}${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;
|
return params;
|
||||||
@ -160,8 +181,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
|
|||||||
return (
|
return (
|
||||||
<Box key={`${widgetMetaData.name}-${i}`} sx={{alignItems: "stretch", flexGrow: 1, display: "flex", marginTop: "0px", paddingTop: "0px", width: "100%", height: "100%"}}>
|
<Box key={`${widgetMetaData.name}-${i}`} sx={{alignItems: "stretch", flexGrow: 1, display: "flex", marginTop: "0px", paddingTop: "0px", width: "100%", height: "100%"}}>
|
||||||
{
|
{
|
||||||
widgetMetaData.type === "parentWidget" && (
|
haveLoadedParams && widgetMetaData.type === "parentWidget" && (
|
||||||
<ParentWidget
|
<ParentWidget
|
||||||
|
urlParams={currentUrlParams}
|
||||||
entityPrimaryKey={entityPrimaryKey}
|
entityPrimaryKey={entityPrimaryKey}
|
||||||
tableName={tableName}
|
tableName={tableName}
|
||||||
widgetIndex={i}
|
widgetIndex={i}
|
||||||
|
@ -50,6 +50,7 @@ export interface ParentWidgetData
|
|||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
interface Props
|
interface Props
|
||||||
{
|
{
|
||||||
|
urlParams?: string;
|
||||||
widgetMetaData?: QWidgetMetaData;
|
widgetMetaData?: QWidgetMetaData;
|
||||||
widgetIndex: number;
|
widgetIndex: number;
|
||||||
data: ParentWidgetData;
|
data: ParentWidgetData;
|
||||||
@ -61,9 +62,9 @@ interface Props
|
|||||||
|
|
||||||
|
|
||||||
const qController = Client.getInstance();
|
const qController = Client.getInstance();
|
||||||
function ParentWidget({widgetMetaData, widgetIndex, data, reloadWidgetCallback, entityPrimaryKey, tableName, storeDropdownSelections}: Props, ): JSX.Element
|
function ParentWidget({urlParams, widgetMetaData, widgetIndex, data, reloadWidgetCallback, entityPrimaryKey, tableName, storeDropdownSelections}: Props, ): JSX.Element
|
||||||
{
|
{
|
||||||
const [childUrlParams, setChildUrlParams] = useState("");
|
const [childUrlParams, setChildUrlParams] = useState((urlParams) ? urlParams : "");
|
||||||
const [qInstance, setQInstance] = useState(null as QInstance);
|
const [qInstance, setQInstance] = useState(null as QInstance);
|
||||||
const [widgets, setWidgets] = useState([] as any[]);
|
const [widgets, setWidgets] = useState([] as any[]);
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ function ParentWidget({widgetMetaData, widgetIndex, data, reloadWidgetCallback,
|
|||||||
})
|
})
|
||||||
setWidgets(widgetMetaDataList);
|
setWidgets(widgetMetaDataList);
|
||||||
}
|
}
|
||||||
}, [qInstance, data]);
|
}, [qInstance, data, childUrlParams]);
|
||||||
|
|
||||||
const parentReloadWidgetCallback = (data: string) =>
|
const parentReloadWidgetCallback = (data: string) =>
|
||||||
{
|
{
|
||||||
@ -98,16 +99,18 @@ function ParentWidget({widgetMetaData, widgetIndex, data, reloadWidgetCallback,
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return (
|
return (
|
||||||
<Widget
|
qInstance && data ? (
|
||||||
widgetMetaData={widgetMetaData}
|
<Widget
|
||||||
widgetData={data}
|
widgetMetaData={widgetMetaData}
|
||||||
storeDropdownSelections={storeDropdownSelections}
|
widgetData={data}
|
||||||
reloadWidgetCallback={parentReloadWidgetCallback}
|
storeDropdownSelections={storeDropdownSelections}
|
||||||
>
|
reloadWidgetCallback={parentReloadWidgetCallback}
|
||||||
<Box sx={{height: "100%", width: "100%"}}>
|
>
|
||||||
<DashboardWidgets widgetMetaDataList={widgets} entityPrimaryKey={entityPrimaryKey} tableName={tableName} childUrlParams={childUrlParams} areChildren={true}/>
|
<Box sx={{height: "100%", width: "100%"}}>
|
||||||
</Box>
|
<DashboardWidgets widgetMetaDataList={widgets} entityPrimaryKey={entityPrimaryKey} tableName={tableName} childUrlParams={childUrlParams} areChildren={true} />
|
||||||
</Widget>
|
</Box>
|
||||||
|
</Widget>
|
||||||
|
) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import DropdownMenu, {DropdownOption} from "qqq/components/widgets/components/Dr
|
|||||||
|
|
||||||
export interface WidgetData
|
export interface WidgetData
|
||||||
{
|
{
|
||||||
|
label?: string;
|
||||||
dropdownLabelList?: string[];
|
dropdownLabelList?: string[];
|
||||||
dropdownNameList?: string[];
|
dropdownNameList?: string[];
|
||||||
dropdownDataList?: {
|
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<Props>): JSX.Element
|
function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
||||||
@ -254,7 +255,7 @@ function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
|||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(dropdownData)
|
if(dropdownData && counter > 0)
|
||||||
{
|
{
|
||||||
let params = "";
|
let params = "";
|
||||||
for (let i = 0; i < dropdownData.length; i++)
|
for (let i = 0; i < dropdownData.length; i++)
|
||||||
@ -311,10 +312,19 @@ function Widget(props: React.PropsWithChildren<Props>): JSX.Element
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
props.widgetMetaData?.label && (
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// first look for a label in the widget data, which would override that in the metadata //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
props.widgetData?.label? (
|
||||||
<Typography variant="h5" fontWeight="medium" pl={3} display="inline">
|
<Typography variant="h5" fontWeight="medium" pl={3} display="inline">
|
||||||
{props.widgetMetaData.label}
|
{props.widgetData.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
) : (
|
||||||
|
props.widgetMetaData?.label && (
|
||||||
|
<Typography variant="h5" fontWeight="medium" pl={3} display="inline">
|
||||||
|
{props.widgetMetaData.label}
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@ export const chartColors = ["info", "warning", "primary", "success", "error", "s
|
|||||||
export interface DefaultChartData
|
export interface DefaultChartData
|
||||||
{
|
{
|
||||||
labels: string[];
|
labels: string[];
|
||||||
|
urls?: string[];
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
|
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import {BarElement, CategoryScale, Chart as ChartJS, Legend, LinearScale, Title, Tooltip,} from "chart.js";
|
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 {Bar} from "react-chartjs-2";
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
import colors from "qqq/assets/theme/base/colors";
|
import colors from "qqq/assets/theme/base/colors";
|
||||||
import {chartColors, DefaultChartData} from "qqq/components/widgets/charts/DefaultChartData";
|
import {chartColors, DefaultChartData} from "qqq/components/widgets/charts/DefaultChartData";
|
||||||
|
|
||||||
@ -56,29 +57,36 @@ interface Props
|
|||||||
const {gradients} = colors;
|
const {gradients} = colors;
|
||||||
function StackedBarChart({data}: Props): JSX.Element
|
function StackedBarChart({data}: Props): JSX.Element
|
||||||
{
|
{
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const handleClick = (e: Array<{}>) =>
|
const handleClick = (e: Array<{}>) =>
|
||||||
{
|
{
|
||||||
/*
|
if(e && e.length > 0 && data?.urls && data?.urls.length)
|
||||||
if(e && e.length > 0 && data?.dataset?.urls && data?.dataset?.urls.length)
|
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
navigate(chartData.dataset.urls[e[0]["index"]]);
|
navigate(data.urls[e[0]["index"]]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
console.log(e);
|
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 <Box p={3}><Bar data={data} options={options} getElementsAtEvent={handleClick} /></Box>;
|
|
||||||
|
return data ? (
|
||||||
|
<Box p={3}><Bar data={data} options={options} getElementsAtEvent={handleClick} /></Box>
|
||||||
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default StackedBarChart;
|
export default StackedBarChart;
|
||||||
|
@ -27,7 +27,6 @@ import parse from "html-react-parser";
|
|||||||
import React, {useMemo} from "react";
|
import React, {useMemo} from "react";
|
||||||
import {Pie} from "react-chartjs-2";
|
import {Pie} from "react-chartjs-2";
|
||||||
import {useNavigate} from "react-router-dom";
|
import {useNavigate} from "react-router-dom";
|
||||||
import MDBadgeDot from "qqq/components/legacy/MDBadgeDot";
|
|
||||||
import MDTypography from "qqq/components/legacy/MDTypography";
|
import MDTypography from "qqq/components/legacy/MDTypography";
|
||||||
import {chartColors} from "qqq/components/widgets/charts/DefaultChartData";
|
import {chartColors} from "qqq/components/widgets/charts/DefaultChartData";
|
||||||
import configs from "qqq/components/widgets/charts/piechart/PieChartConfigs";
|
import configs from "qqq/components/widgets/charts/piechart/PieChartConfigs";
|
||||||
@ -56,6 +55,7 @@ interface Props
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function PieChart({description, chartData}: Props): JSX.Element
|
function PieChart({description, chartData}: Props): JSX.Element
|
||||||
{
|
{
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -80,9 +80,8 @@ function PieChart({description, chartData}: Props): JSX.Element
|
|||||||
<Card sx={{boxShadow: "none", height: "100%", width: "100%", display: "flex", flexGrow: 1}}>
|
<Card sx={{boxShadow: "none", height: "100%", width: "100%", display: "flex", flexGrow: 1}}>
|
||||||
<Box mt={3}>
|
<Box mt={3}>
|
||||||
<Grid container alignItems="center">
|
<Grid container alignItems="center">
|
||||||
<Grid item xs={5}>
|
<Grid item xs={12} justifyContent="center">
|
||||||
|
<Box width="100%" height="80%" py={2} pr={2} pl={2}>
|
||||||
<Box py={2} pr={2} pl={2}>
|
|
||||||
{useMemo(
|
{useMemo(
|
||||||
() => (
|
() => (
|
||||||
<Pie data={data} options={options} getElementsAtEvent={handleClick} />
|
<Pie data={data} options={options} getElementsAtEvent={handleClick} />
|
||||||
@ -91,19 +90,6 @@ function PieChart({description, chartData}: Props): JSX.Element
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={7}>
|
|
||||||
<Box pr={1}>
|
|
||||||
{
|
|
||||||
data && data.labels ? (
|
|
||||||
(data.labels.map((label: string, index: number) => (
|
|
||||||
<Box key={index}>
|
|
||||||
<MDBadgeDot color={chartColors[index]} size="sm" badgeContent={label} />
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
))) : null
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Divider />
|
<Divider />
|
||||||
{
|
{
|
||||||
|
@ -58,11 +58,12 @@ function configs(labels: any, datasets: any)
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: true,
|
maintainAspectRatio: true,
|
||||||
|
responsive: true,
|
||||||
|
aspectRatio: 2,
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: {
|
legend: {
|
||||||
display: false,
|
position: "bottom",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
|
@ -23,7 +23,7 @@ import {Theme} from "@mui/material";
|
|||||||
import Autocomplete from "@mui/material/Autocomplete";
|
import Autocomplete from "@mui/material/Autocomplete";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import {SxProps} from "@mui/system";
|
import {SxProps} from "@mui/system";
|
||||||
import React, {useEffect} from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
export interface DropdownOption
|
export interface DropdownOption
|
||||||
@ -47,15 +47,6 @@ interface Props
|
|||||||
|
|
||||||
function DropdownMenu({localStorageKey, defaultValue, label, dropdownOptions, onChangeCallback, sx}: Props): JSX.Element
|
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) =>
|
const handleOnChange = (event: any, value: any, reason: string) =>
|
||||||
{
|
{
|
||||||
onChangeCallback(label, value);
|
onChangeCallback(label, value);
|
||||||
|
Reference in New Issue
Block a user