mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
QQQ-32 udpating styles on query; record list & view sections; record labels; apps in nav; updated breadcrumb; updated navigation
This commit is contained in:
264
src/App.tsx
264
src/App.tsx
@ -1,14 +1,10 @@
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
JSXElementConstructor,
|
||||
Key,
|
||||
ReactElement,
|
||||
JSXElementConstructor, Key, ReactElement, useEffect, useState,
|
||||
} from "react";
|
||||
|
||||
// react-router components
|
||||
import {
|
||||
Routes, Route, Navigate, useLocation,
|
||||
Navigate, Route, Routes, useLocation,
|
||||
} from "react-router-dom";
|
||||
|
||||
import {useAuth0} from "@auth0/auth0-react";
|
||||
@ -33,23 +29,28 @@ import theme from "assets/theme";
|
||||
import themeDark from "assets/theme-dark";
|
||||
|
||||
// Material Dashboard 2 PRO React TS contexts
|
||||
import {useMaterialUIController, setMiniSidenav, setOpenConfigurator} from "context";
|
||||
import {setMiniSidenav, setOpenConfigurator, useMaterialUIController} from "context";
|
||||
|
||||
// Images
|
||||
import nfLogo from "assets/images/nutrifresh_one_icon_white.png";
|
||||
import {Md5} from "ts-md5/dist/md5";
|
||||
import {useCookies} from "react-cookie";
|
||||
import {QAppMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppMetaData";
|
||||
import EntityCreate from "./qqq/pages/entity-create";
|
||||
import EntityList from "./qqq/pages/entity-list";
|
||||
import EntityView from "./qqq/pages/entity-view";
|
||||
import EntityEdit from "./qqq/pages/entity-edit";
|
||||
import ProcessRun from "./qqq/pages/process-run";
|
||||
import AppHome from "qqq/pages/app-home";
|
||||
import MDAvatar from "./components/MDAvatar";
|
||||
import ProfileOverview from "./layouts/pages/profile/profile-overview";
|
||||
import Settings from "./layouts/pages/account/settings";
|
||||
import Analytics from "./layouts/dashboards/analytics";
|
||||
import Sales from "./layouts/dashboards/sales";
|
||||
import QClient from "./qqq/utils/QClient";
|
||||
import {QAppNodeType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QAppNodeType";
|
||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||
import QProcessUtils from "qqq/utils/QProcessUtils";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define the parts of the nav that are static - before the qqq tables etc get dynamic added //
|
||||
@ -79,7 +80,6 @@ function getStaticRoutes()
|
||||
],
|
||||
},
|
||||
{type: "divider", key: "divider-1"},
|
||||
{type: "title", title: "Tables", key: "title-docs"},
|
||||
];
|
||||
}
|
||||
|
||||
@ -134,7 +134,10 @@ export default function App()
|
||||
const {pathname} = useLocation();
|
||||
|
||||
const [needToLoadRoutes, setNeedToLoadRoutes] = useState(true);
|
||||
const [routes, setRoutes] = useState(getStaticRoutes());
|
||||
const [sideNavRoutes, setSideNavRoutes] = useState(getStaticRoutes());
|
||||
const [appRoutes, setAppRoutes] = useState(null as any);
|
||||
|
||||
const dynamicAppChildElement = <AppHome />;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// load qqq meta data to make more routes //
|
||||
@ -149,32 +152,149 @@ export default function App()
|
||||
|
||||
(async () =>
|
||||
{
|
||||
function addAppToSideNavList(app: QAppMetaData, appList: any[], parentPath: string, depth: number)
|
||||
{
|
||||
const path = `${parentPath}/${app.name}`;
|
||||
if (app.type !== QAppNodeType.APP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (app.type === QAppNodeType.APP && depth <= 2)
|
||||
{
|
||||
const childList: any[] = [];
|
||||
app.children.forEach((child: QAppMetaData) =>
|
||||
{
|
||||
addAppToSideNavList(child, childList, path, depth + 1);
|
||||
});
|
||||
|
||||
if (childList.length === 0)
|
||||
{
|
||||
if (depth === 0)
|
||||
{
|
||||
/////////////////////////////////////////////////////
|
||||
// at level 0, the entry must always be a collapse //
|
||||
/////////////////////////////////////////////////////
|
||||
appList.push({
|
||||
type: "collapse",
|
||||
name: app.label,
|
||||
key: app.name,
|
||||
route: path,
|
||||
icon: <Icon fontSize="medium">{app.iconName}</Icon>,
|
||||
noCollapse: true,
|
||||
component: <AppHome />,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
appList.push({
|
||||
name: app.label,
|
||||
key: app.name,
|
||||
route: path,
|
||||
icon: <Icon fontSize="medium">{app.iconName}</Icon>,
|
||||
component: <AppHome />,
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
appList.push({
|
||||
type: "collapse",
|
||||
name: app.label,
|
||||
key: app.name,
|
||||
dropdown: true,
|
||||
icon: <Icon fontSize="medium">{app.iconName}</Icon>,
|
||||
collapse: childList,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addAppToAppRoutesList(metaData: QInstance, app: QAppMetaData, routeList: any[], parentPath: string, depth: number)
|
||||
{
|
||||
const path = `${parentPath}/${app.name}`;
|
||||
if (app.type === QAppNodeType.APP)
|
||||
{
|
||||
app.children.forEach((child: QAppMetaData) =>
|
||||
{
|
||||
addAppToAppRoutesList(metaData, child, routeList, path, depth + 1);
|
||||
});
|
||||
|
||||
routeList.push({
|
||||
name: `${app.label}`,
|
||||
key: app.name,
|
||||
route: path,
|
||||
component: <AppHome app={app} />,
|
||||
});
|
||||
}
|
||||
else if (app.type === QAppNodeType.TABLE)
|
||||
{
|
||||
const table = metaData.tables.get(app.name);
|
||||
routeList.push({
|
||||
name: `${app.label}`,
|
||||
key: app.name,
|
||||
route: path,
|
||||
component: <EntityList table={table} />,
|
||||
});
|
||||
|
||||
routeList.push({
|
||||
name: `${app.label} Create`,
|
||||
key: `${app.name}.create`,
|
||||
route: `${path}/create`,
|
||||
component: <EntityCreate table={table} />,
|
||||
});
|
||||
|
||||
routeList.push({
|
||||
name: `${app.label} View`,
|
||||
key: `${app.name}.view`,
|
||||
route: `${path}/:id`,
|
||||
component: <EntityView table={table} />,
|
||||
});
|
||||
|
||||
routeList.push({
|
||||
name: `${app.label}`,
|
||||
key: `${app.name}.edit`,
|
||||
route: `${path}/:id/edit`,
|
||||
component: <EntityEdit table={table} />,
|
||||
});
|
||||
|
||||
const processesForTable = QProcessUtils.getProcessesForTable(metaData, table.name, true);
|
||||
processesForTable.forEach((process) =>
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// special provision for the standard bulk processes - strip the table name from the process name //
|
||||
// todo - this var isn't used - is this needed?
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
let processName = process.name;
|
||||
if (processName.startsWith(`${process.tableName}.`))
|
||||
{
|
||||
processName = processName.replace(`${process.tableName}.`, "");
|
||||
}
|
||||
|
||||
routeList.push({
|
||||
name: process.label,
|
||||
key: process.name,
|
||||
route: `${path}/${process.name}`,
|
||||
component: <ProcessRun process={process} />,
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (app.type === QAppNodeType.PROCESS)
|
||||
{
|
||||
const process = metaData.processes.get(app.name);
|
||||
routeList.push({
|
||||
name: `${app.label}`,
|
||||
key: app.name,
|
||||
route: path,
|
||||
component: <ProcessRun process={process} />,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const metaData = await QClient.getInstance().loadMetaData();
|
||||
|
||||
// get the keys sorted
|
||||
const keys = [...metaData.tables.keys()].sort((a, b): number =>
|
||||
{
|
||||
const labelA = metaData.tables.get(a).label;
|
||||
const labelB = metaData.tables.get(b).label;
|
||||
return (labelA.localeCompare(labelB));
|
||||
});
|
||||
const tableList = [] as any[];
|
||||
keys.forEach((key) =>
|
||||
{
|
||||
const table = metaData.tables.get(key);
|
||||
if (!table.isHidden)
|
||||
{
|
||||
tableList.push({
|
||||
name: `${table.label}`,
|
||||
key: table.name,
|
||||
route: `/${table.name}`,
|
||||
component: <EntityList table={table} />,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let profileRoute = {};
|
||||
const gravatarBase = "http://www.gravatar.com/avatar/";
|
||||
const hash = Md5.hashStr(user.email);
|
||||
@ -200,19 +320,25 @@ export default function App()
|
||||
],
|
||||
};
|
||||
|
||||
const tables = {
|
||||
type: "collapse",
|
||||
name: "Tables",
|
||||
key: "tables",
|
||||
icon: <Icon fontSize="medium">dashboard</Icon>,
|
||||
collapse: tableList,
|
||||
};
|
||||
const sideNavAppList = [] as any[];
|
||||
const appRoutesList = [] as any[];
|
||||
for (let i = 0; i < metaData.appTree.length; i++)
|
||||
{
|
||||
const app = metaData.appTree[i];
|
||||
addAppToSideNavList(app, sideNavAppList, "", 0);
|
||||
addAppToAppRoutesList(metaData, app, appRoutesList, "", 0);
|
||||
}
|
||||
|
||||
const newDynamicRoutes = getStaticRoutes();
|
||||
const newSideNavRoutes = getStaticRoutes();
|
||||
// @ts-ignore
|
||||
newDynamicRoutes.unshift(profileRoute);
|
||||
newDynamicRoutes.push(tables);
|
||||
setRoutes(newDynamicRoutes);
|
||||
newSideNavRoutes.unshift(profileRoute);
|
||||
for (let i = 0; i < sideNavAppList.length; i++)
|
||||
{
|
||||
newSideNavRoutes.push(sideNavAppList[i]);
|
||||
}
|
||||
|
||||
setSideNavRoutes(newSideNavRoutes);
|
||||
setAppRoutes(appRoutesList);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@ -306,38 +432,28 @@ export default function App()
|
||||
</MDBox>
|
||||
);
|
||||
|
||||
const entityListElement = <EntityList />;
|
||||
const entityCreateElement = <EntityCreate />;
|
||||
const entityViewElement = <EntityView />;
|
||||
const entityEditElement = <EntityEdit />;
|
||||
const processRunElement = <ProcessRun />;
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={darkMode ? themeDark : theme}>
|
||||
<CssBaseline />
|
||||
{layout === "dashboard" && (
|
||||
<>
|
||||
<Sidenav
|
||||
color={sidenavColor}
|
||||
brand={nfLogo}
|
||||
brandName="Nutrifresh One"
|
||||
routes={routes}
|
||||
onMouseEnter={handleOnMouseEnter}
|
||||
onMouseLeave={handleOnMouseLeave}
|
||||
/>
|
||||
<Configurator />
|
||||
{configsButton}
|
||||
</>
|
||||
)}
|
||||
<Routes>
|
||||
<Route path="*" element={<Navigate to="/dashboards/analytics" />} />
|
||||
<Route path="/:tableName" element={entityListElement} key="entity-list" />
|
||||
<Route path="/:tableName/create" element={entityCreateElement} key="entity-create" />
|
||||
<Route path="/processes/:processName" element={processRunElement} key="process-run" />
|
||||
<Route path="/:tableName/:id" element={entityViewElement} key="entity-view" />
|
||||
<Route path="/:tableName/:id/edit" element={entityEditElement} key="entity-edit" />
|
||||
{getRoutes(routes)}
|
||||
</Routes>
|
||||
</ThemeProvider>
|
||||
appRoutes && (
|
||||
<ThemeProvider theme={darkMode ? themeDark : theme}>
|
||||
<CssBaseline />
|
||||
{layout === "dashboard" && (
|
||||
<>
|
||||
<Sidenav
|
||||
color={sidenavColor}
|
||||
brand={nfLogo}
|
||||
brandName="Nutrifresh One"
|
||||
routes={sideNavRoutes}
|
||||
onMouseEnter={handleOnMouseEnter}
|
||||
onMouseLeave={handleOnMouseLeave}
|
||||
/>
|
||||
<Configurator />
|
||||
</>
|
||||
)}
|
||||
<Routes>
|
||||
{appRoutes && getRoutes(appRoutes)}
|
||||
{sideNavRoutes && getRoutes(sideNavRoutes)}
|
||||
</Routes>
|
||||
</ThemeProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user