@applica-software-guru/react-admin 1.0.32 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +43 -0
- package/.husky/pre-commit +4 -0
- package/.nvmrc +1 -0
- package/.prettierrc +8 -0
- package/bitbucket-pipelines.yml +30 -0
- package/dist/Admin.d.ts +1 -1
- package/dist/ApplicaAdmin.d.ts +3 -3
- package/dist/ApplicaAdmin.d.ts.map +1 -1
- package/dist/components/@extended/AnimateButton.d.ts +5 -5
- package/dist/components/@extended/Avatar.d.ts +3 -3
- package/dist/components/@extended/Breadcrumbs.d.ts +5 -5
- package/dist/components/@extended/Dot.d.ts +1 -1
- package/dist/components/@extended/Tooltip.d.ts +1 -1
- package/dist/components/ActionsMenu.d.ts +1 -1
- package/dist/components/ActionsMenu.d.ts.map +1 -1
- package/dist/components/Layout/Drawer/DrawerContent/Navigation/NavGroup.d.ts +1 -1
- package/dist/components/Layout/Drawer/DrawerContent/Navigation/NavGroup.d.ts.map +1 -1
- package/dist/components/Layout/Drawer/DrawerHeader/DrawerHeaderStyled.d.ts +5 -5
- package/dist/components/Layout/Header/AppBarStyled.d.ts +13 -13
- package/dist/components/Layout/Header/HeaderContent/NotificationItem.d.ts +3 -3
- package/dist/components/Logo.d.ts +2 -2
- package/dist/components/MenuPopover/MenuPopover.d.ts +1 -1
- package/dist/components/Notification.d.ts +5 -1
- package/dist/components/Notification.d.ts.map +1 -1
- package/dist/components/ra-buttons/CreateInDialogButton.d.ts +16 -1
- package/dist/components/ra-buttons/CreateInDialogButton.d.ts.map +1 -1
- package/dist/components/ra-buttons/ImpersonateUserButton.d.ts +1 -1
- package/dist/components/ra-fields/ActionsField.d.ts +1 -1
- package/dist/components/ra-fields/ActionsField.d.ts.map +1 -1
- package/dist/components/ra-fields/AttachmentField.d.ts +19 -1
- package/dist/components/ra-fields/AttachmentField.d.ts.map +1 -1
- package/dist/components/ra-fields/BaseAttachmentField.d.ts +2 -2
- package/dist/components/ra-fields/CoverField.d.ts +19 -1
- package/dist/components/ra-fields/CoverField.d.ts.map +1 -1
- package/dist/components/ra-fields/EmailField.d.ts +12 -1
- package/dist/components/ra-fields/FileField.d.ts +19 -1
- package/dist/components/ra-fields/FileField.d.ts.map +1 -1
- package/dist/components/ra-fields/ImageField.d.ts +15 -1
- package/dist/components/ra-fields/ImageField.d.ts.map +1 -1
- package/dist/components/ra-fields/ReadonlyField.d.ts +1 -1
- package/dist/components/ra-fields/ReferenceManyField.d.ts +32 -2
- package/dist/components/ra-fields/ReferenceManyField.d.ts.map +1 -1
- package/dist/components/ra-forms/Edit.d.ts +24 -1
- package/dist/components/ra-forms/Edit.d.ts.map +1 -1
- package/dist/components/ra-forms/LongForm/LongFormHeader.d.ts +1 -1
- package/dist/components/ra-forms/LongForm/LongFormHeader.d.ts.map +1 -1
- package/dist/components/ra-forms/LongForm/LongFormTab.d.ts +4 -4
- package/dist/components/ra-forms/LongForm/LongFormTab.d.ts.map +1 -1
- package/dist/components/ra-forms/LongForm/LongFormTabs.d.ts +2 -2
- package/dist/components/ra-forms/SimpleForm.d.ts +13 -1
- package/dist/components/ra-forms/SimpleForm.d.ts.map +1 -1
- package/dist/components/ra-forms/TabbedForm.d.ts +9 -1
- package/dist/components/ra-forms/TabbedForm.d.ts.map +1 -1
- package/dist/components/ra-forms/Toolbar.d.ts +5 -1
- package/dist/components/ra-inputs/AttachmentInput.d.ts +20 -1
- package/dist/components/ra-inputs/AttachmentInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/AutocompleteArrayInput.d.ts +1 -2
- package/dist/components/ra-inputs/AutocompleteArrayInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/AutocompleteInput.d.ts +1 -2
- package/dist/components/ra-inputs/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/BooleanInput.d.ts +19 -2
- package/dist/components/ra-inputs/BooleanInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/DateInput.d.ts +11 -1
- package/dist/components/ra-inputs/FileInput.d.ts +21 -1
- package/dist/components/ra-inputs/FileInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/LabeledInput.d.ts +2 -2
- package/dist/components/ra-inputs/NumberInput.d.ts +19 -2
- package/dist/components/ra-inputs/RecordInput.d.ts +1 -1
- package/dist/components/ra-inputs/ReferenceArrayInput.d.ts +25 -2
- package/dist/components/ra-inputs/ReferenceArrayInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/ReferenceInput.d.ts +26 -2
- package/dist/components/ra-inputs/ReferenceInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/ReferenceManyInput.d.ts +34 -2
- package/dist/components/ra-inputs/ReferenceManyInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/SelectArrayInput.d.ts +18 -1
- package/dist/components/ra-inputs/SelectInput.d.ts +21 -1
- package/dist/components/ra-inputs/SmartTextInput.d.ts +17 -1
- package/dist/components/ra-inputs/SmartTextInput.d.ts.map +1 -1
- package/dist/components/ra-inputs/TextInput.d.ts +16 -2
- package/dist/components/ra-inputs/TimeInput.d.ts +11 -1
- package/dist/components/ra-lists/Datagrid.d.ts +616 -2
- package/dist/components/ra-lists/List.d.ts +28 -2
- package/dist/contexts/AppConfigContext.d.ts +1 -1
- package/dist/contexts/MenuConfigContext.d.ts +4 -4
- package/dist/dev/useCliErrorCatcher.d.ts +5 -5
- package/dist/hooks/useAppConfig.d.ts +1 -1
- package/dist/hooks/useBreadcrumbs.d.ts +2 -2
- package/dist/hooks/useMenu.d.ts +2 -2
- package/dist/hooks/useMenu.d.ts.map +1 -1
- package/dist/hooks/useMenuConfig.d.ts +2 -2
- package/dist/i18n/createI18nProvider.d.ts +1 -1
- package/dist/i18n/useI18nCatcher.d.ts +4 -4
- package/dist/i18n/useI18nLanguages.d.ts +4 -4
- package/dist/i18n/useI18nProvider.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/react-admin.cjs.js +25 -25
- package/dist/react-admin.es.js +304 -315
- package/dist/react-admin.umd.js +25 -25
- package/dist/themes/overrides/PaginationItem.d.ts +72 -72
- package/jsconfig.json +31 -0
- package/jsconfig.node.json +10 -0
- package/package.json +6 -5
- package/playground/config-overrides.js +31 -0
- package/playground/jsconfig.json +9 -0
- package/playground/package-lock.json +17764 -0
- package/playground/package.json +69 -0
- package/playground/public/favicon-dark.png +0 -0
- package/playground/public/favicon-light.png +0 -0
- package/playground/public/index.html +46 -0
- package/playground/src/App.js +49 -0
- package/playground/src/build.json +1 -0
- package/playground/src/components/index.js +5 -0
- package/playground/src/components/pages/CustomPage.jsx +7 -0
- package/playground/src/components/pages/index.jsx +2 -0
- package/playground/src/components/ra-buttons/index.js +1 -0
- package/playground/src/components/ra-fields/UserPictureField.js +20 -0
- package/playground/src/components/ra-fields/index.js +2 -0
- package/playground/src/components/ra-forms/DeviceForm.js +36 -0
- package/playground/src/components/ra-forms/I18nMessageForm.js +24 -0
- package/playground/src/components/ra-forms/UserForm.js +51 -0
- package/playground/src/components/ra-forms/index.js +5 -0
- package/playground/src/components/ra-inputs/LangSelectInput.js +4 -0
- package/playground/src/components/ra-inputs/YesOrNoSelectInput.js +14 -0
- package/playground/src/components/ra-inputs/index.js +3 -0
- package/playground/src/components/ra-lists/DeviceList.js +33 -0
- package/playground/src/components/ra-lists/I18nMessageList.js +20 -0
- package/playground/src/components/ra-lists/UserList.js +96 -0
- package/playground/src/components/ra-lists/index.js +4 -0
- package/playground/src/config.js +19 -0
- package/playground/src/contexts/index.js +1 -0
- package/playground/src/hooks/index.js +1 -0
- package/playground/src/index.js +10 -0
- package/playground/src/menu.js +72 -0
- package/playground/src/react-app-env.d.js +1 -0
- package/playground/src/reportWebVitals.js +13 -0
- package/playground/src/resource/device.js +23 -0
- package/playground/src/resource/i18n-message.js +29 -0
- package/playground/src/resource/index.js +4 -0
- package/playground/src/resource/notification.js +18 -0
- package/playground/src/resource/user.js +28 -0
- package/playground/src/theme.js +3 -0
- package/src/Admin.jsx +67 -0
- package/src/AdminContext.jsx +26 -0
- package/src/ApplicaAdmin.jsx +210 -0
- package/src/assets/README.md +7 -0
- package/src/assets/logo-icon.png +0 -0
- package/src/assets/logo-main.png +0 -0
- package/src/components/@extended/AnimateButton.jsx +96 -0
- package/src/components/@extended/Avatar.jsx +125 -0
- package/src/components/@extended/Breadcrumbs.jsx +324 -0
- package/src/components/@extended/Dot.jsx +35 -0
- package/src/components/@extended/IconButton.jsx +166 -0
- package/src/components/@extended/LoadingButton.jsx +228 -0
- package/src/components/@extended/Tooltip.jsx +67 -0
- package/src/components/@extended/Transitions.jsx +125 -0
- package/src/components/@extended/index.jsx +11 -0
- package/src/components/@extended/progress/CircularWithLabel.jsx +34 -0
- package/src/components/@extended/progress/CircularWithPath.jsx +74 -0
- package/src/components/@extended/progress/LinearWithIcon.jsx +22 -0
- package/src/components/@extended/progress/LinearWithLabel.jsx +23 -0
- package/src/components/@extended/progress/index.jsx +6 -0
- package/src/components/ActionsMenu.jsx +77 -0
- package/src/components/Layout/Drawer/DrawerContent/Navigation/NavCollapse.jsx +440 -0
- package/src/components/Layout/Drawer/DrawerContent/Navigation/NavGroup.jsx +359 -0
- package/src/components/Layout/Drawer/DrawerContent/Navigation/NavItem.jsx +259 -0
- package/src/components/Layout/Drawer/DrawerContent/Navigation/index.jsx +73 -0
- package/src/components/Layout/Drawer/DrawerContent/index.jsx +19 -0
- package/src/components/Layout/Drawer/DrawerHeader/DrawerHeaderStyled.jsx +20 -0
- package/src/components/Layout/Drawer/DrawerHeader/index.jsx +44 -0
- package/src/components/Layout/Drawer/HorizontalBar.jsx +55 -0
- package/src/components/Layout/Drawer/MiniDrawerStyled.jsx +47 -0
- package/src/components/Layout/Drawer/index.jsx +63 -0
- package/src/components/Layout/Footer.jsx +23 -0
- package/src/components/Layout/Header/AppBarStyled.jsx +34 -0
- package/src/components/Layout/Header/HeaderContent/MobileSection.jsx +91 -0
- package/src/components/Layout/Header/HeaderContent/Notification.jsx +179 -0
- package/src/components/Layout/Header/HeaderContent/NotificationItem.jsx +109 -0
- package/src/components/Layout/Header/HeaderContent/Profile.jsx +181 -0
- package/src/components/Layout/Header/HeaderContent/index.jsx +38 -0
- package/src/components/Layout/Header/index.jsx +99 -0
- package/src/components/Layout/index.jsx +119 -0
- package/src/components/Loadable.jsx +11 -0
- package/src/components/Loader.jsx +21 -0
- package/src/components/Logo.jsx +29 -0
- package/src/components/MainCard.jsx +111 -0
- package/src/components/MainIcon.jsx +20 -0
- package/src/components/MenuPopover/MenuPopover.jsx +61 -0
- package/src/components/MenuPopover/getPosition.jsx +98 -0
- package/src/components/MenuPopover/index.jsx +3 -0
- package/src/components/MenuPopover/styles.jsx +87 -0
- package/src/components/Notification.jsx +13 -0
- package/src/components/ScrollTop.jsx +24 -0
- package/src/components/ScrollX.jsx +10 -0
- package/src/components/SmallIcon.jsx +14 -0
- package/src/components/index.jsx +36 -0
- package/src/components/ra-buttons/CreateInDialogButton.jsx +203 -0
- package/src/components/ra-buttons/EditInDialogButton.jsx +108 -0
- package/src/components/ra-buttons/ImpersonateUserButton.jsx +41 -0
- package/src/components/ra-buttons/index.jsx +4 -0
- package/src/components/ra-fields/ActionsField.jsx +33 -0
- package/src/components/ra-fields/AttachmentField.jsx +82 -0
- package/src/components/ra-fields/BaseAttachmentField.jsx +72 -0
- package/src/components/ra-fields/CoverField.jsx +83 -0
- package/src/components/ra-fields/DateAgoField.jsx +35 -0
- package/src/components/ra-fields/DateField.jsx +27 -0
- package/src/components/ra-fields/EmailField.jsx +27 -0
- package/src/components/ra-fields/FileField.jsx +40 -0
- package/src/components/ra-fields/FunctionField.jsx +9 -0
- package/src/components/ra-fields/ImageField.jsx +20 -0
- package/src/components/ra-fields/ReadonlyField.jsx +107 -0
- package/src/components/ra-fields/ReferenceManyField.jsx +63 -0
- package/src/components/ra-fields/SizeField.jsx +32 -0
- package/src/components/ra-fields/TextField.jsx +27 -0
- package/src/components/ra-fields/index.jsx +28 -0
- package/src/components/ra-forms/CardForm.jsx +113 -0
- package/src/components/ra-forms/Edit.jsx +13 -0
- package/src/components/ra-forms/FormHeader.jsx +42 -0
- package/src/components/ra-forms/LongForm/DispositionProps.jsx +10 -0
- package/src/components/ra-forms/LongForm/LongForm.jsx +38 -0
- package/src/components/ra-forms/LongForm/LongFormHeader.jsx +24 -0
- package/src/components/ra-forms/LongForm/LongFormTab.jsx +121 -0
- package/src/components/ra-forms/LongForm/LongFormTabs.jsx +63 -0
- package/src/components/ra-forms/LongForm/LongFormView.jsx +129 -0
- package/src/components/ra-forms/LongForm/index.jsx +2 -0
- package/src/components/ra-forms/LongForm/useFormRootPath.jsx +22 -0
- package/src/components/ra-forms/SimpleForm.jsx +69 -0
- package/src/components/ra-forms/TabbedForm.jsx +19 -0
- package/src/components/ra-forms/Toolbar.jsx +36 -0
- package/src/components/ra-forms/index.jsx +8 -0
- package/src/components/ra-inputs/ArrayInput.jsx +29 -0
- package/src/components/ra-inputs/AttachmentInput.jsx +57 -0
- package/src/components/ra-inputs/AutocompleteArrayInput.jsx +25 -0
- package/src/components/ra-inputs/AutocompleteInput.jsx +24 -0
- package/src/components/ra-inputs/BooleanInput.jsx +54 -0
- package/src/components/ra-inputs/DateInput.jsx +30 -0
- package/src/components/ra-inputs/FileInput.jsx +98 -0
- package/src/components/ra-inputs/ImageInput.jsx +44 -0
- package/src/components/ra-inputs/LabeledInput.jsx +80 -0
- package/src/components/ra-inputs/NumberInput.jsx +28 -0
- package/src/components/ra-inputs/RecordInput.jsx +102 -0
- package/src/components/ra-inputs/ReferenceArrayInput.jsx +23 -0
- package/src/components/ra-inputs/ReferenceInput.jsx +23 -0
- package/src/components/ra-inputs/ReferenceManyInput.jsx +44 -0
- package/src/components/ra-inputs/SearchInput.jsx +14 -0
- package/src/components/ra-inputs/SelectArrayInput.jsx +45 -0
- package/src/components/ra-inputs/SelectInput.jsx +24 -0
- package/src/components/ra-inputs/SmartTextInput.jsx +52 -0
- package/src/components/ra-inputs/TextInput.jsx +20 -0
- package/src/components/ra-inputs/TimeInput.jsx +46 -0
- package/src/components/ra-inputs/index.jsx +42 -0
- package/src/components/ra-lists/Datagrid.jsx +42 -0
- package/src/components/ra-lists/Empty.jsx +94 -0
- package/src/components/ra-lists/List.jsx +81 -0
- package/src/components/ra-lists/NotificationList/NotificationList.jsx +41 -0
- package/src/components/ra-lists/NotificationList/button/MarkAsReadedButton.jsx +57 -0
- package/src/components/ra-lists/NotificationList/button/MarkAsUnreadedButton.jsx +56 -0
- package/src/components/ra-lists/NotificationList/button/index.jsx +2 -0
- package/src/components/ra-lists/NotificationList/field/NotificationField.jsx +80 -0
- package/src/components/ra-lists/NotificationList/field/index.jsx +1 -0
- package/src/components/ra-lists/NotificationList/index.jsx +2 -0
- package/src/components/ra-lists/index.jsx +5 -0
- package/src/components/third-party/SimpleBar.jsx +61 -0
- package/src/components/third-party/index.jsx +3 -0
- package/src/contexts/AppConfigContext.jsx +54 -0
- package/src/contexts/MenuConfigContext.jsx +93 -0
- package/src/contexts/MenuPropTypes.jsx +19 -0
- package/src/contexts/ThemeConfigContext.jsx +138 -0
- package/src/contexts/index.jsx +5 -0
- package/src/dev/index.jsx +2 -0
- package/src/dev/useCliErrorCatcher.jsx +86 -0
- package/src/hooks/index.jsx +16 -0
- package/src/hooks/useAppConfig.jsx +6 -0
- package/src/hooks/useBreadcrumbs.jsx +68 -0
- package/src/hooks/useLocalStorage.jsx +31 -0
- package/src/hooks/useMenu.jsx +223 -0
- package/src/hooks/useMenuConfig.jsx +6 -0
- package/src/hooks/useResourceTitle.jsx +25 -0
- package/src/hooks/useThemeConfig.jsx +6 -0
- package/src/i18n/createI18nProvider.jsx +15 -0
- package/src/i18n/index.jsx +4 -0
- package/src/i18n/useI18nCatcher.jsx +71 -0
- package/src/i18n/useI18nLanguages.jsx +22 -0
- package/src/i18n/useI18nProvider.jsx +5 -0
- package/src/index.jsx +67 -0
- package/src/themes/getColors.jsx +18 -0
- package/src/themes/getShadow.jsx +37 -0
- package/src/themes/index.jsx +70 -0
- package/src/themes/overrides/Accordion.jsx +27 -0
- package/src/themes/overrides/AccordionDetails.jsx +14 -0
- package/src/themes/overrides/AccordionSummary.jsx +33 -0
- package/src/themes/overrides/Alert.jsx +72 -0
- package/src/themes/overrides/AlertTitle.jsx +15 -0
- package/src/themes/overrides/Autocomplete.jsx +23 -0
- package/src/themes/overrides/Badge.jsx +36 -0
- package/src/themes/overrides/Button.jsx +229 -0
- package/src/themes/overrides/ButtonBase.jsx +12 -0
- package/src/themes/overrides/ButtonGroup.jsx +11 -0
- package/src/themes/overrides/CardContent.jsx +16 -0
- package/src/themes/overrides/Checkbox.jsx +125 -0
- package/src/themes/overrides/Chip.jsx +75 -0
- package/src/themes/overrides/Dialog.jsx +18 -0
- package/src/themes/overrides/DialogContentText.jsx +14 -0
- package/src/themes/overrides/DialogTitle.jsx +14 -0
- package/src/themes/overrides/Fab.jsx +77 -0
- package/src/themes/overrides/IconButton.jsx +28 -0
- package/src/themes/overrides/InputBase.jsx +13 -0
- package/src/themes/overrides/InputLabel.jsx +25 -0
- package/src/themes/overrides/LinearProgress.jsx +17 -0
- package/src/themes/overrides/Link.jsx +11 -0
- package/src/themes/overrides/ListItemButton.jsx +18 -0
- package/src/themes/overrides/ListItemIcon.jsx +14 -0
- package/src/themes/overrides/LoadingButton.jsx +17 -0
- package/src/themes/overrides/OutlinedInput.jsx +54 -0
- package/src/themes/overrides/Pagination.jsx +11 -0
- package/src/themes/overrides/PaginationItem.jsx +211 -0
- package/src/themes/overrides/Popover.jsx +13 -0
- package/src/themes/overrides/Radio.jsx +121 -0
- package/src/themes/overrides/Slider.jsx +66 -0
- package/src/themes/overrides/Switch.jsx +88 -0
- package/src/themes/overrides/Tab.jsx +24 -0
- package/src/themes/overrides/TableBody.jsx +27 -0
- package/src/themes/overrides/TableCell.jsx +44 -0
- package/src/themes/overrides/TableFooter.jsx +15 -0
- package/src/themes/overrides/TableHead.jsx +15 -0
- package/src/themes/overrides/TablePagination.jsx +16 -0
- package/src/themes/overrides/TableRow.jsx +25 -0
- package/src/themes/overrides/Tabs.jsx +13 -0
- package/src/themes/overrides/ToggleButton.jsx +20 -0
- package/src/themes/overrides/Tooltip.jsx +13 -0
- package/src/themes/overrides/TreeItem.jsx +18 -0
- package/src/themes/overrides/Typography.jsx +13 -0
- package/src/themes/overrides/index.jsx +98 -0
- package/src/themes/palette.jsx +78 -0
- package/src/themes/shadows.jsx +27 -0
- package/src/themes/theme/default.jsx +98 -0
- package/src/themes/theme/index.jsx +44 -0
- package/src/themes/theme/theme1.jsx +128 -0
- package/src/themes/theme/theme2.jsx +128 -0
- package/src/themes/theme/theme3.jsx +128 -0
- package/src/themes/theme/theme4.jsx +128 -0
- package/src/themes/theme/theme5.jsx +128 -0
- package/src/themes/theme/theme6.jsx +128 -0
- package/src/themes/theme/theme7.jsx +128 -0
- package/src/themes/theme/theme8.jsx +128 -0
- package/src/themes/typography.jsx +71 -0
- package/src/utils/index.js +2 -0
- package/src/utils/lang.js +12 -0
- package/src/utils/time.js +13 -0
- package/tsconfig.json +28 -0
- package/vite.config.js +74 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Form, SaveButton, useResourceContext, useTranslate } from 'react-admin'
|
|
2
|
+
import { Grid, Stack } from '@mui/material'
|
|
3
|
+
import React, { Fragment, useMemo } from 'react'
|
|
4
|
+
|
|
5
|
+
import MainCard from '../MainCard'
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
import Toolbar from './Toolbar'
|
|
8
|
+
import { styled } from '@mui/material/styles'
|
|
9
|
+
import { useThemeConfig } from '../../hooks'
|
|
10
|
+
|
|
11
|
+
const Section = ({ children, content, title, subheader, secondary, toolbar, ...gridProps }) => {
|
|
12
|
+
const translate = useTranslate()
|
|
13
|
+
const resource = useResourceContext()
|
|
14
|
+
const { cardTitle, cardSubheader } = useMemo(() => {
|
|
15
|
+
const defaultTitle = title || `resources.${resource}.title`
|
|
16
|
+
return {
|
|
17
|
+
cardTitle: translate(defaultTitle, { _: defaultTitle }),
|
|
18
|
+
cardSubheader: subheader !== null ? translate(subheader, { _: subheader }) : null,
|
|
19
|
+
}
|
|
20
|
+
}, [resource, subheader, title, translate])
|
|
21
|
+
return (
|
|
22
|
+
<Grid item {...gridProps}>
|
|
23
|
+
<MainCard
|
|
24
|
+
content={content}
|
|
25
|
+
title={cardTitle}
|
|
26
|
+
subheader={cardSubheader}
|
|
27
|
+
secondary={secondary}
|
|
28
|
+
divider
|
|
29
|
+
>
|
|
30
|
+
<Fragment>
|
|
31
|
+
{children}
|
|
32
|
+
{toolbar === true ? (
|
|
33
|
+
<Toolbar>
|
|
34
|
+
<SaveButton />
|
|
35
|
+
</Toolbar>
|
|
36
|
+
) : (
|
|
37
|
+
toolbar
|
|
38
|
+
)}
|
|
39
|
+
</Fragment>
|
|
40
|
+
</MainCard>
|
|
41
|
+
</Grid>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Section.defaultProps = {
|
|
46
|
+
...Grid.defaultProps,
|
|
47
|
+
content: true,
|
|
48
|
+
subheader: null,
|
|
49
|
+
title: null,
|
|
50
|
+
secondary: null,
|
|
51
|
+
toolbar: false,
|
|
52
|
+
item: true,
|
|
53
|
+
|
|
54
|
+
lg: 12,
|
|
55
|
+
md: 12,
|
|
56
|
+
sm: 12,
|
|
57
|
+
xs: 12,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Section.propTypes = {
|
|
61
|
+
...Grid.propTypes,
|
|
62
|
+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
|
|
63
|
+
contained: PropTypes.bool,
|
|
64
|
+
content: PropTypes.bool,
|
|
65
|
+
subheader: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
66
|
+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
67
|
+
secondary: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]),
|
|
68
|
+
spacing: PropTypes.number,
|
|
69
|
+
toolbar: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]),
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const StyledForm = styled(Form, {
|
|
73
|
+
name: 'RaApplicaCardForm',
|
|
74
|
+
slot: 'root',
|
|
75
|
+
})(({ theme, spacing }) => ({
|
|
76
|
+
backgroundColor: 'transparent',
|
|
77
|
+
'& .RaToolbar-desktopToolbar': {
|
|
78
|
+
marginTop: theme.spacing(spacing * 2),
|
|
79
|
+
padding: 0,
|
|
80
|
+
},
|
|
81
|
+
}))
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @see https://mui.com/material-ui/react-stack/
|
|
85
|
+
*/
|
|
86
|
+
const CardForm = ({ children, spacing, defaultValues, ...gridProps }) => {
|
|
87
|
+
const { spacing: themeSpacing } = useThemeConfig()
|
|
88
|
+
return (
|
|
89
|
+
<StyledForm defaultValues={defaultValues} spacing={spacing || themeSpacing}>
|
|
90
|
+
<Grid container {...gridProps} spacing={spacing || themeSpacing}>
|
|
91
|
+
{children}
|
|
92
|
+
</Grid>
|
|
93
|
+
</StyledForm>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
CardForm.propTypes = {
|
|
98
|
+
...Grid.propTypes,
|
|
99
|
+
...Form.propTypes,
|
|
100
|
+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
|
|
101
|
+
spacing: PropTypes.number,
|
|
102
|
+
defaultValues: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
|
103
|
+
record: PropTypes.object,
|
|
104
|
+
validate: PropTypes.func,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
CardForm.defaultProps = {
|
|
108
|
+
...Stack.defaultProps,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
CardForm.Section = Section
|
|
112
|
+
|
|
113
|
+
export default CardForm
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Edit as RaEdit } from 'react-admin'
|
|
2
|
+
import { styled } from '@mui/material/styles'
|
|
3
|
+
|
|
4
|
+
const StyledEdit = styled(RaEdit, {
|
|
5
|
+
name: 'RaApplicaEdit',
|
|
6
|
+
slot: 'root',
|
|
7
|
+
})(({ theme }) => ({
|
|
8
|
+
'& .RaEdi-card, & > div > div > form': {
|
|
9
|
+
backgroundColor: theme.palette.background.default,
|
|
10
|
+
},
|
|
11
|
+
}))
|
|
12
|
+
|
|
13
|
+
export default StyledEdit
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CardHeader, Divider } from '@mui/material'
|
|
2
|
+
|
|
3
|
+
import { Fragment } from 'react'
|
|
4
|
+
import PropTypes from 'prop-types'
|
|
5
|
+
import { styled } from '@mui/material/styles'
|
|
6
|
+
import { useTranslate } from 'react-admin'
|
|
7
|
+
|
|
8
|
+
const StyledCardHeader = styled(CardHeader)(({ theme }) => ({
|
|
9
|
+
marginTop: theme.spacing(4),
|
|
10
|
+
marginLeft: 0,
|
|
11
|
+
marginRight: 0,
|
|
12
|
+
paddingLeft: 0,
|
|
13
|
+
paddingRight: 0,
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
const StyledDivider = styled(Divider)(({ theme }) => ({
|
|
17
|
+
marginLeft: `-${theme.spacing(2.5)}`,
|
|
18
|
+
marginRight: `-${theme.spacing(2.5)}`,
|
|
19
|
+
marginBottom: theme.spacing(2),
|
|
20
|
+
width: `calc(100% + ${theme.spacing(5)})`,
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
const FormHeader = ({ title, divider }) => {
|
|
24
|
+
const translate = useTranslate()
|
|
25
|
+
return (
|
|
26
|
+
<Fragment>
|
|
27
|
+
<StyledCardHeader title={translate(title, { _: title })} />
|
|
28
|
+
{divider && <StyledDivider />}
|
|
29
|
+
</Fragment>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
FormHeader.propTypes = {
|
|
34
|
+
title: PropTypes.string.isRequired,
|
|
35
|
+
divider: PropTypes.bool,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
FormHeader.defaultProps = {
|
|
39
|
+
divider: true,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default FormHeader
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import DispositionProps from './DispositionProps'
|
|
2
|
+
import { Form } from 'react-admin'
|
|
3
|
+
import LongFormTab from './LongFormTab'
|
|
4
|
+
import LongFormTabHeader from './LongFormHeader'
|
|
5
|
+
import LongFormView from './LongFormView'
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
import useFormRootPath from './useFormRootPath'
|
|
8
|
+
import { useThemeConfig } from '../../../hooks'
|
|
9
|
+
|
|
10
|
+
const LongForm = ({ spacing: _spacing, ...props }) => {
|
|
11
|
+
const formRootPathname = useFormRootPath()
|
|
12
|
+
const { spacing: _themeSpacing } = useThemeConfig()
|
|
13
|
+
const spacing = _spacing || _themeSpacing
|
|
14
|
+
return (
|
|
15
|
+
<Form formRootPathname={formRootPathname} {...props}>
|
|
16
|
+
<LongFormView formRootPathname={formRootPathname} {...props} spacing={spacing} />
|
|
17
|
+
</Form>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
LongForm.propTypes = {
|
|
22
|
+
syncWithLocation: PropTypes.bool,
|
|
23
|
+
spacing: PropTypes.number,
|
|
24
|
+
tabsDisposition: DispositionProps,
|
|
25
|
+
contentDisposition: DispositionProps,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
LongForm.defaultProps = {
|
|
29
|
+
syncWithLocation: false,
|
|
30
|
+
spacing: 2,
|
|
31
|
+
tabsDisposition: { xl: 3, lg: 3, md: 4, sm: 4, xs: 12 },
|
|
32
|
+
contentDisposition: { xl: 9, lg: 9, md: 8, sm: 8, xs: 12 },
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
LongForm.Tab = LongFormTab
|
|
36
|
+
LongForm.Header = LongFormTabHeader
|
|
37
|
+
|
|
38
|
+
export default LongForm
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
import { styled } from '@mui/material/styles'
|
|
3
|
+
import { useMediaQuery } from '@mui/material'
|
|
4
|
+
const StyledSidebar = styled('div')(({ theme }) => ({
|
|
5
|
+
marginBottom: theme.spacing(2),
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
const LongFormTabHeader = ({ children, visibility }) => {
|
|
9
|
+
const isVisible = useMediaQuery((theme) => theme.breakpoints.up(visibility))
|
|
10
|
+
return isVisible ? <StyledSidebar>{children}</StyledSidebar> : null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
LongFormTabHeader.propTypes = {
|
|
14
|
+
visibility: PropTypes.oneOf(['xl', 'lg', 'md', 'sm', 'xs']),
|
|
15
|
+
position: PropTypes.oneOf(['top', 'bottom']).isRequired,
|
|
16
|
+
children: PropTypes.node.isRequired,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
LongFormTabHeader.defaultProps = {
|
|
20
|
+
position: 'top',
|
|
21
|
+
visibility: 'md',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default LongFormTabHeader
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Avatar,
|
|
3
|
+
ListItemButton,
|
|
4
|
+
ListItemIcon,
|
|
5
|
+
ListItemSecondaryAction,
|
|
6
|
+
ListItemText,
|
|
7
|
+
Stack,
|
|
8
|
+
} from '@mui/material'
|
|
9
|
+
import { FormGroupContextProvider, useTranslate } from 'react-admin'
|
|
10
|
+
import React, { useCallback } from 'react'
|
|
11
|
+
|
|
12
|
+
import { Link } from 'react-router-dom'
|
|
13
|
+
import PropTypes from 'prop-types'
|
|
14
|
+
import { useLocation } from 'react-router'
|
|
15
|
+
|
|
16
|
+
const hiddenStyle = { display: 'none' }
|
|
17
|
+
|
|
18
|
+
const LongFormTab = ({
|
|
19
|
+
intent,
|
|
20
|
+
hidden,
|
|
21
|
+
unmountOnExit,
|
|
22
|
+
label,
|
|
23
|
+
icon,
|
|
24
|
+
value,
|
|
25
|
+
syncWithLocation,
|
|
26
|
+
selected,
|
|
27
|
+
onChange,
|
|
28
|
+
children,
|
|
29
|
+
badgeColor,
|
|
30
|
+
badgeContent,
|
|
31
|
+
...props
|
|
32
|
+
}) => {
|
|
33
|
+
const translate = useTranslate()
|
|
34
|
+
const location = useLocation()
|
|
35
|
+
const propsForLink = {
|
|
36
|
+
component: Link,
|
|
37
|
+
to: { ...location, pathname: value },
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const tabLabel = React.isValidElement(label) ? label : translate(label, { _: label })
|
|
41
|
+
const handleChange = useCallback(() => onChange(value), [onChange, value])
|
|
42
|
+
|
|
43
|
+
const renderTab = () => (
|
|
44
|
+
<ListItemButton
|
|
45
|
+
selected={selected}
|
|
46
|
+
{...(syncWithLocation ? propsForLink : {})}
|
|
47
|
+
onClick={handleChange}
|
|
48
|
+
>
|
|
49
|
+
{icon && <ListItemIcon>{icon}</ListItemIcon>}
|
|
50
|
+
<ListItemText primary={tabLabel} />
|
|
51
|
+
{badgeContent && (
|
|
52
|
+
<ListItemSecondaryAction>
|
|
53
|
+
<Avatar
|
|
54
|
+
sx={{
|
|
55
|
+
width: 24,
|
|
56
|
+
height: 24,
|
|
57
|
+
fontSize: 12,
|
|
58
|
+
backgroundColor: (theme) => theme.palette[badgeColor]?.main,
|
|
59
|
+
color: (theme) => theme.palette[badgeColor]?.contrastText,
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
{badgeContent}
|
|
63
|
+
</Avatar>
|
|
64
|
+
</ListItemSecondaryAction>
|
|
65
|
+
)}
|
|
66
|
+
</ListItemButton>
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
const renderContent = () =>
|
|
70
|
+
unmountOnExit && hidden ? null : (
|
|
71
|
+
<FormGroupContextProvider name={value.toString()}>
|
|
72
|
+
<Stack
|
|
73
|
+
alignContent={'stretch'}
|
|
74
|
+
style={hidden ? hiddenStyle : null}
|
|
75
|
+
id={`tabpanel-${value}`}
|
|
76
|
+
aria-labelledby={`tabheader-${value}`}
|
|
77
|
+
// Set undefined instead of false because WAI-ARIA Authoring Practices 1.1
|
|
78
|
+
// notes that aria-hidden="false" currently behaves inconsistently across browsers.
|
|
79
|
+
aria-hidden={hidden || undefined}
|
|
80
|
+
{...props}
|
|
81
|
+
>
|
|
82
|
+
{children}
|
|
83
|
+
</Stack>
|
|
84
|
+
</FormGroupContextProvider>
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return intent === 'header' ? renderTab() : renderContent()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
LongFormTab.propTypes = {
|
|
91
|
+
intent: PropTypes.oneOf(['header', 'content', 'sidebar']),
|
|
92
|
+
className: PropTypes.string,
|
|
93
|
+
contentClassName: PropTypes.string,
|
|
94
|
+
url: PropTypes.string,
|
|
95
|
+
icon: PropTypes.element,
|
|
96
|
+
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
97
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
98
|
+
syncWithLocation: PropTypes.bool,
|
|
99
|
+
onChange: PropTypes.func,
|
|
100
|
+
selected: PropTypes.bool,
|
|
101
|
+
hidden: PropTypes.bool,
|
|
102
|
+
unmountOnExit: PropTypes.bool,
|
|
103
|
+
children: PropTypes.node,
|
|
104
|
+
badgeColor: PropTypes.oneOf([
|
|
105
|
+
'default',
|
|
106
|
+
'error',
|
|
107
|
+
'info',
|
|
108
|
+
'primary',
|
|
109
|
+
'secondary',
|
|
110
|
+
'success',
|
|
111
|
+
'warning',
|
|
112
|
+
]),
|
|
113
|
+
badgeContent: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
LongFormTab.defaultProps = {
|
|
117
|
+
badgeColor: 'default',
|
|
118
|
+
unmountOnExit: false,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default LongFormTab
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { matchPath, useLocation } from 'react-router'
|
|
2
|
+
|
|
3
|
+
import { List } from '@mui/material'
|
|
4
|
+
import MainCard from '../../MainCard'
|
|
5
|
+
import PropTypes from 'prop-types'
|
|
6
|
+
import React from 'react'
|
|
7
|
+
import { styled } from '@mui/system'
|
|
8
|
+
|
|
9
|
+
const StyledList = styled(List, {
|
|
10
|
+
name: 'RaLongFormTabs',
|
|
11
|
+
slot: 'Root',
|
|
12
|
+
})(({ theme }) => ({
|
|
13
|
+
p: 0,
|
|
14
|
+
|
|
15
|
+
'& .MuiListItemIcon-root': {
|
|
16
|
+
minWidth: 32,
|
|
17
|
+
color: theme.palette.grey[500],
|
|
18
|
+
},
|
|
19
|
+
'& .MuiListItemButton-root.Mui-selected': {
|
|
20
|
+
borderRight: `2px solid ${theme.palette.primary.main}`,
|
|
21
|
+
marginRight: `-2px`,
|
|
22
|
+
},
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
const LongFormTabs = ({ children, syncWithLocation, value, url, onChange }) => {
|
|
26
|
+
const location = useLocation()
|
|
27
|
+
return (
|
|
28
|
+
<MainCard>
|
|
29
|
+
<StyledList component="nav">
|
|
30
|
+
{React.Children.map(children, (tab, index) => {
|
|
31
|
+
if (!React.isValidElement(tab)) return null
|
|
32
|
+
const tabPath = getTabbedFormTabFullPath(tab, index)
|
|
33
|
+
const selected = syncWithLocation
|
|
34
|
+
? !!matchPath(`${url}/${tabPath}`, location.pathname)
|
|
35
|
+
: index === value
|
|
36
|
+
|
|
37
|
+
return React.cloneElement(tab, {
|
|
38
|
+
intent: 'header',
|
|
39
|
+
value: syncWithLocation ? tabPath : index,
|
|
40
|
+
syncWithLocation,
|
|
41
|
+
onChange,
|
|
42
|
+
url,
|
|
43
|
+
selected,
|
|
44
|
+
})
|
|
45
|
+
})}
|
|
46
|
+
</StyledList>
|
|
47
|
+
</MainCard>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const getTabbedFormTabFullPath = (tab, index) =>
|
|
52
|
+
tab.props.path != null ? tab.props.path : index > 0 ? index.toString() : ''
|
|
53
|
+
|
|
54
|
+
LongFormTabs.propTypes = {
|
|
55
|
+
children: PropTypes.node,
|
|
56
|
+
url: PropTypes.string,
|
|
57
|
+
tabsWithErrors: PropTypes.arrayOf(PropTypes.string),
|
|
58
|
+
syncWithLocation: PropTypes.bool,
|
|
59
|
+
onChange: PropTypes.func,
|
|
60
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default LongFormTabs
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react'
|
|
2
|
+
import { Route, Routes, matchPath, useLocation, useResolvedPath } from 'react-router'
|
|
3
|
+
import { getTabbedFormTabFullPath, useResourceContext } from 'react-admin'
|
|
4
|
+
|
|
5
|
+
import DispositionProps from './DispositionProps'
|
|
6
|
+
import { Grid } from '@mui/material'
|
|
7
|
+
import LongFormCard from './LongFormHeader'
|
|
8
|
+
import LongFormTab from './LongFormTab'
|
|
9
|
+
import LongFormTabs from './LongFormTabs'
|
|
10
|
+
import PropTypes from 'prop-types'
|
|
11
|
+
import { styled } from '@mui/material/styles'
|
|
12
|
+
|
|
13
|
+
const StyledGrid = styled(Grid, {
|
|
14
|
+
name: 'RaLongFormView',
|
|
15
|
+
slot: 'Root',
|
|
16
|
+
})(({ theme }) => ({
|
|
17
|
+
'& .MuiToolbar-root': {
|
|
18
|
+
marginTop: theme.spacing(2),
|
|
19
|
+
marginLeft: `-${theme.spacing(3)}`,
|
|
20
|
+
marginRight: `-${theme.spacing(3)}`,
|
|
21
|
+
marginBottom: `-${theme.spacing(2)}`,
|
|
22
|
+
borderTop: `1px solid ${theme.palette.divider}`,
|
|
23
|
+
},
|
|
24
|
+
}))
|
|
25
|
+
|
|
26
|
+
const isSidebar = (child, position) =>
|
|
27
|
+
child && child.type === LongFormCard && child.props.position === position
|
|
28
|
+
const isTab = (child) => child && child.type === LongFormTab
|
|
29
|
+
|
|
30
|
+
const LongFormView = ({
|
|
31
|
+
children,
|
|
32
|
+
formRootPathname,
|
|
33
|
+
syncWithLocation,
|
|
34
|
+
spacing,
|
|
35
|
+
tabs,
|
|
36
|
+
tabsDisposition,
|
|
37
|
+
contentDisposition,
|
|
38
|
+
...props
|
|
39
|
+
}) => {
|
|
40
|
+
const [tabValue, setTabValue] = useState(0)
|
|
41
|
+
const resolvedPath = useResolvedPath('')
|
|
42
|
+
const resource = useResourceContext(props)
|
|
43
|
+
const location = useLocation()
|
|
44
|
+
const topSidebars = useMemo(
|
|
45
|
+
() => React.Children.toArray(children).find((child) => isSidebar(child, 'top')),
|
|
46
|
+
[children],
|
|
47
|
+
)
|
|
48
|
+
const bottomSidebars = useMemo(
|
|
49
|
+
() => React.Children.toArray(children).find((child) => isSidebar(child, 'bottom')),
|
|
50
|
+
[children],
|
|
51
|
+
)
|
|
52
|
+
const tabChildrens = useMemo(
|
|
53
|
+
() => React.Children.toArray(children).filter((child) => isTab(child)),
|
|
54
|
+
[children],
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
const handleTabChange = (value) => {
|
|
58
|
+
if (!syncWithLocation) {
|
|
59
|
+
setTabValue(value)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const renderTabs = () =>
|
|
63
|
+
React.cloneElement(
|
|
64
|
+
tabs,
|
|
65
|
+
{
|
|
66
|
+
onChange: handleTabChange,
|
|
67
|
+
syncWithLocation,
|
|
68
|
+
url: formRootPathname,
|
|
69
|
+
value: tabValue,
|
|
70
|
+
intent: 'header',
|
|
71
|
+
},
|
|
72
|
+
tabChildrens,
|
|
73
|
+
)
|
|
74
|
+
return (
|
|
75
|
+
<StyledGrid container spacing={spacing * 2}>
|
|
76
|
+
<Grid item {...tabsDisposition}>
|
|
77
|
+
{topSidebars}
|
|
78
|
+
{syncWithLocation ? (
|
|
79
|
+
<Routes>
|
|
80
|
+
<Route path="/*" element={renderTabs()} />
|
|
81
|
+
</Routes>
|
|
82
|
+
) : (
|
|
83
|
+
renderTabs()
|
|
84
|
+
)}
|
|
85
|
+
{bottomSidebars}
|
|
86
|
+
</Grid>
|
|
87
|
+
<Grid item {...contentDisposition}>
|
|
88
|
+
{/* All tabs are rendered (not only the one in focus), to allow validation
|
|
89
|
+
on tabs not in focus. The tabs receive a `hidden` property, which they'll
|
|
90
|
+
use to hide the tab using CSS if it's not the one in focus.
|
|
91
|
+
See https://github.com/marmelab/react-admin/issues/1866 */}
|
|
92
|
+
{React.Children.map(tabChildrens, (tab, index) => {
|
|
93
|
+
if (!tab) {
|
|
94
|
+
return null
|
|
95
|
+
}
|
|
96
|
+
const tabPath = getTabbedFormTabFullPath(tab, index)
|
|
97
|
+
const hidden = syncWithLocation
|
|
98
|
+
? !matchPath(`${resolvedPath.pathname}/${tabPath}`, location.pathname)
|
|
99
|
+
: tabValue !== index
|
|
100
|
+
|
|
101
|
+
return React.isValidElement(tab)
|
|
102
|
+
? React.cloneElement(tab, {
|
|
103
|
+
intent: 'content',
|
|
104
|
+
resource,
|
|
105
|
+
hidden,
|
|
106
|
+
value: syncWithLocation ? tabPath : index,
|
|
107
|
+
})
|
|
108
|
+
: null
|
|
109
|
+
})}
|
|
110
|
+
</Grid>
|
|
111
|
+
</StyledGrid>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
LongFormView.propTypes = {
|
|
116
|
+
children: PropTypes.node,
|
|
117
|
+
spacing: PropTypes.number,
|
|
118
|
+
syncWithLocation: PropTypes.bool,
|
|
119
|
+
tabs: PropTypes.element,
|
|
120
|
+
formRootPathname: PropTypes.string,
|
|
121
|
+
tabsDisposition: DispositionProps,
|
|
122
|
+
contentDisposition: DispositionProps,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
LongFormView.defaultProps = {
|
|
126
|
+
tabs: <LongFormTabs />,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default LongFormView
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { matchPath, useLocation } from 'react-router-dom'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This hook infers the tabbed form root path from the current location.
|
|
5
|
+
*/
|
|
6
|
+
const useFormRootPath = () => {
|
|
7
|
+
const location = useLocation()
|
|
8
|
+
const createMatch = matchPath(':resource/create/*', location.pathname)
|
|
9
|
+
const editMatch = matchPath(':resource/:id/*', location.pathname)
|
|
10
|
+
|
|
11
|
+
if (createMatch) {
|
|
12
|
+
return createMatch.pathnameBase
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (editMatch) {
|
|
16
|
+
return editMatch.pathnameBase
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return ''
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default useFormRootPath
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeleteWithConfirmButton,
|
|
3
|
+
SimpleForm as RaSimpleForm,
|
|
4
|
+
SaveButton,
|
|
5
|
+
useRecordContext,
|
|
6
|
+
} from 'react-admin'
|
|
7
|
+
|
|
8
|
+
import ActionsMenu from '../ActionsMenu'
|
|
9
|
+
import MainCard from '../MainCard'
|
|
10
|
+
import PropTypes from 'prop-types'
|
|
11
|
+
import React from 'react'
|
|
12
|
+
import Toolbar from './Toolbar'
|
|
13
|
+
import { styled } from '@mui/system'
|
|
14
|
+
import { useResourceTitle } from '../../hooks'
|
|
15
|
+
|
|
16
|
+
const ApplicaStyledSimpleForm = styled(RaSimpleForm, {
|
|
17
|
+
name: 'RaApplicaSimpleForm',
|
|
18
|
+
slot: 'Root',
|
|
19
|
+
})(({ theme, modal }) => ({
|
|
20
|
+
'& .MuiGrid-root.MuiGrid-container': {
|
|
21
|
+
paddingBottom: theme.spacing(modal ? 2 : 1),
|
|
22
|
+
},
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
const SimpleForm = ({ title, modal, content, subheader, secondary, ...props }) => {
|
|
26
|
+
const cardTitle = useResourceTitle(title)
|
|
27
|
+
const record = useRecordContext()
|
|
28
|
+
return (
|
|
29
|
+
<MainCard
|
|
30
|
+
content={content}
|
|
31
|
+
title={cardTitle}
|
|
32
|
+
subheader={subheader}
|
|
33
|
+
secondary={record?.id ? secondary : null}
|
|
34
|
+
border={!modal}
|
|
35
|
+
divider
|
|
36
|
+
>
|
|
37
|
+
<ApplicaStyledSimpleForm toolbar={<Toolbar />} {...props} />
|
|
38
|
+
</MainCard>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
SimpleForm.defaultProps = {
|
|
43
|
+
...RaSimpleForm.defaultProps,
|
|
44
|
+
modal: false,
|
|
45
|
+
content: false,
|
|
46
|
+
subheader: null,
|
|
47
|
+
title: null,
|
|
48
|
+
toolbar: (
|
|
49
|
+
<Toolbar>
|
|
50
|
+
<SaveButton />
|
|
51
|
+
</Toolbar>
|
|
52
|
+
),
|
|
53
|
+
secondary: (
|
|
54
|
+
<ActionsMenu>
|
|
55
|
+
<DeleteWithConfirmButton />
|
|
56
|
+
</ActionsMenu>
|
|
57
|
+
),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
SimpleForm.propTypes = {
|
|
61
|
+
...RaSimpleForm.propTypes,
|
|
62
|
+
contained: PropTypes.bool,
|
|
63
|
+
content: PropTypes.bool,
|
|
64
|
+
subheader: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
65
|
+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
66
|
+
secondary: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default SimpleForm
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TabbedForm as RaTabbedForm } from 'react-admin'
|
|
2
|
+
import { styled } from '@mui/system'
|
|
3
|
+
|
|
4
|
+
const ApplicaStyledTabbedForm = styled(RaTabbedForm, {
|
|
5
|
+
name: 'RaApplicaTabbedForm',
|
|
6
|
+
slot: 'Root',
|
|
7
|
+
})(() => ({}))
|
|
8
|
+
|
|
9
|
+
ApplicaStyledTabbedForm.propTypes = {
|
|
10
|
+
...RaTabbedForm.propTypes,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
ApplicaStyledTabbedForm.defaultProps = {
|
|
14
|
+
...RaTabbedForm.defaultProps,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
ApplicaStyledTabbedForm.Tab = RaTabbedForm.Tab
|
|
18
|
+
|
|
19
|
+
export default ApplicaStyledTabbedForm
|