mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +00:00
QQQ-21: initial stab at merging some of form parts of create/edit and processes
This commit is contained in:
@ -1,26 +1,16 @@
|
|||||||
/**
|
// react components
|
||||||
=========================================================
|
|
||||||
* Material Dashboard 2 PRO React TS - v1.0.0
|
|
||||||
=========================================================
|
|
||||||
|
|
||||||
* Product Page: https://www.creative-tim.com/product/material-dashboard-2-pro-react-ts
|
|
||||||
* Copyright 2022 Creative Tim (https://www.creative-tim.com)
|
|
||||||
|
|
||||||
Coded by www.creative-tim.com
|
|
||||||
|
|
||||||
=========================================================
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// react imports
|
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import React, { useReducer, useState } from "react";
|
import React, { useReducer, useState } from "react";
|
||||||
|
|
||||||
// qqq imports
|
// misc components
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import { Form, Formik } from "formik";
|
||||||
|
|
||||||
|
// qqq components
|
||||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||||
import { QRecord } from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import DynamicFormUtils from "qqq/components/QDynamicForm/utils/DynamicFormUtils";
|
||||||
import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
import QDynamicForm from "qqq/components/QDynamicForm";
|
||||||
|
import { QFieldMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||||
|
|
||||||
// @material-ui core components
|
// @material-ui core components
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
@ -29,7 +19,6 @@ import Grid from "@mui/material/Grid";
|
|||||||
// Material Dashboard 2 PRO React TS components
|
// Material Dashboard 2 PRO React TS components
|
||||||
import MDBox from "components/MDBox";
|
import MDBox from "components/MDBox";
|
||||||
import MDTypography from "components/MDTypography";
|
import MDTypography from "components/MDTypography";
|
||||||
import FormField from "layouts/pages/account/components/FormField";
|
|
||||||
import MDButton from "../../../components/MDButton";
|
import MDButton from "../../../components/MDButton";
|
||||||
|
|
||||||
// Declaring props types for EntityForm
|
// Declaring props types for EntityForm
|
||||||
@ -41,17 +30,24 @@ function EntityForm({ id }: Props): JSX.Element {
|
|||||||
const qController = new QController("");
|
const qController = new QController("");
|
||||||
const { tableName } = useParams();
|
const { tableName } = useParams();
|
||||||
|
|
||||||
|
const [validations, setValidations] = useState({});
|
||||||
|
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
||||||
|
const [formFields, setFormFields] = useState({});
|
||||||
|
|
||||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||||
const [formFields, setFormFields] = useState([] as JSX.Element[]);
|
|
||||||
const [tableMetaData, setTableMetaData] = useState(null);
|
const [tableMetaData, setTableMetaData] = useState(null);
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
|
||||||
const handleInputChange = (e: { target: { name: any; value: any } }) => {
|
function getDynamicStepContent(formData: any): JSX.Element {
|
||||||
const { name, value } = e.target;
|
const { formFields, values, errors, touched } = formData;
|
||||||
formValues[name] = value;
|
|
||||||
setFormValues(formValues);
|
if (!Object.keys(formFields).length) {
|
||||||
};
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <QDynamicForm formData={formData} primaryKeyId={tableMetaData.primaryKeyField} />;
|
||||||
|
}
|
||||||
|
|
||||||
if (!asyncLoadInited) {
|
if (!asyncLoadInited) {
|
||||||
setAsyncLoadInited(true);
|
setAsyncLoadInited(true);
|
||||||
@ -59,73 +55,46 @@ function EntityForm({ id }: Props): JSX.Element {
|
|||||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
const tableMetaData = await qController.loadTableMetaData(tableName);
|
||||||
setTableMetaData(tableMetaData);
|
setTableMetaData(tableMetaData);
|
||||||
|
|
||||||
|
const fieldArray = [] as QFieldMetaData[];
|
||||||
|
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
||||||
|
sortedKeys.forEach((key) => {
|
||||||
|
const fieldMetaData = tableMetaData.fields.get(key);
|
||||||
|
fieldArray.push(fieldMetaData);
|
||||||
|
});
|
||||||
|
|
||||||
if (id !== null) {
|
if (id !== null) {
|
||||||
const foundRecord = await qController.get(tableName, id);
|
const record = await qController.get(tableName, id);
|
||||||
|
|
||||||
tableMetaData.fields.forEach((fieldMetaData, key) => {
|
tableMetaData.fields.forEach((fieldMetaData, key) => {
|
||||||
formValues[key] = foundRecord.values.get(key);
|
initialValues[key] = record.values.get(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
setFormValues(formValues);
|
setFormValues(formValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
const { dynamicFormFields, formValidations } = DynamicFormUtils.getFormData(fieldArray);
|
||||||
sortedKeys.forEach((key) => {
|
setInitialValues(initialValues);
|
||||||
const fieldMetaData = tableMetaData.fields.get(key);
|
setFormFields(dynamicFormFields);
|
||||||
if (fieldMetaData.name !== tableMetaData.primaryKeyField) {
|
setValidations(Yup.object().shape(formValidations));
|
||||||
let fieldType: string;
|
|
||||||
switch (fieldMetaData.type.toString()) {
|
|
||||||
case QFieldType.DECIMAL:
|
|
||||||
case QFieldType.INTEGER:
|
|
||||||
fieldType = "number";
|
|
||||||
break;
|
|
||||||
case QFieldType.DATE_TIME:
|
|
||||||
fieldType = "datetime-local";
|
|
||||||
break;
|
|
||||||
case QFieldType.PASSWORD:
|
|
||||||
case QFieldType.TIME:
|
|
||||||
case QFieldType.DATE:
|
|
||||||
fieldType = fieldMetaData.type.toString();
|
|
||||||
break;
|
|
||||||
case QFieldType.TEXT:
|
|
||||||
case QFieldType.HTML:
|
|
||||||
case QFieldType.STRING:
|
|
||||||
default:
|
|
||||||
fieldType = "text";
|
|
||||||
}
|
|
||||||
|
|
||||||
formFields.push(
|
|
||||||
<Grid item xs={12} sm={4} key={fieldMetaData.name}>
|
|
||||||
<FormField
|
|
||||||
id={fieldMetaData.name}
|
|
||||||
key={fieldMetaData.name}
|
|
||||||
name={fieldMetaData.name}
|
|
||||||
label={fieldMetaData.label}
|
|
||||||
type={fieldType}
|
|
||||||
defaultValue={formValues[fieldMetaData.name]}
|
|
||||||
onChange={handleInputChange}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setFormFields(formFields);
|
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = (event: { preventDefault: () => void }) => {
|
const handleSubmit = async (values: any, actions: any) => {
|
||||||
event.preventDefault();
|
actions.setSubmitting(true);
|
||||||
|
await (async () => {
|
||||||
(async () => {
|
|
||||||
if (id !== null) {
|
if (id !== null) {
|
||||||
await qController.update(tableName, id, formValues).then((record) => {
|
await qController.update(tableName, id, values).then((record) => {
|
||||||
window.location.href = `/${tableName}/view/${record.values.get("id")}`; // todo - primaryKeyField
|
window.location.href = `/${tableName}/${record.values.get(
|
||||||
|
tableMetaData.primaryKeyField
|
||||||
|
)}`;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await qController.create(tableName, formValues).then((record) => {
|
await qController.create(tableName, values).then((record) => {
|
||||||
window.location.href = `/${tableName}/view/${record.values.get("id")}`; // todo - primaryKeyField
|
window.location.href = `/${tableName}/${record.values.get(
|
||||||
|
tableMetaData.primaryKeyField
|
||||||
|
)}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@ -133,24 +102,46 @@ function EntityForm({ id }: Props): JSX.Element {
|
|||||||
|
|
||||||
const pageTitle =
|
const pageTitle =
|
||||||
id != null ? `Edit ${tableMetaData?.label} (${id})` : `Create New ${tableMetaData?.label}`;
|
id != null ? `Edit ${tableMetaData?.label} (${id})` : `Create New ${tableMetaData?.label}`;
|
||||||
|
const formId =
|
||||||
|
id != null ? `edit-${tableMetaData?.label}-form` : `create-${tableMetaData?.label}-form`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card id="basic-info" sx={{ overflow: "visible" }}>
|
<Card id="edit-form-container" sx={{ overflow: "visible" }}>
|
||||||
<MDBox p={3}>
|
<MDBox p={3}>
|
||||||
<MDTypography variant="h5">{pageTitle}</MDTypography>
|
<MDTypography variant="h5">{pageTitle}</MDTypography>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
<MDBox component="form" pb={3} px={3} onSubmit={handleSubmit}>
|
<MDBox pb={3} px={3}>
|
||||||
<Grid key="fieldsGrid" container spacing={3}>
|
<Grid key="fields-grid" container spacing={3}>
|
||||||
{formFields}
|
<Formik
|
||||||
</Grid>
|
initialValues={initialValues}
|
||||||
</MDBox>
|
validationSchema={validations}
|
||||||
<MDBox p={3}>
|
onSubmit={handleSubmit}
|
||||||
<Grid key="buttonGrid" container spacing={3}>
|
>
|
||||||
<MDBox ml="auto">
|
{({ values, errors, touched, isSubmitting }) => (
|
||||||
<MDButton type="submit" variant="gradient" color="dark" size="small">
|
<Form id={formId} autoComplete="off">
|
||||||
save {tableMetaData?.label}
|
<MDBox p={3} width="100%">
|
||||||
</MDButton>
|
<MDBox>
|
||||||
</MDBox>
|
{/***************************************************************************
|
||||||
|
** step content - e.g., the appropriate form or other screen for the step **
|
||||||
|
***************************************************************************/}
|
||||||
|
{getDynamicStepContent({
|
||||||
|
values,
|
||||||
|
touched,
|
||||||
|
formFields,
|
||||||
|
errors,
|
||||||
|
})}
|
||||||
|
<Grid key="buttonGrid" container spacing={3}>
|
||||||
|
<MDBox mt={5} ml="auto">
|
||||||
|
<MDButton type="submit" variant="gradient" color="dark" size="small">
|
||||||
|
save {tableMetaData?.label}
|
||||||
|
</MDButton>
|
||||||
|
</MDBox>
|
||||||
|
</Grid>
|
||||||
|
</MDBox>
|
||||||
|
</MDBox>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
</Grid>
|
</Grid>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -25,29 +25,30 @@ import FormField from "layouts/pages/users/new-user/components/FormField";
|
|||||||
import { QFrontendStepMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
import { QFrontendStepMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
formLabel?: string;
|
||||||
formData: any;
|
formData: any;
|
||||||
step?: QFrontendStepMetaData | undefined;
|
primaryKeyId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function QDynamicForm(props: Props): JSX.Element {
|
function QDynamicForm(props: Props): JSX.Element {
|
||||||
const { formData, step } = props;
|
const { formData, formLabel, primaryKeyId } = props;
|
||||||
const { formFields, values, errors, touched } = formData;
|
const { formFields, values, errors, touched } = formData;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const {
|
const {
|
||||||
firstName: firstNameV,
|
firstName: firstNameV,
|
||||||
lastName: lastNameV,
|
lastName: lastNameV,
|
||||||
company: companyV,
|
company: companyV,
|
||||||
email: emailV,
|
email: emailV,
|
||||||
password: passwordV,
|
password: passwordV,
|
||||||
repeatPassword: repeatPasswordV,
|
repeatPassword: repeatPasswordV,
|
||||||
} = values;
|
} = values;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MDBox>
|
<MDBox>
|
||||||
<MDBox lineHeight={0}>
|
<MDBox lineHeight={0}>
|
||||||
<MDTypography variant="h5">{step?.label}</MDTypography>
|
<MDTypography variant="h5">{formLabel}</MDTypography>
|
||||||
{/* TODO - help text
|
{/* TODO - help text
|
||||||
<MDTypography variant="button" color="text">
|
<MDTypography variant="button" color="text">
|
||||||
Mandatory information
|
Mandatory information
|
||||||
@ -60,12 +61,16 @@ function QDynamicForm(props: Props): JSX.Element {
|
|||||||
Object.keys(formFields).length > 0 &&
|
Object.keys(formFields).length > 0 &&
|
||||||
Object.keys(formFields).map((fieldName: any) => {
|
Object.keys(formFields).map((fieldName: any) => {
|
||||||
const field = formFields[fieldName];
|
const field = formFields[fieldName];
|
||||||
|
if (primaryKeyId && fieldName === primaryKeyId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (values[fieldName] === undefined) {
|
if (values[fieldName] === undefined) {
|
||||||
values[fieldName] = "";
|
values[fieldName] = "";
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Grid item xs={12} sm={6} key={fieldName}>
|
<Grid item xs={12} sm={6} key={fieldName}>
|
||||||
<FormField
|
<FormField
|
||||||
|
required={field.isRequired}
|
||||||
type={field.type}
|
type={field.type}
|
||||||
label={field.label}
|
label={field.label}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
@ -156,7 +161,8 @@ function QDynamicForm(props: Props): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QDynamicForm.defaultProps = {
|
QDynamicForm.defaultProps = {
|
||||||
step: undefined,
|
formLabel: undefined,
|
||||||
|
primaryKeyId: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default QDynamicForm;
|
export default QDynamicForm;
|
||||||
|
75
src/qqq/components/QDynamicForm/utils/DynamicFormUtils.ts
Normal file
75
src/qqq/components/QDynamicForm/utils/DynamicFormUtils.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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 * as Yup from "yup";
|
||||||
|
|
||||||
|
import { QFieldMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldMetaData";
|
||||||
|
import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Meta-data to represent a single field in a table.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class DynamicFormUtils {
|
||||||
|
public static getFormData(qqqFormFields: QFieldMetaData[]) {
|
||||||
|
const dynamicFormFields: any = {};
|
||||||
|
const formValidations: any = {};
|
||||||
|
|
||||||
|
qqqFormFields.forEach((field) => {
|
||||||
|
let fieldType: string;
|
||||||
|
switch (field.type.toString()) {
|
||||||
|
case QFieldType.DECIMAL:
|
||||||
|
case QFieldType.INTEGER:
|
||||||
|
fieldType = "number";
|
||||||
|
break;
|
||||||
|
case QFieldType.DATE_TIME:
|
||||||
|
fieldType = "datetime-local";
|
||||||
|
break;
|
||||||
|
case QFieldType.PASSWORD:
|
||||||
|
case QFieldType.TIME:
|
||||||
|
case QFieldType.DATE:
|
||||||
|
fieldType = field.type.toString();
|
||||||
|
break;
|
||||||
|
case QFieldType.TEXT:
|
||||||
|
case QFieldType.HTML:
|
||||||
|
case QFieldType.STRING:
|
||||||
|
default:
|
||||||
|
fieldType = "text";
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicFormFields[field.name] = {
|
||||||
|
name: field.name,
|
||||||
|
label: field.label ? field.label : field.name,
|
||||||
|
isRequired: field.isRequired,
|
||||||
|
type: fieldType,
|
||||||
|
// todo invalidMsg: "Zipcode is not valid (e.g. 70000).",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (field.isRequired) {
|
||||||
|
formValidations[field.name] = Yup.string().required(`${field.label} is required.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { dynamicFormFields, formValidations };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DynamicFormUtils;
|
@ -22,23 +22,24 @@ 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 Divider from "@mui/material/Divider";
|
import Divider from "@mui/material/Divider";
|
||||||
|
import Link from "@mui/material/Link";
|
||||||
// Material Dashboard 2 PRO React TS components
|
|
||||||
import MDBox from "components/MDBox";
|
|
||||||
import MDTypography from "components/MDTypography";
|
|
||||||
import MDButton from "components/MDButton";
|
|
||||||
|
|
||||||
// Material Dashboard 2 PRO React TS examples components
|
// Material Dashboard 2 PRO React TS examples components
|
||||||
import DashboardLayout from "examples/LayoutContainers/DashboardLayout";
|
import DashboardLayout from "examples/LayoutContainers/DashboardLayout";
|
||||||
import DashboardNavbar from "examples/Navbars/DashboardNavbar";
|
import DashboardNavbar from "examples/Navbars/DashboardNavbar";
|
||||||
import DataTable from "examples/Tables/DataTable";
|
import DataTable from "examples/Tables/DataTable";
|
||||||
|
|
||||||
// Data
|
// QQQ
|
||||||
import { QProcessMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
import { QProcessMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
||||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||||
import Link from "@mui/material/Link";
|
|
||||||
import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import DynamicFormUtils from "qqq/components/QDynamicForm/utils/DynamicFormUtils";
|
||||||
|
|
||||||
|
// Material Dashboard 2 PRO React TS components
|
||||||
|
import MDBox from "components/MDBox";
|
||||||
|
import MDTypography from "components/MDTypography";
|
||||||
|
import MDButton from "components/MDButton";
|
||||||
import Footer from "../../components/Footer";
|
import Footer from "../../components/Footer";
|
||||||
import IdCell from "../../components/EntityForm/components/IdCell";
|
import IdCell from "../../components/EntityForm/components/IdCell";
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// react components
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import React, { useReducer, useState } from "react";
|
||||||
|
|
||||||
// @material-ui core components
|
// @material-ui core components
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
@ -26,17 +28,12 @@ import DialogContentText from "@mui/material/DialogContentText";
|
|||||||
import DialogActions from "@mui/material/DialogActions";
|
import DialogActions from "@mui/material/DialogActions";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
|
|
||||||
|
// qqq imports
|
||||||
|
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||||
|
|
||||||
// Material Dashboard 2 PRO React TS components
|
// Material Dashboard 2 PRO React TS components
|
||||||
import MDBox from "components/MDBox";
|
import MDBox from "components/MDBox";
|
||||||
import MDTypography from "components/MDTypography";
|
import MDTypography from "components/MDTypography";
|
||||||
|
|
||||||
// Settings page components
|
|
||||||
|
|
||||||
// qqq imports
|
|
||||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
|
||||||
import { QRecord } from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
|
||||||
import React, { useReducer, useState } from "react";
|
|
||||||
|
|
||||||
import MDButton from "../../../../../components/MDButton";
|
import MDButton from "../../../../../components/MDButton";
|
||||||
|
|
||||||
const qController = new QController("");
|
const qController = new QController("");
|
||||||
@ -104,20 +101,16 @@ function ViewContents({ id }: Props): JSX.Element {
|
|||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
const handleDelete = (event: { preventDefault: () => void }) => {
|
const handleDelete = (event: { preventDefault: () => void }) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
/*
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await qController.delete(tableName, id).then(() => {
|
await qController.delete(tableName, id).then(() => {
|
||||||
window.location.href = `/${tableName}/list/`;
|
window.location.href = `/${tableName}`;
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
const editPath = `/${tableName}/edit/${id}`;
|
const editPath = `/${tableName}/${id}/edit`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card id="basic-info" sx={{ overflow: "visible" }}>
|
<Card id="basic-info" sx={{ overflow: "visible" }}>
|
||||||
@ -131,7 +124,6 @@ function ViewContents({ id }: Props): JSX.Element {
|
|||||||
<Grid key="tres" container spacing={3}>
|
<Grid key="tres" container spacing={3}>
|
||||||
<MDBox ml="auto" mr={3}>
|
<MDBox ml="auto" mr={3}>
|
||||||
<MDButton
|
<MDButton
|
||||||
type="submit"
|
|
||||||
variant="gradient"
|
variant="gradient"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
@ -153,14 +145,14 @@ function ViewContents({ id }: Props): JSX.Element {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={handleClickConfirmClose}>No</Button>
|
<Button onClick={handleClickConfirmClose}>No</Button>
|
||||||
<Button onClick={handleClickConfirmClose} autoFocus>
|
<Button onClick={handleDelete} autoFocus>
|
||||||
Yes
|
Yes
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
<MDBox>
|
<MDBox>
|
||||||
<MDButton type="submit" variant="gradient" color="dark" size="small">
|
<MDButton variant="gradient" color="dark" size="small">
|
||||||
<Link href={editPath}>edit {tableMetaData?.label}</Link>
|
<Link href={editPath}>edit {tableMetaData?.label}</Link>
|
||||||
</MDButton>
|
</MDButton>
|
||||||
</MDBox>
|
</MDBox>
|
||||||
|
@ -45,6 +45,7 @@ import * as Yup from "yup";
|
|||||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||||
import { QFrontendStepMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
import { QFrontendStepMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import DynamicFormUtils from "qqq/components/QDynamicForm/utils/DynamicFormUtils";
|
||||||
import QDynamicForm from "../../components/QDynamicForm";
|
import QDynamicForm from "../../components/QDynamicForm";
|
||||||
|
|
||||||
function getDynamicStepContent(stepIndex: number, stepParam: any, formData: any): JSX.Element {
|
function getDynamicStepContent(stepIndex: number, stepParam: any, formData: any): JSX.Element {
|
||||||
@ -57,7 +58,7 @@ function getDynamicStepContent(stepIndex: number, stepParam: any, formData: any)
|
|||||||
return <div>Loading...</div>;
|
return <div>Loading...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <QDynamicForm formData={formData} step={step} />;
|
return <QDynamicForm formData={formData} formLabel={step.name} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qController = new QController("");
|
const qController = new QController("");
|
||||||
@ -90,31 +91,23 @@ function ProcessRun(): JSX.Element {
|
|||||||
setActiveStep(activeStep);
|
setActiveStep(activeStep);
|
||||||
setFormId(activeStep.name);
|
setFormId(activeStep.name);
|
||||||
|
|
||||||
|
const { dynamicFormFields, formValidations } = DynamicFormUtils.getFormData(
|
||||||
|
activeStep.formFields
|
||||||
|
);
|
||||||
|
|
||||||
const formFields: any = {};
|
const formFields: any = {};
|
||||||
const initialValues: any = {};
|
const initialValues: any = {};
|
||||||
const validations: any = {};
|
const validations: any = {};
|
||||||
|
|
||||||
activeStep.formFields.forEach((field) => {
|
activeStep.formFields.forEach((field) => {
|
||||||
formFields[field.name] = {
|
|
||||||
name: field.name,
|
|
||||||
label: field.label,
|
|
||||||
type: "text", // todo better
|
|
||||||
// todo invalidMsg: "Zipcode is not valid (e.g. 70000).",
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo - not working - also, needs real value.
|
// todo - not working - also, needs real value.
|
||||||
initialValues[field.name] = "Hi";
|
initialValues[field.name] = "Hi";
|
||||||
|
|
||||||
// todo - all this based on type and other metadata.
|
|
||||||
// see src/layouts/pages/users/new-user/schemas/validations.ts
|
|
||||||
validations[field.name] = Yup.string().required(`${field.label} is required.`);
|
|
||||||
// validations[field.name] = Yup.string().optional();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setFormFields(formFields);
|
setFormFields(dynamicFormFields);
|
||||||
setInitialValues(initialValues);
|
setInitialValues(initialValues);
|
||||||
setValidations(Yup.object().shape(validations));
|
setValidations(Yup.object().shape(formValidations));
|
||||||
console.log(`in updateActiveStep: formFields ${JSON.stringify(formFields)}`);
|
console.log(`in updateActiveStep: formFields ${JSON.stringify(dynamicFormFields)}`);
|
||||||
console.log(`in updateActiveStep: initialValues ${JSON.stringify(initialValues)}`);
|
console.log(`in updateActiveStep: initialValues ${JSON.stringify(initialValues)}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user