mirror of
https://github.com/strapi/strapi.git
synced 2025-09-01 04:42:58 +00:00
Add not allowed input
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
8571a6442a
commit
36161fbc49
@ -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
|
||||
|
@ -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') {
|
||||
|
@ -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;
|
@ -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>
|
||||
`);
|
||||
});
|
||||
});
|
@ -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';
|
||||
|
@ -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;
|
@ -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);
|
Loading…
x
Reference in New Issue
Block a user