+ @if (deleteConfirmOpen) {
+
+ }
diff --git a/src/app/shared/nodes/container-node/container-node.ts b/src/app/shared/nodes/container-node/container-node.ts
index dc91681..baea90e 100644
--- a/src/app/shared/nodes/container-node/container-node.ts
+++ b/src/app/shared/nodes/container-node/container-node.ts
@@ -20,6 +20,7 @@ import { CONTAINER_SUBFLOW_DRAG_MIME } from './container-node-drag';
export class ContainerNodeComponent {
private editorState = inject(EditorStateHolder);
private subflowPreview = inject(SubflowPreviewDialogService);
+ deleteConfirmOpen = false;
@Input() data!: any;
@Input() emit!: (data: any) => void;
@@ -112,6 +113,24 @@ export class ContainerNodeComponent {
return this.data?.data?.['__containerAssigning'] === true;
}
+ get missingRequiredParams() {
+ const missing: string[] = [];
+ if (!this.name.trim()) {
+ missing.push('Name');
+ }
+ if (!this.subFlow) {
+ missing.push('Sub Flow');
+ }
+ const config = this.configuration ?? {};
+ if (!Array.isArray(config['publicInputs'])) {
+ missing.push('Public Inputs');
+ }
+ if (!Array.isArray(config['publicOutputs'])) {
+ missing.push('Public Outputs');
+ }
+ return missing;
+ }
+
inputDisplayLabel(inputKey: string) {
return pathToLabel(inputKey);
}
@@ -168,6 +187,10 @@ export class ContainerNodeComponent {
deleteNode(event?: Event) {
event?.preventDefault();
event?.stopPropagation();
+ if (!this.deleteConfirmOpen) {
+ this.deleteConfirmOpen = true;
+ return;
+ }
const remove = this.data?.data?.deleteNode;
if (typeof remove === 'function') {
@@ -175,6 +198,12 @@ export class ContainerNodeComponent {
}
}
+ cancelDelete(event?: Event) {
+ event?.preventDefault();
+ event?.stopPropagation();
+ this.deleteConfirmOpen = false;
+ }
+
openSubflowPreview(event?: Event) {
event?.preventDefault();
event?.stopPropagation();
diff --git a/src/app/shared/rete-editor/rete-editor.ts b/src/app/shared/rete-editor/rete-editor.ts
index b977a27..e1063b8 100644
--- a/src/app/shared/rete-editor/rete-editor.ts
+++ b/src/app/shared/rete-editor/rete-editor.ts
@@ -1,6 +1,7 @@
import { Component, ElementRef, Injector, input, OnChanges, OnDestroy, output, signal, SimpleChanges, ViewChild } from '@angular/core';
import { BlockType, FlowData, FlowNode } from '@models/flow';
import { BlocksService } from '@services/blocks/blocks';
+import { ContainersService } from '@services/containers/containers';
import { BLOCK_TYPE_DRAG_MIME } from '@shared/blocks-list/block-drag';
import { CONTAINER_SUBFLOW_DRAG_MIME } from '@shared/nodes/container-node/container-node-drag';
import { EditorStateHolder } from '@stores/flow-editor';
@@ -22,7 +23,8 @@ export class ReteEditor implements OnChanges, OnDestroy {
constructor(
private injector: Injector,
private flowState: EditorStateHolder,
- private blocksService: BlocksService
+ private blocksService: BlocksService,
+ private containersService: ContainersService
) {}
@ViewChild("editor") container!: ElementRef;
@@ -95,7 +97,9 @@ export class ReteEditor implements OnChanges, OnDestroy {
this.creatingEmptyBlock = true;
this.creatingEmptyBlockType = blockType.type;
try {
- newBlock = await firstValueFrom(this.blocksService.createEmptyBlock(blockType.type, blockType.family));
+ newBlock = blockType.family === 'container'
+ ? await firstValueFrom(this.containersService.createEmptyContainer(blockType.type))
+ : await firstValueFrom(this.blocksService.createEmptyBlock(blockType.type));
} catch (error) {
console.error('Failed to create empty block', error);
return;
diff --git a/src/app/utilities/rete-editor.ts b/src/app/utilities/rete-editor.ts
index a3f71ab..04e7f40 100644
--- a/src/app/utilities/rete-editor.ts
+++ b/src/app/utilities/rete-editor.ts
@@ -19,6 +19,7 @@ import {
normalizeFlowPortValueKinds
} from "@models/flow";
import { BlocksService } from "@services/blocks/blocks";
+import { ContainersService } from "@services/containers/containers";
import { NodeSettingsDialogService } from "@services/dialogs/node-settings-dialog";
import { EditorStateHolder } from "@stores/flow-editor";
import { ContainerNodeComponent } from "@shared/nodes/container-node/container-node";
@@ -37,6 +38,7 @@ export type ReteEditorInstance = {
type ReteRuntimeContext = {
blocksService: BlocksService;
+ containersService: ContainersService;
flowState: EditorStateHolder;
settingsDialog: NodeSettingsDialogService;
};
@@ -55,6 +57,7 @@ export async function createEditor(
const nodeView = options?.nodeView ?? "editor";
const runtime: ReteRuntimeContext = {
blocksService: injector.get(BlocksService),
+ containersService: injector.get(ContainersService),
flowState: injector.get(EditorStateHolder),
settingsDialog: injector.get(NodeSettingsDialogService)
};
@@ -255,7 +258,7 @@ export async function addBlockToEditor(
};
await area.update("node", node.id);
- resolvedRuntime.blocksService.validateContainerSubflow(candidateSubFlow).subscribe({
+ resolvedRuntime.containersService.validateContainerSubflow(candidateSubFlow).subscribe({
next: async (result) => {
const liveNode = editor.getNode(node.id) as HFNode | undefined;
if (!liveNode?.data) return;
diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts
index 681b192..5787cac 100644
--- a/src/environments/environment.development.ts
+++ b/src/environments/environment.development.ts
@@ -1,6 +1,7 @@
import { AssistantCallServiceFake } from "@services/assistant/assistant-call.fake";
import { AuthorizationCallFakeService } from "@services/authorization/authorization-call.fake";
import { BlocksCallServiceFake } from "@services/blocks/blocks-call.fake";
+import { ContainersCallServiceFake } from "@services/containers/containers-call.fake";
import { FlowsCallServiceFake } from "@services/flows/flows-call.fake";
import { FieldRetrieverCallServiceFake } from "@services/retriever/field-retriever-call.fake";
import { TaskExecutionsCallServiceFake } from "@services/task-executions/task-executions-call.fake";
@@ -13,6 +14,7 @@ export const environment = {
assistantCallService: AssistantCallServiceFake,
flowsCallService: FlowsCallServiceFake,
blocksCallService: BlocksCallServiceFake,
+ containersCallService: ContainersCallServiceFake,
fieldRetrieverCallService: FieldRetrieverCallServiceFake,
taskExecutionsCallService: TaskExecutionsCallServiceFake
};
diff --git a/src/environments/environment.staging.ts b/src/environments/environment.staging.ts
index aeae932..1cee041 100644
--- a/src/environments/environment.staging.ts
+++ b/src/environments/environment.staging.ts
@@ -1,6 +1,7 @@
import { AssistantCallService } from "@services/assistant/assistant-call";
import { AuthorizationCallService } from "@services/authorization/authorization-call";
import { BlocksCallService } from "@services/blocks/blocks-call";
+import { ContainersCallService } from "@services/containers/containers-call";
import { FlowsCallService } from "@services/flows/flows-call";
import { FieldRetrieverCallService } from "@services/retriever/field-retriever-call";
import { TaskExecutionsCallService } from "@services/task-executions/task-executions-call";
@@ -13,6 +14,7 @@ export const environment = {
authorizationCallService: AuthorizationCallService,
flowsCallService: FlowsCallService,
blocksCallService: BlocksCallService,
+ containersCallService: ContainersCallService,
fieldRetrieverCallService: FieldRetrieverCallService,
taskExecutionsCallService: TaskExecutionsCallService
};
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 470a800..9561845 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1,6 +1,7 @@
import { AssistantCallService } from "@services/assistant/assistant-call";
import { AuthorizationCallService } from "@services/authorization/authorization-call";
import { BlocksCallService } from "@services/blocks/blocks-call";
+import { ContainersCallService } from "@services/containers/containers-call";
import { FlowsCallService } from "@services/flows/flows-call";
import { FieldRetrieverCallService } from "@services/retriever/field-retriever-call";
import { TaskExecutionsCallService } from "@services/task-executions/task-executions-call";
@@ -13,6 +14,7 @@ export const environment = {
assistantCallService: AssistantCallService,
flowsCallService: FlowsCallService,
blocksCallService: BlocksCallService,
+ containersCallService: ContainersCallService,
fieldRetrieverCallService: FieldRetrieverCallService,
taskExecutionsCallService: TaskExecutionsCallService
};