Disable conditions in EE

Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
soupette 2021-11-02 15:29:49 +01:00
parent c08dadaa50
commit c3147e90c2
17 changed files with 10 additions and 575 deletions

View File

@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import IS_DISABLED from 'ee_else_ce/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/constants';
import { Box } from '@strapi/design-system/Box';
import { Flex } from '@strapi/design-system/Flex';
import { TableLabel } from '@strapi/design-system/Text';
@ -95,7 +96,7 @@ const ActionRow = ({
onChange={handleChange}
value={values}
options={options}
disabled={isFormDisabled}
disabled={isFormDisabled || IS_DISABLED}
/>
</Box>
</FlexWrapper>

View File

@ -1,15 +0,0 @@
import React from 'react';
import { Remove } from '@buffetjs/icons';
import { components } from 'react-select';
const ClearIndicator = props => {
const Component = components.ClearIndicator;
return (
<Component {...props}>
<Remove width="11px" height="11px" fill="#9EA7B8" />
</Component>
);
};
export default ClearIndicator;

View File

@ -1,39 +0,0 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Flex } from '@buffetjs/core';
import styled from 'styled-components';
import PropTypes from 'prop-types';
const Wrapper = styled(Flex)`
height: 100%;
width: 32px;
background: #fafafb;
> svg {
align-self: center;
font-size: 11px;
color: #b3b5b9;
}
`;
const DropdownIndicator = ({ selectProps: { menuIsOpen } }) => {
const icon = menuIsOpen ? 'caret-up' : 'caret-down';
return (
<Wrapper>
<FontAwesomeIcon icon={icon} />
</Wrapper>
);
};
DropdownIndicator.propTypes = {
selectProps: PropTypes.shape({
menuIsOpen: PropTypes.bool.isRequired,
}).isRequired,
};
Wrapper.defaultProps = {
flexDirection: 'column',
justifyContent: 'center',
};
export default DropdownIndicator;

View File

@ -1,3 +0,0 @@
const IndicatorSeparator = () => null;
export default IndicatorSeparator;

View File

@ -1,48 +0,0 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Collapse } from 'reactstrap';
const ToggleUl = styled(Collapse)`
font-size: 13px;
padding: 12px 15px 0 15px;
list-style: none;
background-color: #fff;
> li {
padding-top: 5px;
label {
cursor: pointer;
}
.check-wrapper {
z-index: 9;
> input {
z-index: 1;
}
}
}
> li:not(:last-child) {
padding-bottom: 12px;
}
`;
const SubUl = ({ children, isOpen }) => {
return (
<ToggleUl tag="ul" isOpen={isOpen}>
{children}
</ToggleUl>
);
};
SubUl.defaultProps = {
children: null,
isOpen: false,
};
SubUl.propTypes = {
children: PropTypes.node,
isOpen: PropTypes.bool,
};
export default SubUl;

View File

@ -1,80 +0,0 @@
/* eslint-disable indent */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import styled from 'styled-components';
const Ul = styled.ul`
max-height: 150px;
font-size: 13px;
padding: 0 15px;
margin-bottom: 0px;
list-style: none;
background-color: #fff;
> li {
label {
flex-shrink: 1;
width: fit-content !important;
cursor: pointer;
margin-bottom: 0px;
}
.check-wrapper {
z-index: 9;
> input {
z-index: 1;
}
}
.chevron {
margin: auto;
font-size: 11px;
color: #919bae;
}
}
.li-multi-menu {
margin-bottom: -3px;
}
.li {
line-height: 27px;
position: relative;
> p {
margin: 0;
}
&:hover {
> p::after {
content: attr(datadescr);
position: absolute;
left: 0;
color: ${({ theme }) => theme.main.colors.mediumBlue};
font-weight: 700;
z-index: 100;
}
&::after {
content: '';
position: absolute;
z-index: 1;
top: 0;
left: -30px;
right: -30px;
bottom: 0;
background-color: ${({ theme }) => theme.main.colors.lightBlue};
}
}
}
${({ disabled, theme }) =>
disabled &&
`
label {
cursor: not-allowed !important;
}
input[type='checkbox'] {
cursor: not-allowed;
&:after {
cursor: not-allowed;
color: ${theme.main.colors.grey};
}
}
`}
`;
export default Ul;

View File

@ -1,6 +0,0 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import upperFirst from 'lodash/upperFirst';
const UpperFirst = ({ content }) => upperFirst(content);
export default UpperFirst;

View File

