diff --git a/package.json b/package.json
index 86cf182..52c73bf 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"@fullcalendar/interaction": "5.10.0",
"@fullcalendar/react": "5.10.0",
"@fullcalendar/timegrid": "5.10.0",
- "@kingsrook/qqq-frontend-core": "1.0.38",
+ "@kingsrook/qqq-frontend-core": "1.0.39",
"@mui/icons-material": "5.4.1",
"@mui/material": "5.4.1",
"@mui/styled-engine": "5.4.1",
diff --git a/public/flags/AU.png b/public/flags/AU.png
new file mode 100644
index 0000000..13fd089
Binary files /dev/null and b/public/flags/AU.png differ
diff --git a/public/flags/BR.png b/public/flags/BR.png
new file mode 100644
index 0000000..91e3862
Binary files /dev/null and b/public/flags/BR.png differ
diff --git a/public/flags/DE.png b/public/flags/DE.png
new file mode 100644
index 0000000..5029361
Binary files /dev/null and b/public/flags/DE.png differ
diff --git a/public/flags/GB.png b/public/flags/GB.png
new file mode 100644
index 0000000..b2f1b3b
Binary files /dev/null and b/public/flags/GB.png differ
diff --git a/public/flags/US.png b/public/flags/US.png
new file mode 100644
index 0000000..5b42a56
Binary files /dev/null and b/public/flags/US.png differ
diff --git a/src/App.tsx b/src/App.tsx
index 296db35..d32ffc7 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -83,7 +83,6 @@ function getStaticRoutes()
},
],
},
- {type: "divider", key: "divider-1"},
];
}
@@ -411,14 +410,35 @@ export default function App()
const sideNavAppList = [] as any[];
const appRoutesList = [] as any[];
+ const mainDashboardsApp = {} as any;
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // iterate throught the list to find the 'main dashboard so we can put it first' //
+ ///////////////////////////////////////////////////////////////////////////////////
for (let i = 0; i < metaData.appTree.length; i++)
{
const app = metaData.appTree[i];
+ if(app.name === "mainDashboards")
+ {
+ addAppToSideNavList(app, sideNavAppList, "", 0);
+ addAppToAppRoutesList(metaData, app, appRoutesList, "", 0);
+ sideNavAppList.push({type: "divider", key: "divider-1"});
+ break;
+ }
+ }
+ for (let i = 0; i < metaData.appTree.length; i++)
+ {
+ const app = metaData.appTree[i];
+ if(app.name === "mainDashboards")
+ {
+ continue;
+ }
+
addAppToSideNavList(app, sideNavAppList, "", 0);
addAppToAppRoutesList(metaData, app, appRoutesList, "", 0);
}
- const newSideNavRoutes = getStaticRoutes();
+ const newSideNavRoutes = []; // getStaticRoutes();
// @ts-ignore
newSideNavRoutes.unshift(profileRoutes);
for (let i = 0; i < sideNavAppList.length; i++)
diff --git a/src/qqq/components/DashboardWidgets.tsx b/src/qqq/components/DashboardWidgets.tsx
index 9725d42..f78167e 100644
--- a/src/qqq/components/DashboardWidgets.tsx
+++ b/src/qqq/components/DashboardWidgets.tsx
@@ -37,11 +37,15 @@ import FieldValueListWidget from "qqq/pages/dashboards/Widgets/FieldValueListWid
import HorizontalBarChart from "qqq/pages/dashboards/Widgets/HorizontalBarChart";
import MultiStatisticsCard from "qqq/pages/dashboards/Widgets/MultiStatisticsCard";
import ParentWidget from "qqq/pages/dashboards/Widgets/ParentWidget";
+import PieChartCard from "qqq/pages/dashboards/Widgets/PieChartCard";
import QuickSightChart from "qqq/pages/dashboards/Widgets/QuickSightChart";
import RecordGridWidget from "qqq/pages/dashboards/Widgets/RecordGridWidget";
import SimpleStatisticsCard from "qqq/pages/dashboards/Widgets/SimpleStatisticsCard";
+import SmallLineChart from "qqq/pages/dashboards/Widgets/SmallLineChart";
+import StatisticsCard from "qqq/pages/dashboards/Widgets/StatisticsCard";
import StepperCard from "qqq/pages/dashboards/Widgets/StepperCard";
import TableCard from "qqq/pages/dashboards/Widgets/TableCard";
+import USMapWidget from "qqq/pages/dashboards/Widgets/USMapWidget";
import Widget from "qqq/pages/dashboards/Widgets/Widget";
import ProcessRun from "qqq/pages/process-run";
import QClient from "qqq/utils/QClient";
@@ -98,9 +102,9 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
widgetData[i] = {};
(async () =>
{
- console.log(`widgets: ${getQueryParams(null)}`)
widgetData[i] = await qController.widget(widgetMetaDataList[i].name, getQueryParams(null));
setWidgetCounter(widgetCounter + 1);
+ console.log(`widget data: ${JSON.stringify(widgetData[i])}`)
forceUpdate();
})();
}
@@ -147,7 +151,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
}
return params;
- };
+ }
const widgetCount = widgetMetaDataList ? widgetMetaDataList.length : 0;
@@ -158,6 +162,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
{
widgetMetaData.type === "parentWidget" && (
)
}
+ {
+ widgetMetaData.type === "table" && (
+ reloadWidget(i, data)}
+ isChild={areChildren}
+ >
+ reloadWidget(i, data)}
+ widgetIndex={i}
+ />
+
+ )
+ }
{
widgetMetaData.type === "process" && widgetData[i]?.processMetaData && (
+ )
+ }
+ {
+ widgetMetaData.type === "simpleStatistics" && (
widgetData && widgetData[i] && (
+ )
+ )
+ }
{
widgetMetaData.type === "quickSightChart" && (
@@ -255,8 +300,18 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
widgetMetaData.type === "barChart" && (
+ )
+ }
+ {
+ widgetMetaData.type === "pieChart" && (
+
)
@@ -270,14 +325,12 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
}
{
widgetMetaData.type === "horizontalBarChart" && (
- widgetData && widgetData[i] && widgetData[i].chartData && (
-
- )
+
)
}
{
diff --git a/src/qqq/components/Temporary/DataTable/index.tsx b/src/qqq/components/Temporary/DataTable/index.tsx
index 75bfa55..73de877 100644
--- a/src/qqq/components/Temporary/DataTable/index.tsx
+++ b/src/qqq/components/Temporary/DataTable/index.tsx
@@ -38,12 +38,7 @@ import MDInput from "qqq/components/Temporary/MDInput";
import MDPagination from "qqq/components/Temporary/MDPagination";
import MDTypography from "qqq/components/Temporary/MDTypography";
import ImageCell from "qqq/pages/dashboards/Tables/ImageCell";
-
-export interface TableDataInput
-{
- columns: { [key: string]: any }[];
- rows: { [key: string]: any }[];
-}
+import {TableDataInput} from "qqq/pages/dashboards/Widgets/TableCard";
interface Props
{
diff --git a/src/qqq/pages/dashboards/CarrierPerformance.tsx b/src/qqq/pages/dashboards/CarrierPerformance.tsx
index faba779..88d36a6 100644
--- a/src/qqq/pages/dashboards/CarrierPerformance.tsx
+++ b/src/qqq/pages/dashboards/CarrierPerformance.tsx
@@ -29,7 +29,6 @@ import QContext from "QContext";
import DashboardLayout from "qqq/components/DashboardLayout";
import Footer from "qqq/components/Footer";
import Navbar from "qqq/components/Navbar";
-import {TableDataInput} from "qqq/components/Temporary/DataTable";
import MDBox from "qqq/components/Temporary/MDBox";
import ShipmentsByWarehouseTable from "qqq/pages/dashboards/Tables/ShipmentsByWarehouseTable";
import {GenericChartData} from "qqq/pages/dashboards/Widgets/Data/GenericChartData";
@@ -40,7 +39,7 @@ import {PieChartData} from "qqq/pages/dashboards/Widgets/PieChart";
import PieChartCard from "qqq/pages/dashboards/Widgets/PieChartCard";
import SimpleStatisticsCard from "qqq/pages/dashboards/Widgets/SimpleStatisticsCard";
import {StatisticsCardData} from "qqq/pages/dashboards/Widgets/StatisticsCard";
-import TableCard from "qqq/pages/dashboards/Widgets/TableCard";
+import TableCard, {TableDataInput} from "qqq/pages/dashboards/Widgets/TableCard";
import QClient from "qqq/utils/QClient";
const qController = QClient.getInstance();
diff --git a/src/qqq/pages/dashboards/Overview.tsx b/src/qqq/pages/dashboards/Overview.tsx
index c9d2c72..2fbfde3 100644
--- a/src/qqq/pages/dashboards/Overview.tsx
+++ b/src/qqq/pages/dashboards/Overview.tsx
@@ -47,7 +47,6 @@ function Overview(): JSX.Element
//////////////////////////////////
// shipments by day widget data //
//////////////////////////////////
- const [shipmentsByDayTitle, setShipmentsByDayTitle] = useState("");
const [shipmentsByDayDescription, setShipmentsByDayDescription] = useState("");
const [shipmentsByDayData, setShipmentsByDayData] = useState({} as GenericChartDataSingleDataset);
@@ -135,7 +134,6 @@ function Overview(): JSX.Element
}
const description = "Over the last week there have been " + daysOverAverage.toLocaleString() + (daysOverAverage == 1 ? " day" : " days") + " with total shipments greater than the daily average of " + average.toLocaleString() + " shipments.";
- setShipmentsByDayTitle(widgetData.title);
setShipmentsByDayData(widgetData.chartData);
setShipmentsByDayDescription(description);
})();
diff --git a/src/qqq/pages/dashboards/Widgets/BarChart.tsx b/src/qqq/pages/dashboards/Widgets/BarChart.tsx
index cb09524..bae41ba 100644
--- a/src/qqq/pages/dashboards/Widgets/BarChart.tsx
+++ b/src/qqq/pages/dashboards/Widgets/BarChart.tsx
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*/
+import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import Divider from "@mui/material/Divider";
import Icon from "@mui/material/Icon";
@@ -142,44 +143,47 @@ function BarChart({color, title, description, date, data}: Props): JSX.Element
const {chartData} = getChartData(data?.labels, data?.dataset);
return (
-
-
- {useMemo(
- () => (
-
-
+
+
+
+
+ {useMemo(
+ () => (
+
+
+
+ ),
+ [data, color]
+ )}
+
+
+ {title}
+
+
+ {parse(description)}
+
+
+
+
+ schedule
+
+
+ {date}
+
- ),
- [data, color]
- )}
-
-
- {title}
-
-
- {parse(description)}
-
-
-
-
- schedule
-
-
- {date}
-
-
-
+
+
);
}
diff --git a/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx b/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
index 9e7f579..8830dcd 100644
--- a/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
+++ b/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
@@ -57,7 +57,7 @@ const options = {
callbacks: {
label: function(context:any)
{
- return(context.parsed.x);
+ return(" " + Number(context.parsed.y).toLocaleString());
}
}
}
@@ -90,7 +90,7 @@ const options = {
},
callback: function(value: any, index: any, values: any)
{
- return value;
+ return value.toLocaleString();
}
},
},
diff --git a/src/qqq/pages/dashboards/Widgets/HorizontalBarChart.tsx b/src/qqq/pages/dashboards/Widgets/HorizontalBarChart.tsx
index d8c619b..72063ea 100644
--- a/src/qqq/pages/dashboards/Widgets/HorizontalBarChart.tsx
+++ b/src/qqq/pages/dashboards/Widgets/HorizontalBarChart.tsx
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*/
+import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import Icon from "@mui/material/Icon";
import {ReactNode, useMemo} from "react";
@@ -48,7 +49,7 @@ const options = {
return(context.parsed.x);
}
}
- }
+ },
},
scales: {
y: {
@@ -122,27 +123,30 @@ interface Props
function HorizontalBarChart({icon, title, description, height, data, isCurrency}: Props): JSX.Element
{
- const chartDatasets = data.datasets
- ? data.datasets.map((dataset) => ({
- ...dataset,
- weight: 5,
- borderWidth: 0,
- borderRadius: 4,
- backgroundColor: dataset?.color
- ? dataset.color
- : colors.info.main,
- fill: false,
- maxBarThickness: 15,
- }))
- : [];
-
let fullData = {};
- if (data)
+ if(data && data.datasets)
{
- fullData = {
- labels: data.labels,
- datasets: chartDatasets
- };
+ const chartDatasets = data.datasets
+ ? data.datasets.map((dataset) => ({
+ ...dataset,
+ weight: 5,
+ borderWidth: 0,
+ borderRadius: 4,
+ backgroundColor: dataset?.color
+ ? dataset.color
+ : colors.info.main,
+ fill: false,
+ maxBarThickness: 15,
+ }))
+ : [];
+
+ if (data)
+ {
+ fullData = {
+ labels: data.labels,
+ datasets: chartDatasets
+ };
+ }
}
let customOptions = options;
@@ -166,10 +170,9 @@ function HorizontalBarChart({icon, title, description, height, data, isCurrency}
}
}
-
const renderChart = (
- {title || description ? (
+ {title || description && (
{icon.component && (
- ) : null}
+ )}
{useMemo(
() => (
-
+ {
+ data && data?.datasets && data?.datasets.length > 0 ?(
+
+ ):(
+ No data was provided to this chart
+ )
+ }
),
[data, height]
diff --git a/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx b/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
index e1f3a75..0d968b9 100644
--- a/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
@@ -21,13 +21,10 @@
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData";
-import {Box, Typography} from "@mui/material";
-import Card from "@mui/material/Card";
-import Grid from "@mui/material/Grid";
+import {Box} from "@mui/material";
import React, {useEffect, useState} from "react";
import DashboardWidgets from "qqq/components/DashboardWidgets";
-import DropdownMenu from "qqq/pages/dashboards/Widgets/Components/DropdownMenu";
-import Widget, {Dropdown, LabelComponent} from "qqq/pages/dashboards/Widgets/Widget";
+import Widget from "qqq/pages/dashboards/Widgets/Widget";
import QClient from "qqq/utils/QClient";
@@ -44,6 +41,7 @@ export interface ParentWidgetData
}[][];
childWidgetNameList: string[];
dropdownNeedsSelectedText?: string;
+ icon?: string;
}
@@ -54,6 +52,7 @@ interface Props
{
widgetIndex: number;
label: string;
+ icon?: string;
data: ParentWidgetData;
reloadWidgetCallback?: (widgetIndex: number, params: string) => void;
entityPrimaryKey?: string;
@@ -62,7 +61,7 @@ interface Props
const qController = QClient.getInstance();
-function ParentWidget({widgetIndex, label, data, reloadWidgetCallback, entityPrimaryKey, tableName}: Props, ): JSX.Element
+function ParentWidget({widgetIndex, label, icon, data, reloadWidgetCallback, entityPrimaryKey, tableName}: Props, ): JSX.Element
{
const [childUrlParams, setChildUrlParams] = useState("");
const [qInstance, setQInstance] = useState(null as QInstance);
@@ -93,16 +92,19 @@ function ParentWidget({widgetIndex, label, data, reloadWidgetCallback, entityPri
const parentReloadWidgetCallback = (data: string) =>
{
setChildUrlParams(data);
+
reloadWidgetCallback(widgetIndex, data);
}
+ // @ts-ignore
return (
-
+
diff --git a/src/qqq/pages/dashboards/Widgets/PieChartCard.tsx b/src/qqq/pages/dashboards/Widgets/PieChartCard.tsx
index ad4fbc0..a360724 100644
--- a/src/qqq/pages/dashboards/Widgets/PieChartCard.tsx
+++ b/src/qqq/pages/dashboards/Widgets/PieChartCard.tsx
@@ -48,8 +48,8 @@ function PieChartCard({title, description, data}: Props): JSX.Element
}
return (
-
-
+
+
{title}
@@ -72,15 +72,19 @@ function PieChartCard({title, description, data}: Props): JSX.Element
-
-
-
-
- {parse(description)}
-
-
-
-
+ {
+ description && (
+
+
+
+
+ {parse(description)}
+
+
+
+
+ )
+ }
);
diff --git a/src/qqq/pages/dashboards/Widgets/SimpleStatisticsCard.tsx b/src/qqq/pages/dashboards/Widgets/SimpleStatisticsCard.tsx
index f3a75a2..f4f6a7b 100644
--- a/src/qqq/pages/dashboards/Widgets/SimpleStatisticsCard.tsx
+++ b/src/qqq/pages/dashboards/Widgets/SimpleStatisticsCard.tsx
@@ -82,7 +82,7 @@ function SimpleStatisticsCard({title, data, increaseIsGood, isCurrency, dropdown
{
- count ? (
+ count !== undefined ? (
isCurrency ? (
{count.toLocaleString("en-US", {style: "currency", currency: "USD"})}
@@ -90,21 +90,29 @@ function SimpleStatisticsCard({title, data, increaseIsGood, isCurrency, dropdown
) : (
- {count.toLocaleString("en-US", {style: "currency", currency: "USD"})}
+ {count.toLocaleString()}
)
) : null
}
-
- {percentageString}
-
- {percentageLabel}
-
-
+ {
+ count !== undefined ? (
+
+ {percentageString}
+
+ {percentageLabel}
+
+
+ ):(
+
+ Loading.
+
+ )
+ }
{dropdown && (
diff --git a/src/qqq/pages/dashboards/Widgets/SmallLineChart.tsx b/src/qqq/pages/dashboards/Widgets/SmallLineChart.tsx
index 34302df..95dd196 100644
--- a/src/qqq/pages/dashboards/Widgets/SmallLineChart.tsx
+++ b/src/qqq/pages/dashboards/Widgets/SmallLineChart.tsx
@@ -19,9 +19,8 @@
* along with this program. If not, see .
*/
+import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
-import Divider from "@mui/material/Divider";
-import Icon from "@mui/material/Icon";
import parse from "html-react-parser";
import {useMemo} from "react";
import {Line} from "react-chartjs-2";
@@ -57,47 +56,40 @@ function SmallLineChart({color, title, description, date, chart}: Props): JSX.El
{
const {data, options} = configs(chart?.labels || [], chart?.dataset || {});
- console.log(`DATA: ${JSON.stringify(data)}`);
-
return (
-
-
- {useMemo(
- () => (
-
-
-
- ),
- [chart, color]
- )}
-
-
- {title}
-
-
- {parse(description)}
-
-
-
-
- schedule
+
+
+
+
+
+ {useMemo(
+ () => (
+
+
+
+ ),
+ [chart, color]
+ )}
+
+
+ {title}
-
- {date}
+
+ {parse(description)}
-
-
+
+
);
}
diff --git a/src/qqq/pages/dashboards/Widgets/StatisticsCard.tsx b/src/qqq/pages/dashboards/Widgets/StatisticsCard.tsx
index d20fe5e..2816586 100644
--- a/src/qqq/pages/dashboards/Widgets/StatisticsCard.tsx
+++ b/src/qqq/pages/dashboards/Widgets/StatisticsCard.tsx
@@ -88,7 +88,8 @@ function StatisticsCard({data, color, icon, increaseIsGood}: Props): JSX.Element
}
return (
-
+
+
-
{
percentageAmount !== undefined && percentageAmount !== 0 ? (
-
+
+
.
*/
-import {Icon, Skeleton} from "@mui/material";
-import Card from "@mui/material/Card";
-import Grid from "@mui/material/Grid";
-import Menu from "@mui/material/Menu";
-import MenuItem from "@mui/material/MenuItem";
+import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
+import {Skeleton} from "@mui/material";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableContainer from "@mui/material/TableContainer";
import TableRow from "@mui/material/TableRow";
import parse from "html-react-parser";
import React, {useEffect, useState} from "react";
-import {NavLink} from "react-router-dom";
-import DataTable, {TableDataInput} from "qqq/components/Temporary/DataTable";
+import DataTable from "qqq/components/Temporary/DataTable";
import DataTableBodyCell from "qqq/components/Temporary/DataTable/DataTableBodyCell";
import DataTableHeadCell from "qqq/components/Temporary/DataTable/DataTableHeadCell";
import DefaultCell from "qqq/components/Temporary/DefaultCell";
import MDBox from "qqq/components/Temporary/MDBox";
import MDTypography from "qqq/components/Temporary/MDTypography";
+import QClient from "qqq/utils/QClient";
+
+
+//////////////////////////////////////
+// structure of expected table data //
+//////////////////////////////////////
+export interface TableDataInput
+{
+ columns: { [key: string]: any }[];
+ rows: { [key: string]: any }[];
+}
/////////////////////////
@@ -49,130 +56,39 @@ interface Props
linkURL?: string;
noRowsFoundHTML?: string;
data: TableDataInput;
- dropdownOptions?: {
- id: string,
- name: string
- }[];
- reloadWidgetCallback?: (widgetIndex: number, params: string) => void;
+ reloadWidgetCallback?: (params: string) => void;
widgetIndex?: number;
isChild?: boolean;
[key: string]: any;
}
-function TableCard({title, linkText, linkURL, noRowsFoundHTML, data, dropdownOptions, reloadWidgetCallback, widgetIndex, isChild}: Props): JSX.Element
+const qController = QClient.getInstance();
+function TableCard({noRowsFoundHTML, data, reloadWidgetCallback}: Props): JSX.Element
{
- const openArrowIcon = "arrow_drop_down";
- const closeArrowIcon = "arrow_drop_up";
- const [dropdown, setDropdown] = useState(null);
- const [dropdownValue, setDropdownValue] = useState("");
- const [dropdownLabel, setDropdownLabel] = useState("");
- const [dropdownIcon, setDropdownIcon] = useState(openArrowIcon);
-
- // console.log(`data: ${JSON.stringify(data?.rows)}`);
- // console.log(`bool: ${data && data?.columns && !data?.rows}`);
- // console.log(`norowsfound: ${noRowsFoundHTML}`);
-
- const openDropdown = ({currentTarget}: any) =>
- {
- setDropdown(currentTarget);
- setDropdownIcon(closeArrowIcon);
- };
- const closeDropdown = ({currentTarget}: any) =>
- {
- setDropdown(null);
- setDropdownValue(currentTarget.innerText || dropdownValue);
- setDropdownIcon(openArrowIcon);
- reloadWidgetCallback(widgetIndex, null);
- };
-
- const renderMenu = (state: any, open: any, close: any, icon: string) => (
- dropdownOptions && (
-
- {icon}
-
-
- )
- );
+ const [qInstance, setQInstance] = useState(null as QInstance);
useEffect(() =>
{
- if (dropdownOptions)
+ (async () =>
{
- setDropdownValue(dropdownOptions[0]["id"]);
- setDropdownLabel(dropdownOptions[0]["name"]);
-
- }
- }, [dropdownOptions]);
+ const newQInstance = await qController.loadMetaData();
+ setQInstance(newQInstance);
+ })();
+ }, []);
return (
-
-
-
-
-
- {title}
-
-
-
-
- {
- linkText && (
-
- {linkText}
-
- )
- }
-
-
- {dropdownOptions && (
-
-
- Billing Period:
-
-
- {dropdownLabel}
-
- {renderMenu(dropdown, openDropdown, closeDropdown, dropdownIcon)}
-
- )}
-
-
-
-
- {
- data && data.columns && !noRowsFoundHTML ? (
-
- ) : noRowsFoundHTML ? (
+
+ {
+ data && data.columns && !noRowsFoundHTML ?
+
+ : noRowsFoundHTML ?
- ) : (
+ :
@@ -211,10 +127,8 @@ function TableCard({title, linkText, linkURL, noRowsFoundHTML, data, dropdownOpt
- )
- }
-
-
+ }
+
);
}
diff --git a/src/qqq/pages/dashboards/Widgets/USMapWidget.tsx b/src/qqq/pages/dashboards/Widgets/USMapWidget.tsx
new file mode 100644
index 0000000..88ef558
--- /dev/null
+++ b/src/qqq/pages/dashboards/Widgets/USMapWidget.tsx
@@ -0,0 +1,146 @@
+/*
+ * 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 {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
+import {Box, Grid} from "@mui/material";
+import {VectorMap} from "@react-jvectormap/core";
+import {usAea} from "@react-jvectormap/unitedstates";
+import React, {useEffect, useState} from "react";
+import QClient from "qqq/utils/QClient";
+
+
+////////////////////////////////////////////////
+// structure of expected US and A widget data //
+////////////////////////////////////////////////
+export interface MapMarkerData
+{
+ name: string;
+ latitude: number;
+ longitude: number;
+}
+export interface USMapWidgetData
+{
+ height: string;
+ markers?: MapMarkerData[];
+}
+
+
+////////////////////////////////////
+// define properties and defaults //
+////////////////////////////////////
+interface Props
+{
+ widgetIndex: number;
+ label: string;
+ icon?: string;
+ reloadWidgetCallback?: (widgetIndex: number, params: string) => void;
+ data: USMapWidgetData;
+}
+
+
+const qController = QClient.getInstance();
+function USMapWidget(props: Props, ): JSX.Element
+{
+ const [qInstance, setQInstance] = useState(null as QInstance);
+
+ useEffect(() =>
+ {
+ (async () =>
+ {
+ const newQInstance = await qController.loadMetaData();
+ setQInstance(newQInstance);
+ })();
+ }, []);
+
+ console.log(JSON.stringify(props))
+
+ return (
+
+
+ {
+ props.data?.height && (
+
+ false}
+ onMarkerTipShow={() => false}
+ />
+
+ )
+ }
+
+
+
+ );
+}
+
+export default USMapWidget;
diff --git a/src/qqq/pages/dashboards/Widgets/Widget.tsx b/src/qqq/pages/dashboards/Widgets/Widget.tsx
index 7987752..3c1aeb2 100644
--- a/src/qqq/pages/dashboards/Widgets/Widget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/Widget.tsx
@@ -23,19 +23,18 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Card from "@mui/material/Card";
-import Modal from "@mui/material/Modal";
+import Icon from "@mui/material/Icon";
import Typography from "@mui/material/Typography";
import React, {useEffect, useState} from "react";
import {Link, useNavigate} from "react-router-dom";
-import DashboardWidgets from "qqq/components/DashboardWidgets";
-import EntityForm from "qqq/components/EntityForm";
+import colors from "qqq/components/Temporary/colors";
import DropdownMenu, {DropdownOption} from "qqq/pages/dashboards/Widgets/Components/DropdownMenu";
export interface WidgetData
{
- dropdownLabelList: string[];
- dropdownNameList: string[];
- dropdownDataList: {
+ dropdownLabelList?: string[];
+ dropdownNameList?: string[];
+ dropdownDataList?: {
id: string,
label: string
}[][];
@@ -45,15 +44,20 @@ export interface WidgetData
interface Props
{
+ icon?: string;
label: string;
labelAdditionalComponentsLeft: LabelComponent[];
labelAdditionalComponentsRight: LabelComponent[];
widgetData?: WidgetData;
children: JSX.Element;
reloadWidgetCallback?: (params: string) => void;
+ isChild?: boolean;
+ isCard?: boolean;
}
Widget.defaultProps = {
+ isCard: true,
+ isChild: false,
label: null,
widgetData: {},
labelAdditionalComponentsLeft: [],
@@ -246,44 +250,70 @@ function Widget(props: React.PropsWithChildren): JSX.Element
}
}, [counter]);
- return (
- <>
-
-
-
-
- {props.label}
-
- {
- props.labelAdditionalComponentsLeft.map((component, i) =>
+ const widgetContent =
+
+ {
+ (props.icon || props.label) && (
+
+
{
- return ({renderComponent(component)});
- })
- }
-
-
- {
- effectiveLabelAdditionalComponentsRight.map((component, i) =>
- {
- return ({renderComponent(component)});
- })
- }
-
-
- {
- props.widgetData?.dropdownNeedsSelectedText ? (
-
-
- {props.widgetData?.dropdownNeedsSelectedText}
+ props.icon && (
+
+
+ {props.icon}
+
+
+ )
+ }
+
+ {props.label}
+ {
+ props.labelAdditionalComponentsLeft.map((component, i) =>
+ {
+ return ({renderComponent(component)});
+ })
+ }
- ) : (
- props.children
- )
- }
-
- >
- );
+
+ {
+ effectiveLabelAdditionalComponentsRight.map((component, i) =>
+ {
+ return ({renderComponent(component)});
+ })
+ }
+
+
+ )
+ }
+ {
+ props.widgetData?.dropdownNeedsSelectedText ? (
+
+
+ {props.widgetData?.dropdownNeedsSelectedText}
+
+
+ ) : (
+ props.children
+ )
+ }
+ ;
+
+ return props.isCard ? {widgetContent} : widgetContent;
}
export default Widget;