156 lines
6.5 KiB
HTML
156 lines
6.5 KiB
HTML
<div class="container-node" [class.container-node-assigning]="isAssigning" [class.container-node-delete-pending]="deleteConfirmOpen">
|
|
@if (deleteConfirmOpen) {
|
|
<div class="container-node__delete-overlay"></div>
|
|
}
|
|
<div class="container-node__header" [class.cursor-move]="!isReadonly">
|
|
<div class="container-node__icon">
|
|
<i class="bi bi-box-seam"></i>
|
|
</div>
|
|
<div class="container-node__titles">
|
|
<div class="container-node__eyebrow">Generic Container</div>
|
|
<div class="container-node__name">{{ name }}</div>
|
|
</div>
|
|
<div class="container-node__header-actions">
|
|
@if (missingRequiredParams.length) {
|
|
<div class="container-node__warning-wrap">
|
|
<div class="container-node__warning">
|
|
<i class="bi bi-exclamation-triangle-fill"></i>
|
|
</div>
|
|
<div class="container-node__warning-tooltip">
|
|
<div class="container-node__warning-title">Missing required fields</div>
|
|
@for (missing of missingRequiredParams; track missing) {
|
|
<div class="container-node__warning-item">{{ missing }}</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (!isReadonly && deleteConfirmOpen) {
|
|
<div class="container-node__delete-confirm" (pointerdown)="$event.stopPropagation()" (click)="$event.stopPropagation()">
|
|
<span class="container-node__delete-confirm-text">Delete container?</span>
|
|
<button type="button" class="container-node__delete-confirm-cancel" (click)="cancelDelete($event)">Cancel</button>
|
|
<button type="button" class="container-node__delete-confirm-action" (click)="deleteNode($event)">Delete</button>
|
|
</div>
|
|
}
|
|
@if (!isReadonly) {
|
|
<button type="button" class="container-node__delete" title="Delete node" (pointerdown)="$event.stopPropagation()" (click)="deleteNode($event)">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container-node__ports">
|
|
<div class="container-node__port-column">
|
|
<div class="container-node__port-title">Inputs</div>
|
|
@for (input of inputs; track input.key) {
|
|
<div class="container-node__port-row">
|
|
<div
|
|
refComponent
|
|
class="container-node__socket"
|
|
[data]="{
|
|
type: 'socket',
|
|
side: 'input',
|
|
key: input.key,
|
|
nodeId: data.id,
|
|
__readonly: isReadonly,
|
|
payload: input.socket
|
|
}"
|
|
[emit]="emit">
|
|
</div>
|
|
<span class="container-node__port-label container-node__port-label--input">
|
|
@if (inputDisplayLabelParts(input.key).context; as context) {
|
|
<span class="container-node__port-context">{{ context }}</span>
|
|
}
|
|
<span class="container-node__port-name">{{ inputDisplayLabelParts(input.key).name }}</span>
|
|
<span class="container-node__port-kind">{{ inputKindLabel(input.key) }}</span>
|
|
</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<div class="container-node__port-column container-node__port-column--right">
|
|
<div class="container-node__port-title">Outputs</div>
|
|
@for (output of outputs; track output.key) {
|
|
<div class="container-node__port-row container-node__port-row--right">
|
|
<span class="container-node__port-label container-node__port-label--output">
|
|
@if (outputDisplayLabelParts(output.key).context; as context) {
|
|
<span class="container-node__port-context">{{ context }}</span>
|
|
}
|
|
<span class="container-node__port-name">{{ outputDisplayLabelParts(output.key).name }}</span>
|
|
<span class="container-node__port-kind">{{ outputKindLabel(output.key) }}</span>
|
|
</span>
|
|
<div
|
|
refComponent
|
|
class="container-node__socket container-node__socket--right"
|
|
[data]="{
|
|
type: 'socket',
|
|
side: 'output',
|
|
key: output.key,
|
|
nodeId: data.id,
|
|
__readonly: isReadonly,
|
|
payload: output.socket
|
|
}"
|
|
[emit]="emit">
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="container-node__dropzone"
|
|
[class.container-node__dropzone--active]="!isReadonly && selectedCount > 0"
|
|
[class.container-node__dropzone--filled]="subFlowBlockCount > 0"
|
|
(dragover)="onDropZoneDragOver($event)"
|
|
(dragleave)="onDropZoneDragLeave($event)"
|
|
(drop)="onDropZoneDrop($event)">
|
|
@if (replaceConfirmOpen) {
|
|
<div class="container-node__replace-confirm" (pointerdown)="$event.stopPropagation()" (click)="$event.stopPropagation()">
|
|
<div class="container-node__replace-confirm-text">Replace current subflow?</div>
|
|
<div class="container-node__replace-confirm-note">The existing embedded flow will be removed and replaced by the dropped selection.</div>
|
|
<div class="container-node__replace-confirm-actions">
|
|
<button type="button" class="container-node__replace-confirm-cancel" (click)="cancelReplaceSubflow($event)">Cancel</button>
|
|
<button type="button" class="container-node__replace-confirm-action" (click)="confirmReplaceSubflow($event)">Replace</button>
|
|
</div>
|
|
</div>
|
|
} @else if (isAssigning) {
|
|
<div class="container-node__dropzone-main">
|
|
<span class="container-node__spinner" aria-hidden="true"></span>
|
|
<span>Updating container...</span>
|
|
</div>
|
|
} @else {
|
|
<div class="container-node__dropzone-main">
|
|
<span class="container-node__dropzone-empty">Drag a flow here or import from flow</span>
|
|
</div>
|
|
<div class="container-node__dropzone-note">
|
|
Use the selection box in the editor, then drag the floating selection badge into this area.
|
|
</div>
|
|
}
|
|
@if (subFlowBlockCount > 0 && !replaceConfirmOpen && !isAssigning) {
|
|
<div class="container-node__dropzone-actions">
|
|
<button type="button" class="container-node__subflow-view" (pointerdown)="$event.stopPropagation()" (click)="openSubflowPreview($event)">
|
|
View Flow
|
|
</button>
|
|
</div>
|
|
}
|
|
@if (!isReadonly && !replaceConfirmOpen && !isAssigning) {
|
|
<div class="container-node__dropzone-actions">
|
|
<button type="button" class="container-node__import" (pointerdown)="$event.stopPropagation()" (click)="importSubflow($event)">
|
|
@if (importLoading) {
|
|
<span class="container-node__spinner" aria-hidden="true"></span>
|
|
<span>Loading flows...</span>
|
|
} @else {
|
|
<span>Import flow</span>
|
|
}
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@if (assignmentErrorMessage) {
|
|
<div class="container-node__message container-node__message--error">
|
|
{{ assignmentErrorMessage }}
|
|
</div>
|
|
}
|
|
</div>
|