@ -1,140 +0,0 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import React, { useState, useMemo } from 'react';
import PropTypes from 'prop-types';
import { components } from 'react-select';
import { get } from 'lodash';
import { Checkbox, Flex } from '@buffetjs/core';
import { Label } from '@buffetjs/styles';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import IS_DISABLED from 'ee_else_ce/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ConditionsSelect/MenuList/utils/constants';
import { getCheckboxState } from '../../../utils';
import createCollapsesObject from './utils/createCollapsesObject';
import SubUl from './SubUl';
import Ul from './Ul';
import UpperFirst from './UpperFirst';
/* eslint-disable jsx-a11y/no-static-element-interactions */
const MenuList = ({ selectProps, ...rest }) => {
const Component = components.MenuList;
const { arrayOfOptionsGroupedByCategory } = selectProps;
const initCollapses = useMemo(() => createCollapsesObject(arrayOfOptionsGroupedByCategory), [
arrayOfOptionsGroupedByCategory,
]);
const [collapses, setCollapses] = useState(initCollapses);
const toggleCollapse = collapseName => {
setCollapses(prevState => ({ ...prevState, [collapseName]: !collapses[collapseName] }));
};
return (
<Component {...rest}>
<Ul disabled={IS_DISABLED}>
{arrayOfOptionsGroupedByCategory.map((category, index) => {
const [categoryName, conditions] = category;
const checkboxName = `${selectProps.name}..${categoryName}`;
const {
hasAllActionsSelected: hasAllConditionsSelected,
hasSomeActionsSelected: hasSomeConditionsSelected,
} = getCheckboxState(selectProps.value);
return (
<li key={categoryName}>
<div>
<Flex justifyContent="space-between">
<Label
htmlFor="overrideReactSelectBehavior"
onClick={() => {
if (!IS_DISABLED) {
selectProps.onCategoryChange({
keys: [selectProps.name, categoryName],
value: !hasAllConditionsSelected,
});
}
}}
>
<Flex>
<Checkbox
disabled={IS_DISABLED}
id="checkCategory"
name={checkboxName}
onChange={() => {}}
someChecked={hasSomeConditionsSelected}
value={hasAllConditionsSelected}
/>
<UpperFirst content={categoryName} />
</Flex>
</Label>
<div
style={{ flex: 1, textAlign: 'end', cursor: 'pointer' }}
onClick={() => toggleCollapse(categoryName)}
>
<FontAwesomeIcon
style={{
margin: 'auto',
fontSize: '11px',
color: '#919bae',
}}
icon={collapses[categoryName] ? 'chevron-up' : 'chevron-down'}
/>
</div>
</Flex>
</div>
<SubUl tag="ul" isOpen={collapses[categoryName]}>
{conditions.map(condition => {
const checkboxValue = get(selectProps.value, [categoryName, condition.id], false);
return (
<li key={condition.id}>
<Flex>
<Label
htmlFor={condition.id}
message={condition.displayName}
onClick={() => {
if (!IS_DISABLED) {
selectProps.onChange({
keys: [selectProps.name, categoryName, condition.id],
value: !checkboxValue,
});
}
}}
>
<Flex>
<Checkbox
id="check"
name={condition.id}
// Remove the handler
onChange={() => {}}
value={checkboxValue}
/>
{condition.displayName}
</Flex>
</Label>
</Flex>
</li>
);
})}
</SubUl>
{index + 1 < arrayOfOptionsGroupedByCategory.length.length && (
<div style={{ paddingTop: '17px' }} />
)}
</li>
);
})}
</Ul>
</Component>
);
};
MenuList.propTypes = {
selectProps: PropTypes.shape({
arrayOfOptionsGroupedByCategory: PropTypes.array.isRequired,
name: PropTypes.string.isRequired,
onCategoryChange: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.object.isRequired,
}).isRequired,
};
export default MenuList;

View File

@ -1,14 +0,0 @@
/**
* Creates an object with keys corresponding to the categoryName and leafs to false except for the first category
*
* @param {array<array>} arrayOfCategories
* @returns {object}
*/
const createCollapsesObject = arrayOfCategories =>
arrayOfCategories.reduce((acc, current, index) => {
acc[current[0]] = index === 0;
return acc;
}, {});
export default createCollapsesObject;

View File

@ -1,13 +0,0 @@
import createCollapsesObject from '../createCollapsesObject';
describe('ADMIN | COMPONENTS | ROLES | ConditionsSelect | utils | createCollapsesObject', () => {
it('should return an object of collapses', () => {
const arrayOfCategories = [['default', [{ id: 'test' }]], ['custom', { id: 'test' }]];
const expected = {
default: true,
custom: false,
};
expect(createCollapsesObject(arrayOfCategories)).toEqual(expected);
});
});

View File

@ -1,46 +0,0 @@
/* eslint-disable indent */
import React from 'react';
import PropTypes from 'prop-types';
import { components } from 'react-select';
import { Text } from '@buffetjs/core';
import { useIntl } from 'react-intl';
import { createArrayOfValues } from '../../utils';
const Value = ({ children, selectProps, ...props }) => {
const { formatMessage } = useIntl();
const SingleValue = components.SingleValue;
const valuesArray = createArrayOfValues(selectProps.value).filter(val => val);
return (
<SingleValue {...props}>
<Text style={{ paddingTop: 1 }}>
{valuesArray.length === 0
? formatMessage({ id: 'Settings.permissions.conditions.none-selected' })
: formatMessage(
{
id: `Settings.permissions.conditions.selected.${
selectProps.value.length > 1 ? 'plural' : 'singular'
}`,
},
{ number: valuesArray.length }
)}
</Text>
</SingleValue>
);
};
Value.defaultProps = {
children: null,
selectProps: {
value: [],
},
};
Value.propTypes = {
children: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
selectProps: PropTypes.shape({
value: PropTypes.object,
}),
};
export default Value;

