From 5e129f51044ec084f1303214b188c1e16da0c82a Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Fri, 17 Jan 2020 21:31:22 +0530 Subject: [PATCH 01/19] add option for isReadOnly and disable field in admin-ui with isReadOnly config --- packages/app-admin-ui/client/pages/Item/index.js | 9 ++++++--- packages/fields/src/Controller.js | 1 + packages/fields/src/Implementation.js | 14 +++++++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/app-admin-ui/client/pages/Item/index.js b/packages/app-admin-ui/client/pages/Item/index.js index c7765eae601..7a442a74b61 100644 --- a/packages/app-admin-ui/client/pages/Item/index.js +++ b/packages/app-admin-ui/client/pages/Item/index.js @@ -48,6 +48,8 @@ const Form = styled.form({ const getValues = (fieldsObject, item) => mapKeys(fieldsObject, field => field.serialize(item)); +const checkIsReadOnly = ({ maybeAccess, config }) => !maybeAccess.update || !!config.isReadOnly; + // Memoizing allows us to reduce the calls to `.serialize` when data hasn't // changed. const getInitialValues = memoizeOne(getValues); @@ -56,9 +58,7 @@ const getCurrentValues = memoizeOne(getValues); const deserializeItem = memoizeOne((list, data) => list.deserializeItemData(data)); const getRenderableFields = memoizeOne(list => - list.fields - .filter(({ isPrimaryKey }) => !isPrimaryKey) - .filter(({ maybeAccess, config }) => !!maybeAccess.update || !!config.isReadOnly) + list.fields.filter(({ isPrimaryKey }) => !isPrimaryKey) ); const ItemDetails = ({ @@ -263,6 +263,7 @@ const ItemDetails = ({ {() => { const [Field] = field.adminMeta.readViews([field.views.Field]); + const isReadOnly = checkIsReadOnly(field); // eslint-disable-next-line react-hooks/rules-of-hooks const onChange = useCallback( value => { @@ -293,6 +294,7 @@ const ItemDetails = ({ field={field} list={list} item={item} + isReadOnly={isReadOnly} errors={[ ...(itemErrors[field.path] ? [itemErrors[field.path]] : []), ...(validationErrors[field.path] || []), @@ -316,6 +318,7 @@ const ItemDetails = ({ validationWarnings[field.path], initialData[field.path], onChange, + isReadOnly, ] ); }} diff --git a/packages/fields/src/Controller.js b/packages/fields/src/Controller.js index c8d5d3a571c..1b9aef83f4b 100644 --- a/packages/fields/src/Controller.js +++ b/packages/fields/src/Controller.js @@ -8,6 +8,7 @@ export default class FieldController { this.type = config.type; this.maybeAccess = config.access; this.isPrimaryKey = config.isPrimaryKey; + this.isReadOnly = config.isReadOnly; this.list = list; this.adminMeta = adminMeta; this.views = views; diff --git a/packages/fields/src/Implementation.js b/packages/fields/src/Implementation.js index a3f78e97be2..109386e4712 100644 --- a/packages/fields/src/Implementation.js +++ b/packages/fields/src/Implementation.js @@ -4,11 +4,22 @@ import { parseFieldAccess } from '@keystonejs/access-control'; class Field { constructor( path, - { hooks = {}, isRequired, defaultValue, access, label, schemaDoc, adminDoc, ...config }, + { + hooks = {}, + isRequired, + defaultValue, + access, + label, + schemaDoc, + adminDoc, + isReadOnly, + ...config + }, { getListByKey, listKey, listAdapter, fieldAdapterClass, defaultAccess, schemaNames } ) { this.path = path; this.isPrimaryKey = path === 'id'; + this.isReadOnly = isReadOnly; this.schemaDoc = schemaDoc; this.adminDoc = adminDoc; this.config = config; @@ -171,6 +182,7 @@ class Field { // functions defaultValue: typeof this.defaultValue !== 'function' ? this.defaultValue : undefined, isPrimaryKey: this.isPrimaryKey, + isReadOnly: this.isReadOnly, // NOTE: This data is serialised, so we're unable to pass through any // access control _functions_. But we can still check for the boolean case // and pass that through (we assume that if there is a function, it's a From 509ea1d229638eb35983bbe23602ff6b511a60f4 Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Fri, 17 Jan 2020 22:23:51 +0530 Subject: [PATCH 02/19] consume isReadOnly in core fields --- .../fields/src/types/CalendarDay/views/Field.js | 3 ++- .../fields/src/types/Checkbox/views/Field.js | 9 ++++++++- .../src/types/CloudinaryImage/views/Field.js | 16 +++++++++++----- packages/fields/src/types/Color/views/Field.js | 4 ++-- .../fields/src/types/DateTime/views/Field.js | 10 ++++++++-- packages/fields/src/types/Decimal/views/Field.js | 3 ++- packages/fields/src/types/File/views/Field.js | 16 +++++++++++----- packages/fields/src/types/Float/views/Field.js | 3 ++- packages/fields/src/types/Integer/views/Field.js | 3 ++- .../fields/src/types/Location/views/Field.js | 11 ++++++++++- packages/fields/src/types/OEmbed/views/Field.js | 11 ++++++++++- .../fields/src/types/Password/views/Field.js | 11 ++++++++++- .../fields/src/types/Relationship/views/Field.js | 10 ++++++++-- .../Relationship/views/RelationshipSelect.js | 4 ++++ packages/fields/src/types/Select/views/Field.js | 11 ++++++++++- packages/fields/src/types/Text/views/Field.js | 3 ++- .../fields/src/types/Unsplash/views/Field.js | 3 ++- packages/fields/src/types/Url/views/Field.js | 3 ++- packages/fields/src/types/Uuid/views/Field.js | 3 ++- 19 files changed, 108 insertions(+), 29 deletions(-) diff --git a/packages/fields/src/types/CalendarDay/views/Field.js b/packages/fields/src/types/CalendarDay/views/Field.js index 0cae1d0b1e8..bdf3834b65d 100644 --- a/packages/fields/src/types/CalendarDay/views/Field.js +++ b/packages/fields/src/types/CalendarDay/views/Field.js @@ -6,7 +6,7 @@ import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch- import { TextDayPicker } from '@arch-ui/day-picker'; import { Alert } from '@arch-ui/alert'; -const CalendarDayField = ({ autoFocus, field, value, errors, onChange }) => { +const CalendarDayField = ({ autoFocus, field, value, errors, onChange, isReadOnly }) => { const htmlID = `ks-daypicker-${field.path}`; return ( @@ -20,6 +20,7 @@ const CalendarDayField = ({ autoFocus, field, value, errors, onChange }) => { date={value} format={field.config.format} onChange={onChange} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Checkbox/views/Field.js b/packages/fields/src/types/Checkbox/views/Field.js index bc51d258444..0a0e5bf41cb 100644 --- a/packages/fields/src/types/Checkbox/views/Field.js +++ b/packages/fields/src/types/Checkbox/views/Field.js @@ -2,7 +2,13 @@ import { jsx } from '@emotion/core'; -import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; +import { + FieldContainer, + FieldLabel, + FieldDescription, + FieldInput, + isReadOnly, +} from '@arch-ui/fields'; import { CheckboxPrimitive } from '@arch-ui/controls'; @@ -23,6 +29,7 @@ const TextField = ({ onChange, autoFocus, field, value, errors }) => { checked={checked} onChange={handleChange} id={htmlID} + isDisabled={isReadOnly} /> { - const { uploadButtonLabel } = this.props; + const { uploadButtonLabel, isReadOnly } = this.props; const { changeStatus, isLoading } = this.state; return ( - + {uploadButtonLabel({ status: changeStatus })} ); }; renderCancelButton = () => { - const { cancelButtonLabel } = this.props; + const { cancelButtonLabel, isReadOnly } = this.props; const { changeStatus } = this.state; // possible states; no case for 'empty' as cancel is not rendered @@ -214,14 +219,14 @@ export default class FileField extends Component { } return ( - ); }; render() { - const { autoFocus, field, statusMessage, errors } = this.props; + const { autoFocus, field, statusMessage, errors, isReadOnly } = this.props; const { changeStatus, errorMessage } = this.state; const { file } = this.getFile(); @@ -269,6 +274,7 @@ export default class FileField extends Component { name={field.path} onChange={this.onChange} type="file" + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Color/views/Field.js b/packages/fields/src/types/Color/views/Field.js index e2fedc1ee45..c0d9b43245c 100644 --- a/packages/fields/src/types/Color/views/Field.js +++ b/packages/fields/src/types/Color/views/Field.js @@ -6,7 +6,7 @@ import Popout from '@arch-ui/popout'; import { Button } from '@arch-ui/button'; import SketchPicker from 'react-color/lib/Sketch'; -const ColorField = ({ field, value: serverValue, errors, onChange }) => { +const ColorField = ({ field, value: serverValue, errors, onChange, isReadOnly }) => { const value = serverValue || ''; const htmlID = `ks-input-${field.path}`; @@ -24,7 +24,7 @@ const ColorField = ({ field, value: serverValue, errors, onChange }) => { }, [value]); const target = props => ( - ); }; render() { - const { autoFocus, field, statusMessage, errors } = this.props; + const { autoFocus, field, statusMessage, errors, isReadOnly } = this.props; const { changeStatus, errorMessage } = this.state; const { file } = this.getFile(); @@ -260,6 +265,7 @@ export default class FileField extends Component { name={field.path} onChange={this.onChange} type="file" + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Float/views/Field.js b/packages/fields/src/types/Float/views/Field.js index 02d652abda3..641f9451a9d 100644 --- a/packages/fields/src/types/Float/views/Field.js +++ b/packages/fields/src/types/Float/views/Field.js @@ -3,7 +3,7 @@ import React from 'react'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const TextField = ({ onChange, autoFocus, field, value, errors }) => { +const TextField = ({ onChange, autoFocus, field, value, errors, isReadOnly }) => { const handleChange = event => { const value = event.target.value; // Similar implementation as per old Keystone version @@ -26,6 +26,7 @@ const TextField = ({ onChange, autoFocus, field, value, errors }) => { value={value} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Integer/views/Field.js b/packages/fields/src/types/Integer/views/Field.js index c8cd1a8c9c2..3b419579703 100644 --- a/packages/fields/src/types/Integer/views/Field.js +++ b/packages/fields/src/types/Integer/views/Field.js @@ -3,7 +3,7 @@ import React from 'react'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const TextField = ({ onChange, autoFocus, field, value, errors }) => { +const TextField = ({ onChange, autoFocus, field, value, errors, isReadOnly }) => { const handleChange = event => { const value = event.target.value; onChange(value.replace(/\D/g, '')); @@ -35,6 +35,7 @@ const TextField = ({ onChange, autoFocus, field, value, errors }) => { value={valueToString(value)} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Location/views/Field.js b/packages/fields/src/types/Location/views/Field.js index 45ab729c76b..a526db816e8 100644 --- a/packages/fields/src/types/Location/views/Field.js +++ b/packages/fields/src/types/Location/views/Field.js @@ -6,7 +6,15 @@ import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch- import Select from '@arch-ui/select'; import { Map, Marker, GoogleApiWrapper } from 'google-maps-react'; -const LocationField = ({ field, value: serverValue, errors, onChange, google, renderContext }) => { +const LocationField = ({ + field, + value: serverValue, + errors, + onChange, + google, + renderContext, + isReadOnly, +}) => { const { googlePlaceID, formattedAddress, lat, lng } = serverValue || {}; const htmlID = `ks-input-${field.path}`; const autocompleteService = new google.maps.places.AutocompleteService(); @@ -89,6 +97,7 @@ const LocationField = ({ field, value: serverValue, errors, onChange, google, re inputId={htmlID} instanceId={htmlID} css={{ width: '100%' }} + isDisabled={isReadOnly} {...selectProps} /> {marker && ( diff --git a/packages/fields/src/types/OEmbed/views/Field.js b/packages/fields/src/types/OEmbed/views/Field.js index fb4ef9e9a3a..a23e026b540 100644 --- a/packages/fields/src/types/OEmbed/views/Field.js +++ b/packages/fields/src/types/OEmbed/views/Field.js @@ -40,7 +40,15 @@ const PlaceholderPreview = ({ originalUrl, fieldPath }) => ( /> ); -const OEmbedField = ({ onChange, autoFocus, field, value = null, savedValue = null, errors }) => { +const OEmbedField = ({ + onChange, + autoFocus, + field, + value = null, + savedValue = null, + errors, + isReadOnly, +}) => { const handleChange = event => { onChange({ originalUrl: event.target.value, @@ -67,6 +75,7 @@ const OEmbedField = ({ onChange, autoFocus, field, value = null, savedValue = nu placeholder={canRead ? undefined : error.message} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> {value && value.originalUrl && hasChanged && ( diff --git a/packages/fields/src/types/Password/views/Field.js b/packages/fields/src/types/Password/views/Field.js index 392ffd9dd65..04b7a163ca1 100644 --- a/packages/fields/src/types/Password/views/Field.js +++ b/packages/fields/src/types/Password/views/Field.js @@ -18,6 +18,7 @@ const PasswordField = ({ item: { password_is_set } = {}, errors, warnings, + isReadOnly, }) => { const focusTarget = useRef(); @@ -79,6 +80,7 @@ const PasswordField = ({ placeholder="New Password" type={showInputValue ? 'text' : 'password'} value={inputPassword} + disabled={isReadOnly} /> ) : ( - )} diff --git a/packages/fields/src/types/Relationship/views/Field.js b/packages/fields/src/types/Relationship/views/Field.js index 7d08ff0b099..a0c85f441b0 100644 --- a/packages/fields/src/types/Relationship/views/Field.js +++ b/packages/fields/src/types/Relationship/views/Field.js @@ -16,7 +16,7 @@ import { ListProvider, useList } from '@keystonejs/app-admin-ui/components'; const MAX_IDS_IN_FILTER = 100; -function SetAsCurrentUser({ listKey, value, onAddUser, many }) { +function SetAsCurrentUser({ listKey, value, onAddUser, many, isDisabled }) { const path = 'authenticated' + listKey; const { data } = useQuery(gql` @@ -46,6 +46,7 @@ function SetAsCurrentUser({ listKey, value, onAddUser, many }) { }} icon={PersonIcon} aria-label={label} + isDisabled={isDisabled} /> )} @@ -103,7 +104,7 @@ function LinkToRelatedItems({ field, value }) { ); } -function CreateAndAddItem({ field, item, onCreate, CreateItemModal }) { +function CreateAndAddItem({ field, item, onCreate, CreateItemModal, isDisabled }) { const { list, openCreateItemModal } = useList(); let relatedList = field.adminMeta.getListByKey(field.config.ref); @@ -144,6 +145,7 @@ function CreateAndAddItem({ field, item, onCreate, CreateItemModal }) { aria-label={label} variant="ghost" css={{ marginLeft: gridSize }} + isDisabled={isDisabled} /> ); }} @@ -168,6 +170,7 @@ const RelationshipField = ({ item, list, CreateItemModal, + isReadOnly, }) => { const handleChange = option => { const { many } = field.config; @@ -199,6 +202,7 @@ const RelationshipField = ({ renderContext={renderContext} htmlID={htmlID} onChange={handleChange} + isDisabled={isReadOnly} /> @@ -210,6 +214,7 @@ const RelationshipField = ({ item={item} list={list} CreateItemModal={CreateItemModal} + isDisabled={isReadOnly} /> {authStrategy && ref === authStrategy.listKey && ( @@ -220,6 +225,7 @@ const RelationshipField = ({ }} value={value} listKey={authStrategy.listKey} + isDisabled={isReadOnly} /> )} diff --git a/packages/fields/src/types/Relationship/views/RelationshipSelect.js b/packages/fields/src/types/Relationship/views/RelationshipSelect.js index d42902fa430..fe0169bbd30 100644 --- a/packages/fields/src/types/Relationship/views/RelationshipSelect.js +++ b/packages/fields/src/types/Relationship/views/RelationshipSelect.js @@ -39,6 +39,7 @@ const Relationship = forwardRef( setSearch, selectProps, fetchMore, + isDisabled, }, ref ) => { @@ -134,6 +135,7 @@ const Relationship = forwardRef( inputId={htmlID} innerRef={ref} menuPortalTarget={document.body} + isDisabled={isDisabled} {...selectProps} /> ); @@ -150,6 +152,7 @@ const RelationshipSelect = ({ onChange, isMulti, value, + isDisabled, }) => { const [search, setSearch] = useState(''); const refList = field.getRefList(); @@ -194,6 +197,7 @@ const RelationshipSelect = ({ selectProps, fetchMore, ref: innerRef, + isDisabled, }} /> ); diff --git a/packages/fields/src/types/Select/views/Field.js b/packages/fields/src/types/Select/views/Field.js index 6cbe2595828..ffe04739b81 100644 --- a/packages/fields/src/types/Select/views/Field.js +++ b/packages/fields/src/types/Select/views/Field.js @@ -5,7 +5,15 @@ import { jsx } from '@emotion/core'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import Select from '@arch-ui/select'; -const SelectField = ({ onChange, autoFocus, field, value: serverValue, renderContext, errors }) => { +const SelectField = ({ + onChange, + autoFocus, + field, + value: serverValue, + renderContext, + errors, + isReadOnly, +}) => { const handleChange = option => { onChange(option ? option.value : null); }; @@ -41,6 +49,7 @@ const SelectField = ({ onChange, autoFocus, field, value: serverValue, renderCon id={`react-select-${htmlID}`} inputId={htmlID} instanceId={htmlID} + isDisabled={isReadOnly} {...selectProps} /> diff --git a/packages/fields/src/types/Text/views/Field.js b/packages/fields/src/types/Text/views/Field.js index 610aa51cf39..30ef9d35bf9 100644 --- a/packages/fields/src/types/Text/views/Field.js +++ b/packages/fields/src/types/Text/views/Field.js @@ -5,7 +5,7 @@ import { jsx } from '@emotion/core'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const TextField = ({ onChange, autoFocus, field, errors, value: serverValue }) => { +const TextField = ({ onChange, autoFocus, field, errors, value: serverValue, isReadOnly }) => { const handleChange = event => { onChange(event.target.value); }; @@ -32,6 +32,7 @@ const TextField = ({ onChange, autoFocus, field, errors, value: serverValue }) = onChange={handleChange} id={htmlID} isMultiline={isMultiline} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Unsplash/views/Field.js b/packages/fields/src/types/Unsplash/views/Field.js index 787142935ef..94d52d07e8d 100644 --- a/packages/fields/src/types/Unsplash/views/Field.js +++ b/packages/fields/src/types/Unsplash/views/Field.js @@ -5,7 +5,7 @@ import { jsx } from '@emotion/core'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const UnsplashField = ({ onChange, autoFocus, field, errors, value: serverValue }) => { +const UnsplashField = ({ onChange, autoFocus, field, errors, value: serverValue, isReadOnly }) => { const handleChange = event => { onChange(event.target.value); }; @@ -30,6 +30,7 @@ const UnsplashField = ({ onChange, autoFocus, field, errors, value: serverValue placeholder={canRead ? 'Unsplash Image ID' : error.message} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Url/views/Field.js b/packages/fields/src/types/Url/views/Field.js index da64ed32761..30f7d122a88 100644 --- a/packages/fields/src/types/Url/views/Field.js +++ b/packages/fields/src/types/Url/views/Field.js @@ -5,7 +5,7 @@ import { jsx } from '@emotion/core'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const UrlField = ({ onChange, autoFocus, field, value: serverValue, errors }) => { +const UrlField = ({ onChange, autoFocus, field, value: serverValue, errors, isReadOnly }) => { const handleChange = event => { onChange(event.target.value); }; @@ -30,6 +30,7 @@ const UrlField = ({ onChange, autoFocus, field, value: serverValue, errors }) => placeholder={canRead ? undefined : error.message} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> diff --git a/packages/fields/src/types/Uuid/views/Field.js b/packages/fields/src/types/Uuid/views/Field.js index 1e2dda7a302..b9e3cbddd26 100644 --- a/packages/fields/src/types/Uuid/views/Field.js +++ b/packages/fields/src/types/Uuid/views/Field.js @@ -5,7 +5,7 @@ import { jsx } from '@emotion/core'; import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { Input } from '@arch-ui/input'; -const UuidField = ({ onChange, autoFocus, field, errors, value: serverValue }) => { +const UuidField = ({ onChange, autoFocus, field, errors, value: serverValue, isReadOnly }) => { const handleChange = event => { onChange(event.target.value); }; @@ -30,6 +30,7 @@ const UuidField = ({ onChange, autoFocus, field, errors, value: serverValue }) = placeholder={canRead ? undefined : error.message} onChange={handleChange} id={htmlID} + disabled={isReadOnly} /> From c571fe850e13b58929133286fed27d10d31f03fb Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Fri, 17 Jan 2020 22:55:57 +0530 Subject: [PATCH 03/19] consume isReadOnly in all the other non core fields --- packages/field-content/src/views/Field.js | 3 ++- packages/field-content/src/views/editor/index.js | 3 ++- packages/fields-markdown/src/views/Field.js | 4 +++- packages/fields-wysiwyg-tinymce/src/views/Field.js | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/field-content/src/views/Field.js b/packages/field-content/src/views/Field.js index 52f90961f34..196da8fd331 100644 --- a/packages/field-content/src/views/Field.js +++ b/packages/field-content/src/views/Field.js @@ -24,7 +24,7 @@ class ErrorBoundary extends Component { } } -let ContentField = ({ field, value, onChange, autoFocus, errors }) => { +let ContentField = ({ field, value, onChange, autoFocus, errors, isReadOnly }) => { const htmlID = `ks-content-editor-${field.path}`; return ( @@ -62,6 +62,7 @@ let ContentField = ({ field, value, onChange, autoFocus, errors }) => { padding: '16px 32px', minHeight: 200, }} + isReadOnly={isReadOnly} /> )} diff --git a/packages/field-content/src/views/editor/index.js b/packages/field-content/src/views/editor/index.js index b9fb07b0b70..83bb08bb873 100755 --- a/packages/field-content/src/views/editor/index.js +++ b/packages/field-content/src/views/editor/index.js @@ -32,7 +32,7 @@ function getSchema(blocks) { return schema; } -function Stories({ value: editorState, onChange, blocks, className, id }) { +function Stories({ value: editorState, onChange, blocks, className, id, isReadOnly }) { let schema = useMemo(() => { return getSchema(blocks); }, [blocks]); @@ -75,6 +75,7 @@ function Stories({ value: editorState, onChange, blocks, className, id }) { onChange={({ value }) => { onChange(value); }} + readOnly={isReadOnly} /> diff --git a/packages/fields-markdown/src/views/Field.js b/packages/fields-markdown/src/views/Field.js index 851ede32d81..110cada7755 100644 --- a/packages/fields-markdown/src/views/Field.js +++ b/packages/fields-markdown/src/views/Field.js @@ -60,7 +60,7 @@ let IconToolbarButton = ({ isActive, label, icon, tooltipPlacement = 'top', ...p ); }; -export default function MarkdownField({ field, errors, value, onChange }) { +export default function MarkdownField({ field, errors, value, onChange, isReadOnly }) { const htmlID = `ks-input-${field.path}`; const accessError = errors.find( error => error instanceof Error && error.name === 'AccessDeniedError' @@ -81,6 +81,7 @@ export default function MarkdownField({ field, errors, value, onChange }) { icon={} onClick={onClick} label={tool.label} + disabled={isReadOnly} /> ); })} @@ -122,6 +123,7 @@ export default function MarkdownField({ field, errors, value, onChange }) { tabSize: '2', lineWrapping: true, addModeClass: true, + readOnly: isReadOnly, }} editorDidMount={editor => { setTools(getTools(editor)); diff --git a/packages/fields-wysiwyg-tinymce/src/views/Field.js b/packages/fields-wysiwyg-tinymce/src/views/Field.js index 070bf721b73..756b9c51bc0 100644 --- a/packages/fields-wysiwyg-tinymce/src/views/Field.js +++ b/packages/fields-wysiwyg-tinymce/src/views/Field.js @@ -37,7 +37,7 @@ const GlobalStyles = () => ( /> ); -const WysiwygField = ({ onChange, autoFocus, field, errors, value: serverValue }) => { +const WysiwygField = ({ onChange, autoFocus, field, errors, value: serverValue, isReadOnly }) => { const handleChange = value => { if (typeof value === 'string') { onChange(value); @@ -63,6 +63,7 @@ const WysiwygField = ({ onChange, autoFocus, field, errors, value: serverValue } init={{ ...defaultOptions, auto_focus: autoFocus, ...overrideOptions }} onEditorChange={handleChange} value={value} + isDisabled={isReadOnly} /> From a66104085051e82a7a21a919774f1067306e3bc3 Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Sun, 12 Apr 2020 04:05:31 +0530 Subject: [PATCH 04/19] fix test case --- .../cypress/integration/field/admin-ui.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-projects/access-control/cypress/integration/field/admin-ui.js b/test-projects/access-control/cypress/integration/field/admin-ui.js index d67b8ae58d1..af6e93bb93e 100644 --- a/test-projects/access-control/cypress/integration/field/admin-ui.js +++ b/test-projects/access-control/cypress/integration/field/admin-ui.js @@ -203,14 +203,14 @@ describe('Access Control Fields > Admin UI', () => { }); }); - it('does not show non-updatable inputs', () => { + it('shows non-updatable inputs as disabled', () => { fieldAccessVariations .filter(({ update, read }) => !update && read) .forEach(access => { const field = getFieldName(access); cy.get(`label[for="ks-input-${field}"]`) - .should('not.exist') - .then(() => cy.get(`#ks-input-${field}`).should('not.exist')); + .should('exist') + .then(() => cy.get(`#ks-input-${field}`).should('be.disabled')); }); }); @@ -241,14 +241,14 @@ describe('Access Control Fields > Admin UI', () => { }); }); - it.skip('does not show non-updatable inputs', () => { + it.skip('shows non-updatable inputs as disabled', () => { fieldAccessVariations .filter(({ update, read }) => !update && read) .forEach(access => { const field = getFieldName(access); cy.get(`label[for="ks-input-${field}"]`) - .should('not.exist') - .then(() => cy.get(`#ks-input-${field}`).should('not.exist')); + .should('exist') + .then(() => cy.get(`#ks-input-${field}`).should('be.disabled')); }); }); From 911232301f6509c6246915aeda721354c503b2af Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Sun, 12 Apr 2020 04:38:04 +0530 Subject: [PATCH 05/19] changeset --- .changeset/blue-ways-work.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/blue-ways-work.md diff --git a/.changeset/blue-ways-work.md b/.changeset/blue-ways-work.md new file mode 100644 index 00000000000..1eadd1a49a2 --- /dev/null +++ b/.changeset/blue-ways-work.md @@ -0,0 +1,10 @@ +--- +'@keystonejs/app-admin-ui': minor +'@keystonejs/field-content': minor +'@keystonejs/fields-markdown': minor +'@keystonejs/fields-wysiwyg-tinymce': minor +'@keystonejs/fields': minor +'@keystonejs/cypress-project-access-control': patch +--- + +Added `isReadOnly` option on fields and show them as disabled in admin ui edit item page. Before this you can not see the fields in admin-ui if you do not have `update` access From 4f6a3dbc3366bdf96993cb5bbeeec1171c6dc6af Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Wed, 20 May 2020 15:44:05 +0530 Subject: [PATCH 06/19] remove explicit isReadOnly field config to make it usable via `adminConfig` --- packages/app-admin-ui/client/pages/Item/index.js | 2 +- packages/fields/src/Implementation.js | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/app-admin-ui/client/pages/Item/index.js b/packages/app-admin-ui/client/pages/Item/index.js index ffdb641bdc9..5dae6e73366 100644 --- a/packages/app-admin-ui/client/pages/Item/index.js +++ b/packages/app-admin-ui/client/pages/Item/index.js @@ -44,7 +44,7 @@ const Form = props =>
mapKeys(fieldsObject, field => field.serialize(item)); -const checkIsReadOnly = ({ maybeAccess, config }) => !maybeAccess.update || !!config.isReadOnly; +const checkIsReadOnly = ({ maybeAccess, isReadOnly }) => !maybeAccess.update || !!isReadOnly; // Memoizing allows us to reduce the calls to `.serialize` when data hasn't // changed. diff --git a/packages/fields/src/Implementation.js b/packages/fields/src/Implementation.js index b346ea7e0f9..7904f99f8d0 100644 --- a/packages/fields/src/Implementation.js +++ b/packages/fields/src/Implementation.js @@ -12,7 +12,6 @@ class Field { label, schemaDoc, adminDoc, - isReadOnly, adminConfig, ...config }, @@ -20,7 +19,6 @@ class Field { ) { this.path = path; this.isPrimaryKey = path === 'id'; - this.isReadOnly = isReadOnly; this.schemaDoc = schemaDoc; this.adminDoc = adminDoc; this.adminConfig = adminConfig; @@ -184,7 +182,6 @@ class Field { // functions defaultValue: typeof this.defaultValue !== 'function' ? this.defaultValue : undefined, isPrimaryKey: this.isPrimaryKey, - isReadOnly: this.isReadOnly, ...this.adminConfig, // NOTE: This data is serialised, so we're unable to pass through any // access control _functions_. But we can still check for the boolean case From 4d9fcfb4c3a78c817331695e70bd8b77fda9c187 Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Wed, 20 May 2020 16:34:20 +0530 Subject: [PATCH 07/19] show read only in createItemModal --- packages/app-admin-ui/client/components/CreateItemModal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-admin-ui/client/components/CreateItemModal.js b/packages/app-admin-ui/client/components/CreateItemModal.js index b034affa450..dd141d6b854 100644 --- a/packages/app-admin-ui/client/components/CreateItemModal.js +++ b/packages/app-admin-ui/client/components/CreateItemModal.js @@ -222,6 +222,7 @@ const CreateItemModal = ({ prefillData = {}, onClose, onCreate }) => { warnings={validationWarnings[field.path] || []} onChange={onChange} renderContext="dialog" + isReadOnly={field.isReadOnly} /> ), [ From f4efae9e97b991173df2a320d782b8beae652eb6 Mon Sep 17 00:00:00 2001 From: Gautam Singh Date: Thu, 21 May 2020 00:39:47 +0530 Subject: [PATCH 08/19] update readme and add more tests --- .changeset/blue-ways-work.md | 22 +++++++- packages/fields/README.md | 22 ++++++++ .../cypress/integration/readOnly_spec.js | 29 +++++++++++ test-projects/basic/data.js | 5 ++ test-projects/basic/index.js | 50 +++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 test-projects/basic/cypress/integration/readOnly_spec.js diff --git a/.changeset/blue-ways-work.md b/.changeset/blue-ways-work.md index 1eadd1a49a2..4af0cab90cb 100644 --- a/.changeset/blue-ways-work.md +++ b/.changeset/blue-ways-work.md @@ -7,4 +7,24 @@ '@keystonejs/cypress-project-access-control': patch --- -Added `isReadOnly` option on fields and show them as disabled in admin ui edit item page. Before this you can not see the fields in admin-ui if you do not have `update` access +* Added `isReadOnly` option on field's `adminConfig`. This allows to show them as disabled in `admin-ui` item detail page. +* This PR also enables you to see the fields (disabled) in item detail page when you have no `update` access to field. + +example: + +```js +keystone.createList('Todo', { + fields: { + name: { type: Text, isRequired: true }, + someReadOnlyField: { + type: Text, + adminConfig: { + isReadOnly: true, + }, + defaultValue: 'Some default value', + }, + }, +}); +``` + + diff --git a/packages/fields/README.md b/packages/fields/README.md index 40a7f8396cf..a6172a5fb41 100644 --- a/packages/fields/README.md +++ b/packages/fields/README.md @@ -81,6 +81,28 @@ A description of the field used in the AdminUI. A description of the field used used in the GraphQL schema. +### `adminConfig` + +Additional field configs affecting field rendering or display in `admin-ui`. + +#### `adminConfig.isReadOnly` + +This admin config makes the field read only in `admin-ui`, Field with `isReadOnly` set to `true` will be rendered as disabled and you can not modify them in Item Details page or in Create item modal. + +```javascript +keystone.createList('Post', { + fields: { + title: { type: Text }, + slug: { + type: Slug, + adminConfig: { + isReadOnly: true, //slug can be created automatically and you may want to show this as read only + }, + }, + }, +}); +``` + ### `defaultValue` Sets the value when no data is provided. diff --git a/test-projects/basic/cypress/integration/readOnly_spec.js b/test-projects/basic/cypress/integration/readOnly_spec.js new file mode 100644 index 00000000000..6e91f1e2401 --- /dev/null +++ b/test-projects/basic/cypress/integration/readOnly_spec.js @@ -0,0 +1,29 @@ +const path = '/admin/users?fields=_label_%2Cdob%2ClastOnline'; + +const getCellFromSecondRow = index => + `#ks-list-table tbody > tr:nth-child(2) > td:nth-child(${index})`; + +describe('ReadOnly Fields', () => { + it('Ensure readonly fields are rendered as disabled', () => { + cy.visit('/admin/read-only-lists'); + + cy.get('a[href^="/admin/read-only-lists/"]:first').click({ force: true }); + + ['slug', 'status', 'author', 'views', 'price', 'currency', 'hero'].forEach(field => { + cy.get(`label[for="ks-input-${field}"]`) + .should('exist') + .then(() => cy.get(`#ks-input-${field}`).should('be.disabled')); + }); + + // markdown field rendering + cy.get(`label[for="ks-input-markdownValue"]`) + .should('exist') + .then($label => { + cy.get($label) + .next() + .within(() => { + cy.get('button').should('be.disabled'); + }); + }); + }); +}); diff --git a/test-projects/basic/data.js b/test-projects/basic/data.js index 5ae9f53d9a0..22c3d371174 100644 --- a/test-projects/basic/data.js +++ b/test-projects/basic/data.js @@ -107,5 +107,10 @@ module.exports = { name: 'Number comparison', }, ], + ReadOnlyList: [ + { + name: 'ReadOnly', + }, + ], User: users.map(user => ({ ...user, password: 'password' })), }; diff --git a/test-projects/basic/index.js b/test-projects/basic/index.js index 324d237a5e3..1481621a834 100644 --- a/test-projects/basic/index.js +++ b/test-projects/basic/index.js @@ -14,6 +14,7 @@ const { Url, Decimal, OEmbed, + Slug, Unsplash, Virtual, } = require('@keystonejs/fields'); @@ -205,6 +206,55 @@ keystone.createList('Post', { }, }); +keystone.createList('ReadOnlyList', { + fields: { + name: { type: Text }, + slug: { type: Slug, adminConfig: { isReadOnly: true } }, + status: { + type: Select, + defaultValue: 'draft', + options: [ + { label: 'Draft', value: 'draft' }, + { label: 'Published', value: 'published' }, + ], + adminConfig: { isReadOnly: true }, + }, + author: { + type: Relationship, + ref: 'User', + adminConfig: { isReadOnly: true }, + }, + views: { type: Integer, adminConfig: { isReadOnly: true } }, + price: { type: Decimal, symbol: '$', adminConfig: { isReadOnly: true } }, + currency: { type: Text, adminConfig: { isReadOnly: true } }, + hero: { type: File, adapter: fileAdapter, adminConfig: { isReadOnly: true } }, + markdownValue: { type: Markdown, adminConfig: { isReadOnly: true } }, + value: { + type: Content, + blocks: [ + ...(cloudinaryAdapter + ? [[CloudinaryImage.blocks.image, { adapter: cloudinaryAdapter }]] + : []), + ...(embedAdapter ? [[OEmbed.blocks.oEmbed, { adapter: embedAdapter }]] : []), + ...(unsplash.accessKey + ? [[Unsplash.blocks.unsplashImage, { attribution: 'KeystoneJS', ...unsplash }]] + : []), + Content.blocks.blockquote, + Content.blocks.orderedList, + Content.blocks.unorderedList, + Content.blocks.link, + Content.blocks.heading, + ], + adminConfig: { isReadOnly: true }, + }, + }, + adminConfig: { + defaultPageSize: 20, + defaultColumns: 'name, status', + defaultSort: 'name', + }, +}); + keystone.createList('PostCategory', { fields: { name: { type: Text }, From 044b5e23dd9caeb0ad8c430e14c95a673ff2bc92 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 08:59:44 +1000 Subject: [PATCH 09/19] Update packages/fields/README.md --- packages/fields/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fields/README.md b/packages/fields/README.md index a6172a5fb41..95dada96286 100644 --- a/packages/fields/README.md +++ b/packages/fields/README.md @@ -87,7 +87,7 @@ Additional field configs affecting field rendering or display in `admin-ui`. #### `adminConfig.isReadOnly` -This admin config makes the field read only in `admin-ui`, Field with `isReadOnly` set to `true` will be rendered as disabled and you can not modify them in Item Details page or in Create item modal. +Fields with `isReadOnly` set to `true` will be disabled preventing users from modifying the min the Admin UI. This does not affect access control and fields can still be updated via GraphQL. ```javascript keystone.createList('Post', { From 5953b0b490ba349b0003dd29d3761314b7acd85a Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:27:09 +1000 Subject: [PATCH 10/19] Update packages/fields/README.md Co-authored-by: Jess Telford --- packages/fields/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fields/README.md b/packages/fields/README.md index 95dada96286..f3ab4bb20df 100644 --- a/packages/fields/README.md +++ b/packages/fields/README.md @@ -87,7 +87,7 @@ Additional field configs affecting field rendering or display in `admin-ui`. #### `adminConfig.isReadOnly` -Fields with `isReadOnly` set to `true` will be disabled preventing users from modifying the min the Admin UI. This does not affect access control and fields can still be updated via GraphQL. +Fields with `isReadOnly` set to `true` will be disabled preventing users from modifying them in the Admin UI. This does not affect access control and fields can still be updated via GraphQL. ```javascript keystone.createList('Post', { From 61b34fc4f16a003b4fe63b5b04f7d792ace7c14f Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:28:32 +1000 Subject: [PATCH 11/19] Update packages/fields/src/types/Checkbox/views/Field.js --- packages/fields/src/types/Checkbox/views/Field.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fields/src/types/Checkbox/views/Field.js b/packages/fields/src/types/Checkbox/views/Field.js index 8c71161de3a..28ae9990dbe 100644 --- a/packages/fields/src/types/Checkbox/views/Field.js +++ b/packages/fields/src/types/Checkbox/views/Field.js @@ -7,7 +7,6 @@ import { FieldLabel, FieldDescription, FieldInput, - isReadOnly, } from '@arch-ui/fields'; import { CheckboxPrimitive } from '@arch-ui/controls'; From f061c1831dada23b8614d97e6d00c1b7c4340e76 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:28:47 +1000 Subject: [PATCH 12/19] Update Field.js --- packages/fields/src/types/Checkbox/views/Field.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fields/src/types/Checkbox/views/Field.js b/packages/fields/src/types/Checkbox/views/Field.js index 28ae9990dbe..387d096e3a5 100644 --- a/packages/fields/src/types/Checkbox/views/Field.js +++ b/packages/fields/src/types/Checkbox/views/Field.js @@ -11,7 +11,7 @@ import { import { CheckboxPrimitive } from '@arch-ui/controls'; -const CheckboxField = ({ onChange, autoFocus, field, value, errors }) => { +const CheckboxField = ({ onChange, autoFocus, field, value, errors, isReadOnly }) => { const handleChange = event => { onChange(event.target.checked); }; From 8290d0270921c9508f0850bcdb8eb2c434ceb70a Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:40:30 +1000 Subject: [PATCH 13/19] Update .changeset/blue-ways-work.md Co-authored-by: Tim Leslie --- .changeset/blue-ways-work.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/blue-ways-work.md b/.changeset/blue-ways-work.md index 4af0cab90cb..538062945f8 100644 --- a/.changeset/blue-ways-work.md +++ b/.changeset/blue-ways-work.md @@ -7,7 +7,7 @@ '@keystonejs/cypress-project-access-control': patch --- -* Added `isReadOnly` option on field's `adminConfig`. This allows to show them as disabled in `admin-ui` item detail page. +* Added `isReadOnly` option on field's `adminConfig`. Fields with this option set will be excluded from the `create` form, and set as disabled in the `update` form in the Admin UI. * This PR also enables you to see the fields (disabled) in item detail page when you have no `update` access to field. example: @@ -27,4 +27,3 @@ keystone.createList('Todo', { }); ``` - From 5665c3af2a654a9339ba72d0148cece2b1d15d0e Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:40:38 +1000 Subject: [PATCH 14/19] Update .changeset/blue-ways-work.md Co-authored-by: Tim Leslie --- .changeset/blue-ways-work.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/blue-ways-work.md b/.changeset/blue-ways-work.md index 538062945f8..ea686ba5f50 100644 --- a/.changeset/blue-ways-work.md +++ b/.changeset/blue-ways-work.md @@ -10,7 +10,7 @@ * Added `isReadOnly` option on field's `adminConfig`. Fields with this option set will be excluded from the `create` form, and set as disabled in the `update` form in the Admin UI. * This PR also enables you to see the fields (disabled) in item detail page when you have no `update` access to field. -example: +Example: ```js keystone.createList('Todo', { @@ -26,4 +26,3 @@ keystone.createList('Todo', { }, }); ``` - From 9b32e5aa77752a2e02278e5f99c9b009b71a5c12 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 10:46:30 +1000 Subject: [PATCH 15/19] Update CreateItemModal.js I've done this in a way that I think ensure that the hooks for readonly fields will still be triggered... did I get that right? --- packages/app-admin-ui/client/components/CreateItemModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-admin-ui/client/components/CreateItemModal.js b/packages/app-admin-ui/client/components/CreateItemModal.js index dd141d6b854..b9141dd597f 100644 --- a/packages/app-admin-ui/client/components/CreateItemModal.js +++ b/packages/app-admin-ui/client/components/CreateItemModal.js @@ -192,6 +192,7 @@ const CreateItemModal = ({ prefillData = {}, onClose, onCreate }) => { {() => { const creatable = list.fields .filter(({ isPrimaryKey }) => !isPrimaryKey) + .filter(({ isReadOnly }) => !isReadOnly) // Remove read-only fields from the create dialog .filter(({ maybeAccess }) => !!maybeAccess.create); captureSuspensePromises(creatable.map(field => () => field.initFieldView())); @@ -222,7 +223,6 @@ const CreateItemModal = ({ prefillData = {}, onClose, onCreate }) => { warnings={validationWarnings[field.path] || []} onChange={onChange} renderContext="dialog" - isReadOnly={field.isReadOnly} /> ), [ From d7ff14303499347c9c09d03ba4962b79b82e1c41 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 11:08:50 +1000 Subject: [PATCH 16/19] Update CreateItemModal.js --- packages/app-admin-ui/client/components/CreateItemModal.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/app-admin-ui/client/components/CreateItemModal.js b/packages/app-admin-ui/client/components/CreateItemModal.js index b9141dd597f..224d55adcce 100644 --- a/packages/app-admin-ui/client/components/CreateItemModal.js +++ b/packages/app-admin-ui/client/components/CreateItemModal.js @@ -192,7 +192,8 @@ const CreateItemModal = ({ prefillData = {}, onClose, onCreate }) => { {() => { const creatable = list.fields .filter(({ isPrimaryKey }) => !isPrimaryKey) - .filter(({ isReadOnly }) => !isReadOnly) // Remove read-only fields from the create dialog + // Remove read-only fields from the create dialog + .filter(({ isReadOnly }) => !isReadOnly) .filter(({ maybeAccess }) => !!maybeAccess.create); captureSuspensePromises(creatable.map(field => () => field.initFieldView())); From f16795e4a4b718d2af2fc14fc358cdd01046b26f Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 11:11:20 +1000 Subject: [PATCH 17/19] Update .changeset/blue-ways-work.md Co-authored-by: Tim Leslie --- .changeset/blue-ways-work.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/blue-ways-work.md b/.changeset/blue-ways-work.md index ea686ba5f50..c5f9b61887a 100644 --- a/.changeset/blue-ways-work.md +++ b/.changeset/blue-ways-work.md @@ -8,7 +8,7 @@ --- * Added `isReadOnly` option on field's `adminConfig`. Fields with this option set will be excluded from the `create` form, and set as disabled in the `update` form in the Admin UI. -* This PR also enables you to see the fields (disabled) in item detail page when you have no `update` access to field. +* Updated the item detail page to include fields with access `{ update: false }` in a disabled state, rather than excluded the form. Example: From 689969ddfe300ec3aeab3ef86589c42042660b32 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 12:03:01 +1000 Subject: [PATCH 18/19] Update packages/app-admin-ui/client/components/CreateItemModal.js --- packages/app-admin-ui/client/components/CreateItemModal.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/app-admin-ui/client/components/CreateItemModal.js b/packages/app-admin-ui/client/components/CreateItemModal.js index 224d55adcce..cba8e0e7875 100644 --- a/packages/app-admin-ui/client/components/CreateItemModal.js +++ b/packages/app-admin-ui/client/components/CreateItemModal.js @@ -192,7 +192,6 @@ const CreateItemModal = ({ prefillData = {}, onClose, onCreate }) => { {() => { const creatable = list.fields .filter(({ isPrimaryKey }) => !isPrimaryKey) - // Remove read-only fields from the create dialog .filter(({ isReadOnly }) => !isReadOnly) .filter(({ maybeAccess }) => !!maybeAccess.create); From 1a6ff058721f2b1ceb42b3f7b3e960959fc3de4e Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 21 May 2020 12:13:12 +1000 Subject: [PATCH 19/19] prettier --- packages/fields/src/types/Checkbox/views/Field.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/fields/src/types/Checkbox/views/Field.js b/packages/fields/src/types/Checkbox/views/Field.js index 387d096e3a5..9f3f1af4682 100644 --- a/packages/fields/src/types/Checkbox/views/Field.js +++ b/packages/fields/src/types/Checkbox/views/Field.js @@ -2,12 +2,7 @@ import { jsx } from '@emotion/core'; -import { - FieldContainer, - FieldLabel, - FieldDescription, - FieldInput, -} from '@arch-ui/fields'; +import { FieldContainer, FieldLabel, FieldDescription, FieldInput } from '@arch-ui/fields'; import { CheckboxPrimitive } from '@arch-ui/controls';