@applica-software-guru/react-admin 1.1.113 → 1.2.115

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.
Files changed (71) hide show
  1. package/bitbucket-pipelines.yml +14 -15
  2. package/dist/components/ra-forms/LongForm/BaseForm.d.ts +8 -0
  3. package/dist/components/ra-forms/LongForm/BaseForm.d.ts.map +1 -0
  4. package/dist/components/ra-forms/LongForm/Content.d.ts +8 -0
  5. package/dist/components/ra-forms/LongForm/Content.d.ts.map +1 -0
  6. package/dist/components/ra-forms/LongForm/Form.d.ts +11 -0
  7. package/dist/components/ra-forms/LongForm/Form.d.ts.map +1 -0
  8. package/dist/components/ra-forms/LongForm/NavMenu.d.ts +19 -0
  9. package/dist/components/ra-forms/LongForm/NavMenu.d.ts.map +1 -0
  10. package/dist/components/ra-forms/LongForm/Provider.d.ts +15 -0
  11. package/dist/components/ra-forms/LongForm/Provider.d.ts.map +1 -0
  12. package/dist/components/ra-forms/LongForm/Sidebar.d.ts +23 -0
  13. package/dist/components/ra-forms/LongForm/Sidebar.d.ts.map +1 -0
  14. package/dist/components/ra-forms/LongForm/Tab.d.ts +11 -0
  15. package/dist/components/ra-forms/LongForm/Tab.d.ts.map +1 -0
  16. package/dist/components/ra-forms/LongForm/hooks.d.ts +5 -0
  17. package/dist/components/ra-forms/LongForm/hooks.d.ts.map +1 -0
  18. package/dist/components/ra-forms/LongForm/index.d.ts +30 -2
  19. package/dist/components/ra-forms/LongForm/index.d.ts.map +1 -1
  20. package/dist/components/ra-forms/LongForm/types.d.ts +12 -9
  21. package/dist/components/ra-forms/LongForm/types.d.ts.map +1 -1
  22. package/dist/components/ra-forms/LongForm/utils.d.ts +8 -0
  23. package/dist/components/ra-forms/LongForm/utils.d.ts.map +1 -0
  24. package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts +2 -0
  25. package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts.map +1 -1
  26. package/dist/react-admin.cjs.js +65 -65
  27. package/dist/react-admin.cjs.js.map +1 -1
  28. package/dist/react-admin.es.js +9206 -9131
  29. package/dist/react-admin.es.js.map +1 -1
  30. package/dist/react-admin.umd.js +65 -65
  31. package/dist/react-admin.umd.js.map +1 -1
  32. package/dist/themes/overrides/ListItemText.d.ts +12 -0
  33. package/dist/themes/overrides/ListItemText.d.ts.map +1 -0
  34. package/dist/themes/overrides/index.d.ts.map +1 -1
  35. package/dist/types.d.ts +4 -0
  36. package/dist/types.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/src/components/ra-forms/LongForm/BaseForm.tsx +54 -0
  39. package/src/components/ra-forms/LongForm/Content.tsx +19 -0
  40. package/src/components/ra-forms/LongForm/Form.tsx +37 -0
  41. package/src/components/ra-forms/LongForm/NavMenu.tsx +128 -0
  42. package/src/components/ra-forms/LongForm/Provider.tsx +196 -0
  43. package/src/components/ra-forms/LongForm/Sidebar.tsx +71 -0
  44. package/src/components/ra-forms/LongForm/Tab.tsx +67 -0
  45. package/src/components/ra-forms/LongForm/hooks.tsx +25 -0
  46. package/src/components/ra-forms/LongForm/index.ts +52 -0
  47. package/src/components/ra-forms/LongForm/types.ts +13 -9
  48. package/src/components/ra-forms/LongForm/utils.ts +22 -0
  49. package/src/components/ra-forms/TableForm/TableFormIterator.tsx +32 -11
  50. package/src/themes/overrides/ListItemText.jsx +15 -0
  51. package/src/themes/overrides/index.jsx +2 -0
  52. package/src/types.ts +5 -0
  53. package/dist/components/ra-forms/LongForm/LongForm.d.ts +0 -98
  54. package/dist/components/ra-forms/LongForm/LongForm.d.ts.map +0 -1
  55. package/dist/components/ra-forms/LongForm/LongFormSidebar.d.ts +0 -34
  56. package/dist/components/ra-forms/LongForm/LongFormSidebar.d.ts.map +0 -1
  57. package/dist/components/ra-forms/LongForm/LongFormTab.d.ts +0 -45
  58. package/dist/components/ra-forms/LongForm/LongFormTab.d.ts.map +0 -1
  59. package/dist/components/ra-forms/LongForm/LongFormTabs.d.ts +0 -23
  60. package/dist/components/ra-forms/LongForm/LongFormTabs.d.ts.map +0 -1
  61. package/dist/components/ra-forms/LongForm/LongFormView.d.ts +0 -42
  62. package/dist/components/ra-forms/LongForm/LongFormView.d.ts.map +0 -1
  63. package/dist/components/ra-forms/LongForm/useFormRootPath.d.ts +0 -6
  64. package/dist/components/ra-forms/LongForm/useFormRootPath.d.ts.map +0 -1
  65. package/src/components/ra-forms/LongForm/LongForm.tsx +0 -59
  66. package/src/components/ra-forms/LongForm/LongFormSidebar.tsx +0 -44
  67. package/src/components/ra-forms/LongForm/LongFormTab.tsx +0 -122
  68. package/src/components/ra-forms/LongForm/LongFormTabs.tsx +0 -72
  69. package/src/components/ra-forms/LongForm/LongFormView.tsx +0 -161
  70. package/src/components/ra-forms/LongForm/index.tsx +0 -2
  71. package/src/components/ra-forms/LongForm/useFormRootPath.ts +0 -21
