mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
QQQ-30: got rid of 'prettier', first pass at eslint configuration pointing only to qqq specific files, reformated all qqq files
This commit is contained in:
@ -30,41 +30,44 @@ interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
function BaseLayout({ stickyNavbar, children }: Props): JSX.Element {
|
||||
const [tabsOrientation, setTabsOrientation] = useState<"horizontal" | "vertical">("horizontal");
|
||||
function BaseLayout({ stickyNavbar, children }: Props): JSX.Element
|
||||
{
|
||||
const [tabsOrientation, setTabsOrientation] = useState<"horizontal" | "vertical">("horizontal");
|
||||
|
||||
useEffect(() => {
|
||||
// A function that sets the orientation state of the tabs.
|
||||
function handleTabsOrientation() {
|
||||
return window.innerWidth < breakpoints.values.sm
|
||||
? setTabsOrientation("vertical")
|
||||
: setTabsOrientation("horizontal");
|
||||
}
|
||||
useEffect(() =>
|
||||
{
|
||||
// A function that sets the orientation state of the tabs.
|
||||
function handleTabsOrientation()
|
||||
{
|
||||
return window.innerWidth < breakpoints.values.sm
|
||||
? setTabsOrientation("vertical")
|
||||
: setTabsOrientation("horizontal");
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
The event listener that's calling the handleTabsOrientation function when resizing the window.
|
||||
*/
|
||||
window.addEventListener("resize", handleTabsOrientation);
|
||||
window.addEventListener("resize", handleTabsOrientation);
|
||||
|
||||
// Call the handleTabsOrientation function to set the state with the initial value.
|
||||
handleTabsOrientation();
|
||||
// Call the handleTabsOrientation function to set the state with the initial value.
|
||||
handleTabsOrientation();
|
||||
|
||||
// Remove event listener on cleanup
|
||||
return () => window.removeEventListener("resize", handleTabsOrientation);
|
||||
}, [tabsOrientation]);
|
||||
// Remove event listener on cleanup
|
||||
return () => window.removeEventListener("resize", handleTabsOrientation);
|
||||
}, [tabsOrientation]);
|
||||
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar absolute={!stickyNavbar} isMini />
|
||||
<MDBox mt={stickyNavbar ? 3 : 10}>{children}</MDBox>
|
||||
<Footer />
|
||||
</DashboardLayout>
|
||||
);
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar absolute={!stickyNavbar} isMini />
|
||||
<MDBox mt={stickyNavbar ? 3 : 10}>{children}</MDBox>
|
||||
<Footer />
|
||||
</DashboardLayout>
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for BaseLayout
|
||||
BaseLayout.defaultProps = {
|
||||
stickyNavbar: false,
|
||||
stickyNavbar: false,
|
||||
};
|
||||
|
||||
export default BaseLayout;
|
||||
|
@ -34,23 +34,24 @@ interface Props {
|
||||
| "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" />
|
||||
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>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text" sx={{ lineHeight: 0 }}>
|
||||
{name}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for CustomerCell
|
||||
CustomerCell.defaultProps = {
|
||||
image: "",
|
||||
color: "dark",
|
||||
image: "",
|
||||
color: "dark",
|
||||
};
|
||||
|
||||
export default CustomerCell;
|
||||
|
@ -22,22 +22,24 @@ interface Props {
|
||||
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>
|
||||
);
|
||||
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: "",
|
||||
suffix: "",
|
||||
};
|
||||
|
||||
export default DefaultCell;
|
||||
|
@ -27,27 +27,28 @@ interface Props {
|
||||
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>;
|
||||
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>
|
||||
return (
|
||||
<MDBox display="flex" alignItems="center">
|
||||
<Checkbox defaultChecked={checked} />
|
||||
<MDBox ml={1}>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text">
|
||||
{link}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for IdCell
|
||||
IdCell.defaultProps = {
|
||||
checked: false,
|
||||
checked: false,
|
||||
};
|
||||
|
||||
export default IdCell;
|
||||
|
@ -38,19 +38,20 @@ interface Props {
|
||||
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>
|
||||
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>
|
||||
<MDTypography variant="caption" fontWeight="medium" color="text" sx={{ lineHeight: 0 }}>
|
||||
{status}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default StatusCell;
|
||||
|
@ -14,180 +14,180 @@ Coded by www.creative-tim.com
|
||||
*/
|
||||
|
||||
const selectData = {
|
||||
gender: ["Male", "Female"],
|
||||
birthDate: [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
],
|
||||
days: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
"18",
|
||||
"19",
|
||||
"20",
|
||||
"21",
|
||||
"22",
|
||||
"23",
|
||||
"24",
|
||||
"25",
|
||||
"26",
|
||||
"27",
|
||||
"28",
|
||||
"29",
|
||||
"30",
|
||||
],
|
||||
years: [
|
||||
"1900",
|
||||
"1901",
|
||||
"1902",
|
||||
"1903",
|
||||
"1904",
|
||||
"1905",
|
||||
"1906",
|
||||
"1907",
|
||||
"1908",
|
||||
"1909",
|
||||
"1910",
|
||||
"1911",
|
||||
"1912",
|
||||
"1913",
|
||||
"1914",
|
||||
"1915",
|
||||
"1915",
|
||||
"1915",
|
||||
"1916",
|
||||
"1917",
|
||||
"1918",
|
||||
"1919",
|
||||
"1920",
|
||||
"1921",
|
||||
"1922",
|
||||
"1923",
|
||||
"1924",
|
||||
"1925",
|
||||
"1926",
|
||||
"1927",
|
||||
"1928",
|
||||
"1929",
|
||||
"1930",
|
||||
"1931",
|
||||
"1932",
|
||||
"1933",
|
||||
"1934",
|
||||
"1935",
|
||||
"1936",
|
||||
"1937",
|
||||
"1938",
|
||||
"1939",
|
||||
"1940",
|
||||
"1941",
|
||||
"1942",
|
||||
"1943",
|
||||
"1944",
|
||||
"1945",
|
||||
"1946",
|
||||
"1947",
|
||||
"1948",
|
||||
"1949",
|
||||
"1950",
|
||||
"1951",
|
||||
"1952",
|
||||
"1953",
|
||||
"1954",
|
||||
"1955",
|
||||
"1956",
|
||||
"1957",
|
||||
"1958",
|
||||
"1959",
|
||||
"1960",
|
||||
"1961",
|
||||
"1962",
|
||||
"1963",
|
||||
"1964",
|
||||
"1965",
|
||||
"1966",
|
||||
"1967",
|
||||
"1968",
|
||||
"1969",
|
||||
"1970",
|
||||
"1971",
|
||||
"1972",
|
||||
"1973",
|
||||
"1974",
|
||||
"1975",
|
||||
"1976",
|
||||
"1977",
|
||||
"1978",
|
||||
"1979",
|
||||
"1980",
|
||||
"1981",
|
||||
"1982",
|
||||
"1983",
|
||||
"1984",
|
||||
"1985",
|
||||
"1986",
|
||||
"1987",
|
||||
"1988",
|
||||
"1989",
|
||||
"1990",
|
||||
"1991",
|
||||
"1992",
|
||||
"1993",
|
||||
"1994",
|
||||
"1995",
|
||||
"1996",
|
||||
"1997",
|
||||
"1998",
|
||||
"1999",
|
||||
"2000",
|
||||
"2001",
|
||||
"2002",
|
||||
"2003",
|
||||
"2004",
|
||||
"2005",
|
||||
"2006",
|
||||
"2007",
|
||||
"2008",
|
||||
"2009",
|
||||
"2010",
|
||||
"2011",
|
||||
"2012",
|
||||
"2013",
|
||||
"2014",
|
||||
"2015",
|
||||
"2016",
|
||||
"2017",
|
||||
"2018",
|
||||
"2019",
|
||||
"2020",
|
||||
"2021",
|
||||
],
|
||||
skills: ["react", "vue", "angular", "svelte", "javascript"],
|
||||
gender: ["Male", "Female"],
|
||||
birthDate: [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
],
|
||||
days: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
"18",
|
||||
"19",
|
||||
"20",
|
||||
"21",
|
||||
"22",
|
||||
"23",
|
||||
"24",
|
||||
"25",
|
||||
"26",
|
||||
"27",
|
||||
"28",
|
||||
"29",
|
||||
"30",
|
||||
],
|
||||
years: [
|
||||
"1900",
|
||||
"1901",
|
||||
"1902",
|
||||
"1903",
|
||||
"1904",
|
||||
"1905",
|
||||
"1906",
|
||||
"1907",
|
||||
"1908",
|
||||
"1909",
|
||||
"1910",
|
||||
"1911",
|
||||
"1912",
|
||||
"1913",
|
||||
"1914",
|
||||
"1915",
|
||||
"1915",
|
||||
"1915",
|
||||
"1916",
|
||||
"1917",
|
||||
"1918",
|
||||
"1919",
|
||||
"1920",
|
||||
"1921",
|
||||
"1922",
|
||||
"1923",
|
||||
"1924",
|
||||
"1925",
|
||||
"1926",
|
||||
"1927",
|
||||
"1928",
|
||||
"1929",
|
||||
"1930",
|
||||
"1931",
|
||||
"1932",
|
||||
"1933",
|
||||
"1934",
|
||||
"1935",
|
||||
"1936",
|
||||
"1937",
|
||||
"1938",
|
||||
"1939",
|
||||
"1940",
|
||||
"1941",
|
||||
"1942",
|
||||
"1943",
|
||||
"1944",
|
||||
"1945",
|
||||
"1946",
|
||||
"1947",
|
||||
"1948",
|
||||
"1949",
|
||||
"1950",
|
||||
"1951",
|
||||
"1952",
|
||||
"1953",
|
||||
"1954",
|
||||
"1955",
|
||||
"1956",
|
||||
"1957",
|
||||
"1958",
|
||||
"1959",
|
||||
"1960",
|
||||
"1961",
|
||||
"1962",
|
||||
"1963",
|
||||
"1964",
|
||||
"1965",
|
||||
"1966",
|
||||
"1967",
|
||||
"1968",
|
||||
"1969",
|
||||
"1970",
|
||||
"1971",
|
||||
"1972",
|
||||
"1973",
|
||||
"1974",
|
||||
"1975",
|
||||
"1976",
|
||||
"1977",
|
||||
"1978",
|
||||
"1979",
|
||||
"1980",
|
||||
"1981",
|
||||
"1982",
|
||||
"1983",
|
||||
"1984",
|
||||
"1985",
|
||||
"1986",
|
||||
"1987",
|
||||
"1988",
|
||||
"1989",
|
||||
"1990",
|
||||
"1991",
|
||||
"1992",
|
||||
"1993",
|
||||
"1994",
|
||||
"1995",
|
||||
"1996",
|
||||
"1997",
|
||||
"1998",
|
||||
"1999",
|
||||
"2000",
|
||||
"2001",
|
||||
"2002",
|
||||
"2003",
|
||||
"2004",
|
||||
"2005",
|
||||
"2006",
|
||||
"2007",
|
||||
"2008",
|
||||
"2009",
|
||||
"2010",
|
||||
"2011",
|
||||
"2012",
|
||||
"2013",
|
||||
"2014",
|
||||
"2015",
|
||||
"2016",
|
||||
"2017",
|
||||
"2018",
|
||||
"2019",
|
||||
"2020",
|
||||
"2021",
|
||||
],
|
||||
skills: ["react", "vue", "angular", "svelte", "javascript"],
|
||||
};
|
||||
|
||||
export default selectData;
|
||||
|
@ -28,153 +28,174 @@ interface Props {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
function EntityForm({ id }: Props): JSX.Element {
|
||||
const qController = new QController("");
|
||||
const { tableName } = useParams();
|
||||
function EntityForm({ id }: Props): JSX.Element
|
||||
{
|
||||
const qController = new QController("");
|
||||
const { tableName } = useParams();
|
||||
|
||||
const [validations, setValidations] = useState({});
|
||||
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
||||
const [formFields, setFormFields] = useState({});
|
||||
const [alertContent, setAlertContent] = useState("");
|
||||
const [validations, setValidations] = useState({});
|
||||
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
||||
const [formFields, setFormFields] = useState({});
|
||||
const [alertContent, setAlertContent] = useState("");
|
||||
|
||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||
const [tableMetaData, setTableMetaData] = useState(null);
|
||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||
const [tableMetaData, setTableMetaData] = useState(null);
|
||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||
|
||||
function getDynamicStepContent(formData: any): JSX.Element {
|
||||
const { formFields, values, errors, touched } = formData;
|
||||
function getDynamicStepContent(formData: any): JSX.Element
|
||||
{
|
||||
const {
|
||||
formFields, values, errors, touched,
|
||||
} = formData;
|
||||
|
||||
if (!Object.keys(formFields).length) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
return <QDynamicForm formData={formData} primaryKeyId={tableMetaData.primaryKeyField} />;
|
||||
}
|
||||
|
||||
if (!asyncLoadInited) {
|
||||
setAsyncLoadInited(true);
|
||||
(async () => {
|
||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
||||
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) {
|
||||
const record = await qController.get(tableName, id);
|
||||
|
||||
tableMetaData.fields.forEach((fieldMetaData, key) => {
|
||||
initialValues[key] = record.values.get(key);
|
||||
});
|
||||
|
||||
setFormValues(formValues);
|
||||
if (!Object.keys(formFields).length)
|
||||
{
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
const { dynamicFormFields, formValidations } = DynamicFormUtils.getFormData(fieldArray);
|
||||
setInitialValues(initialValues);
|
||||
setFormFields(dynamicFormFields);
|
||||
setValidations(Yup.object().shape(formValidations));
|
||||
return <QDynamicForm formData={formData} primaryKeyId={tableMetaData.primaryKeyField} />;
|
||||
}
|
||||
|
||||
forceUpdate();
|
||||
})();
|
||||
}
|
||||
if (!asyncLoadInited)
|
||||
{
|
||||
setAsyncLoadInited(true);
|
||||
(async () =>
|
||||
{
|
||||
const tableMetaData = await qController.loadTableMetaData(tableName);
|
||||
setTableMetaData(tableMetaData);
|
||||
|
||||
const handleSubmit = async (values: any, actions: any) => {
|
||||
actions.setSubmitting(true);
|
||||
await (async () => {
|
||||
if (id !== null) {
|
||||
await qController
|
||||
.update(tableName, id, values)
|
||||
.then((record) => {
|
||||
window.location.href = `/${tableName}/${record.values.get(
|
||||
tableMetaData.primaryKeyField
|
||||
)}`;
|
||||
})
|
||||
.catch((error) => {
|
||||
setAlertContent(error.response.data.error);
|
||||
});
|
||||
} else {
|
||||
await qController
|
||||
.create(tableName, values)
|
||||
.then((record) => {
|
||||
window.location.href = `/${tableName}/${record.values.get(
|
||||
tableMetaData.primaryKeyField
|
||||
)}`;
|
||||
})
|
||||
.catch((error) => {
|
||||
setAlertContent(error.response.data.error);
|
||||
});
|
||||
}
|
||||
})();
|
||||
};
|
||||
const fieldArray = [] as QFieldMetaData[];
|
||||
const sortedKeys = [...tableMetaData.fields.keys()].sort();
|
||||
sortedKeys.forEach((key) =>
|
||||
{
|
||||
const fieldMetaData = tableMetaData.fields.get(key);
|
||||
fieldArray.push(fieldMetaData);
|
||||
});
|
||||
|
||||
const formTitle =
|
||||
id != null ? `Edit ${tableMetaData?.label} (${id})` : `Create New ${tableMetaData?.label}`;
|
||||
const formId =
|
||||
id != null ? `edit-${tableMetaData?.label}-form` : `create-${tableMetaData?.label}-form`;
|
||||
if (id !== null)
|
||||
{
|
||||
const record = await qController.get(tableName, id);
|
||||
|
||||
return (
|
||||
<MDBox mb={3}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
{alertContent ? (
|
||||
<MDBox mb={3}>
|
||||
<Alert severity="error">{alertContent}</Alert>
|
||||
</MDBox>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Card id="edit-form-container" sx={{ overflow: "visible" }}>
|
||||
<MDBox p={3}>
|
||||
<MDTypography variant="h5">{formTitle}</MDTypography>
|
||||
</MDBox>
|
||||
<MDBox pb={3} px={3}>
|
||||
<Grid key="fields-grid" container spacing={3}>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validations}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ values, errors, touched, isSubmitting }) => (
|
||||
<Form id={formId} autoComplete="off">
|
||||
<MDBox p={3} width="100%">
|
||||
{/***************************************************************************
|
||||
tableMetaData.fields.forEach((fieldMetaData, key) =>
|
||||
{
|
||||
initialValues[key] = record.values.get(key);
|
||||
});
|
||||
|
||||
setFormValues(formValues);
|
||||
}
|
||||
|
||||
const { dynamicFormFields, formValidations } = DynamicFormUtils.getFormData(fieldArray);
|
||||
setInitialValues(initialValues);
|
||||
setFormFields(dynamicFormFields);
|
||||
setValidations(Yup.object().shape(formValidations));
|
||||
|
||||
forceUpdate();
|
||||
})();
|
||||
}
|
||||
|
||||
const handleSubmit = async (values: any, actions: any) =>
|
||||
{
|
||||
actions.setSubmitting(true);
|
||||
await (async () =>
|
||||
{
|
||||
if (id !== null)
|
||||
{
|
||||
await qController
|
||||
.update(tableName, id, values)
|
||||
.then((record) =>
|
||||
{
|
||||
window.location.href = `/${tableName}/${record.values.get(
|
||||
tableMetaData.primaryKeyField,
|
||||
)}`;
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
setAlertContent(error.response.data.error);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await qController
|
||||
.create(tableName, values)
|
||||
.then((record) =>
|
||||
{
|
||||
window.location.href = `/${tableName}/${record.values.get(
|
||||
tableMetaData.primaryKeyField,
|
||||
)}`;
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
setAlertContent(error.response.data.error);
|
||||
});
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
const formTitle = id != null ? `Edit ${tableMetaData?.label} (${id})` : `Create New ${tableMetaData?.label}`;
|
||||
const formId = id != null ? `edit-${tableMetaData?.label}-form` : `create-${tableMetaData?.label}-form`;
|
||||
|
||||
return (
|
||||
<MDBox mb={3}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
{alertContent ? (
|
||||
<MDBox mb={3}>
|
||||
<Alert severity="error">{alertContent}</Alert>
|
||||
</MDBox>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Card id="edit-form-container" sx={{ overflow: "visible" }}>
|
||||
<MDBox p={3}>
|
||||
<MDTypography variant="h5">{formTitle}</MDTypography>
|
||||
</MDBox>
|
||||
<MDBox pb={3} px={3}>
|
||||
<Grid key="fields-grid" container spacing={3}>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validations}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({
|
||||
values, errors, touched, isSubmitting,
|
||||
}) => (
|
||||
<Form id={formId} autoComplete="off">
|
||||
<MDBox p={3} width="100%">
|
||||
{/***************************************************************************
|
||||
** 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>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</Grid>
|
||||
</MDBox>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</MDBox>
|
||||
);
|
||||
{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>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</Grid>
|
||||
</MDBox>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</MDBox>
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for DefaultCell
|
||||
EntityForm.defaultProps = {
|
||||
id: null,
|
||||
id: null,
|
||||
};
|
||||
|
||||
export default EntityForm;
|
||||
|
@ -37,80 +37,85 @@ interface Props {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
function Footer({ company, links }: Props): JSX.Element {
|
||||
const { href, name } = company;
|
||||
const { size } = typography;
|
||||
function Footer({ company, links }: Props): JSX.Element
|
||||
{
|
||||
const { href, name } = company;
|
||||
const { size } = typography;
|
||||
|
||||
const renderLinks = () =>
|
||||
links.map((link) => (
|
||||
const renderLinks = () => links.map((link) => (
|
||||
<MDBox key={link.name} component="li" px={2} lineHeight={1}>
|
||||
<Link href={link.href} target="_blank">
|
||||
<MDTypography variant="button" fontWeight="regular" color="text">
|
||||
{link.name}
|
||||
</MDTypography>
|
||||
</Link>
|
||||
<Link href={link.href} target="_blank">
|
||||
<MDTypography variant="button" fontWeight="regular" color="text">
|
||||
{link.name}
|
||||
</MDTypography>
|
||||
</Link>
|
||||
</MDBox>
|
||||
));
|
||||
));
|
||||
|
||||
return (
|
||||
<MDBox
|
||||
width="100%"
|
||||
display="flex"
|
||||
flexDirection={{ xs: "column", lg: "row" }}
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
px={1.5}
|
||||
>
|
||||
return (
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
flexWrap="wrap"
|
||||
color="text"
|
||||
fontSize={size.sm}
|
||||
px={1.5}
|
||||
width="100%"
|
||||
display="flex"
|
||||
flexDirection={{ xs: "column", lg: "row" }}
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
px={1.5}
|
||||
>
|
||||
© {new Date().getFullYear()}, made with
|
||||
<MDBox fontSize={size.md} color="text" mb={-0.5} mx={0.25}>
|
||||
<Icon color="inherit" fontSize="inherit">
|
||||
favorite
|
||||
</Icon>
|
||||
</MDBox>
|
||||
by
|
||||
<Link href={href} target="_blank">
|
||||
<MDTypography variant="button" fontWeight="medium">
|
||||
{name}
|
||||
</MDTypography>
|
||||
</Link>
|
||||
for a better web.
|
||||
</MDBox>
|
||||
<MDBox
|
||||
component="ul"
|
||||
sx={({ breakpoints }) => ({
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
listStyle: "none",
|
||||
mt: 3,
|
||||
mb: 0,
|
||||
p: 0,
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
flexWrap="wrap"
|
||||
color="text"
|
||||
fontSize={size.sm}
|
||||
px={1.5}
|
||||
>
|
||||
©
|
||||
{" "}
|
||||
{new Date().getFullYear()}
|
||||
, made with
|
||||
<MDBox fontSize={size.md} color="text" mb={-0.5} mx={0.25}>
|
||||
<Icon color="inherit" fontSize="inherit">
|
||||
favorite
|
||||
</Icon>
|
||||
</MDBox>
|
||||
by
|
||||
<Link href={href} target="_blank">
|
||||
<MDTypography variant="button" fontWeight="medium">
|
||||
|
||||
{name}
|
||||
|
||||
</MDTypography>
|
||||
</Link>
|
||||
for a better web.
|
||||
</MDBox>
|
||||
<MDBox
|
||||
component="ul"
|
||||
sx={({ breakpoints }) => ({
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
listStyle: "none",
|
||||
mt: 3,
|
||||
mb: 0,
|
||||
p: 0,
|
||||
|
||||
[breakpoints.up("lg")]: {
|
||||
mt: 0,
|
||||
},
|
||||
})}
|
||||
>
|
||||
{renderLinks()}
|
||||
[breakpoints.up("lg")]: {
|
||||
mt: 0,
|
||||
},
|
||||
})}
|
||||
>
|
||||
{renderLinks()}
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Declaring default props for Footer
|
||||
Footer.defaultProps = {
|
||||
company: { href: "https://www.kingsrook.com/", name: "Kingsrook" },
|
||||
links: [{ href: "https://www.kingsrook.com/", name: "Kingsrook" }],
|
||||
company: { href: "https://www.kingsrook.com/", name: "Kingsrook" },
|
||||
links: [{ href: "https://www.kingsrook.com/", name: "Kingsrook" }],
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
|
@ -30,11 +30,14 @@ interface Props {
|
||||
primaryKeyId?: string;
|
||||
}
|
||||
|
||||
function QDynamicForm(props: Props): JSX.Element {
|
||||
const { formData, formLabel, primaryKeyId } = props;
|
||||
const { formFields, values, errors, touched } = formData;
|
||||
function QDynamicForm(props: Props): JSX.Element
|
||||
{
|
||||
const { formData, formLabel, primaryKeyId } = props;
|
||||
const {
|
||||
formFields, values, errors, touched,
|
||||
} = formData;
|
||||
|
||||
/*
|
||||
/*
|
||||
const {
|
||||
firstName: firstNameV,
|
||||
lastName: lastNameV,
|
||||
@ -45,42 +48,45 @@ function QDynamicForm(props: Props): JSX.Element {
|
||||
} = values;
|
||||
*/
|
||||
|
||||
return (
|
||||
<MDBox>
|
||||
<MDBox lineHeight={0}>
|
||||
<MDTypography variant="h5">{formLabel}</MDTypography>
|
||||
{/* TODO - help text
|
||||
return (
|
||||
<MDBox>
|
||||
<MDBox lineHeight={0}>
|
||||
<MDTypography variant="h5">{formLabel}</MDTypography>
|
||||
{/* TODO - help text
|
||||
<MDTypography variant="button" color="text">
|
||||
Mandatory information
|
||||
</MDTypography>
|
||||
*/}
|
||||
</MDBox>
|
||||
<MDBox mt={1.625}>
|
||||
<Grid container spacing={3}>
|
||||
{formFields &&
|
||||
Object.keys(formFields).length > 0 &&
|
||||
Object.keys(formFields).map((fieldName: any) => {
|
||||
const field = formFields[fieldName];
|
||||
if (primaryKeyId && fieldName === primaryKeyId) {
|
||||
return null;
|
||||
}
|
||||
if (values[fieldName] === undefined) {
|
||||
values[fieldName] = "";
|
||||
}
|
||||
return (
|
||||
<Grid item xs={12} sm={6} key={fieldName}>
|
||||
<FormField
|
||||
type={field.type}
|
||||
label={field.label}
|
||||
name={fieldName}
|
||||
value={values[fieldName]}
|
||||
error={errors[fieldName] && touched[fieldName]}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
</MDBox>
|
||||
<MDBox mt={1.625}>
|
||||
<Grid container spacing={3}>
|
||||
{formFields
|
||||
&& Object.keys(formFields).length > 0
|
||||
&& Object.keys(formFields).map((fieldName: any) =>
|
||||
{
|
||||
const field = formFields[fieldName];
|
||||
if (primaryKeyId && fieldName === primaryKeyId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (values[fieldName] === undefined)
|
||||
{
|
||||
values[fieldName] = "";
|
||||
}
|
||||
return (
|
||||
<Grid item xs={12} sm={6} key={fieldName}>
|
||||
<FormField
|
||||
type={field.type}
|
||||
label={field.label}
|
||||
name={fieldName}
|
||||
value={values[fieldName]}
|
||||
error={errors[fieldName] && touched[fieldName]}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
{/*
|
||||
</Grid>
|
||||
{/*
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<FormField
|
||||
@ -154,14 +160,14 @@ function QDynamicForm(props: Props): JSX.Element {
|
||||
</Grid>
|
||||
</Grid>
|
||||
*/}
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
QDynamicForm.defaultProps = {
|
||||
formLabel: undefined,
|
||||
primaryKeyId: undefined,
|
||||
formLabel: undefined,
|
||||
primaryKeyId: undefined,
|
||||
};
|
||||
|
||||
export default QDynamicForm;
|
||||
|
@ -30,51 +30,56 @@ import { QFieldType } from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFie
|
||||
** Meta-data to represent a single field in a table.
|
||||
**
|
||||
*******************************************************************************/
|
||||
class DynamicFormUtils {
|
||||
public static getFormData(qqqFormFields: QFieldMetaData[]) {
|
||||
const dynamicFormFields: any = {};
|
||||
const formValidations: any = {};
|
||||
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";
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
let label = field.label ? field.label : field.name;
|
||||
label += field.isRequired ? " *" : "";
|
||||
let label = field.label ? field.label : field.name;
|
||||
label += field.isRequired ? " *" : "";
|
||||
|
||||
dynamicFormFields[field.name] = {
|
||||
name: field.name,
|
||||
label: label,
|
||||
isRequired: field.isRequired,
|
||||
type: fieldType,
|
||||
// todo invalidMsg: "Zipcode is not valid (e.g. 70000).",
|
||||
};
|
||||
dynamicFormFields[field.name] = {
|
||||
name: field.name,
|
||||
label: label,
|
||||
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.`);
|
||||
}
|
||||
});
|
||||
if (field.isRequired)
|
||||
{
|
||||
formValidations[field.name] = Yup.string().required(`${field.label} is required.`);
|
||||
}
|
||||
});
|
||||
|
||||
return { dynamicFormFields, formValidations };
|
||||
}
|
||||
return { dynamicFormFields, formValidations };
|
||||
}
|
||||
}
|
||||
|
||||
export default DynamicFormUtils;
|
||||
|
Reference in New Issue
Block a user