diff --git a/.changeset/sdk-readonly-not-overridden-by-rule.md b/.changeset/sdk-readonly-not-overridden-by-rule.md new file mode 100644 index 000000000..b8efc88ec --- /dev/null +++ b/.changeset/sdk-readonly-not-overridden-by-rule.md @@ -0,0 +1,5 @@ +--- +'@workflowbuilder/sdk': minor +--- + +Form-wide readonly mode is no longer overridden by a local uischema `rule`. Every JSON Form control now stays non-editable while `config.readonly` is `true`, even when a rule with an `ENABLE` effect applies to it. diff --git a/packages/sdk/src/features/json-form/controls/ai-tools-control/ai-tools-control.tsx b/packages/sdk/src/features/json-form/controls/ai-tools-control/ai-tools-control.tsx index cc11d8182..54db3c0b4 100644 --- a/packages/sdk/src/features/json-form/controls/ai-tools-control/ai-tools-control.tsx +++ b/packages/sdk/src/features/json-form/controls/ai-tools-control/ai-tools-control.tsx @@ -9,15 +9,19 @@ import styles from './ai-tools-control.module.css'; import { FormControlWithLabel } from '../../../../components/form/form-control-with-label/form-control-with-label'; import { closeModal } from '../../../modals/stores/use-modal-store'; +import { useIsControlEditable } from '../../hooks/use-is-control-editable'; import type { AiAgentTool, AiToolsControlProps } from '../../types/controls'; import { createControlRenderer } from '../../utils/rendering'; import { createAiTool, hasAnyValue } from './create-ai-tool'; import { openAddToolModal } from './open-add-tool-modal'; import { toolOptions } from './select-options'; -function AiToolsControl({ path, handleChange, data, enabled, uischema }: AiToolsControlProps) { +function AiToolsControl(props: AiToolsControlProps) { + const { path, handleChange, data } = props; + const isEditable = useIsControlEditable(props); + const { t } = useTranslation(undefined, { keyPrefix: 'aiTools' }); - const isDisabled = !enabled || uischema.disabled === true; + const handleSubmit = useCallback( (change: AiAgentTool) => { if (hasAnyValue(change)) { @@ -61,7 +65,7 @@ function AiToolsControl({ path, handleChange, data, enabled, uischema }: AiTools variant: 'secondary', className: styles['selected-tool-button'], onClick: () => openEditorModal(toolData), - disabled: isDisabled, + disabled: !isEditable, }; return ( @@ -75,14 +79,14 @@ function AiToolsControl({ path, handleChange, data, enabled, uischema }: AiTools ) : ( )} - onRemoveTool(toolData.id)} disabled={isDisabled}> + onRemoveTool(toolData.id)} disabled={!isEditable}> ); })} - diff --git a/packages/sdk/src/features/json-form/controls/date-picker-control/date-picker-control.tsx b/packages/sdk/src/features/json-form/controls/date-picker-control/date-picker-control.tsx index 5ec0260da..3a3c0d689 100644 --- a/packages/sdk/src/features/json-form/controls/date-picker-control/date-picker-control.tsx +++ b/packages/sdk/src/features/json-form/controls/date-picker-control/date-picker-control.tsx @@ -1,12 +1,13 @@ import { DatePicker, type DatePickerProps } from '@workflowbuilder/ui'; +import { useIsControlEditable } from '../../hooks/use-is-control-editable'; import type { DatePickerControlProps } from '../../types/controls'; import { createControlRenderer } from '../../utils/rendering'; import { ControlWrapper } from '../control-wrapper'; function DatePickerControl(props: DatePickerControlProps) { - const { data, handleChange, path, enabled, uischema } = props; - const isDisabled = !enabled || uischema.disabled === true; + const { data, handleChange, path } = props; + const isEditable = useIsControlEditable(props); const onChange: DatePickerProps['onChange'] = (value) => { handleChange(path, value?.toString()); @@ -14,7 +15,7 @@ function DatePickerControl(props: DatePickerControlProps) { return ( - + ); } diff --git a/packages/sdk/src/features/json-form/controls/decision-branches-control/decision-branches-control.tsx b/packages/sdk/src/features/json-form/controls/decision-branches-control/decision-branches-control.tsx index b0616ccc2..585fc15fa 100644 --- a/packages/sdk/src/features/json-form/controls/decision-branches-control/decision-branches-control.tsx +++ b/packages/sdk/src/features/json-form/controls/decision-branches-control/decision-branches-control.tsx @@ -4,14 +4,15 @@ import { useTranslation } from 'react-i18next'; import styles from './decision-branches-control.module.css'; import { PlaceholderButton } from '../../../diagram/nodes/components/placeholder-button/placeholder-button'; +import { useIsControlEditable } from '../../hooks/use-is-control-editable'; import type { DecisionBranch, DecisionBranchesControlProps } from '../../types/controls'; import { createControlRenderer } from '../../utils/rendering'; import { BranchCard } from './branch-card/branch-card'; import { createDecisionBranch } from './create-decision-branch'; function DecisionBranchesControl(props: DecisionBranchesControlProps) { - const { data = [], handleChange, path, enabled, uischema } = props; - const isDisabled = !enabled || uischema.disabled === true; + const { data = [], handleChange, path } = props; + const isEditable = useIsControlEditable(props); const decisionBranches = data as DecisionBranch[]; @@ -33,7 +34,7 @@ function DecisionBranchesControl(props: DecisionBranchesControlProps) { } function onAddBranch() { - if (isDisabled) { + if (!isEditable) { return; } handleChange(path, [...decisionBranches, createDecisionBranch()]); @@ -48,7 +49,7 @@ function DecisionBranchesControl(props: DecisionBranchesControlProps) { branch={branch} onUpdate={onUpdateBranch} onRemove={onRemoveBranch} - enabled={!isDisabled} + enabled={isEditable} /> ))} diff --git a/packages/sdk/src/features/json-form/controls/dynamic-conditions-control/dynamic-conditions-control.tsx b/packages/sdk/src/features/json-form/controls/dynamic-conditions-control/dynamic-conditions-control.tsx index ef6327bab..20877234e 100644 --- a/packages/sdk/src/features/json-form/controls/dynamic-conditions-control/dynamic-conditions-control.tsx +++ b/packages/sdk/src/features/json-form/controls/dynamic-conditions-control/dynamic-conditions-control.tsx @@ -8,6 +8,7 @@ import { Icon } from '@workflow-builder/icons'; import styles from './dynamic-conditions-control.module.css'; import { closeModal, openModal } from '../../../modals/stores/use-modal-store'; +import { useIsControlEditable } from '../../hooks/use-is-control-editable'; import type { DynamicCondition, DynamicConditionsControlProps } from '../../types/controls'; import { createControlRenderer } from '../../utils/rendering'; import { Dependencies } from './dependencies/dependencies'; @@ -15,8 +16,8 @@ import { ConditionModalFooter } from './dynamic-condition-modal-footer/condition import { ConditionsForm, type ConditionsFormHandle } from './dynamic-conditions-form/conditions-form'; function DynamicConditionsControl(props: DynamicConditionsControlProps) { - const { data = [], handleChange, path, enabled, uischema } = props; - const isDisabled = !enabled || uischema.disabled === true; + const { data = [], handleChange, path } = props; + const isEditable = useIsControlEditable(props); const formRef = useRef(null); const { t } = useTranslation(undefined, { keyPrefix: 'conditions' }); @@ -44,11 +45,11 @@ function DynamicConditionsControl(props: DynamicConditionsControlProps) {
{t('title')} - +
- + {t('totalNumber', { count: data.length })}
); diff --git a/packages/sdk/src/features/json-form/controls/select-control/select-control.tsx b/packages/sdk/src/features/json-form/controls/select-control/select-control.tsx index cdf1df0b0..c8ecad527 100644 --- a/packages/sdk/src/features/json-form/controls/select-control/select-control.tsx +++ b/packages/sdk/src/features/json-form/controls/select-control/select-control.tsx @@ -3,13 +3,14 @@ import { Select, type SelectBaseProps } from '@workflowbuilder/ui'; import { Icon } from '@workflow-builder/icons'; import type { PrimitiveFieldSchema } from '../../../../node/node-schema'; +import { useIsControlEditable } from '../../hooks/use-is-control-editable'; import type { SelectControlProps } from '../../types/controls'; import { createControlRenderer } from '../../utils/rendering'; import { ControlWrapper } from '../control-wrapper'; function SelectControl(props: SelectControlProps) { - const { data, handleChange, path, enabled, schema, uischema } = props; - const isDisabled = !enabled || uischema.disabled === true; + const { data, handleChange, path, schema } = props; + const isEditable = useIsControlEditable(props); const items = (schema as PrimitiveFieldSchema).options?.map((option) => option.type === 'separator' || !option.icon @@ -29,7 +30,7 @@ function SelectControl(props: SelectControlProps) {