Add not allowed input

Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
soupette 2021-09-22 10:51:12 +02:00
parent 8571a6442a
commit 36161fbc49
7 changed files with 303 additions and 108 deletions

View File

@ -31,7 +31,8 @@
"i18n": {
"localized": true
}
}
},
"required": true
},
"email": {
"type": "email",
@ -48,7 +49,7 @@
"localized": true
}
},
"required": true
"required": false
},
"password": {
"type": "password",
@ -198,7 +199,7 @@
"deux",
"trois"
],
"required": true,
"required": false,
"pluginOptions": {
"i18n": {
"localized": true

View File

@ -4,13 +4,15 @@ import get from 'lodash/get';
import omit from 'lodash/omit';
import take from 'lodash/take';
import isEqual from 'react-fast-compare';
// import { Inputs as InputsIndex } from '@buffetjs/custom';
// import { NotAllowedInput, useLibrary } from '@strapi/helper-plugin';
import {
NotAllowedInput,
// useLibrary
} from '@strapi/helper-plugin';
import { useContentTypeLayout } from '../../hooks';
import { getFieldName } from '../../utils';
import Wysiwyg from '../Wysiwyg';
import GenericInput from './GenericInput';
import InputJSON from '../InputJSON';
import GenericInput from './GenericInput';
// import SelectWrapper from '../SelectWrapper';
// import WysiwygWithErrors from '../WysiwygWithErrors';
// import InputUID from '../InputUID';
@ -174,14 +176,15 @@ function Inputs({
}
if (!shouldDisplayNotAllowedInput) {
return 'NOT ALLOWED INPUT';
// return (
// <NotAllowedInput
// label={metadatas.label}
// labelAction={labelAction}
// error={errorMessage}
// />
// );
return (
<NotAllowedInput
description={description ? { id: description, defaultMessage: description } : null}
intlLabel={{ id: label, defaultMessage: label }}
labelAction={labelAction}
error={errorId}
name={keys}
/>
);
}
if (type === 'relation') {

View File

@ -0,0 +1,83 @@
/**
*
* NotAllowedInput
*
*/
import React from 'react';
import { useIntl } from 'react-intl';
import { TextInput } from '@strapi/parts/TextInput';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Hide from '@strapi/icons/Hide';
const StyledIcon = styled(Hide)`
> path {
fill: ${({ theme }) => theme.colors.neutral600};
}
`;
const NotAllowedInput = ({ description, intlLabel, labelAction, error, name }) => {
const { formatMessage } = useIntl();
const label = intlLabel.id
? formatMessage(
{ id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
{ ...intlLabel.values }
)
: name;
const hint = description
? formatMessage(
{ id: description.id, defaultMessage: description.defaultMessage },
{ ...description.values }
)
: '';
const placeholder = formatMessage({
id: 'components.NotAllowedInput.text',
defaultMessage: 'No permissions to see this field',
});
const errorMessage = error ? formatMessage({ id: error, defaultMessage: error }) : '';
return (
<TextInput
disabled
error={errorMessage}
label={label}
labelAction={labelAction}
id={name}
hint={hint}
name={name}
onChange={() => {}}
placeholder={placeholder}
startAction={<StyledIcon />}
type="text"
value=""
/>
);
};
NotAllowedInput.defaultProps = {
description: null,
error: '',
labelAction: undefined,
};
NotAllowedInput.propTypes = {
description: PropTypes.shape({
id: PropTypes.string.isRequired,
defaultMessage: PropTypes.string.isRequired,
values: PropTypes.object,
}),
error: PropTypes.string,
intlLabel: PropTypes.shape({
id: PropTypes.string.isRequired,
defaultMessage: PropTypes.string.isRequired,
values: PropTypes.object,
}).isRequired,
labelAction: PropTypes.element,
name: PropTypes.string.isRequired,
};
export default NotAllowedInput;

View File

@ -0,0 +1,201 @@
/**
*
* Tests for NotAllowedInput
*
*/
import React from 'react';
import { render } from '@testing-library/react';
import { ThemeProvider, lightTheme } from '@strapi/parts';
import { IntlProvider } from 'react-intl';
import NotAllowedInput from '../index';
const messages = {
'components.NotAllowedInput.text': 'No permissions to see this field',
};
describe('<NotAllowedInput />', () => {
it('renders and matches the snapshot', () => {
const {
container: { firstChild },
} = render(
<ThemeProvider theme={lightTheme}>
<IntlProvider locale="en" messages={messages} defaultLocale="en">
<NotAllowedInput name="test" intlLabel={{ id: 'test', defaultMessage: 'test' }} />
</IntlProvider>
</ThemeProvider>
);
expect(firstChild).toMatchInlineSnapshot(`
.c3 {
font-weight: 500;
font-size: 0.75rem;
line-height: 1.33;
color: #32324d;
}
.c6 {
padding-right: 8px;
padding-left: 12px;
}
.c2 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.c8 {
border: none;
border-radius: 4px;
padding-left: 0;
padding-right: 16px;
color: #32324d;
font-weight: 400;
font-size: 0.875rem;
display: block;
width: 100%;
height: 2.5rem;
}
.c8::-webkit-input-placeholder {
color: #8e8ea9;
opacity: 1;
}
.c8::-moz-placeholder {
color: #8e8ea9;
opacity: 1;
}
.c8:-ms-input-placeholder {
color: #8e8ea9;
opacity: 1;
}
.c8::placeholder {
color: #8e8ea9;
opacity: 1;
}
.c8[aria-disabled='true'] {
background: inherit;
color: inherit;
}
.c5 {
border: 1px solid #dcdce4;
border-radius: 4px;
background: #ffffff;
color: #666687;
background: #eaeaef;
}
.c1 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.c1 > * {
margin-top: 0;
margin-bottom: 0;
}
.c1 > * + * {
margin-top: 4px;
}
.c0 textarea {
height: 5rem;
}
.c7 > path {
fill: #666687;
}
<div
class="c0"
>
<div>
<div
class="c1"
>
<div
class="c2"
>
<label
class="c3"
for="test"
>
test
</label>
</div>
<div
class="c4 c5"
disabled=""
>
<div
class="c6"
>
<svg
class="c7"
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4.048 6.875L2.103 4.93a1 1 0 111.414-1.415l16.966 16.966a1 1 0 11-1.414 1.415l-2.686-2.686a12.247 12.247 0 01-4.383.788c-3.573 0-6.559-1.425-8.962-3.783a15.842 15.842 0 01-2.116-2.568 11.096 11.096 0 01-.711-1.211 1.145 1.145 0 010-.875c.124-.258.36-.68.711-1.211.58-.876 1.283-1.75 2.116-2.569.326-.32.663-.622 1.01-.906zm10.539 10.539l-1.551-1.551a4.005 4.005 0 01-4.9-4.9L6.584 9.411a6 6 0 008.002 8.002zM7.617 4.787A12.248 12.248 0 0112 3.998c3.572 0 6.559 1.426 8.961 3.783a15.845 15.845 0 012.117 2.569c.351.532.587.954.711 1.211.116.242.115.636 0 .875-.124.257-.36.68-.711 1.211-.58.876-1.283 1.75-2.117 2.568-.325.32-.662.623-1.01.907l-2.536-2.537a6 6 0 00-8.002-8.002L7.617 4.787zm3.347 3.347A4.005 4.005 0 0116 11.998c0 .359-.047.706-.136 1.037l-4.9-4.901z"
fill="#212134"
/>
</svg>
</div>
<input
aria-disabled="true"
aria-invalid="false"
class="c8"
id="test"
name="test"
placeholder="No permissions to see this field"
type="text"
value=""
/>
</div>
</div>
</div>
</div>
`);
});
});

View File

@ -75,7 +75,6 @@ export { default as ModalHeader } from './old/components/ModalHeader';
export { default as ModalFooter } from './old/components/FooterModal';
export { default as ModalForm } from './old/components/FormModal';
export { default as ModalSection } from './old/components/ModalSection';
export { default as NotAllowedInput } from './old/components/NotAllowedInput';
export { default as NotFound } from './old/components/NotFound';
export { default as PageFooter } from './old/components/PageFooter';
@ -178,6 +177,7 @@ export { default as EmptyBodyTable } from './components/EmptyBodyTable';
export { default as GenericInput } from './components/GenericInput';
export * from './components/InjectionZone';
export { default as LoadingIndicatorPage } from './components/LoadingIndicatorPage';
export { default as NotAllowedInput } from './components/NotAllowedInput';
export { default as SettingsPageTitle } from './components/SettingsPageTitle';
export { default as Search } from './components/Search';
export { default as Status } from './components/Status';

View File

@ -1,20 +0,0 @@
import styled from 'styled-components';
const Field = styled.div`
height: 34px;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
margin-top: 11px;
padding-top: 2px;
border-radius: 2px;
background-color: ${({ theme }) => theme.main.colors.mediumGrey};
${({ error, theme }) =>
error &&
`
border: 1px solid ${theme.main.colors.lightOrange};
`}
`;
export default Field;

View File

@ -1,73 +0,0 @@
import React, { memo, useMemo, useRef } from 'react';
import PropTypes from 'prop-types';
import { Flex, Padded, Text } from '@buffetjs/core';
import { useIntl } from 'react-intl';
import EyeSlashed from '../../svgs/EyeSlashed';
import BaselineAlignment from '../BaselineAlignment';
import LabelIconWrapper from '../LabelIconWrapper';
import Field from './Field';
const NotAllowedInput = ({ label, labelIcon, description, error, spacerHeight }) => {
const { formatMessage } = useIntl();
const formatMessageRef = useRef(formatMessage);
const text = useMemo(
() => formatMessageRef.current({ id: 'components.NotAllowedInput.text' }),
[]
);
return (
<BaselineAlignment bottom size="18px">
<Flex style={{ lineHeight: '18px' }}>
<Text fontWeight="semiBold" lineHeight="18px">
<span>{label}</span>
</Text>
{labelIcon && <LabelIconWrapper title={labelIcon.title}>{labelIcon.icon}</LabelIconWrapper>}
</Flex>
<Field error={error}>
<Padded left right size="sm">
<Flex>
<Padded right size="sm">
<EyeSlashed />
</Padded>
<Text fontSize="md" color="grey" as="div" lineHeight="18px" ellipsis>
{text}
</Text>
</Flex>
</Padded>
</Field>
{!error && description && (
<BaselineAlignment top size="9px">
<Text fontSize="md" color="grey" lineHeight="18px" ellipsis>
{description}
</Text>
</BaselineAlignment>
)}
{error && (
<BaselineAlignment top size="9px">
<Text fontSize="md" color="lightOrange" lineHeight="18px" ellipsis>
{error}
</Text>
</BaselineAlignment>
)}
{!error && !description && <BaselineAlignment top size={spacerHeight} />}
</BaselineAlignment>
);
};
NotAllowedInput.defaultProps = {
description: null,
label: '',
spacerHeight: '9px',
};
NotAllowedInput.propTypes = {
description: PropTypes.string,
label: PropTypes.string,
labelIcon: PropTypes.shape({
icon: PropTypes.any,
title: PropTypes.string,
}),
};
export default memo(NotAllowedInput);