mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
ONE-38: checkpoint commit of frontend MVP goal
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
/**
|
||||
=========================================================
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Material Dashboard 2 PRO React TS components
|
||||
import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
import MDAvatar from "components/MDAvatar";
|
||||
|
||||
// Declaring props types for CustomerCell
|
||||
interface Props {
|
||||
image?: string;
|
||||
name: string;
|
||||
color?:
|
||||
| "transparent"
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "info"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "error"
|
||||
| "light"
|
||||
| "dark";
|
||||
}
|
||||
|
||||
function CustomerCell({ image, name, color }: Props): JSX.Element {
|
||||
return (
|
||||
<MDBox display="flex" alignItems="center">
|
||||
<MDBox mr={1}>
|
||||
<MDAvatar bgColor={color} src={image} alt={name} size="xs" />
|
||||
</MDBox>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text" sx={{ lineHeight: 0 }}>
|
||||
{name}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for CustomerCell
|
||||
CustomerCell.defaultProps = {
|
||||
image: "",
|
||||
color: "dark",
|
||||
};
|
||||
|
||||
export default CustomerCell;
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
=========================================================
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Material Dashboard 2 PRO React TS components
|
||||
import MDTypography from "components/MDTypography";
|
||||
|
||||
// Declaring props types for DefaultCell
|
||||
interface Props {
|
||||
value: string;
|
||||
suffix?: string | boolean;
|
||||
}
|
||||
|
||||
function DefaultCell({ value, suffix }: Props): JSX.Element {
|
||||
return (
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text">
|
||||
{value}
|
||||
{suffix && (
|
||||
<MDTypography variant="caption" fontWeight="medium" color="secondary">
|
||||
{suffix}
|
||||
</MDTypography>
|
||||
)}
|
||||
</MDTypography>
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for DefaultCell
|
||||
DefaultCell.defaultProps = {
|
||||
suffix: "",
|
||||
};
|
||||
|
||||
export default DefaultCell;
|
53
src/qqq/components/EntityForm/components/IdCell/index.tsx
Normal file
53
src/qqq/components/EntityForm/components/IdCell/index.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
=========================================================
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// @mui material components
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
|
||||
// Material Dashboard 2 PRO React TS components
|
||||
import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
import Link from "@mui/material/Link";
|
||||
|
||||
// Declaring props types for IdCell
|
||||
interface Props {
|
||||
id: string;
|
||||
checked?: boolean;
|
||||
}
|
||||
|
||||
function IdCell({ id, checked }: Props): JSX.Element {
|
||||
const pathParts = window.location.pathname.split("/");
|
||||
const tableName = pathParts[1];
|
||||
const href = `/${tableName}/${id}`;
|
||||
const link = <Link href={href}>{id}</Link>;
|
||||
|
||||
return (
|
||||
<MDBox display="flex" alignItems="center">
|
||||
<Checkbox defaultChecked={checked} />
|
||||
<MDBox ml={1}>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text">
|
||||
{link}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for IdCell
|
||||
IdCell.defaultProps = {
|
||||
checked: false,
|
||||
};
|
||||
|
||||
export default IdCell;
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
=========================================================
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// @mui material components
|
||||
import Icon from "@mui/material/Icon";
|
||||
|
||||
// Material Dashboard 2 PRO React TS components
|
||||
import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
import MDButton from "components/MDButton";
|
||||
|
||||
// Declaring props types for StatusCell
|
||||
interface Props {
|
||||
icon: string;
|
||||
color:
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "info"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "error"
|
||||
| "dark"
|
||||
| "light"
|
||||
| "white"
|
||||
| "default";
|
||||
status: string;
|
||||
}
|
||||
|
||||
function StatusCell({ icon, color, status }: Props): JSX.Element {
|
||||
return (
|
||||
<MDBox display="flex" alignItems="center">
|
||||
<MDBox mr={1}>
|
||||
<MDButton variant="outlined" color={color} size="small" iconOnly circular>
|
||||
<Icon sx={{ fontWeight: "bold" }}>{icon}</Icon>
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text" sx={{ lineHeight: 0 }}>
|
||||
{status}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
);
|
||||
}
|
||||
|
||||
export default StatusCell;
|
@ -13,10 +13,14 @@
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable spaced-comment */
|
||||
|
||||
// react imports
|
||||
import { useParams } from "react-router-dom";
|
||||
import React, { useReducer, useState } from "react";
|
||||
|
||||
// qqq imports
|
||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||
import { QRecord } from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||
import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFieldType";
|
||||
|
||||
// @material-ui core components
|
||||
import Card from "@mui/material/Card";
|
||||
@ -25,52 +29,36 @@ import Grid from "@mui/material/Grid";
|
||||
// Material Dashboard 2 PRO React TS components
|
||||
import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
|
||||
// Settings page components
|
||||
import FormField from "layouts/pages/account/components/FormField";
|
||||
|
||||
// qqq imports
|
||||
import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController";
|
||||
import { QRecord } from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||
import React, { useState } from "react";
|
||||
import { QTableRecord } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableRecord";
|
||||
import MDButton from "../../../components/MDButton";
|
||||
|
||||
const qController = new QController("");
|
||||
|
||||
// Declaring props types for EntityForm
|
||||
interface Props {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
function EntityForm({ id }: Props): JSX.Element {
|
||||
const qController = new QController("");
|
||||
const { tableName } = useParams();
|
||||
|
||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||
const [formFields, setFormFields] = useState([] as JSX.Element[]);
|
||||
const defaultValues: { [key: string]: string } = {};
|
||||
const [formValues, setFormValues] = useState(defaultValues);
|
||||
const [loadCounter, setLoadCounter] = useState(0);
|
||||
const [tableMetaData, setTableMetaData] = useState(null);
|
||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||
|
||||
const handleInputChange = (e: { target: { name: any; value: any } }) => {
|
||||
console.log("A");
|
||||
const { name, value } = e.target;
|
||||
console.log(name);
|
||||
console.log(value);
|
||||
formValues[name] = value;
|
||||
setFormValues(formValues);
|
||||
};
|
||||
|
||||
if (loadCounter === 0) {
|
||||
setLoadCounter(1);
|
||||
|
||||
if (!asyncLoadInited) {
|
||||
setAsyncLoadInited(true);
|
||||
(async () => {
|
||||
// await qController.loadTableMetaData(tableName).then((tableMetaData) => {
|
||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
||||
setTableMetaData(tableMetaData);
|
||||
const formFields = [] as JSX.Element[];
|
||||
|
||||
// make a call to query (just get all for now, and iterate and filter like a caveman)
|
||||
if (id !== null) {
|
||||
const records = await qController.query(tableName, 250);
|
||||
let foundRecord: QRecord;
|
||||
@ -84,55 +72,56 @@ function EntityForm({ id }: Props): JSX.Element {
|
||||
});
|
||||
});
|
||||
|
||||
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
||||
sortedKeys.forEach((key) => {
|
||||
tableMetaData.fields.forEach((fieldMetaData, key) => {
|
||||
formValues[key] = foundRecord.values.get(key);
|
||||
|
||||
const fieldMetaData = tableMetaData.fields.get(key);
|
||||
if (fieldMetaData.name !== tableMetaData.primaryKeyField) {
|
||||
if (formValues[fieldMetaData.name] == null) {
|
||||
formValues[fieldMetaData.name] = "";
|
||||
}
|
||||
|
||||
formFields.push(
|
||||
<Grid item xs={12} sm={4} key={fieldMetaData.name}>
|
||||
<FormField
|
||||
key={fieldMetaData.name}
|
||||
name={fieldMetaData.name}
|
||||
id={fieldMetaData.name}
|
||||
label={fieldMetaData.label}
|
||||
value={formValues[fieldMetaData.name]}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
setLoadCounter(2);
|
||||
setFormValues(formValues);
|
||||
} else {
|
||||
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
||||
sortedKeys.forEach((key) => {
|
||||
const fieldMetaData = tableMetaData.fields.get(key);
|
||||
if (fieldMetaData.name !== tableMetaData.primaryKeyField) {
|
||||
formFields.push(
|
||||
<Grid item xs={12} sm={4} key={fieldMetaData.name}>
|
||||
<FormField
|
||||
key={fieldMetaData.name}
|
||||
name={fieldMetaData.name}
|
||||
id={fieldMetaData.name}
|
||||
label={fieldMetaData.label}
|
||||
value={formValues[fieldMetaData.name]}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
||||
sortedKeys.forEach((key) => {
|
||||
const fieldMetaData = tableMetaData.fields.get(key);
|
||||
if (fieldMetaData.name !== tableMetaData.primaryKeyField) {
|
||||
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();
|
||||
})();
|
||||
}
|
||||
|
||||
@ -140,13 +129,20 @@ function EntityForm({ id }: Props): JSX.Element {
|
||||
event.preventDefault();
|
||||
|
||||
(async () => {
|
||||
await qController.create(tableName, formValues).then((record) => {
|
||||
window.location.href = `/${tableName}/view/${record.values.get("id")}`; // todo - primaryKeyField
|
||||
});
|
||||
if (id !== null) {
|
||||
await qController.update(tableName, id, formValues).then((record) => {
|
||||
window.location.href = `/${tableName}/view/${record.values.get("id")}`; // todo - primaryKeyField
|
||||
});
|
||||
} else {
|
||||
await qController.create(tableName, formValues).then((record) => {
|
||||
window.location.href = `/${tableName}/view/${record.values.get("id")}`; // todo - primaryKeyField
|
||||
});
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
const pageTitle = id != null ? `Edit ${tableMetaData?.label}` : `Create ${tableMetaData?.label}`;
|
||||
const pageTitle =
|
||||
id != null ? `Edit ${tableMetaData?.label} (${id})` : `Create New ${tableMetaData?.label}`;
|
||||
|
||||
return (
|
||||
<Card id="basic-info" sx={{ overflow: "visible" }}>
|
||||
@ -157,6 +153,8 @@ function EntityForm({ id }: Props): JSX.Element {
|
||||
<Grid key="fieldsGrid" container spacing={3}>
|
||||
{formFields}
|
||||
</Grid>
|
||||
</MDBox>
|
||||
<MDBox p={3}>
|
||||
<Grid key="buttonGrid" container spacing={3}>
|
||||
<MDBox ml="auto">
|
||||
<MDButton type="submit" variant="gradient" color="dark" size="small">
|
||||
|
Reference in New Issue
Block a user