mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
SPRINT-12: added skeletons throughout widgets, fixed page header under breadcrumb, misc other improvements
This commit is contained in:
@ -36,6 +36,7 @@ import {Md5} from "ts-md5/dist/md5";
|
|||||||
import {setMiniSidenav, setOpenConfigurator, useMaterialUIController} from "context";
|
import {setMiniSidenav, setOpenConfigurator, useMaterialUIController} from "context";
|
||||||
import Settings from "layouts/pages/account/settings";
|
import Settings from "layouts/pages/account/settings";
|
||||||
import ProfileOverview from "layouts/pages/profile/profile-overview";
|
import ProfileOverview from "layouts/pages/profile/profile-overview";
|
||||||
|
import QContext from "QContext";
|
||||||
import Sidenav from "qqq/components/Sidenav";
|
import Sidenav from "qqq/components/Sidenav";
|
||||||
import Configurator from "qqq/components/Temporary/Configurator";
|
import Configurator from "qqq/components/Temporary/Configurator";
|
||||||
import MDAvatar from "qqq/components/Temporary/MDAvatar";
|
import MDAvatar from "qqq/components/Temporary/MDAvatar";
|
||||||
@ -469,8 +470,15 @@ export default function App()
|
|||||||
</MDBox>
|
</MDBox>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [pageHeader, setPageHeader] = useState("");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
appRoutes && (
|
appRoutes && (
|
||||||
|
<QContext.Provider value={{
|
||||||
|
pageHeader: pageHeader,
|
||||||
|
setPageHeader: (header: string) => setPageHeader(header)
|
||||||
|
}}>
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
{layout === "dashboard" && (
|
{layout === "dashboard" && (
|
||||||
@ -494,6 +502,7 @@ export default function App()
|
|||||||
{profileRoutes && getRoutes([profileRoutes])}
|
{profileRoutes && getRoutes([profileRoutes])}
|
||||||
</Routes>
|
</Routes>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
</QContext.Provider>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
36
src/QContext.tsx
Normal file
36
src/QContext.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {createContext} from "react";
|
||||||
|
|
||||||
|
|
||||||
|
interface QContext
|
||||||
|
{
|
||||||
|
pageHeader: string;
|
||||||
|
setPageHeader?: (header: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultState = {
|
||||||
|
pageHeader: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
const QContext = createContext<QContext>(defaultState);
|
||||||
|
export default QContext;
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData";
|
import {QWidgetMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QWidgetMetaData";
|
||||||
|
import {Skeleton} from "@mui/material";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import parse from "html-react-parser";
|
import parse from "html-react-parser";
|
||||||
@ -73,6 +74,7 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceUpdate();
|
||||||
for (let i = 0; i < widgetMetaDataList.length; i++)
|
for (let i = 0; i < widgetMetaDataList.length; i++)
|
||||||
{
|
{
|
||||||
widgetData[i] = {};
|
widgetData[i] = {};
|
||||||
@ -100,17 +102,19 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
};
|
};
|
||||||
|
|
||||||
const widgetCount = widgetMetaDataList ? widgetMetaDataList.length : 0;
|
const widgetCount = widgetMetaDataList ? widgetMetaDataList.length : 0;
|
||||||
|
console.log(JSON.stringify(widgetMetaDataList));
|
||||||
|
console.log(widgetCount);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
widgetCount > 0 ? (
|
widgetCount > 0 ? (
|
||||||
<Grid item xs={12} lg={12}>
|
<Grid container spacing={3} pb={4}>
|
||||||
<Grid container spacing={3}>
|
|
||||||
{
|
{
|
||||||
widgetMetaDataList.map((widgetMetaData, i) => (
|
widgetMetaDataList.map((widgetMetaData, i) => (
|
||||||
<Grid key={`${i}`} item xs={12} lg={12}>
|
<Grid key={`${i}`} item lg={widgetMetaData.gridColumns ? widgetMetaData.gridColumns : 12} xs={12}>
|
||||||
{
|
{
|
||||||
widgetMetaData.type === "table" && (
|
widgetMetaData.type === "table" && (
|
||||||
widgetData && widgetData[i] ? (
|
widgetData && widgetData[i] ? (
|
||||||
|
<MDBox>
|
||||||
<TableCard
|
<TableCard
|
||||||
color="info"
|
color="info"
|
||||||
title={widgetMetaData.label}
|
title={widgetMetaData.label}
|
||||||
@ -122,6 +126,7 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
dropdownOnChange={handleDropdownOnChange}
|
dropdownOnChange={handleDropdownOnChange}
|
||||||
widgetIndex={i}
|
widgetIndex={i}
|
||||||
/>
|
/>
|
||||||
|
</MDBox>
|
||||||
) : null
|
) : null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -145,17 +150,17 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
widgetMetaData.type === "html" && (
|
widgetMetaData.type === "html" && (
|
||||||
<MDBox pb={3}>
|
<MDBox>
|
||||||
<Card sx={{marginTop: "0px", paddingTop: "0px"}}>
|
<Card sx={{alignContents: "stretch", marginTop: "0px", paddingTop: "0px"}}>
|
||||||
<MDBox padding="1rem">
|
<MDBox padding="1rem">
|
||||||
<MDTypography variant="h5" textTransform="capitalize">
|
<MDTypography variant="h5" textTransform="capitalize">
|
||||||
{widgetMetaData.label}
|
{widgetMetaData.label}
|
||||||
</MDTypography>
|
</MDTypography>
|
||||||
<MDTypography component="div" variant="button" color="text" fontWeight="light">
|
<MDTypography component="div" variant="button" color="text" fontWeight="light">
|
||||||
{
|
{
|
||||||
widgetData && widgetData[i] && widgetData[i].html && (
|
widgetData && widgetData[i] && widgetData[i].html ? (
|
||||||
parse(widgetData[i].html)
|
parse(widgetData[i].html)
|
||||||
)
|
) : <Skeleton />
|
||||||
}
|
}
|
||||||
</MDTypography>
|
</MDTypography>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
@ -165,23 +170,13 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
widgetMetaData.type === "multiStatistics" && (
|
widgetMetaData.type === "multiStatistics" && (
|
||||||
widgetData && widgetData[i] ? (
|
|
||||||
<MultiStatisticsCard
|
<MultiStatisticsCard
|
||||||
color="info"
|
color="info"
|
||||||
title={widgetData[i].title}
|
title={widgetMetaData.label}
|
||||||
data={widgetData[i]}
|
data={widgetData[i]}
|
||||||
/>
|
/>
|
||||||
) : null
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Grid>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} lg={widgetCount === 1 ? 3 : 6}>
|
|
||||||
{
|
|
||||||
widgetMetaDataList.map((widgetMetaData, i) => (
|
|
||||||
<Grid key={`${i}`} item xs={12} lg={widgetCount === 1 ? 12 : 6}>
|
|
||||||
{
|
{
|
||||||
widgetMetaData.type === "quickSightChart" && (
|
widgetMetaData.type === "quickSightChart" && (
|
||||||
widgetData && widgetData[i] ? (
|
widgetData && widgetData[i] ? (
|
||||||
@ -233,7 +228,6 @@ function DashboardWidgets({widgetMetaDataList, entityPrimaryKey}: Props): JSX.El
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
|
||||||
) : null
|
) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,10 @@ import Card from "@mui/material/Card";
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Icon from "@mui/material/Icon";
|
import Icon from "@mui/material/Icon";
|
||||||
import {Form, Formik} from "formik";
|
import {Form, Formik} from "formik";
|
||||||
import React, {useReducer, useState} from "react";
|
import React, {useContext, useReducer, useState} from "react";
|
||||||
import {useLocation, useNavigate, useParams} from "react-router-dom";
|
import {useLocation, useNavigate, useParams} from "react-router-dom";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
import QContext from "QContext";
|
||||||
import {QCancelButton, QSaveButton} from "qqq/components/QButtons";
|
import {QCancelButton, QSaveButton} from "qqq/components/QButtons";
|
||||||
import QDynamicForm from "qqq/components/QDynamicForm";
|
import QDynamicForm from "qqq/components/QDynamicForm";
|
||||||
import DynamicFormUtils from "qqq/components/QDynamicForm/utils/DynamicFormUtils";
|
import DynamicFormUtils from "qqq/components/QDynamicForm/utils/DynamicFormUtils";
|
||||||
@ -54,6 +55,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
const tableNameParam = useParams().tableName;
|
const tableNameParam = useParams().tableName;
|
||||||
const tableName = table === null ? tableNameParam : table.name;
|
const tableName = table === null ? tableNameParam : table.name;
|
||||||
|
|
||||||
|
const [formTitle, setFormTitle] = useState("");
|
||||||
const [validations, setValidations] = useState({});
|
const [validations, setValidations] = useState({});
|
||||||
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
||||||
const [formFields, setFormFields] = useState(null as Map<string, any>);
|
const [formFields, setFormFields] = useState(null as Map<string, any>);
|
||||||
@ -69,6 +71,8 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
const [tableSections, setTableSections] = useState(null as QTableSection[]);
|
const [tableSections, setTableSections] = useState(null as QTableSection[]);
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
@ -79,7 +83,6 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
formData.touched = touched;
|
formData.touched = touched;
|
||||||
formData.errors = errors;
|
formData.errors = errors;
|
||||||
formData.formFields = {};
|
formData.formFields = {};
|
||||||
console.log(formFields);
|
|
||||||
for (let i = 0; i < formFields.length; i++)
|
for (let i = 0; i < formFields.length; i++)
|
||||||
{
|
{
|
||||||
formData.formFields[formFields[i].name] = formFields[i];
|
formData.formFields[formFields[i].name] = formFields[i];
|
||||||
@ -121,6 +124,8 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
const record = await qController.get(tableName, id);
|
const record = await qController.get(tableName, id);
|
||||||
setRecord(record);
|
setRecord(record);
|
||||||
|
setFormTitle(`Edit ${tableMetaData?.label}: ${record?.recordLabel}`);
|
||||||
|
setPageHeader(`Edit ${tableMetaData?.label}: ${record?.recordLabel}`);
|
||||||
|
|
||||||
tableMetaData.fields.forEach((fieldMetaData, key) =>
|
tableMetaData.fields.forEach((fieldMetaData, key) =>
|
||||||
{
|
{
|
||||||
@ -129,6 +134,11 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
|
|
||||||
setFormValues(formValues);
|
setFormValues(formValues);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFormTitle(`Creating New ${tableMetaData?.label}`);
|
||||||
|
setPageHeader(`Creating New ${tableMetaData?.label}`);
|
||||||
|
}
|
||||||
setInitialValues(initialValues);
|
setInitialValues(initialValues);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
@ -255,19 +265,6 @@ function EntityForm({table, id}: Props): JSX.Element
|
|||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
let formTitle = "";
|
|
||||||
if (tableMetaData)
|
|
||||||
{
|
|
||||||
if (id == null)
|
|
||||||
{
|
|
||||||
formTitle = `Create new ${tableMetaData?.label}`;
|
|
||||||
}
|
|
||||||
else if (record != null)
|
|
||||||
{
|
|
||||||
formTitle = `Edit ${tableMetaData?.label}: ${record?.recordLabel}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const formId = id != null ? `edit-${tableMetaData?.name}-form` : `create-${tableMetaData?.name}-form`;
|
const formId = id != null ? `edit-${tableMetaData?.name}-form` : `create-${tableMetaData?.name}-form`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
import {Breadcrumbs as MuiBreadcrumbs} from "@mui/material";
|
import {Breadcrumbs as MuiBreadcrumbs} from "@mui/material";
|
||||||
import Icon from "@mui/material/Icon";
|
import Icon from "@mui/material/Icon";
|
||||||
import {ReactNode} from "react";
|
import {ReactNode, useContext} from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
|
import QContext from "QContext";
|
||||||
import MDBox from "qqq/components/Temporary/MDBox";
|
import MDBox from "qqq/components/Temporary/MDBox";
|
||||||
import MDTypography from "qqq/components/Temporary/MDTypography";
|
import MDTypography from "qqq/components/Temporary/MDTypography";
|
||||||
|
|
||||||
@ -56,11 +57,10 @@ export const routeToLabel = (route: string): string =>
|
|||||||
return (label);
|
return (label);
|
||||||
};
|
};
|
||||||
|
|
||||||
function QBreadcrumbs({
|
function QBreadcrumbs({icon, title, route, light}: Props): JSX.Element
|
||||||
icon, title, route, light,
|
|
||||||
}: Props): JSX.Element
|
|
||||||
{
|
{
|
||||||
const routes: string[] | any = route.slice(0, -1);
|
const routes: string[] | any = route.slice(0, -1);
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
let pageTitle = "Nutrifresh One";
|
let pageTitle = "Nutrifresh One";
|
||||||
const fullRoutes: string[] = [];
|
const fullRoutes: string[] = [];
|
||||||
@ -118,7 +118,7 @@ function QBreadcrumbs({
|
|||||||
color={light ? "white" : "dark"}
|
color={light ? "white" : "dark"}
|
||||||
noWrap
|
noWrap
|
||||||
>
|
>
|
||||||
{routeToLabel(title)}
|
{pageHeader}
|
||||||
</MDTypography>
|
</MDTypography>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
);
|
);
|
||||||
|
@ -38,9 +38,11 @@ interface Props
|
|||||||
value: any;
|
value: any;
|
||||||
type: string;
|
type: string;
|
||||||
isEditable?: boolean;
|
isEditable?: boolean;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|
||||||
bulkEditMode?: boolean;
|
bulkEditMode?: boolean;
|
||||||
bulkEditSwitchChangeHandler?: any
|
bulkEditSwitchChangeHandler?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
function QDynamicFormField({
|
function QDynamicFormField({
|
||||||
@ -71,11 +73,21 @@ function QDynamicFormField({
|
|||||||
inputProps.endAdornment = <InputAdornment position="end">%</InputAdornment>;
|
inputProps.endAdornment = <InputAdornment position="end">%</InputAdornment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const handleOnWheel = (e) =>
|
||||||
|
{
|
||||||
|
if (type.toLowerCase().match("number"))
|
||||||
|
{
|
||||||
|
e.target.blur();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const field = () =>
|
const field = () =>
|
||||||
(type == "checkbox" ?
|
(type == "checkbox" ?
|
||||||
<QBooleanFieldSwitch name={name} label={label} value={value} isDisabled={isDisabled} /> :
|
<QBooleanFieldSwitch name={name} label={label} value={value} isDisabled={isDisabled} /> :
|
||||||
<>
|
<>
|
||||||
<Field {...rest} name={name} type={type} as={MDInput} variant="standard" label={label} InputLabelProps={inputLabelProps} InputProps={inputProps} fullWidth disabled={isDisabled} />
|
<Field {...rest} onWheel={handleOnWheel} name={name} type={type} as={MDInput} variant="standard" label={label} InputLabelProps={inputLabelProps} InputProps={inputProps} fullWidth disabled={isDisabled} />
|
||||||
<MDBox mt={0.75}>
|
<MDBox mt={0.75}>
|
||||||
<MDTypography component="div" variant="caption" color="error" fontWeight="regular">
|
<MDTypography component="div" variant="caption" color="error" fontWeight="regular">
|
||||||
{!isDisabled && <div className="fieldErrorMessage"><ErrorMessage name={name} /></div>}
|
{!isDisabled && <div className="fieldErrorMessage"><ErrorMessage name={name} /></div>}
|
||||||
|
@ -29,8 +29,9 @@ import {Icon} from "@mui/material";
|
|||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Divider from "@mui/material/Divider";
|
import Divider from "@mui/material/Divider";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
import {Link, useLocation} from "react-router-dom";
|
import {Link, useLocation} from "react-router-dom";
|
||||||
|
import QContext from "QContext";
|
||||||
import BaseLayout from "qqq/components/BaseLayout";
|
import BaseLayout from "qqq/components/BaseLayout";
|
||||||
import DashboardWidgets from "qqq/components/DashboardWidgets";
|
import DashboardWidgets from "qqq/components/DashboardWidgets";
|
||||||
import ProcessLinkCard from "qqq/components/ProcessLinkCard";
|
import ProcessLinkCard from "qqq/components/ProcessLinkCard";
|
||||||
@ -57,6 +58,8 @@ function AppHome({app}: Props): JSX.Element
|
|||||||
const [updatedTableCounts, setUpdatedTableCounts] = useState(new Date());
|
const [updatedTableCounts, setUpdatedTableCounts] = useState(new Date());
|
||||||
const [widgets, setWidgets] = useState([] as any[]);
|
const [widgets, setWidgets] = useState([] as any[]);
|
||||||
|
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
@ -70,6 +73,8 @@ function AppHome({app}: Props): JSX.Element
|
|||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
setPageHeader(app.label);
|
||||||
|
|
||||||
if (!qInstance)
|
if (!qInstance)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -153,11 +158,9 @@ function AppHome({app}: Props): JSX.Element
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<MDBox mt={4}>
|
<MDBox mt={4} mb={4}>
|
||||||
{app.widgets && (
|
{app.widgets && (
|
||||||
<Grid container spacing={3}>
|
|
||||||
<DashboardWidgets widgetMetaDataList={widgets} />
|
<DashboardWidgets widgetMetaDataList={widgets} />
|
||||||
</Grid>
|
|
||||||
)}
|
)}
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,8 @@ import {Icon} from "@mui/material";
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Menu from "@mui/material/Menu";
|
import Menu from "@mui/material/Menu";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
|
import QContext from "QContext";
|
||||||
import DashboardLayout from "qqq/components/DashboardLayout";
|
import DashboardLayout from "qqq/components/DashboardLayout";
|
||||||
import Footer from "qqq/components/Footer";
|
import Footer from "qqq/components/Footer";
|
||||||
import Navbar from "qqq/components/Navbar";
|
import Navbar from "qqq/components/Navbar";
|
||||||
@ -115,12 +116,15 @@ function CarrierPerformance(): JSX.Element
|
|||||||
|
|
||||||
const [qInstance, setQInstance] = useState(null as QInstance);
|
const [qInstance, setQInstance] = useState(null as QInstance);
|
||||||
const [dataLoaded, setDataLoaded] = useState(false);
|
const [dataLoaded, setDataLoaded] = useState(false);
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// load meta data first //
|
// load meta data first //
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
setPageHeader("Carrier Performance");
|
||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const newQInstance = await qController.loadMetaData();
|
const newQInstance = await qController.loadMetaData();
|
||||||
|
@ -23,7 +23,8 @@ import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstan
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Icon from "@mui/material/Icon";
|
import Icon from "@mui/material/Icon";
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import {useEffect, useState} from "react";
|
import {useContext, useEffect, useState} from "react";
|
||||||
|
import QContext from "QContext";
|
||||||
import DashboardLayout from "qqq/components/DashboardLayout";
|
import DashboardLayout from "qqq/components/DashboardLayout";
|
||||||
import Footer from "qqq/components/Footer";
|
import Footer from "qqq/components/Footer";
|
||||||
import Navbar from "qqq/components/Navbar";
|
import Navbar from "qqq/components/Navbar";
|
||||||
@ -66,6 +67,7 @@ function Overview(): JSX.Element
|
|||||||
const [warehouseData, setWarehouseData] = useState([] as LocationCardData[]);
|
const [warehouseData, setWarehouseData] = useState([] as LocationCardData[]);
|
||||||
|
|
||||||
const [qInstance, setQInstance] = useState(null as QInstance);
|
const [qInstance, setQInstance] = useState(null as QInstance);
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
@ -73,6 +75,8 @@ function Overview(): JSX.Element
|
|||||||
//////////////////////////
|
//////////////////////////
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
setPageHeader("Overview");
|
||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const newQInstance = await qController.loadMetaData();
|
const newQInstance = await qController.loadMetaData();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {Skeleton} from "@mui/material";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Divider from "@mui/material/Divider";
|
import Divider from "@mui/material/Divider";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
@ -76,7 +77,7 @@ function MultiStatisticsCard({title, data}: Props): JSX.Element
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
{
|
{
|
||||||
data && data.statisticsGroupData && (
|
data && data.statisticsGroupData ? (
|
||||||
data.statisticsGroupData.map((statisticsGroup, i1) =>
|
data.statisticsGroupData.map((statisticsGroup, i1) =>
|
||||||
<Grid key={`statgroup-${i1}`} item xs={3} lg={3} sx={{textAlign: "center"}}>
|
<Grid key={`statgroup-${i1}`} item xs={3} lg={3} sx={{textAlign: "center"}}>
|
||||||
<MDBox p={3} pt={3} sx={{alignItems: "center"}}>
|
<MDBox p={3} pt={3} sx={{alignItems: "center"}}>
|
||||||
@ -112,6 +113,34 @@ function MultiStatisticsCard({title, data}: Props): JSX.Element
|
|||||||
</MDBox>
|
</MDBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
)
|
)
|
||||||
|
) : (
|
||||||
|
Array(4).fill(0).map((_, i) =>
|
||||||
|
<Grid key={`item-${i}`} item xs={3} lg={3} sx={{textAlign: "center"}}>
|
||||||
|
<MDBox p={3} pt={3} sx={{alignItems: "center"}}>
|
||||||
|
<MDBox>
|
||||||
|
<MDTypography variant="h6">
|
||||||
|
<Icon sx={{fontSize: "30px", margin: "5px", color: "grey"}} fontSize="medium">pending</Icon>
|
||||||
|
</MDTypography>
|
||||||
|
</MDBox>
|
||||||
|
<MDBox>
|
||||||
|
<MDTypography variant="h6">
|
||||||
|
<Skeleton />
|
||||||
|
</MDTypography>
|
||||||
|
<MDTypography variant="subtitle2">
|
||||||
|
<Skeleton />
|
||||||
|
</MDTypography>
|
||||||
|
</MDBox>
|
||||||
|
<Divider sx={{margin: "10px"}}></Divider>
|
||||||
|
<MDBox sx={{alignItems: "center"}}>
|
||||||
|
<MDBox key={`stat-${i}`}>
|
||||||
|
<MDTypography variant="subtitle2">
|
||||||
|
<Skeleton />
|
||||||
|
</MDTypography>
|
||||||
|
</MDBox>
|
||||||
|
</MDBox>
|
||||||
|
</MDBox>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -65,10 +65,6 @@ function StepperCard({data}: Props): JSX.Element
|
|||||||
marginTop: "9px",
|
marginTop: "9px",
|
||||||
marginRight: "30px",
|
marginRight: "30px",
|
||||||
marginLeft: "30px",
|
marginLeft: "30px",
|
||||||
},
|
|
||||||
"& .MuiStepConnector-completed":
|
|
||||||
{
|
|
||||||
color: "red !important"
|
|
||||||
}
|
}
|
||||||
})(StepConnector);
|
})(StepConnector);
|
||||||
|
|
||||||
@ -132,7 +128,21 @@ function StepperCard({data}: Props): JSX.Element
|
|||||||
</Step>
|
</Step>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<Skeleton width="100%" height="80px" />
|
|
||||||
|
Array(5).fill(0).map((_, i) =>
|
||||||
|
<Step key={`step-${i}`}>
|
||||||
|
<MDBox>
|
||||||
|
<StepLabel icon={<Pending />} sx={{
|
||||||
|
color: "#ced4da",
|
||||||
|
fontSize: "35px",
|
||||||
|
"& .MuiStepLabel-label.MuiStepLabel-alternativeLabel":
|
||||||
|
{
|
||||||
|
color: "#ced4da !important",
|
||||||
|
}
|
||||||
|
}}><Skeleton /></StepLabel>
|
||||||
|
</MDBox>
|
||||||
|
</Step>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Stepper>
|
</Stepper>
|
||||||
|
@ -24,10 +24,17 @@ import Card from "@mui/material/Card";
|
|||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Menu from "@mui/material/Menu";
|
import Menu from "@mui/material/Menu";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
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 parse from "html-react-parser";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import {NavLink} from "react-router-dom";
|
import {NavLink} from "react-router-dom";
|
||||||
|
import DefaultCell from "layouts/dashboards/sales/components/DefaultCell";
|
||||||
import DataTable, {TableDataInput} from "qqq/components/Temporary/DataTable";
|
import DataTable, {TableDataInput} from "qqq/components/Temporary/DataTable";
|
||||||
|
import DataTableBodyCell from "qqq/components/Temporary/DataTable/DataTableBodyCell";
|
||||||
|
import DataTableHeadCell from "qqq/components/Temporary/DataTable/DataTableHeadCell";
|
||||||
import MDBox from "qqq/components/Temporary/MDBox";
|
import MDBox from "qqq/components/Temporary/MDBox";
|
||||||
import MDTypography from "qqq/components/Temporary/MDTypography";
|
import MDTypography from "qqq/components/Temporary/MDTypography";
|
||||||
|
|
||||||
@ -175,17 +182,30 @@ function TableCard({title, linkText, linkURL, noRowsFoundHTML, data, dropdownOpt
|
|||||||
</MDTypography>
|
</MDTypography>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
) : (
|
) : (
|
||||||
<MDBox p={3} pt={1} pb={1} sx={{textAlign: "center"}}>
|
<TableContainer sx={{boxShadow: "none"}}>
|
||||||
<MDTypography
|
<Table>
|
||||||
variant="subtitle2"
|
<MDBox component="thead">
|
||||||
color="secondary"
|
<TableRow key="header">
|
||||||
fontWeight="regular"
|
{Array(8).fill(0).map((_, i) =>
|
||||||
>
|
<DataTableHeadCell key={`head-${i}`} sorted={false} width="auto" align="center">
|
||||||
<Skeleton />
|
<Skeleton width="100%" />
|
||||||
<Skeleton />
|
</DataTableHeadCell>
|
||||||
<Skeleton />
|
)}
|
||||||
</MDTypography>
|
</TableRow>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
|
<TableBody>
|
||||||
|
{Array(5).fill(0).map((_, i) =>
|
||||||
|
<TableRow sx={{verticalAlign: "top"}} key={`row-${i}`}>
|
||||||
|
{Array(8).fill(0).map((_, j) =>
|
||||||
|
<DataTableBodyCell key={`cell-${i}-${j}`} align="center">
|
||||||
|
<DefaultCell><Skeleton /></DefaultCell>
|
||||||
|
</DataTableBodyCell>
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</MDBox>
|
</MDBox>
|
||||||
|
@ -57,8 +57,9 @@ import {
|
|||||||
MuiEvent
|
MuiEvent
|
||||||
} from "@mui/x-data-grid-pro";
|
} from "@mui/x-data-grid-pro";
|
||||||
import {GridFilterOperator} from "@mui/x-data-grid/models/gridFilterOperator";
|
import {GridFilterOperator} from "@mui/x-data-grid/models/gridFilterOperator";
|
||||||
import React, {useCallback, useEffect, useReducer, useRef, useState} from "react";
|
import React, {useCallback, useContext, useEffect, useReducer, useRef, useState} from "react";
|
||||||
import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom";
|
import {Link, useNavigate, useParams, useSearchParams} from "react-router-dom";
|
||||||
|
import QContext from "QContext";
|
||||||
import DashboardLayout from "qqq/components/DashboardLayout";
|
import DashboardLayout from "qqq/components/DashboardLayout";
|
||||||
import Footer from "qqq/components/Footer";
|
import Footer from "qqq/components/Footer";
|
||||||
import Navbar from "qqq/components/Navbar";
|
import Navbar from "qqq/components/Navbar";
|
||||||
@ -197,6 +198,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
const [queryErrors, setQueryErrors] = useState({} as any);
|
const [queryErrors, setQueryErrors] = useState({} as any);
|
||||||
const [receivedQueryErrorTimestamp, setReceivedQueryErrorTimestamp] = useState(new Date());
|
const [receivedQueryErrorTimestamp, setReceivedQueryErrorTimestamp] = useState(new Date());
|
||||||
|
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
@ -233,6 +235,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
const tableMetaData = await qController.loadTableMetaData(tableName);
|
||||||
|
setPageHeader(tableMetaData.label);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// we need the table meta data to look up the default filter (if it comes from query string), //
|
// we need the table meta data to look up the default filter (if it comes from query string), //
|
||||||
@ -263,7 +266,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
// assign a new query id to the query being issued here. then run both the count & query async //
|
// assign a new query id to the query being issued here. then run both the count & query async //
|
||||||
// and when they load, store their results associated with this id. //
|
// and when they load, store their results associated with this id. //
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
const thisQueryId = latestQueryId + 1
|
const thisQueryId = latestQueryId + 1;
|
||||||
setLatestQueryId(thisQueryId);
|
setLatestQueryId(thisQueryId);
|
||||||
|
|
||||||
console.log(`Issuing query: ${thisQueryId}`);
|
console.log(`Issuing query: ${thisQueryId}`);
|
||||||
@ -291,7 +294,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
errorMessage = error.message;
|
errorMessage = error.message;
|
||||||
}
|
}
|
||||||
else if(error && error.response && error.response.data && error.response.data.error)
|
else if (error && error.response && error.response.data && error.response.data.error)
|
||||||
{
|
{
|
||||||
errorMessage = error.response.data.error;
|
errorMessage = error.response.data.error;
|
||||||
}
|
}
|
||||||
@ -307,7 +310,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}
|
};
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
// display count results //
|
// display count results //
|
||||||
@ -360,7 +363,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
///////////////////////////
|
///////////////////////////
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!queryResults[latestQueryId])
|
if (!queryResults[latestQueryId])
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// to avoid showing results from an "older" query (e.g., one that was slow, and returned //
|
// to avoid showing results from an "older" query (e.g., one that was slow, and returned //
|
||||||
@ -382,8 +385,8 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
const row: any = {};
|
const row: any = {};
|
||||||
fields.forEach((field) =>
|
fields.forEach((field) =>
|
||||||
{
|
{
|
||||||
const value = QValueUtils.getDisplayValue(field, record)
|
const value = QValueUtils.getDisplayValue(field, record);
|
||||||
if(typeof value !== "string")
|
if (typeof value !== "string")
|
||||||
{
|
{
|
||||||
columnsToRender[field.name] = true;
|
columnsToRender[field.name] = true;
|
||||||
}
|
}
|
||||||
@ -454,11 +457,11 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(field.hasAdornment(AdornmentType.SIZE))
|
if (field.hasAdornment(AdornmentType.SIZE))
|
||||||
{
|
{
|
||||||
const sizeAdornment = field.getAdornment(AdornmentType.SIZE)
|
const sizeAdornment = field.getAdornment(AdornmentType.SIZE);
|
||||||
const width = sizeAdornment.getValue("width")
|
const width = sizeAdornment.getValue("width");
|
||||||
switch(width)
|
switch (width)
|
||||||
{
|
{
|
||||||
case "small":
|
case "small":
|
||||||
{
|
{
|
||||||
@ -482,7 +485,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
console.log("Unrecognized size.width adornment value: " + width)
|
console.log("Unrecognized size.width adornment value: " + width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +499,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
filterOperators: filterOperators,
|
filterOperators: filterOperators,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(columnsToRender[field.name])
|
if (columnsToRender[field.name])
|
||||||
{
|
{
|
||||||
column.renderCell = (cellValues: any) => (
|
column.renderCell = (cellValues: any) => (
|
||||||
(cellValues.value)
|
(cellValues.value)
|
||||||
@ -811,9 +814,9 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const defaultLabelDisplayedRows = ({from, to, count}) =>
|
const defaultLabelDisplayedRows = ({from, to, count}) =>
|
||||||
{
|
{
|
||||||
if(count !== null && count !== undefined)
|
if (count !== null && count !== undefined)
|
||||||
{
|
{
|
||||||
if(count === 0)
|
if (count === 0)
|
||||||
{
|
{
|
||||||
return (loading ? "Counting records..." : "No rows");
|
return (loading ? "Counting records..." : "No rows");
|
||||||
}
|
}
|
||||||
@ -823,7 +826,7 @@ function EntityList({table}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
return ("Counting records...");
|
return ("Counting records...");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function CustomPagination()
|
function CustomPagination()
|
||||||
{
|
{
|
||||||
|
@ -36,8 +36,9 @@ import Grid from "@mui/material/Grid";
|
|||||||
import Icon from "@mui/material/Icon";
|
import Icon from "@mui/material/Icon";
|
||||||
import Menu from "@mui/material/Menu";
|
import Menu from "@mui/material/Menu";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import React, {useEffect, useReducer, useState} from "react";
|
import React, {useContext, useEffect, useReducer, useState} from "react";
|
||||||
import {useLocation, useNavigate, useSearchParams} from "react-router-dom";
|
import {useLocation, useNavigate, useSearchParams} from "react-router-dom";
|
||||||
|
import QContext from "QContext";
|
||||||
import DashboardWidgets from "qqq/components/DashboardWidgets";
|
import DashboardWidgets from "qqq/components/DashboardWidgets";
|
||||||
import {QActionsMenuButton, QDeleteButton, QEditButton} from "qqq/components/QButtons";
|
import {QActionsMenuButton, QDeleteButton, QEditButton} from "qqq/components/QButtons";
|
||||||
import QRecordSidebar from "qqq/components/QRecordSidebar";
|
import QRecordSidebar from "qqq/components/QRecordSidebar";
|
||||||
@ -80,6 +81,7 @@ function ViewContents({id, table}: Props): JSX.Element
|
|||||||
const [actionsMenu, setActionsMenu] = useState(null);
|
const [actionsMenu, setActionsMenu] = useState(null);
|
||||||
const [tableWidgets, setTableWidgets] = useState([] as QWidgetMetaData[]);
|
const [tableWidgets, setTableWidgets] = useState([] as QWidgetMetaData[]);
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
|
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
|
||||||
@ -126,6 +128,7 @@ function ViewContents({id, table}: Props): JSX.Element
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
const record = await qController.get(tableName, id);
|
const record = await qController.get(tableName, id);
|
||||||
setRecord(record);
|
setRecord(record);
|
||||||
|
setPageHeader(record.recordLabel);
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
// load widget meta data //
|
// load widget meta data //
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
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 {QReportMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QReportMetaData";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
|
import QContext from "QContext";
|
||||||
import ProcessRun from "qqq/pages/process-run/index";
|
import ProcessRun from "qqq/pages/process-run/index";
|
||||||
import QClient from "qqq/utils/QClient";
|
import QClient from "qqq/utils/QClient";
|
||||||
|
|
||||||
@ -36,10 +36,11 @@ function ReportRun({report}: Props): JSX.Element
|
|||||||
// const reportNameParam = useParams().reportName;
|
// const reportNameParam = useParams().reportName;
|
||||||
// const processName = process === null ? processNameParam : process.name;
|
// const processName = process === null ? processNameParam : process.name;
|
||||||
const [metaData, setMetaData] = useState(null as QInstance);
|
const [metaData, setMetaData] = useState(null as QInstance);
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!metaData)
|
if (!metaData)
|
||||||
{
|
{
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
@ -49,18 +50,20 @@ function ReportRun({report}: Props): JSX.Element
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(metaData)
|
if (metaData)
|
||||||
{
|
{
|
||||||
console.log(`Report Process name is ${report.processName}`)
|
setPageHeader(report.label);
|
||||||
const process = metaData.processes.get(report.processName)
|
|
||||||
console.log(`Process is ${process.name}`)
|
console.log(`Report Process name is ${report.processName}`);
|
||||||
const defaultProcessValues = {reportName: report.name}
|
const process = metaData.processes.get(report.processName);
|
||||||
|
console.log(`Process is ${process.name}`);
|
||||||
|
const defaultProcessValues = {reportName: report.name};
|
||||||
return (<ProcessRun process={process} defaultProcessValues={defaultProcessValues} />);
|
return (<ProcessRun process={process} defaultProcessValues={defaultProcessValues} />);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// todo - loading?
|
// todo - loading?
|
||||||
return (<div/>);
|
return (<div />);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobEr
|
|||||||
import {QJobRunning} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobRunning";
|
import {QJobRunning} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobRunning";
|
||||||
import {QJobStarted} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobStarted";
|
import {QJobStarted} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobStarted";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import {Button, Icon, CircularProgress, TablePagination} from "@mui/material";
|
import {Button, CircularProgress, Icon, TablePagination} from "@mui/material";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
@ -41,12 +41,12 @@ import StepLabel from "@mui/material/StepLabel";
|
|||||||
import Stepper from "@mui/material/Stepper";
|
import Stepper from "@mui/material/Stepper";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import {DataGridPro, GridColDef} from "@mui/x-data-grid-pro";
|
import {DataGridPro, GridColDef} from "@mui/x-data-grid-pro";
|
||||||
import {GoogleOAuthProvider} from "@react-oauth/google";
|
|
||||||
import FormData from "form-data";
|
import FormData from "form-data";
|
||||||
import {Form, Formik} from "formik";
|
import {Form, Formik} from "formik";
|
||||||
import React, {useEffect, useState} from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
import {useLocation, useParams, useNavigate} from "react-router-dom";
|
import {useLocation, useNavigate, useParams} from "react-router-dom";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
import QContext from "QContext";
|
||||||
import BaseLayout from "qqq/components/BaseLayout";
|
import BaseLayout from "qqq/components/BaseLayout";
|
||||||
import {QCancelButton, QSubmitButton} from "qqq/components/QButtons";
|
import {QCancelButton, QSubmitButton} from "qqq/components/QButtons";
|
||||||
import QDynamicForm from "qqq/components/QDynamicForm";
|
import QDynamicForm from "qqq/components/QDynamicForm";
|
||||||
@ -102,6 +102,8 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
const [showErrorDetail, setShowErrorDetail] = useState(false);
|
const [showErrorDetail, setShowErrorDetail] = useState(false);
|
||||||
const [showFullHelpText, setShowFullHelpText] = useState(false);
|
const [showFullHelpText, setShowFullHelpText] = useState(false);
|
||||||
|
|
||||||
|
const {pageHeader, setPageHeader} = useContext(QContext);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// for setting the processError state - call this function, which will also set the isUserFacingError state //
|
// for setting the processError state - call this function, which will also set the isUserFacingError state //
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -302,7 +304,7 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
component.values.previewText ?
|
component.values.previewText ?
|
||||||
<>
|
<>
|
||||||
<Box mt={1}>
|
<Box mt={1}>
|
||||||
<Button onClick={toggleShowFullHelpText} startIcon={<Icon>{showFullHelpText ? "expand_less" : "expand_more"}</Icon>} sx={{pl: 1}} >
|
<Button onClick={toggleShowFullHelpText} startIcon={<Icon>{showFullHelpText ? "expand_less" : "expand_more"}</Icon>} sx={{pl: 1}}>
|
||||||
{showFullHelpText ? "Hide " : "Show "}
|
{showFullHelpText ? "Hide " : "Show "}
|
||||||
{component.values.previewText}
|
{component.values.previewText}
|
||||||
</Button>
|
</Button>
|
||||||
@ -471,17 +473,17 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
let rs: QFieldMetaData[] = [];
|
let rs: QFieldMetaData[] = [];
|
||||||
|
|
||||||
if(activeStep && activeStep.formFields)
|
if (activeStep && activeStep.formFields)
|
||||||
{
|
{
|
||||||
for(let i = 0; i<activeStep.formFields.length; i++)
|
for (let i = 0; i < activeStep.formFields.length; i++)
|
||||||
{
|
{
|
||||||
rs.push(activeStep.formFields[i]);
|
rs.push(activeStep.formFields[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(processValues.inputFieldList)
|
if (processValues.inputFieldList)
|
||||||
{
|
{
|
||||||
for(let i = 0; i<processValues.inputFieldList.length; i++)
|
for (let i = 0; i < processValues.inputFieldList.length; i++)
|
||||||
{
|
{
|
||||||
let inputField = new QFieldMetaData(processValues.inputFieldList[i]);
|
let inputField = new QFieldMetaData(processValues.inputFieldList[i]);
|
||||||
rs.push(inputField);
|
rs.push(inputField);
|
||||||
@ -501,6 +503,7 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
console.log("No process meta data yet, so returning early");
|
console.log("No process meta data yet, so returning early");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
setPageHeader(processMetaData.label)
|
||||||
|
|
||||||
let newIndex = null;
|
let newIndex = null;
|
||||||
if (typeof newStep === "number")
|
if (typeof newStep === "number")
|
||||||
@ -590,7 +593,7 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
addField("googleDriveFolderName", {type: "hidden", omitFromQDynamicForm: true}, null, null);
|
addField("googleDriveFolderName", {type: "hidden", omitFromQDynamicForm: true}, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Object.keys(dynamicFormFields).length > 0)
|
if (Object.keys(dynamicFormFields).length > 0)
|
||||||
{
|
{
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// if there are form fields, set them up //
|
// if there are form fields, set them up //
|
||||||
@ -743,7 +746,7 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
const qJobError = lastProcessResponse as QJobError;
|
const qJobError = lastProcessResponse as QJobError;
|
||||||
console.log(`Got an error from the backend... ${qJobError.error} : ${qJobError.userFacingError}`);
|
console.log(`Got an error from the backend... ${qJobError.error} : ${qJobError.userFacingError}`);
|
||||||
setJobUUID(null);
|
setJobUUID(null);
|
||||||
if(qJobError.userFacingError)
|
if (qJobError.userFacingError)
|
||||||
{
|
{
|
||||||
setProcessError(qJobError.userFacingError, true);
|
setProcessError(qJobError.userFacingError, true);
|
||||||
}
|
}
|
||||||
@ -874,9 +877,9 @@ function ProcessRun({process, defaultProcessValues}: Props): JSX.Element
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defaultProcessValues)
|
if (defaultProcessValues)
|
||||||
{
|
{
|
||||||
for(let key in defaultProcessValues)
|
for (let key in defaultProcessValues)
|
||||||
{
|
{
|
||||||
queryStringPairsForInit.push(`${key}=${encodeURIComponent(defaultProcessValues[key])}`);
|
queryStringPairsForInit.push(`${key}=${encodeURIComponent(defaultProcessValues[key])}`);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user