Skip to content

Commit

Permalink
fix: disables all edit form buttons when in readOnly mode
Browse files Browse the repository at this point in the history
  • Loading branch information
collinlokken committed Sep 12, 2023
1 parent c72d62a commit f0fe0b3
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
"dimensions": "*",
"default": [],
"optional": false
},
{
"name": "readOnly",
"type": "CORE:BlueprintAttribute",
"attributeType": "boolean",
"optional": true,
"default": false
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const AttributeField = (props: TAttributeFieldProps) => {
optional={attribute.optional ?? false}
uiAttribute={uiAttribute}
defaultValue={attribute.default}
readOnly={readOnly}
/>
)

Expand Down
45 changes: 34 additions & 11 deletions packages/dm-core-plugins/src/form/fields/ObjectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -70,6 +75,7 @@ const SelectReference = (props: { type: string; namePath: string }) => {
buttonVariant="outlined"
typeFilter={props.type}
alternativeButtonText="Select and save"
disabled={props.disabled}
/>
)
}
Expand All @@ -78,8 +84,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()
Expand Down Expand Up @@ -118,14 +125,15 @@ const AddObject = (props: {
variant="outlined"
data-testid={`add-${namePath}`}
onClick={handleAdd}
disabled={disabled}
>
Add and save
</Button>
)
}

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()
Expand All @@ -151,6 +159,7 @@ const RemoveObject = (props: { namePath: string }) => {
variant="outlined"
data-testid={`remove-${namePath}`}
onClick={onClick}
disabled={disabled}
>
Remove and save
</Button>
Expand All @@ -167,23 +176,24 @@ 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 (
<Stack spacing={0.25} alignItems="flex-start">
<Typography bold={true}>{displayLabel}</Typography>
{optional &&
(isDefined ? (
<RemoveObject namePath={namePath} />
<RemoveObject namePath={namePath} disabled={readOnly} />
) : (
<AddObject
namePath={namePath}
type={type}
defaultValue={defaultValue}
disabled={readOnly}
/>
))}
{isDefined &&
Expand Down Expand Up @@ -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)
Expand All @@ -263,8 +280,10 @@ export const UncontainedAttribute = (props: TContentProps): JSX.Element => {
<Typography bold={true}>{displayLabel}</Typography>
{address && <Typography>Address: {value.address}</Typography>}
<Stack direction="row" spacing={0.5}>
<SelectReference type={type} namePath={namePath} />
{optional && address && <RemoveObject namePath={namePath} />}
<SelectReference type={type} namePath={namePath} disabled={readOnly} />
{optional && address && (
<RemoveObject namePath={namePath} disabled={readOnly} />
)}
{address && onOpen && !uiAttribute?.showInline && (
<OpenObjectButton
viewId={namePath}
Expand All @@ -290,7 +309,8 @@ export const UncontainedAttribute = (props: TContentProps): JSX.Element => {
}

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
Expand All @@ -308,6 +328,7 @@ export const ObjectField = (props: TObjectFieldProps): JSX.Element => {
label={displayLabel}
type={type === 'object' && values ? values.type : type}
defaultValue={defaultValue}
readOnly={readOnly}
/>
)
}
Expand All @@ -321,6 +342,7 @@ export const ObjectTypeSelector = (props: TObjectFieldProps): JSX.Element => {
contained,
uiAttribute,
defaultValue,
readOnly,
} = props

const { blueprint, uiRecipes, isLoading, error } = useBlueprint(type)
Expand All @@ -345,6 +367,7 @@ export const ObjectTypeSelector = (props: TObjectFieldProps): JSX.Element => {
uiRecipe={uiRecipe}
uiAttribute={uiAttribute}
defaultValue={defaultValue}
readOnly={readOnly}
/>
)
}
3 changes: 2 additions & 1 deletion packages/dm-core-plugins/src/list/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {

export const AppendButton = (props: {
onClick: (event: MouseEvent<HTMLButtonElement>) => void
disabled: boolean
}) => (
<Button variant="outlined" onClick={props.onClick}>
<Button variant="outlined" onClick={props.onClick} disabled={props.disabled}>
<Icon data={add} title="Append" /> Add Item
</Button>
)
Expand Down
13 changes: 10 additions & 3 deletions packages/dm-core-plugins/src/list/ListPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type TListConfig = {
sort: boolean
delete: boolean
}
readOnly: boolean
}
const defaultConfig: TListConfig = {
expanded: false,
Expand All @@ -44,6 +45,7 @@ const defaultConfig: TListConfig = {
sort: false,
delete: false,
},
readOnly: false,
}

type ItemRow = {
Expand Down Expand Up @@ -230,7 +232,7 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
{internalConfig?.functionality?.delete && (
<>
<ListItemButton
disabled={index === 0}
disabled={index === 0 || internalConfig.readOnly}
onClick={() => {
setItems(moveItem(items, item.key, 'up'))
setUnsavedChanges(true)
Expand All @@ -241,7 +243,8 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
type="down"
disabled={
index === paginationRowsPerPage - 1 ||
index === items?.length - 1
index === items?.length - 1 ||
internalConfig.readOnly
}
onClick={() => {
setItems(moveItem(items, item.key, 'down'))
Expand All @@ -253,6 +256,7 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
onClick={() =>
deleteItem(`${idReference}[${item.index}]`, item.key)
}
disabled={internalConfig.readOnly}
/>
</>
)}
Expand Down Expand Up @@ -285,7 +289,10 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
setRowsPerPage={setPaginationRowsPerPage}
/>
<Stack direction="row" spacing={1}>
<AppendButton onClick={() => addItem()} />
<AppendButton
onClick={() => addItem()}
disabled={internalConfig.readOnly}
/>
<SaveButton
onClick={save}
disabled={!unsavedChanges}
Expand Down
2 changes: 1 addition & 1 deletion packages/dm-core/src/components/EntityView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const EntityView = (props: IEntityView): JSX.Element => {
recipeName,
dimensions
)

console.log(type, recipeName, recipe)
if (isLoading)
return (
<div style={{ alignSelf: 'center', padding: '50px' }}>
Expand Down
12 changes: 10 additions & 2 deletions packages/dm-core/src/components/Pickers/EntityPickerButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>(false)
const [loading, setLoading] = useState<boolean>(true)
Expand Down Expand Up @@ -81,6 +88,7 @@ export const EntityPickerButton = (props: {
<Button
variant={buttonVariant || 'contained'}
onClick={() => setShowModal(true)}
disabled={disabled}
>
{alternativeButtonText || 'Select'}
</Button>
Expand Down

0 comments on commit f0fe0b3

Please sign in to comment.