View File

@ -1,67 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Select from 'react-select';
import { useIntl } from 'react-intl';
import MenuList from './MenuList';
import ClearIndicator from './ClearIndicator';
import DropdownIndicator from './CustomDropdownIndicator';
import IndicatorSeparator from './IndicatorSeparator';
import SingleValue from './SingleValue';
import selectStyle from '../utils/selectStyle';
const Wrapper = styled.div`
padding-left: ${({ theme }) => theme.main.sizes.paddings.md};
width: 60%;
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'default')};
`;
const ConditionsSelect = ({
arrayOfOptionsGroupedByCategory,
isFormDisabled,
name,
onCategoryChange,
onChange,
value,
}) => {
const { formatMessage } = useIntl();
return (
<Wrapper disabled={isFormDisabled}>
<Select
components={{
ClearIndicator,
DropdownIndicator,
IndicatorSeparator,
SingleValue,
MenuList,
}}
arrayOfOptionsGroupedByCategory={arrayOfOptionsGroupedByCategory}
isDisabled={isFormDisabled}
name={name}
onChange={onChange}
isClearable={false}
isLoading={false}
closeMenuOnSelect={false}
isSearchable={false}
hideSelectedOptions={false}
placeholder={formatMessage({ id: 'Settings.permissions.conditions.anytime' })}
onCategoryChange={onCategoryChange}
options={[]}
styles={selectStyle}
value={value}
/>
</Wrapper>
);
};
ConditionsSelect.propTypes = {
arrayOfOptionsGroupedByCategory: PropTypes.array.isRequired,
isFormDisabled: PropTypes.bool.isRequired,
name: PropTypes.string.isRequired,
onCategoryChange: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.object.isRequired,
};
export default ConditionsSelect;

View File

@ -1,95 +0,0 @@
/* eslint-disable indent */
/* eslint-disable no-nested-ternary */
const selectStyle = {
container: base => ({
...base,
width: '70%',
alignItems: 'center',
height: '36px',
}),
menu: base => ({
...base,
margin: '0',
paddingTop: 0,
borderRadius: '2px !important',
borderTopLeftRadius: '0 !important',
borderTopRightRadius: '0 !important',
border: '1px solid #78caff !important',
boxShadow: 0,
borderTop: '0 !important',
fontSize: '13px',
}),
menuList: base => ({
...base,
paddingBottom: 9,
paddingTop: 10,
}),
multiValue: base => ({
...base,
backgroundColor: 'none',
color: '#333740',
}),
multiValueLabel: base => ({
...base,
fontSize: '13px',
}),
multiValueRemove: base => ({
...base,
display: 'none',
}),
control: (base, state) => {
const borderRadiusStyle = state.selectProps.menuIsOpen
? {
borderBottomLeftRadius: '0 !important',
borderBottomRightRadius: '0 !important',
}
: {};
const {
selectProps: { error, value },
} = state;
let border;
let borderBottom;
if (state.isFocused) {
border = '1px solid #78caff !important';
} else if (error && !value.length) {
border = '1px solid #f64d0a !important';
} else {
border = '1px solid #e3e9f3 !important';
}
if (state.menuIsOpen === true) {
borderBottom = '1px solid #e3e9f3 !important';
}
return {
...base,
fontSize: 13,
minHeight: 34,
top: '1px',
border,
outline: 0,
boxShadow: 0,
borderRadius: '2px !important',
...borderRadiusStyle,
borderBottom,
};
},
valueContainer: base => ({
...base,
padding: '2px 4px 4px 10px',
lineHeight: '18px',
minWidth: 200,
}),
placeholder: base => ({
...base,
paddingTop: 1,
color: 'black',
}),
};
export default selectStyle;

View File

@ -770,6 +770,10 @@ describe('Admin | containers | RoleCreatePage', () => {
background: #d9d8ff;
}
.c40:hover:not([aria-disabled='true']) svg path {
fill: #4945ff;
}
.c47 {
background: transparent;
border: none;
@ -857,10 +861,6 @@ describe('Admin | containers | RoleCreatePage', () => {
height: 5.5rem;
}
.c44:hover svg path {
fill: #4945ff;
}
@media (max-width:68.75rem) {
.c20 {
grid-column: span;

View File

@ -853,6 +853,10 @@ describe('Admin | containers | RoleEditPage', () => {
background: #d9d8ff;
}
.c47:hover:not([aria-disabled='true']) svg path {
fill: #4945ff;
}
.c54 {
background: transparent;
border: none;
@ -940,10 +944,6 @@ describe('Admin | containers | RoleEditPage', () => {
height: 5.5rem;
}
.c51:hover svg path {
fill: #4945ff;
}
@media (max-width:68.75rem) {
.c27 {
grid-column: span;