Checkpoint - using types out of QController as intended fully typescript types

This commit is contained in:
2022-07-05 12:35:24 -05:00
parent d9d6c887f6
commit 4960dde81e
11 changed files with 290 additions and 308 deletions

View File

@ -21,8 +21,8 @@ import breakpoints from "assets/theme/base/breakpoints";
// 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 Footer from "qqq/pages/components/Footer"; import Footer from "qqq/components/Footer";
import MDBox from "../../../../components/MDBox"; import MDBox from "../../../components/MDBox";
// Declaring props types for BaseLayout // Declaring props types for BaseLayout
interface Props { interface Props {

View File

@ -0,0 +1,177 @@
/**
=========================================================
* 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.
*/
/* eslint-disable no-unused-vars */
/* eslint-disable spaced-comment */
import { useParams } from "react-router-dom";
// @material-ui core components
import Card from "@mui/material/Card";
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 { QControllerV3 } from "@kingsrook/qqq-frontend-core/lib/controllers/QControllerV2";
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 QControllerV3("");
// Declaring props types for EntityForm
interface Props {
id?: string;
}
function EntityForm({ id }: Props): JSX.Element {
const { tableName } = useParams();
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 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);
(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;
records.forEach((innerRecord) => {
const fieldKeys = [...innerRecord.values.keys()];
fieldKeys.forEach((key) => {
const value = innerRecord.values.get(key);
if (key === tableMetaData.primaryKeyField && `${value}` === `${id}`) {
foundRecord = innerRecord;
}
});
});
const sortedKeys = [...tableMetaData.fields.keys()].sort();
sortedKeys.forEach((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>
);
}
});
}
setFormFields(formFields);
})();
}
const handleSubmit = (event: { preventDefault: () => void }) => {
event.preventDefault();
(async () => {
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}`;
return (
<Card id="basic-info" sx={{ overflow: "visible" }}>
<MDBox p={3}>
<MDTypography variant="h5">{pageTitle}</MDTypography>
</MDBox>
<MDBox component="form" pb={3} px={3} onSubmit={handleSubmit}>
<Grid key="fieldsGrid" container spacing={3}>
{formFields}
</Grid>
<Grid key="buttonGrid" container spacing={3}>
<MDBox ml="auto">
<MDButton type="submit" variant="gradient" color="dark" size="small">
save {tableMetaData?.label}
</MDButton>
</MDBox>
</Grid>
</MDBox>
</Card>
);
}
// Declaring default props for DefaultCell
EntityForm.defaultProps = {
id: null,
};
export default EntityForm;

View File

@ -1,184 +0,0 @@
/**
=========================================================
* 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.
*/
/* eslint-disable no-unused-vars */
/* eslint-disable spaced-comment */
import { useParams } from "react-router-dom";
// @material-ui core components
import Card from "@mui/material/Card";
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 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 { tableName } = useParams();
const [formFields, setFormFields] = useState([] as JSX.Element[]);
const defaultValues: { [key: string]: string } = {};
const [formValues, setFormValues] = useState(defaultValues);
const [loadCounter, setLoadCounter] = useState(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);
};
const tableMetaData = new QTableMetaData(tableName);
if (loadCounter === 0) {
setLoadCounter(1);
(async () => {
await qController.loadTableMetaData(tableName).then((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) {
(async () => {
await qController.query(tableName, 250).then((results) => {
let foundRecord: QTableRecord;
results.forEach((record) => {
const values = new Map(Object.entries(record.values));
values.forEach((value, key) => {
if (key === tableMetaData.primaryKeyField && value.toString() === id) {
foundRecord = record;
}
});
});
if (id != null) {
const values = new Map(Object.entries(foundRecord.values));
values.forEach((value, key) => {
formValues[key] = value;
console.log(`key:${key},value:${value}`);
});
}
const fields = new Map(Object.entries(tableMetaData.fields));
const sortedEntries = new Map([...fields.entries()].sort());
sortedEntries.forEach((fieldMetaData) => {
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 fields = new Map(Object.entries(tableMetaData.fields));
const sortedEntries = new Map([...fields.entries()].sort());
sortedEntries.forEach((fieldMetaData) => {
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>
);
}
});
}
setFormFields(formFields);
});
})();
}
const handleSubmit = (event: { preventDefault: () => void }) => {
event.preventDefault();
(async () => {
await qController.create(tableName, formValues).then((recordList) => {
const values = new Map(Object.entries(recordList[0].values));
window.location.href = `/${tableName}/view/${values.get("id")}`;
});
})();
};
const pageTitle = id != null ? `Edit ${tableMetaData.label}` : `Create ${tableMetaData.label}`;
return (
<Card id="basic-info" sx={{ overflow: "visible" }}>
<MDBox p={3}>
<MDTypography variant="h5">{pageTitle}</MDTypography>
</MDBox>
<MDBox component="form" pb={3} px={3} onSubmit={handleSubmit}>
<Grid key="fieldsGrid" container spacing={3}>
{formFields}
</Grid>
<Grid key="buttonGrid" container spacing={3}>
<MDBox ml="auto">
<MDButton type="submit" variant="gradient" color="dark" size="small">
save {tableMetaData.label}
</MDButton>
</MDBox>
</Grid>
</MDBox>
</Card>
);
}
// Declaring default props for DefaultCell
EntityForm.defaultProps = {
id: null,
};
export default EntityForm;

View File

@ -20,8 +20,8 @@ import Grid from "@mui/material/Grid";
import MDBox from "components/MDBox"; import MDBox from "components/MDBox";
// Settings page components // Settings page components
import CreateForm from "qqq/pages/components/EntityForm"; import CreateForm from "qqq/components/EntityForm";
import BaseLayout from "qqq/pages/components/BaseLayout"; import BaseLayout from "qqq/components/BaseLayout";
function EntityCreate(): JSX.Element { function EntityCreate(): JSX.Element {
return ( return (

View File

@ -20,9 +20,9 @@ import Grid from "@mui/material/Grid";
import MDBox from "components/MDBox"; import MDBox from "components/MDBox";
// Settings page components // Settings page components
import BaseLayout from "qqq/pages/components/BaseLayout"; import BaseLayout from "qqq/components/BaseLayout";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import EntityForm from "qqq/pages/components/EntityForm"; import EntityForm from "qqq/components/EntityForm";
function EntityEdit(): JSX.Element { function EntityEdit(): JSX.Element {
const { id } = useParams(); const { id } = useParams();

View File

@ -34,13 +34,13 @@ import DashboardNavbar from "examples/Navbars/DashboardNavbar";
import DataTable from "examples/Tables/DataTable"; import DataTable from "examples/Tables/DataTable";
// Data // Data
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController"; import { QControllerV3 } from "@kingsrook/qqq-frontend-core/lib/controllers/QControllerV2";
import Link from "@mui/material/Link"; 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 IdCell from "./components/IdCell"; import IdCell from "./components/IdCell";
import Footer from "../components/Footer"; import Footer from "../../components/Footer";
const qController = new QController(""); const qController = new QControllerV3("");
console.log(qController); console.log(qController);
// Declaring props types for DefaultCell // Declaring props types for DefaultCell
@ -65,44 +65,35 @@ function EntityList({ table }: Props): JSX.Element {
const createPath = `/${table.name}/create`; const createPath = `/${table.name}/create`;
(async () => { (async () => {
await qController.loadTableMetaData(table.name).then((tableMetaData) => { const tableMetaData = await qController.loadTableMetaData(table.name);
(async () => { const results = await qController.query(table.name, 250);
await qController.query(table.name, 250).then((results) => { dataTableData = {
dataTableData = { columns: [],
columns: [], rows: [],
rows: [], };
};
const fields = new Map(Object.entries(tableMetaData.fields)); const sortedKeys = [...tableMetaData.fields.keys()].sort();
const sortedEntries = new Map([...fields.entries()].sort()); sortedKeys.forEach((key) => {
sortedEntries.forEach((value, key) => { const field = tableMetaData.fields.get(key);
if (key === tableMetaData.primaryKeyField) { if (key === tableMetaData.primaryKeyField) {
dataTableData.columns.splice(0, 0, { dataTableData.columns.splice(0, 0, {
Header: key, Header: field.label,
accessor: key, accessor: key,
Cell: ({ value }: any) => <IdCell id={value} />, Cell: ({ value }: any) => <IdCell id={value} />,
});
} else {
dataTableData.columns.push({
Header: key,
accessor: key,
});
}
});
results.forEach((record) => {
const row = new Map();
const values = new Map(Object.entries(record.values));
values.forEach((value, key) => {
row.set(key, value);
});
dataTableData.rows.push(Object.fromEntries(row));
});
setTableState(table.name);
}); });
})(); } else {
dataTableData.columns.push({
Header: field.label,
accessor: key,
});
}
}); });
results.forEach((record) => {
dataTableData.rows.push(Object.fromEntries(record.values.entries()));
});
setTableState(table.name);
})(); })();
const renderMenu = ( const renderMenu = (

View File

@ -30,8 +30,8 @@ import MDTypography from "components/MDTypography";
// Settings page components // Settings page components
// qqq imports // qqq imports
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController"; import { QControllerV3 } from "@kingsrook/qqq-frontend-core/lib/controllers/QControllerV2";
import { QTableRecord } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableRecord"; import { QRecord } from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
import React, { useState } from "react"; import React, { useState } from "react";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
@ -45,7 +45,7 @@ import Button from "@mui/material/Button";
import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; import { QTableMetaData } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
import MDButton from "../../../../../components/MDButton"; import MDButton from "../../../../../components/MDButton";
const qController = new QController(""); const qController = new QControllerV3("");
console.log(qController); console.log(qController);
// Declaring props types for ViewForm // Declaring props types for ViewForm
@ -58,6 +58,8 @@ function ViewContents({ id }: Props): JSX.Element {
const [nameValues, setNameValues] = useState([] as JSX.Element[]); const [nameValues, setNameValues] = useState([] as JSX.Element[]);
const [loadCounter, setLoadCounter] = useState(0); const [loadCounter, setLoadCounter] = useState(0);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [tableMetaData, setTableMetaData] = useState(null);
const [record, setRecord] = useState(null);
const handleConfirmDelete = (event: { preventDefault: () => void }) => { const handleConfirmDelete = (event: { preventDefault: () => void }) => {
event.preventDefault(); event.preventDefault();
@ -69,59 +71,57 @@ function ViewContents({ id }: Props): JSX.Element {
})(); })();
}; };
const tableMetaData = new QTableMetaData(tableName);
if (loadCounter === 0) { if (loadCounter === 0) {
setLoadCounter(1); setLoadCounter(1);
(async () => { (async () => {
await qController.loadTableMetaData(tableName).then((tableMetaData) => { const tableMetaData = await qController.loadTableMetaData(tableName);
const formFields = [] as JSX.Element[]; console.log("@dk: table meta data");
const fields = new Map(Object.entries(tableMetaData.fields)); console.log(tableMetaData);
setTableMetaData(tableMetaData);
// make a call to query (just get all for now, and iterate and filter like a caveman) // make a call to query (just get all for now, and iterate and filter like a caveman)
(async () => { const records = await qController.query(tableName, 250);
await qController.query(tableName, 250).then((results) => { let foundRecord: QRecord;
let foundRecord: QTableRecord; records.forEach((innerRecord) => {
results.forEach((record) => { const fieldKeys = [...innerRecord.values.keys()];
const values = new Map(Object.entries(record.values)); fieldKeys.forEach((key) => {
values.forEach((value, key) => { const value = innerRecord.values.get(key);
if (key === tableMetaData.primaryKeyField && value.toString() === id) { if (key === tableMetaData.primaryKeyField && `${value}` === `${id}`) {
foundRecord = record; foundRecord = innerRecord;
} setRecord(innerRecord);
}); }
}); });
nameValues.push(
<MDBox key={tableMetaData.primaryKeyField} display="flex" py={1} pr={2}>
<MDTypography variant="button" fontWeight="bold" textTransform="capitalize">
{tableMetaData.primaryKeyField}: &nbsp;
</MDTypography>
<MDTypography variant="button" fontWeight="regular" color="text">
&nbsp;{id}
</MDTypography>
</MDBox>
);
const values = new Map(Object.entries(foundRecord.values));
const sortedEntries = new Map([...values.entries()].sort());
sortedEntries.forEach((value, key) => {
if (key !== tableMetaData.primaryKeyField) {
nameValues.push(
<MDBox key={key} display="flex" py={1} pr={2}>
<MDTypography variant="button" fontWeight="bold" textTransform="capitalize">
{key}: &nbsp;
</MDTypography>
<MDTypography variant="button" fontWeight="regular" color="text">
&nbsp;{value}
</MDTypography>
</MDBox>
);
}
});
setLoadCounter(2);
});
})();
}); });
nameValues.push(
<MDBox key={tableMetaData.primaryKeyField} display="flex" py={1} pr={2}>
<MDTypography variant="button" fontWeight="bold" textTransform="capitalize">
{tableMetaData.primaryKeyField}: &nbsp;
</MDTypography>
<MDTypography variant="button" fontWeight="regular" color="text">
&nbsp;{id}
</MDTypography>
</MDBox>
);
const sortedKeys = [...foundRecord.values.keys()].sort();
sortedKeys.forEach((key) => {
if (key !== tableMetaData.primaryKeyField) {
nameValues.push(
<MDBox key={key} display="flex" py={1} pr={2}>
<MDTypography variant="button" fontWeight="bold" textTransform="capitalize">
{tableMetaData.fields.get(key).label}: &nbsp;
</MDTypography>
<MDTypography variant="button" fontWeight="regular" color="text">
&nbsp;{foundRecord.values.get(key)}
</MDTypography>
</MDBox>
);
}
});
setLoadCounter(2);
})(); })();
} }
@ -139,7 +139,7 @@ function ViewContents({ id }: Props): JSX.Element {
<Card id="basic-info" sx={{ overflow: "visible" }}> <Card id="basic-info" sx={{ overflow: "visible" }}>
<MDBox p={3}> <MDBox p={3}>
<MDTypography variant="h5"> <MDTypography variant="h5">
Viewing {tableMetaData.label} ({id}) Viewing {tableMetaData?.label} ({id})
</MDTypography> </MDTypography>
</MDBox> </MDBox>
<MDBox p={3}>{nameValues}</MDBox> <MDBox p={3}>{nameValues}</MDBox>
@ -153,7 +153,7 @@ function ViewContents({ id }: Props): JSX.Element {
size="small" size="small"
onClick={handleConfirmDelete} onClick={handleConfirmDelete}
> >
delete {tableMetaData.label} delete {tableMetaData?.label}
</MDButton> </MDButton>
<Dialog <Dialog
open={open} open={open}
@ -175,7 +175,7 @@ function ViewContents({ id }: Props): JSX.Element {
</DialogActions> </DialogActions>
</Dialog> </Dialog>
<MDButton type="submit" variant="gradient" color="dark" size="small"> <MDButton type="submit" variant="gradient" color="dark" size="small">
<Link href={editPath}>edit {tableMetaData.label}</Link> <Link href={editPath}>edit {tableMetaData?.label}</Link>
</MDButton> </MDButton>
</MDBox> </MDBox>
</Grid> </Grid>

View File

@ -23,7 +23,7 @@ import MDBox from "components/MDBox";
// Settings page components // Settings page components
// import CreateForm from "qqq/pages/entity-create/components/CreateForm"; // import CreateForm from "qqq/pages/entity-create/components/CreateForm";
import BaseLayout from "qqq/pages/components/BaseLayout"; import BaseLayout from "qqq/components/BaseLayout";
import ViewContents from "./components/ViewContents"; import ViewContents from "./components/ViewContents";
function EntityView(): JSX.Element { function EntityView(): JSX.Element {

View File

@ -75,7 +75,7 @@ import Icon from "@mui/material/Icon";
import profilePicture from "assets/images/team-3.jpg"; import profilePicture from "assets/images/team-3.jpg";
// QQQ // QQQ
import { QController } from "@kingsrook/qqq-frontend-core/lib/controllers/QController"; import { QControllerV3 } from "@kingsrook/qqq-frontend-core/lib/controllers/QControllerV2";
import EntityList from "./pages/entity-list"; import EntityList from "./pages/entity-list";
@ -386,36 +386,34 @@ const qqqRoutes = [
{ type: "title", title: "Tables", key: "title-docs" }, { type: "title", title: "Tables", key: "title-docs" },
]; ];
const qController = new QController(""); const qController = new QControllerV3("");
console.log(qController); console.log(qController);
(async () => { (async () => {
await qController.loadMetaData().then((metaData) => { const metaData = await qController.loadMetaData();
console.log(`metaData: ${metaData}`); console.log(`metaData: ${metaData}`);
// get the keys sorted // get the keys sorted
const keys = new Map([...metaData.entries()].sort()); const keys = [...metaData.keys()].sort();
const tableList = [] as any[];
const tableList = [] as any[]; keys.forEach((key) => {
keys.forEach((value, key) => { const table = metaData.get(key);
const table = metaData.get(key); tableList.push({
tableList.push({ name: table.label,
name: table.label, key: table.name,
key: table.name, route: `/${table.name}/list`,
route: `/${table.name}/list`, component: <EntityList table={table} />,
component: <EntityList table={table} />,
});
}); });
const tables = {
type: "collapse",
name: "Tables",
key: "tables",
icon: <Icon fontSize="medium">dashboard</Icon>,
collapse: tableList,
};
qqqRoutes.push(tables);
}); });
const tables = {
type: "collapse",
name: "Tables",
key: "tables",
icon: <Icon fontSize="medium">dashboard</Icon>,
collapse: tableList,
};
qqqRoutes.push(tables);
})(); })();
export default qqqRoutes; export default qqqRoutes;