@@ -1,122 +0,0 @@
1
- import { Avatar, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Stack } from '@mui/material';
2
- import { FormGroupContextProvider, useTranslate } from 'react-admin';
3
- import React, { useCallback } from 'react';
4
-
5
- import { Link } from 'react-router-dom';
6
- import PropTypes from 'prop-types';
7
- import { useLocation } from 'react-router';
8
-
9
- const hiddenStyle = { display: 'none' };
10
-
11
- export type LongFormTabProps = {
12
- intent: 'header' | 'content' | 'sidebar';
13
- className?: string;
14
- contentClassName?: string;
15
- url?: string;
16
- icon?: React.ReactNode;
17
- label: string | React.ReactNode;
18
- value: string | number;
19
- syncWithLocation?: boolean;
20
- onChange: (value: string | number) => void;
21
- selected?: boolean;
22
- hidden?: boolean;
23
- unmountOnExit?: boolean;
24
- children?: React.ReactNode;
25
- badgeColor?: 'default' | 'error' | 'info' | 'primary' | 'secondary' | 'success' | 'warning';
26
- badgeContent?: string | number;
27
- };
28
-
29
- const LongFormTab = ({
30
- intent,
31
- hidden,
32
- unmountOnExit,
33
- label,
34
- icon,
35
- value,
36
- syncWithLocation,
37
- selected,
38
- onChange,
39
- children,
40
- badgeColor,
41
- badgeContent,
42
- ...props
43
- }: LongFormTabProps) => {
44
- const translate = useTranslate();
45
- const location = useLocation();
46
- const propsForLink = {
47
- component: Link,
48
- to: { ...location, pathname: value }
49
- };
50
-
51
- const tabLabel = React.isValidElement(label) ? label : translate(label as string, { _: label });
52
- const handleChange = useCallback(() => onChange(value), [onChange, value]);
53
-
54
- const renderTab = () => (
55
- <ListItemButton selected={selected} {...(syncWithLocation ? propsForLink : {})} onClick={handleChange}>
56
- {icon && <ListItemIcon>{icon}</ListItemIcon>}
57
- <ListItemText primary={tabLabel} />
58
- {badgeContent && (
59
- <ListItemSecondaryAction>
60
- <Avatar
61
- sx={{
62
- width: 24,
63
- height: 24,
64
- fontSize: 12,
65
- // @ts-ignore
66
- backgroundColor: (theme) => theme.palette[badgeColor]?.main,
67
- // @ts-ignore
68
- color: (theme) => theme.palette[badgeColor]?.contrastText
69
- }}
70
- >
71
- {badgeContent}
72
- </Avatar>
73
- </ListItemSecondaryAction>
74
- )}
75
- </ListItemButton>
76
- );
77
-
78
- const renderContent = () =>
79
- unmountOnExit && hidden ? null : (
80
- <FormGroupContextProvider name={value.toString()}>
81
- <Stack
82
- alignContent={'stretch'}
83
- style={hidden ? hiddenStyle : {}}
84
- id={`tabpanel-${value}`}
85
- aria-labelledby={`tabheader-${value}`}
86
- // Set undefined instead of false because WAI-ARIA Authoring Practices 1.1
87
- // notes that aria-hidden="false" currently behaves inconsistently across browsers.
88
- aria-hidden={hidden || undefined}
89
- {...props}
90
- >
91
- {children}
92
- </Stack>
93
- </FormGroupContextProvider>
94
- );
95
-
96
- return intent === 'header' ? renderTab() : renderContent();
97
- };
98
-
99
- LongFormTab.propTypes = {
100
- intent: PropTypes.oneOf(['header', 'content', 'sidebar']),
101
- className: PropTypes.string,
102
- contentClassName: PropTypes.string,
103
- url: PropTypes.string,
104
- icon: PropTypes.element,
105
- label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
106
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
107
- syncWithLocation: PropTypes.bool,
108
- onChange: PropTypes.func,
109
- selected: PropTypes.bool,
110
- hidden: PropTypes.bool,
111
- unmountOnExit: PropTypes.bool,
112
- children: PropTypes.node,
113
- badgeColor: PropTypes.oneOf(['default', 'error', 'info', 'primary', 'secondary', 'success', 'warning']),
114
- badgeContent: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
115
- };
116
-
117
- LongFormTab.defaultProps = {
118
- badgeColor: 'default',
119
- unmountOnExit: false
120
- };
121
-
122
- export default LongFormTab;
@@ -1,72 +0,0 @@
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
- '& .MuiListItemIcon-root': {
15
- minWidth: 32,
16
- color: theme.palette.grey[500]
17
- },
18
- '& .MuiListItemButton-root.Mui-selected': {
19
- borderRight: `2px solid ${theme.palette.primary.main}`,
20
- marginRight: `-2px`
21
- }
22
- }));
23
-
24
- export type LongFormTabsProps = {
25
- children: React.ReactNode;
26
- syncWithLocation?: boolean;
27
- value: string | number;
28
- url: string;
29
- onChange: (value: string | number) => void;
30
- };
31
-
32
- const LongFormTabs = ({ children, syncWithLocation, value, url, onChange }: LongFormTabsProps) => {
33
- const location = useLocation();
34
-
35
- return (
36
- // @ts-ignore
37
- <MainCard>
38
- {/** @ts-ignore */}
39
- <StyledList component="nav">
40
- {React.Children.map(children, (tab, index) => {
41
- if (!React.isValidElement(tab)) return null;
42
- const tabPath = getTabbedFormTabFullPath(tab, index);
43
- const selected = syncWithLocation ? !!matchPath(`${url}/${tabPath}`, location.pathname) : index === value;
44
-
45
- return React.cloneElement(tab, {
46
- // @ts-ignore
47
- intent: 'header',
48
- value: syncWithLocation ? tabPath : index,
49
- syncWithLocation,
50
- onChange,
51
- url,
52
- selected
53
- });
54
- })}
55
- </StyledList>
56
- </MainCard>
57
- );
58
- };
59
-
60
- export const getTabbedFormTabFullPath = (tab: any, index: number) =>
61
- tab.props.path != null ? tab.props.path : index > 0 ? index.toString() : '';
62
-
63
- LongFormTabs.propTypes = {
64
- children: PropTypes.node,
65
- url: PropTypes.string,
66
- tabsWithErrors: PropTypes.arrayOf(PropTypes.string),
67
- syncWithLocation: PropTypes.bool,
68
- onChange: PropTypes.func,
69
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
70
- };
71
-
72
- export default LongFormTabs;
@@ -1,161 +0,0 @@
1
- import { Disposition, DispositionProps } from './types';
2
- import React, { Fragment, useMemo, useState } from 'react';
3
- import { Route, Routes, matchPath, useLocation, useResolvedPath } from 'react-router';
4
- import { getTabbedFormTabFullPath, useResourceContext } from 'react-admin';
5
-
6
- import { Grid } from '@mui/material';
7
- import LongFormHeader from './LongFormSidebar';
8
- import LongFormTab from './LongFormTab';
9
- import LongFormTabs from './LongFormTabs';
10
- import PropTypes from 'prop-types';
11
- import StickyBox from 'react-sticky-box';
12
- import { styled } from '@mui/material/styles';
13
-
14
- const StyledGrid = styled(Grid, {
15
- name: 'ApplicaLongFormView',
16
- slot: 'Root'
17
- })(({ theme }) => ({
18
- '& .MuiToolbar-root': {
19
- position: 'initial',
20
- marginTop: theme.spacing(2),
21
- marginLeft: `-${theme.spacing(3)}`,
22
- marginRight: `-${theme.spacing(3)}`,
23
- marginBottom: `-${theme.spacing(2)}`,
24
- borderTop: `1px solid ${theme.palette.divider}`,
25
- [theme.breakpoints.down('sm')]: {
26
- position: 'initial !important',
27
- width: 'auto !important'
28
- }
29
- },
30
- '& form > .MuiToolbar-root': {
31
- // È molto importante: questa regola serve per poter inserire form, all'interno di altri form, evitando
32
- // che la toolbar del form interno recepisca gli stili della regola precedente (che genera un padding strano).
33
- margin: 0,
34
- marginRight: `-${theme.spacing(0.5)}`,
35
- [theme.breakpoints.down('sm')]: {
36
- marginRight: theme.spacing(0.5)
37
- }
38
- }
39
- }));
40
-
41
- const isSidebar = (child: any, position: string) => child && child.type === LongFormHeader && child.props.position === position;
42
- const isTab = (child: any) => child && child.type === LongFormTab;
43
-
44
- export type LongFormViewProps = {
45
- children: React.ReactNode;
46
- formRootPathname: string;
47
- syncWithLocation?: boolean;
48
- spacing: number;
49
- tabs: React.ReactElement;
50
- tabsDisposition: Disposition;
51
- contentDisposition: Disposition;
52
- sticky?: boolean;
53
- };
54
-
55
- const LongFormView = ({
56
- children,
57
- formRootPathname,
58
- syncWithLocation,
59
- spacing,
60
- tabs,
61
- tabsDisposition,
62
- contentDisposition,
63
- sticky,
64
- ...props
65
- }: LongFormViewProps) => {
66
- const [tabValue, setTabValue] = useState(0);
67
- const resolvedPath = useResolvedPath('');
68
- const resource = useResourceContext(props);
69
- const location = useLocation();
70
- const topSidebars = useMemo(() => React.Children.toArray(children).find((child) => isSidebar(child, 'top')), [children]);
71
- const bottomSidebars = useMemo(() => React.Children.toArray(children).find((child) => isSidebar(child, 'bottom')), [children]);
72
- const tabChildrens = useMemo(() => React.Children.toArray(children).filter((child) => isTab(child)), [children]);
73
-
74
- const handleTabChange = (value: number) => {
75
- if (!syncWithLocation) {
76
- setTabValue(value);
77
- }
78
- };
79
- const renderTabs = () =>
80
- React.cloneElement(
81
- tabs,
82
- {
83
- onChange: handleTabChange,
84
- syncWithLocation,
85
- url: formRootPathname,
86
- value: tabValue,
87
- intent: 'header'
88
- },
89
- tabChildrens
90
- );
91
- const sidebarContent = useMemo(
92
- () => (
93
- <Fragment>
94
- {topSidebars}
95
- {syncWithLocation ? (
96
- <Routes>
97
- <Route path="/*" element={renderTabs()} />
98
- </Routes>
99
- ) : (
100
- renderTabs()
101
- )}
102
- {bottomSidebars}
103
- </Fragment>
104
- ),
105
- [topSidebars, syncWithLocation, renderTabs, bottomSidebars]
106
- );
107
- return (
108
- <StyledGrid container spacing={spacing * 2}>
109
- <Grid item {...tabsDisposition}>
110
- {sticky ? (
111
- <StickyBox offsetTop={74} offsetBottom={spacing * 2}>
112
- {sidebarContent}
113
- </StickyBox>
114
- ) : (
115
- sidebarContent
116
- )}
117
- </Grid>
118
-
119
- <Grid item {...contentDisposition}>
120
- {/* All tabs are rendered (not only the one in focus), to allow validation
121
- on tabs not in focus. The tabs receive a `hidden` property, which they'll
122
- use to hide the tab using CSS if it's not the one in focus.
123
- See https://github.com/marmelab/react-admin/issues/1866 */}
124
- {React.Children.map(tabChildrens, (tab: any, index: number) => {
125
- if (!tab) {
126
- return null;
127
- }
128
- const tabPath = getTabbedFormTabFullPath(tab, index);
129
- const hidden = syncWithLocation ? !matchPath(`${resolvedPath.pathname}/${tabPath}`, location.pathname) : tabValue !== index;
130
-
131
- return React.isValidElement(tab)
132
- ? React.cloneElement(tab, {
133
- // @ts-ignore
134
- intent: 'content',
135
- resource,
136
- hidden,
137
- value: syncWithLocation ? tabPath : index
138
- })
139
- : null;
140
- })}
141
- </Grid>
142
- </StyledGrid>
143
- );
144
- };
145
-
146
- LongFormView.propTypes = {
147
- children: PropTypes.node,
148
- spacing: PropTypes.number,
149
- syncWithLocation: PropTypes.bool,
150
- tabs: PropTypes.element,
151
- formRootPathname: PropTypes.string,
152
- tabsDisposition: DispositionProps,
153
- contentDisposition: DispositionProps
154
- };
155
-
156
- LongFormView.defaultProps = {
157
- // @ts-ignore
158
- tabs: <LongFormTabs />
159
- };
160
-
161
- export default LongFormView;
@@ -1,2 +0,0 @@
1
- import LongForm from './LongForm';
2
- export default LongForm;
@@ -1,21 +0,0 @@
1
- import { matchPath, useLocation } from 'react-router-dom';
2
-
3
- /**
4
- * Restituisce il path di base del form in base ad una serie di specifici match di path che è possibile incontrare.
5
- */
6
- const useFormRootPath = (): string => {
7
- const location = useLocation();
8
- // I possibili match sono ordinati per priorità (è fondamentale).
9
- const allPossibleMatches = ['entities/:resource/create/*', ':resource/create/*', 'entities/:resource/:id/*', ':resource/:id/*'];
10
-
11
- for (const possibleMatch of allPossibleMatches) {
12
- const match = matchPath(possibleMatch, location.pathname);
13
- if (match) {
14
- return match.pathnameBase;
15
- }
16
- }
17
-
18
- return '';
19
- };
20
-
21
- export default useFormRootPath;