wuic-framework-lib 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{wuic-framework-lib-chart-list.component-Dq9IEKsY.mjs → wuic-framework-lib-chart-list.component-B7d2AQ3G.mjs} +4 -4
- package/fesm2022/{wuic-framework-lib-code-editor.component-B6IpTSo8.mjs → wuic-framework-lib-code-editor.component-Bx_fV1X1.mjs} +6 -6
- package/fesm2022/{wuic-framework-lib-designer.component-D6cbqNFg.mjs → wuic-framework-lib-designer.component-CohHkalb.mjs} +12 -12
- package/fesm2022/{wuic-framework-lib-first-run-wizard.component-D1ZQUl-q.mjs → wuic-framework-lib-first-run-wizard.component-BoP77ip9.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-framework-docs.component-C_o5r7pg.mjs → wuic-framework-lib-framework-docs.component-CcyeNUzz.mjs} +10 -10
- package/fesm2022/{wuic-framework-lib-pivot-builder.component-DkWGzJpr.mjs → wuic-framework-lib-pivot-builder.component-BUkGGFaw.mjs} +164 -164
- package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-D29go5yA.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DPapKCIE.mjs} +28 -28
- package/fesm2022/{wuic-framework-lib-report-designer.component-DcpCWghx.mjs → wuic-framework-lib-report-designer.component-A6_tmp6z.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-report-scaffold-dialog.component-CgUjG7Bi.mjs → wuic-framework-lib-report-scaffold-dialog.component-Dbrx9bSq.mjs} +246 -246
- package/fesm2022/{wuic-framework-lib-report-viewer.component-C4Opgl_M.mjs → wuic-framework-lib-report-viewer.component-CYl77DcU.mjs} +4 -4
- package/fesm2022/{wuic-framework-lib-scene3d-designer.component-8l3vsyEb.mjs → wuic-framework-lib-scene3d-designer.component-DyVwOmXa.mjs} +20 -20
- package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-C1w-8Aai.mjs → wuic-framework-lib-scene3d-light-baker-gpu-DEGIR8lh.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-scene3d-shader-effect-DjHyCAFK.mjs → wuic-framework-lib-scene3d-shader-effect-gBEFKNvi.mjs} +18 -18
- package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-nMSl5jbe.mjs → wuic-framework-lib-scene3d-viewer.component-G_ykpDDF.mjs} +5 -5
- package/fesm2022/{wuic-framework-lib-scheduler-list.component-Cvk3Zg0Q.mjs → wuic-framework-lib-scheduler-list.component-C_1YjS3c.mjs} +4 -4
- package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-C1U7JPiq.mjs → wuic-framework-lib-spreadsheet-list-sf.component-BKtu4edX.mjs} +47 -47
- package/fesm2022/{wuic-framework-lib-timeline-list.component-cZbPgNh1.mjs → wuic-framework-lib-timeline-list.component-Dcosb8Zx.mjs} +6 -6
- package/fesm2022/{wuic-framework-lib-workflow-designer.component-C_4RQGa0.mjs → wuic-framework-lib-workflow-designer.component-BXnoS_ts.mjs} +6 -6
- package/fesm2022/{wuic-framework-lib-wuic-framework-lib-BZZwta8b.mjs → wuic-framework-lib-wuic-framework-lib-54sySY_p.mjs} +838 -823
- package/fesm2022/wuic-framework-lib.mjs +1 -1
- package/package.json +1 -1
- package/styles/_wuic-tokens.scss +82 -82
- package/types/wuic-framework-lib.d.ts +15 -2
|
@@ -23,7 +23,7 @@ import { TooltipModule } from 'primeng/tooltip';
|
|
|
23
23
|
import * as i8 from '@ngx-translate/core';
|
|
24
24
|
import { TranslateModule } from '@ngx-translate/core';
|
|
25
25
|
import { BehaviorSubject } from 'rxjs';
|
|
26
|
-
import { W as WtoolboxService, M as MetadataProviderService, f as ParametricDialogComponent, m as WuicClientException, n as WuicErrorCodes, G as GlobalHandler, h as DataProviderService, C as ChatbotHostRegistryService, b as DataSourceComponent, l as MetadataEditorComponent } from './wuic-framework-lib-wuic-framework-lib-
|
|
26
|
+
import { W as WtoolboxService, M as MetadataProviderService, f as ParametricDialogComponent, m as WuicClientException, n as WuicErrorCodes, G as GlobalHandler, h as DataProviderService, C as ChatbotHostRegistryService, b as DataSourceComponent, l as MetadataEditorComponent } from './wuic-framework-lib-wuic-framework-lib-54sySY_p.mjs';
|
|
27
27
|
|
|
28
28
|
class WorkflowDesignerLayoutHelper {
|
|
29
29
|
/**
|
|
@@ -1583,13 +1583,13 @@ class WorkflowDesignerNodeComponent {
|
|
|
1583
1583
|
return value.slice(0, Math.max(1, limit - 1)) + '…';
|
|
1584
1584
|
}
|
|
1585
1585
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowDesignerNodeComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1586
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WorkflowDesignerNodeComponent, isStandalone: true, selector: "wuic-workflow-designer-node", inputs: { data: "data", emit: "emit", rendered: "rendered" }, host: { attributes: { "data-testid": "node" }, properties: { "style.width.px": "this.width", "style.height.px": "this.height", "class.selected": "this.selected", "attr.data-wf-node-type": "this.nodeType", "attr.data-wf-action-scope": "this.actionScope", "attr.data-wf-action-type": "this.actionType", "style.--wf-node-accent": "this.accentColor", "style.--wf-node-bg": "this.backgroundColor" } }, usesOnChanges: true, ngImport: i0, template: "<svg class=\"wf-shape-layer\" [attr.viewBox]=\"svgViewBox\" aria-hidden=\"true\">\n <path class=\"wf-shape-fill\" [attr.d]=\"shapePath\"></path>\n <rect class=\"wf-shape-title-band\" [attr.x]=\"titleBandX\" y=\"2\" [attr.width]=\"titleBandWidth\" [attr.height]=\"titleBandHeight\" rx=\"5\" ry=\"5\"></rect>\n <text class=\"wf-shape-title-text\" [attr.x]=\"titleTextX\" [attr.y]=\"titleTextY\">\n @for (line of titleLines; track $index; let i = $index) {\n <tspan [attr.x]=\"titleTextX\" [attr.dy]=\"i === 0 ? 0 : titleLineDy\">{{ line }}</tspan>\n }\n </text>\n <path class=\"wf-shape-stroke\" [attr.d]=\"shapePath\" [attr.stroke-dasharray]=\"dashedStroke\"></path>\n</svg>\n\n<!-- Overlay TRASPARENTE per il tooltip: l'`.wf-shape-layer` ha\n pointer-events:none (serve al drag di rete), quindi il hover reale non lo\n raggiunge. Questo target riempie il nodo con pointer-events:auto: il\n mouseenter arriva a pTooltip; pointerdown/contextmenu BOLLONO all'host\n (drag + context menu invariati); i socket sono DOPO nel DOM (stacking piu'\n alto) quindi restano cliccabili. -->\n<div class=\"wf-node-hover-target\"\n [pTooltip]=\"tooltipHtml\" [escape]=\"false\" tooltipPosition=\"top\"\n [tooltipDisabled]=\"!tooltipHtml\" [showDelay]=\"250\" tooltipStyleClass=\"wf-node-tooltip\"></div>\n\n<!-- SOCKET/CONTROL: `@for` con track per KEY (chiave stabile del socket). La\n pipe impura `keyvalueimpure` restituisce un nuovo array a ogni CD; tracciare\n per key fa RIUSARE le view invece di ricrearle (niente warning NG0956).\n rete-angular-plugin e' costruito sul ciclo mount/unmount del RefDirective\n (emit('render')/emit('unmount')) e senza guardia crasherebbe in teardown\n con \"this.emit is not a function\": la guardia idempotente nel .ts del\n componente (RefDirective.prototype) tollera quei momenti. -->\n@for (output of data.outputs | keyvalueimpure: sortByIndex; track output.key) {\n <!-- Switch: socket posizionato inline sul VERTICE del poligono (ngStyle null\n per gli altri tipi = CSS default) + tooltip nativo con la condizione. -->\n <div class=\"wf-output\" [attr.data-testid]=\"'output-'+output.key\" [attr.data-wf-output-key]=\"output.key\"\n [ngStyle]=\"switchOutputStyle(output.key)\" [attr.title]=\"switchOutputTitle(output.key)\">\n <div class=\"wf-output-title\" data-testid=\"output-title\">{{ output.value?.label }}</div>\n <div\n class=\"wf-output-socket\"\n refComponent\n [data]=\"{type: 'socket', side: 'output', key: output.key, nodeId: data.id, payload: output.value?.socket, seed: seed }\"\n [emit]=\"emit\"\n data-testid=\"output-socket\">\n </div>\n </div>\n}\n\n@for (control of data.controls | keyvalueimpure: sortByIndex; track control.key) {\n <div\n class=\"wf-control\"\n refComponent\n [data]=\"{type: 'control', payload: control.value }\"\n [emit]=\"emit\"\n [attr.data-testid]=\"'control-'+control.key\">\n </div>\n}\n\n@for (input of data.inputs | keyvalueimpure: sortByIndex; track input.key) {\n <div class=\"wf-input\" [attr.data-testid]=\"'input-'+input.key\">\n <div\n class=\"wf-input-socket\"\n refComponent\n [data]=\"{type: 'socket', side: 'input', key: input.key, nodeId: data.id, payload: input.value?.socket, seed: seed }\"\n [emit]=\"emit\"\n data-testid=\"input-socket\">\n </div>\n @if (!input.value?.control || !input.value?.showControl) {\n <div class=\"wf-input-title\" data-testid=\"input-title\">{{ input.value?.label }}</div>\n }\n <div\n class=\"wf-input-control\"\n [style.display]=\"input.value?.control && input.value?.showControl ? '' : 'none'\"\n refComponent\n [data]=\"{type: 'control', payload: input.value?.control }\"\n [emit]=\"emit\"\n data-testid=\"input-control\">\n </div>\n </div>\n}\n", styles: [":host{display:block;box-sizing:border-box;min-height:92px;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:initial;font-family:Arial,sans-serif;position:relative;overflow:visible;color:#0f172a}.wf-shape-layer{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}.wf-shape-fill{fill:var(--wf-node-bg, #f8fafc)}.wf-shape-stroke{fill:none;stroke:var(--wf-node-accent, #475569);stroke-width:2.2;vector-effect:non-scaling-stroke}.wf-shape-title-band{fill:var(--wf-node-accent, #475569)}.wf-shape-title-text{fill:#fff;font-size:12px;font-weight:700;font-family:Arial,sans-serif;dominant-baseline:hanging;text-anchor:start}:host.selected{filter:drop-shadow(0 0 .35rem color-mix(in srgb,var(--wf-node-accent, #475569) 42%,transparent))}:host>*{position:relative;z-index:1}.wf-output{position:absolute;top:50%;right:0;transform:translate(50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}.wf-input{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}:host[data-wf-node-type=action][data-wf-action-type=\"0\"] .wf-input{left:10%}.wf-input-title,.wf-output-title{display:none}.wf-output-socket{line-height:0;vertical-align:top;margin-right:0;display:block}.wf-input-socket{line-height:0;vertical-align:top;margin-left:0;display:block}.wf-input-control{z-index:1;width:calc(100% - 36px);vertical-align:middle;display:inline-block}.wf-control{padding:6px 18px}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true]{inset:50% 0 auto auto;transform:translate(50%,-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false]{inset:auto auto 0 50%;transform:translate(-50%,50%)}:host[data-wf-node-type=condition] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #0f766e);pointer-events:none}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true] .wf-output-title{right:12px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false] .wf-output-title{bottom:10px;left:50%;transform:translate(-50%)}:host[data-wf-node-type=switch] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #4338ca);pointer-events:none;right:14px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=switch] .wf-output[data-wf-output-key=else] .wf-output-title{inset:auto auto 12px 50%;transform:translate(-50%)}.wf-node-hover-target{position:absolute;inset:0;z-index:0;pointer-events:auto;background:transparent}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: RefDirective, selector: "[refComponent]", inputs: ["data", "emit"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: ImpureKeyvaluePipe, name: "keyvalueimpure" }] });
|
|
1586
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WorkflowDesignerNodeComponent, isStandalone: true, selector: "wuic-workflow-designer-node", inputs: { data: "data", emit: "emit", rendered: "rendered" }, host: { attributes: { "data-testid": "node" }, properties: { "style.width.px": "this.width", "style.height.px": "this.height", "class.selected": "this.selected", "attr.data-wf-node-type": "this.nodeType", "attr.data-wf-action-scope": "this.actionScope", "attr.data-wf-action-type": "this.actionType", "style.--wf-node-accent": "this.accentColor", "style.--wf-node-bg": "this.backgroundColor" } }, usesOnChanges: true, ngImport: i0, template: "<svg class=\"wf-shape-layer\" [attr.viewBox]=\"svgViewBox\" aria-hidden=\"true\">\r\n <path class=\"wf-shape-fill\" [attr.d]=\"shapePath\"></path>\r\n <rect class=\"wf-shape-title-band\" [attr.x]=\"titleBandX\" y=\"2\" [attr.width]=\"titleBandWidth\" [attr.height]=\"titleBandHeight\" rx=\"5\" ry=\"5\"></rect>\r\n <text class=\"wf-shape-title-text\" [attr.x]=\"titleTextX\" [attr.y]=\"titleTextY\">\r\n @for (line of titleLines; track $index; let i = $index) {\r\n <tspan [attr.x]=\"titleTextX\" [attr.dy]=\"i === 0 ? 0 : titleLineDy\">{{ line }}</tspan>\r\n }\r\n </text>\r\n <path class=\"wf-shape-stroke\" [attr.d]=\"shapePath\" [attr.stroke-dasharray]=\"dashedStroke\"></path>\r\n</svg>\r\n\r\n<!-- Overlay TRASPARENTE per il tooltip: l'`.wf-shape-layer` ha\r\n pointer-events:none (serve al drag di rete), quindi il hover reale non lo\r\n raggiunge. Questo target riempie il nodo con pointer-events:auto: il\r\n mouseenter arriva a pTooltip; pointerdown/contextmenu BOLLONO all'host\r\n (drag + context menu invariati); i socket sono DOPO nel DOM (stacking piu'\r\n alto) quindi restano cliccabili. -->\r\n<div class=\"wf-node-hover-target\"\r\n [pTooltip]=\"tooltipHtml\" [escape]=\"false\" tooltipPosition=\"top\"\r\n [tooltipDisabled]=\"!tooltipHtml\" [showDelay]=\"250\" tooltipStyleClass=\"wf-node-tooltip\"></div>\r\n\r\n<!-- SOCKET/CONTROL: `@for` con track per KEY (chiave stabile del socket). La\r\n pipe impura `keyvalueimpure` restituisce un nuovo array a ogni CD; tracciare\r\n per key fa RIUSARE le view invece di ricrearle (niente warning NG0956).\r\n rete-angular-plugin e' costruito sul ciclo mount/unmount del RefDirective\r\n (emit('render')/emit('unmount')) e senza guardia crasherebbe in teardown\r\n con \"this.emit is not a function\": la guardia idempotente nel .ts del\r\n componente (RefDirective.prototype) tollera quei momenti. -->\r\n@for (output of data.outputs | keyvalueimpure: sortByIndex; track output.key) {\r\n <!-- Switch: socket posizionato inline sul VERTICE del poligono (ngStyle null\r\n per gli altri tipi = CSS default) + tooltip nativo con la condizione. -->\r\n <div class=\"wf-output\" [attr.data-testid]=\"'output-'+output.key\" [attr.data-wf-output-key]=\"output.key\"\r\n [ngStyle]=\"switchOutputStyle(output.key)\" [attr.title]=\"switchOutputTitle(output.key)\">\r\n <div class=\"wf-output-title\" data-testid=\"output-title\">{{ output.value?.label }}</div>\r\n <div\r\n class=\"wf-output-socket\"\r\n refComponent\r\n [data]=\"{type: 'socket', side: 'output', key: output.key, nodeId: data.id, payload: output.value?.socket, seed: seed }\"\r\n [emit]=\"emit\"\r\n data-testid=\"output-socket\">\r\n </div>\r\n </div>\r\n}\r\n\r\n@for (control of data.controls | keyvalueimpure: sortByIndex; track control.key) {\r\n <div\r\n class=\"wf-control\"\r\n refComponent\r\n [data]=\"{type: 'control', payload: control.value }\"\r\n [emit]=\"emit\"\r\n [attr.data-testid]=\"'control-'+control.key\">\r\n </div>\r\n}\r\n\r\n@for (input of data.inputs | keyvalueimpure: sortByIndex; track input.key) {\r\n <div class=\"wf-input\" [attr.data-testid]=\"'input-'+input.key\">\r\n <div\r\n class=\"wf-input-socket\"\r\n refComponent\r\n [data]=\"{type: 'socket', side: 'input', key: input.key, nodeId: data.id, payload: input.value?.socket, seed: seed }\"\r\n [emit]=\"emit\"\r\n data-testid=\"input-socket\">\r\n </div>\r\n @if (!input.value?.control || !input.value?.showControl) {\r\n <div class=\"wf-input-title\" data-testid=\"input-title\">{{ input.value?.label }}</div>\r\n }\r\n <div\r\n class=\"wf-input-control\"\r\n [style.display]=\"input.value?.control && input.value?.showControl ? '' : 'none'\"\r\n refComponent\r\n [data]=\"{type: 'control', payload: input.value?.control }\"\r\n [emit]=\"emit\"\r\n data-testid=\"input-control\">\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-height:92px;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:initial;font-family:Arial,sans-serif;position:relative;overflow:visible;color:#0f172a}.wf-shape-layer{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}.wf-shape-fill{fill:var(--wf-node-bg, #f8fafc)}.wf-shape-stroke{fill:none;stroke:var(--wf-node-accent, #475569);stroke-width:2.2;vector-effect:non-scaling-stroke}.wf-shape-title-band{fill:var(--wf-node-accent, #475569)}.wf-shape-title-text{fill:#fff;font-size:12px;font-weight:700;font-family:Arial,sans-serif;dominant-baseline:hanging;text-anchor:start}:host.selected{filter:drop-shadow(0 0 .35rem color-mix(in srgb,var(--wf-node-accent, #475569) 42%,transparent))}:host>*{position:relative;z-index:1}.wf-output{position:absolute;top:50%;right:0;transform:translate(50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}.wf-input{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}:host[data-wf-node-type=action][data-wf-action-type=\"0\"] .wf-input{left:10%}.wf-input-title,.wf-output-title{display:none}.wf-output-socket{line-height:0;vertical-align:top;margin-right:0;display:block}.wf-input-socket{line-height:0;vertical-align:top;margin-left:0;display:block}.wf-input-control{z-index:1;width:calc(100% - 36px);vertical-align:middle;display:inline-block}.wf-control{padding:6px 18px}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true]{inset:50% 0 auto auto;transform:translate(50%,-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false]{inset:auto auto 0 50%;transform:translate(-50%,50%)}:host[data-wf-node-type=condition] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #0f766e);pointer-events:none}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true] .wf-output-title{right:12px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false] .wf-output-title{bottom:10px;left:50%;transform:translate(-50%)}:host[data-wf-node-type=switch] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #4338ca);pointer-events:none;right:14px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=switch] .wf-output[data-wf-output-key=else] .wf-output-title{inset:auto auto 12px 50%;transform:translate(-50%)}.wf-node-hover-target{position:absolute;inset:0;z-index:0;pointer-events:auto;background:transparent}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: RefDirective, selector: "[refComponent]", inputs: ["data", "emit"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: ImpureKeyvaluePipe, name: "keyvalueimpure" }] });
|
|
1587
1587
|
}
|
|
1588
1588
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowDesignerNodeComponent, decorators: [{
|
|
1589
1589
|
type: Component,
|
|
1590
1590
|
args: [{ selector: 'wuic-workflow-designer-node', standalone: true, imports: [CommonModule, RefDirective, ImpureKeyvaluePipe, TooltipModule], host: {
|
|
1591
1591
|
'data-testid': 'node'
|
|
1592
|
-
}, template: "<svg class=\"wf-shape-layer\" [attr.viewBox]=\"svgViewBox\" aria-hidden=\"true\">\n <path class=\"wf-shape-fill\" [attr.d]=\"shapePath\"></path>\n <rect class=\"wf-shape-title-band\" [attr.x]=\"titleBandX\" y=\"2\" [attr.width]=\"titleBandWidth\" [attr.height]=\"titleBandHeight\" rx=\"5\" ry=\"5\"></rect>\n <text class=\"wf-shape-title-text\" [attr.x]=\"titleTextX\" [attr.y]=\"titleTextY\">\n @for (line of titleLines; track $index; let i = $index) {\n <tspan [attr.x]=\"titleTextX\" [attr.dy]=\"i === 0 ? 0 : titleLineDy\">{{ line }}</tspan>\n }\n </text>\n <path class=\"wf-shape-stroke\" [attr.d]=\"shapePath\" [attr.stroke-dasharray]=\"dashedStroke\"></path>\n</svg>\n\n<!-- Overlay TRASPARENTE per il tooltip: l'`.wf-shape-layer` ha\n pointer-events:none (serve al drag di rete), quindi il hover reale non lo\n raggiunge. Questo target riempie il nodo con pointer-events:auto: il\n mouseenter arriva a pTooltip; pointerdown/contextmenu BOLLONO all'host\n (drag + context menu invariati); i socket sono DOPO nel DOM (stacking piu'\n alto) quindi restano cliccabili. -->\n<div class=\"wf-node-hover-target\"\n [pTooltip]=\"tooltipHtml\" [escape]=\"false\" tooltipPosition=\"top\"\n [tooltipDisabled]=\"!tooltipHtml\" [showDelay]=\"250\" tooltipStyleClass=\"wf-node-tooltip\"></div>\n\n<!-- SOCKET/CONTROL: `@for` con track per KEY (chiave stabile del socket). La\n pipe impura `keyvalueimpure` restituisce un nuovo array a ogni CD; tracciare\n per key fa RIUSARE le view invece di ricrearle (niente warning NG0956).\n rete-angular-plugin e' costruito sul ciclo mount/unmount del RefDirective\n (emit('render')/emit('unmount')) e senza guardia crasherebbe in teardown\n con \"this.emit is not a function\": la guardia idempotente nel .ts del\n componente (RefDirective.prototype) tollera quei momenti. -->\n@for (output of data.outputs | keyvalueimpure: sortByIndex; track output.key) {\n <!-- Switch: socket posizionato inline sul VERTICE del poligono (ngStyle null\n per gli altri tipi = CSS default) + tooltip nativo con la condizione. -->\n <div class=\"wf-output\" [attr.data-testid]=\"'output-'+output.key\" [attr.data-wf-output-key]=\"output.key\"\n [ngStyle]=\"switchOutputStyle(output.key)\" [attr.title]=\"switchOutputTitle(output.key)\">\n <div class=\"wf-output-title\" data-testid=\"output-title\">{{ output.value?.label }}</div>\n <div\n class=\"wf-output-socket\"\n refComponent\n [data]=\"{type: 'socket', side: 'output', key: output.key, nodeId: data.id, payload: output.value?.socket, seed: seed }\"\n [emit]=\"emit\"\n data-testid=\"output-socket\">\n </div>\n </div>\n}\n\n@for (control of data.controls | keyvalueimpure: sortByIndex; track control.key) {\n <div\n class=\"wf-control\"\n refComponent\n [data]=\"{type: 'control', payload: control.value }\"\n [emit]=\"emit\"\n [attr.data-testid]=\"'control-'+control.key\">\n </div>\n}\n\n@for (input of data.inputs | keyvalueimpure: sortByIndex; track input.key) {\n <div class=\"wf-input\" [attr.data-testid]=\"'input-'+input.key\">\n <div\n class=\"wf-input-socket\"\n refComponent\n [data]=\"{type: 'socket', side: 'input', key: input.key, nodeId: data.id, payload: input.value?.socket, seed: seed }\"\n [emit]=\"emit\"\n data-testid=\"input-socket\">\n </div>\n @if (!input.value?.control || !input.value?.showControl) {\n <div class=\"wf-input-title\" data-testid=\"input-title\">{{ input.value?.label }}</div>\n }\n <div\n class=\"wf-input-control\"\n [style.display]=\"input.value?.control && input.value?.showControl ? '' : 'none'\"\n refComponent\n [data]=\"{type: 'control', payload: input.value?.control }\"\n [emit]=\"emit\"\n data-testid=\"input-control\">\n </div>\n </div>\n}\n", styles: [":host{display:block;box-sizing:border-box;min-height:92px;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:initial;font-family:Arial,sans-serif;position:relative;overflow:visible;color:#0f172a}.wf-shape-layer{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}.wf-shape-fill{fill:var(--wf-node-bg, #f8fafc)}.wf-shape-stroke{fill:none;stroke:var(--wf-node-accent, #475569);stroke-width:2.2;vector-effect:non-scaling-stroke}.wf-shape-title-band{fill:var(--wf-node-accent, #475569)}.wf-shape-title-text{fill:#fff;font-size:12px;font-weight:700;font-family:Arial,sans-serif;dominant-baseline:hanging;text-anchor:start}:host.selected{filter:drop-shadow(0 0 .35rem color-mix(in srgb,var(--wf-node-accent, #475569) 42%,transparent))}:host>*{position:relative;z-index:1}.wf-output{position:absolute;top:50%;right:0;transform:translate(50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}.wf-input{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}:host[data-wf-node-type=action][data-wf-action-type=\"0\"] .wf-input{left:10%}.wf-input-title,.wf-output-title{display:none}.wf-output-socket{line-height:0;vertical-align:top;margin-right:0;display:block}.wf-input-socket{line-height:0;vertical-align:top;margin-left:0;display:block}.wf-input-control{z-index:1;width:calc(100% - 36px);vertical-align:middle;display:inline-block}.wf-control{padding:6px 18px}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true]{inset:50% 0 auto auto;transform:translate(50%,-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false]{inset:auto auto 0 50%;transform:translate(-50%,50%)}:host[data-wf-node-type=condition] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #0f766e);pointer-events:none}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true] .wf-output-title{right:12px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false] .wf-output-title{bottom:10px;left:50%;transform:translate(-50%)}:host[data-wf-node-type=switch] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #4338ca);pointer-events:none;right:14px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=switch] .wf-output[data-wf-output-key=else] .wf-output-title{inset:auto auto 12px 50%;transform:translate(-50%)}.wf-node-hover-target{position:absolute;inset:0;z-index:0;pointer-events:auto;background:transparent}\n"] }]
|
|
1592
|
+
}, template: "<svg class=\"wf-shape-layer\" [attr.viewBox]=\"svgViewBox\" aria-hidden=\"true\">\r\n <path class=\"wf-shape-fill\" [attr.d]=\"shapePath\"></path>\r\n <rect class=\"wf-shape-title-band\" [attr.x]=\"titleBandX\" y=\"2\" [attr.width]=\"titleBandWidth\" [attr.height]=\"titleBandHeight\" rx=\"5\" ry=\"5\"></rect>\r\n <text class=\"wf-shape-title-text\" [attr.x]=\"titleTextX\" [attr.y]=\"titleTextY\">\r\n @for (line of titleLines; track $index; let i = $index) {\r\n <tspan [attr.x]=\"titleTextX\" [attr.dy]=\"i === 0 ? 0 : titleLineDy\">{{ line }}</tspan>\r\n }\r\n </text>\r\n <path class=\"wf-shape-stroke\" [attr.d]=\"shapePath\" [attr.stroke-dasharray]=\"dashedStroke\"></path>\r\n</svg>\r\n\r\n<!-- Overlay TRASPARENTE per il tooltip: l'`.wf-shape-layer` ha\r\n pointer-events:none (serve al drag di rete), quindi il hover reale non lo\r\n raggiunge. Questo target riempie il nodo con pointer-events:auto: il\r\n mouseenter arriva a pTooltip; pointerdown/contextmenu BOLLONO all'host\r\n (drag + context menu invariati); i socket sono DOPO nel DOM (stacking piu'\r\n alto) quindi restano cliccabili. -->\r\n<div class=\"wf-node-hover-target\"\r\n [pTooltip]=\"tooltipHtml\" [escape]=\"false\" tooltipPosition=\"top\"\r\n [tooltipDisabled]=\"!tooltipHtml\" [showDelay]=\"250\" tooltipStyleClass=\"wf-node-tooltip\"></div>\r\n\r\n<!-- SOCKET/CONTROL: `@for` con track per KEY (chiave stabile del socket). La\r\n pipe impura `keyvalueimpure` restituisce un nuovo array a ogni CD; tracciare\r\n per key fa RIUSARE le view invece di ricrearle (niente warning NG0956).\r\n rete-angular-plugin e' costruito sul ciclo mount/unmount del RefDirective\r\n (emit('render')/emit('unmount')) e senza guardia crasherebbe in teardown\r\n con \"this.emit is not a function\": la guardia idempotente nel .ts del\r\n componente (RefDirective.prototype) tollera quei momenti. -->\r\n@for (output of data.outputs | keyvalueimpure: sortByIndex; track output.key) {\r\n <!-- Switch: socket posizionato inline sul VERTICE del poligono (ngStyle null\r\n per gli altri tipi = CSS default) + tooltip nativo con la condizione. -->\r\n <div class=\"wf-output\" [attr.data-testid]=\"'output-'+output.key\" [attr.data-wf-output-key]=\"output.key\"\r\n [ngStyle]=\"switchOutputStyle(output.key)\" [attr.title]=\"switchOutputTitle(output.key)\">\r\n <div class=\"wf-output-title\" data-testid=\"output-title\">{{ output.value?.label }}</div>\r\n <div\r\n class=\"wf-output-socket\"\r\n refComponent\r\n [data]=\"{type: 'socket', side: 'output', key: output.key, nodeId: data.id, payload: output.value?.socket, seed: seed }\"\r\n [emit]=\"emit\"\r\n data-testid=\"output-socket\">\r\n </div>\r\n </div>\r\n}\r\n\r\n@for (control of data.controls | keyvalueimpure: sortByIndex; track control.key) {\r\n <div\r\n class=\"wf-control\"\r\n refComponent\r\n [data]=\"{type: 'control', payload: control.value }\"\r\n [emit]=\"emit\"\r\n [attr.data-testid]=\"'control-'+control.key\">\r\n </div>\r\n}\r\n\r\n@for (input of data.inputs | keyvalueimpure: sortByIndex; track input.key) {\r\n <div class=\"wf-input\" [attr.data-testid]=\"'input-'+input.key\">\r\n <div\r\n class=\"wf-input-socket\"\r\n refComponent\r\n [data]=\"{type: 'socket', side: 'input', key: input.key, nodeId: data.id, payload: input.value?.socket, seed: seed }\"\r\n [emit]=\"emit\"\r\n data-testid=\"input-socket\">\r\n </div>\r\n @if (!input.value?.control || !input.value?.showControl) {\r\n <div class=\"wf-input-title\" data-testid=\"input-title\">{{ input.value?.label }}</div>\r\n }\r\n <div\r\n class=\"wf-input-control\"\r\n [style.display]=\"input.value?.control && input.value?.showControl ? '' : 'none'\"\r\n refComponent\r\n [data]=\"{type: 'control', payload: input.value?.control }\"\r\n [emit]=\"emit\"\r\n data-testid=\"input-control\">\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-height:92px;cursor:pointer;-webkit-user-select:none;user-select:none;line-height:initial;font-family:Arial,sans-serif;position:relative;overflow:visible;color:#0f172a}.wf-shape-layer{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}.wf-shape-fill{fill:var(--wf-node-bg, #f8fafc)}.wf-shape-stroke{fill:none;stroke:var(--wf-node-accent, #475569);stroke-width:2.2;vector-effect:non-scaling-stroke}.wf-shape-title-band{fill:var(--wf-node-accent, #475569)}.wf-shape-title-text{fill:#fff;font-size:12px;font-weight:700;font-family:Arial,sans-serif;dominant-baseline:hanging;text-anchor:start}:host.selected{filter:drop-shadow(0 0 .35rem color-mix(in srgb,var(--wf-node-accent, #475569) 42%,transparent))}:host>*{position:relative;z-index:1}.wf-output{position:absolute;top:50%;right:0;transform:translate(50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}.wf-input{position:absolute;top:50%;left:0;transform:translate(-50%,-50%);width:0;height:0;display:flex;align-items:center;justify-content:center;z-index:2}:host[data-wf-node-type=action][data-wf-action-type=\"0\"] .wf-input{left:10%}.wf-input-title,.wf-output-title{display:none}.wf-output-socket{line-height:0;vertical-align:top;margin-right:0;display:block}.wf-input-socket{line-height:0;vertical-align:top;margin-left:0;display:block}.wf-input-control{z-index:1;width:calc(100% - 36px);vertical-align:middle;display:inline-block}.wf-control{padding:6px 18px}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true]{inset:50% 0 auto auto;transform:translate(50%,-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false]{inset:auto auto 0 50%;transform:translate(-50%,50%)}:host[data-wf-node-type=condition] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #0f766e);pointer-events:none}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=true] .wf-output-title{right:12px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=condition] .wf-output[data-wf-output-key=false] .wf-output-title{bottom:10px;left:50%;transform:translate(-50%)}:host[data-wf-node-type=switch] .wf-output-title{display:block;position:absolute;white-space:nowrap;font-size:9px;font-weight:700;letter-spacing:.3px;color:var(--wf-node-accent, #4338ca);pointer-events:none;right:14px;top:50%;transform:translateY(-50%)}:host[data-wf-node-type=switch] .wf-output[data-wf-output-key=else] .wf-output-title{inset:auto auto 12px 50%;transform:translate(-50%)}.wf-node-hover-target{position:absolute;inset:0;z-index:0;pointer-events:auto;background:transparent}\n"] }]
|
|
1593
1593
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { data: [{
|
|
1594
1594
|
type: Input
|
|
1595
1595
|
}], emit: [{
|
|
@@ -9470,11 +9470,11 @@ class WorkflowDesignerComponent {
|
|
|
9470
9470
|
});
|
|
9471
9471
|
}
|
|
9472
9472
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowDesignerComponent, deps: [{ token: i0.Injector }, { token: DataProviderService }, { token: ChatbotHostRegistryService }], target: i0.ɵɵFactoryTarget.Component });
|
|
9473
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WorkflowDesignerComponent, isStandalone: true, selector: "wuic-workflow-designer", outputs: { workflowChange: "workflowChange" }, viewQueries: [{ propertyName: "workflowCanvasRef", first: true, predicate: ["workflowCanvas"], descendants: true, static: true }, { propertyName: "primeContextMenu", first: true, predicate: ["primeContextMenu"], descendants: true }, { propertyName: "routeMetadataDs", first: true, predicate: ["routeMetadataDs"], descendants: true }, { propertyName: "startMenuDs", first: true, predicate: ["startMenuDs"], descendants: true }, { propertyName: "menuAuthDs", first: true, predicate: ["menuAuthDs"], descendants: true }, { propertyName: "routeMetadataEditor", first: true, predicate: ["routeMetadataEditor"], descendants: true }, { propertyName: "actionMetadataEditor", first: true, predicate: ["actionMetadataEditor"], descendants: true }], ngImport: i0, template: "<div class=\"workflow-designer\">\n <div class=\"workflow-toolbar\">\n <div class=\"workflow-current-graph\">{{ currentGraphCaption }}</div>\n <!-- Filtro \"anteprima autorizzazioni\": simula cosa vede un ruolo/utente.\n Opzioni dai principal citati nel grafo (permessi bundle + permission\n transizioni); il dropdown utenti appare solo se esistono auth\n per-utente. Selezione vuota = mostra tutto. -->\n @if (authFilterRoleOptions.length > 1) {\n <div class=\"workflow-toolbar-filter\">\n <p-select\n [options]=\"authFilterRoleOptions\"\n [(ngModel)]=\"authFilterRoleId\"\n (onChange)=\"onAuthFilterChanged('role')\"\n appendTo=\"body\"\n data-testid=\"wf-auth-filter-role\" />\n </div>\n }\n @if (authFilterUserOptions.length > 1) {\n <div class=\"workflow-toolbar-filter\">\n <p-select\n [options]=\"authFilterUserOptions\"\n [(ngModel)]=\"authFilterUserId\"\n (onChange)=\"onAuthFilterChanged('user')\"\n appendTo=\"body\"\n data-testid=\"wf-auth-filter-user\" />\n </div>\n }\n <div class=\"workflow-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">\n Azioni grafo\n </button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n <div class=\"workflow-toolbar-menu-group\">\n <button type=\"button\" (click)=\"runnerActionsMenu.toggle($event)\" [disabled]=\"!canOpenWorkflowRunner\">\n Runner\n </button>\n <p-menu #runnerActionsMenu [popup]=\"true\" [model]=\"runnerActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n </div>\n\n <aside class=\"workflow-palette\">\n <div class=\"workflow-palette-title\">{{ 'workflow.palette' | translate }}</div>\n <div class=\"workflow-palette-list\">\n @for (item of paletteNodes; track item) {\n <div\n class=\"workflow-palette-item\"\n [ngClass]=\"{\n 'workflow-palette-item-route': item.type === 'route',\n 'workflow-palette-item-action': item.type === 'action',\n 'workflow-palette-item-start': item.type === 'start',\n 'workflow-palette-item-condition': item.type === 'condition',\n 'workflow-palette-item-end': item.type === 'end',\n 'workflow-palette-item-disabled': !isPaletteNodeEnabled(item)\n }\"\n [attr.draggable]=\"isPaletteNodeEnabled(item) ? 'true' : 'false'\"\n (dragstart)=\"onPaletteDragStart($event, item)\"\n [pTooltip]=\"item.tooltip || ''\"\n [escape]=\"false\"\n tooltipPosition=\"right\"\n [tooltipStyleClass]=\"'workflow-palette-tooltip'\">\n <div class=\"workflow-palette-item-title\">{{ item.label }}</div>\n @if (item.type === 'route') {\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.route' | translate }}</div>\n }\n @if (item.type === 'action') {\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.action_scope' | translate }}</div>\n }\n <div class=\"workflow-palette-item-description\">{{ item.description }}</div>\n </div>\n }\n </div>\n </aside>\n\n <section\n #workflowCanvas\n class=\"workflow-canvas\"\n (dragover)=\"onCanvasDragOver($event)\"\n (drop)=\"onCanvasDrop($event)\"\n (contextmenu)=\"onCanvasContextMenu($event)\"\n (click)=\"onCanvasClick()\">\n @if (showEmptyGraphChecklist) {\n <div class=\"workflow-canvas-checklist\">\n <div class=\"workflow-canvas-checklist-title\">{{ hintChecklistTitle }}</div>\n <ol>\n @for (step of hintChecklistStepStates; track $index) {\n <li [ngClass]=\"{ 'workflow-canvas-checklist-done': step.done }\">{{ step.text }}</li>\n }\n </ol>\n @if (showChecklistTemplateLink) {\n <button type=\"button\" class=\"workflow-canvas-checklist-link\" (click)=\"createWorkflowFromTemplate()\">\n {{ hintOrTemplateLabel }}\n </button>\n }\n </div>\n }\n </section>\n <p-contextMenu\n #primeContextMenu\n [model]=\"contextMenuItems\"\n appendTo=\"body\"\n [autoZIndex]=\"true\"\n [baseZIndex]=\"13000\">\n </p-contextMenu>\n</div>\n\n<p-dialog\n [header]=\"'Riapri grafo'\"\n [(visible)]=\"reopenWorkflowDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenWorkflowDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-reopen-select\">Grafi esistenti</label>\n <p-select\n inputId=\"workflow-reopen-select\"\n [options]=\"savedGraphOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedGraphKey\"\n [filter]=\"true\"\n [showClear]=\"true\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenWorkflowDialog()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenWorkflowDialog()\"\n [disabled]=\"!reopenDialogSelectedGraphKey || loadingWorkflow\">Riapri</button>\n </div>\n </div>\n</p-dialog>\n\n<div style=\"display:none\">\n <wuic-data-source #routeMetadataDs [hardcodedRoute]=\"routeMetadataRoute\"></wuic-data-source>\n <wuic-data-source #startMenuDs [hardcodedRoute]=\"' metadati menu'\"></wuic-data-source>\n <wuic-data-source #menuAuthDs [hardcodedRoute]=\"' mtdt tnt trizzazioni menus'\"></wuic-data-source>\n @if (routeMetadataDs) {\n <wuic-metadata-editor\n #actionMetadataEditor\n [hardcodedDatasource]=\"routeMetadataDs!\"\n [saveCallback]=\"routeMetadataSaveCallback\"\n [hideReports]=\"true\"\n [hideRelatedTableActions]=\"true\"\n [hideRelatedColumnActions]=\"true\">\n </wuic-metadata-editor>\n }\n</div>\n\n<p-dialog\n [header]=\"'workflow.configure_route' | translate\"\n [(visible)]=\"routePopupVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-route-source-select\">Sorgente nodo</label>\n <p-select\n inputId=\"workflow-route-source-select\"\n [options]=\"routeSourceOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedRouteSourceType\"\n (ngModelChange)=\"onRouteSourceTypeChanged()\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n @if (selectedRouteSourceType === 'route') {\n <label for=\"workflow-route-select\">{{ 'workflow.route' | translate }}</label>\n <p-autoComplete\n inputId=\"workflow-route-select\"\n [(ngModel)]=\"selectedRouteName\"\n [suggestions]=\"filteredRouteOptions\"\n [forceSelection]=\"true\"\n [dropdown]=\"true\"\n dropdownMode=\"current\"\n [optionLabel]=\"'label'\"\n [optionValue]=\"'value'\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\"\n (completeMethod)=\"filterRouteOptions($event)\" />\n <label for=\"workflow-action-select\">{{ 'workflow.action' | translate }}</label>\n <p-select\n inputId=\"workflow-action-select\"\n [options]=\"routeActionOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedRouteAction\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n } @else {\n <label for=\"workflow-dashboard-select\">Dashboard</label>\n <p-autoComplete\n inputId=\"workflow-dashboard-select\"\n [(ngModel)]=\"selectedDashboardRoute\"\n [suggestions]=\"filteredDashboardOptions\"\n [forceSelection]=\"true\"\n [dropdown]=\"true\"\n dropdownMode=\"current\"\n [optionLabel]=\"'label'\"\n [optionValue]=\"'value'\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\"\n (completeMethod)=\"filterDashboardOptions($event)\" />\n }\n\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelRouteDrop()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmRouteDrop()\"\n [disabled]=\"selectedRouteSourceType === 'dashboard' ? !selectedDashboardRoute : (!selectedRouteName || !selectedRouteAction)\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<p-dialog\n [header]=\"'workflow.metadata_route' | translate\"\n [(visible)]=\"routeMetadataDialogVisible\"\n [modal]=\"true\"\n position=\"top\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n styleClass=\"workflow-route-metadata-dialog\"\n [style]=\"{ width: '78rem', maxHeight: 'calc(100vh - 2rem)' }\"\n [contentStyle]=\"{ overflow: 'visible', maxHeight: 'calc(100vh - 10rem)' }\">\n @if (routeMetadataDialogVisible && routeMetadataDs) {\n <wuic-metadata-editor\n #routeMetadataEditor\n [hardcodedDatasource]=\"routeMetadataDs!\"\n [saveCallback]=\"routeMetadataSaveCallback\"\n [hideReports]=\"true\"\n [hideRelatedTableActions]=\"false\"\n [hideRelatedColumnActions]=\"false\">\n </wuic-metadata-editor>\n }\n</p-dialog>\n\n<p-dialog\n [header]=\"'workflow.configure_action' | translate\"\n [(visible)]=\"actionPopupVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-action-scope-select\">{{ 'workflow.action_scope' | translate }}</label>\n <p-select\n inputId=\"workflow-action-scope-select\"\n [options]=\"actionScopeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedActionScopeId\"\n (onChange)=\"onActionScopeChanged()\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <label for=\"workflow-action-type-select\">{{ 'workflow.action_type' | translate }}</label>\n <p-select\n inputId=\"workflow-action-type-select\"\n [options]=\"visibleActionTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedActionTypeId\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelActionDrop()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmActionDrop()\"\n [disabled]=\"selectedActionTypeId === null || selectedActionTypeId === undefined || selectedActionScopeId === null || selectedActionScopeId === undefined\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<p-dialog\n [header]=\"'Opzioni workflow'\"\n [(visible)]=\"workflowOptionsDialogVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-options-caption\">Caption menu start</label>\n <input\n id=\"workflow-options-caption\"\n class=\"workflow-options-input\"\n type=\"text\"\n [(ngModel)]=\"workflowOptionsCaption\" />\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsInheritMetadata\" />\n <span>Eredita metadati</span>\n </label>\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsExclusiveMenu\" />\n <span>Menu esclusivo</span>\n </label>\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsShowExit\" />\n <span>Mostra esci</span>\n </label>\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelWorkflowOptionsDialog()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmWorkflowOptionsDialog()\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<!-- Lint del grafo: elenco findings (on-demand \"Valida grafo\" o conferma pre-save).\n Il save non e' mai bloccato: con findings serve la conferma esplicita. -->\n<p-dialog\n [header]=\"lintDialogTitle\"\n [(visible)]=\"lintDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n [style]=\"{ width: '46rem', maxHeight: '80vh' }\"\n (onHide)=\"onLintDialogClose()\">\n <div class=\"workflow-lint-summary\">\n @if (lintErrorCount) {\n <span class=\"workflow-lint-count workflow-lint-count-error\">\n <i class=\"pi pi-times-circle\"></i> {{ lintErrorCount }} {{ lintErrorsCountLabel }}\n </span>\n }\n @if (lintWarnCount) {\n <span class=\"workflow-lint-count workflow-lint-count-warn\">\n <i class=\"pi pi-exclamation-triangle\"></i> {{ lintWarnCount }} {{ lintWarningsCountLabel }}\n </span>\n }\n </div>\n <ul class=\"workflow-lint-list\">\n @for (finding of lintFindings; track $index) {\n <li\n class=\"workflow-lint-item\"\n [ngClass]=\"finding.severity === 'error' ? 'workflow-lint-item-error' : 'workflow-lint-item-warn'\"\n [class.workflow-lint-item-clickable]=\"!!finding.nodeId\"\n (click)=\"zoomToLintFinding(finding)\">\n <i [class]=\"finding.severity === 'error' ? 'pi pi-times-circle' : 'pi pi-exclamation-triangle'\"></i>\n <span class=\"workflow-lint-code\">{{ finding.code }}</span>\n <span class=\"workflow-lint-message\">{{ finding.message }}</span>\n </li>\n }\n </ul>\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"onLintDialogClose()\">\n {{ lintDialogMode === 'confirm-save' ? ('cancel' | translate) : ('close' | translate) }}\n </button>\n @if (lintDialogMode === 'confirm-save') {\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"onLintDialogSaveAnyway()\">\n {{ lintSaveAnywayLabel }}\n </button>\n }\n </div>\n</p-dialog>\n\n<!-- Guida rapida: legenda tipi nodo (dal nodeRegistry) + glossario workflow. -->\n<p-dialog\n [header]=\"quickGuideTitle\"\n [(visible)]=\"quickGuideDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n styleClass=\"workflow-quick-guide-dialog\"\n [style]=\"{ width: '52rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <div class=\"workflow-guide-section-title\">{{ quickGuideLegendTitle }}</div>\n <div class=\"workflow-guide-legend\">\n @for (entry of guideLegendEntries; track entry.type) {\n <div class=\"workflow-guide-legend-item\">\n <span class=\"workflow-guide-legend-chip\" [style.background]=\"entry.background\" [style.borderColor]=\"entry.accent\" [style.color]=\"entry.accent\">\n {{ entry.label }}\n </span>\n <span class=\"workflow-guide-legend-desc\">{{ entry.description }}</span>\n </div>\n }\n </div>\n <div class=\"workflow-guide-section-title\">{{ quickGuideGlossaryTitle }}</div>\n <dl class=\"workflow-guide-glossary\">\n @for (entry of guideGlossaryEntries; track entry.term) {\n <dt>{{ entry.term }}</dt>\n <dd>{{ entry.text }}</dd>\n }\n </dl>\n</p-dialog>\n", styles: [":host{display:block;height:100%}.workflow-designer{display:grid;grid-template-rows:auto 1fr;grid-template-columns:260px 1fr;gap:12px;height:100%;min-height:520px}.workflow-toolbar{grid-column:1 / span 2;display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;padding:10px 12px}.workflow-toolbar label{font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-toolbar input{height:30px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;min-width:170px}.workflow-toolbar button{height:30px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.workflow-toolbar button[disabled]{opacity:.6;cursor:not-allowed}.workflow-toolbar-menu-group{display:inline-flex}.workflow-toolbar-filter{display:inline-flex;align-items:center}.workflow-toolbar-filter ::ng-deep .p-select{min-width:170px;font-size:.82rem}.workflow-current-graph{flex:1 1 auto;min-width:240px;font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-palette{border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;overflow:auto}.workflow-palette-title{padding:10px 12px;font-size:.86rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#3d4f67;border-bottom:1px solid #d5dce6}.workflow-palette-list{display:flex;flex-direction:column;gap:8px;padding:10px}.workflow-palette-item{border:1px solid #c8d3e2;border-radius:8px;background:#fff;padding:10px;cursor:grab;-webkit-user-select:none;user-select:none}.workflow-palette-item-badge{display:inline-block;margin-top:4px;margin-bottom:4px;padding:2px 7px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;background:#e2e8f0;color:#334155}.workflow-palette-item-route{border-color:#93c5fd;background:#eff6ff}.workflow-palette-item-route .workflow-palette-item-badge{background:#dbeafe;color:#1d4ed8}.workflow-palette-item-action{border-color:#c4b5fd;background:#f5f3ff}.workflow-palette-item-action .workflow-palette-item-badge{background:#ede9fe;color:#6d28d9}.workflow-palette-item-start{border-color:#86efac;background:#f0fdf4}.workflow-palette-item-condition{border-color:#99f6e4;background:#f0fdfa}.workflow-palette-item-end{border-color:#fda4af;background:#fff1f2}.workflow-palette-item:active{cursor:grabbing}.workflow-palette-item-disabled{opacity:.6;cursor:not-allowed;filter:grayscale(.2)}:host-context(.theme-dark) .workflow-palette-item-disabled{opacity:.5}.workflow-palette-item-title{font-size:.94rem;font-weight:600;color:#21324a}.workflow-palette-item-description{margin-top:4px;font-size:.82rem;color:#60738f}.workflow-canvas{position:relative;border:1px solid #d5dce6;border-radius:10px;overflow:hidden;background:radial-gradient(circle at 1px 1px,#dbe3ef 1px,transparent 0);background-size:24px 24px;background-color:#f8fbff;user-select:none;-webkit-user-select:none}.workflow-canvas-hint{position:absolute;right:12px;bottom:12px;font-size:.82rem;color:#60738f;background:#ffffffeb;border:1px solid #d5dce6;border-radius:6px;padding:5px 8px}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-input{width:100%;height:34px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;color:#1f2f49}.workflow-options-toggle{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-toggle input[type=checkbox]{width:16px;height:16px}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid #c7d2e2;background:#fff;color:#1f2f49;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}:host ::ng-deep .workflow-route-metadata-dialog.p-dialog{max-height:calc(100vh - 2rem)}:host ::ng-deep .workflow-route-metadata-dialog .p-dialog-content{overflow:visible;max-height:calc(100vh - 10rem)}:host ::ng-deep .workflow-canvas [data-wf-node-type] .node{border:1px solid var(--wf-node-accent, #64748b)!important;background:var(--wf-node-bg, #f8fafc)!important}:host ::ng-deep .workflow-canvas [data-wf-node-type] .title{background:var(--wf-node-accent, #64748b)!important;color:#fff!important;font-weight:700}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=col] .node{border-style:dashed!important}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=tab] .node{border-style:solid!important}:host-context(.theme-dark) .workflow-toolbar{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-current-graph,:host-context(.theme-dark) .workflow-toolbar label{color:#d8e2f1}:host-context(.theme-dark) .workflow-toolbar input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .workflow-toolbar button{border-color:#335fcf;background:#335fcf}:host-context(.theme-dark) .workflow-palette{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-palette-title{color:#dbe4f2;border-bottom-color:#2a3447}:host-context(.theme-dark) .workflow-palette-item{border-color:#334155;background:#0f1724}:host-context(.theme-dark) .workflow-palette-item-title{color:#e6edf8}:host-context(.theme-dark) .workflow-palette-item-description{color:#9fb0c7}:host-context(.theme-dark) .workflow-palette-item-badge{background:#273247;color:#c9d7ec}:host-context(.theme-dark) .workflow-palette-item-route{border-color:#3b82f6;background:#0f1f35}:host-context(.theme-dark) .workflow-palette-item-route .workflow-palette-item-badge{background:#1e3a6a;color:#c8ddff}:host-context(.theme-dark) .workflow-palette-item-action{border-color:#8b5cf6;background:#24183d}:host-context(.theme-dark) .workflow-palette-item-action .workflow-palette-item-badge{background:#3a2370;color:#ded1ff}:host-context(.theme-dark) .workflow-palette-item-start{border-color:#22c55e;background:#11281c}:host-context(.theme-dark) .workflow-palette-item-condition{border-color:#14b8a6;background:#0f2726}:host-context(.theme-dark) .workflow-palette-item-end{border-color:#ef4444;background:#30171b}:host-context(.theme-dark) .workflow-canvas{border-color:#2a3447;background:radial-gradient(circle at 1px 1px,#334155 1px,transparent 0);background-size:24px 24px;background-color:#0f1724}:host-context(.theme-dark) .workflow-canvas-hint{color:#b9c8de;background:#0f1724e6;border-color:#334155}:host-context(.theme-dark) .route-popup-form label,:host-context(.theme-dark) .workflow-options-toggle{color:#d8e2f1}:host-context(.theme-dark) .workflow-options-input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .route-popup-btn{border-color:#334155;background:#111b2b;color:#d8e2f1}:host-context(.theme-dark) .route-popup-btn-primary{border-color:#335fcf;background:#335fcf;color:#fff}:host-context(.theme-dark) ::ng-deep .p-menu,:host-context(.theme-dark) ::ng-deep .p-contextmenu{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content{color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content:hover,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content:hover{background:#1f2a3d}:host-context(.theme-dark) ::ng-deep .p-dialog{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-header,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-content,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-footer{background:#121b2b;color:#dbe4f2;border-color:#334155}.workflow-canvas-checklist{position:absolute;right:18px;bottom:18px;max-width:340px;padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;background:#fffffff0;color:#334155;font-size:12.5px;line-height:1.5;box-shadow:0 4px 14px #0f172a14;pointer-events:auto;z-index:5}.workflow-canvas-checklist-title{font-weight:700;margin-bottom:6px;color:#0f172a}.workflow-canvas-checklist ol{margin:0 0 8px;padding-left:18px}.workflow-canvas-checklist li{margin:2px 0}.workflow-canvas-checklist-done{text-decoration:line-through;opacity:.55}.workflow-canvas-checklist-link{border:none;background:none;padding:0;color:#2563eb;cursor:pointer;font-size:12.5px;text-decoration:underline}:host-context(.theme-dark) .workflow-canvas-checklist{background:#121b2bf0;border-color:#334155;color:#cbd5e1}:host-context(.theme-dark) .workflow-canvas-checklist-title{color:#e2e8f0}.workflow-lint-summary{display:flex;gap:14px;margin-bottom:10px;font-size:12.5px}.workflow-lint-count{display:inline-flex;align-items:center;gap:6px;font-weight:600}.workflow-lint-count-error{color:#dc2626}.workflow-lint-count-warn{color:#d97706}.workflow-lint-list{list-style:none;margin:0 0 12px;padding:0;max-height:46vh;overflow:auto}.workflow-lint-item{display:flex;align-items:flex-start;gap:8px;padding:7px 8px;border-radius:6px;font-size:12.5px;line-height:1.45}.workflow-lint-item+.workflow-lint-item{margin-top:4px}.workflow-lint-item-error{background:#fef2f2;color:#7f1d1d}.workflow-lint-item-error .pi{color:#dc2626;margin-top:2px}.workflow-lint-item-warn{background:#fffbeb;color:#78350f}.workflow-lint-item-warn .pi{color:#d97706;margin-top:2px}.workflow-lint-item-clickable{cursor:pointer}.workflow-lint-item-clickable:hover{filter:brightness(.97)}.workflow-lint-code{font-family:monospace;font-size:11px;opacity:.75;white-space:nowrap;margin-top:1px}:host-context(.theme-dark) .workflow-lint-item-error{background:#dc26261f;color:#fca5a5}:host-context(.theme-dark) .workflow-lint-item-warn{background:#d977061f;color:#fcd34d}.workflow-guide-section-title{font-weight:700;font-size:13px;margin:10px 0 8px;color:#0f172a}.workflow-guide-legend{display:grid;grid-template-columns:1fr 1fr;gap:8px 18px;margin-bottom:8px}.workflow-guide-legend-item{display:flex;align-items:center;gap:8px;font-size:12.5px}.workflow-guide-legend-chip{display:inline-block;min-width:74px;text-align:center;padding:3px 8px;border:1.5px solid;border-radius:7px;font-weight:700;font-size:11.5px;white-space:nowrap}.workflow-guide-legend-desc{color:#475569;line-height:1.4}.workflow-guide-glossary{margin:0;font-size:12.5px}.workflow-guide-glossary dt{font-weight:700;margin-top:8px;color:#0f172a}.workflow-guide-glossary dd{margin:2px 0 0;color:#475569;line-height:1.5}:host-context(.theme-dark) .workflow-guide-section-title,:host-context(.theme-dark) .workflow-guide-glossary dt{color:#e2e8f0}:host-context(.theme-dark) .workflow-guide-legend-desc,:host-context(.theme-dark) .workflow-guide-glossary dd{color:#94a3b8}::ng-deep .workflow-palette-tooltip .p-tooltip-text{max-width:340px;font-size:12px;line-height:1.45}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2$1.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i7$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i14.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: DataSourceComponent, selector: "wuic-data-source", inputs: ["route", "routeFromRouting", "hardcodedRoute", "autoload", "loading", "changeTracking", "parentRecord", "parentMetaInfo", "parentDatasource", "useComboEndpoint", "comboFormulaLookup", "comboMcId", "comboField", "comboExtraFields", "comboCurrentRecord", "componentRef"] }, { kind: "component", type: MetadataEditorComponent, selector: "wuic-metadata-editor", inputs: ["datasource", "hardcodedDatasource", "saveCallback", "hideReports", "hideRelatedTableActions", "hideRelatedColumnActions"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
|
|
9473
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WorkflowDesignerComponent, isStandalone: true, selector: "wuic-workflow-designer", outputs: { workflowChange: "workflowChange" }, viewQueries: [{ propertyName: "workflowCanvasRef", first: true, predicate: ["workflowCanvas"], descendants: true, static: true }, { propertyName: "primeContextMenu", first: true, predicate: ["primeContextMenu"], descendants: true }, { propertyName: "routeMetadataDs", first: true, predicate: ["routeMetadataDs"], descendants: true }, { propertyName: "startMenuDs", first: true, predicate: ["startMenuDs"], descendants: true }, { propertyName: "menuAuthDs", first: true, predicate: ["menuAuthDs"], descendants: true }, { propertyName: "routeMetadataEditor", first: true, predicate: ["routeMetadataEditor"], descendants: true }, { propertyName: "actionMetadataEditor", first: true, predicate: ["actionMetadataEditor"], descendants: true }], ngImport: i0, template: "<div class=\"workflow-designer\">\r\n <div class=\"workflow-toolbar\">\r\n <div class=\"workflow-current-graph\">{{ currentGraphCaption }}</div>\r\n <!-- Filtro \"anteprima autorizzazioni\": simula cosa vede un ruolo/utente.\r\n Opzioni dai principal citati nel grafo (permessi bundle + permission\r\n transizioni); il dropdown utenti appare solo se esistono auth\r\n per-utente. Selezione vuota = mostra tutto. -->\r\n @if (authFilterRoleOptions.length > 1) {\r\n <div class=\"workflow-toolbar-filter\">\r\n <p-select\r\n [options]=\"authFilterRoleOptions\"\r\n [(ngModel)]=\"authFilterRoleId\"\r\n (onChange)=\"onAuthFilterChanged('role')\"\r\n appendTo=\"body\"\r\n data-testid=\"wf-auth-filter-role\" />\r\n </div>\r\n }\r\n @if (authFilterUserOptions.length > 1) {\r\n <div class=\"workflow-toolbar-filter\">\r\n <p-select\r\n [options]=\"authFilterUserOptions\"\r\n [(ngModel)]=\"authFilterUserId\"\r\n (onChange)=\"onAuthFilterChanged('user')\"\r\n appendTo=\"body\"\r\n data-testid=\"wf-auth-filter-user\" />\r\n </div>\r\n }\r\n <div class=\"workflow-toolbar-menu-group\">\r\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">\r\n Azioni grafo\r\n </button>\r\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\r\n </div>\r\n <div class=\"workflow-toolbar-menu-group\">\r\n <button type=\"button\" (click)=\"runnerActionsMenu.toggle($event)\" [disabled]=\"!canOpenWorkflowRunner\">\r\n Runner\r\n </button>\r\n <p-menu #runnerActionsMenu [popup]=\"true\" [model]=\"runnerActionsMenuItems\" appendTo=\"body\"></p-menu>\r\n </div>\r\n </div>\r\n\r\n <aside class=\"workflow-palette\">\r\n <div class=\"workflow-palette-title\">{{ 'workflow.palette' | translate }}</div>\r\n <div class=\"workflow-palette-list\">\r\n @for (item of paletteNodes; track item) {\r\n <div\r\n class=\"workflow-palette-item\"\r\n [ngClass]=\"{\r\n 'workflow-palette-item-route': item.type === 'route',\r\n 'workflow-palette-item-action': item.type === 'action',\r\n 'workflow-palette-item-start': item.type === 'start',\r\n 'workflow-palette-item-condition': item.type === 'condition',\r\n 'workflow-palette-item-end': item.type === 'end',\r\n 'workflow-palette-item-disabled': !isPaletteNodeEnabled(item)\r\n }\"\r\n [attr.draggable]=\"isPaletteNodeEnabled(item) ? 'true' : 'false'\"\r\n (dragstart)=\"onPaletteDragStart($event, item)\"\r\n [pTooltip]=\"item.tooltip || ''\"\r\n [escape]=\"false\"\r\n tooltipPosition=\"right\"\r\n [tooltipStyleClass]=\"'workflow-palette-tooltip'\">\r\n <div class=\"workflow-palette-item-title\">{{ item.label }}</div>\r\n @if (item.type === 'route') {\r\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.route' | translate }}</div>\r\n }\r\n @if (item.type === 'action') {\r\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.action_scope' | translate }}</div>\r\n }\r\n <div class=\"workflow-palette-item-description\">{{ item.description }}</div>\r\n </div>\r\n }\r\n </div>\r\n </aside>\r\n\r\n <section\r\n #workflowCanvas\r\n class=\"workflow-canvas\"\r\n (dragover)=\"onCanvasDragOver($event)\"\r\n (drop)=\"onCanvasDrop($event)\"\r\n (contextmenu)=\"onCanvasContextMenu($event)\"\r\n (click)=\"onCanvasClick()\">\r\n @if (showEmptyGraphChecklist) {\r\n <div class=\"workflow-canvas-checklist\">\r\n <div class=\"workflow-canvas-checklist-title\">{{ hintChecklistTitle }}</div>\r\n <ol>\r\n @for (step of hintChecklistStepStates; track $index) {\r\n <li [ngClass]=\"{ 'workflow-canvas-checklist-done': step.done }\">{{ step.text }}</li>\r\n }\r\n </ol>\r\n @if (showChecklistTemplateLink) {\r\n <button type=\"button\" class=\"workflow-canvas-checklist-link\" (click)=\"createWorkflowFromTemplate()\">\r\n {{ hintOrTemplateLabel }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </section>\r\n <p-contextMenu\r\n #primeContextMenu\r\n [model]=\"contextMenuItems\"\r\n appendTo=\"body\"\r\n [autoZIndex]=\"true\"\r\n [baseZIndex]=\"13000\">\r\n </p-contextMenu>\r\n</div>\r\n\r\n<p-dialog\r\n [header]=\"'Riapri grafo'\"\r\n [(visible)]=\"reopenWorkflowDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n [style]=\"{ width: '34rem' }\"\r\n (onHide)=\"cancelReopenWorkflowDialog()\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-reopen-select\">Grafi esistenti</label>\r\n <p-select\r\n inputId=\"workflow-reopen-select\"\r\n [options]=\"savedGraphOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"reopenDialogSelectedGraphKey\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenWorkflowDialog()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenWorkflowDialog()\"\r\n [disabled]=\"!reopenDialogSelectedGraphKey || loadingWorkflow\">Riapri</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<div style=\"display:none\">\r\n <wuic-data-source #routeMetadataDs [hardcodedRoute]=\"routeMetadataRoute\"></wuic-data-source>\r\n <wuic-data-source #startMenuDs [hardcodedRoute]=\"' metadati menu'\"></wuic-data-source>\r\n <wuic-data-source #menuAuthDs [hardcodedRoute]=\"' mtdt tnt trizzazioni menus'\"></wuic-data-source>\r\n @if (routeMetadataDs) {\r\n <wuic-metadata-editor\r\n #actionMetadataEditor\r\n [hardcodedDatasource]=\"routeMetadataDs!\"\r\n [saveCallback]=\"routeMetadataSaveCallback\"\r\n [hideReports]=\"true\"\r\n [hideRelatedTableActions]=\"true\"\r\n [hideRelatedColumnActions]=\"true\">\r\n </wuic-metadata-editor>\r\n }\r\n</div>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.configure_route' | translate\"\r\n [(visible)]=\"routePopupVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-route-source-select\">Sorgente nodo</label>\r\n <p-select\r\n inputId=\"workflow-route-source-select\"\r\n [options]=\"routeSourceOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedRouteSourceType\"\r\n (ngModelChange)=\"onRouteSourceTypeChanged()\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n @if (selectedRouteSourceType === 'route') {\r\n <label for=\"workflow-route-select\">{{ 'workflow.route' | translate }}</label>\r\n <p-autoComplete\r\n inputId=\"workflow-route-select\"\r\n [(ngModel)]=\"selectedRouteName\"\r\n [suggestions]=\"filteredRouteOptions\"\r\n [forceSelection]=\"true\"\r\n [dropdown]=\"true\"\r\n dropdownMode=\"current\"\r\n [optionLabel]=\"'label'\"\r\n [optionValue]=\"'value'\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\"\r\n (completeMethod)=\"filterRouteOptions($event)\" />\r\n <label for=\"workflow-action-select\">{{ 'workflow.action' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-select\"\r\n [options]=\"routeActionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedRouteAction\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n } @else {\r\n <label for=\"workflow-dashboard-select\">Dashboard</label>\r\n <p-autoComplete\r\n inputId=\"workflow-dashboard-select\"\r\n [(ngModel)]=\"selectedDashboardRoute\"\r\n [suggestions]=\"filteredDashboardOptions\"\r\n [forceSelection]=\"true\"\r\n [dropdown]=\"true\"\r\n dropdownMode=\"current\"\r\n [optionLabel]=\"'label'\"\r\n [optionValue]=\"'value'\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\"\r\n (completeMethod)=\"filterDashboardOptions($event)\" />\r\n }\r\n\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelRouteDrop()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmRouteDrop()\"\r\n [disabled]=\"selectedRouteSourceType === 'dashboard' ? !selectedDashboardRoute : (!selectedRouteName || !selectedRouteAction)\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.metadata_route' | translate\"\r\n [(visible)]=\"routeMetadataDialogVisible\"\r\n [modal]=\"true\"\r\n position=\"top\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n styleClass=\"workflow-route-metadata-dialog\"\r\n [style]=\"{ width: '78rem', maxHeight: 'calc(100vh - 2rem)' }\"\r\n [contentStyle]=\"{ overflow: 'visible', maxHeight: 'calc(100vh - 10rem)' }\">\r\n @if (routeMetadataDialogVisible && routeMetadataDs) {\r\n <wuic-metadata-editor\r\n #routeMetadataEditor\r\n [hardcodedDatasource]=\"routeMetadataDs!\"\r\n [saveCallback]=\"routeMetadataSaveCallback\"\r\n [hideReports]=\"true\"\r\n [hideRelatedTableActions]=\"false\"\r\n [hideRelatedColumnActions]=\"false\">\r\n </wuic-metadata-editor>\r\n }\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.configure_action' | translate\"\r\n [(visible)]=\"actionPopupVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-action-scope-select\">{{ 'workflow.action_scope' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-scope-select\"\r\n [options]=\"actionScopeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedActionScopeId\"\r\n (onChange)=\"onActionScopeChanged()\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <label for=\"workflow-action-type-select\">{{ 'workflow.action_type' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-type-select\"\r\n [options]=\"visibleActionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedActionTypeId\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelActionDrop()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmActionDrop()\"\r\n [disabled]=\"selectedActionTypeId === null || selectedActionTypeId === undefined || selectedActionScopeId === null || selectedActionScopeId === undefined\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'Opzioni workflow'\"\r\n [(visible)]=\"workflowOptionsDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-options-caption\">Caption menu start</label>\r\n <input\r\n id=\"workflow-options-caption\"\r\n class=\"workflow-options-input\"\r\n type=\"text\"\r\n [(ngModel)]=\"workflowOptionsCaption\" />\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsInheritMetadata\" />\r\n <span>Eredita metadati</span>\r\n </label>\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsExclusiveMenu\" />\r\n <span>Menu esclusivo</span>\r\n </label>\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsShowExit\" />\r\n <span>Mostra esci</span>\r\n </label>\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelWorkflowOptionsDialog()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmWorkflowOptionsDialog()\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<!-- Lint del grafo: elenco findings (on-demand \"Valida grafo\" o conferma pre-save).\r\n Il save non e' mai bloccato: con findings serve la conferma esplicita. -->\r\n<p-dialog\r\n [header]=\"lintDialogTitle\"\r\n [(visible)]=\"lintDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n [style]=\"{ width: '46rem', maxHeight: '80vh' }\"\r\n (onHide)=\"onLintDialogClose()\">\r\n <div class=\"workflow-lint-summary\">\r\n @if (lintErrorCount) {\r\n <span class=\"workflow-lint-count workflow-lint-count-error\">\r\n <i class=\"pi pi-times-circle\"></i> {{ lintErrorCount }} {{ lintErrorsCountLabel }}\r\n </span>\r\n }\r\n @if (lintWarnCount) {\r\n <span class=\"workflow-lint-count workflow-lint-count-warn\">\r\n <i class=\"pi pi-exclamation-triangle\"></i> {{ lintWarnCount }} {{ lintWarningsCountLabel }}\r\n </span>\r\n }\r\n </div>\r\n <ul class=\"workflow-lint-list\">\r\n @for (finding of lintFindings; track $index) {\r\n <li\r\n class=\"workflow-lint-item\"\r\n [ngClass]=\"finding.severity === 'error' ? 'workflow-lint-item-error' : 'workflow-lint-item-warn'\"\r\n [class.workflow-lint-item-clickable]=\"!!finding.nodeId\"\r\n (click)=\"zoomToLintFinding(finding)\">\r\n <i [class]=\"finding.severity === 'error' ? 'pi pi-times-circle' : 'pi pi-exclamation-triangle'\"></i>\r\n <span class=\"workflow-lint-code\">{{ finding.code }}</span>\r\n <span class=\"workflow-lint-message\">{{ finding.message }}</span>\r\n </li>\r\n }\r\n </ul>\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"onLintDialogClose()\">\r\n {{ lintDialogMode === 'confirm-save' ? ('cancel' | translate) : ('close' | translate) }}\r\n </button>\r\n @if (lintDialogMode === 'confirm-save') {\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"onLintDialogSaveAnyway()\">\r\n {{ lintSaveAnywayLabel }}\r\n </button>\r\n }\r\n </div>\r\n</p-dialog>\r\n\r\n<!-- Guida rapida: legenda tipi nodo (dal nodeRegistry) + glossario workflow. -->\r\n<p-dialog\r\n [header]=\"quickGuideTitle\"\r\n [(visible)]=\"quickGuideDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n styleClass=\"workflow-quick-guide-dialog\"\r\n [style]=\"{ width: '52rem', maxHeight: '85vh' }\"\r\n [contentStyle]=\"{ overflow: 'auto' }\">\r\n <div class=\"workflow-guide-section-title\">{{ quickGuideLegendTitle }}</div>\r\n <div class=\"workflow-guide-legend\">\r\n @for (entry of guideLegendEntries; track entry.type) {\r\n <div class=\"workflow-guide-legend-item\">\r\n <span class=\"workflow-guide-legend-chip\" [style.background]=\"entry.background\" [style.borderColor]=\"entry.accent\" [style.color]=\"entry.accent\">\r\n {{ entry.label }}\r\n </span>\r\n <span class=\"workflow-guide-legend-desc\">{{ entry.description }}</span>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"workflow-guide-section-title\">{{ quickGuideGlossaryTitle }}</div>\r\n <dl class=\"workflow-guide-glossary\">\r\n @for (entry of guideGlossaryEntries; track entry.term) {\r\n <dt>{{ entry.term }}</dt>\r\n <dd>{{ entry.text }}</dd>\r\n }\r\n </dl>\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%}.workflow-designer{display:grid;grid-template-rows:auto 1fr;grid-template-columns:260px 1fr;gap:12px;height:100%;min-height:520px}.workflow-toolbar{grid-column:1 / span 2;display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;padding:10px 12px}.workflow-toolbar label{font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-toolbar input{height:30px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;min-width:170px}.workflow-toolbar button{height:30px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.workflow-toolbar button[disabled]{opacity:.6;cursor:not-allowed}.workflow-toolbar-menu-group{display:inline-flex}.workflow-toolbar-filter{display:inline-flex;align-items:center}.workflow-toolbar-filter ::ng-deep .p-select{min-width:170px;font-size:.82rem}.workflow-current-graph{flex:1 1 auto;min-width:240px;font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-palette{border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;overflow:auto}.workflow-palette-title{padding:10px 12px;font-size:.86rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#3d4f67;border-bottom:1px solid #d5dce6}.workflow-palette-list{display:flex;flex-direction:column;gap:8px;padding:10px}.workflow-palette-item{border:1px solid #c8d3e2;border-radius:8px;background:#fff;padding:10px;cursor:grab;-webkit-user-select:none;user-select:none}.workflow-palette-item-badge{display:inline-block;margin-top:4px;margin-bottom:4px;padding:2px 7px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;background:#e2e8f0;color:#334155}.workflow-palette-item-route{border-color:#93c5fd;background:#eff6ff}.workflow-palette-item-route .workflow-palette-item-badge{background:#dbeafe;color:#1d4ed8}.workflow-palette-item-action{border-color:#c4b5fd;background:#f5f3ff}.workflow-palette-item-action .workflow-palette-item-badge{background:#ede9fe;color:#6d28d9}.workflow-palette-item-start{border-color:#86efac;background:#f0fdf4}.workflow-palette-item-condition{border-color:#99f6e4;background:#f0fdfa}.workflow-palette-item-end{border-color:#fda4af;background:#fff1f2}.workflow-palette-item:active{cursor:grabbing}.workflow-palette-item-disabled{opacity:.6;cursor:not-allowed;filter:grayscale(.2)}:host-context(.theme-dark) .workflow-palette-item-disabled{opacity:.5}.workflow-palette-item-title{font-size:.94rem;font-weight:600;color:#21324a}.workflow-palette-item-description{margin-top:4px;font-size:.82rem;color:#60738f}.workflow-canvas{position:relative;border:1px solid #d5dce6;border-radius:10px;overflow:hidden;background:radial-gradient(circle at 1px 1px,#dbe3ef 1px,transparent 0);background-size:24px 24px;background-color:#f8fbff;user-select:none;-webkit-user-select:none}.workflow-canvas-hint{position:absolute;right:12px;bottom:12px;font-size:.82rem;color:#60738f;background:#ffffffeb;border:1px solid #d5dce6;border-radius:6px;padding:5px 8px}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-input{width:100%;height:34px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;color:#1f2f49}.workflow-options-toggle{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-toggle input[type=checkbox]{width:16px;height:16px}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid #c7d2e2;background:#fff;color:#1f2f49;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}:host ::ng-deep .workflow-route-metadata-dialog.p-dialog{max-height:calc(100vh - 2rem)}:host ::ng-deep .workflow-route-metadata-dialog .p-dialog-content{overflow:visible;max-height:calc(100vh - 10rem)}:host ::ng-deep .workflow-canvas [data-wf-node-type] .node{border:1px solid var(--wf-node-accent, #64748b)!important;background:var(--wf-node-bg, #f8fafc)!important}:host ::ng-deep .workflow-canvas [data-wf-node-type] .title{background:var(--wf-node-accent, #64748b)!important;color:#fff!important;font-weight:700}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=col] .node{border-style:dashed!important}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=tab] .node{border-style:solid!important}:host-context(.theme-dark) .workflow-toolbar{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-current-graph,:host-context(.theme-dark) .workflow-toolbar label{color:#d8e2f1}:host-context(.theme-dark) .workflow-toolbar input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .workflow-toolbar button{border-color:#335fcf;background:#335fcf}:host-context(.theme-dark) .workflow-palette{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-palette-title{color:#dbe4f2;border-bottom-color:#2a3447}:host-context(.theme-dark) .workflow-palette-item{border-color:#334155;background:#0f1724}:host-context(.theme-dark) .workflow-palette-item-title{color:#e6edf8}:host-context(.theme-dark) .workflow-palette-item-description{color:#9fb0c7}:host-context(.theme-dark) .workflow-palette-item-badge{background:#273247;color:#c9d7ec}:host-context(.theme-dark) .workflow-palette-item-route{border-color:#3b82f6;background:#0f1f35}:host-context(.theme-dark) .workflow-palette-item-route .workflow-palette-item-badge{background:#1e3a6a;color:#c8ddff}:host-context(.theme-dark) .workflow-palette-item-action{border-color:#8b5cf6;background:#24183d}:host-context(.theme-dark) .workflow-palette-item-action .workflow-palette-item-badge{background:#3a2370;color:#ded1ff}:host-context(.theme-dark) .workflow-palette-item-start{border-color:#22c55e;background:#11281c}:host-context(.theme-dark) .workflow-palette-item-condition{border-color:#14b8a6;background:#0f2726}:host-context(.theme-dark) .workflow-palette-item-end{border-color:#ef4444;background:#30171b}:host-context(.theme-dark) .workflow-canvas{border-color:#2a3447;background:radial-gradient(circle at 1px 1px,#334155 1px,transparent 0);background-size:24px 24px;background-color:#0f1724}:host-context(.theme-dark) .workflow-canvas-hint{color:#b9c8de;background:#0f1724e6;border-color:#334155}:host-context(.theme-dark) .route-popup-form label,:host-context(.theme-dark) .workflow-options-toggle{color:#d8e2f1}:host-context(.theme-dark) .workflow-options-input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .route-popup-btn{border-color:#334155;background:#111b2b;color:#d8e2f1}:host-context(.theme-dark) .route-popup-btn-primary{border-color:#335fcf;background:#335fcf;color:#fff}:host-context(.theme-dark) ::ng-deep .p-menu,:host-context(.theme-dark) ::ng-deep .p-contextmenu{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content{color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content:hover,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content:hover{background:#1f2a3d}:host-context(.theme-dark) ::ng-deep .p-dialog{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-header,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-content,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-footer{background:#121b2b;color:#dbe4f2;border-color:#334155}.workflow-canvas-checklist{position:absolute;right:18px;bottom:18px;max-width:340px;padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;background:#fffffff0;color:#334155;font-size:12.5px;line-height:1.5;box-shadow:0 4px 14px #0f172a14;pointer-events:auto;z-index:5}.workflow-canvas-checklist-title{font-weight:700;margin-bottom:6px;color:#0f172a}.workflow-canvas-checklist ol{margin:0 0 8px;padding-left:18px}.workflow-canvas-checklist li{margin:2px 0}.workflow-canvas-checklist-done{text-decoration:line-through;opacity:.55}.workflow-canvas-checklist-link{border:none;background:none;padding:0;color:#2563eb;cursor:pointer;font-size:12.5px;text-decoration:underline}:host-context(.theme-dark) .workflow-canvas-checklist{background:#121b2bf0;border-color:#334155;color:#cbd5e1}:host-context(.theme-dark) .workflow-canvas-checklist-title{color:#e2e8f0}.workflow-lint-summary{display:flex;gap:14px;margin-bottom:10px;font-size:12.5px}.workflow-lint-count{display:inline-flex;align-items:center;gap:6px;font-weight:600}.workflow-lint-count-error{color:#dc2626}.workflow-lint-count-warn{color:#d97706}.workflow-lint-list{list-style:none;margin:0 0 12px;padding:0;max-height:46vh;overflow:auto}.workflow-lint-item{display:flex;align-items:flex-start;gap:8px;padding:7px 8px;border-radius:6px;font-size:12.5px;line-height:1.45}.workflow-lint-item+.workflow-lint-item{margin-top:4px}.workflow-lint-item-error{background:#fef2f2;color:#7f1d1d}.workflow-lint-item-error .pi{color:#dc2626;margin-top:2px}.workflow-lint-item-warn{background:#fffbeb;color:#78350f}.workflow-lint-item-warn .pi{color:#d97706;margin-top:2px}.workflow-lint-item-clickable{cursor:pointer}.workflow-lint-item-clickable:hover{filter:brightness(.97)}.workflow-lint-code{font-family:monospace;font-size:11px;opacity:.75;white-space:nowrap;margin-top:1px}:host-context(.theme-dark) .workflow-lint-item-error{background:#dc26261f;color:#fca5a5}:host-context(.theme-dark) .workflow-lint-item-warn{background:#d977061f;color:#fcd34d}.workflow-guide-section-title{font-weight:700;font-size:13px;margin:10px 0 8px;color:#0f172a}.workflow-guide-legend{display:grid;grid-template-columns:1fr 1fr;gap:8px 18px;margin-bottom:8px}.workflow-guide-legend-item{display:flex;align-items:center;gap:8px;font-size:12.5px}.workflow-guide-legend-chip{display:inline-block;min-width:74px;text-align:center;padding:3px 8px;border:1.5px solid;border-radius:7px;font-weight:700;font-size:11.5px;white-space:nowrap}.workflow-guide-legend-desc{color:#475569;line-height:1.4}.workflow-guide-glossary{margin:0;font-size:12.5px}.workflow-guide-glossary dt{font-weight:700;margin-top:8px;color:#0f172a}.workflow-guide-glossary dd{margin:2px 0 0;color:#475569;line-height:1.5}:host-context(.theme-dark) .workflow-guide-section-title,:host-context(.theme-dark) .workflow-guide-glossary dt{color:#e2e8f0}:host-context(.theme-dark) .workflow-guide-legend-desc,:host-context(.theme-dark) .workflow-guide-glossary dd{color:#94a3b8}::ng-deep .workflow-palette-tooltip .p-tooltip-text{max-width:340px;font-size:12px;line-height:1.45}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i2$1.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i7$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i14.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: DataSourceComponent, selector: "wuic-data-source", inputs: ["route", "routeFromRouting", "hardcodedRoute", "autoload", "loading", "changeTracking", "parentRecord", "parentMetaInfo", "parentDatasource", "useComboEndpoint", "comboFormulaLookup", "comboMcId", "comboField", "comboExtraFields", "comboCurrentRecord", "componentRef"] }, { kind: "component", type: MetadataEditorComponent, selector: "wuic-metadata-editor", inputs: ["datasource", "hardcodedDatasource", "saveCallback", "hideReports", "hideRelatedTableActions", "hideRelatedColumnActions"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
|
|
9474
9474
|
}
|
|
9475
9475
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowDesignerComponent, decorators: [{
|
|
9476
9476
|
type: Component,
|
|
9477
|
-
args: [{ selector: 'wuic-workflow-designer', standalone: true, imports: [NgClass, FormsModule, DialogModule, SelectModule, AutoCompleteModule, MenuModule, ContextMenuModule, TooltipModule, TranslateModule, DataSourceComponent, MetadataEditorComponent], template: "<div class=\"workflow-designer\">\n <div class=\"workflow-toolbar\">\n <div class=\"workflow-current-graph\">{{ currentGraphCaption }}</div>\n <!-- Filtro \"anteprima autorizzazioni\": simula cosa vede un ruolo/utente.\n Opzioni dai principal citati nel grafo (permessi bundle + permission\n transizioni); il dropdown utenti appare solo se esistono auth\n per-utente. Selezione vuota = mostra tutto. -->\n @if (authFilterRoleOptions.length > 1) {\n <div class=\"workflow-toolbar-filter\">\n <p-select\n [options]=\"authFilterRoleOptions\"\n [(ngModel)]=\"authFilterRoleId\"\n (onChange)=\"onAuthFilterChanged('role')\"\n appendTo=\"body\"\n data-testid=\"wf-auth-filter-role\" />\n </div>\n }\n @if (authFilterUserOptions.length > 1) {\n <div class=\"workflow-toolbar-filter\">\n <p-select\n [options]=\"authFilterUserOptions\"\n [(ngModel)]=\"authFilterUserId\"\n (onChange)=\"onAuthFilterChanged('user')\"\n appendTo=\"body\"\n data-testid=\"wf-auth-filter-user\" />\n </div>\n }\n <div class=\"workflow-toolbar-menu-group\">\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">\n Azioni grafo\n </button>\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n <div class=\"workflow-toolbar-menu-group\">\n <button type=\"button\" (click)=\"runnerActionsMenu.toggle($event)\" [disabled]=\"!canOpenWorkflowRunner\">\n Runner\n </button>\n <p-menu #runnerActionsMenu [popup]=\"true\" [model]=\"runnerActionsMenuItems\" appendTo=\"body\"></p-menu>\n </div>\n </div>\n\n <aside class=\"workflow-palette\">\n <div class=\"workflow-palette-title\">{{ 'workflow.palette' | translate }}</div>\n <div class=\"workflow-palette-list\">\n @for (item of paletteNodes; track item) {\n <div\n class=\"workflow-palette-item\"\n [ngClass]=\"{\n 'workflow-palette-item-route': item.type === 'route',\n 'workflow-palette-item-action': item.type === 'action',\n 'workflow-palette-item-start': item.type === 'start',\n 'workflow-palette-item-condition': item.type === 'condition',\n 'workflow-palette-item-end': item.type === 'end',\n 'workflow-palette-item-disabled': !isPaletteNodeEnabled(item)\n }\"\n [attr.draggable]=\"isPaletteNodeEnabled(item) ? 'true' : 'false'\"\n (dragstart)=\"onPaletteDragStart($event, item)\"\n [pTooltip]=\"item.tooltip || ''\"\n [escape]=\"false\"\n tooltipPosition=\"right\"\n [tooltipStyleClass]=\"'workflow-palette-tooltip'\">\n <div class=\"workflow-palette-item-title\">{{ item.label }}</div>\n @if (item.type === 'route') {\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.route' | translate }}</div>\n }\n @if (item.type === 'action') {\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.action_scope' | translate }}</div>\n }\n <div class=\"workflow-palette-item-description\">{{ item.description }}</div>\n </div>\n }\n </div>\n </aside>\n\n <section\n #workflowCanvas\n class=\"workflow-canvas\"\n (dragover)=\"onCanvasDragOver($event)\"\n (drop)=\"onCanvasDrop($event)\"\n (contextmenu)=\"onCanvasContextMenu($event)\"\n (click)=\"onCanvasClick()\">\n @if (showEmptyGraphChecklist) {\n <div class=\"workflow-canvas-checklist\">\n <div class=\"workflow-canvas-checklist-title\">{{ hintChecklistTitle }}</div>\n <ol>\n @for (step of hintChecklistStepStates; track $index) {\n <li [ngClass]=\"{ 'workflow-canvas-checklist-done': step.done }\">{{ step.text }}</li>\n }\n </ol>\n @if (showChecklistTemplateLink) {\n <button type=\"button\" class=\"workflow-canvas-checklist-link\" (click)=\"createWorkflowFromTemplate()\">\n {{ hintOrTemplateLabel }}\n </button>\n }\n </div>\n }\n </section>\n <p-contextMenu\n #primeContextMenu\n [model]=\"contextMenuItems\"\n appendTo=\"body\"\n [autoZIndex]=\"true\"\n [baseZIndex]=\"13000\">\n </p-contextMenu>\n</div>\n\n<p-dialog\n [header]=\"'Riapri grafo'\"\n [(visible)]=\"reopenWorkflowDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n [style]=\"{ width: '34rem' }\"\n (onHide)=\"cancelReopenWorkflowDialog()\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-reopen-select\">Grafi esistenti</label>\n <p-select\n inputId=\"workflow-reopen-select\"\n [options]=\"savedGraphOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"reopenDialogSelectedGraphKey\"\n [filter]=\"true\"\n [showClear]=\"true\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenWorkflowDialog()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenWorkflowDialog()\"\n [disabled]=\"!reopenDialogSelectedGraphKey || loadingWorkflow\">Riapri</button>\n </div>\n </div>\n</p-dialog>\n\n<div style=\"display:none\">\n <wuic-data-source #routeMetadataDs [hardcodedRoute]=\"routeMetadataRoute\"></wuic-data-source>\n <wuic-data-source #startMenuDs [hardcodedRoute]=\"' metadati menu'\"></wuic-data-source>\n <wuic-data-source #menuAuthDs [hardcodedRoute]=\"' mtdt tnt trizzazioni menus'\"></wuic-data-source>\n @if (routeMetadataDs) {\n <wuic-metadata-editor\n #actionMetadataEditor\n [hardcodedDatasource]=\"routeMetadataDs!\"\n [saveCallback]=\"routeMetadataSaveCallback\"\n [hideReports]=\"true\"\n [hideRelatedTableActions]=\"true\"\n [hideRelatedColumnActions]=\"true\">\n </wuic-metadata-editor>\n }\n</div>\n\n<p-dialog\n [header]=\"'workflow.configure_route' | translate\"\n [(visible)]=\"routePopupVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-route-source-select\">Sorgente nodo</label>\n <p-select\n inputId=\"workflow-route-source-select\"\n [options]=\"routeSourceOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedRouteSourceType\"\n (ngModelChange)=\"onRouteSourceTypeChanged()\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n @if (selectedRouteSourceType === 'route') {\n <label for=\"workflow-route-select\">{{ 'workflow.route' | translate }}</label>\n <p-autoComplete\n inputId=\"workflow-route-select\"\n [(ngModel)]=\"selectedRouteName\"\n [suggestions]=\"filteredRouteOptions\"\n [forceSelection]=\"true\"\n [dropdown]=\"true\"\n dropdownMode=\"current\"\n [optionLabel]=\"'label'\"\n [optionValue]=\"'value'\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\"\n (completeMethod)=\"filterRouteOptions($event)\" />\n <label for=\"workflow-action-select\">{{ 'workflow.action' | translate }}</label>\n <p-select\n inputId=\"workflow-action-select\"\n [options]=\"routeActionOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedRouteAction\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n } @else {\n <label for=\"workflow-dashboard-select\">Dashboard</label>\n <p-autoComplete\n inputId=\"workflow-dashboard-select\"\n [(ngModel)]=\"selectedDashboardRoute\"\n [suggestions]=\"filteredDashboardOptions\"\n [forceSelection]=\"true\"\n [dropdown]=\"true\"\n dropdownMode=\"current\"\n [optionLabel]=\"'label'\"\n [optionValue]=\"'value'\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\"\n (completeMethod)=\"filterDashboardOptions($event)\" />\n }\n\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelRouteDrop()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmRouteDrop()\"\n [disabled]=\"selectedRouteSourceType === 'dashboard' ? !selectedDashboardRoute : (!selectedRouteName || !selectedRouteAction)\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<p-dialog\n [header]=\"'workflow.metadata_route' | translate\"\n [(visible)]=\"routeMetadataDialogVisible\"\n [modal]=\"true\"\n position=\"top\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n styleClass=\"workflow-route-metadata-dialog\"\n [style]=\"{ width: '78rem', maxHeight: 'calc(100vh - 2rem)' }\"\n [contentStyle]=\"{ overflow: 'visible', maxHeight: 'calc(100vh - 10rem)' }\">\n @if (routeMetadataDialogVisible && routeMetadataDs) {\n <wuic-metadata-editor\n #routeMetadataEditor\n [hardcodedDatasource]=\"routeMetadataDs!\"\n [saveCallback]=\"routeMetadataSaveCallback\"\n [hideReports]=\"true\"\n [hideRelatedTableActions]=\"false\"\n [hideRelatedColumnActions]=\"false\">\n </wuic-metadata-editor>\n }\n</p-dialog>\n\n<p-dialog\n [header]=\"'workflow.configure_action' | translate\"\n [(visible)]=\"actionPopupVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-action-scope-select\">{{ 'workflow.action_scope' | translate }}</label>\n <p-select\n inputId=\"workflow-action-scope-select\"\n [options]=\"actionScopeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedActionScopeId\"\n (onChange)=\"onActionScopeChanged()\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <label for=\"workflow-action-type-select\">{{ 'workflow.action_type' | translate }}</label>\n <p-select\n inputId=\"workflow-action-type-select\"\n [options]=\"visibleActionTypeOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [(ngModel)]=\"selectedActionTypeId\"\n [style]=\"{ width: '100%' }\"\n appendTo=\"body\" />\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelActionDrop()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmActionDrop()\"\n [disabled]=\"selectedActionTypeId === null || selectedActionTypeId === undefined || selectedActionScopeId === null || selectedActionScopeId === undefined\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<p-dialog\n [header]=\"'Opzioni workflow'\"\n [(visible)]=\"workflowOptionsDialogVisible\"\n [modal]=\"true\"\n [closable]=\"false\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [style]=\"{ width: '32rem' }\">\n <div class=\"route-popup-form\">\n <label for=\"workflow-options-caption\">Caption menu start</label>\n <input\n id=\"workflow-options-caption\"\n class=\"workflow-options-input\"\n type=\"text\"\n [(ngModel)]=\"workflowOptionsCaption\" />\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsInheritMetadata\" />\n <span>Eredita metadati</span>\n </label>\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsExclusiveMenu\" />\n <span>Menu esclusivo</span>\n </label>\n\n <label class=\"workflow-options-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsShowExit\" />\n <span>Mostra esci</span>\n </label>\n\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelWorkflowOptionsDialog()\">{{ 'cancel' | translate }}</button>\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmWorkflowOptionsDialog()\">{{ 'confirmation' | translate }}</button>\n </div>\n </div>\n</p-dialog>\n\n<!-- Lint del grafo: elenco findings (on-demand \"Valida grafo\" o conferma pre-save).\n Il save non e' mai bloccato: con findings serve la conferma esplicita. -->\n<p-dialog\n [header]=\"lintDialogTitle\"\n [(visible)]=\"lintDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n [style]=\"{ width: '46rem', maxHeight: '80vh' }\"\n (onHide)=\"onLintDialogClose()\">\n <div class=\"workflow-lint-summary\">\n @if (lintErrorCount) {\n <span class=\"workflow-lint-count workflow-lint-count-error\">\n <i class=\"pi pi-times-circle\"></i> {{ lintErrorCount }} {{ lintErrorsCountLabel }}\n </span>\n }\n @if (lintWarnCount) {\n <span class=\"workflow-lint-count workflow-lint-count-warn\">\n <i class=\"pi pi-exclamation-triangle\"></i> {{ lintWarnCount }} {{ lintWarningsCountLabel }}\n </span>\n }\n </div>\n <ul class=\"workflow-lint-list\">\n @for (finding of lintFindings; track $index) {\n <li\n class=\"workflow-lint-item\"\n [ngClass]=\"finding.severity === 'error' ? 'workflow-lint-item-error' : 'workflow-lint-item-warn'\"\n [class.workflow-lint-item-clickable]=\"!!finding.nodeId\"\n (click)=\"zoomToLintFinding(finding)\">\n <i [class]=\"finding.severity === 'error' ? 'pi pi-times-circle' : 'pi pi-exclamation-triangle'\"></i>\n <span class=\"workflow-lint-code\">{{ finding.code }}</span>\n <span class=\"workflow-lint-message\">{{ finding.message }}</span>\n </li>\n }\n </ul>\n <div class=\"route-popup-actions\">\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"onLintDialogClose()\">\n {{ lintDialogMode === 'confirm-save' ? ('cancel' | translate) : ('close' | translate) }}\n </button>\n @if (lintDialogMode === 'confirm-save') {\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"onLintDialogSaveAnyway()\">\n {{ lintSaveAnywayLabel }}\n </button>\n }\n </div>\n</p-dialog>\n\n<!-- Guida rapida: legenda tipi nodo (dal nodeRegistry) + glossario workflow. -->\n<p-dialog\n [header]=\"quickGuideTitle\"\n [(visible)]=\"quickGuideDialogVisible\"\n [modal]=\"true\"\n [closable]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [appendTo]=\"'body'\"\n styleClass=\"workflow-quick-guide-dialog\"\n [style]=\"{ width: '52rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\">\n <div class=\"workflow-guide-section-title\">{{ quickGuideLegendTitle }}</div>\n <div class=\"workflow-guide-legend\">\n @for (entry of guideLegendEntries; track entry.type) {\n <div class=\"workflow-guide-legend-item\">\n <span class=\"workflow-guide-legend-chip\" [style.background]=\"entry.background\" [style.borderColor]=\"entry.accent\" [style.color]=\"entry.accent\">\n {{ entry.label }}\n </span>\n <span class=\"workflow-guide-legend-desc\">{{ entry.description }}</span>\n </div>\n }\n </div>\n <div class=\"workflow-guide-section-title\">{{ quickGuideGlossaryTitle }}</div>\n <dl class=\"workflow-guide-glossary\">\n @for (entry of guideGlossaryEntries; track entry.term) {\n <dt>{{ entry.term }}</dt>\n <dd>{{ entry.text }}</dd>\n }\n </dl>\n</p-dialog>\n", styles: [":host{display:block;height:100%}.workflow-designer{display:grid;grid-template-rows:auto 1fr;grid-template-columns:260px 1fr;gap:12px;height:100%;min-height:520px}.workflow-toolbar{grid-column:1 / span 2;display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;padding:10px 12px}.workflow-toolbar label{font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-toolbar input{height:30px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;min-width:170px}.workflow-toolbar button{height:30px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.workflow-toolbar button[disabled]{opacity:.6;cursor:not-allowed}.workflow-toolbar-menu-group{display:inline-flex}.workflow-toolbar-filter{display:inline-flex;align-items:center}.workflow-toolbar-filter ::ng-deep .p-select{min-width:170px;font-size:.82rem}.workflow-current-graph{flex:1 1 auto;min-width:240px;font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-palette{border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;overflow:auto}.workflow-palette-title{padding:10px 12px;font-size:.86rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#3d4f67;border-bottom:1px solid #d5dce6}.workflow-palette-list{display:flex;flex-direction:column;gap:8px;padding:10px}.workflow-palette-item{border:1px solid #c8d3e2;border-radius:8px;background:#fff;padding:10px;cursor:grab;-webkit-user-select:none;user-select:none}.workflow-palette-item-badge{display:inline-block;margin-top:4px;margin-bottom:4px;padding:2px 7px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;background:#e2e8f0;color:#334155}.workflow-palette-item-route{border-color:#93c5fd;background:#eff6ff}.workflow-palette-item-route .workflow-palette-item-badge{background:#dbeafe;color:#1d4ed8}.workflow-palette-item-action{border-color:#c4b5fd;background:#f5f3ff}.workflow-palette-item-action .workflow-palette-item-badge{background:#ede9fe;color:#6d28d9}.workflow-palette-item-start{border-color:#86efac;background:#f0fdf4}.workflow-palette-item-condition{border-color:#99f6e4;background:#f0fdfa}.workflow-palette-item-end{border-color:#fda4af;background:#fff1f2}.workflow-palette-item:active{cursor:grabbing}.workflow-palette-item-disabled{opacity:.6;cursor:not-allowed;filter:grayscale(.2)}:host-context(.theme-dark) .workflow-palette-item-disabled{opacity:.5}.workflow-palette-item-title{font-size:.94rem;font-weight:600;color:#21324a}.workflow-palette-item-description{margin-top:4px;font-size:.82rem;color:#60738f}.workflow-canvas{position:relative;border:1px solid #d5dce6;border-radius:10px;overflow:hidden;background:radial-gradient(circle at 1px 1px,#dbe3ef 1px,transparent 0);background-size:24px 24px;background-color:#f8fbff;user-select:none;-webkit-user-select:none}.workflow-canvas-hint{position:absolute;right:12px;bottom:12px;font-size:.82rem;color:#60738f;background:#ffffffeb;border:1px solid #d5dce6;border-radius:6px;padding:5px 8px}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-input{width:100%;height:34px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;color:#1f2f49}.workflow-options-toggle{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-toggle input[type=checkbox]{width:16px;height:16px}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid #c7d2e2;background:#fff;color:#1f2f49;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}:host ::ng-deep .workflow-route-metadata-dialog.p-dialog{max-height:calc(100vh - 2rem)}:host ::ng-deep .workflow-route-metadata-dialog .p-dialog-content{overflow:visible;max-height:calc(100vh - 10rem)}:host ::ng-deep .workflow-canvas [data-wf-node-type] .node{border:1px solid var(--wf-node-accent, #64748b)!important;background:var(--wf-node-bg, #f8fafc)!important}:host ::ng-deep .workflow-canvas [data-wf-node-type] .title{background:var(--wf-node-accent, #64748b)!important;color:#fff!important;font-weight:700}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=col] .node{border-style:dashed!important}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=tab] .node{border-style:solid!important}:host-context(.theme-dark) .workflow-toolbar{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-current-graph,:host-context(.theme-dark) .workflow-toolbar label{color:#d8e2f1}:host-context(.theme-dark) .workflow-toolbar input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .workflow-toolbar button{border-color:#335fcf;background:#335fcf}:host-context(.theme-dark) .workflow-palette{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-palette-title{color:#dbe4f2;border-bottom-color:#2a3447}:host-context(.theme-dark) .workflow-palette-item{border-color:#334155;background:#0f1724}:host-context(.theme-dark) .workflow-palette-item-title{color:#e6edf8}:host-context(.theme-dark) .workflow-palette-item-description{color:#9fb0c7}:host-context(.theme-dark) .workflow-palette-item-badge{background:#273247;color:#c9d7ec}:host-context(.theme-dark) .workflow-palette-item-route{border-color:#3b82f6;background:#0f1f35}:host-context(.theme-dark) .workflow-palette-item-route .workflow-palette-item-badge{background:#1e3a6a;color:#c8ddff}:host-context(.theme-dark) .workflow-palette-item-action{border-color:#8b5cf6;background:#24183d}:host-context(.theme-dark) .workflow-palette-item-action .workflow-palette-item-badge{background:#3a2370;color:#ded1ff}:host-context(.theme-dark) .workflow-palette-item-start{border-color:#22c55e;background:#11281c}:host-context(.theme-dark) .workflow-palette-item-condition{border-color:#14b8a6;background:#0f2726}:host-context(.theme-dark) .workflow-palette-item-end{border-color:#ef4444;background:#30171b}:host-context(.theme-dark) .workflow-canvas{border-color:#2a3447;background:radial-gradient(circle at 1px 1px,#334155 1px,transparent 0);background-size:24px 24px;background-color:#0f1724}:host-context(.theme-dark) .workflow-canvas-hint{color:#b9c8de;background:#0f1724e6;border-color:#334155}:host-context(.theme-dark) .route-popup-form label,:host-context(.theme-dark) .workflow-options-toggle{color:#d8e2f1}:host-context(.theme-dark) .workflow-options-input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .route-popup-btn{border-color:#334155;background:#111b2b;color:#d8e2f1}:host-context(.theme-dark) .route-popup-btn-primary{border-color:#335fcf;background:#335fcf;color:#fff}:host-context(.theme-dark) ::ng-deep .p-menu,:host-context(.theme-dark) ::ng-deep .p-contextmenu{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content{color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content:hover,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content:hover{background:#1f2a3d}:host-context(.theme-dark) ::ng-deep .p-dialog{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-header,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-content,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-footer{background:#121b2b;color:#dbe4f2;border-color:#334155}.workflow-canvas-checklist{position:absolute;right:18px;bottom:18px;max-width:340px;padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;background:#fffffff0;color:#334155;font-size:12.5px;line-height:1.5;box-shadow:0 4px 14px #0f172a14;pointer-events:auto;z-index:5}.workflow-canvas-checklist-title{font-weight:700;margin-bottom:6px;color:#0f172a}.workflow-canvas-checklist ol{margin:0 0 8px;padding-left:18px}.workflow-canvas-checklist li{margin:2px 0}.workflow-canvas-checklist-done{text-decoration:line-through;opacity:.55}.workflow-canvas-checklist-link{border:none;background:none;padding:0;color:#2563eb;cursor:pointer;font-size:12.5px;text-decoration:underline}:host-context(.theme-dark) .workflow-canvas-checklist{background:#121b2bf0;border-color:#334155;color:#cbd5e1}:host-context(.theme-dark) .workflow-canvas-checklist-title{color:#e2e8f0}.workflow-lint-summary{display:flex;gap:14px;margin-bottom:10px;font-size:12.5px}.workflow-lint-count{display:inline-flex;align-items:center;gap:6px;font-weight:600}.workflow-lint-count-error{color:#dc2626}.workflow-lint-count-warn{color:#d97706}.workflow-lint-list{list-style:none;margin:0 0 12px;padding:0;max-height:46vh;overflow:auto}.workflow-lint-item{display:flex;align-items:flex-start;gap:8px;padding:7px 8px;border-radius:6px;font-size:12.5px;line-height:1.45}.workflow-lint-item+.workflow-lint-item{margin-top:4px}.workflow-lint-item-error{background:#fef2f2;color:#7f1d1d}.workflow-lint-item-error .pi{color:#dc2626;margin-top:2px}.workflow-lint-item-warn{background:#fffbeb;color:#78350f}.workflow-lint-item-warn .pi{color:#d97706;margin-top:2px}.workflow-lint-item-clickable{cursor:pointer}.workflow-lint-item-clickable:hover{filter:brightness(.97)}.workflow-lint-code{font-family:monospace;font-size:11px;opacity:.75;white-space:nowrap;margin-top:1px}:host-context(.theme-dark) .workflow-lint-item-error{background:#dc26261f;color:#fca5a5}:host-context(.theme-dark) .workflow-lint-item-warn{background:#d977061f;color:#fcd34d}.workflow-guide-section-title{font-weight:700;font-size:13px;margin:10px 0 8px;color:#0f172a}.workflow-guide-legend{display:grid;grid-template-columns:1fr 1fr;gap:8px 18px;margin-bottom:8px}.workflow-guide-legend-item{display:flex;align-items:center;gap:8px;font-size:12.5px}.workflow-guide-legend-chip{display:inline-block;min-width:74px;text-align:center;padding:3px 8px;border:1.5px solid;border-radius:7px;font-weight:700;font-size:11.5px;white-space:nowrap}.workflow-guide-legend-desc{color:#475569;line-height:1.4}.workflow-guide-glossary{margin:0;font-size:12.5px}.workflow-guide-glossary dt{font-weight:700;margin-top:8px;color:#0f172a}.workflow-guide-glossary dd{margin:2px 0 0;color:#475569;line-height:1.5}:host-context(.theme-dark) .workflow-guide-section-title,:host-context(.theme-dark) .workflow-guide-glossary dt{color:#e2e8f0}:host-context(.theme-dark) .workflow-guide-legend-desc,:host-context(.theme-dark) .workflow-guide-glossary dd{color:#94a3b8}::ng-deep .workflow-palette-tooltip .p-tooltip-text{max-width:340px;font-size:12px;line-height:1.45}\n"] }]
|
|
9477
|
+
args: [{ selector: 'wuic-workflow-designer', standalone: true, imports: [NgClass, FormsModule, DialogModule, SelectModule, AutoCompleteModule, MenuModule, ContextMenuModule, TooltipModule, TranslateModule, DataSourceComponent, MetadataEditorComponent], template: "<div class=\"workflow-designer\">\r\n <div class=\"workflow-toolbar\">\r\n <div class=\"workflow-current-graph\">{{ currentGraphCaption }}</div>\r\n <!-- Filtro \"anteprima autorizzazioni\": simula cosa vede un ruolo/utente.\r\n Opzioni dai principal citati nel grafo (permessi bundle + permission\r\n transizioni); il dropdown utenti appare solo se esistono auth\r\n per-utente. Selezione vuota = mostra tutto. -->\r\n @if (authFilterRoleOptions.length > 1) {\r\n <div class=\"workflow-toolbar-filter\">\r\n <p-select\r\n [options]=\"authFilterRoleOptions\"\r\n [(ngModel)]=\"authFilterRoleId\"\r\n (onChange)=\"onAuthFilterChanged('role')\"\r\n appendTo=\"body\"\r\n data-testid=\"wf-auth-filter-role\" />\r\n </div>\r\n }\r\n @if (authFilterUserOptions.length > 1) {\r\n <div class=\"workflow-toolbar-filter\">\r\n <p-select\r\n [options]=\"authFilterUserOptions\"\r\n [(ngModel)]=\"authFilterUserId\"\r\n (onChange)=\"onAuthFilterChanged('user')\"\r\n appendTo=\"body\"\r\n data-testid=\"wf-auth-filter-user\" />\r\n </div>\r\n }\r\n <div class=\"workflow-toolbar-menu-group\">\r\n <button type=\"button\" (click)=\"graphActionsMenu.toggle($event)\">\r\n Azioni grafo\r\n </button>\r\n <p-menu #graphActionsMenu [popup]=\"true\" [model]=\"graphActionsMenuItems\" appendTo=\"body\"></p-menu>\r\n </div>\r\n <div class=\"workflow-toolbar-menu-group\">\r\n <button type=\"button\" (click)=\"runnerActionsMenu.toggle($event)\" [disabled]=\"!canOpenWorkflowRunner\">\r\n Runner\r\n </button>\r\n <p-menu #runnerActionsMenu [popup]=\"true\" [model]=\"runnerActionsMenuItems\" appendTo=\"body\"></p-menu>\r\n </div>\r\n </div>\r\n\r\n <aside class=\"workflow-palette\">\r\n <div class=\"workflow-palette-title\">{{ 'workflow.palette' | translate }}</div>\r\n <div class=\"workflow-palette-list\">\r\n @for (item of paletteNodes; track item) {\r\n <div\r\n class=\"workflow-palette-item\"\r\n [ngClass]=\"{\r\n 'workflow-palette-item-route': item.type === 'route',\r\n 'workflow-palette-item-action': item.type === 'action',\r\n 'workflow-palette-item-start': item.type === 'start',\r\n 'workflow-palette-item-condition': item.type === 'condition',\r\n 'workflow-palette-item-end': item.type === 'end',\r\n 'workflow-palette-item-disabled': !isPaletteNodeEnabled(item)\r\n }\"\r\n [attr.draggable]=\"isPaletteNodeEnabled(item) ? 'true' : 'false'\"\r\n (dragstart)=\"onPaletteDragStart($event, item)\"\r\n [pTooltip]=\"item.tooltip || ''\"\r\n [escape]=\"false\"\r\n tooltipPosition=\"right\"\r\n [tooltipStyleClass]=\"'workflow-palette-tooltip'\">\r\n <div class=\"workflow-palette-item-title\">{{ item.label }}</div>\r\n @if (item.type === 'route') {\r\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.route' | translate }}</div>\r\n }\r\n @if (item.type === 'action') {\r\n <div class=\"workflow-palette-item-badge\">{{ 'workflow.badge.action_scope' | translate }}</div>\r\n }\r\n <div class=\"workflow-palette-item-description\">{{ item.description }}</div>\r\n </div>\r\n }\r\n </div>\r\n </aside>\r\n\r\n <section\r\n #workflowCanvas\r\n class=\"workflow-canvas\"\r\n (dragover)=\"onCanvasDragOver($event)\"\r\n (drop)=\"onCanvasDrop($event)\"\r\n (contextmenu)=\"onCanvasContextMenu($event)\"\r\n (click)=\"onCanvasClick()\">\r\n @if (showEmptyGraphChecklist) {\r\n <div class=\"workflow-canvas-checklist\">\r\n <div class=\"workflow-canvas-checklist-title\">{{ hintChecklistTitle }}</div>\r\n <ol>\r\n @for (step of hintChecklistStepStates; track $index) {\r\n <li [ngClass]=\"{ 'workflow-canvas-checklist-done': step.done }\">{{ step.text }}</li>\r\n }\r\n </ol>\r\n @if (showChecklistTemplateLink) {\r\n <button type=\"button\" class=\"workflow-canvas-checklist-link\" (click)=\"createWorkflowFromTemplate()\">\r\n {{ hintOrTemplateLabel }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </section>\r\n <p-contextMenu\r\n #primeContextMenu\r\n [model]=\"contextMenuItems\"\r\n appendTo=\"body\"\r\n [autoZIndex]=\"true\"\r\n [baseZIndex]=\"13000\">\r\n </p-contextMenu>\r\n</div>\r\n\r\n<p-dialog\r\n [header]=\"'Riapri grafo'\"\r\n [(visible)]=\"reopenWorkflowDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n [style]=\"{ width: '34rem' }\"\r\n (onHide)=\"cancelReopenWorkflowDialog()\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-reopen-select\">Grafi esistenti</label>\r\n <p-select\r\n inputId=\"workflow-reopen-select\"\r\n [options]=\"savedGraphOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"reopenDialogSelectedGraphKey\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelReopenWorkflowDialog()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmReopenWorkflowDialog()\"\r\n [disabled]=\"!reopenDialogSelectedGraphKey || loadingWorkflow\">Riapri</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<div style=\"display:none\">\r\n <wuic-data-source #routeMetadataDs [hardcodedRoute]=\"routeMetadataRoute\"></wuic-data-source>\r\n <wuic-data-source #startMenuDs [hardcodedRoute]=\"' metadati menu'\"></wuic-data-source>\r\n <wuic-data-source #menuAuthDs [hardcodedRoute]=\"' mtdt tnt trizzazioni menus'\"></wuic-data-source>\r\n @if (routeMetadataDs) {\r\n <wuic-metadata-editor\r\n #actionMetadataEditor\r\n [hardcodedDatasource]=\"routeMetadataDs!\"\r\n [saveCallback]=\"routeMetadataSaveCallback\"\r\n [hideReports]=\"true\"\r\n [hideRelatedTableActions]=\"true\"\r\n [hideRelatedColumnActions]=\"true\">\r\n </wuic-metadata-editor>\r\n }\r\n</div>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.configure_route' | translate\"\r\n [(visible)]=\"routePopupVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-route-source-select\">Sorgente nodo</label>\r\n <p-select\r\n inputId=\"workflow-route-source-select\"\r\n [options]=\"routeSourceOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedRouteSourceType\"\r\n (ngModelChange)=\"onRouteSourceTypeChanged()\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n @if (selectedRouteSourceType === 'route') {\r\n <label for=\"workflow-route-select\">{{ 'workflow.route' | translate }}</label>\r\n <p-autoComplete\r\n inputId=\"workflow-route-select\"\r\n [(ngModel)]=\"selectedRouteName\"\r\n [suggestions]=\"filteredRouteOptions\"\r\n [forceSelection]=\"true\"\r\n [dropdown]=\"true\"\r\n dropdownMode=\"current\"\r\n [optionLabel]=\"'label'\"\r\n [optionValue]=\"'value'\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\"\r\n (completeMethod)=\"filterRouteOptions($event)\" />\r\n <label for=\"workflow-action-select\">{{ 'workflow.action' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-select\"\r\n [options]=\"routeActionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedRouteAction\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n } @else {\r\n <label for=\"workflow-dashboard-select\">Dashboard</label>\r\n <p-autoComplete\r\n inputId=\"workflow-dashboard-select\"\r\n [(ngModel)]=\"selectedDashboardRoute\"\r\n [suggestions]=\"filteredDashboardOptions\"\r\n [forceSelection]=\"true\"\r\n [dropdown]=\"true\"\r\n dropdownMode=\"current\"\r\n [optionLabel]=\"'label'\"\r\n [optionValue]=\"'value'\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\"\r\n (completeMethod)=\"filterDashboardOptions($event)\" />\r\n }\r\n\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelRouteDrop()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmRouteDrop()\"\r\n [disabled]=\"selectedRouteSourceType === 'dashboard' ? !selectedDashboardRoute : (!selectedRouteName || !selectedRouteAction)\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.metadata_route' | translate\"\r\n [(visible)]=\"routeMetadataDialogVisible\"\r\n [modal]=\"true\"\r\n position=\"top\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n styleClass=\"workflow-route-metadata-dialog\"\r\n [style]=\"{ width: '78rem', maxHeight: 'calc(100vh - 2rem)' }\"\r\n [contentStyle]=\"{ overflow: 'visible', maxHeight: 'calc(100vh - 10rem)' }\">\r\n @if (routeMetadataDialogVisible && routeMetadataDs) {\r\n <wuic-metadata-editor\r\n #routeMetadataEditor\r\n [hardcodedDatasource]=\"routeMetadataDs!\"\r\n [saveCallback]=\"routeMetadataSaveCallback\"\r\n [hideReports]=\"true\"\r\n [hideRelatedTableActions]=\"false\"\r\n [hideRelatedColumnActions]=\"false\">\r\n </wuic-metadata-editor>\r\n }\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'workflow.configure_action' | translate\"\r\n [(visible)]=\"actionPopupVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-action-scope-select\">{{ 'workflow.action_scope' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-scope-select\"\r\n [options]=\"actionScopeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedActionScopeId\"\r\n (onChange)=\"onActionScopeChanged()\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <label for=\"workflow-action-type-select\">{{ 'workflow.action_type' | translate }}</label>\r\n <p-select\r\n inputId=\"workflow-action-type-select\"\r\n [options]=\"visibleActionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"selectedActionTypeId\"\r\n [style]=\"{ width: '100%' }\"\r\n appendTo=\"body\" />\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelActionDrop()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmActionDrop()\"\r\n [disabled]=\"selectedActionTypeId === null || selectedActionTypeId === undefined || selectedActionScopeId === null || selectedActionScopeId === undefined\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<p-dialog\r\n [header]=\"'Opzioni workflow'\"\r\n [(visible)]=\"workflowOptionsDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"false\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [style]=\"{ width: '32rem' }\">\r\n <div class=\"route-popup-form\">\r\n <label for=\"workflow-options-caption\">Caption menu start</label>\r\n <input\r\n id=\"workflow-options-caption\"\r\n class=\"workflow-options-input\"\r\n type=\"text\"\r\n [(ngModel)]=\"workflowOptionsCaption\" />\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsInheritMetadata\" />\r\n <span>Eredita metadati</span>\r\n </label>\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsExclusiveMenu\" />\r\n <span>Menu esclusivo</span>\r\n </label>\r\n\r\n <label class=\"workflow-options-toggle\">\r\n <input type=\"checkbox\" [(ngModel)]=\"workflowOptionsShowExit\" />\r\n <span>Mostra esci</span>\r\n </label>\r\n\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"cancelWorkflowOptionsDialog()\">{{ 'cancel' | translate }}</button>\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"confirmWorkflowOptionsDialog()\">{{ 'confirmation' | translate }}</button>\r\n </div>\r\n </div>\r\n</p-dialog>\r\n\r\n<!-- Lint del grafo: elenco findings (on-demand \"Valida grafo\" o conferma pre-save).\r\n Il save non e' mai bloccato: con findings serve la conferma esplicita. -->\r\n<p-dialog\r\n [header]=\"lintDialogTitle\"\r\n [(visible)]=\"lintDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n [style]=\"{ width: '46rem', maxHeight: '80vh' }\"\r\n (onHide)=\"onLintDialogClose()\">\r\n <div class=\"workflow-lint-summary\">\r\n @if (lintErrorCount) {\r\n <span class=\"workflow-lint-count workflow-lint-count-error\">\r\n <i class=\"pi pi-times-circle\"></i> {{ lintErrorCount }} {{ lintErrorsCountLabel }}\r\n </span>\r\n }\r\n @if (lintWarnCount) {\r\n <span class=\"workflow-lint-count workflow-lint-count-warn\">\r\n <i class=\"pi pi-exclamation-triangle\"></i> {{ lintWarnCount }} {{ lintWarningsCountLabel }}\r\n </span>\r\n }\r\n </div>\r\n <ul class=\"workflow-lint-list\">\r\n @for (finding of lintFindings; track $index) {\r\n <li\r\n class=\"workflow-lint-item\"\r\n [ngClass]=\"finding.severity === 'error' ? 'workflow-lint-item-error' : 'workflow-lint-item-warn'\"\r\n [class.workflow-lint-item-clickable]=\"!!finding.nodeId\"\r\n (click)=\"zoomToLintFinding(finding)\">\r\n <i [class]=\"finding.severity === 'error' ? 'pi pi-times-circle' : 'pi pi-exclamation-triangle'\"></i>\r\n <span class=\"workflow-lint-code\">{{ finding.code }}</span>\r\n <span class=\"workflow-lint-message\">{{ finding.message }}</span>\r\n </li>\r\n }\r\n </ul>\r\n <div class=\"route-popup-actions\">\r\n <button type=\"button\" class=\"route-popup-btn\" (click)=\"onLintDialogClose()\">\r\n {{ lintDialogMode === 'confirm-save' ? ('cancel' | translate) : ('close' | translate) }}\r\n </button>\r\n @if (lintDialogMode === 'confirm-save') {\r\n <button type=\"button\" class=\"route-popup-btn route-popup-btn-primary\" (click)=\"onLintDialogSaveAnyway()\">\r\n {{ lintSaveAnywayLabel }}\r\n </button>\r\n }\r\n </div>\r\n</p-dialog>\r\n\r\n<!-- Guida rapida: legenda tipi nodo (dal nodeRegistry) + glossario workflow. -->\r\n<p-dialog\r\n [header]=\"quickGuideTitle\"\r\n [(visible)]=\"quickGuideDialogVisible\"\r\n [modal]=\"true\"\r\n [closable]=\"true\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n [appendTo]=\"'body'\"\r\n styleClass=\"workflow-quick-guide-dialog\"\r\n [style]=\"{ width: '52rem', maxHeight: '85vh' }\"\r\n [contentStyle]=\"{ overflow: 'auto' }\">\r\n <div class=\"workflow-guide-section-title\">{{ quickGuideLegendTitle }}</div>\r\n <div class=\"workflow-guide-legend\">\r\n @for (entry of guideLegendEntries; track entry.type) {\r\n <div class=\"workflow-guide-legend-item\">\r\n <span class=\"workflow-guide-legend-chip\" [style.background]=\"entry.background\" [style.borderColor]=\"entry.accent\" [style.color]=\"entry.accent\">\r\n {{ entry.label }}\r\n </span>\r\n <span class=\"workflow-guide-legend-desc\">{{ entry.description }}</span>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"workflow-guide-section-title\">{{ quickGuideGlossaryTitle }}</div>\r\n <dl class=\"workflow-guide-glossary\">\r\n @for (entry of guideGlossaryEntries; track entry.term) {\r\n <dt>{{ entry.term }}</dt>\r\n <dd>{{ entry.text }}</dd>\r\n }\r\n </dl>\r\n</p-dialog>\r\n", styles: [":host{display:block;height:100%}.workflow-designer{display:grid;grid-template-rows:auto 1fr;grid-template-columns:260px 1fr;gap:12px;height:100%;min-height:520px}.workflow-toolbar{grid-column:1 / span 2;display:flex;align-items:center;flex-wrap:wrap;gap:8px;border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;padding:10px 12px}.workflow-toolbar label{font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-toolbar input{height:30px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;min-width:170px}.workflow-toolbar button{height:30px;border:1px solid #2f67d8;border-radius:6px;background:#2f67d8;color:#fff;padding:0 10px;font-size:.82rem;cursor:pointer}.workflow-toolbar button[disabled]{opacity:.6;cursor:not-allowed}.workflow-toolbar-menu-group{display:inline-flex}.workflow-toolbar-filter{display:inline-flex;align-items:center}.workflow-toolbar-filter ::ng-deep .p-select{min-width:170px;font-size:.82rem}.workflow-current-graph{flex:1 1 auto;min-width:240px;font-size:.82rem;font-weight:600;color:#2f3f58}.workflow-palette{border:1px solid #d5dce6;border-radius:10px;background:#f7f9fc;overflow:auto}.workflow-palette-title{padding:10px 12px;font-size:.86rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#3d4f67;border-bottom:1px solid #d5dce6}.workflow-palette-list{display:flex;flex-direction:column;gap:8px;padding:10px}.workflow-palette-item{border:1px solid #c8d3e2;border-radius:8px;background:#fff;padding:10px;cursor:grab;-webkit-user-select:none;user-select:none}.workflow-palette-item-badge{display:inline-block;margin-top:4px;margin-bottom:4px;padding:2px 7px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;background:#e2e8f0;color:#334155}.workflow-palette-item-route{border-color:#93c5fd;background:#eff6ff}.workflow-palette-item-route .workflow-palette-item-badge{background:#dbeafe;color:#1d4ed8}.workflow-palette-item-action{border-color:#c4b5fd;background:#f5f3ff}.workflow-palette-item-action .workflow-palette-item-badge{background:#ede9fe;color:#6d28d9}.workflow-palette-item-start{border-color:#86efac;background:#f0fdf4}.workflow-palette-item-condition{border-color:#99f6e4;background:#f0fdfa}.workflow-palette-item-end{border-color:#fda4af;background:#fff1f2}.workflow-palette-item:active{cursor:grabbing}.workflow-palette-item-disabled{opacity:.6;cursor:not-allowed;filter:grayscale(.2)}:host-context(.theme-dark) .workflow-palette-item-disabled{opacity:.5}.workflow-palette-item-title{font-size:.94rem;font-weight:600;color:#21324a}.workflow-palette-item-description{margin-top:4px;font-size:.82rem;color:#60738f}.workflow-canvas{position:relative;border:1px solid #d5dce6;border-radius:10px;overflow:hidden;background:radial-gradient(circle at 1px 1px,#dbe3ef 1px,transparent 0);background-size:24px 24px;background-color:#f8fbff;user-select:none;-webkit-user-select:none}.workflow-canvas-hint{position:absolute;right:12px;bottom:12px;font-size:.82rem;color:#60738f;background:#ffffffeb;border:1px solid #d5dce6;border-radius:6px;padding:5px 8px}.route-popup-form{display:flex;flex-direction:column;gap:8px}.route-popup-form label{font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-input{width:100%;height:34px;border:1px solid #c7d2e2;border-radius:6px;background:#fff;padding:0 8px;color:#1f2f49}.workflow-options-toggle{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:#2f3f58;margin-top:2px}.workflow-options-toggle input[type=checkbox]{width:16px;height:16px}.route-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.route-popup-btn{border:1px solid #c7d2e2;background:#fff;color:#1f2f49;border-radius:6px;padding:7px 12px;font-size:.85rem;cursor:pointer}.route-popup-btn-primary{border-color:#2f67d8;background:#2f67d8;color:#fff}:host ::ng-deep .workflow-route-metadata-dialog.p-dialog{max-height:calc(100vh - 2rem)}:host ::ng-deep .workflow-route-metadata-dialog .p-dialog-content{overflow:visible;max-height:calc(100vh - 10rem)}:host ::ng-deep .workflow-canvas [data-wf-node-type] .node{border:1px solid var(--wf-node-accent, #64748b)!important;background:var(--wf-node-bg, #f8fafc)!important}:host ::ng-deep .workflow-canvas [data-wf-node-type] .title{background:var(--wf-node-accent, #64748b)!important;color:#fff!important;font-weight:700}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=col] .node{border-style:dashed!important}:host ::ng-deep .workflow-canvas [data-wf-node-type=action][data-wf-action-scope=tab] .node{border-style:solid!important}:host-context(.theme-dark) .workflow-toolbar{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-current-graph,:host-context(.theme-dark) .workflow-toolbar label{color:#d8e2f1}:host-context(.theme-dark) .workflow-toolbar input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .workflow-toolbar button{border-color:#335fcf;background:#335fcf}:host-context(.theme-dark) .workflow-palette{border-color:#2a3447;background:#141b27}:host-context(.theme-dark) .workflow-palette-title{color:#dbe4f2;border-bottom-color:#2a3447}:host-context(.theme-dark) .workflow-palette-item{border-color:#334155;background:#0f1724}:host-context(.theme-dark) .workflow-palette-item-title{color:#e6edf8}:host-context(.theme-dark) .workflow-palette-item-description{color:#9fb0c7}:host-context(.theme-dark) .workflow-palette-item-badge{background:#273247;color:#c9d7ec}:host-context(.theme-dark) .workflow-palette-item-route{border-color:#3b82f6;background:#0f1f35}:host-context(.theme-dark) .workflow-palette-item-route .workflow-palette-item-badge{background:#1e3a6a;color:#c8ddff}:host-context(.theme-dark) .workflow-palette-item-action{border-color:#8b5cf6;background:#24183d}:host-context(.theme-dark) .workflow-palette-item-action .workflow-palette-item-badge{background:#3a2370;color:#ded1ff}:host-context(.theme-dark) .workflow-palette-item-start{border-color:#22c55e;background:#11281c}:host-context(.theme-dark) .workflow-palette-item-condition{border-color:#14b8a6;background:#0f2726}:host-context(.theme-dark) .workflow-palette-item-end{border-color:#ef4444;background:#30171b}:host-context(.theme-dark) .workflow-canvas{border-color:#2a3447;background:radial-gradient(circle at 1px 1px,#334155 1px,transparent 0);background-size:24px 24px;background-color:#0f1724}:host-context(.theme-dark) .workflow-canvas-hint{color:#b9c8de;background:#0f1724e6;border-color:#334155}:host-context(.theme-dark) .route-popup-form label,:host-context(.theme-dark) .workflow-options-toggle{color:#d8e2f1}:host-context(.theme-dark) .workflow-options-input{border-color:#334155;background:#0f1724;color:#e5ecf8}:host-context(.theme-dark) .route-popup-btn{border-color:#334155;background:#111b2b;color:#d8e2f1}:host-context(.theme-dark) .route-popup-btn-primary{border-color:#335fcf;background:#335fcf;color:#fff}:host-context(.theme-dark) ::ng-deep .p-menu,:host-context(.theme-dark) ::ng-deep .p-contextmenu{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content{color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-menu .p-menu-item-content:hover,:host-context(.theme-dark) ::ng-deep .p-contextmenu .p-menu-item-content:hover{background:#1f2a3d}:host-context(.theme-dark) ::ng-deep .p-dialog{background:#121b2b;border-color:#334155;color:#dbe4f2}:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-header,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-content,:host-context(.theme-dark) ::ng-deep .p-dialog .p-dialog-footer{background:#121b2b;color:#dbe4f2;border-color:#334155}.workflow-canvas-checklist{position:absolute;right:18px;bottom:18px;max-width:340px;padding:14px 16px;border:1px solid #cbd5e1;border-radius:10px;background:#fffffff0;color:#334155;font-size:12.5px;line-height:1.5;box-shadow:0 4px 14px #0f172a14;pointer-events:auto;z-index:5}.workflow-canvas-checklist-title{font-weight:700;margin-bottom:6px;color:#0f172a}.workflow-canvas-checklist ol{margin:0 0 8px;padding-left:18px}.workflow-canvas-checklist li{margin:2px 0}.workflow-canvas-checklist-done{text-decoration:line-through;opacity:.55}.workflow-canvas-checklist-link{border:none;background:none;padding:0;color:#2563eb;cursor:pointer;font-size:12.5px;text-decoration:underline}:host-context(.theme-dark) .workflow-canvas-checklist{background:#121b2bf0;border-color:#334155;color:#cbd5e1}:host-context(.theme-dark) .workflow-canvas-checklist-title{color:#e2e8f0}.workflow-lint-summary{display:flex;gap:14px;margin-bottom:10px;font-size:12.5px}.workflow-lint-count{display:inline-flex;align-items:center;gap:6px;font-weight:600}.workflow-lint-count-error{color:#dc2626}.workflow-lint-count-warn{color:#d97706}.workflow-lint-list{list-style:none;margin:0 0 12px;padding:0;max-height:46vh;overflow:auto}.workflow-lint-item{display:flex;align-items:flex-start;gap:8px;padding:7px 8px;border-radius:6px;font-size:12.5px;line-height:1.45}.workflow-lint-item+.workflow-lint-item{margin-top:4px}.workflow-lint-item-error{background:#fef2f2;color:#7f1d1d}.workflow-lint-item-error .pi{color:#dc2626;margin-top:2px}.workflow-lint-item-warn{background:#fffbeb;color:#78350f}.workflow-lint-item-warn .pi{color:#d97706;margin-top:2px}.workflow-lint-item-clickable{cursor:pointer}.workflow-lint-item-clickable:hover{filter:brightness(.97)}.workflow-lint-code{font-family:monospace;font-size:11px;opacity:.75;white-space:nowrap;margin-top:1px}:host-context(.theme-dark) .workflow-lint-item-error{background:#dc26261f;color:#fca5a5}:host-context(.theme-dark) .workflow-lint-item-warn{background:#d977061f;color:#fcd34d}.workflow-guide-section-title{font-weight:700;font-size:13px;margin:10px 0 8px;color:#0f172a}.workflow-guide-legend{display:grid;grid-template-columns:1fr 1fr;gap:8px 18px;margin-bottom:8px}.workflow-guide-legend-item{display:flex;align-items:center;gap:8px;font-size:12.5px}.workflow-guide-legend-chip{display:inline-block;min-width:74px;text-align:center;padding:3px 8px;border:1.5px solid;border-radius:7px;font-weight:700;font-size:11.5px;white-space:nowrap}.workflow-guide-legend-desc{color:#475569;line-height:1.4}.workflow-guide-glossary{margin:0;font-size:12.5px}.workflow-guide-glossary dt{font-weight:700;margin-top:8px;color:#0f172a}.workflow-guide-glossary dd{margin:2px 0 0;color:#475569;line-height:1.5}:host-context(.theme-dark) .workflow-guide-section-title,:host-context(.theme-dark) .workflow-guide-glossary dt{color:#e2e8f0}:host-context(.theme-dark) .workflow-guide-legend-desc,:host-context(.theme-dark) .workflow-guide-glossary dd{color:#94a3b8}::ng-deep .workflow-palette-tooltip .p-tooltip-text{max-width:340px;font-size:12px;line-height:1.45}\n"] }]
|
|
9478
9478
|
}], ctorParameters: () => [{ type: i0.Injector }, { type: DataProviderService }, { type: ChatbotHostRegistryService }], propDecorators: { workflowCanvasRef: [{
|
|
9479
9479
|
type: ViewChild,
|
|
9480
9480
|
args: ['workflowCanvas', { static: true }]
|
|
@@ -9501,4 +9501,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
9501
9501
|
}] } });
|
|
9502
9502
|
|
|
9503
9503
|
export { WorkflowDesignerComponent };
|
|
9504
|
-
//# sourceMappingURL=wuic-framework-lib-workflow-designer.component-
|
|
9504
|
+
//# sourceMappingURL=wuic-framework-lib-workflow-designer.component-BXnoS_ts.mjs.map
|