mirror of
https://github.com/strapi/strapi.git
synced 2025-09-27 09:25:46 +00:00
Move input component to helper plugin
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
53563d82a3
commit
d69ee57dae
@ -0,0 +1,108 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import {
|
||||||
|
Stack,
|
||||||
|
Grid,
|
||||||
|
GridItem,
|
||||||
|
ModalLayout,
|
||||||
|
ModalHeader,
|
||||||
|
ModalFooter,
|
||||||
|
ModalBody,
|
||||||
|
Button,
|
||||||
|
Breadcrumbs,
|
||||||
|
Crumb,
|
||||||
|
Text,
|
||||||
|
Box,
|
||||||
|
H2,
|
||||||
|
} from '@strapi/parts';
|
||||||
|
import { Formik } from 'formik';
|
||||||
|
import { Form } from '@strapi/helper-plugin';
|
||||||
|
import schema from './utils/schema';
|
||||||
|
import stepper from './utils/stepper';
|
||||||
|
|
||||||
|
const ModalForm = ({ onToggle }) => {
|
||||||
|
const [currentStep, setStep] = useState('create');
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const headerTitle = formatMessage({
|
||||||
|
id: 'Settings.permissions.users.create',
|
||||||
|
defaultMessage: 'Create new user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const goNext = () => {
|
||||||
|
if (next) {
|
||||||
|
setStep(next);
|
||||||
|
} else {
|
||||||
|
onToggle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const { buttonSubmitLabel, isDisabled, next } = stepper[currentStep];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalLayout onClose={onToggle} labelledBy="title">
|
||||||
|
<ModalHeader>
|
||||||
|
<Breadcrumbs label={headerTitle}>
|
||||||
|
<Crumb>{headerTitle}</Crumb>
|
||||||
|
</Breadcrumbs>
|
||||||
|
</ModalHeader>
|
||||||
|
<Formik
|
||||||
|
initialValues={{ firstname: '', lastname: '', email: '', roles: [] }}
|
||||||
|
onSubmit={() => {}}
|
||||||
|
validationSchema={schema}
|
||||||
|
validateOnChange={false}
|
||||||
|
>
|
||||||
|
{({ errors, handleChange, values }) => {
|
||||||
|
return (
|
||||||
|
<Form>
|
||||||
|
<ModalBody>
|
||||||
|
<Stack size={6}>
|
||||||
|
<Box>
|
||||||
|
<H2>
|
||||||
|
{formatMessage({
|
||||||
|
id: 'app.components.Users.ModalCreateBody.block-title.details',
|
||||||
|
defaultMessage: 'Details',
|
||||||
|
})}
|
||||||
|
</H2>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<H2>
|
||||||
|
{formatMessage({
|
||||||
|
id: 'app.components.Users.ModalCreateBody.block-title.login',
|
||||||
|
defaultMessage: 'Login settings',
|
||||||
|
})}
|
||||||
|
</H2>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
<input type="text" value={values.firstname} name="firstname" />
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter
|
||||||
|
startActions={
|
||||||
|
<Button variant="tertiary" onClick={onToggle} type="button">
|
||||||
|
{formatMessage({
|
||||||
|
id: 'app.components.Button.cancel',
|
||||||
|
defaultMessage: 'Cancel',
|
||||||
|
})}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
endActions={
|
||||||
|
<>
|
||||||
|
<Button type="submit" loading={false}>
|
||||||
|
{formatMessage(buttonSubmitLabel)}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
</ModalLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ModalForm.propTypes = {
|
||||||
|
onToggle: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalForm;
|
@ -0,0 +1,17 @@
|
|||||||
|
import * as yup from 'yup';
|
||||||
|
import { translatedErrors } from '@strapi/helper-plugin';
|
||||||
|
|
||||||
|
const schema = yup.object().shape({
|
||||||
|
firstname: yup.string().required(translatedErrors.required),
|
||||||
|
lastname: yup.string().required(translatedErrors.required),
|
||||||
|
email: yup
|
||||||
|
.string()
|
||||||
|
.email(translatedErrors.email)
|
||||||
|
.required(translatedErrors.required),
|
||||||
|
roles: yup
|
||||||
|
.array()
|
||||||
|
.min(1, translatedErrors.min)
|
||||||
|
.required(translatedErrors.required),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default schema;
|
@ -0,0 +1,21 @@
|
|||||||
|
// import { ModalCreateBody } fro../../../../../components/Usersers';
|
||||||
|
|
||||||
|
const stepper = {
|
||||||
|
create: {
|
||||||
|
buttonSubmitLabel: {
|
||||||
|
id: 'app.containers.Users.ModalForm.footer.button-success',
|
||||||
|
defaultMessage: 'Create user',
|
||||||
|
},
|
||||||
|
// Component: ModalCreateBody,
|
||||||
|
isDisabled: false,
|
||||||
|
next: 'magic-link',
|
||||||
|
},
|
||||||
|
'magic-link': {
|
||||||
|
buttonSubmitLabel: { id: 'form.button.finish', defaultMessage: 'Finish' },
|
||||||
|
// Component: ModalCreateBody,
|
||||||
|
isDisabled: true,
|
||||||
|
next: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default stepper;
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { Button } from '@buffetjs/core';
|
import { Button } from '@buffetjs/core';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { Modal, ModalFooter, ModalHeader } from '@strapi/helper-plugin';
|
import { Modal, ModalFooter, ModalHeader } from '@strapi/helper-plugin';
|
||||||
import stepper from './stepper';
|
import stepper from './ModalForm/utils/stepper';
|
||||||
|
|
||||||
const ModalForm = ({ isOpen, onClosed, onToggle }) => {
|
const ModalForm = ({ isOpen, onClosed, onToggle }) => {
|
||||||
const [currentStep, setStep] = useState('create');
|
const [currentStep, setStep] = useState('create');
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
CustomContentLayout,
|
CustomContentLayout,
|
||||||
useRBAC,
|
useRBAC,
|
||||||
@ -15,6 +15,7 @@ import get from 'lodash/get';
|
|||||||
import adminPermissions from '../../../permissions';
|
import adminPermissions from '../../../permissions';
|
||||||
import DynamicTable from './DynamicTable';
|
import DynamicTable from './DynamicTable';
|
||||||
import Filters from './Filters';
|
import Filters from './Filters';
|
||||||
|
import ModalForm from './ModalForm';
|
||||||
import Search from './Search';
|
import Search from './Search';
|
||||||
import PaginationFooter from './PaginationFooter';
|
import PaginationFooter from './PaginationFooter';
|
||||||
import { deleteData, fetchData } from './utils/api';
|
import { deleteData, fetchData } from './utils/api';
|
||||||
@ -22,6 +23,7 @@ import displayedFilters from './utils/displayedFilters';
|
|||||||
import tableHeaders from './utils/tableHeaders';
|
import tableHeaders from './utils/tableHeaders';
|
||||||
|
|
||||||
const ListPage = () => {
|
const ListPage = () => {
|
||||||
|
const [isModalOpened, setIsModalOpen] = useState(true);
|
||||||
const {
|
const {
|
||||||
allowedActions: { canCreate, canDelete, canRead, canUpdate },
|
allowedActions: { canCreate, canDelete, canRead, canUpdate },
|
||||||
} = useRBAC(adminPermissions.settings.users);
|
} = useRBAC(adminPermissions.settings.users);
|
||||||
@ -29,6 +31,7 @@ const ListPage = () => {
|
|||||||
const toggleNotification = useNotification();
|
const toggleNotification = useNotification();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
|
useFocusWhenNavigate();
|
||||||
|
|
||||||
const { status, data, isFetching } = useQuery(['users', search], () => fetchData(search), {
|
const { status, data, isFetching } = useQuery(['users', search], () => fetchData(search), {
|
||||||
enabled: canRead,
|
enabled: canRead,
|
||||||
@ -43,7 +46,9 @@ const ListPage = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useFocusWhenNavigate();
|
const handleToggle = () => {
|
||||||
|
setIsModalOpen(prev => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
const total = get(data, 'pagination.total', 0);
|
const total = get(data, 'pagination.total', 0);
|
||||||
|
|
||||||
@ -68,11 +73,7 @@ const ListPage = () => {
|
|||||||
(status !== 'success' && status !== 'error') || (status === 'success' && isFetching);
|
(status !== 'success' && status !== 'error') || (status === 'success' && isFetching);
|
||||||
|
|
||||||
const createAction = canCreate ? (
|
const createAction = canCreate ? (
|
||||||
<Button
|
<Button data-testid="create-user-button" onClick={handleToggle} startIcon={<Mail />}>
|
||||||
data-testid="create-user-button"
|
|
||||||
onClick={() => 'handleToggleModalForCreatingRole'}
|
|
||||||
startIcon={<Mail />}
|
|
||||||
>
|
|
||||||
{formatMessage({
|
{formatMessage({
|
||||||
id: 'Settings.permissions.users.create',
|
id: 'Settings.permissions.users.create',
|
||||||
defaultMessage: 'Create new user',
|
defaultMessage: 'Create new user',
|
||||||
@ -129,6 +130,7 @@ const ListPage = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CustomContentLayout>
|
</CustomContentLayout>
|
||||||
|
{isModalOpened && <ModalForm onToggle={handleToggle} />}
|
||||||
</Main>
|
</Main>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import { ModalCreateBody } from '../../../components/Users';
|
|
||||||
|
|
||||||
const stepper = {
|
|
||||||
create: {
|
|
||||||
buttonSubmitLabel: 'app.containers.Users.ModalForm.footer.button-success',
|
|
||||||
Component: ModalCreateBody,
|
|
||||||
isDisabled: false,
|
|
||||||
next: 'magic-link',
|
|
||||||
},
|
|
||||||
'magic-link': {
|
|
||||||
buttonSubmitLabel: 'form.button.continue',
|
|
||||||
Component: ModalCreateBody,
|
|
||||||
isDisabled: true,
|
|
||||||
next: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default stepper;
|
|
@ -110,7 +110,6 @@
|
|||||||
"Settings.permissions.conditions.when": "When",
|
"Settings.permissions.conditions.when": "When",
|
||||||
"Settings.permissions.menu.link.roles.label": "Roles",
|
"Settings.permissions.menu.link.roles.label": "Roles",
|
||||||
"Settings.permissions.menu.link.users.label": "Users",
|
"Settings.permissions.menu.link.users.label": "Users",
|
||||||
"Settings.permissions.users.add-new": "Add new user",
|
|
||||||
"Settings.permissions.users.create": "Create new user",
|
"Settings.permissions.users.create": "Create new user",
|
||||||
"Settings.permissions.users.form.email": "Email",
|
"Settings.permissions.users.form.email": "Email",
|
||||||
"Settings.permissions.users.form.firstname": "First name",
|
"Settings.permissions.users.form.firstname": "First name",
|
||||||
|
@ -10,7 +10,7 @@ import { ToggleInput } from '@strapi/parts/ToggleInput';
|
|||||||
import { TextInput } from '@strapi/parts/TextInput';
|
import { TextInput } from '@strapi/parts/TextInput';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const Input = ({
|
const GenericInput = ({
|
||||||
description,
|
description,
|
||||||
disabled,
|
disabled,
|
||||||
intlLabel,
|
intlLabel,
|
||||||
@ -85,7 +85,7 @@ const Input = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Input.defaultProps = {
|
GenericInput.defaultProps = {
|
||||||
description: null,
|
description: null,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
error: '',
|
error: '',
|
||||||
@ -93,7 +93,7 @@ Input.defaultProps = {
|
|||||||
value: '',
|
value: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
Input.propTypes = {
|
GenericInput.propTypes = {
|
||||||
description: PropTypes.shape({
|
description: PropTypes.shape({
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
defaultMessage: PropTypes.string.isRequired,
|
defaultMessage: PropTypes.string.isRequired,
|
||||||
@ -118,4 +118,4 @@ Input.propTypes = {
|
|||||||
value: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
value: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Input;
|
export default GenericInput;
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Tests for Input
|
* Tests for GenericInput
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ const makeApp = (name, type, value) => (
|
|||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
describe('<Input />', () => {
|
describe('<GenericInput />', () => {
|
||||||
it('renders and matches the snapshot', () => {
|
it('renders and matches the snapshot', () => {
|
||||||
const {
|
const {
|
||||||
container: { firstChild },
|
container: { firstChild },
|
@ -175,6 +175,7 @@ export { default as CheckPermissions } from './components/CheckPermissions';
|
|||||||
export { default as CustomContentLayout } from './components/CustomContentLayout';
|
export { default as CustomContentLayout } from './components/CustomContentLayout';
|
||||||
export { default as EmptyStateLayout } from './components/EmptyStateLayout';
|
export { default as EmptyStateLayout } from './components/EmptyStateLayout';
|
||||||
export { default as EmptyBodyTable } from './components/EmptyBodyTable';
|
export { default as EmptyBodyTable } from './components/EmptyBodyTable';
|
||||||
|
export { default as GenericInput } from './components/GenericInput';
|
||||||
export * from './components/InjectionZone';
|
export * from './components/InjectionZone';
|
||||||
export { default as LoadingIndicatorPage } from './components/LoadingIndicatorPage';
|
export { default as LoadingIndicatorPage } from './components/LoadingIndicatorPage';
|
||||||
export { default as SettingsPageTitle } from './components/SettingsPageTitle';
|
export { default as SettingsPageTitle } from './components/SettingsPageTitle';
|
||||||
|
@ -20,8 +20,7 @@ import {
|
|||||||
} from '@strapi/parts';
|
} from '@strapi/parts';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import { Form } from '@strapi/helper-plugin';
|
import { Form, GenericInput } from '@strapi/helper-plugin';
|
||||||
import Input from './Input';
|
|
||||||
|
|
||||||
const FormModal = ({
|
const FormModal = ({
|
||||||
headerBreadcrumbs,
|
headerBreadcrumbs,
|
||||||
@ -64,7 +63,7 @@ const FormModal = ({
|
|||||||
return row.map(input => {
|
return row.map(input => {
|
||||||
return (
|
return (
|
||||||
<GridItem key={input.name} col={input.size} xs={12}>
|
<GridItem key={input.name} col={input.size} xs={12}>
|
||||||
<Input
|
<GenericInput
|
||||||
{...input}
|
{...input}
|
||||||
error={errors[input.name]}
|
error={errors[input.name]}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user