From 5cf41d97deb8b8a038b38f9cd5ff2399c40eb569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20Collin=20L=C3=B8kken?= Date: Tue, 12 Sep 2023 08:47:46 +0200 Subject: [PATCH] fix: disables all edit form buttons when in readOnly mode --- .../plugins/form/read_only/car.recipe.json | 25 +++++- .../read_only/carRentalCompany.recipe.json | 15 +++- .../form/read_only/customer.recipe.json | 27 ++++++- .../blueprints/form/FormInput.json | 8 -- .../blueprints/list/ListPluginConfig.json | 7 ++ .../src/form/components/AttributeList.tsx | 10 +-- .../src/form/components/Form.tsx | 16 ++-- .../src/form/fields/ArrayField.tsx | 48 +++++------ .../src/form/fields/AttributeField.tsx | 1 + .../src/form/fields/ObjectField.tsx | 45 ++++++++--- packages/dm-core-plugins/src/form/types.tsx | 1 - .../dm-core-plugins/src/list/ListPlugin.tsx | 79 ++++++++++--------- .../dm-core/src/components/EntityView.tsx | 1 - .../components/Pickers/EntityPickerButton.tsx | 12 ++- 14 files changed, 192 insertions(+), 103 deletions(-) diff --git a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/car.recipe.json b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/car.recipe.json index 06d0c69fb..3d8e4af33 100644 --- a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/car.recipe.json +++ b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/car.recipe.json @@ -17,5 +17,28 @@ ], "readOnly": true } - } + }, + "uiRecipes": [ + { + "name": "MyCustomList", + "type": "dmss://system/SIMOS/UiRecipe", + "description": "", + "plugin": "@development-framework/dm-core-plugins/list", + "dimensions": "*", + "config": { + "type": "PLUGINS:dm-core-plugins/list/ListPluginConfig", + "views": [], + "headers": [ + "name", + "plateNumber" + ], + "openInline": false, + "functionality": { + "type": "PLUGINS:dm-core-plugins/list/FunctionalityConfig", + "delete": true + }, + "readOnly": true + } + } + ] } diff --git a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/carRentalCompany.recipe.json b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/carRentalCompany.recipe.json index 78e1a24a4..e6bab181b 100644 --- a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/carRentalCompany.recipe.json +++ b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/carRentalCompany.recipe.json @@ -35,6 +35,12 @@ "showInline": false, "uiRecipe": "defaultForm" }, + { + "name": "ceo", + "type": "PLUGINS:dm-core-plugins/form/fields/ObjectField", + "showInline": false, + "uiRecipe": "defaultForm" + }, { "name": "trainee", "type": "PLUGINS:dm-core-plugins/form/fields/ObjectField", @@ -56,6 +62,12 @@ "name": "locations", "type": "PLUGINS:dm-core-plugins/form/fields/ArrayField", "showInline": true + }, + { + "name": "customers", + "type": "PLUGINS:dm-core-plugins/form/fields/ArrayField", + "showInline": false, + "uiRecipe": "myCustomArrayRecipe" } ], "fields": [ @@ -68,8 +80,7 @@ "customers", "isBankrupt" ], - "readOnly": true, - "editToggle": true + "readOnly": true } } ] diff --git a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/customer.recipe.json b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/customer.recipe.json index 0765180b6..8e49b3d9a 100644 --- a/example/app/data/DemoDataSource/recipes/plugins/form/read_only/customer.recipe.json +++ b/example/app/data/DemoDataSource/recipes/plugins/form/read_only/customer.recipe.json @@ -4,7 +4,11 @@ "initialUiRecipe": { "name": "form", "type": "CORE:UiRecipe", - "plugin": "@development-framework/dm-core-plugins/form" + "plugin": "@development-framework/dm-core-plugins/form", + "config": { + "type": "PLUGINS:dm-core-plugins/form/FormInput", + "readOnly": true + } }, "uiRecipes": [ { @@ -18,6 +22,27 @@ "type": "CORE:UiRecipe", "plugin": "@development-framework/dm-core-plugins/form", "category": "edit" + }, + { + "name": "myCustomArrayRecipe", + "type": "dmss://system/SIMOS/UiRecipe", + "description": "", + "plugin": "@development-framework/dm-core-plugins/list", + "dimensions": "*", + "config": { + "type": "PLUGINS:dm-core-plugins/list/ListPluginConfig", + "views": [], + "headers": [ + "name", + "plateNumber" + ], + "openInline": false, + "functionality": { + "type": "PLUGINS:dm-core-plugins/list/FunctionalityConfig", + "delete": true + }, + "readOnly": true + } } ] } diff --git a/packages/dm-core-plugins/blueprints/form/FormInput.json b/packages/dm-core-plugins/blueprints/form/FormInput.json index 65ff1c3ac..e52dd14fc 100644 --- a/packages/dm-core-plugins/blueprints/form/FormInput.json +++ b/packages/dm-core-plugins/blueprints/form/FormInput.json @@ -32,14 +32,6 @@ "optional": true, "contained": true, "default": false - }, - { - "name": "editToggle", - "type": "dmss://system/SIMOS/BlueprintAttribute", - "attributeType": "boolean", - "optional": true, - "contained": true, - "default": false } ] } diff --git a/packages/dm-core-plugins/blueprints/list/ListPluginConfig.json b/packages/dm-core-plugins/blueprints/list/ListPluginConfig.json index c85f1acab..21f21e811 100644 --- a/packages/dm-core-plugins/blueprints/list/ListPluginConfig.json +++ b/packages/dm-core-plugins/blueprints/list/ListPluginConfig.json @@ -52,6 +52,13 @@ "dimensions": "*", "default": [], "optional": false + }, + { + "name": "readOnly", + "type": "CORE:BlueprintAttribute", + "attributeType": "boolean", + "optional": true, + "default": false } ] } diff --git a/packages/dm-core-plugins/src/form/components/AttributeList.tsx b/packages/dm-core-plugins/src/form/components/AttributeList.tsx index 7caff51bd..42798f730 100644 --- a/packages/dm-core-plugins/src/form/components/AttributeList.tsx +++ b/packages/dm-core-plugins/src/form/components/AttributeList.tsx @@ -2,7 +2,6 @@ import { Stack, TAttribute, TBlueprint } from '@development-framework/dm-core' import React, { useState } from 'react' import { AttributeField } from '../fields/AttributeField' import { TConfig } from '../types' -import { Button } from '@equinor/eds-core-react' export const AttributeList = (props: { namePath: string @@ -49,12 +48,5 @@ export const AttributeList = (props: { ) }) - return ( - - {config?.editToggle && ( - - )} - {attributeFields} - - ) + return {attributeFields} } diff --git a/packages/dm-core-plugins/src/form/components/Form.tsx b/packages/dm-core-plugins/src/form/components/Form.tsx index f778f1f32..40cc32da4 100644 --- a/packages/dm-core-plugins/src/form/components/Form.tsx +++ b/packages/dm-core-plugins/src/form/components/Form.tsx @@ -54,13 +54,15 @@ export const Form = (props: TFormProps) => { config={config} blueprint={blueprint} /> - + {!config?.readOnly && ( + + )} diff --git a/packages/dm-core-plugins/src/form/fields/ArrayField.tsx b/packages/dm-core-plugins/src/form/fields/ArrayField.tsx index c9ee29c54..168c124be 100644 --- a/packages/dm-core-plugins/src/form/fields/ArrayField.tsx +++ b/packages/dm-core-plugins/src/form/fields/ArrayField.tsx @@ -111,32 +111,34 @@ export default function ArrayField(props: TArrayFieldProps) { readOnly={readOnly} /> - + {!readOnly && ( + + )} ) })} - + {!readOnly && ( + + )} ) } diff --git a/packages/dm-core-plugins/src/form/fields/AttributeField.tsx b/packages/dm-core-plugins/src/form/fields/AttributeField.tsx index 662323ecd..644edcb62 100644 --- a/packages/dm-core-plugins/src/form/fields/AttributeField.tsx +++ b/packages/dm-core-plugins/src/form/fields/AttributeField.tsx @@ -65,6 +65,7 @@ export const AttributeField = (props: TAttributeFieldProps) => { optional={attribute.optional ?? false} uiAttribute={uiAttribute} defaultValue={attribute.default} + readOnly={readOnly} /> ) diff --git a/packages/dm-core-plugins/src/form/fields/ObjectField.tsx b/packages/dm-core-plugins/src/form/fields/ObjectField.tsx index 855181e61..b017037ed 100644 --- a/packages/dm-core-plugins/src/form/fields/ObjectField.tsx +++ b/packages/dm-core-plugins/src/form/fields/ObjectField.tsx @@ -24,8 +24,13 @@ import { OpenObjectButton } from '../components/OpenObjectButton' import { useRegistryContext } from '../context/RegistryContext' import { getWidget } from '../context/WidgetContext' import { TContentProps, TObjectFieldProps, TUiRecipeForm } from '../types' +import * as readline from 'readline' -const SelectReference = (props: { type: string; namePath: string }) => { +const SelectReference = (props: { + type: string + namePath: string + disabled?: boolean +}) => { const { setValue, watch } = useFormContext() const dmssAPI = useDMSS() const { idReference } = useRegistryContext() @@ -78,8 +83,9 @@ const AddObject = (props: { type: string namePath: string defaultValue: any + disabled?: boolean }) => { - const { type, namePath, defaultValue } = props + const { type, namePath, defaultValue, disabled } = props const { setValue } = useFormContext() const dmssAPI = useDMSS() const { idReference } = useRegistryContext() @@ -118,14 +124,15 @@ const AddObject = (props: { variant="outlined" data-testid={`add-${namePath}`} onClick={handleAdd} + disabled={disabled} > Add and save ) } -const RemoveObject = (props: { namePath: string }) => { - const { namePath } = props +const RemoveObject = (props: { namePath: string; disabled?: boolean }) => { + const { namePath, disabled } = props const { setValue } = useFormContext() const { idReference } = useRegistryContext() const dmssAPI = useDMSS() @@ -151,6 +158,7 @@ const RemoveObject = (props: { namePath: string }) => { variant="outlined" data-testid={`remove-${namePath}`} onClick={onClick} + disabled={disabled} > Remove and save @@ -167,23 +175,25 @@ export const ContainedAttribute = (props: TContentProps): JSX.Element => { uiRecipe, blueprint, defaultValue, + readOnly, } = props const { watch } = useFormContext() const { idReference, onOpen } = useRegistryContext() const value = watch(namePath) const isDefined = value && Object.keys(value).length > 0 - return ( {displayLabel} {optional && + !readOnly && (isDefined ? ( - + ) : ( ))} {isDefined && @@ -247,8 +257,15 @@ const Indent = styled.div` ` export const UncontainedAttribute = (props: TContentProps): JSX.Element => { - const { type, namePath, displayLabel, uiAttribute, uiRecipe, optional } = - props + const { + type, + namePath, + displayLabel, + uiAttribute, + uiRecipe, + optional, + readOnly, + } = props const { watch } = useFormContext() const { idReference, onOpen } = useRegistryContext() const value = watch(namePath) @@ -263,8 +280,10 @@ export const UncontainedAttribute = (props: TContentProps): JSX.Element => { {displayLabel} {address && Address: {value.address}} - - {optional && address && } + {!readOnly && } + {optional && address && !readOnly && ( + + )} {address && onOpen && !uiAttribute?.showInline && ( { } export const ObjectField = (props: TObjectFieldProps): JSX.Element => { - const { type, namePath, uiAttribute, displayLabel, defaultValue } = props + const { type, namePath, uiAttribute, displayLabel, defaultValue, readOnly } = + props const { getValues } = useFormContext() // Be able to override the object field @@ -308,6 +328,7 @@ export const ObjectField = (props: TObjectFieldProps): JSX.Element => { label={displayLabel} type={type === 'object' && values ? values.type : type} defaultValue={defaultValue} + readOnly={readOnly} /> ) } @@ -321,6 +342,7 @@ export const ObjectTypeSelector = (props: TObjectFieldProps): JSX.Element => { contained, uiAttribute, defaultValue, + readOnly, } = props const { blueprint, uiRecipes, isLoading, error } = useBlueprint(type) @@ -345,6 +367,7 @@ export const ObjectTypeSelector = (props: TObjectFieldProps): JSX.Element => { uiRecipe={uiRecipe} uiAttribute={uiAttribute} defaultValue={defaultValue} + readOnly={readOnly} /> ) } diff --git a/packages/dm-core-plugins/src/form/types.tsx b/packages/dm-core-plugins/src/form/types.tsx index f4155f954..acd9142a7 100644 --- a/packages/dm-core-plugins/src/form/types.tsx +++ b/packages/dm-core-plugins/src/form/types.tsx @@ -99,7 +99,6 @@ export type TConfig = { attributes: TAttributeConfig[] fields: string[] readOnly?: boolean - editToggle?: boolean } export type TUiRecipeForm = Omit & { config: TConfig } diff --git a/packages/dm-core-plugins/src/list/ListPlugin.tsx b/packages/dm-core-plugins/src/list/ListPlugin.tsx index dcc824aa7..17d452b5f 100644 --- a/packages/dm-core-plugins/src/list/ListPlugin.tsx +++ b/packages/dm-core-plugins/src/list/ListPlugin.tsx @@ -30,6 +30,7 @@ type TListConfig = { sort: boolean delete: boolean } + readOnly: boolean } const defaultConfig: TListConfig = { expanded: false, @@ -44,6 +45,7 @@ const defaultConfig: TListConfig = { sort: false, delete: false, }, + readOnly: false, } type ItemRow = { @@ -227,35 +229,36 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => { )} - {internalConfig?.functionality?.delete && ( - <> - { - setItems(moveItem(items, item.key, 'up')) - setUnsavedChanges(true) - }} - type="up" - /> - { - setItems(moveItem(items, item.key, 'down')) - setUnsavedChanges(true) - }} - /> - - deleteItem(`${idReference}[${item.index}]`, item.key) - } - /> - - )} + {internalConfig?.functionality?.delete && + !internalConfig.readOnly && ( + <> + { + setItems(moveItem(items, item.key, 'up')) + setUnsavedChanges(true) + }} + type="up" + /> + { + setItems(moveItem(items, item.key, 'down')) + setUnsavedChanges(true) + }} + /> + + deleteItem(`${idReference}[${item.index}]`, item.key) + } + /> + + )} @@ -284,14 +287,16 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => { rowsPerPage={paginationRowsPerPage} setRowsPerPage={setPaginationRowsPerPage} /> - - addItem()} /> - - + {!internalConfig.readOnly && ( + + addItem()} /> + + + )} ) diff --git a/packages/dm-core/src/components/EntityView.tsx b/packages/dm-core/src/components/EntityView.tsx index 687fb58b3..c862fcf12 100644 --- a/packages/dm-core/src/components/EntityView.tsx +++ b/packages/dm-core/src/components/EntityView.tsx @@ -26,7 +26,6 @@ export const EntityView = (props: IEntityView): JSX.Element => { recipeName, dimensions ) - if (isLoading) return (
diff --git a/packages/dm-core/src/components/Pickers/EntityPickerButton.tsx b/packages/dm-core/src/components/Pickers/EntityPickerButton.tsx index 535d9ea29..4d4706972 100644 --- a/packages/dm-core/src/components/Pickers/EntityPickerButton.tsx +++ b/packages/dm-core/src/components/Pickers/EntityPickerButton.tsx @@ -32,9 +32,16 @@ export const EntityPickerButton = (props: { alternativeButtonText?: string buttonVariant?: 'contained' | 'outlined' | 'ghost' | 'ghost_icon' scope?: string + disabled?: boolean }) => { - const { onChange, typeFilter, alternativeButtonText, buttonVariant, scope } = - props + const { + onChange, + typeFilter, + alternativeButtonText, + buttonVariant, + scope, + disabled, + } = props const appConfig = useContext(ApplicationContext) const [showModal, setShowModal] = useState(false) const [loading, setLoading] = useState(true) @@ -81,6 +88,7 @@ export const EntityPickerButton = (props: {