diff --git a/src/qqq/components/DashboardWidgets.tsx b/src/qqq/components/DashboardWidgets.tsx
index e26995f..9725d42 100644
--- a/src/qqq/components/DashboardWidgets.tsx
+++ b/src/qqq/components/DashboardWidgets.tsx
@@ -240,7 +240,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
)
@@ -320,6 +320,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit
reloadWidget(i, data)}
/>
)
}
diff --git a/src/qqq/pages/dashboards/Widgets/Components/DropdownMenu.tsx b/src/qqq/pages/dashboards/Widgets/Components/DropdownMenu.tsx
index 90ed2db..9447751 100644
--- a/src/qqq/pages/dashboards/Widgets/Components/DropdownMenu.tsx
+++ b/src/qqq/pages/dashboards/Widgets/Components/DropdownMenu.tsx
@@ -61,6 +61,9 @@ function DropdownMenu({label, dropdownOptions, onChangeCallback, sx}: Props): JS
sx={{...sx, cursor: "pointer"}}
onChange={handleOnChange}
renderInput={(params: any) => }
+ renderOption={(props, option: DropdownOption) => (
+ {option.label}
+ )}
/>
) : null
diff --git a/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx b/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
index f14e06a..9e7f579 100644
--- a/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
+++ b/src/qqq/pages/dashboards/Widgets/DefaultLineChart.tsx
@@ -68,6 +68,7 @@ const options = {
},
scales: {
y: {
+ beginAtZero: true,
grid: {
drawBorder: false,
display: true,
diff --git a/src/qqq/pages/dashboards/Widgets/FieldValueListWidget.tsx b/src/qqq/pages/dashboards/Widgets/FieldValueListWidget.tsx
index b868358..3fd38e6 100644
--- a/src/qqq/pages/dashboards/Widgets/FieldValueListWidget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/FieldValueListWidget.tsx
@@ -33,12 +33,22 @@ interface Props
{
title: string;
data: any;
+ reloadWidgetCallback?: (params: string) => void;
}
FieldValueListWidget.defaultProps = {};
-function FieldValueListWidget({title, data}: Props): JSX.Element
+function FieldValueListWidget({title, data, reloadWidgetCallback}: Props): JSX.Element
{
+ if(data?.dropdownNeedsSelectedText)
+ {
+ return (
+
+
+
+ );
+ }
+
if(!data.fields || !data.record)
{
const skeletons = [75, 50, 90];
@@ -69,7 +79,7 @@ function FieldValueListWidget({title, data}: Props): JSX.Element
const fieldIndentLevels = data.fieldIndentLevels ?? {};
return (
-
+
{
fields.map((field: QFieldMetaData, index: number) => (
diff --git a/src/qqq/pages/dashboards/Widgets/LineChart.tsx b/src/qqq/pages/dashboards/Widgets/LineChart.tsx
deleted file mode 100644
index 5256e0a..0000000
--- a/src/qqq/pages/dashboards/Widgets/LineChart.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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 Card from "@mui/material/Card";
-import Icon from "@mui/material/Icon";
-import {ReactNode, useMemo} from "react";
-import {Line} from "react-chartjs-2";
-import colors from "qqq/components/Temporary/colors";
-import MDBox from "qqq/components/Temporary/MDBox";
-import MDTypography from "qqq/components/Temporary/MDTypography";
-import configs from "qqq/pages/dashboards/Widgets/Configs/LineChartConfigs";
-
-
-///////////////////////////////////////////
-// structure of expected line chart data //
-///////////////////////////////////////////
-export interface LineChartData
-{
- labels: string[];
- datasets: {
- label: string;
- color?: "primary" | "secondary" | "info" | "success" | "warning" | "error" | "light" | "dark";
- data: number[];
- }[];
-};
-
-
-////////////////////////
-// line chart options //
-////////////////////////
-const options = {
- responsive: true,
- maintainAspectRatio: false,
- plugins: {
- legend: {
- display: false,
- },
- },
- interaction: {
- intersect: false,
- mode: "index",
- },
- scales: {
- y: {
- grid: {
- drawBorder: false,
- display: true,
- drawOnChartArea: true,
- drawTicks: false,
- borderDash: [5, 5],
- color: "rgba(255, 255, 255, .2)",
- },
- ticks: {
- display: true,
- color: "#f8f9fa",
- padding: 10,
- font: {
- size: 14,
- weight: 300,
- family: "Roboto",
- style: "normal",
- lineHeight: 2,
- },
- },
- },
- x: {
- grid: {
- drawBorder: false,
- display: false,
- drawOnChartArea: false,
- drawTicks: false,
- borderDash: [5, 5],
- },
- ticks: {
- display: true,
- color: "#f8f9fa",
- padding: 10,
- font: {
- size: 14,
- weight: 300,
- family: "Roboto",
- style: "normal",
- lineHeight: 2,
- },
- },
- },
- },
-};
-
-
-//////////////////////////////////////////
-// define input properties and defaults //
-//////////////////////////////////////////
-interface Props
-{
- icon?: {
- color?: "primary" | "secondary" | "info" | "success" | "warning" | "error" | "light" | "dark";
- component: ReactNode;
- };
- title?: string;
- description?: string | ReactNode;
- height?: string | number;
- chart: {
- labels: string[];
- datasets: {
- label: string;
- color?: "primary" | "secondary" | "info" | "success" | "warning" | "error" | "light" | "dark";
- data: number[];
- }[];
- };
-
- [key: string]: any;
-}
-
-LineChart.defaultProps = {
- icon: {color: "info", component: ""},
- title: "",
- description: "",
- height: "19.125rem",
-};
-
-function LineChart({icon, title, description, height, chart}: Props): JSX.Element
-{
- const chartDatasets = chart.datasets
- ? chart.datasets.map((dataset) => ({
- ...dataset,
- tension: 0,
- pointRadius: 3,
- borderWidth: 4,
- backgroundColor: "transparent",
- fill: true,
- pointBackgroundColor: colors[dataset.color]
- ? colors[dataset.color || "dark"].main
- : colors.dark.main,
- borderColor: colors[dataset.color]
- ? colors[dataset.color || "dark"].main
- : colors.dark.main,
- maxBarThickness: 6,
- }))
- : [];
-
- const {data} = configs(chart.labels || [], chartDatasets);
-
- const renderChart = (
-
- {title || description ? (
-
- {icon.component && (
-
- {icon.component}
-
- )}
-
- {title && {title}}
-
-
- {description}
-
-
-
-
- ) : null}
- {useMemo(
- () => (
-
-
-
- ),
- [chart, height]
- )}
-
- );
-
- return title || description ? {renderChart} : renderChart;
-}
-
-
-export default LineChart;
diff --git a/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx b/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
index 29d778a..e1f3a75 100644
--- a/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/ParentWidget.tsx
@@ -66,9 +66,7 @@ function ParentWidget({widgetIndex, label, data, reloadWidgetCallback, entityPri
{
const [childUrlParams, setChildUrlParams] = useState("");
const [qInstance, setQInstance] = useState(null as QInstance);
- const [dropdownData, setDropdownData] = useState([]);
const [widgets, setWidgets] = useState([] as any[]);
- const [counter, setCounter] = useState(0);
useEffect(() =>
{
diff --git a/src/qqq/pages/dashboards/Widgets/RecordGridWidget.tsx b/src/qqq/pages/dashboards/Widgets/RecordGridWidget.tsx
index d3b3b7d..f28dc74 100644
--- a/src/qqq/pages/dashboards/Widgets/RecordGridWidget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/RecordGridWidget.tsx
@@ -21,9 +21,11 @@
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
-import {DataGridPro} from "@mui/x-data-grid-pro";
+import {DataGridPro, GridCallbackDetails, GridRowParams, MuiEvent} from "@mui/x-data-grid-pro";
import React, {useEffect, useState} from "react";
+import {useNavigate} from "react-router-dom";
import DataGridUtils from "qqq/utils/DataGridUtils";
+import QClient from "qqq/utils/QClient";
import Widget, {AddNewRecordButton, HeaderLink, LabelComponent} from "./Widget";
interface Props
@@ -34,10 +36,13 @@ interface Props
RecordGridWidget.defaultProps = {};
+const qController = QClient.getInstance();
+
function RecordGridWidget({title, data}: Props): JSX.Element
{
const [rows, setRows] = useState([]);
const [columns, setColumns] = useState([]);
+ const navigate = useNavigate();
useEffect(() =>
{
@@ -59,6 +64,21 @@ function RecordGridWidget({title, data}: Props): JSX.Element
const childTablePath = data.tablePath + (data.tablePath.endsWith("/") ? "" : "/")
const columns = DataGridUtils.setupGridColumns(tableMetaData, columnsToRender, childTablePath);
+ ////////////////////////////////////////////////////////////////
+ // do not not show the foreign-key column of the parent table //
+ ////////////////////////////////////////////////////////////////
+ if(data.defaultValuesForNewChildRecords)
+ {
+ for (let i = 0; i < columns.length; i++)
+ {
+ if(data.defaultValuesForNewChildRecords[columns[i].field])
+ {
+ columns.splice(i, 1);
+ i--
+ }
+ }
+ }
+
setRows(rows);
setColumns(columns);
}
@@ -81,6 +101,21 @@ function RecordGridWidget({title, data}: Props): JSX.Element
labelAdditionalComponentsRight.push(new AddNewRecordButton(data.childTableMetaData, data.defaultValuesForNewChildRecords, "Add new", disabledFields))
}
+
+ const handleRowClick = (params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) =>
+ {
+ (async () =>
+ {
+ const qInstance = await qController.loadMetaData()
+ const tablePath = qInstance.getTablePathByName(data.childTableMetaData.name)
+ if(tablePath)
+ {
+ navigate(`${tablePath}/${params.id}`);
+ }
+ })();
+ };
+
+
return (
(params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd")}
+ onRowClick={handleRowClick}
// getRowHeight={() => "auto"} // maybe nice? wraps values in cells...
// components={{Toolbar: CustomToolbar, Pagination: CustomPagination, LoadingOverlay: Loading}}
// pinnedColumns={pinnedColumns}
@@ -106,7 +142,6 @@ function RecordGridWidget({title, data}: Props): JSX.Element
// checkboxSelection
// rowCount={totalRecords === null ? 0 : totalRecords}
// onPageSizeChange={handleRowsPerPageChange}
- // onRowClick={handleRowClick}
// onStateChange={handleStateChange}
// density={density}
// loading={loading}
diff --git a/src/qqq/pages/dashboards/Widgets/Widget.tsx b/src/qqq/pages/dashboards/Widgets/Widget.tsx
index e46e72d..7987752 100644
--- a/src/qqq/pages/dashboards/Widgets/Widget.tsx
+++ b/src/qqq/pages/dashboards/Widgets/Widget.tsx
@@ -155,7 +155,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element
{
const dropdown = component as Dropdown
return (
-
+
-
+