From 16f15e5273898d639595dadd40ddcbe05094cf27 Mon Sep 17 00:00:00 2001 From: Jefferson Silva Date: Thu, 29 Aug 2024 15:16:06 -0300 Subject: [PATCH 1/3] refactor: move form props and adjust toggle function --- .../submodules/DrawerForm/index.tsx | 60 +---- .../components/submodules/ModalForm/index.tsx | 210 +++++++----------- .../src/components/submodules/types/Form.ts | 48 ++++ .../src/modules/crud/index.tsx | 22 +- 4 files changed, 145 insertions(+), 195 deletions(-) create mode 100644 packages/react-material-ui/src/components/submodules/types/Form.ts diff --git a/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx b/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx index db862d7e..5ee1e758 100644 --- a/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx +++ b/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx @@ -1,8 +1,5 @@ -import React, { useState, PropsWithChildren, ReactNode } from 'react'; - -import type { RJSFSchema, UiSchema, CustomValidator } from '@rjsf/utils'; -import type { IChangeEvent, FormProps } from '@rjsf/core'; - +import React, { useState } from 'react'; +import type { IChangeEvent } from '@rjsf/core'; import { Box, Drawer, @@ -17,53 +14,11 @@ import CloseIcon from '@mui/icons-material/Close'; import useDataProvider, { useQuery } from '@concepta/react-data-provider'; import validator from '@rjsf/validator-ajv6'; -import { SchemaForm, SchemaFormProps } from '../../../components/SchemaForm'; - +import { SchemaForm } from '../../../components/SchemaForm'; import { CustomTextFieldWidget } from '../../../styles/CustomWidgets'; +import { FormSubmoduleProps } from '../types/Form'; -type Action = 'creation' | 'edit' | 'details' | null; - -type DrawerFormSubmoduleProps = PropsWithChildren< - Omit< - SchemaFormProps, - | 'schema' - | 'uiSchema' - | 'validator' - | 'onSubmit' - | 'noHtml5Validate' - | 'showErrorList' - | 'formData' - | 'readonly' - | 'customValidate' - > -> & { - queryResource: string; - title?: string; - formSchema?: RJSFSchema; - viewMode?: Action | null; - formUiSchema?: UiSchema; - formData?: Record | null; - submitButtonTitle?: string; - cancelButtonTitle?: string; - hideCancelButton?: boolean; - customFooterContent?: ReactNode; - onClose?: () => void; - customValidate?: CustomValidator; - widgets?: FormProps['widgets']; - onSuccess?: (data: unknown) => void; - onError?: (error: unknown) => void; - onDeleteSuccess?: (data: unknown) => void; - onDeleteError?: (error: unknown) => void; - onPrevious?: (data: unknown) => void; - onNext?: (data: unknown) => void; - isLoading?: boolean; - viewIndex?: number; - rowsPerPage?: number; - currentPage?: number; - pageCount?: number; -}; - -const DrawerFormSubmodule = (props: DrawerFormSubmoduleProps) => { +const DrawerFormSubmodule = (props: FormSubmoduleProps) => { const { queryResource, viewMode, @@ -87,11 +42,12 @@ const DrawerFormSubmodule = (props: DrawerFormSubmoduleProps) => { rowsPerPage, currentPage, pageCount, + isVisible, ...otherProps } = props; const [fieldValues, setFieldValues] = - useState(null); + useState(null); const { post, patch, del } = useDataProvider(); @@ -155,7 +111,7 @@ const DrawerFormSubmodule = (props: DrawerFormSubmoduleProps) => { }; return ( - + -> & { - title?: string; - queryResource: string; - formSchema?: RJSFSchema; - viewMode?: Action | null; - formUiSchema?: UiSchema; - formData?: Record | null; - submitButtonTitle?: string; - cancelButtonTitle?: string; - hideCancelButton?: boolean; - customFooterContent?: ReactNode; - onClose?: () => void; - customValidate?: CustomValidator; - widgets?: FormProps['widgets']; - onSuccess?: (data: unknown) => void; - onError?: (error: unknown) => void; - onDeleteSuccess?: (data: unknown) => void; - onDeleteError?: (error: unknown) => void; - onPrevious?: (data: unknown) => void; - onNext?: (data: unknown) => void; - isLoading?: boolean; - viewIndex?: number; - rowsPerPage?: number; - currentPage?: number; - pageCount?: number; -}; - -const ModalFormSubmodule = (props: ModalFormSubmoduleProps) => { +const ModalFormSubmodule = (props: FormSubmoduleProps) => { const { queryResource, viewMode, @@ -87,6 +44,7 @@ const ModalFormSubmodule = (props: ModalFormSubmoduleProps) => { rowsPerPage, currentPage, pageCount, + isVisible, ...otherProps } = props; @@ -150,7 +108,7 @@ const ModalFormSubmodule = (props: ModalFormSubmoduleProps) => { }; return ( - + {viewMode === 'creation' ? 'Add Data' @@ -189,92 +147,88 @@ const ModalFormSubmodule = (props: ModalFormSubmoduleProps) => { readonly={viewMode === 'details'} {...otherProps} > - <> - {children} + {children} + + {viewMode !== 'creation' && ( + + onPrevious(formData)} + disabled={isLoading || (currentPage === 1 && viewIndex === 1)} + > + + + + {isLoading ? '' : `Row ${viewIndex}/${rowsPerPage}`} + + onNext(formData)} + disabled={ + isLoading || + (currentPage === pageCount && viewIndex === rowsPerPage) + } + > + + + + )} - {viewMode !== 'creation' && ( - - onPrevious(formData)} - disabled={ - isLoading || (currentPage === 1 && viewIndex === 1) - } - > - - - - {isLoading ? '' : `Row ${viewIndex}/${rowsPerPage}`} - - onNext(formData)} - disabled={ - isLoading || - (currentPage === pageCount && viewIndex === rowsPerPage) - } - > - - - + {props.customFooterContent} + {viewMode === 'creation' && !props.hideCancelButton && ( + + )} + {viewMode === 'edit' && !props.hideCancelButton && ( + + )} + {viewMode === 'details' && !props.hideCancelButton && ( + + )} + {viewMode !== 'details' && ( + )} - - {props.customFooterContent} - {viewMode === 'creation' && !props.hideCancelButton && ( - - )} - {viewMode === 'edit' && !props.hideCancelButton && ( - - )} - {viewMode === 'details' && !props.hideCancelButton && ( - - )} - {viewMode !== 'details' && ( - - )} - - + diff --git a/packages/react-material-ui/src/components/submodules/types/Form.ts b/packages/react-material-ui/src/components/submodules/types/Form.ts new file mode 100644 index 00000000..90f6a148 --- /dev/null +++ b/packages/react-material-ui/src/components/submodules/types/Form.ts @@ -0,0 +1,48 @@ +import { PropsWithChildren, ReactNode } from 'react'; +import { RJSFSchema, UiSchema, CustomValidator } from '@rjsf/utils'; +import { FormProps } from '@rjsf/core'; + +import { SchemaFormProps } from '../../../components/SchemaForm'; + +export type Action = 'creation' | 'edit' | 'details' | null; + +export type FormSubmoduleProps = PropsWithChildren< + Omit< + SchemaFormProps, + | 'schema' + | 'uiSchema' + | 'validator' + | 'onSubmit' + | 'noHtml5Validate' + | 'showErrorList' + | 'formData' + | 'readonly' + | 'customValidate' + > +> & { + isVisible: boolean; + queryResource: string; + title?: string; + formSchema?: RJSFSchema; + viewMode?: Action | null; + formUiSchema?: UiSchema; + formData?: Record | null; + submitButtonTitle?: string; + cancelButtonTitle?: string; + hideCancelButton?: boolean; + customFooterContent?: ReactNode; + onClose?: () => void; + customValidate?: CustomValidator; + widgets?: FormProps['widgets']; + onSuccess?: (data: unknown) => void; + onError?: (error: unknown) => void; + onDeleteSuccess?: (data: unknown) => void; + onDeleteError?: (error: unknown) => void; + onPrevious?: (data: unknown) => void; + onNext?: (data: unknown) => void; + isLoading?: boolean; + viewIndex?: number; + rowsPerPage?: number; + currentPage?: number; + pageCount?: number; +}; diff --git a/packages/react-material-ui/src/modules/crud/index.tsx b/packages/react-material-ui/src/modules/crud/index.tsx index bf098038..e7b59d95 100644 --- a/packages/react-material-ui/src/modules/crud/index.tsx +++ b/packages/react-material-ui/src/modules/crud/index.tsx @@ -89,6 +89,7 @@ const CrudModule = (props: ModuleProps) => { const [drawerViewMode, setDrawerViewMode] = useState(null); const [selectedRow, setSelectedRow] = useState(null); const [currentViewIndex, setCurrentViewIndex] = useState(0); + const [isFormVisible, setFormVisible] = useState(false); const useTableReturn = useTable(props.resource, { callbacks: { @@ -224,11 +225,13 @@ const CrudModule = (props: ModuleProps) => { setSelectedRow(payload.row); setDrawerViewMode(payload.action); setCurrentViewIndex(payload.index); + setFormVisible(true); }} onAddNew={() => { setSelectedRow(null); setDrawerViewMode('creation'); setCurrentViewIndex(0); + setFormVisible(true); }} hideAddButton={!props.createFormProps} hideEditButton={!props.editFormProps || props.hideEditButton} @@ -250,37 +253,26 @@ const CrudModule = (props: ModuleProps) => { {enhancedFormProps && ( { useTableReturn.refresh(); - - setSelectedRow(null); - setDrawerViewMode(null); - setCurrentViewIndex(0); - + setFormVisible(false); if (formOnSuccess) { formOnSuccess(data); } }} onDeleteSuccess={(data) => { useTableReturn.refresh(); - - setSelectedRow(null); - setDrawerViewMode(null); - setCurrentViewIndex(0); - + setFormVisible(false); if (formOnDeleteSuccess) { formOnDeleteSuccess(data); } }} - onClose={() => { - setSelectedRow(null); - setDrawerViewMode(null); - setCurrentViewIndex(0); - }} + onClose={() => setFormVisible(false)} onPrevious={() => changeCurrentFormData('previous')} onNext={() => changeCurrentFormData('next')} isLoading={isPending} From 9ce9d58a8f80a5dcd473e6c0799089dce25fa649 Mon Sep 17 00:00:00 2001 From: Jefferson Silva Date: Thu, 29 Aug 2024 16:12:56 -0300 Subject: [PATCH 2/3] refactor: move table row controls to separate component --- .../submodules/DrawerForm/index.tsx | 37 ++++++-------- .../components/submodules/ModalForm/index.tsx | 38 ++++++-------- .../submodules/TableRowControls/index.tsx | 51 +++++++++++++++++++ 3 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 packages/react-material-ui/src/components/submodules/TableRowControls/index.tsx diff --git a/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx b/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx index 5ee1e758..a7ee8abd 100644 --- a/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx +++ b/packages/react-material-ui/src/components/submodules/DrawerForm/index.tsx @@ -8,8 +8,6 @@ import { IconButton, Typography, } from '@mui/material'; -import ChevronLeft from '@mui/icons-material/ChevronLeft'; -import ChevronRight from '@mui/icons-material/ChevronRight'; import CloseIcon from '@mui/icons-material/Close'; import useDataProvider, { useQuery } from '@concepta/react-data-provider'; import validator from '@rjsf/validator-ajv6'; @@ -17,6 +15,7 @@ import validator from '@rjsf/validator-ajv6'; import { SchemaForm } from '../../../components/SchemaForm'; import { CustomTextFieldWidget } from '../../../styles/CustomWidgets'; import { FormSubmoduleProps } from '../types/Form'; +import TableRowControls from '../TableRowControls'; const DrawerFormSubmodule = (props: FormSubmoduleProps) => { const { @@ -181,26 +180,20 @@ const DrawerFormSubmodule = (props: FormSubmoduleProps) => { } > {viewMode !== 'creation' && ( - - onPrevious(formData)} - disabled={isLoading || (currentPage === 1 && viewIndex === 1)} - > - - - - {isLoading ? '' : `Row ${viewIndex}/${rowsPerPage}`} - - onNext(formData)} - disabled={ - isLoading || - (currentPage === pageCount && viewIndex === rowsPerPage) - } - > - - - + onPrevious(formData)} + onNext={() => onNext(formData)} + /> )} {props.customFooterContent} diff --git a/packages/react-material-ui/src/components/submodules/ModalForm/index.tsx b/packages/react-material-ui/src/components/submodules/ModalForm/index.tsx index 1b6bc0b2..1ebe9d60 100644 --- a/packages/react-material-ui/src/components/submodules/ModalForm/index.tsx +++ b/packages/react-material-ui/src/components/submodules/ModalForm/index.tsx @@ -8,10 +8,7 @@ import { DialogTitle, DialogContent, IconButton, - Typography, } from '@mui/material'; -import ChevronLeft from '@mui/icons-material/ChevronLeft'; -import ChevronRight from '@mui/icons-material/ChevronRight'; import CloseIcon from '@mui/icons-material/Close'; import useDataProvider, { useQuery } from '@concepta/react-data-provider'; import validator from '@rjsf/validator-ajv6'; @@ -19,6 +16,7 @@ import validator from '@rjsf/validator-ajv6'; import { SchemaForm } from '../../../components/SchemaForm'; import { CustomTextFieldWidget } from '../../../styles/CustomWidgets'; import { FormSubmoduleProps } from '../types/Form'; +import TableRowControls from '../TableRowControls'; const ModalFormSubmodule = (props: FormSubmoduleProps) => { const { @@ -158,26 +156,20 @@ const ModalFormSubmodule = (props: FormSubmoduleProps) => { mt={4} > {viewMode !== 'creation' && ( - - onPrevious(formData)} - disabled={isLoading || (currentPage === 1 && viewIndex === 1)} - > - - - - {isLoading ? '' : `Row ${viewIndex}/${rowsPerPage}`} - - onNext(formData)} - disabled={ - isLoading || - (currentPage === pageCount && viewIndex === rowsPerPage) - } - > - - - + onPrevious(formData)} + onNext={() => onNext(formData)} + /> )} void; + onNext: () => void; +}; + +const TableRowControls = (props: Props) => { + const { + isLoading, + currentIndex, + rowsPerPage, + isPreviousDisabled, + isNextDisabled, + onPrevious, + onNext, + } = props; + + return ( + + + + + + {isLoading ? ( + + ) : ( + `Row ${currentIndex}/${rowsPerPage}` + )} + + + + + + ); +}; + +export default TableRowControls; From 98c749613a0da73095a5eb7e908a251fd200e4bd Mon Sep 17 00:00:00 2001 From: Jefferson Silva Date: Thu, 29 Aug 2024 17:50:57 -0300 Subject: [PATCH 3/3] refactor: change position of action buttons on filter row --- .../components/submodules/Filter/index.tsx | 3 +- .../src/components/submodules/Table/index.tsx | 70 +++++++++---------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/packages/react-material-ui/src/components/submodules/Filter/index.tsx b/packages/react-material-ui/src/components/submodules/Filter/index.tsx index 89c6e847..1f102059 100644 --- a/packages/react-material-ui/src/components/submodules/Filter/index.tsx +++ b/packages/react-material-ui/src/components/submodules/Filter/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, ReactNode } from 'react'; import { Filter, FilterVariant, @@ -42,6 +42,7 @@ export type FilterCallback = (filter: FilterValues) => void; type Props = { orderableListCacheKey?: string; cacheApiPath?: string; + complementaryActions?: ReactNode; }; const FilterSubmodule = (props: Props) => { diff --git a/packages/react-material-ui/src/components/submodules/Table/index.tsx b/packages/react-material-ui/src/components/submodules/Table/index.tsx index 66ca9d2a..2324eede 100644 --- a/packages/react-material-ui/src/components/submodules/Table/index.tsx +++ b/packages/react-material-ui/src/components/submodules/Table/index.tsx @@ -278,45 +278,41 @@ const TableSubmodule = (props: TableSubmoduleProps) => { + {props.reordable !== false && ( + + )} + + {props.additionalFilterRowContent} + {!props.hideAddButton && ( + + )} + + + } /> )} - - - {props.reordable !== false && ( - - )} - - {props.additionalFilterRowContent} - {!props.hideAddButton && ( - - )} - -