diff --git a/client/src/pages/platform/workflow-editor/components/Properties/Property.tsx b/client/src/pages/platform/workflow-editor/components/Properties/Property.tsx index e60bcadbe72..90ac3c532f7 100644 --- a/client/src/pages/platform/workflow-editor/components/Properties/Property.tsx +++ b/client/src/pages/platform/workflow-editor/components/Properties/Property.tsx @@ -2,6 +2,7 @@ import {DEFAULT_SCHEMA} from '@/components/JsonSchemaBuilder/utils/constants'; import {SchemaRecordType} from '@/components/JsonSchemaBuilder/utils/types'; import RequiredMark from '@/components/RequiredMark'; import {Label} from '@/components/ui/label'; +import {Skeleton} from '@/components/ui/skeleton'; import {Tooltip, TooltipContent, TooltipTrigger} from '@/components/ui/tooltip'; import InputTypeSwitchButton from '@/pages/platform/workflow-editor/components/Properties/components/InputTypeSwitchButton'; import PropertyCodeEditor from '@/pages/platform/workflow-editor/components/Properties/components/PropertyCodeEditor/PropertyCodeEditor'; @@ -22,6 +23,7 @@ import deleteProperty from '@/pages/platform/workflow-editor/utils/deletePropert import getInputHTMLType from '@/pages/platform/workflow-editor/utils/getInputHTMLType'; import saveProperty from '@/pages/platform/workflow-editor/utils/saveProperty'; import {Option} from '@/shared/middleware/platform/configuration'; +import {useGetWorkflowNodeParameterDisplayConditionsQuery} from '@/shared/queries/platform/workflowNodeParameters.queries'; import {ArrayPropertyType, PropertyAllType} from '@/shared/types'; import {QuestionMarkCircledIcon} from '@radix-ui/react-icons'; import {TooltipPortal} from '@radix-ui/react-tooltip'; @@ -116,6 +118,15 @@ const Property = ({ const {showPropertyCodeEditorSheet, showPropertyJsonSchemaBuilder, showWorkflowCodeEditorSheet} = useWorkflowEditorStore(); + const {isFetching: isFetchingDisplayConditions} = useGetWorkflowNodeParameterDisplayConditionsQuery( + { + id: workflow.id!, + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + workflowNodeName: currentNode?.workflowNodeName!, + }, + !!currentNode?.workflowNodeName + ); + const previousOperationName = usePrevious(currentNode?.operationName); const defaultValue = property.defaultValue !== undefined ? property.defaultValue : ''; @@ -729,6 +740,16 @@ const Property = ({ return <>; } + if (displayCondition && currentComponent?.displayConditions?.[displayCondition] && isFetchingDisplayConditions) { + return ( +
+ + + +
+ ); + } + return (
  • { if (currentNodeDefinition?.properties) { @@ -528,7 +533,7 @@ const WorkflowNodeDetailsPanel = ({
    - {operationDataMissing && ( + {!!currentTaskDataOperations?.length && operationDataMissing && (
    Actions @@ -536,25 +541,23 @@ const WorkflowNodeDetailsPanel = ({
    )} - {(!!(currentTaskData as ComponentDefinition).actions?.length || - !!(currentTaskData as ComponentDefinition).triggers?.length) && - !operationDataMissing && ( - - )} + {currentTaskDataOperations && !operationDataMissing && ( + + )} {tabDataExists && (
    @@ -590,12 +593,28 @@ const WorkflowNodeDetailsPanel = ({
    {currentTaskData && (
    - {activeTab === 'description' && ( - - )} + {activeTab === 'description' && + (nodeDefinition ? ( + + ) : ( +
    +
    + + + +
    + +
    + + + +
    +
    + ))} {activeTab === 'dataStreamComponents' && } diff --git a/client/src/pages/platform/workflow-editor/components/node-details-tabs/DescriptionTab.tsx b/client/src/pages/platform/workflow-editor/components/node-details-tabs/DescriptionTab.tsx index 4492b3538a7..5738f91c5b2 100644 --- a/client/src/pages/platform/workflow-editor/components/node-details-tabs/DescriptionTab.tsx +++ b/client/src/pages/platform/workflow-editor/components/node-details-tabs/DescriptionTab.tsx @@ -3,37 +3,127 @@ import {Label} from '@/components/ui/label'; import {Textarea} from '@/components/ui/textarea'; import useWorkflowDataStore from '@/pages/platform/workflow-editor/stores/useWorkflowDataStore'; import useWorkflowNodeDetailsPanelStore from '@/pages/platform/workflow-editor/stores/useWorkflowNodeDetailsPanelStore'; -import {ComponentType, UpdateWorkflowMutationType} from '@/shared/types'; +import {WorkflowTask} from '@/shared/middleware/automation/configuration'; +import { + ComponentDefinition, + TaskDispatcherDefinition, + TriggerDefinition, +} from '@/shared/middleware/platform/configuration'; +import {NodeDataType, UpdateWorkflowMutationType} from '@/shared/types'; import {useQueryClient} from '@tanstack/react-query'; import {ChangeEvent} from 'react'; import {useDebouncedCallback} from 'use-debounce'; import saveWorkflowDefinition from '../../utils/saveWorkflowDefinition'; +import updateRootConditionNode from '../../utils/updateRootConditionNode'; -const DescriptionTab = ({updateWorkflowMutation}: {updateWorkflowMutation: UpdateWorkflowMutationType}) => { - const {workflow} = useWorkflowDataStore(); - const {currentComponent, currentNode, setCurrentComponent} = useWorkflowNodeDetailsPanelStore(); +const DescriptionTab = ({ + nodeDefinition, + updateWorkflowMutation, +}: { + nodeDefinition: ComponentDefinition | TaskDispatcherDefinition | TriggerDefinition; + updateWorkflowMutation: UpdateWorkflowMutationType; +}) => { + const {nodes, workflow} = useWorkflowDataStore(); + const {currentComponent, currentNode, setCurrentComponent, setCurrentNode} = useWorkflowNodeDetailsPanelStore(); const queryClient = useQueryClient(); - const componentData: ComponentType = { - ...currentComponent!, - workflowNodeName: currentNode!.workflowNodeName, + const updateNodeData = (value: string, field: 'label' | 'description'): NodeDataType | undefined => { + if (!currentNode) { + return; + } + + let nodeData = { + ...currentNode!, + [field]: value, + name: currentNode.workflowNodeName, + }; + + if (currentNode.conditionData) { + const parentConditionNode = nodes.find( + (node) => node.data.name === currentNode?.conditionData?.conditionId + ); + + if (!parentConditionNode) { + return; + } + + const conditionCase = currentNode.conditionData.conditionCase; + const conditionParameters: Array = parentConditionNode.data.parameters[conditionCase]; + + if (conditionParameters) { + const taskIndex = conditionParameters.findIndex((subtask) => subtask.name === currentNode.name); + + if (taskIndex !== -1) { + conditionParameters[taskIndex] = { + ...conditionParameters[taskIndex], + [field]: value, + }; + + if (!workflow.definition) { + return; + } + + const tasks = JSON.parse(workflow.definition).tasks; + + const updatedParentConditionTask = workflow.tasks?.find( + (task) => task.name === currentNode.conditionData?.conditionId + ); + + if (!updatedParentConditionTask) { + return; + } + + nodeData = updateRootConditionNode({ + conditionCase, + conditionId: currentNode.conditionData.conditionId, + nodeIndex: taskIndex, + nodes, + tasks, + updatedParentConditionNodeData: parentConditionNode.data, + updatedParentConditionTask, + workflow, + }); + } + } + } + + return nodeData; }; const handleLabelChange = useDebouncedCallback((event: ChangeEvent) => { - if (!currentComponent || !currentNode) { + if (!currentNode) { return; } + let nodeData: NodeDataType = { + ...currentNode, + label: event.target.value, + name: currentNode.workflowNodeName, + version: 'version' in nodeDefinition ? nodeDefinition.version : 1, + }; + + if (currentNode.conditionData) { + nodeData = updateNodeData(event.target.value, 'label') ?? nodeData; + } + saveWorkflowDefinition({ decorative: true, - nodeData: {...currentComponent!, label: event.target.value, name: currentComponent.workflowNodeName}, - onSuccess: () => + nodeData, + onSuccess: () => { setCurrentComponent({ ...currentComponent, + componentName: currentNode.componentName, + label: event.target.value, + workflowNodeName: currentNode.workflowNodeName, + }); + + setCurrentNode({ + ...currentNode, label: event.target.value, - }), + }); + }, queryClient, updateWorkflowMutation, workflow, @@ -41,18 +131,37 @@ const DescriptionTab = ({updateWorkflowMutation}: {updateWorkflowMutation: Updat }, 200); const handleNotesChange = useDebouncedCallback((event: ChangeEvent) => { - if (!currentComponent || !currentNode) { + if (!currentNode) { return; } + let nodeData: NodeDataType = { + ...currentNode, + description: event.target.value, + name: currentNode.workflowNodeName, + version: 'version' in nodeDefinition ? nodeDefinition.version : 1, + }; + + if (currentNode.conditionData) { + nodeData = updateNodeData(event.target.value, 'description') ?? nodeData; + } + saveWorkflowDefinition({ decorative: true, - nodeData: {...componentData, description: event.target.value, name: currentComponent.workflowNodeName}, - onSuccess: () => + nodeData, + onSuccess: () => { setCurrentComponent({ ...currentComponent, + componentName: currentNode.componentName, + description: event.target.value, + workflowNodeName: currentNode.workflowNodeName, + }); + + setCurrentNode({ + ...currentNode, description: event.target.value, - }), + }); + }, queryClient, updateWorkflowMutation, workflow, @@ -65,8 +174,8 @@ const DescriptionTab = ({updateWorkflowMutation}: {updateWorkflowMutation: Updat @@ -76,8 +185,8 @@ const DescriptionTab = ({updateWorkflowMutation}: {updateWorkflowMutation: Updat