mirror of
https://github.com/strapi/strapi.git
synced 2025-07-24 09:25:25 +00:00
Fix a11y issues
This commit is contained in:
parent
9a042610ea
commit
3c9e92a2c4
@ -18,7 +18,7 @@ const Wrapper = styled.div`
|
||||
left: -10px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 20px;
|
||||
border-radius: ${20 / 16}rem;;
|
||||
background: ${disabled ? theme.colors.neutral100 : theme.colors.primary600};
|
||||
}
|
||||
`}
|
||||
|
@ -7,7 +7,7 @@ import styled from 'styled-components';
|
||||
import ConditionsSelect from '../ConditionsSelect';
|
||||
|
||||
const RowWrapper = styled(Row)`
|
||||
height: 52px;
|
||||
height: ${52 / 16}rem;
|
||||
`;
|
||||
|
||||
const ActionRow = ({
|
||||
@ -23,9 +23,9 @@ const ActionRow = ({
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<RowWrapper background={isGrey ? 'neutral100' : 'neutral0'}>
|
||||
<RowWrapper as="li" background={isGrey ? 'neutral100' : 'neutral0'}>
|
||||
<Row paddingLeft={6} style={{ width: 180 }}>
|
||||
<TableLabel textColor="neutral500">
|
||||
<TableLabel textColor="neutral600">
|
||||
{formatMessage({
|
||||
id: 'Settings.permissions.conditions.can',
|
||||
defaultMessage: 'Can',
|
||||
@ -47,7 +47,7 @@ const ActionRow = ({
|
||||
defaultMessage: label,
|
||||
})}
|
||||
</TableLabel>
|
||||
<TableLabel textColor="neutral500">
|
||||
<TableLabel textColor="neutral600">
|
||||
|
||||
{formatMessage({
|
||||
id: 'Settings.permissions.conditions.when',
|
||||
|
@ -1,39 +1,25 @@
|
||||
import { After } from '@strapi/icons';
|
||||
import {
|
||||
Box,
|
||||
Breadcrumbs,
|
||||
Button,
|
||||
Crumb,
|
||||
H2,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalLayout,
|
||||
Stack,
|
||||
Text,
|
||||
TextButton,
|
||||
Divider,
|
||||
} from '@strapi/parts';
|
||||
import { cloneDeep, get, groupBy, set, upperFirst } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
import styled from 'styled-components';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { usePermissionsDataManager } from '../../../hooks';
|
||||
import updateValues from '../Permissions/utils/updateValues';
|
||||
import ActionRow from './ActionRow';
|
||||
import createDefaultConditionsForm from './utils/createDefaultConditionsForm';
|
||||
|
||||
// ! Something needs to be done in the DS parts to avoid doing this
|
||||
const Icon = styled(Box)`
|
||||
svg {
|
||||
width: 6px;
|
||||
}
|
||||
* {
|
||||
fill: ${({ theme }) => theme.colors.neutral300};
|
||||
}
|
||||
`;
|
||||
|
||||
const Separator = styled.div`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.main.colors.brightGrey};
|
||||
`;
|
||||
|
||||
const ConditionsModal = ({
|
||||
actions,
|
||||
headerBreadCrumbs,
|
||||
@ -45,11 +31,6 @@ const ConditionsModal = ({
|
||||
const { formatMessage } = useIntl();
|
||||
const { availableConditions, modifiedData, onChangeConditions } = usePermissionsDataManager();
|
||||
|
||||
const translatedHeaders = headerBreadCrumbs.map(headerTrad => ({
|
||||
key: headerTrad,
|
||||
element: <FormattedMessage id={headerTrad} defaultMessage={upperFirst(headerTrad)} />,
|
||||
}));
|
||||
|
||||
const arrayOfOptionsGroupedByCategory = useMemo(() => {
|
||||
return Object.entries(groupBy(availableConditions, 'category'));
|
||||
}, [availableConditions]);
|
||||
@ -113,22 +94,18 @@ const ConditionsModal = ({
|
||||
return (
|
||||
<ModalLayout onClose={onClosed}>
|
||||
<ModalHeader>
|
||||
<Stack horizontal size={3}>
|
||||
{translatedHeaders.map(({ key, element }, index) => {
|
||||
const shouldDisplayChevron = index < translatedHeaders.length - 1;
|
||||
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
<TextButton textColor="neutral800">{element}</TextButton>
|
||||
{shouldDisplayChevron && (
|
||||
<Icon>
|
||||
<After />
|
||||
</Icon>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
<Breadcrumbs label={headerBreadCrumbs.join(', ')}>
|
||||
{headerBreadCrumbs.map(label => (
|
||||
<Crumb key={label}>
|
||||
{upperFirst(
|
||||
formatMessage({
|
||||
id: label,
|
||||
defaultMessage: label,
|
||||
})
|
||||
)}
|
||||
</Crumb>
|
||||
))}
|
||||
</Breadcrumbs>
|
||||
</ModalHeader>
|
||||
<Box padding={8}>
|
||||
<Stack size={6}>
|
||||
@ -138,7 +115,8 @@ const ConditionsModal = ({
|
||||
defaultMessage: 'Define conditions',
|
||||
})}
|
||||
</H2>
|
||||
<Separator />
|
||||
{/* ! Need to force margin here - Remove this when Divider is updated in parts */}
|
||||
<Divider style={{ marginTop: `${24 / 16}rem` }} />
|
||||
<Box>
|
||||
{actionsToDisplay.length === 0 && (
|
||||
<Text>
|
||||
@ -149,23 +127,25 @@ const ConditionsModal = ({
|
||||
})}
|
||||
</Text>
|
||||
)}
|
||||
{actionsToDisplay.map(({ actionId, label, pathToConditionsObject }, index) => {
|
||||
const name = pathToConditionsObject.join('..');
|
||||
<ul>
|
||||
{actionsToDisplay.map(({ actionId, label, pathToConditionsObject }, index) => {
|
||||
const name = pathToConditionsObject.join('..');
|
||||
|
||||
return (
|
||||
<ActionRow
|
||||
key={actionId}
|
||||
arrayOfOptionsGroupedByCategory={arrayOfOptionsGroupedByCategory}
|
||||
label={label}
|
||||
isFormDisabled={isFormDisabled}
|
||||
isGrey={index % 2 === 0}
|
||||
name={name}
|
||||
onCategoryChange={handleCategoryChange}
|
||||
onChange={handleChange}
|
||||
value={get(state, name, {})}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<ActionRow
|
||||
key={actionId}
|
||||
arrayOfOptionsGroupedByCategory={arrayOfOptionsGroupedByCategory}
|
||||
label={label}
|
||||
isFormDisabled={isFormDisabled}
|
||||
isGrey={index % 2 === 0}
|
||||
name={name}
|
||||
onCategoryChange={handleCategoryChange}
|
||||
onChange={handleChange}
|
||||
value={get(state, name, {})}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
@ -34,7 +34,7 @@ const activeRowStyle = (theme, isActive, isClicked) => `
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 52px;
|
||||
height: ${52 / 16}rem;
|
||||
background-color: ${({ isGrey, theme }) =>
|
||||
isGrey ? theme.colors.neutral100 : theme.colors.neutral0};
|
||||
border: 1px solid transparent;
|
||||
@ -45,6 +45,10 @@ const Wrapper = styled.div`
|
||||
&:hover {
|
||||
${({ theme, isActive }) => activeRowStyle(theme, isActive)}
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
${({ theme, isActive }) => activeRowStyle(theme, isActive)}
|
||||
}
|
||||
`;
|
||||
|
||||
const Cell = styled(Row)`
|
||||
@ -81,7 +85,7 @@ const Collapse = ({
|
||||
onClickToggle,
|
||||
pathToData,
|
||||
}) => {
|
||||
const [modalState, setModalState] = useState({ isOpen: false, isMounted: false });
|
||||
const [isModalOpen, setModalOpen] = useState(false);
|
||||
const {
|
||||
modifiedData,
|
||||
onChangeParentCheckbox,
|
||||
@ -89,11 +93,11 @@ const Collapse = ({
|
||||
} = usePermissionsDataManager();
|
||||
|
||||
const handleToggleModalIsOpen = () => {
|
||||
setModalState(prevState => ({ isMounted: true, isOpen: !prevState.isOpen }));
|
||||
setModalOpen(s => !s);
|
||||
};
|
||||
|
||||
const handleModalClose = () => {
|
||||
setModalState(prevState => ({ ...prevState, isMounted: false }));
|
||||
setModalOpen(false);
|
||||
};
|
||||
|
||||
// This corresponds to the data related to the CT left checkbox
|
||||
@ -133,6 +137,7 @@ const Collapse = ({
|
||||
onClick={onClickToggle}
|
||||
someChecked={hasSomeActionsSelected}
|
||||
value={hasAllActionsSelected}
|
||||
isActive={isActive}
|
||||
>
|
||||
<Chevron paddingLeft={2}>{isActive ? <Up /> : <Down />}</Chevron>
|
||||
</RowLabelWithCheckbox>
|
||||
@ -159,6 +164,7 @@ const Collapse = ({
|
||||
<Checkbox
|
||||
disabled={isFormDisabled || IS_DISABLED}
|
||||
name={checkboxName}
|
||||
aria-label={checkboxName}
|
||||
// Keep same signature as packages/core/admin/admin/src/components/Roles/Permissions/index.js l.91
|
||||
onValueChange={value =>
|
||||
onChangeParentCheckbox({
|
||||
@ -202,16 +208,14 @@ const Collapse = ({
|
||||
hasConditions={doesConditionButtonHasConditions}
|
||||
/>
|
||||
</Box>
|
||||
{modalState.isMounted && (
|
||||
<ConditionsModal
|
||||
headerBreadCrumbs={[label, 'app.components.LeftMenuLinkContainer.settings']}
|
||||
actions={checkboxesActions}
|
||||
isOpen={modalState.isOpen}
|
||||
isFormDisabled={isFormDisabled}
|
||||
onClosed={handleModalClose}
|
||||
onToggle={handleToggleModalIsOpen}
|
||||
/>
|
||||
)}
|
||||
<ConditionsModal
|
||||
headerBreadCrumbs={[label, 'app.components.LeftMenuLinkContainer.settings']}
|
||||
actions={checkboxesActions}
|
||||
isOpen={isModalOpen}
|
||||
isFormDisabled={isFormDisabled}
|
||||
onClosed={handleModalClose}
|
||||
onToggle={handleToggleModalIsOpen}
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ const Cell = styled(Box)`
|
||||
const Chevron = styled(Box)`
|
||||
display: none;
|
||||
svg {
|
||||
width: 11px;
|
||||
width: ${11 / 16}rem;
|
||||
}
|
||||
* {
|
||||
fill: ${({ theme }) => theme.colors.primary600};
|
||||
@ -39,7 +39,7 @@ const Wrapper = styled(Row)`
|
||||
flex: 1;
|
||||
background: ${({ theme, isOdd }) => theme.colors[isOdd ? 'neutral100' : 'neutral0']};
|
||||
${Chevron} {
|
||||
width: 13px;
|
||||
width: ${13 / 16}rem;
|
||||
}
|
||||
${({ isCollapsable, theme }) =>
|
||||
isCollapsable &&
|
||||
@ -118,6 +118,7 @@ const ActionRow = ({
|
||||
label={label}
|
||||
someChecked={hasSomeActionsSelected}
|
||||
value={hasAllActionsSelected}
|
||||
isActive={isActive}
|
||||
>
|
||||
{required && <RequiredSign />}
|
||||
<Chevron paddingLeft={2}>{isActive ? <Up /> : <Down />}</Chevron>
|
||||
@ -144,6 +145,7 @@ const ActionRow = ({
|
||||
<Checkbox
|
||||
disabled={isFormDisabled || IS_DISABLED}
|
||||
name={checkboxName.join('..')}
|
||||
aria-label={checkboxName.join('..')}
|
||||
// Keep same signature as packages/core/admin/admin/src/components/Roles/Permissions/index.js l.91
|
||||
onValueChange={value =>
|
||||
onChangeSimpleCheckbox({
|
||||
|
@ -1,29 +1,16 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Row, Box } from '@strapi/parts';
|
||||
import { Row, TableLabel } from '@strapi/parts';
|
||||
import styled from 'styled-components';
|
||||
import { cellWidth, firstRowWidth } from '../../../Permissions/utils/constants';
|
||||
// Those styles are very specific.
|
||||
// so it is not a big problem to use custom paddings and widths.
|
||||
const HeaderLabel = styled.div`
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
|
||||
const HeaderLabel = styled(Row)`
|
||||
width: ${cellWidth};
|
||||
`;
|
||||
const PropertyLabelWrapper = styled.div`
|
||||
const PropertyLabelWrapper = styled(Row)`
|
||||
width: ${firstRowWidth};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: ${({ theme }) => theme.spaces[6]};
|
||||
height: 52px;
|
||||
`;
|
||||
|
||||
const Label = styled(Box)`
|
||||
font-size: ${11 / 16}rem;
|
||||
text-transform: uppercase;
|
||||
color: ${({ theme }) => theme.colors.neutral500};
|
||||
font-weight: bold;
|
||||
height: ${52 / 16}rem;
|
||||
`;
|
||||
|
||||
const Header = ({ headers, label }) => {
|
||||
@ -38,8 +25,8 @@ const Header = ({ headers, label }) => {
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<PropertyLabelWrapper>
|
||||
<Label>{translatedLabel}</Label>
|
||||
<PropertyLabelWrapper alignItems="center" paddingLeft={6}>
|
||||
<TableLabel textColor="neutral500">{translatedLabel}</TableLabel>
|
||||
</PropertyLabelWrapper>
|
||||
{headers.map(header => {
|
||||
if (!header.isActionRelatedToCurrentProperty) {
|
||||
@ -47,13 +34,13 @@ const Header = ({ headers, label }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<HeaderLabel key={header.label}>
|
||||
<Label>
|
||||
<HeaderLabel justifyContent="center" key={header.label}>
|
||||
<TableLabel textColor="neutral500">
|
||||
{formatMessage({
|
||||
id: `Settings.roles.form.permissions.${header.label.toLowerCase()}`,
|
||||
defaultMessage: header.label,
|
||||
})}
|
||||
</Label>
|
||||
</TableLabel>
|
||||
</HeaderLabel>
|
||||
);
|
||||
})}
|
||||
|
@ -16,7 +16,6 @@ const Wrapper = styled.div`
|
||||
|
||||
return `none`;
|
||||
}};
|
||||
border-radius: 0px 0px 2px 2px;
|
||||
`;
|
||||
|
||||
Wrapper.defaultProps = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Checkbox, Stack, TableLabel } from '@strapi/parts';
|
||||
import { Checkbox, Stack, TableLabel, Box } from '@strapi/parts';
|
||||
import IS_DISABLED from 'ee_else_ce/components/Roles/GlobalActions/utils/constants';
|
||||
import { get } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -15,21 +15,6 @@ const CenteredStack = styled(Stack)`
|
||||
width: ${cellWidth};
|
||||
`;
|
||||
|
||||
const Wrapper = styled.div`
|
||||
padding-left: ${firstRowWidth};
|
||||
padding-bottom: ${({ theme }) => theme.spaces[4]};
|
||||
padding-top: ${({ theme }) => theme.spaces[6]};
|
||||
${({ disabled, theme }) =>
|
||||
`
|
||||
input[type='checkbox'] {
|
||||
&:after {
|
||||
color: ${!disabled ? theme.main.colors.mediumBlue : theme.main.colors.grey};
|
||||
}
|
||||
}
|
||||
cursor: initial;
|
||||
`}
|
||||
`;
|
||||
|
||||
const GlobalActions = ({ actions, isFormDisabled, kind }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { modifiedData, onChangeCollectionTypeGlobalActionCheckbox } = usePermissionsDataManager();
|
||||
@ -43,7 +28,7 @@ const GlobalActions = ({ actions, isFormDisabled, kind }) => {
|
||||
}, [modifiedData, displayedActions, kind]);
|
||||
|
||||
return (
|
||||
<Wrapper disabled={isFormDisabled}>
|
||||
<Box paddingBottom={4} paddingTop={6} style={{ paddingLeft: firstRowWidth }}>
|
||||
<Stack horizontal>
|
||||
{displayedActions.map(({ label, actionId }) => {
|
||||
return (
|
||||
@ -60,6 +45,7 @@ const GlobalActions = ({ actions, isFormDisabled, kind }) => {
|
||||
onChangeCollectionTypeGlobalActionCheckbox(kind, actionId, value);
|
||||
}}
|
||||
name={actionId}
|
||||
aria-label={actionId}
|
||||
value={get(checkboxesState, [actionId, 'hasAllActionsSelected'], false)}
|
||||
indeterminate={get(checkboxesState, [actionId, 'hasSomeActionsSelected'], false)}
|
||||
/>
|
||||
@ -67,7 +53,7 @@ const GlobalActions = ({ actions, isFormDisabled, kind }) => {
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
</Wrapper>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
export const cellWidth = '120px';
|
||||
export const firstRowWidth = '200px';
|
||||
export const cellWidth = `${120 / 16}rem`;
|
||||
export const firstRowWidth = `${200 / 16}rem`;
|
||||
|
@ -26,18 +26,18 @@ const CheckboxWrapper = styled.div`
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: -8px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 20px;
|
||||
top: ${-4 / 16}rem;
|
||||
left: ${-8 / 16}rem;
|
||||
width: ${6 / 16}rem;
|
||||
height: ${6 / 16}rem;
|
||||
border-radius: ${20 / 16}rem;
|
||||
background: ${disabled ? theme.colors.neutral100 : theme.colors.primary600};
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const SubCategory = ({ categoryName, isFormDisabled, subCategoryName, actions, pathToData }) => {
|
||||
const [modalState, setModalState] = useState({ isOpen: false, isMounted: false });
|
||||
const [isModalOpen, setModalOpen] = useState(false);
|
||||
const {
|
||||
modifiedData,
|
||||
onChangeParentCheckbox,
|
||||
@ -57,13 +57,12 @@ const SubCategory = ({ categoryName, isFormDisabled, subCategoryName, actions, p
|
||||
const { hasAllActionsSelected, hasSomeActionsSelected } = getCheckboxState(dataWithoutCondition);
|
||||
|
||||
const handleToggleModalIsOpen = () => {
|
||||
setModalState(prevState => ({ isMounted: true, isOpen: !prevState.isOpen }));
|
||||
setModalOpen(s => !s);
|
||||
};
|
||||
|
||||
const handleModalClose = () => {
|
||||
setModalState(prevState => ({ ...prevState, isMounted: false }));
|
||||
setModalOpen(false);
|
||||
};
|
||||
|
||||
// We need to format the actions so it matches the shape of the ConditionsModal actions props
|
||||
const formattedActions = formatActions(actions, modifiedData, pathToData);
|
||||
const doesButtonHasCondition = getConditionsButtonState(get(modifiedData, [...pathToData], {}));
|
||||
@ -79,6 +78,7 @@ const SubCategory = ({ categoryName, isFormDisabled, subCategoryName, actions, p
|
||||
<Box paddingLeft={4}>
|
||||
<Checkbox
|
||||
name={pathToData.join('..')}
|
||||
aria-label={pathToData.join('..')}
|
||||
disabled={isFormDisabled || IS_DISABLED}
|
||||
// Keep same signature as packages/core/admin/admin/src/components/Roles/Permissions/index.js l.91
|
||||
onValueChange={value =>
|
||||
@ -131,16 +131,14 @@ const SubCategory = ({ categoryName, isFormDisabled, subCategoryName, actions, p
|
||||
/>
|
||||
</Row>
|
||||
</Box>
|
||||
{modalState.isMounted && (
|
||||
<ConditionsModal
|
||||
headerBreadCrumbs={[categoryName, subCategoryName]}
|
||||
actions={formattedActions}
|
||||
isOpen={modalState.isOpen}
|
||||
isFormDisabled={isFormDisabled}
|
||||
onClosed={handleModalClose}
|
||||
onToggle={handleToggleModalIsOpen}
|
||||
/>
|
||||
)}
|
||||
<ConditionsModal
|
||||
headerBreadCrumbs={[categoryName, subCategoryName]}
|
||||
actions={formattedActions}
|
||||
isOpen={isModalOpen}
|
||||
isFormDisabled={isFormDisabled}
|
||||
onClosed={handleModalClose}
|
||||
onToggle={handleToggleModalIsOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, Checkbox, Text } from '@strapi/parts';
|
||||
import { Row, Checkbox, Text } from '@strapi/parts';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { memo } from 'react';
|
||||
@ -6,24 +6,6 @@ import styled from 'styled-components';
|
||||
import CollapseLabel from '../CollapseLabel';
|
||||
import { firstRowWidth } from '../Permissions/utils/constants';
|
||||
|
||||
const Wrapper = styled(Box)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: ${firstRowWidth};
|
||||
padding-left: ${({ theme }) => theme.spaces[6]};
|
||||
|
||||
${({ disabled, theme }) =>
|
||||
disabled &&
|
||||
`
|
||||
input[type='checkbox'] {
|
||||
cursor: not-allowed;
|
||||
&:after {
|
||||
color: ${theme.main.colors.grey};
|
||||
}
|
||||
}
|
||||
`};
|
||||
`;
|
||||
|
||||
// ! REMOVE THIS WHEN DS IS UPDATED WITH ELLIPSIS PROP
|
||||
const StyledText = styled(Text)`
|
||||
white-space: nowrap;
|
||||
@ -34,6 +16,7 @@ const StyledText = styled(Text)`
|
||||
const RowLabelWithCheckbox = ({
|
||||
children,
|
||||
isCollapsable,
|
||||
isActive,
|
||||
isFormDisabled,
|
||||
label,
|
||||
onChange,
|
||||
@ -43,9 +26,10 @@ const RowLabelWithCheckbox = ({
|
||||
value,
|
||||
}) => {
|
||||
return (
|
||||
<Wrapper disabled={isFormDisabled}>
|
||||
<Row alignItems="center" paddingLeft={6} style={{ width: firstRowWidth }}>
|
||||
<Checkbox
|
||||
name={checkboxName}
|
||||
aria-label={checkboxName}
|
||||
disabled={isFormDisabled}
|
||||
// Keep same signature as packages/core/admin/admin/src/components/Roles/Permissions/index.js l.91
|
||||
onValueChange={value =>
|
||||
@ -64,6 +48,7 @@ const RowLabelWithCheckbox = ({
|
||||
isCollapsable={isCollapsable}
|
||||
{...(isCollapsable && {
|
||||
onClick,
|
||||
'aria-expanded': isActive,
|
||||
onKeyDown: ({ key }) => (key === 'Enter' || key === ' ') && onClick(),
|
||||
tabIndex: 0,
|
||||
role: 'button',
|
||||
@ -72,7 +57,7 @@ const RowLabelWithCheckbox = ({
|
||||
<StyledText>{upperFirst(label)}</StyledText>
|
||||
{children}
|
||||
</CollapseLabel>
|
||||
</Wrapper>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
@ -95,6 +80,7 @@ RowLabelWithCheckbox.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
someChecked: PropTypes.bool,
|
||||
value: PropTypes.bool,
|
||||
isActive: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default memo(RowLabelWithCheckbox);
|
||||
|
@ -132,6 +132,7 @@ const Login = ({ onSubmit, schema, children }) => {
|
||||
handleChange({ target: { value: checked, name: 'rememberMe' } });
|
||||
}}
|
||||
value={values.rememberMe}
|
||||
aria-label="rememberMe"
|
||||
name="rememberMe"
|
||||
>
|
||||
{formatMessage({
|
||||
|
@ -280,6 +280,7 @@ const Register = ({ fieldsToDisable, noSignin, onSubmit, schema }) => {
|
||||
}}
|
||||
value={values.news}
|
||||
name="news"
|
||||
aria-label="news"
|
||||
>
|
||||
{formatMessage(
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
useNotification,
|
||||
useOverlayBlocker,
|
||||
useTracking,
|
||||
Form,
|
||||
} from '@strapi/helper-plugin';
|
||||
import {
|
||||
Box,
|
||||
@ -124,8 +125,8 @@ const CreatePage = () => {
|
||||
validationSchema={schema}
|
||||
validateOnChange={false}
|
||||
>
|
||||
{({ handleSubmit, values, errors, handleReset, handleChange, handleBlur }) => (
|
||||
<form onSubmit={handleSubmit}>
|
||||
{({ handleSubmit, values, errors, handleReset, handleChange }) => (
|
||||
<Form noValidate>
|
||||
<>
|
||||
<HeaderLayout
|
||||
id="title"
|
||||
@ -162,87 +163,86 @@ const CreatePage = () => {
|
||||
as="h1"
|
||||
/>
|
||||
<ContentLayout>
|
||||
<Box background="neutral0" padding={6} shadow="filterShadow" hasRadius>
|
||||
<Stack size={4}>
|
||||
<Row justifyContent="space-between">
|
||||
<Box>
|
||||
<Stack size={6}>
|
||||
<Box background="neutral0" padding={6} shadow="filterShadow" hasRadius>
|
||||
<Stack size={4}>
|
||||
<Row justifyContent="space-between">
|
||||
<Box>
|
||||
<Text highlighted>
|
||||
{formatMessage({
|
||||
id: 'Settings.roles.form.title',
|
||||
defaultMessage: 'Details',
|
||||
})}
|
||||
</Text>
|
||||
<Box>
|
||||
<Text highlighted>
|
||||
{formatMessage({
|
||||
id: 'Settings.roles.form.title',
|
||||
defaultMessage: 'Details',
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text textColor="neutral600" small>
|
||||
{formatMessage({
|
||||
id: 'Settings.roles.form.description',
|
||||
defaultMessage: 'Name and description of the role',
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text textColor="neutral500" small>
|
||||
{formatMessage({
|
||||
id: 'Settings.roles.form.description',
|
||||
defaultMessage: 'Name and description of the role',
|
||||
<UsersRoleNumber>
|
||||
{formatMessage(
|
||||
{
|
||||
id: 'Settings.roles.form.button.users-with-role',
|
||||
defaultMessage:
|
||||
'{number, plural, =0 {# users} one {# user} other {# users}} with this role',
|
||||
},
|
||||
{ number: 0 }
|
||||
)}
|
||||
</UsersRoleNumber>
|
||||
</Row>
|
||||
<Grid gap={4}>
|
||||
<GridItem col={6}>
|
||||
<TextInput
|
||||
name="name"
|
||||
error={errors.name && formatMessage({ id: errors.name })}
|
||||
label={formatMessage({
|
||||
id: 'Settings.roles.form.input.name',
|
||||
defaultMessage: 'Name',
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<UsersRoleNumber>
|
||||
{formatMessage(
|
||||
{
|
||||
id: 'Settings.roles.form.button.users-with-role',
|
||||
defaultMessage:
|
||||
'{number, plural, =0 {# users} one {# user} other {# users}} with this role',
|
||||
},
|
||||
{ number: 0 }
|
||||
)}
|
||||
</UsersRoleNumber>
|
||||
</Row>
|
||||
<Grid gap={4}>
|
||||
<GridItem col={6}>
|
||||
<TextInput
|
||||
name="name"
|
||||
error={errors.name && formatMessage({ id: errors.name })}
|
||||
label={formatMessage({
|
||||
id: 'Settings.roles.form.input.name',
|
||||
defaultMessage: 'Name',
|
||||
})}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.name}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem col={6}>
|
||||
<Textarea
|
||||
label={formatMessage({
|
||||
id: 'Settings.roles.form.input.description',
|
||||
defaultMessage: 'Description',
|
||||
})}
|
||||
name="description"
|
||||
error={errors.name && formatMessage({ id: errors.name })}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
>
|
||||
{values.description}
|
||||
</Textarea>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Box>
|
||||
{!isLayoutLoading && !isRoleLoading ? (
|
||||
<Box paddingTop={6} paddingBottom={6}>
|
||||
<Permissions
|
||||
isFormDisabled={false}
|
||||
ref={permissionsRef}
|
||||
permissions={rolePermissions}
|
||||
layout={permissionsLayout}
|
||||
/>
|
||||
onChange={handleChange}
|
||||
value={values.name}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem col={6}>
|
||||
<Textarea
|
||||
label={formatMessage({
|
||||
id: 'Settings.roles.form.input.description',
|
||||
defaultMessage: 'Description',
|
||||
})}
|
||||
name="description"
|
||||
error={errors.name && formatMessage({ id: errors.name })}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{values.description}
|
||||
</Textarea>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Box>
|
||||
) : (
|
||||
// ! TODO : Switch to the DS component when done
|
||||
<Row alignItems="center" justifyContent="center" padding={11}>
|
||||
<Loader />
|
||||
</Row>
|
||||
)}
|
||||
{!isLayoutLoading && !isRoleLoading ? (
|
||||
<Box shadow="filterShadow" hasRadius>
|
||||
<Permissions
|
||||
isFormDisabled={false}
|
||||
ref={permissionsRef}
|
||||
permissions={rolePermissions}
|
||||
layout={permissionsLayout}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<Row alignItems="center" justifyContent="center" padding={11}>
|
||||
<Loader />
|
||||
</Row>
|
||||
)}
|
||||
</Stack>
|
||||
</ContentLayout>
|
||||
</>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</Main>
|
||||
|
Loading…
x
Reference in New Issue
Block a user