@applica-software-guru/react-admin 1.5.281 → 1.5.283
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/dist/components/Pagination/Pagination.d.ts +15 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationActions.d.ts +12 -0
- package/dist/components/Pagination/PaginationActions.d.ts.map +1 -0
- package/dist/components/ra-forms/LongForm/Tab.d.ts.map +1 -1
- package/dist/components/ra-forms/WizardForm/Content.d.ts +15 -0
- package/dist/components/ra-forms/WizardForm/Content.d.ts.map +1 -0
- package/dist/components/ra-forms/WizardForm/Form.d.ts +38 -0
- package/dist/components/ra-forms/WizardForm/Form.d.ts.map +1 -0
- package/dist/components/ra-forms/WizardForm/Provider.d.ts +48 -0
- package/dist/components/ra-forms/WizardForm/Provider.d.ts.map +1 -0
- package/dist/components/ra-forms/WizardForm/Stepper.d.ts +18 -0
- package/dist/components/ra-forms/WizardForm/Stepper.d.ts.map +1 -0
- package/dist/components/ra-forms/WizardForm/Toolbar.d.ts +20 -0
- package/dist/components/ra-forms/WizardForm/Toolbar.d.ts.map +1 -0
- package/dist/components/ra-forms/WizardForm/index.d.ts +4 -0
- package/dist/components/ra-forms/WizardForm/index.d.ts.map +1 -0
- package/dist/components/ra-forms/index.d.ts +1 -0
- package/dist/components/ra-forms/index.d.ts.map +1 -1
- package/dist/components/ra-lists/List.d.ts.map +1 -1
- package/dist/components/ra-lists/SimpleList.d.ts +2 -2
- package/dist/react-admin.cjs.js +58 -58
- package/dist/react-admin.cjs.js.gz +0 -0
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +9507 -9168
- package/dist/react-admin.es.js.gz +0 -0
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +56 -56
- package/dist/react-admin.umd.js.gz +0 -0
- package/dist/react-admin.umd.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/react.d.ts +14 -0
- package/dist/utils/react.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Pagination/Pagination.tsx +184 -0
- package/src/components/Pagination/PaginationActions.tsx +84 -0
- package/src/components/Pagination/index.ts +2 -0
- package/src/components/ra-forms/LongForm/Tab.tsx +2 -11
- package/src/components/ra-forms/WizardForm/Content.tsx +82 -0
- package/src/components/ra-forms/WizardForm/Form.tsx +113 -0
- package/src/components/ra-forms/WizardForm/Provider.tsx +62 -0
- package/src/components/ra-forms/WizardForm/Stepper.tsx +113 -0
- package/src/components/ra-forms/WizardForm/Toolbar.tsx +58 -0
- package/src/components/ra-forms/WizardForm/index.ts +4 -0
- package/src/components/ra-forms/index.ts +1 -0
- package/src/components/ra-lists/List.tsx +2 -1
- package/src/playground/App.jsx +2 -1
- package/src/playground/components/ra-forms/TestWizardForm/AdvancedUsage.jsx +176 -0
- package/src/playground/components/ra-forms/TestWizardForm/BaseUsage.jsx +115 -0
- package/src/playground/components/ra-forms/TestWizardForm/TestWizardForm.jsx +27 -0
- package/src/playground/components/ra-forms/TestWizardForm/index.jsx +1 -0
- package/src/playground/components/ra-forms/index.jsx +1 -0
- package/src/playground/menu.jsx +8 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/react.ts +25 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { Box, Stepper as MuiStepper, Step, StepIconProps, StepLabel, styled } from '@mui/material';
|
|
3
|
+
import { useWizardFormContext } from './Provider';
|
|
4
|
+
import { useFormState } from 'react-hook-form';
|
|
5
|
+
import _ from 'lodash';
|
|
6
|
+
|
|
7
|
+
interface WizardStepperProps {
|
|
8
|
+
isHorizontal: boolean;
|
|
9
|
+
setCurrentStep: (step: number) => void;
|
|
10
|
+
stepFields: Array<Array<string>>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const StyledStepper = styled(MuiStepper, {
|
|
14
|
+
shouldForwardProp: (prop) => prop !== 'isHorizontal'
|
|
15
|
+
})<{ isHorizontal: boolean }>(({ theme, isHorizontal }) => ({
|
|
16
|
+
paddingBottom: theme.spacing(2),
|
|
17
|
+
display: 'flex',
|
|
18
|
+
justifyContent: isHorizontal ? 'space-between' : 'flex-start',
|
|
19
|
+
'.MuiStep-root': {
|
|
20
|
+
flex: isHorizontal ? 1 : 'none',
|
|
21
|
+
maxWidth: isHorizontal ? 'none' : '100%',
|
|
22
|
+
display: 'flex',
|
|
23
|
+
justifyContent: isHorizontal ? 'center' : 'flex-start'
|
|
24
|
+
},
|
|
25
|
+
'.MuiStepConnector-line.MuiStepConnector-lineVertical': {
|
|
26
|
+
minHeight: 12
|
|
27
|
+
},
|
|
28
|
+
'.MuiStepConnector-vertical': {
|
|
29
|
+
marginLeft: 14.5
|
|
30
|
+
},
|
|
31
|
+
'.MuiStepConnector-horizontal': {
|
|
32
|
+
marginLeft: -10
|
|
33
|
+
}
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
const StyledStepIconRoot = styled(Box)<{
|
|
37
|
+
ownerState: { completed?: boolean; active?: boolean; error?: boolean };
|
|
38
|
+
}>(({ theme, ownerState }) => ({
|
|
39
|
+
backgroundColor: ownerState.error
|
|
40
|
+
? theme.palette.error.main
|
|
41
|
+
: ownerState.completed || ownerState.active
|
|
42
|
+
? theme.palette.primary.main
|
|
43
|
+
: theme.palette.mode === 'dark'
|
|
44
|
+
? theme.palette.grey[200]
|
|
45
|
+
: theme.palette.grey[400],
|
|
46
|
+
zIndex: 1,
|
|
47
|
+
color: theme.palette.common.white,
|
|
48
|
+
width: 30,
|
|
49
|
+
height: 30,
|
|
50
|
+
display: 'flex',
|
|
51
|
+
borderRadius: '50%',
|
|
52
|
+
justifyContent: 'center',
|
|
53
|
+
alignItems: 'center'
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
function StyledStepIcon({ completed, active, error, icon, className }: StepIconProps) {
|
|
57
|
+
return (
|
|
58
|
+
<StyledStepIconRoot ownerState={{ completed, active, error }} className={className}>
|
|
59
|
+
{error ? '!' : icon}
|
|
60
|
+
</StyledStepIconRoot>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Stepper component for rendering a step-by-step navigation UI.
|
|
66
|
+
*
|
|
67
|
+
* @param {Object} props - The properties object.
|
|
68
|
+
* @param {boolean} props.isHorizontal - Determines the orientation of the stepper (horizontal or vertical).
|
|
69
|
+
* @param {function} props.setCurrentStep - Function to set the current step index.
|
|
70
|
+
* @param {Array} props.stepFields - Array of fields associated with each step.
|
|
71
|
+
*
|
|
72
|
+
* @returns {JSX.Element} The rendered Stepper component.
|
|
73
|
+
*/
|
|
74
|
+
function Stepper({ isHorizontal, setCurrentStep, stepFields }: WizardStepperProps) {
|
|
75
|
+
const { currentStep, steps } = useWizardFormContext();
|
|
76
|
+
const { errors } = useFormState();
|
|
77
|
+
|
|
78
|
+
function handleClick(index: number) {
|
|
79
|
+
if (index <= currentStep) {
|
|
80
|
+
setCurrentStep(index);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<StyledStepper
|
|
86
|
+
activeStep={currentStep}
|
|
87
|
+
orientation={isHorizontal ? 'horizontal' : 'vertical'}
|
|
88
|
+
isHorizontal={isHorizontal}
|
|
89
|
+
sx={{ p: 3, mt: 1 }}
|
|
90
|
+
>
|
|
91
|
+
{steps.map((step: ReactElement, index: number) => {
|
|
92
|
+
const stepHasError = stepFields[index].some((field) => _.get(errors, field));
|
|
93
|
+
const { label, icon } = step.props;
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<Step key={index}>
|
|
97
|
+
<StepLabel
|
|
98
|
+
StepIconComponent={StyledStepIcon}
|
|
99
|
+
error={stepHasError}
|
|
100
|
+
icon={icon}
|
|
101
|
+
onClick={() => handleClick(index)}
|
|
102
|
+
style={{ cursor: index <= currentStep ? 'pointer' : 'default' }}
|
|
103
|
+
>
|
|
104
|
+
{isHorizontal ? null : label}
|
|
105
|
+
</StepLabel>
|
|
106
|
+
</Step>
|
|
107
|
+
);
|
|
108
|
+
})}
|
|
109
|
+
</StyledStepper>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export { Stepper };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ReactNode, cloneElement, useCallback } from 'react';
|
|
2
|
+
import { Box, Button } from '@mui/material';
|
|
3
|
+
import { Toolbar as RaToolbar, ToolbarProps } from '@/components/ra-forms/Toolbar';
|
|
4
|
+
import { SaveButton } from 'react-admin';
|
|
5
|
+
import { useTranslate } from 'ra-core';
|
|
6
|
+
import { useFormContext } from 'react-hook-form';
|
|
7
|
+
import { useWizardFormContext } from './Provider';
|
|
8
|
+
|
|
9
|
+
interface WizardToolbarProps extends ToolbarProps {
|
|
10
|
+
cancelButton?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Toolbar component for the WizardForm.
|
|
15
|
+
*
|
|
16
|
+
* This component renders a toolbar with navigation buttons for a multi-step form.
|
|
17
|
+
* It includes buttons to navigate to the previous and next steps, as well as a cancel button.
|
|
18
|
+
*
|
|
19
|
+
* @param {WizardToolbarProps} props - The properties for the Toolbar component.
|
|
20
|
+
* @param {React.ReactElement} props.cancelButton - An optional cancel button element.
|
|
21
|
+
* @param {object} props.toolbarProps - Additional properties to pass to the RaToolbar component.
|
|
22
|
+
*
|
|
23
|
+
* @returns {JSX.Element} The rendered Toolbar component.
|
|
24
|
+
*/
|
|
25
|
+
function Toolbar({ cancelButton, ...props }: WizardToolbarProps) {
|
|
26
|
+
const { hasNextStep, hasPreviousStep, goToNextStep, goToPreviousStep } = useWizardFormContext();
|
|
27
|
+
const translate = useTranslate();
|
|
28
|
+
const { handleSubmit } = useFormContext();
|
|
29
|
+
const onSubmit = useCallback(() => {
|
|
30
|
+
goToNextStep();
|
|
31
|
+
}, [goToNextStep]);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<RaToolbar {...props}>
|
|
35
|
+
<Box sx={{ '& .MuiButtonBase-root': { ml: 0 } }}>
|
|
36
|
+
{
|
|
37
|
+
//@ts-ignore
|
|
38
|
+
cancelButton ? cloneElement(cancelButton) : null
|
|
39
|
+
}
|
|
40
|
+
</Box>
|
|
41
|
+
<Box sx={{ flex: '1 1 auto' }} />
|
|
42
|
+
{hasPreviousStep() && (
|
|
43
|
+
<Button variant="text" color="primary" onClick={goToPreviousStep}>
|
|
44
|
+
{translate('ra.action.back')}
|
|
45
|
+
</Button>
|
|
46
|
+
)}
|
|
47
|
+
{hasNextStep() ? (
|
|
48
|
+
<Button variant="contained" color="primary" onClick={handleSubmit(onSubmit)}>
|
|
49
|
+
{translate('ra.action.next')}
|
|
50
|
+
</Button>
|
|
51
|
+
) : (
|
|
52
|
+
<SaveButton />
|
|
53
|
+
)}
|
|
54
|
+
</RaToolbar>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Toolbar };
|
|
@@ -4,6 +4,7 @@ import { styled } from '@mui/system';
|
|
|
4
4
|
import { ListBase, RaRecord } from 'ra-core';
|
|
5
5
|
import { ReactElement } from 'react';
|
|
6
6
|
import { ListProps } from 'react-admin';
|
|
7
|
+
import { Pagination } from '@/components/Pagination/Pagination';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* List page component
|
|
@@ -191,7 +192,7 @@ const StyledList = styled(RaList, { slot: 'root' })(({ theme }) => ({
|
|
|
191
192
|
function List(props: ListProps): ReactElement {
|
|
192
193
|
return (
|
|
193
194
|
<MainCard content={false}>
|
|
194
|
-
<StyledList {...props} />
|
|
195
|
+
<StyledList {...props} pagination={<Pagination />} />
|
|
195
196
|
</MainCard>
|
|
196
197
|
);
|
|
197
198
|
}
|
package/src/playground/App.jsx
CHANGED
|
@@ -3,7 +3,7 @@ import { menu } from './menu';
|
|
|
3
3
|
import { theme } from './theme';
|
|
4
4
|
import { ActivatePage, ApplicaAdmin, HttpError, RecoverPage, RegisterPage, Resource } from '@/';
|
|
5
5
|
import build from '@/playground/build.json';
|
|
6
|
-
import { CustomPage } from '@/playground/components';
|
|
6
|
+
import { CustomPage, TestWizardForm } from '@/playground/components';
|
|
7
7
|
import { API_URL, APP_NAME } from '@/playground/config';
|
|
8
8
|
import { ApplicaDataProvider, createAttachmentsParser } from '@applica-software-guru/crud-client';
|
|
9
9
|
import { ApplicaAuthProvider, LocalStorage } from '@applica-software-guru/iam-client';
|
|
@@ -44,6 +44,7 @@ function App() {
|
|
|
44
44
|
>
|
|
45
45
|
<CustomRoutes>
|
|
46
46
|
<Route path="/custom-page" element={<CustomPage />} />
|
|
47
|
+
<Route path="/wizard-form" element={<TestWizardForm />} />
|
|
47
48
|
</CustomRoutes>
|
|
48
49
|
<Resource name="entities/notification" {...entities.notification} />
|
|
49
50
|
<Resource name="entities/user" {...entities.user} />
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BooleanInput,
|
|
3
|
+
ReadonlyField,
|
|
4
|
+
TextInput,
|
|
5
|
+
Toolbar,
|
|
6
|
+
WizardForm,
|
|
7
|
+
required,
|
|
8
|
+
useThemeConfig,
|
|
9
|
+
useTranslate,
|
|
10
|
+
useWizardFormContext
|
|
11
|
+
} from '@applica-software-guru/react-admin';
|
|
12
|
+
import { Box, Button, Grid, Step, StepLabel, Stepper, Typography } from '@mui/material';
|
|
13
|
+
import { SaveButton } from 'ra-ui-materialui';
|
|
14
|
+
import { useFormContext } from 'react-hook-form';
|
|
15
|
+
|
|
16
|
+
//il seguente form non avrà uno stile coerente, ma è solo per testare il funzionamento del WizardForm
|
|
17
|
+
|
|
18
|
+
function CustomToolbar({ ...props }) {
|
|
19
|
+
const { hasNextStep, hasPreviousStep, goToNextStep, goToPreviousStep } = useWizardFormContext();
|
|
20
|
+
const translate = useTranslate();
|
|
21
|
+
const { handleSubmit } = useFormContext();
|
|
22
|
+
|
|
23
|
+
const handleNext = handleSubmit(() => {
|
|
24
|
+
goToNextStep();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Toolbar {...props}>
|
|
29
|
+
{hasPreviousStep() && (
|
|
30
|
+
<Button variant="text" color="primary" onClick={goToPreviousStep}>
|
|
31
|
+
{translate('ra.action.back')}
|
|
32
|
+
</Button>
|
|
33
|
+
)}
|
|
34
|
+
{hasNextStep() ? (
|
|
35
|
+
<>
|
|
36
|
+
<Button variant="contained" color="primary" onClick={goToNextStep}>
|
|
37
|
+
Skip
|
|
38
|
+
</Button>
|
|
39
|
+
<Button variant="contained" color="primary" onClick={handleNext}>
|
|
40
|
+
{translate('ra.action.next')}
|
|
41
|
+
</Button>
|
|
42
|
+
</>
|
|
43
|
+
) : (
|
|
44
|
+
<SaveButton />
|
|
45
|
+
)}
|
|
46
|
+
</Toolbar>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function CustomProgress() {
|
|
51
|
+
const { steps, currentStep } = useWizardFormContext();
|
|
52
|
+
return (
|
|
53
|
+
<Stepper activeStep={currentStep} orientation="vertical">
|
|
54
|
+
{steps.map((step, index) => (
|
|
55
|
+
<Step key={index}>
|
|
56
|
+
<StepLabel>{step.props.label}</StepLabel>
|
|
57
|
+
</Step>
|
|
58
|
+
))}
|
|
59
|
+
</Stepper>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function AdvancedUsage() {
|
|
64
|
+
const { spacing } = useThemeConfig();
|
|
65
|
+
return (
|
|
66
|
+
<WizardForm
|
|
67
|
+
defaultValues={{ name: 'Mario', surname: 'Rossi' }}
|
|
68
|
+
toolbar={<CustomToolbar />}
|
|
69
|
+
progress={<CustomProgress />}
|
|
70
|
+
title="Conferma ordine"
|
|
71
|
+
validate={(values) => {
|
|
72
|
+
const errors = {};
|
|
73
|
+
if (values.terms !== true) {
|
|
74
|
+
errors.terms = 'Devi accettare i termini e le condizioni';
|
|
75
|
+
}
|
|
76
|
+
return errors;
|
|
77
|
+
}}
|
|
78
|
+
secondary="Ordine #1"
|
|
79
|
+
subheader="Wizard Form"
|
|
80
|
+
>
|
|
81
|
+
<WizardForm.Step label="Indirizzo di spedizione">
|
|
82
|
+
<Grid container spacing={spacing}>
|
|
83
|
+
<Grid item xs={6}>
|
|
84
|
+
<TextInput source="name" label="Nome" validate={required()} fullWidth />
|
|
85
|
+
</Grid>
|
|
86
|
+
<Grid item xs={6}>
|
|
87
|
+
<TextInput source="surname" label="Cognome" validate={required()} fullWidth />
|
|
88
|
+
</Grid>
|
|
89
|
+
<Grid item xs={12}>
|
|
90
|
+
<TextInput source="address" label="Indirizzo" fullWidth />
|
|
91
|
+
</Grid>
|
|
92
|
+
<Grid item xs={6}>
|
|
93
|
+
<TextInput source="nation" label="Nazione" fullWidth />
|
|
94
|
+
</Grid>
|
|
95
|
+
<Grid item xs={6}>
|
|
96
|
+
<TextInput source="province" label="Provincia" fullWidth />
|
|
97
|
+
</Grid>
|
|
98
|
+
<Grid item xs={6}>
|
|
99
|
+
<TextInput source="city" label="Città" fullWidth />
|
|
100
|
+
</Grid>
|
|
101
|
+
<Grid item xs={6}>
|
|
102
|
+
<TextInput source="zip" label="Codice Postale" fullWidth />
|
|
103
|
+
</Grid>
|
|
104
|
+
</Grid>
|
|
105
|
+
</WizardForm.Step>
|
|
106
|
+
<WizardForm.Step label="Dati di fatturazione">
|
|
107
|
+
<Grid container spacing={spacing}>
|
|
108
|
+
<Grid item xs={6}>
|
|
109
|
+
<TextInput source="billingName" label="Nome sulla carta" validate={required()} fullWidth />
|
|
110
|
+
</Grid>
|
|
111
|
+
<Grid item xs={6}>
|
|
112
|
+
<TextInput source="cardNumber" label="Numero carta" validate={required()} fullWidth />
|
|
113
|
+
</Grid>
|
|
114
|
+
<Grid item xs={12}>
|
|
115
|
+
<TextInput source="expirationDate" label="Data di scadenza" fullWidth />
|
|
116
|
+
</Grid>
|
|
117
|
+
<Grid item xs={12}>
|
|
118
|
+
<TextInput source="cvv" label="CVV" fullWidth />
|
|
119
|
+
</Grid>
|
|
120
|
+
</Grid>
|
|
121
|
+
</WizardForm.Step>
|
|
122
|
+
<WizardForm.Step label="Controlla il tuo ordine">
|
|
123
|
+
<Grid container spacing={spacing}>
|
|
124
|
+
<Grid item xs={12}>
|
|
125
|
+
<Box display="flex" justifyContent="space-between">
|
|
126
|
+
<Box>
|
|
127
|
+
<Typography variant="h6">Prodotto 1</Typography>
|
|
128
|
+
<Typography variant="body2">Descrizione del prodotto 1</Typography>
|
|
129
|
+
</Box>
|
|
130
|
+
<Typography variant="body2" align="right">
|
|
131
|
+
€100.00
|
|
132
|
+
</Typography>
|
|
133
|
+
</Box>
|
|
134
|
+
</Grid>
|
|
135
|
+
<Grid item xs={12}>
|
|
136
|
+
<Box display="flex" justifyContent="space-between">
|
|
137
|
+
<Box>
|
|
138
|
+
<Typography variant="h6">Prodotto 2</Typography>
|
|
139
|
+
<Typography variant="body2">Descrizione del prodotto 2</Typography>
|
|
140
|
+
</Box>
|
|
141
|
+
<Typography variant="body2" align="right">
|
|
142
|
+
€42.00
|
|
143
|
+
</Typography>
|
|
144
|
+
</Box>
|
|
145
|
+
</Grid>
|
|
146
|
+
<Grid item xs={12}>
|
|
147
|
+
<Box display="flex" justifyContent="space-between">
|
|
148
|
+
<Box>
|
|
149
|
+
<Typography variant="h6">Prodotto 3</Typography>
|
|
150
|
+
<Typography variant="body2">Descrizione del prodotto 3</Typography>
|
|
151
|
+
</Box>
|
|
152
|
+
<Typography variant="body2" align="right">
|
|
153
|
+
€37.00
|
|
154
|
+
</Typography>
|
|
155
|
+
</Box>
|
|
156
|
+
</Grid>
|
|
157
|
+
<Grid item xs={12}>
|
|
158
|
+
<Box display="flex" justifyContent="space-between">
|
|
159
|
+
<Box>
|
|
160
|
+
<Typography variant="h6">Totale</Typography>
|
|
161
|
+
</Box>
|
|
162
|
+
<Typography variant="h6" align="right">
|
|
163
|
+
€179.00
|
|
164
|
+
</Typography>
|
|
165
|
+
</Box>
|
|
166
|
+
</Grid>
|
|
167
|
+
<Grid item xs={12}>
|
|
168
|
+
<BooleanInput source="terms" label="Accetto i termini e le condizioni" />
|
|
169
|
+
</Grid>
|
|
170
|
+
</Grid>
|
|
171
|
+
</WizardForm.Step>
|
|
172
|
+
</WizardForm>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export { AdvancedUsage };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { CreateInDialogButton } from '@/components';
|
|
2
|
+
import { ContainerOutlined, CreditCardOutlined, UserOutlined } from '@ant-design/icons';
|
|
3
|
+
import {
|
|
4
|
+
BooleanInput,
|
|
5
|
+
Create,
|
|
6
|
+
ReadonlyField,
|
|
7
|
+
TextInput,
|
|
8
|
+
WizardForm,
|
|
9
|
+
required,
|
|
10
|
+
useThemeConfig
|
|
11
|
+
} from '@applica-software-guru/react-admin';
|
|
12
|
+
import { Box, Grid, Typography } from '@mui/material';
|
|
13
|
+
|
|
14
|
+
function BaseUsage() {
|
|
15
|
+
const { spacing } = useThemeConfig();
|
|
16
|
+
return (
|
|
17
|
+
//<CreateInDialogButton maxWidth="sm" resource="a">
|
|
18
|
+
<WizardForm>
|
|
19
|
+
<WizardForm.Step label="Indirizzo di spedizione" icon={<UserOutlined />}>
|
|
20
|
+
<Grid container spacing={spacing}>
|
|
21
|
+
<Grid item xs={6}>
|
|
22
|
+
<TextInput source="name" label="Nome" validate={required()} fullWidth />
|
|
23
|
+
</Grid>
|
|
24
|
+
<Grid item xs={6}>
|
|
25
|
+
<TextInput source="surname" label="Cognome" validate={required()} fullWidth />
|
|
26
|
+
</Grid>
|
|
27
|
+
<Grid item xs={12}>
|
|
28
|
+
<TextInput source="address" label="Indirizzo" fullWidth />
|
|
29
|
+
</Grid>
|
|
30
|
+
<Grid item xs={6}>
|
|
31
|
+
<TextInput source="nation" label="Nazione" fullWidth />
|
|
32
|
+
</Grid>
|
|
33
|
+
<Grid item xs={6}>
|
|
34
|
+
<TextInput source="province" label="Provincia" fullWidth />
|
|
35
|
+
</Grid>
|
|
36
|
+
<Grid item xs={6}>
|
|
37
|
+
<TextInput source="city" label="Città" fullWidth />
|
|
38
|
+
</Grid>
|
|
39
|
+
<Grid item xs={6}>
|
|
40
|
+
<TextInput source="zip" label="Codice Postale" fullWidth />
|
|
41
|
+
</Grid>
|
|
42
|
+
</Grid>
|
|
43
|
+
</WizardForm.Step>
|
|
44
|
+
<WizardForm.Step label="Dati di fatturazione" icon={<CreditCardOutlined />}>
|
|
45
|
+
<Grid container spacing={spacing}>
|
|
46
|
+
<Grid item xs={6}>
|
|
47
|
+
<TextInput source="billingName" label="Nome sulla carta" validate={required()} fullWidth />
|
|
48
|
+
</Grid>
|
|
49
|
+
<Grid item xs={6}>
|
|
50
|
+
<TextInput source="cardNumber" label="Numero carta" validate={required()} fullWidth />
|
|
51
|
+
</Grid>
|
|
52
|
+
<Grid item xs={12}>
|
|
53
|
+
<TextInput source="expirationDate" label="Data di scadenza" fullWidth />
|
|
54
|
+
</Grid>
|
|
55
|
+
<Grid item xs={12}>
|
|
56
|
+
<TextInput source="cvv" label="CVV" fullWidth />
|
|
57
|
+
</Grid>
|
|
58
|
+
</Grid>
|
|
59
|
+
</WizardForm.Step>
|
|
60
|
+
<WizardForm.Step label="Controlla il tuo ordine" icon={<ContainerOutlined />}>
|
|
61
|
+
<Grid container spacing={spacing}>
|
|
62
|
+
<Grid item xs={12}>
|
|
63
|
+
<Box display="flex" justifyContent="space-between">
|
|
64
|
+
<Box>
|
|
65
|
+
<Typography variant="h6">Prodotto 1</Typography>
|
|
66
|
+
<Typography variant="body2">Descrizione del prodotto 1</Typography>
|
|
67
|
+
</Box>
|
|
68
|
+
<Typography variant="body2" align="right">
|
|
69
|
+
€100.00
|
|
70
|
+
</Typography>
|
|
71
|
+
</Box>
|
|
72
|
+
</Grid>
|
|
73
|
+
<Grid item xs={12}>
|
|
74
|
+
<Box display="flex" justifyContent="space-between">
|
|
75
|
+
<Box>
|
|
76
|
+
<Typography variant="h6">Prodotto 2</Typography>
|
|
77
|
+
<Typography variant="body2">Descrizione del prodotto 2</Typography>
|
|
78
|
+
</Box>
|
|
79
|
+
<Typography variant="body2" align="right">
|
|
80
|
+
€42.00
|
|
81
|
+
</Typography>
|
|
82
|
+
</Box>
|
|
83
|
+
</Grid>
|
|
84
|
+
<Grid item xs={12}>
|
|
85
|
+
<Box display="flex" justifyContent="space-between">
|
|
86
|
+
<Box>
|
|
87
|
+
<Typography variant="h6">Prodotto 3</Typography>
|
|
88
|
+
<Typography variant="body2">Descrizione del prodotto 3</Typography>
|
|
89
|
+
</Box>
|
|
90
|
+
<Typography variant="body2" align="right">
|
|
91
|
+
€37.00
|
|
92
|
+
</Typography>
|
|
93
|
+
</Box>
|
|
94
|
+
</Grid>
|
|
95
|
+
<Grid item xs={12}>
|
|
96
|
+
<Box display="flex" justifyContent="space-between">
|
|
97
|
+
<Box>
|
|
98
|
+
<Typography variant="h6">Totale</Typography>
|
|
99
|
+
</Box>
|
|
100
|
+
<Typography variant="h6" align="right">
|
|
101
|
+
€179.00
|
|
102
|
+
</Typography>
|
|
103
|
+
</Box>
|
|
104
|
+
</Grid>
|
|
105
|
+
<Grid item xs={12}>
|
|
106
|
+
<BooleanInput source="terms" label="Accetto i termini e le condizioni" />
|
|
107
|
+
</Grid>
|
|
108
|
+
</Grid>
|
|
109
|
+
</WizardForm.Step>
|
|
110
|
+
</WizardForm>
|
|
111
|
+
//</CreateInDialogButton>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { BaseUsage };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BooleanInput,
|
|
3
|
+
ReadonlyField,
|
|
4
|
+
TextInput,
|
|
5
|
+
WizardForm,
|
|
6
|
+
required,
|
|
7
|
+
useThemeConfig
|
|
8
|
+
} from '@applica-software-guru/react-admin';
|
|
9
|
+
import { Box, Grid, Typography } from '@mui/material';
|
|
10
|
+
import { BaseUsage } from './BaseUsage';
|
|
11
|
+
import { AdvancedUsage } from './AdvancedUsage';
|
|
12
|
+
|
|
13
|
+
function TestWizardForm() {
|
|
14
|
+
const { spacing } = useThemeConfig();
|
|
15
|
+
return (
|
|
16
|
+
<Grid container spacing={spacing}>
|
|
17
|
+
<Grid item xs={12}>
|
|
18
|
+
<BaseUsage />
|
|
19
|
+
</Grid>
|
|
20
|
+
<Grid item xs={12}>
|
|
21
|
+
<AdvancedUsage />
|
|
22
|
+
</Grid>
|
|
23
|
+
</Grid>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { TestWizardForm };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TestWizardForm';
|
package/src/playground/menu.jsx
CHANGED
|
@@ -36,6 +36,14 @@ export const menu = [
|
|
|
36
36
|
url: '/custom-page',
|
|
37
37
|
resource: false,
|
|
38
38
|
icon: TableOutlined
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'custom-pages/wizard-form',
|
|
42
|
+
title: 'ra.menu.item.wizard_form',
|
|
43
|
+
type: 'item',
|
|
44
|
+
url: '/wizard-form',
|
|
45
|
+
resource: false,
|
|
46
|
+
icon: TableOutlined
|
|
39
47
|
}
|
|
40
48
|
]
|
|
41
49
|
},
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactElement, ReactNode, isValidElement } from 'react';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This file contains utility functions that can be reused across the project.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Originally made for LongForm component to find sources.
|
|
10
|
+
* Walks the children of a React element and calls a callback function for each child.
|
|
11
|
+
*
|
|
12
|
+
* @param {ReactNode} children - The children of a React element.
|
|
13
|
+
* @param {Function} callback - The callback function to call for each child.
|
|
14
|
+
*/
|
|
15
|
+
function walkChildren(children: ReactNode = [], callback: (el: ReactElement) => void) {
|
|
16
|
+
const _children = _.isArray(children) ? children : [children];
|
|
17
|
+
const validChildren = _.filter(_children, (child) => isValidElement(child));
|
|
18
|
+
_.each(validChildren, (child) => {
|
|
19
|
+
callback(child);
|
|
20
|
+
// @ts-ignore @ts-expect-error Property 'children' does not exist on type '{}'.
|
|
21
|
+
walkChildren(child?.props?.children ?? [], callback);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { walkChildren };
|