/* 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 {Capability} from "@kingsrook/qqq-frontend-core/lib/model/metaData/Capability";
import {QAppMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppMetaData";
import {QAppNodeType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppNodeType";
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
import {QReportMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QReportMetaData";
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData";
import {Icon, Typography} from "@mui/material";
import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import Divider from "@mui/material/Divider";
import Grid from "@mui/material/Grid";
import React, {useContext, useEffect, useState} from "react";
import {Link, useLocation} from "react-router-dom";
import QContext from "QContext";
import MDTypography from "qqq/components/legacy/MDTypography";
import ProcessLinkCard from "qqq/components/processes/ProcessLinkCard";
import DashboardWidgets from "qqq/components/widgets/DashboardWidgets";
import MiniStatisticsCard from "qqq/components/widgets/statistics/MiniStatisticsCard";
import BaseLayout from "qqq/layouts/BaseLayout";
import Client from "qqq/utils/qqq/Client";
const qController = Client.getInstance();
interface Props
{
app?: QAppMetaData;
}
function AppHome({app}: Props): JSX.Element
{
const [qInstance, setQInstance] = useState(null as QInstance);
const [tables, setTables] = useState([] as QTableMetaData[]);
const [processes, setProcesses] = useState([] as QProcessMetaData[]);
const [reports, setReports] = useState([] as QReportMetaData[]);
const [childApps, setChildApps] = useState([] as QAppMetaData[]);
const [tableCounts, setTableCounts] = useState(new Map());
const [tableCountNumbers, setTableCountNumbers] = useState(new Map());
const [tableCountTexts, setTableCountTexts] = useState(new Map() as any);
const [updatedTableCounts, setUpdatedTableCounts] = useState(new Date());
const [widgets, setWidgets] = useState([] as any[]);
const {pageHeader, setPageHeader} = useContext(QContext);
const location = useLocation();
useEffect(() =>
{
(async () =>
{
const newQInstance = await qController.loadMetaData();
setQInstance(newQInstance);
})();
}, []);
useEffect(() =>
{
setPageHeader(app.label);
if (!qInstance)
{
return;
}
const newTables: QTableMetaData[] = [];
const newProcesses: QProcessMetaData[] = [];
const newReports: QReportMetaData[] = [];
const newChildApps: QAppMetaData[] = [];
app.children.forEach((child) =>
{
switch (child.type)
{
// todo - filter out hidden
case QAppNodeType.TABLE:
newTables.push(qInstance.tables.get(child.name));
break;
case QAppNodeType.PROCESS:
newProcesses.push(qInstance.processes.get(child.name));
break;
case QAppNodeType.REPORT:
newReports.push(qInstance.reports.get(child.name));
break;
case QAppNodeType.APP:
newChildApps.push(qInstance.apps.get(child.name));
break;
default:
console.log(`Unexpected child type: ${child.type}`);
}
});
setTables(newTables);
setProcesses(newProcesses);
setReports(newReports);
setChildApps(newChildApps);
const tableCounts = new Map();
const tableCountNumbers = new Map();
const tableCountTexts = new Map();
newTables.forEach((table) =>
{
tableCounts.set(table.name, {isLoading: true, value: null});
setTimeout(async () =>
{
const tableMetaData = await qController.loadTableMetaData(table.name);
let countResult = null;
if(tableMetaData.capabilities.has(Capability.TABLE_COUNT) && tableMetaData.readPermission)
{
try
{
[countResult] = await qController.count(table.name);
if (countResult !== null && countResult !== undefined)
{
tableCountNumbers.set(table.name, countResult.toLocaleString());
tableCountTexts.set(table.name, countResult === 1 ? "total record" : "total records");
}
else
{
tableCountNumbers.set(table.name, "–");
tableCountTexts.set(table.name, " ");
}
}
catch(e)
{
console.log("Caught: " + e);
tableCountNumbers.set(table.name, "–");
tableCountTexts.set(table.name, " ");
}
}
else
{
tableCountNumbers.set(table.name, "–");
tableCountTexts.set(table.name, " ");
}
tableCounts.set(table.name, {isLoading: false, value: countResult});
setTableCounts(tableCounts);
setTableCountNumbers(tableCountNumbers);
setTableCountTexts(tableCountTexts);
setUpdatedTableCounts(new Date());
}, 1);
});
setTableCounts(tableCounts);
if (app.widgets)
{
///////////////////////////
// load widget meta data //
///////////////////////////
const matchingWidgets: QWidgetMetaData[] = [];
app.widgets.forEach((widgetName) =>
{
const widget = qInstance.widgets.get(widgetName);
matchingWidgets.push(widget);
});
setWidgets(matchingWidgets);
}
}, [qInstance, location]);
const widgetCount = widgets ? widgets.length : 0;
// eslint-disable-next-line no-nested-ternary
const tileSizeLg = 3;
const hasTablePermission = (tableName: string) =>
{
return tables.find(t => t.name === tableName && (t.readPermission || t.insertPermission || t.editPermission || t.deletePermission));
};
const hasProcessPermission = (processName: string) =>
{
return processes.find(p => p.name === processName && p.hasPermission);
};
const hasReportPermission = (reportName: string) =>
{
return reports.find(r => r.name === reportName && r.hasPermission);
};
return (
{app.widgets && (
)}
{
app.sections ? (
{app.sections.map((section) => (
{
section.icon &&
(
section.icon.path &&
)
}
{section.label}
{
section.processes ? (
Actions
) : null
}
{
section.processes ? (
{
section.processes.map((processName) =>
{
let process = app.childMap.get(processName);
return (
{hasProcessPermission(processName) ?
:
}
);
})
}
) : null
}
{
section.processes && section.reports ? (
) : null
}
{
section.reports ? (
Reports
) : null
}
{
section.reports ? (
{
section.reports.map((reportName) =>
{
let report = app.childMap.get(reportName);
return (
{hasReportPermission(reportName) ?
:
}
);
})
}
) : null
}
{
section.reports && section.tables ? (
) : null
}
{
section.tables ? (
Data
) : null
}
{
section.tables ? (
{
section.tables.map((tableName) =>
{
let table = app.childMap.get(tableName);
return (
{hasTablePermission(tableName) ?
{table.iconName || app.iconName}}}
/>
:
{table.iconName || app.iconName}}}
isDisabled={true}
/>
}
);
})
}
) : null
}
))}
) : null
}
);
}
AppHome.defaultProps = {
app: null,
};
export default AppHome;