mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
Feedback from code reviews
This commit is contained in:
@ -29,6 +29,8 @@ import Avatar from "@mui/material/Avatar";
|
||||
import Icon from "@mui/material/Icon";
|
||||
import QRecordSidebar from "qqq/components/QRecordSidebar";
|
||||
import QTableUtils from "qqq/utils/QTableUtils";
|
||||
import colors from "assets/theme/base/colors";
|
||||
import {QSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QSection";
|
||||
|
||||
interface Props
|
||||
{
|
||||
@ -46,6 +48,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
const [initialValues, setInitialValues] = useState({} as { [key: string]: string });
|
||||
const [formFields, setFormFields] = useState(null as Map<string, any>);
|
||||
const [t1sectionName, setT1SectionName] = useState(null as string);
|
||||
const [nonT1Sections, setNonT1Sections] = useState([] as QSection[]);
|
||||
|
||||
const [alertContent, setAlertContent] = useState("");
|
||||
|
||||
@ -53,7 +56,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||
const [tableMetaData, setTableMetaData] = useState(null as QTableMetaData);
|
||||
const [record, setRecord] = useState(null as QRecord);
|
||||
const [tableSections, setTableSections] = useState(null as any);
|
||||
const [tableSections, setTableSections] = useState(null as QSection[]);
|
||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -76,7 +79,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
{
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
return <QDynamicForm formData={formData} primaryKeyId={tableMetaData.primaryKeyField} />;
|
||||
return <QDynamicForm formData={formData} />;
|
||||
}
|
||||
|
||||
if (!asyncLoadInited)
|
||||
@ -131,6 +134,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
/////////////////////////////////////
|
||||
const dynamicFormFieldsBySection = new Map<string, any>();
|
||||
let t1sectionName;
|
||||
const nonT1Sections: QSection[] = [];
|
||||
for (let i = 0; i < tableSections.length; i++)
|
||||
{
|
||||
const section = tableSections[i];
|
||||
@ -140,6 +144,11 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
{
|
||||
const fieldName = section.fieldNames[j];
|
||||
const field = tableMetaData.fields.get(fieldName);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if id !== null - means we're on the edit screen -- show all fields on the edit screen. //
|
||||
// || (or) we're on the insert screen in which case, only show editable fields. //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if (id !== null || field.isEditable)
|
||||
{
|
||||
sectionDynamicFormFields.push(dynamicFormFields[fieldName]);
|
||||
@ -153,6 +162,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
tableSections.splice(i, 1);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -166,8 +176,13 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
{
|
||||
t1sectionName = section.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
nonT1Sections.push(section);
|
||||
}
|
||||
}
|
||||
setT1SectionName(t1sectionName);
|
||||
setNonT1Sections(nonT1Sections);
|
||||
setFormFields(dynamicFormFieldsBySection);
|
||||
setValidations(Yup.object().shape(formValidations));
|
||||
|
||||
@ -177,6 +192,11 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
|
||||
const handleCancelClicked = () =>
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// todo - we might have rather just done a navigate(-1) (to keep history clean) //
|
||||
// but if the user used the anchors on the page, this doesn't effectively cancel... //
|
||||
// what we have here pushed a new history entry (I think?), so could be better //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (id !== null)
|
||||
{
|
||||
const path = `${location.pathname.replace(/\/edit$/, "")}`;
|
||||
@ -274,7 +294,7 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
<Card id={`${t1sectionName}`} sx={{overflow: "visible"}}>
|
||||
<MDBox display="flex" p={3} pb={1}>
|
||||
<MDBox mr={1.5}>
|
||||
<Avatar sx={{bgcolor: "rgb(26, 115, 232)"}}>
|
||||
<Avatar sx={{bgcolor: colors.info.main}}>
|
||||
<Icon>
|
||||
{tableMetaData?.iconName}
|
||||
</Icon>
|
||||
@ -295,23 +315,22 @@ function EntityForm({table, id}: Props): JSX.Element
|
||||
}
|
||||
</Card>
|
||||
</MDBox>
|
||||
{tableSections && formFields ? tableSections.map((section: any) => (section.name !== t1sectionName
|
||||
? (
|
||||
<MDBox key={`edit-card-${section.name}`} pb={3}>
|
||||
<Card id={section.name} sx={{overflow: "visible"}}>
|
||||
<MDTypography variant="h5" p={3} pb={1}>
|
||||
{section.label}
|
||||
</MDTypography>
|
||||
<MDBox pb={3} px={3}>
|
||||
<MDBox p={3} width="100%">
|
||||
{
|
||||
getFormSection(values, touched, formFields.get(section.name), errors)
|
||||
}
|
||||
</MDBox>
|
||||
{formFields && nonT1Sections.length ? nonT1Sections.map((section: QSection) => (
|
||||
<MDBox key={`edit-card-${section.name}`} pb={3}>
|
||||
<Card id={section.name} sx={{overflow: "visible"}}>
|
||||
<MDTypography variant="h5" p={3} pb={1}>
|
||||
{section.label}
|
||||
</MDTypography>
|
||||
<MDBox pb={3} px={3}>
|
||||
<MDBox p={3} width="100%">
|
||||
{
|
||||
getFormSection(values, touched, formFields.get(section.name), errors)
|
||||
}
|
||||
</MDBox>
|
||||
</Card>
|
||||
</MDBox>
|
||||
) : null)) : null}
|
||||
</MDBox>
|
||||
</Card>
|
||||
</MDBox>
|
||||
)) : null}
|
||||
|
||||
<MDBox component="div" p={3}>
|
||||
<Grid container justifyContent="flex-end" spacing={3}>
|
||||
|
@ -58,7 +58,7 @@ import {
|
||||
} from "context";
|
||||
|
||||
// qqq
|
||||
import QBreadcrumbs from "qqq/components/QBreadcrumbs";
|
||||
import QBreadcrumbs, {routeToLabel} from "qqq/components/QBreadcrumbs";
|
||||
|
||||
// Declaring prop types for Navbar
|
||||
interface Props
|
||||
@ -156,7 +156,7 @@ function Navbar({absolute, light, isMini}: Props): JSX.Element
|
||||
},
|
||||
});
|
||||
|
||||
const breadcrumbTitle = route[route.length - 1].replace(/([A-Z])/g, " $1").trim();
|
||||
const breadcrumbTitle = routeToLabel(route[route.length - 1]);
|
||||
|
||||
return (
|
||||
<AppBar
|
||||
|
@ -44,9 +44,14 @@ const ucFirst = (input: string): string =>
|
||||
return (input.substring(0, 1).toUpperCase() + input.substring(1));
|
||||
};
|
||||
|
||||
const routeToLabel = (route: string): string =>
|
||||
export const routeToLabel = (route: string): string =>
|
||||
{
|
||||
const label = ucFirst(route.replace(".", " ").replace("-", " ").replace("_", " ").replace(/([A-Z])/g, " $1"));
|
||||
const label = ucFirst(route
|
||||
.replace(".", " ")
|
||||
.replace("-", " ")
|
||||
.replace("_", " ")
|
||||
.replace(/([a-z])([A-Z]+)/g, "$1 $2") // transform personUSA => person USA
|
||||
.replace(/^([A-Z]+)([A-Z])([a-z])/, "$1 $2$3")); // transform USAPerson => USA Person
|
||||
return (label);
|
||||
};
|
||||
|
||||
|
@ -61,12 +61,10 @@ interface QDeleteButtonProps
|
||||
export function QDeleteButton({onClickHandler}: QDeleteButtonProps): JSX.Element
|
||||
{
|
||||
return (
|
||||
<MDBox ml={3} mr={3}>
|
||||
<MDBox width={standardWidth}>
|
||||
<MDButton variant="gradient" color="primary" size="small" onClick={onClickHandler} fullWidth startIcon={<Icon>delete</Icon>}>
|
||||
Delete
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
<MDBox ml={3} mr={3} width={standardWidth}>
|
||||
<MDButton variant="gradient" color="primary" size="small" onClick={onClickHandler} fullWidth startIcon={<Icon>delete</Icon>}>
|
||||
Delete
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
);
|
||||
}
|
||||
@ -74,13 +72,11 @@ export function QDeleteButton({onClickHandler}: QDeleteButtonProps): JSX.Element
|
||||
export function QEditButton(): JSX.Element
|
||||
{
|
||||
return (
|
||||
<MDBox>
|
||||
<MDBox width={standardWidth}>
|
||||
<Link to="edit">
|
||||
<MDBox width={standardWidth}>
|
||||
<MDButton variant="gradient" color="dark" size="small" fullWidth startIcon={<Icon>edit</Icon>}>
|
||||
Edit
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
<MDButton variant="gradient" color="dark" size="small" fullWidth startIcon={<Icon>edit</Icon>}>
|
||||
Edit
|
||||
</MDButton>
|
||||
</Link>
|
||||
</MDBox>
|
||||
);
|
||||
|
@ -34,7 +34,6 @@ import QDynamicFormField from "qqq/components/QDynamicFormField";
|
||||
interface Props {
|
||||
formLabel?: string;
|
||||
formData: any;
|
||||
primaryKeyId?: string;
|
||||
bulkEditMode?: boolean;
|
||||
bulkEditSwitchChangeHandler?: any
|
||||
}
|
||||
@ -42,7 +41,7 @@ interface Props {
|
||||
function QDynamicForm(props: Props): JSX.Element
|
||||
{
|
||||
const {
|
||||
formData, formLabel, primaryKeyId, bulkEditMode, bulkEditSwitchChangeHandler,
|
||||
formData, formLabel, bulkEditMode, bulkEditSwitchChangeHandler,
|
||||
} = props;
|
||||
const {
|
||||
formFields, values, errors, touched,
|
||||
@ -116,7 +115,7 @@ function QDynamicForm(props: Props): JSX.Element
|
||||
error={errors[fieldName] && touched[fieldName]}
|
||||
bulkEditMode={bulkEditMode}
|
||||
bulkEditSwitchChangeHandler={bulkEditSwitchChanged}
|
||||
success={!errors[fieldName] && touched[fieldName]}
|
||||
success={`${values[fieldName]}` !== "" && !errors[fieldName] && touched[fieldName]}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
@ -129,7 +128,6 @@ function QDynamicForm(props: Props): JSX.Element
|
||||
|
||||
QDynamicForm.defaultProps = {
|
||||
formLabel: undefined,
|
||||
primaryKeyId: undefined,
|
||||
bulkEditMode: false,
|
||||
bulkEditSwitchChangeHandler: () =>
|
||||
{},
|
||||
|
@ -26,7 +26,6 @@ import {ErrorMessage, Field} from "formik";
|
||||
import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
import MDInput from "components/MDInput";
|
||||
import QDynamicForm from "qqq/components/QDynamicForm";
|
||||
import React, {useState} from "react";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Switch from "@mui/material/Switch";
|
||||
|
@ -28,9 +28,10 @@ import MDBox from "components/MDBox";
|
||||
import MDTypography from "components/MDTypography";
|
||||
import Card from "@mui/material/Card";
|
||||
import {Theme} from "@mui/material/styles";
|
||||
import {QSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QSection";
|
||||
|
||||
interface Props {
|
||||
tableSections: any;
|
||||
tableSections: QSection[];
|
||||
light?: boolean;
|
||||
}
|
||||
|
||||
@ -40,11 +41,11 @@ function QRecordSidebar({tableSections, light}: Props): JSX.Element
|
||||
<Card sx={{borderRadius: ({borders: {borderRadius}}) => borderRadius.lg, position: "sticky", top: "1%"}}>
|
||||
<MDBox component="ul" display="flex" flexDirection="column" p={2} m={0} sx={{listStyle: "none"}}>
|
||||
{
|
||||
tableSections ? tableSections.map(({icon, label, name}: any, key: number) => (
|
||||
<MDBox key={`section-${name}`} component="li" pt={key === 0 ? 0 : 1}>
|
||||
tableSections ? tableSections.map((section: QSection, key: number) => (
|
||||
<MDBox key={`section-${section.name}`} component="li" pt={key === 0 ? 0 : 1}>
|
||||
<MDTypography
|
||||
component="a"
|
||||
href={`#${name}`}
|
||||
href={`#${section.name}`}
|
||||
variant="button"
|
||||
fontWeight="regular"
|
||||
sx={({
|
||||
@ -65,9 +66,9 @@ function QRecordSidebar({tableSections, light}: Props): JSX.Element
|
||||
})}
|
||||
>
|
||||
<MDBox mr={1.5} lineHeight={1} color="black">
|
||||
<Icon fontSize="small">{icon}</Icon>
|
||||
<Icon fontSize="small">{section.iconName}</Icon>
|
||||
</MDBox>
|
||||
{label}
|
||||
{section.label}
|
||||
</MDTypography>
|
||||
</MDBox>
|
||||
)) : null
|
||||
|
Reference in New Issue
Block a user