@tuki-io/tuki-widgets 0.0.177 → 0.0.178

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.
Files changed (54) hide show
  1. package/contact-center/cc-script-editor/cc-script-editor.component.d.ts +53 -0
  2. package/contact-center/cc-script-editor/cc-script-editor.module.d.ts +20 -0
  3. package/contact-center/cc-script-editor/components/dialogs/add-node-dialog/add-node-dialog.component.d.ts +35 -0
  4. package/contact-center/cc-script-editor/components/dialogs/link-node-dialog/link-node-dialog.component.d.ts +38 -0
  5. package/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.component.d.ts +34 -0
  6. package/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.module.d.ts +9 -0
  7. package/contact-center/cc-script-editor/components/node-action-toolbar/node-action-toolbar.component.d.ts +27 -0
  8. package/contact-center/cc-script-editor/components/node-details-sidebar/node-details-sidebar.component.d.ts +27 -0
  9. package/contact-center/cc-script-editor/components/node-search-panel/node-search-panel.component.d.ts +14 -0
  10. package/contact-center/cc-script-editor/components/wxcc-actions-bar/wxcc-actions-bar.component.d.ts +11 -0
  11. package/contact-center/cc-script-editor/components/wxcc-file-selection-bar/wxcc-file-selection-bar.component.d.ts +24 -0
  12. package/contact-center/cc-script-editor/components/wxcc-flowchart/wxcc-flowchart.component.d.ts +66 -0
  13. package/contact-center/cc-script-editor/constants/cytoscape.config.d.ts +2 -0
  14. package/contact-center/cc-script-editor/constants/wxcc-api.constants.d.ts +15 -0
  15. package/contact-center/cc-script-editor/services/wxcc-activity-creation.service.d.ts +21 -0
  16. package/contact-center/cc-script-editor/services/wxcc-activity-manage.service.d.ts +8 -0
  17. package/contact-center/cc-script-editor/services/wxcc-flow-api.service.d.ts +43 -0
  18. package/contact-center/cc-script-editor/services/wxcc2graph.service.d.ts +42 -0
  19. package/contact-center/cc-script-editor/types/extended-activity.d.ts +47 -0
  20. package/contact-center/cc-script-editor/types/wxcc-activity.d.ts +96 -0
  21. package/contact-center/cc-script-editor/types/wxcc.d.ts +161 -0
  22. package/contact-center/cc-script-editor/utils/node-html-template.d.ts +3 -0
  23. package/contact-center/cc-script-editor/utils/node-mappings.d.ts +54 -0
  24. package/contact-center/public-api.d.ts +2 -0
  25. package/esm2020/contact-center/cc-script-editor/cc-script-editor.component.mjs +193 -0
  26. package/esm2020/contact-center/cc-script-editor/cc-script-editor.module.mjs +83 -0
  27. package/esm2020/contact-center/cc-script-editor/components/dialogs/add-node-dialog/add-node-dialog.component.mjs +60 -0
  28. package/esm2020/contact-center/cc-script-editor/components/dialogs/link-node-dialog/link-node-dialog.component.mjs +83 -0
  29. package/esm2020/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.component.mjs +104 -0
  30. package/esm2020/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.module.mjs +28 -0
  31. package/esm2020/contact-center/cc-script-editor/components/node-action-toolbar/node-action-toolbar.component.mjs +65 -0
  32. package/esm2020/contact-center/cc-script-editor/components/node-details-sidebar/node-details-sidebar.component.mjs +97 -0
  33. package/esm2020/contact-center/cc-script-editor/components/node-search-panel/node-search-panel.component.mjs +43 -0
  34. package/esm2020/contact-center/cc-script-editor/components/wxcc-actions-bar/wxcc-actions-bar.component.mjs +27 -0
  35. package/esm2020/contact-center/cc-script-editor/components/wxcc-file-selection-bar/wxcc-file-selection-bar.component.mjs +61 -0
  36. package/esm2020/contact-center/cc-script-editor/components/wxcc-flowchart/wxcc-flowchart.component.mjs +434 -0
  37. package/esm2020/contact-center/cc-script-editor/constants/cytoscape.config.mjs +72 -0
  38. package/esm2020/contact-center/cc-script-editor/constants/wxcc-api.constants.mjs +14 -0
  39. package/esm2020/contact-center/cc-script-editor/mock/data/QWC_ir.json +912 -0
  40. package/esm2020/contact-center/cc-script-editor/services/wxcc-activity-creation.service.mjs +82 -0
  41. package/esm2020/contact-center/cc-script-editor/services/wxcc-activity-manage.service.mjs +162 -0
  42. package/esm2020/contact-center/cc-script-editor/services/wxcc-flow-api.service.mjs +79 -0
  43. package/esm2020/contact-center/cc-script-editor/services/wxcc2graph.service.mjs +144 -0
  44. package/esm2020/contact-center/cc-script-editor/types/extended-activity.mjs +4 -0
  45. package/esm2020/contact-center/cc-script-editor/types/wxcc-activity.mjs +2 -0
  46. package/esm2020/contact-center/cc-script-editor/types/wxcc.mjs +6 -0
  47. package/esm2020/contact-center/cc-script-editor/utils/node-html-template.mjs +76 -0
  48. package/esm2020/contact-center/cc-script-editor/utils/node-mappings.mjs +109 -0
  49. package/esm2020/contact-center/public-api.mjs +3 -1
  50. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs +2948 -3
  51. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
  52. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs +2974 -3
  53. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
  54. package/package.json +1 -1
@@ -1,21 +1,41 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, Component, Input, NgModule } from '@angular/core';
2
+ import { Injectable, inject, Component, Input, NgModule, ChangeDetectionStrategy, Inject, EventEmitter, Output, ViewChild } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpHeaders, HttpClientModule } from '@angular/common/http';
7
- import { map, catchError, of, finalize } from 'rxjs';
7
+ import { map, catchError, of, finalize, Subject, forkJoin, throwError } from 'rxjs';
8
8
  import * as i2 from 'ng-apexcharts';
9
9
  import { NgApexchartsModule } from 'ng-apexcharts';
10
10
  import * as i3 from '@angular/material/select';
11
11
  import { MatSelectModule } from '@angular/material/select';
12
12
  import * as i4 from '@angular/material/core';
13
13
  import { MatOptionModule } from '@angular/material/core';
14
+ import * as i1$4 from '@angular/material/button';
14
15
  import { MatButtonModule } from '@angular/material/button';
15
16
  import { MatCheckboxModule } from '@angular/material/checkbox';
16
17
  import { MatPaginatorModule } from '@angular/material/paginator';
18
+ import * as i4$1 from '@angular/material/progress-spinner';
17
19
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
18
20
  import { MatTableModule } from '@angular/material/table';
21
+ import cytoscape from 'cytoscape';
22
+ import dagre from 'cytoscape-dagre';
23
+ import nodeHtmlLabel from 'cytoscape-node-html-label';
24
+ import * as i1$2 from '@angular/material/dialog';
25
+ import { MAT_DIALOG_DATA } from '@angular/material/dialog';
26
+ import { __rest } from 'tslib';
27
+ import * as uuid from 'uuid';
28
+ import * as i3$1 from '@angular/material/tooltip';
29
+ import { MatTooltipModule } from '@angular/material/tooltip';
30
+ import * as i1$3 from '@angular/platform-browser';
31
+ import * as i2$1 from '@angular/forms';
32
+ import { FormsModule } from '@angular/forms';
33
+ import * as i2$2 from '@angular/material/form-field';
34
+ import { MatFormFieldModule } from '@angular/material/form-field';
35
+ import { mergeMap, takeUntil, finalize as finalize$1, tap } from 'rxjs/operators';
36
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
37
+ import { MatIconModule } from '@angular/material/icon';
38
+ import { MatInputModule } from '@angular/material/input';
19
39
 
20
40
  class APIService {
21
41
  constructor(httpClient) {
@@ -434,9 +454,2934 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
434
454
  }]
435
455
  }] });
436
456
 
457
+ const StyleConfig = [
458
+ {
459
+ selector: 'node',
460
+ style: {
461
+ 'background-color': 'transparent',
462
+ 'background-opacity': 0,
463
+ 'width': 220,
464
+ 'height': 100,
465
+ 'shape': 'roundrectangle',
466
+ 'border-width': 0
467
+ }
468
+ },
469
+ {
470
+ selector: 'node:selected',
471
+ style: {
472
+ 'background-color': 'transparent',
473
+ 'background-opacity': 0
474
+ }
475
+ },
476
+ {
477
+ selector: 'edge',
478
+ style: {
479
+ 'width': 1,
480
+ 'line-color': '#d4d4d4',
481
+ // 'line-color': '#B0BEC5',
482
+ 'target-arrow-color': '#d4d4d4',
483
+ 'target-arrow-shape': 'triangle',
484
+ 'curve-style': 'bezier',
485
+ 'control-point-step-size': 40,
486
+ 'label': 'data(label)',
487
+ 'font-size': '9px',
488
+ 'color': '#546E7A',
489
+ 'text-background-color': '#fff',
490
+ 'text-background-opacity': 1,
491
+ 'text-background-padding': '4px',
492
+ 'text-border-width': 1,
493
+ 'text-border-color': '#E0E0E0',
494
+ 'text-border-opacity': 0.8,
495
+ 'text-margin-y': -10,
496
+ 'z-index': 10
497
+ }
498
+ },
499
+ {
500
+ selector: 'edge[label="default"]',
501
+ style: {
502
+ 'line-color': '#90A4AE',
503
+ 'target-arrow-color': '#90A4AE'
504
+ }
505
+ },
506
+ {
507
+ selector: 'edge[label="queued"]',
508
+ style: {
509
+ 'line-color': '#66BB6A',
510
+ 'target-arrow-color': '#66BB6A'
511
+ }
512
+ },
513
+ {
514
+ selector: 'edge[label="failure"]',
515
+ style: {
516
+ 'line-color': '#EF5350',
517
+ 'target-arrow-color': '#EF5350'
518
+ }
519
+ },
520
+ {
521
+ selector: ':selected',
522
+ style: {
523
+ 'line-color': '#FF6B6B',
524
+ 'target-arrow-color': '#FF6B6B'
525
+ }
526
+ }
527
+ ];
528
+
529
+ const CREATABLE_WXCC_ACTIVITY_TYPES = new Set([
530
+ 'NewPhoneContact',
531
+ 'play-message',
532
+ 'play-music',
533
+ 'ivr-menu',
534
+ 'set-variable',
535
+ 'blind-transfer',
536
+ 'business-hours',
537
+ ]);
538
+ /**
539
+ * Map of node icons based on display type or label
540
+ */
541
+ const ICON_MAP = {
542
+ 'condition-activity': 'assets/wxcc/if.svg',
543
+ 'queue-contact': 'assets/wxcc/route.svg',
544
+ 'ivr-menu': 'assets/wxcc/m1.svg',
545
+ 'blind-transfer': 'assets/wxcc/terminate2.svg',
546
+ 'wait-activity': 'assets/wxcc/delay.svg',
547
+ 'newphonecontact': 'assets/wxcc/p1.svg',
548
+ 'disconnect-contact': 'assets/wxcc/terminate2.svg',
549
+ 'play-message': 'assets/wxcc/s1.svg',
550
+ 'play-music': 'assets/wxcc/delay.svg',
551
+ 'unmapped': 'assets/wxcc/unmapped.svg',
552
+ 'business-hours': 'assets/wxcc/c2.svg',
553
+ 'set-variable': 'assets/wxcc/variable.svg',
554
+ 'end': 'assets/wxcc/close1.svg'
555
+ };
556
+ /**
557
+ * Map of node color classes based on group
558
+ */
559
+ const COLOR_CLASS_MAP = {
560
+ 'start': 'node-start',
561
+ 'end': 'node-end',
562
+ 'terminating-action': 'node-end',
563
+ 'set-variable': 'node-action',
564
+ 'unmapped': 'node-default',
565
+ 'enum-gateway': 'node-gateway',
566
+ 'action': 'node-action'
567
+ };
568
+ /**
569
+ * Map of activity type labels based on group
570
+ */
571
+ const ACTIVITY_TYPE_LABELS = {
572
+ 'start': 'Start',
573
+ 'end': 'End',
574
+ 'terminating-action': 'Terminate',
575
+ 'enum-gateway': 'Menu',
576
+ 'action': 'Action',
577
+ 'unmapped': 'Unmapped'
578
+ };
579
+ /**
580
+ * All available activity display types for node configuration
581
+ * Values match ICON_MAP keys exactly
582
+ */
583
+ const ACTIVITY_DISPLAY_TYPES = [
584
+ { activityName: 'NewPhoneContact', value: 'newphonecontact', label: 'Start', icon: ICON_MAP['newphonecontact'], group: 'start' },
585
+ { activityName: 'end', value: 'end', label: 'End', icon: ICON_MAP['end'], group: 'end' },
586
+ { activityName: 'play-message', value: 'play-message', label: 'Play Message', icon: ICON_MAP['play-message'], group: 'action' },
587
+ { activityName: 'ivr-menu', value: 'ivr-menu', label: 'Menu', icon: ICON_MAP['ivr-menu'], group: 'enum-gateway' },
588
+ { activityName: 'queue-contact', value: 'queue-contact', label: 'Queue Contact', icon: ICON_MAP['queue-contact'], group: 'action' },
589
+ { activityName: 'set-variable', value: 'set-variable', label: 'Set Variable', icon: ICON_MAP['set-variable'], group: 'set-variable' },
590
+ { activityName: 'condition-activity', value: 'condition-activity', label: 'Condition', icon: ICON_MAP['condition-activity'], group: 'enum-gateway' },
591
+ { activityName: 'business-hours', value: 'business-hours', label: 'Business Hours', icon: ICON_MAP['business-hours'], group: 'enum-gateway' },
592
+ { activityName: 'wait-activity', value: 'wait-activity', label: 'Wait', icon: ICON_MAP['wait-activity'], group: 'action' },
593
+ { activityName: 'play-music', value: 'play-music', label: 'Play Music', icon: ICON_MAP['play-music'], group: 'action' },
594
+ { activityName: 'blind-transfer', value: 'blind-transfer', label: 'Blind Transfer', icon: ICON_MAP['blind-transfer'], group: 'action' },
595
+ { activityName: 'disconnect-contact', value: 'disconnect-contact', label: 'Disconnect', icon: ICON_MAP['disconnect-contact'], group: 'terminating-action' },
596
+ { activityName: 'unmapped', value: 'unmapped', label: 'Unmapped', icon: ICON_MAP['unmapped'], group: 'unmapped' }
597
+ ];
598
+ const CREATABLE_ACTIVITY_DISPLAY_TYPES = ACTIVITY_DISPLAY_TYPES
599
+ .filter(type => CREATABLE_WXCC_ACTIVITY_TYPES.has(type.activityName));
600
+ /**
601
+ * Get node icon information based on name or display type
602
+ * @param name - The node name or display type
603
+ * @returns Icon information with src and alt text
604
+ */
605
+ function getNodeIcon(name) {
606
+ const key = name.toLowerCase();
607
+ const iconSrc = ICON_MAP[key] || ICON_MAP['unmapped'];
608
+ return { iconSrc, alt: key };
609
+ }
610
+ /**
611
+ * Get node color class based on group
612
+ * @param group - The node group
613
+ * @returns CSS class name for node coloring
614
+ */
615
+ function getNodeColorClass(group) {
616
+ return COLOR_CLASS_MAP[group] || 'node-default';
617
+ }
618
+ /**
619
+ * Get activity type label based on group
620
+ * @param group - The node group
621
+ * @returns Human-readable activity type label
622
+ */
623
+ function getActivityTypeLabel(group) {
624
+ return ACTIVITY_TYPE_LABELS[group] || 'Activity';
625
+ }
626
+ /**
627
+ * Find activity display type by value
628
+ * @param value - The display type value
629
+ * @returns Display type or unmapped if not found
630
+ */
631
+ function getActivityDisplayTypeByValue(value) {
632
+ return ACTIVITY_DISPLAY_TYPES.find(dt => dt.value === value) || ACTIVITY_DISPLAY_TYPES[ACTIVITY_DISPLAY_TYPES.length - 1];
633
+ }
634
+ function getCreatableActivityDisplayTypeByValue(value) {
635
+ return CREATABLE_ACTIVITY_DISPLAY_TYPES.find(type => type.value === value) || CREATABLE_ACTIVITY_DISPLAY_TYPES[0];
636
+ }
637
+
638
+ function escapeHtml(text) {
639
+ if (!text)
640
+ return '';
641
+ return text
642
+ .replace(/&/g, '&')
643
+ .replace(/</g, '&lt;')
644
+ .replace(/>/g, '&gt;')
645
+ .replace(/"/g, '&quot;')
646
+ .replace(/'/g, '&#039;');
647
+ }
648
+ function getTranformedActivityName(name) {
649
+ return name
650
+ .split('-')
651
+ .map(s => s.charAt(0).toLocaleUpperCase() + s.slice(1))
652
+ .join(' ');
653
+ }
654
+ function getReviewElement(review) {
655
+ if (!review)
656
+ return `No review is available`;
657
+ const reviewColor = review.color;
658
+ const reviewColorLabel = `${reviewColor.charAt(0).toUpperCase()}${reviewColor.slice(1)}`;
659
+ const reviewLevelLabel = review.level.replace('_', ' ');
660
+ return `
661
+ <span class="review-${reviewColor}">
662
+ ${reviewColorLabel} (${reviewLevelLabel})
663
+ </span>
664
+ `;
665
+ }
666
+ function getNodeHtmlTemplate(data) {
667
+ const group = data.wxccGroup || 'unknown';
668
+ const colorClass = getNodeColorClass(group);
669
+ const typeLabel = getActivityTypeLabel(group);
670
+ const name = data.name ? data.name.split('\n')[0] : '';
671
+ const detailsHeading = (data.suggestedProperties && data.suggestedProperties.uccxDescription
672
+ ? data.suggestedProperties.uccxDescription
673
+ : '').trim();
674
+ const activityName = data.wxccActivityName || 'unmapped';
675
+ const iconInfo = data.iconUrl ?
676
+ { iconSrc: data.iconUrl, alt: data.iconUrl } :
677
+ getNodeIcon(typeLabel === 'Unmapped' ? typeLabel : activityName);
678
+ const { iconSrc, alt } = iconInfo;
679
+ const transformedActivityName = getTranformedActivityName(activityName);
680
+ const extraDetails = {
681
+ Review: getReviewElement(data.review)
682
+ };
683
+ // Allow highlight class to be toggled by data.highlighted property
684
+ const highlightClass = data.highlighted ? 'highlighted' : '';
685
+ return `
686
+ <div class="node-content ${colorClass} ${highlightClass}">
687
+ <header>
688
+ <div class="node-icon">
689
+ <img
690
+ src="${iconSrc}"
691
+ alt="${alt}"
692
+ title="${typeLabel}"
693
+ />
694
+ </div>
695
+ <div class="node-info">
696
+ <div class="node-label" title="${escapeHtml(name)}">${name}</div>
697
+ <div class="node-activity-name" title="${escapeHtml(transformedActivityName)}">
698
+ ${transformedActivityName}
699
+ </div>
700
+ </div>
701
+ </header>
702
+ <div class="node-details">
703
+ <div class="node-details-item" title="${escapeHtml(detailsHeading)}">${detailsHeading}</div>
704
+ ${Object.entries(extraDetails).map(([key, value]) => {
705
+ const fullText = `${key}: ${value}`;
706
+ return `<div>${fullText}</div>`;
707
+ })}
708
+ </div>
709
+ </div>
710
+ `;
711
+ }
712
+
713
+ class AddNodeDialogComponent {
714
+ constructor(data, dialogRef) {
715
+ this.data = data;
716
+ this.dialogRef = dialogRef;
717
+ this.activityDisplayTypes = CREATABLE_ACTIVITY_DISPLAY_TYPES;
718
+ this.selectedActivityType = CREATABLE_ACTIVITY_DISPLAY_TYPES[0];
719
+ this.nodeName = '';
720
+ this.selectedParentIds = [];
721
+ this.selectedChildIds = [];
722
+ this.availableNodes = [];
723
+ }
724
+ ngOnInit() {
725
+ this.availableNodes = this.data.availableNodes;
726
+ }
727
+ resetForm() {
728
+ this.selectedActivityType = CREATABLE_ACTIVITY_DISPLAY_TYPES[0];
729
+ this.nodeName = '';
730
+ this.selectedParentIds = [];
731
+ this.selectedChildIds = [];
732
+ }
733
+ onActivityTypeChange(value) {
734
+ this.selectedActivityType = getCreatableActivityDisplayTypeByValue(value);
735
+ }
736
+ onClose() {
737
+ this.dialogRef.close();
738
+ }
739
+ onSubmit() {
740
+ if (!this.nodeName.trim()) {
741
+ return;
742
+ }
743
+ const newNodeData = {
744
+ activityTypeName: this.selectedActivityType.activityName,
745
+ name: this.nodeName.trim(),
746
+ parentNodeIds: this.selectedParentIds,
747
+ childNodeIds: this.selectedChildIds
748
+ };
749
+ this.dialogRef.close(newNodeData);
750
+ }
751
+ trackByValue(index, type) {
752
+ return type.value;
753
+ }
754
+ trackByNodeId(index, node) {
755
+ return node.id;
756
+ }
757
+ }
758
+ AddNodeDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AddNodeDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1$2.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
759
+ AddNodeDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AddNodeDialogComponent, selector: "add-node-dialog", ngImport: i0, template: "", styles: [".form-group{margin-bottom:1.25rem}.form-group:last-child{margin-bottom:0}.form-group .form-label{display:block;font-size:.75rem;font-weight:600;color:#24292e;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px}.form-group .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.form-group .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.form-group .form-control::placeholder{color:#959da5}.form-group textarea.form-control{resize:vertical;min-height:80px}.form-group .display-type-preview{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:#f6f8fa;border-radius:6px;margin-bottom:.5rem}.form-group .display-type-preview .type-icon{width:20px;height:20px}.form-group .display-type-preview .type-label{font-size:.875rem;font-weight:500;color:#24292e}.form-group .node-selection-list{max-height:150px;overflow-y:auto;border:1px solid #d1d5da;border-radius:6px;background:#fafbfc}.form-group .node-selection-list .node-selection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background .15s;border-bottom:1px solid #e1e4e8}.form-group .node-selection-list .node-selection-item:last-child{border-bottom:none}.form-group .node-selection-list .node-selection-item:hover{background:#f0f3f6}.form-group .node-selection-list .node-selection-item.selected{background:rgba(3,102,214,.08)}.form-group .node-selection-list .node-selection-item .node-name{font-size:.8125rem;color:#24292e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group .node-selection-list .empty-list{padding:1rem;text-align:center;color:#586069;font-size:.8125rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AddNodeDialogComponent, decorators: [{
761
+ type: Component,
762
+ args: [{ selector: 'add-node-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "", styles: [".form-group{margin-bottom:1.25rem}.form-group:last-child{margin-bottom:0}.form-group .form-label{display:block;font-size:.75rem;font-weight:600;color:#24292e;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px}.form-group .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.form-group .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.form-group .form-control::placeholder{color:#959da5}.form-group textarea.form-control{resize:vertical;min-height:80px}.form-group .display-type-preview{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;background:#f6f8fa;border-radius:6px;margin-bottom:.5rem}.form-group .display-type-preview .type-icon{width:20px;height:20px}.form-group .display-type-preview .type-label{font-size:.875rem;font-weight:500;color:#24292e}.form-group .node-selection-list{max-height:150px;overflow-y:auto;border:1px solid #d1d5da;border-radius:6px;background:#fafbfc}.form-group .node-selection-list .node-selection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem .75rem;cursor:pointer;transition:background .15s;border-bottom:1px solid #e1e4e8}.form-group .node-selection-list .node-selection-item:last-child{border-bottom:none}.form-group .node-selection-list .node-selection-item:hover{background:#f0f3f6}.form-group .node-selection-list .node-selection-item.selected{background:rgba(3,102,214,.08)}.form-group .node-selection-list .node-selection-item .node-name{font-size:.8125rem;color:#24292e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group .node-selection-list .empty-list{padding:1rem;text-align:center;color:#586069;font-size:.8125rem}\n"] }]
763
+ }], ctorParameters: function () {
764
+ return [{ type: undefined, decorators: [{
765
+ type: Inject,
766
+ args: [MAT_DIALOG_DATA]
767
+ }] }, { type: i1$2.MatDialogRef }];
768
+ } });
769
+
770
+ class LinkNodeDialogComponent {
771
+ constructor(data, dialogRef) {
772
+ this.data = data;
773
+ this.dialogRef = dialogRef;
774
+ // @Input() isOpen = false;
775
+ // @Input() sourceNode: ActivityData | null = null;
776
+ this.availableNodes = [];
777
+ this.close = new EventEmitter();
778
+ this.linkNodes = new EventEmitter();
779
+ this.selectedTargetId = null;
780
+ this.linkLabel = '';
781
+ this.searchQuery = '';
782
+ }
783
+ ngOnInit() {
784
+ this.availableNodes = this.data.availableNodes;
785
+ this.sourceNode = this.data.sourceNode;
786
+ }
787
+ get filteredNodes() {
788
+ if (!this.sourceNode) {
789
+ return [];
790
+ }
791
+ if (!this.searchQuery.trim()) {
792
+ return this.availableNodes.filter(n => n && n.id !== this.sourceNode.id);
793
+ }
794
+ const query = this.searchQuery.toLowerCase();
795
+ return this.availableNodes.filter(n => n && n.id !== this.sourceNode.id &&
796
+ ((n.name && n.name.toLowerCase().includes(query)) ||
797
+ (n.wxccActivityName && n.wxccActivityName.toLowerCase().includes(query))));
798
+ }
799
+ ngOnChanges(changes) {
800
+ // if (changes['isOpen'] && this.isOpen) {
801
+ // this.resetForm();
802
+ // }
803
+ }
804
+ resetForm() {
805
+ this.selectedTargetId = null;
806
+ this.linkLabel = '';
807
+ this.searchQuery = '';
808
+ }
809
+ selectNode(nodeId) {
810
+ this.selectedTargetId = nodeId;
811
+ }
812
+ isSelected(nodeId) {
813
+ return this.selectedTargetId === nodeId;
814
+ }
815
+ onClose() {
816
+ this.dialogRef.close();
817
+ }
818
+ onSubmit() {
819
+ if (!this.sourceNode || !this.selectedTargetId) {
820
+ return;
821
+ }
822
+ const linkData = {
823
+ sourceNodeId: this.sourceNode.id,
824
+ targetNodeId: this.selectedTargetId,
825
+ label: this.linkLabel.trim() || undefined
826
+ };
827
+ this.dialogRef.close(linkData);
828
+ // this.linkNodes.emit(linkData);
829
+ // this.onClose();
830
+ }
831
+ trackByNodeId(index, node) {
832
+ return node.id;
833
+ }
834
+ }
835
+ LinkNodeDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LinkNodeDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1$2.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
836
+ LinkNodeDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LinkNodeDialogComponent, selector: "link-node-dialog", outputs: { close: "close", linkNodes: "linkNodes" }, usesOnChanges: true, ngImport: i0, template: "", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";.source-node-info{margin-bottom:1.25rem}.source-node-info .node-preview{display:flex;flex-direction:column;gap:.25rem;padding:.75rem 1rem;background:#f0f3f6;border-radius:6px}.source-node-info .node-preview .node-name{font-size:.875rem;font-weight:600;color:#24292e}.source-node-info .node-preview .node-type{font-size:.75rem;color:#586069}.form-group{margin-bottom:1.25rem}.form-group:last-child{margin-bottom:0}.form-group .form-label{display:block;font-size:.75rem;font-weight:600;color:#24292e;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px}.form-group .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.form-group .form-control:focus{outline:none;border-color:#0985a0;box-shadow:0 0 0 3px #0366d61a}.form-group .form-control::placeholder{color:#959da5}.form-group .search-input{margin-bottom:.75rem}.form-group .node-selection-list{max-height:200px;overflow-y:auto;border:1px solid #d1d5da;border-radius:6px;background:#fafbfc}.form-group .node-selection-list .node-selection-item{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;cursor:pointer;transition:background .15s;border-bottom:1px solid #e1e4e8}.form-group .node-selection-list .node-selection-item:last-child{border-bottom:none}.form-group .node-selection-list .node-selection-item:hover{background:#f0f3f6}.form-group .node-selection-list .node-selection-item.selected{background:rgba(0,155,183,.08)}.form-group .node-selection-list .node-selection-item.selected .node-radio{border-color:#0985a0}.form-group .node-selection-list .node-selection-item.selected .node-radio .radio-inner{background:#0985A0}.form-group .node-selection-list .node-selection-item .node-radio{width:18px;height:18px;border:2px solid #d1d5da;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .15s}.form-group .node-selection-list .node-selection-item .node-radio .radio-inner{width:10px;height:10px;border-radius:50%}.form-group .node-selection-list .node-selection-item .node-details{display:flex;flex-direction:column;gap:.125rem;min-width:0;flex:1}.form-group .node-selection-list .node-selection-item .node-details .node-name{font-size:.8125rem;font-weight:500;color:#24292e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group .node-selection-list .node-selection-item .node-details .node-type{font-size:.6875rem;color:#586569}.form-group .node-selection-list .empty-list{padding:1.5rem;text-align:center;color:#586569;font-size:.8125rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LinkNodeDialogComponent, decorators: [{
838
+ type: Component,
839
+ args: [{ selector: 'link-node-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";.source-node-info{margin-bottom:1.25rem}.source-node-info .node-preview{display:flex;flex-direction:column;gap:.25rem;padding:.75rem 1rem;background:#f0f3f6;border-radius:6px}.source-node-info .node-preview .node-name{font-size:.875rem;font-weight:600;color:#24292e}.source-node-info .node-preview .node-type{font-size:.75rem;color:#586069}.form-group{margin-bottom:1.25rem}.form-group:last-child{margin-bottom:0}.form-group .form-label{display:block;font-size:.75rem;font-weight:600;color:#24292e;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.5px}.form-group .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.form-group .form-control:focus{outline:none;border-color:#0985a0;box-shadow:0 0 0 3px #0366d61a}.form-group .form-control::placeholder{color:#959da5}.form-group .search-input{margin-bottom:.75rem}.form-group .node-selection-list{max-height:200px;overflow-y:auto;border:1px solid #d1d5da;border-radius:6px;background:#fafbfc}.form-group .node-selection-list .node-selection-item{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;cursor:pointer;transition:background .15s;border-bottom:1px solid #e1e4e8}.form-group .node-selection-list .node-selection-item:last-child{border-bottom:none}.form-group .node-selection-list .node-selection-item:hover{background:#f0f3f6}.form-group .node-selection-list .node-selection-item.selected{background:rgba(0,155,183,.08)}.form-group .node-selection-list .node-selection-item.selected .node-radio{border-color:#0985a0}.form-group .node-selection-list .node-selection-item.selected .node-radio .radio-inner{background:#0985A0}.form-group .node-selection-list .node-selection-item .node-radio{width:18px;height:18px;border:2px solid #d1d5da;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .15s}.form-group .node-selection-list .node-selection-item .node-radio .radio-inner{width:10px;height:10px;border-radius:50%}.form-group .node-selection-list .node-selection-item .node-details{display:flex;flex-direction:column;gap:.125rem;min-width:0;flex:1}.form-group .node-selection-list .node-selection-item .node-details .node-name{font-size:.8125rem;font-weight:500;color:#24292e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-group .node-selection-list .node-selection-item .node-details .node-type{font-size:.6875rem;color:#586569}.form-group .node-selection-list .empty-list{padding:1.5rem;text-align:center;color:#586569;font-size:.8125rem}\n"] }]
840
+ }], ctorParameters: function () {
841
+ return [{ type: undefined, decorators: [{
842
+ type: Inject,
843
+ args: [MAT_DIALOG_DATA]
844
+ }] }, { type: i1$2.MatDialogRef }];
845
+ }, propDecorators: { close: [{
846
+ type: Output
847
+ }], linkNodes: [{
848
+ type: Output
849
+ }] } });
850
+
851
+ class WxCC2GraphService {
852
+ parseWxCC(wxcc, nonIr) {
853
+ this.wxccJSON = wxcc;
854
+ if (nonIr) {
855
+ this.wxccNonIRJSON = nonIr;
856
+ }
857
+ const nodes = [];
858
+ const edges = [];
859
+ wxcc.activities.forEach(activity => nodes.push(this.toWxCCNode(activity)));
860
+ wxcc.links.forEach(link => edges.push(this.toWxCCEdge(link)));
861
+ return {
862
+ flowId: wxcc.generatedAt,
863
+ flowName: wxcc.prefix,
864
+ nodes: nodes,
865
+ edges: edges
866
+ };
867
+ }
868
+ setSourceDocuments(ir, nonIr) {
869
+ this.wxccJSON = ir;
870
+ this.wxccNonIRJSON = nonIr;
871
+ }
872
+ updateActivityData(data) {
873
+ const { iconUrl } = data, dataWithoutIcon = __rest(data, ["iconUrl"]);
874
+ const wxccActivityData = this.getActivityById(data.id);
875
+ if (!wxccActivityData) {
876
+ console.error(`Activity with id ${data.id} not found`);
877
+ return false;
878
+ }
879
+ const source = dataWithoutIcon;
880
+ const target = wxccActivityData;
881
+ Object.keys(source).forEach(key => {
882
+ if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
883
+ // For nested objects, merge them recursively
884
+ target[key] = Object.assign(Object.assign({}, target[key]), source[key]);
885
+ }
886
+ else {
887
+ // For primitives and arrays, assign directly
888
+ target[key] = source[key];
889
+ }
890
+ });
891
+ return true;
892
+ }
893
+ /**
894
+ * Add a new activity to the graph
895
+ */
896
+ addActivity(activity) {
897
+ // Add to internal JSON structure
898
+ this.wxccJSON.activities.push(activity);
899
+ return this.toWxCCNode(activity);
900
+ }
901
+ /**
902
+ * Remove an activity and all its connected links
903
+ */
904
+ removeActivity(activityId) {
905
+ // Remove the activity
906
+ const activityIndex = this.wxccJSON.activities.findIndex(a => a.id === activityId);
907
+ if (activityIndex !== -1) {
908
+ this.wxccJSON.activities.splice(activityIndex, 1);
909
+ }
910
+ // Find and remove all links connected to this activity
911
+ const removedLinkIds = [];
912
+ const linksToRemove = this.wxccJSON.links.filter(link => link.sourceActivityId === activityId || link.targetActivityId === activityId);
913
+ linksToRemove.forEach(link => {
914
+ removedLinkIds.push(link.id);
915
+ const linkIndex = this.wxccJSON.links.findIndex(l => l.id === link.id);
916
+ if (linkIndex !== -1) {
917
+ this.wxccJSON.links.splice(linkIndex, 1);
918
+ }
919
+ });
920
+ return { removedLinkIds };
921
+ }
922
+ /**
923
+ * Add a new link between two activities
924
+ */
925
+ addLink(sourceActivityId, targetActivityId, label) {
926
+ const linkId = this.generateId();
927
+ const link = {
928
+ id: linkId,
929
+ sourceActivityId,
930
+ targetActivityId,
931
+ uccxLabel: label || ''
932
+ };
933
+ this.wxccJSON.links.push(link);
934
+ return this.toWxCCEdge(link);
935
+ }
936
+ /**
937
+ * Remove a link by its id
938
+ */
939
+ removeLink(linkId) {
940
+ const linkIndex = this.wxccJSON.links.findIndex(l => l.id === linkId);
941
+ if (linkIndex !== -1) {
942
+ this.wxccJSON.links.splice(linkIndex, 1);
943
+ return true;
944
+ }
945
+ return false;
946
+ }
947
+ /**
948
+ * Check if a link already exists between two nodes
949
+ */
950
+ linkExists(sourceActivityId, targetActivityId) {
951
+ return this.wxccJSON.links.some(link => link.sourceActivityId === sourceActivityId && link.targetActivityId === targetActivityId);
952
+ }
953
+ /**
954
+ * Get all activities for selection purposes
955
+ */
956
+ getAllActivities() {
957
+ return [...this.wxccJSON.activities];
958
+ }
959
+ getActivityById(id) {
960
+ return this.wxccJSON.activities.find(a => a.id === id);
961
+ }
962
+ generateId() {
963
+ return uuid.v4();
964
+ }
965
+ toWxCCNode(activity) {
966
+ const label = activity.name || activity.wxccActivityName || 'Activity';
967
+ return {
968
+ data: Object.assign(Object.assign({}, activity), { label: label })
969
+ };
970
+ }
971
+ toWxCCEdge(link) {
972
+ const label = link.uccxLabel || link.conditionExpr || '';
973
+ return {
974
+ data: Object.assign(Object.assign({}, link), { source: link.sourceActivityId, target: link.targetActivityId, label: label })
975
+ };
976
+ }
977
+ }
978
+ WxCC2GraphService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCC2GraphService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
979
+ WxCC2GraphService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCC2GraphService });
980
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCC2GraphService, decorators: [{
981
+ type: Injectable
982
+ }] });
983
+
984
+ class WxCCActivityManageService {
985
+ constructor() {
986
+ this.ACTIVITY_TEMPLATES = {
987
+ NewPhoneContact: {
988
+ id: '',
989
+ type: 'NewPhoneContact',
990
+ group: 'start',
991
+ name: 'NewPhoneContact',
992
+ properties: {
993
+ name: 'NewPhoneContact',
994
+ event: 'NewPhoneContact',
995
+ flowType: {
996
+ eventSourceName: 'WebexContactCenter',
997
+ eventSpecificationName: 'ContactStartWorkflow',
998
+ eventClassificationId: '',
999
+ eventClassificationName: '',
1000
+ eventSpecificationId: '',
1001
+ eventSourceId: ''
1002
+ },
1003
+ activityName: 'NewPhoneContact',
1004
+ _renderRequestTimestamp: Date.now(),
1005
+ activityId: 'start'
1006
+ }
1007
+ },
1008
+ "blind-transfer": {
1009
+ id: '',
1010
+ type: 'blind-transfer',
1011
+ group: 'terminating-action',
1012
+ name: 'BlindTransfer',
1013
+ properties: {
1014
+ name: 'BlindTransfer',
1015
+ activityName: 'blind-transfer',
1016
+ _renderRequestTimestamp: Date.now(),
1017
+ transfertodn: '',
1018
+ activityId: '',
1019
+ transfertodn_radioName: 'dn',
1020
+ 'transfertodn:radioName': 'dn',
1021
+ customAttributes: {},
1022
+ flowDecryptAccess: false,
1023
+ }
1024
+ },
1025
+ "ivr-menu": {
1026
+ id: '',
1027
+ type: 'ivr-menu',
1028
+ group: 'enum-gateway',
1029
+ name: 'Menu',
1030
+ properties: {
1031
+ connector_name: null,
1032
+ name: 'Menu',
1033
+ menuLinks: [],
1034
+ toggle: false,
1035
+ activityName: 'ivr-menu',
1036
+ prompts: [],
1037
+ _renderRequestTimestamp: Date.now(),
1038
+ 'connector:name': null,
1039
+ activityId: '',
1040
+ 'menuLinks:input': [],
1041
+ entryTimeout: 3,
1042
+ volumeGainDb: 0,
1043
+ menuLinks_input: [],
1044
+ voiceLanguage_name: null,
1045
+ promptsTts: null,
1046
+ interruptible: false,
1047
+ connector: null,
1048
+ speakingRate: 1,
1049
+ toggleLanguage: null,
1050
+ voiceLanguage: null,
1051
+ flowDecryptAccess: false,
1052
+ 'voiceLanguage:name': null
1053
+ }
1054
+ },
1055
+ "play-message": {
1056
+ id: '',
1057
+ type: 'play-message',
1058
+ group: 'action',
1059
+ name: 'PlayMessage',
1060
+ properties: {
1061
+ connector_name: null,
1062
+ name: 'PlayMessage',
1063
+ toggle: false,
1064
+ activityName: 'play-message',
1065
+ prompts: [],
1066
+ _renderRequestTimestamp: Date.now(),
1067
+ 'connector:name': null,
1068
+ activityId: '',
1069
+ volumeGainDb: 0,
1070
+ voiceLanguage_name: null,
1071
+ promptsTts: null,
1072
+ connector: null,
1073
+ speakingRate: 1,
1074
+ toggleLanguage: null,
1075
+ voiceLanguage: null,
1076
+ flowDecryptAccess: false,
1077
+ 'voiceLanguage:name': null
1078
+ }
1079
+ },
1080
+ "play-music": {
1081
+ id: '',
1082
+ type: 'play-music',
1083
+ group: 'action',
1084
+ name: 'PlayPrompt',
1085
+ properties: {
1086
+ connector_name: null,
1087
+ name: 'PlayPrompt',
1088
+ toggle: false,
1089
+ activityName: 'play-music',
1090
+ prompts: [],
1091
+ _renderRequestTimestamp: Date.now(),
1092
+ 'connector:name': null,
1093
+ activityId: '',
1094
+ volumeGainDb: 0,
1095
+ voiceLanguage_name: null,
1096
+ promptsTts: null,
1097
+ connector: null,
1098
+ speakingRate: 1,
1099
+ toggleLanguage: null,
1100
+ voiceLanguage: null,
1101
+ flowDecryptAccess: false,
1102
+ 'voiceLanguage:name': null
1103
+ }
1104
+ },
1105
+ "set-variable": {
1106
+ id: '',
1107
+ type: 'set-variable',
1108
+ group: 'set-variable',
1109
+ name: 'SetVariable',
1110
+ properties: {
1111
+ setTo: 'set-to-literal',
1112
+ name: 'SetVariable',
1113
+ literal_invalid_error: false,
1114
+ activityName: 'set-variable',
1115
+ _renderRequestTimestamp: Date.now(),
1116
+ activityId: 'set-variable',
1117
+ setVariablesArray: [],
1118
+ flowDecryptAccess: false
1119
+ }
1120
+ },
1121
+ "business-hours": {
1122
+ id: '',
1123
+ type: 'business-hours',
1124
+ name: '',
1125
+ group: '',
1126
+ properties: {
1127
+ activityName: 'business-hours',
1128
+ _renderRequestTimestamp: Date.now(),
1129
+ activityId: ''
1130
+ }
1131
+ }
1132
+ };
1133
+ }
1134
+ create(type) {
1135
+ return JSON.parse(JSON.stringify(this.ACTIVITY_TEMPLATES[type]));
1136
+ }
1137
+ }
1138
+ WxCCActivityManageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityManageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1139
+ WxCCActivityManageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityManageService });
1140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityManageService, decorators: [{
1141
+ type: Injectable
1142
+ }] });
1143
+
1144
+ class WxCCActivityCreationService {
1145
+ constructor(wxcc2graph, wxccActivityTemplateService) {
1146
+ this.wxcc2graph = wxcc2graph;
1147
+ this.wxccActivityTemplateService = wxccActivityTemplateService;
1148
+ }
1149
+ createAndSync(request) {
1150
+ const newActivityId = this.wxcc2graph.generateId();
1151
+ const activityTemplate = this.buildTemplatedActivity(request, newActivityId);
1152
+ this.seedNonIrActivity(activityTemplate, newActivityId);
1153
+ const activityData = this.buildExtendedActivity(request, activityTemplate, newActivityId);
1154
+ const node = this.wxcc2graph.addActivity(activityData);
1155
+ return node;
1156
+ }
1157
+ buildTemplatedActivity(request, newActivityId) {
1158
+ const activityTemplate = this.wxccActivityTemplateService.create(request.activityTypeName);
1159
+ const templateProperties = activityTemplate.properties;
1160
+ const displayType = ACTIVITY_DISPLAY_TYPES.find((type) => type.activityName === request.activityTypeName);
1161
+ activityTemplate.id = newActivityId;
1162
+ activityTemplate.name = request.name;
1163
+ activityTemplate.group = activityTemplate.group || (displayType === null || displayType === void 0 ? void 0 : displayType.group) || "unmapped";
1164
+ activityTemplate.properties.activityId = newActivityId;
1165
+ activityTemplate.properties._renderRequestTimestamp = Date.now();
1166
+ // @ts-ignore
1167
+ templateProperties.name = request.name;
1168
+ return activityTemplate;
1169
+ }
1170
+ seedNonIrActivity(activityTemplate, newActivityId) {
1171
+ const nonIrActivities = this.getNonIrActivitiesMap();
1172
+ if (!nonIrActivities) {
1173
+ return;
1174
+ }
1175
+ nonIrActivities[newActivityId] = {
1176
+ id: newActivityId,
1177
+ group: activityTemplate.group,
1178
+ name: activityTemplate.name,
1179
+ properties: Object.assign({}, activityTemplate.properties),
1180
+ };
1181
+ }
1182
+ getNonIrActivitiesMap() {
1183
+ const nonIrDoc = this.wxcc2graph.wxccNonIRJSON;
1184
+ if (!nonIrDoc) {
1185
+ return null;
1186
+ }
1187
+ const process = nonIrDoc.process;
1188
+ if (!process) {
1189
+ return null;
1190
+ }
1191
+ const activities = process.activities;
1192
+ if (!activities) {
1193
+ return null;
1194
+ }
1195
+ return activities;
1196
+ }
1197
+ buildExtendedActivity(request, activityTemplate, newActivityId) {
1198
+ const displayType = ACTIVITY_DISPLAY_TYPES.find((type) => type.activityName === request.activityTypeName);
1199
+ return {
1200
+ id: newActivityId,
1201
+ name: request.name,
1202
+ wxccActivityName: activityTemplate.type,
1203
+ wxccGroup: activityTemplate.group,
1204
+ wxccActivityId: activityTemplate.properties.activityId,
1205
+ // @ts-ignore
1206
+ iconUrl: displayType.icon || "assets/wxcc/unmapped.svg",
1207
+ suggestedProperties: {
1208
+ uccxDescription: "",
1209
+ },
1210
+ };
1211
+ }
1212
+ }
1213
+ WxCCActivityCreationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityCreationService, deps: [{ token: WxCC2GraphService }, { token: WxCCActivityManageService }], target: i0.ɵɵFactoryTarget.Injectable });
1214
+ WxCCActivityCreationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityCreationService });
1215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActivityCreationService, decorators: [{
1216
+ type: Injectable
1217
+ }], ctorParameters: function () { return [{ type: WxCC2GraphService }, { type: WxCCActivityManageService }]; } });
1218
+
1219
+ const DEFAULT_VISIBILITY = {
1220
+ resetView: true,
1221
+ zoomIn: true,
1222
+ zoomOut: true,
1223
+ export: true
1224
+ };
1225
+ class FloatingToolBarComponent {
1226
+ constructor(sanitizer) {
1227
+ this.sanitizer = sanitizer;
1228
+ this.visibility = DEFAULT_VISIBILITY;
1229
+ this.resetViewChange = new EventEmitter();
1230
+ this.zoomInChange = new EventEmitter();
1231
+ this.zoomOutChange = new EventEmitter();
1232
+ this.exportImageChange = new EventEmitter();
1233
+ }
1234
+ ngOnInit() {
1235
+ const mergedVisibility = Object.assign(Object.assign({}, DEFAULT_VISIBILITY), this.visibility);
1236
+ const allItems = [
1237
+ {
1238
+ id: 'reset-view',
1239
+ visibilityKey: 'resetView',
1240
+ label: 'UCCX.BUTTONS.RESET_VIEW',
1241
+ svg: this.sanitizer.bypassSecurityTrustHtml(`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1242
+ <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
1243
+ <path d="M21 3v5h-5"></path>
1244
+ <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path>
1245
+ <path d="M3 21v-5h5"></path>
1246
+ </svg>`),
1247
+ action: () => this.resetView()
1248
+ },
1249
+ {
1250
+ id: 'zoom-in',
1251
+ visibilityKey: 'zoomIn',
1252
+ label: 'UCCX.BUTTONS.ZOOM_IN',
1253
+ svg: this.sanitizer.bypassSecurityTrustHtml(`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1254
+ <circle cx="11" cy="11" r="8"></circle>
1255
+ <path d="m21 21-4.35-4.35"></path>
1256
+ <path d="M11 8v6M8 11h6"></path>
1257
+ </svg>`),
1258
+ action: () => this.zoomIn()
1259
+ },
1260
+ {
1261
+ id: 'zoom-out',
1262
+ visibilityKey: 'zoomOut',
1263
+ label: 'UCCX.BUTTONS.ZOOM_OUT',
1264
+ svg: this.sanitizer.bypassSecurityTrustHtml(`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1265
+ <circle cx="11" cy="11" r="8"></circle>
1266
+ <path d="m21 21-4.35-4.35"></path>
1267
+ <path d="M8 11h6"></path>
1268
+ </svg>`),
1269
+ action: () => this.zoomOut()
1270
+ },
1271
+ {
1272
+ id: 'export',
1273
+ visibilityKey: 'export',
1274
+ label: 'UCCX.BUTTONS.EXPORT',
1275
+ svg: this.sanitizer.bypassSecurityTrustHtml(`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1276
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
1277
+ <polyline points="7 10 12 15 17 10"></polyline>
1278
+ <line x1="12" y1="15" x2="12" y2="3"></line>
1279
+ </svg>`),
1280
+ action: () => this.exportImage()
1281
+ }
1282
+ ];
1283
+ this.toolbarConfig = allItems.filter(item => mergedVisibility[item.visibilityKey] !== false);
1284
+ }
1285
+ resetView() {
1286
+ this.resetViewChange.emit();
1287
+ }
1288
+ zoomIn() {
1289
+ this.zoomInChange.emit();
1290
+ }
1291
+ zoomOut() {
1292
+ this.zoomOutChange.emit();
1293
+ }
1294
+ exportImage() {
1295
+ this.exportImageChange.emit();
1296
+ }
1297
+ trackById(index, item) {
1298
+ return item.id;
1299
+ }
1300
+ }
1301
+ FloatingToolBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolBarComponent, deps: [{ token: i1$3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1302
+ FloatingToolBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FloatingToolBarComponent, selector: "graph-floating-toolbar", inputs: { visibility: "visibility" }, outputs: { resetViewChange: "resetViewChange", zoomInChange: "zoomInChange", zoomOutChange: "zoomOutChange", exportImageChange: "exportImageChange" }, ngImport: i0, template: "<div class=\"toolbar-wrapper\" role=\"toolbar\">\r\n <ng-container *ngFor=\"let item of toolbarConfig; trackBy: trackById\">\r\n <button\r\n type=\"button\"\r\n [attr.aria-label]=\"item.label\"\r\n [matTooltip]=\"item.label\"\r\n matTooltipPosition=\"left\"\r\n class=\"toolbar-button\"\r\n (click)=\"item.action()\">\r\n <div [innerHTML]=\"item.svg\"></div>\r\n </button>\r\n </ng-container>\r\n</div>", styles: [".toolbar-wrapper{background-color:#ffffffac;position:absolute;display:flex;flex-direction:column;gap:.5rem;bottom:0;right:0;padding:.5rem;width:-moz-fit-content;width:fit-content;margin:1rem;border-radius:1rem;box-shadow:2px 4px 15px #0000002d;z-index:999}.toolbar-wrapper button{outline:none;border:none;border-radius:.5rem;background-color:#f6f6f6;padding:.5rem;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;width:40px;height:40px;transition:all .2s ease}.toolbar-wrapper button:hover{background-color:#eefff8;transform:scale(1.05)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolBarComponent, decorators: [{
1304
+ type: Component,
1305
+ args: [{ selector: 'graph-floating-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"toolbar-wrapper\" role=\"toolbar\">\r\n <ng-container *ngFor=\"let item of toolbarConfig; trackBy: trackById\">\r\n <button\r\n type=\"button\"\r\n [attr.aria-label]=\"item.label\"\r\n [matTooltip]=\"item.label\"\r\n matTooltipPosition=\"left\"\r\n class=\"toolbar-button\"\r\n (click)=\"item.action()\">\r\n <div [innerHTML]=\"item.svg\"></div>\r\n </button>\r\n </ng-container>\r\n</div>", styles: [".toolbar-wrapper{background-color:#ffffffac;position:absolute;display:flex;flex-direction:column;gap:.5rem;bottom:0;right:0;padding:.5rem;width:-moz-fit-content;width:fit-content;margin:1rem;border-radius:1rem;box-shadow:2px 4px 15px #0000002d;z-index:999}.toolbar-wrapper button{outline:none;border:none;border-radius:.5rem;background-color:#f6f6f6;padding:.5rem;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;width:40px;height:40px;transition:all .2s ease}.toolbar-wrapper button:hover{background-color:#eefff8;transform:scale(1.05)}\n"] }]
1306
+ }], ctorParameters: function () { return [{ type: i1$3.DomSanitizer }]; }, propDecorators: { visibility: [{
1307
+ type: Input
1308
+ }], resetViewChange: [{
1309
+ type: Output
1310
+ }], zoomInChange: [{
1311
+ type: Output
1312
+ }], zoomOutChange: [{
1313
+ type: Output
1314
+ }], exportImageChange: [{
1315
+ type: Output
1316
+ }] } });
1317
+
1318
+ class NodeDetailsSidebarComponent {
1319
+ constructor() {
1320
+ this.isOpen = false;
1321
+ this.nodeData = null;
1322
+ this.close = new EventEmitter();
1323
+ this.activityTypeChange = new EventEmitter();
1324
+ this.descriptionChange = new EventEmitter();
1325
+ this.activityDisplayTypes = ACTIVITY_DISPLAY_TYPES;
1326
+ this.selectedActivityType = null;
1327
+ }
1328
+ ngOnChanges(changes) {
1329
+ if (changes['nodeData'] && this.nodeData) {
1330
+ this.initializeActivityType();
1331
+ }
1332
+ }
1333
+ initializeActivityType() {
1334
+ const activityName = this.nodeData && this.nodeData.wxccActivityName;
1335
+ this.selectedActivityType = getActivityDisplayTypeByValue((activityName || 'unmapped').toLocaleLowerCase());
1336
+ this.transformedActivityName = getTranformedActivityName(activityName || 'unmapped');
1337
+ }
1338
+ onDescriptionChange(event) {
1339
+ const target = event.target;
1340
+ if (!target) {
1341
+ return;
1342
+ }
1343
+ const description = target.value.trim();
1344
+ if (!description)
1345
+ return;
1346
+ this.descriptionChange.emit(description);
1347
+ }
1348
+ onActivityTypeChange(type) {
1349
+ this.selectedActivityType = type;
1350
+ this.activityTypeChange.emit(type);
1351
+ }
1352
+ onActivityTypeSelectChange(event) {
1353
+ const target = event.target;
1354
+ if (!target) {
1355
+ return;
1356
+ }
1357
+ const value = target.value;
1358
+ const type = getActivityDisplayTypeByValue(value);
1359
+ this.onActivityTypeChange(type);
1360
+ }
1361
+ onClose() {
1362
+ this.close.emit();
1363
+ }
1364
+ getNodeIcon() {
1365
+ return (this.selectedActivityType && this.selectedActivityType.icon) || ICON_MAP['unmapped'];
1366
+ }
1367
+ getNodeColorClass() {
1368
+ const group = (this.selectedActivityType && this.selectedActivityType.group) || 'unmapped';
1369
+ return getNodeColorClass(group);
1370
+ }
1371
+ getReviewColor() {
1372
+ const color = (this.nodeData && this.nodeData.review && this.nodeData.review.color) ||
1373
+ 'green';
1374
+ const colors = {
1375
+ 'green': '#4CAF50',
1376
+ 'yellow': '#FF9800',
1377
+ 'red': '#F44336'
1378
+ };
1379
+ return colors[color] || colors['green'];
1380
+ }
1381
+ getReviewLabel() {
1382
+ const color = (this.nodeData && this.nodeData.review && this.nodeData.review.color) ||
1383
+ 'green';
1384
+ const level = (this.nodeData && this.nodeData.review && this.nodeData.review.level) ||
1385
+ 'confident';
1386
+ return `${color.charAt(0).toUpperCase() + color.slice(1)} (${level.replace('_', ' ')})`;
1387
+ }
1388
+ trackByValue(index, type) {
1389
+ return type.value;
1390
+ }
1391
+ }
1392
+ NodeDetailsSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeDetailsSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1393
+ NodeDetailsSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NodeDetailsSidebarComponent, selector: "node-details-sidebar", inputs: { isOpen: "isOpen", nodeData: "nodeData" }, outputs: { close: "close", activityTypeChange: "activityTypeChange", descriptionChange: "descriptionChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- <div class=\"sidebar-overlay\" *ngIf=\"isOpen\" (click)=\"onClose()\"></div> -->\r\n\r\n<div class=\"node-details-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <h3>Node Details</h3>\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <span>&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" *ngIf=\"nodeData\">\r\n <!-- Node Preview -->\r\n <div class=\"node-preview\">\r\n <div class=\"node-preview-card\" [ngClass]=\"getNodeColorClass()\">\r\n <div class=\"node-icon\">\r\n <img [src]=\"getNodeIcon()\" alt=\"Node Icon\" />\r\n </div>\r\n <div class=\"node-info\">\r\n <div class=\"node-label\">{{ nodeData?.name?.split(\"\\n\")?.[0] }}</div>\r\n <div class=\"node-type\">{{ transformedActivityName }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Activity Type Selector -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Activity Type</label>\r\n <div class=\"display-type-selector\">\r\n <select\r\n class=\"form-control\"\r\n title=\"Select activity type\"\r\n [value]=\"selectedActivityType?.value\"\r\n (change)=\"onActivityTypeSelectChange($event)\"\r\n >\r\n <option\r\n *ngFor=\"let type of activityDisplayTypes; trackBy: trackByValue\"\r\n [value]=\"type.value\"\r\n >\r\n {{ type.label }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <label class=\"section-label\">Description</label>\r\n <div class=\"display-type-selector\">\r\n <textarea\r\n class=\"form-control\"\r\n aria-label=\"property-description\"\r\n (input)=\"onDescriptionChange($event)\"\r\n [value]=\"nodeData.suggestedProperties?.uccxDescription\"\r\n rows=\"3\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n\r\n <!-- Node Information -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Information</label>\r\n <div class=\"info-grid\">\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">UCCX Type:</span>\r\n <span class=\"info-value\" [title]=\"nodeData.uccxTypeName\">{{\r\n nodeData.uccxTypeName\r\n }}</span>\r\n </div>\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">WxCC Activity Name:</span>\r\n <span class=\"info-value\" [title]=\"transformedActivityName\">{{\r\n transformedActivityName\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Review Status -->\r\n <div class=\"section\" *ngIf=\"nodeData.review\">\r\n <label class=\"section-label\">Review Status</label>\r\n <div class=\"review-status\">\r\n <div class=\"review-badge\" [style.background-color]=\"getReviewColor()\">\r\n {{ getReviewLabel() }}\r\n </div>\r\n <div\r\n class=\"review-reasons\"\r\n *ngIf=\"nodeData.review.reasons && nodeData.review.reasons.length > 0\"\r\n >\r\n <div class=\"reason\" *ngFor=\"let reason of nodeData.review.reasons\">\r\n <span class=\"reason-icon\">\u26A0</span>\r\n <span>{{ reason }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Suggested Properties -->\r\n <div class=\"section\" *ngIf=\"nodeData.suggestedProperties\">\r\n <label class=\"section-label\">Migration Information</label>\r\n <div class=\"migration-info\">\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.closestWxccActivity\"\r\n >\r\n <div class=\"card-label\">Closest WXCC Activity</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.closestWxccActivity }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.mappingNotes\"\r\n >\r\n <div class=\"card-label\">Mapping Notes</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.mappingNotes }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.migrationInstructions\"\r\n >\r\n <div class=\"card-label\">Migration Instructions</div>\r\n <div class=\"card-value instructions\">\r\n {{ nodeData.suggestedProperties.migrationInstructions }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.node-details-sidebar{position:fixed;top:0;right:-420px;width:420px;height:100%;background:#ffffff;box-shadow:-2px 0 8px #00000026;z-index:1000;transition:right .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;overflow:hidden}.node-details-sidebar.open{right:0}.node-details-sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid #e1e4e8;background:#f8f9fa}.node-details-sidebar .sidebar-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#24292e}.node-details-sidebar .sidebar-header .close-btn{background:none;border:none;font-size:2rem;line-height:1;cursor:pointer;color:#586069;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.node-details-sidebar .sidebar-header .close-btn:hover{background:rgba(0,0,0,.05);color:#24292e}.node-details-sidebar .sidebar-content{flex:1;overflow-y:auto;padding:1.5rem}.node-details-sidebar .sidebar-content .node-preview{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .node-preview .node-preview-card{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:8px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;flex-shrink:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon img{width:24px;height:24px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info{flex:1;min-width:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-label{font-size:1rem;font-weight:600;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-type{font-size:.875rem;color:#586069}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start{background-color:#4caf500d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-icon{background-color:#4caf501a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-label{color:#4caf50}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end{background-color:#f443360d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-icon{background-color:#f443361a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-label{color:#f44336}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway{background-color:#ff98000d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-icon{background-color:#ff98001a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-label{color:#ff9800}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action{background-color:#9c27b00d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-icon{background-color:#9c27b01a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-label{color:#9c27b0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default{background-color:#607d8b0d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-icon{background-color:#607d8b1a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-label{color:#607d8b}.node-details-sidebar .sidebar-content .section{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .section .section-label{display:block;font-size:.65rem;font-weight:600;color:#24292e;margin-bottom:.75rem;text-transform:uppercase;letter-spacing:.5px}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s;box-sizing:border-box;resize:vertical}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.node-details-sidebar .sidebar-content .section .info-grid{display:flex;flex-direction:column;gap:.75rem}.node-details-sidebar .sidebar-content .section .info-grid .info-item{display:flex;justify-content:space-between;align-items:flex-start;padding:.75rem;background:#f6f8fa;border-radius:6px}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-label{font-size:.8125rem;color:#586069;font-weight:500}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-value{font-size:.8125rem;color:#24292e;font-weight:600;text-align:right;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .section .review-status .review-badge{display:inline-block;padding:.5rem 1rem;border-radius:20px;color:#fff;font-size:.8125rem;font-weight:600;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#fff3cd;border-radius:4px;margin-bottom:.5rem;font-size:.8125rem;color:#856404}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason .reason-icon{flex-shrink:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card{padding:1rem;background:#f6f8fa;border-radius:6px;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card:last-child{margin-bottom:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-label{font-size:.75rem;font-weight:600;color:#586069;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value{font-size:.875rem;color:#24292e;line-height:1.5}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value.instructions{white-space:pre-wrap}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1394
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeDetailsSidebarComponent, decorators: [{
1395
+ type: Component,
1396
+ args: [{ selector: 'node-details-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- <div class=\"sidebar-overlay\" *ngIf=\"isOpen\" (click)=\"onClose()\"></div> -->\r\n\r\n<div class=\"node-details-sidebar\" [class.open]=\"isOpen\">\r\n <div class=\"sidebar-header\">\r\n <h3>Node Details</h3>\r\n <button class=\"close-btn\" (click)=\"onClose()\">\r\n <span>&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"sidebar-content\" *ngIf=\"nodeData\">\r\n <!-- Node Preview -->\r\n <div class=\"node-preview\">\r\n <div class=\"node-preview-card\" [ngClass]=\"getNodeColorClass()\">\r\n <div class=\"node-icon\">\r\n <img [src]=\"getNodeIcon()\" alt=\"Node Icon\" />\r\n </div>\r\n <div class=\"node-info\">\r\n <div class=\"node-label\">{{ nodeData?.name?.split(\"\\n\")?.[0] }}</div>\r\n <div class=\"node-type\">{{ transformedActivityName }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Activity Type Selector -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Activity Type</label>\r\n <div class=\"display-type-selector\">\r\n <select\r\n class=\"form-control\"\r\n title=\"Select activity type\"\r\n [value]=\"selectedActivityType?.value\"\r\n (change)=\"onActivityTypeSelectChange($event)\"\r\n >\r\n <option\r\n *ngFor=\"let type of activityDisplayTypes; trackBy: trackByValue\"\r\n [value]=\"type.value\"\r\n >\r\n {{ type.label }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"section\">\r\n <label class=\"section-label\">Description</label>\r\n <div class=\"display-type-selector\">\r\n <textarea\r\n class=\"form-control\"\r\n aria-label=\"property-description\"\r\n (input)=\"onDescriptionChange($event)\"\r\n [value]=\"nodeData.suggestedProperties?.uccxDescription\"\r\n rows=\"3\"\r\n ></textarea>\r\n </div>\r\n </div>\r\n\r\n <!-- Node Information -->\r\n <div class=\"section\">\r\n <label class=\"section-label\">Information</label>\r\n <div class=\"info-grid\">\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">UCCX Type:</span>\r\n <span class=\"info-value\" [title]=\"nodeData.uccxTypeName\">{{\r\n nodeData.uccxTypeName\r\n }}</span>\r\n </div>\r\n <div class=\"info-item\">\r\n <span class=\"info-label\">WxCC Activity Name:</span>\r\n <span class=\"info-value\" [title]=\"transformedActivityName\">{{\r\n transformedActivityName\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Review Status -->\r\n <div class=\"section\" *ngIf=\"nodeData.review\">\r\n <label class=\"section-label\">Review Status</label>\r\n <div class=\"review-status\">\r\n <div class=\"review-badge\" [style.background-color]=\"getReviewColor()\">\r\n {{ getReviewLabel() }}\r\n </div>\r\n <div\r\n class=\"review-reasons\"\r\n *ngIf=\"nodeData.review.reasons && nodeData.review.reasons.length > 0\"\r\n >\r\n <div class=\"reason\" *ngFor=\"let reason of nodeData.review.reasons\">\r\n <span class=\"reason-icon\">\u26A0</span>\r\n <span>{{ reason }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Suggested Properties -->\r\n <div class=\"section\" *ngIf=\"nodeData.suggestedProperties\">\r\n <label class=\"section-label\">Migration Information</label>\r\n <div class=\"migration-info\">\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.closestWxccActivity\"\r\n >\r\n <div class=\"card-label\">Closest WXCC Activity</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.closestWxccActivity }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.mappingNotes\"\r\n >\r\n <div class=\"card-label\">Mapping Notes</div>\r\n <div class=\"card-value\">\r\n {{ nodeData.suggestedProperties.mappingNotes }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"info-card\"\r\n *ngIf=\"nodeData.suggestedProperties.migrationInstructions\"\r\n >\r\n <div class=\"card-label\">Migration Instructions</div>\r\n <div class=\"card-value instructions\">\r\n {{ nodeData.suggestedProperties.migrationInstructions }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.node-details-sidebar{position:fixed;top:0;right:-420px;width:420px;height:100%;background:#ffffff;box-shadow:-2px 0 8px #00000026;z-index:1000;transition:right .4s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;overflow:hidden}.node-details-sidebar.open{right:0}.node-details-sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem;border-bottom:1px solid #e1e4e8;background:#f8f9fa}.node-details-sidebar .sidebar-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#24292e}.node-details-sidebar .sidebar-header .close-btn{background:none;border:none;font-size:2rem;line-height:1;cursor:pointer;color:#586069;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s}.node-details-sidebar .sidebar-header .close-btn:hover{background:rgba(0,0,0,.05);color:#24292e}.node-details-sidebar .sidebar-content{flex:1;overflow-y:auto;padding:1.5rem}.node-details-sidebar .sidebar-content .node-preview{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .node-preview .node-preview-card{display:flex;align-items:center;gap:1rem;padding:1rem;border-radius:8px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon{display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;flex-shrink:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-icon img{width:24px;height:24px}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info{flex:1;min-width:0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-label{font-size:1rem;font-weight:600;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .node-preview .node-preview-card .node-info .node-type{font-size:.875rem;color:#586069}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start{background-color:#4caf500d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-icon{background-color:#4caf501a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-start .node-label{color:#4caf50}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end{background-color:#f443360d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-icon{background-color:#f443361a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-end .node-label{color:#f44336}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway{background-color:#ff98000d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-icon{background-color:#ff98001a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-gateway .node-label{color:#ff9800}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action{background-color:#9c27b00d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-icon{background-color:#9c27b01a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-action .node-label{color:#9c27b0}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default{background-color:#607d8b0d}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-icon{background-color:#607d8b1a}.node-details-sidebar .sidebar-content .node-preview .node-preview-card.node-default .node-label{color:#607d8b}.node-details-sidebar .sidebar-content .section{margin-bottom:1.5rem}.node-details-sidebar .sidebar-content .section .section-label{display:block;font-size:.65rem;font-weight:600;color:#24292e;margin-bottom:.75rem;text-transform:uppercase;letter-spacing:.5px}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control{width:100%;padding:.625rem .875rem;font-size:.875rem;border:1px solid #d1d5da;border-radius:6px;background:white;transition:border-color .2s;box-sizing:border-box;resize:vertical}.node-details-sidebar .sidebar-content .section .display-type-selector .form-control:focus{outline:none;border-color:#0366d6;box-shadow:0 0 0 3px #0366d61a}.node-details-sidebar .sidebar-content .section .info-grid{display:flex;flex-direction:column;gap:.75rem}.node-details-sidebar .sidebar-content .section .info-grid .info-item{display:flex;justify-content:space-between;align-items:flex-start;padding:.75rem;background:#f6f8fa;border-radius:6px}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-label{font-size:.8125rem;color:#586069;font-weight:500}.node-details-sidebar .sidebar-content .section .info-grid .info-item .info-value{font-size:.8125rem;color:#24292e;font-weight:600;text-align:right;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-details-sidebar .sidebar-content .section .review-status .review-badge{display:inline-block;padding:.5rem 1rem;border-radius:20px;color:#fff;font-size:.8125rem;font-weight:600;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#fff3cd;border-radius:4px;margin-bottom:.5rem;font-size:.8125rem;color:#856404}.node-details-sidebar .sidebar-content .section .review-status .review-reasons .reason .reason-icon{flex-shrink:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card{padding:1rem;background:#f6f8fa;border-radius:6px;margin-bottom:.75rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card:last-child{margin-bottom:0}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-label{font-size:.75rem;font-weight:600;color:#586069;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value{font-size:.875rem;color:#24292e;line-height:1.5}.node-details-sidebar .sidebar-content .section .migration-info .info-card .card-value.instructions{white-space:pre-wrap}\n"] }]
1397
+ }], propDecorators: { isOpen: [{
1398
+ type: Input
1399
+ }], nodeData: [{
1400
+ type: Input
1401
+ }], close: [{
1402
+ type: Output
1403
+ }], activityTypeChange: [{
1404
+ type: Output
1405
+ }], descriptionChange: [{
1406
+ type: Output
1407
+ }] } });
1408
+
1409
+ class NodeActionToolbarComponent {
1410
+ constructor(sanitizer) {
1411
+ this.sanitizer = sanitizer;
1412
+ this.isVisible = false;
1413
+ this.position = { x: 0, y: 0 };
1414
+ this.deleteNode = new EventEmitter();
1415
+ this.linkNode = new EventEmitter();
1416
+ this.toolbarActions = [
1417
+ {
1418
+ id: 'link',
1419
+ label: 'Link to Node',
1420
+ svg: this.sanitizer.bypassSecurityTrustHtml(`
1421
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1422
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
1423
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
1424
+ </svg>
1425
+ `),
1426
+ action: () => this.onLinkNode()
1427
+ },
1428
+ {
1429
+ id: 'delete',
1430
+ label: 'Delete Node',
1431
+ svg: this.sanitizer.bypassSecurityTrustHtml(`
1432
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1433
+ <path d="M3 6h18"></path>
1434
+ <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
1435
+ <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
1436
+ <line x1="10" y1="11" x2="10" y2="17"></line>
1437
+ <line x1="14" y1="11" x2="14" y2="17"></line>
1438
+ </svg>
1439
+ `),
1440
+ action: () => this.onDeleteNode()
1441
+ }
1442
+ ];
1443
+ }
1444
+ onDeleteNode() {
1445
+ this.deleteNode.emit();
1446
+ }
1447
+ onLinkNode() {
1448
+ this.linkNode.emit();
1449
+ }
1450
+ trackById(index, item) {
1451
+ return item.id;
1452
+ }
1453
+ }
1454
+ NodeActionToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeActionToolbarComponent, deps: [{ token: i1$3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1455
+ NodeActionToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NodeActionToolbarComponent, selector: "node-action-toolbar", inputs: { isVisible: "isVisible", position: "position" }, outputs: { deleteNode: "deleteNode", linkNode: "linkNode" }, ngImport: i0, template: "<div \r\n class=\"node-action-toolbar\" \r\n [class.visible]=\"isVisible\"\r\n [style.left.px]=\"position.x\"\r\n [style.top.px]=\"position.y\">\r\n <ng-container *ngFor=\"let action of toolbarActions; trackBy: trackById\">\r\n <button\r\n type=\"button\"\r\n class=\"toolbar-action-btn\"\r\n [class.delete-btn]=\"action.id === 'delete'\"\r\n [attr.aria-label]=\"action.label\"\r\n [matTooltip]=\"action.label\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"action.action()\">\r\n <div [innerHTML]=\"action.svg\"></div>\r\n </button>\r\n </ng-container>\r\n</div>\r\n", styles: [".node-action-toolbar{position:absolute;display:flex;flex-direction:row;gap:.25rem;padding:.35rem;background:white;border-radius:6px;box-shadow:0 2px 8px #0000001a;border:1px solid #d8d8d8;z-index:1000;opacity:0;visibility:hidden;transform:translateY(10px);transition:all .2s ease;pointer-events:none}.node-action-toolbar.visible{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.node-action-toolbar .toolbar-action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:4px;background:#f6f8fa;color:#586069;cursor:pointer;transition:all .15s ease}.node-action-toolbar .toolbar-action-btn:hover{background:#e1e4e8;color:#24292e;transform:scale(1.05)}.node-action-toolbar .toolbar-action-btn:active{transform:scale(.95)}.node-action-toolbar .toolbar-action-btn.delete-btn:hover{background:rgba(244,67,54,.1);color:#f44336}.node-action-toolbar .toolbar-action-btn div{display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeActionToolbarComponent, decorators: [{
1457
+ type: Component,
1458
+ args: [{ selector: 'node-action-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \r\n class=\"node-action-toolbar\" \r\n [class.visible]=\"isVisible\"\r\n [style.left.px]=\"position.x\"\r\n [style.top.px]=\"position.y\">\r\n <ng-container *ngFor=\"let action of toolbarActions; trackBy: trackById\">\r\n <button\r\n type=\"button\"\r\n class=\"toolbar-action-btn\"\r\n [class.delete-btn]=\"action.id === 'delete'\"\r\n [attr.aria-label]=\"action.label\"\r\n [matTooltip]=\"action.label\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"action.action()\">\r\n <div [innerHTML]=\"action.svg\"></div>\r\n </button>\r\n </ng-container>\r\n</div>\r\n", styles: [".node-action-toolbar{position:absolute;display:flex;flex-direction:row;gap:.25rem;padding:.35rem;background:white;border-radius:6px;box-shadow:0 2px 8px #0000001a;border:1px solid #d8d8d8;z-index:1000;opacity:0;visibility:hidden;transform:translateY(10px);transition:all .2s ease;pointer-events:none}.node-action-toolbar.visible{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}.node-action-toolbar .toolbar-action-btn{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:4px;background:#f6f8fa;color:#586069;cursor:pointer;transition:all .15s ease}.node-action-toolbar .toolbar-action-btn:hover{background:#e1e4e8;color:#24292e;transform:scale(1.05)}.node-action-toolbar .toolbar-action-btn:active{transform:scale(.95)}.node-action-toolbar .toolbar-action-btn.delete-btn:hover{background:rgba(244,67,54,.1);color:#f44336}.node-action-toolbar .toolbar-action-btn div{display:flex;align-items:center;justify-content:center}\n"] }]
1459
+ }], ctorParameters: function () { return [{ type: i1$3.DomSanitizer }]; }, propDecorators: { isVisible: [{
1460
+ type: Input
1461
+ }], position: [{
1462
+ type: Input
1463
+ }], deleteNode: [{
1464
+ type: Output
1465
+ }], linkNode: [{
1466
+ type: Output
1467
+ }] } });
1468
+
1469
+ class NodeSearchPanelComponent {
1470
+ constructor() {
1471
+ this.searchChange = new EventEmitter();
1472
+ this.selectNodeChange = new EventEmitter();
1473
+ }
1474
+ ngOnInit() {
1475
+ this.filteredNodes = this.nodes;
1476
+ }
1477
+ onSearchChange(event) {
1478
+ const value = event.target.value.trim().toLowerCase();
1479
+ if (!value) {
1480
+ this.filteredNodes = this.nodes.slice();
1481
+ return;
1482
+ }
1483
+ this.filteredNodes = this.nodes
1484
+ .filter(node => {
1485
+ var _a, _b, _c, _d, _e;
1486
+ return ((_a = node.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(value)) ||
1487
+ ((_b = node.wxccActivityName) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes(value)) ||
1488
+ ((_c = node.uccxTypeName) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes(value)) ||
1489
+ ((_d = node.wxccGroup) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes(value)) ||
1490
+ ((_e = node.uccxDisplayType) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes(value));
1491
+ });
1492
+ }
1493
+ onSelectNodeChange(event) {
1494
+ const target = event.target;
1495
+ const id = target.id;
1496
+ this.selectNodeChange.emit(id);
1497
+ }
1498
+ }
1499
+ NodeSearchPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeSearchPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1500
+ NodeSearchPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NodeSearchPanelComponent, selector: "node-search-panel", inputs: { nodes: "nodes" }, outputs: { searchChange: "searchChange", selectNodeChange: "selectNodeChange" }, ngImport: i0, template: "<div class=\"search-panel\">\r\n <div class=\"search-input-wrapper\">\r\n <div class=\"search-icon\">\r\n <img src=\"assets/icons/search.svg\" />\r\n </div>\r\n <input (input)=\"onSearchChange($event)\" type=\"text\" name=\"\" id=\"\" placeholder=\"Search nodes by name, type, variables...\" class=\"search-input\">\r\n </div>\r\n <div class=\"search-results-wrapper\" (click)=\"onSelectNodeChange($event)\">\r\n <div class=\"activity-result-wrapper\" *ngFor=\"let act of filteredNodes\" id=\"{{ act.id }}\">\r\n {{ act.wxccActivityName || act.name }}\r\n </div>\r\n </div>\r\n</div>", styles: [".search-panel{position:absolute;min-width:400px;min-height:400px;max-height:500px;top:1rem;left:1rem;display:flex;flex-direction:column;border-radius:1rem;background-color:#fff}.search-input-wrapper{padding:1rem;position:relative;display:flex;align-items:center;justify-content:center}.search-results-wrapper{padding:1rem;display:flex;flex-direction:column;gap:.25rem;overflow-y:auto}.search-icon{position:absolute;left:1.5rem;display:flex}.search-icon img{width:32px;height:32px}.search-input{border-radius:.5rem;padding:.75rem .75rem .75rem 2.5rem;width:100%}.activity-result-wrapper{padding:1rem;cursor:pointer;background-color:#f1f1f180;border-radius:.5rem}.activity-result-wrapper:hover{background-color:#cbe3ecac}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NodeSearchPanelComponent, decorators: [{
1502
+ type: Component,
1503
+ args: [{ selector: 'node-search-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"search-panel\">\r\n <div class=\"search-input-wrapper\">\r\n <div class=\"search-icon\">\r\n <img src=\"assets/icons/search.svg\" />\r\n </div>\r\n <input (input)=\"onSearchChange($event)\" type=\"text\" name=\"\" id=\"\" placeholder=\"Search nodes by name, type, variables...\" class=\"search-input\">\r\n </div>\r\n <div class=\"search-results-wrapper\" (click)=\"onSelectNodeChange($event)\">\r\n <div class=\"activity-result-wrapper\" *ngFor=\"let act of filteredNodes\" id=\"{{ act.id }}\">\r\n {{ act.wxccActivityName || act.name }}\r\n </div>\r\n </div>\r\n</div>", styles: [".search-panel{position:absolute;min-width:400px;min-height:400px;max-height:500px;top:1rem;left:1rem;display:flex;flex-direction:column;border-radius:1rem;background-color:#fff}.search-input-wrapper{padding:1rem;position:relative;display:flex;align-items:center;justify-content:center}.search-results-wrapper{padding:1rem;display:flex;flex-direction:column;gap:.25rem;overflow-y:auto}.search-icon{position:absolute;left:1.5rem;display:flex}.search-icon img{width:32px;height:32px}.search-input{border-radius:.5rem;padding:.75rem .75rem .75rem 2.5rem;width:100%}.activity-result-wrapper{padding:1rem;cursor:pointer;background-color:#f1f1f180;border-radius:.5rem}.activity-result-wrapper:hover{background-color:#cbe3ecac}\n"] }]
1504
+ }], propDecorators: { nodes: [{
1505
+ type: Input
1506
+ }], searchChange: [{
1507
+ type: Output
1508
+ }], selectNodeChange: [{
1509
+ type: Output
1510
+ }] } });
1511
+
1512
+ cytoscape.use(dagre);
1513
+ cytoscape.use(nodeHtmlLabel);
1514
+ class WxCCFlowchartComponent {
1515
+ constructor(wxcc2graph,
1516
+ // private readonly cytoscapeViewportService: CytoscapeViewportService,
1517
+ dialog, wxccActivityCreationService, cdr) {
1518
+ this.wxcc2graph = wxcc2graph;
1519
+ this.dialog = dialog;
1520
+ this.wxccActivityCreationService = wxccActivityCreationService;
1521
+ this.cdr = cdr;
1522
+ this.viewReady = false;
1523
+ this.layoutOptions = {
1524
+ name: "dagre",
1525
+ rankDir: "LR",
1526
+ nodeSep: 180,
1527
+ edgeSep: 60,
1528
+ rankSep: 150,
1529
+ animate: true,
1530
+ animationDuration: 500,
1531
+ fit: true
1532
+ };
1533
+ // Sidebar state
1534
+ this.isSidebarOpen = false;
1535
+ this.selectedNodeData = null;
1536
+ // Search panel state
1537
+ this.isSearchPanelVisible = false;
1538
+ this.searchPanelVisible = false;
1539
+ // Node action toolbar state
1540
+ this.isNodeToolbarVisible = false;
1541
+ this.nodeToolbarPosition = { x: 0, y: 0 };
1542
+ // Add node dialog state
1543
+ this.availableNodes = [];
1544
+ // Link node dialog state
1545
+ this.isLinkDialogOpen = false;
1546
+ this.selectedEdgeId = null;
1547
+ this.selectedEdgeDeleteButtonPosition = null;
1548
+ }
1549
+ ngAfterViewInit() {
1550
+ this.viewReady = true;
1551
+ this.tryInit();
1552
+ }
1553
+ ngOnChanges(changes) {
1554
+ if (changes["flowchart"]) {
1555
+ this.tryInit();
1556
+ }
1557
+ }
1558
+ ngOnDestroy() {
1559
+ var _a;
1560
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.destroy();
1561
+ this.cy = undefined;
1562
+ }
1563
+ tryInit() {
1564
+ if (!this.viewReady || !this.flowchartContainer || !this.flowchart) {
1565
+ return;
1566
+ }
1567
+ this.init();
1568
+ }
1569
+ init() {
1570
+ var _a, _b;
1571
+ const container = this.flowchartContainer.nativeElement;
1572
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.destroy();
1573
+ this.cy = undefined;
1574
+ const elements = [
1575
+ ...this.flowchart.nodes,
1576
+ ...this.flowchart.edges,
1577
+ ];
1578
+ this.cy = cytoscape({
1579
+ container: container,
1580
+ elements: elements,
1581
+ style: this.getStylesheet(),
1582
+ });
1583
+ this.cy.nodeHtmlLabel([
1584
+ {
1585
+ query: "node",
1586
+ halign: "center",
1587
+ valign: "center",
1588
+ halignBox: "center",
1589
+ valignBox: "center",
1590
+ tpl: (data) => getNodeHtmlTemplate(data),
1591
+ },
1592
+ ]);
1593
+ const layout = (_b = this.cy) === null || _b === void 0 ? void 0 : _b.layout(Object.assign({}, this.layoutOptions)).run();
1594
+ layout.on("layoutstop", () => {
1595
+ // this.cytoscapeViewportService.resetView(this.cy, this.cy?.elements());
1596
+ });
1597
+ this.setupEventListeners();
1598
+ }
1599
+ get activities() { return this.wxcc2graph.getAllActivities(); }
1600
+ // Toggle search panel visibility
1601
+ toggleSearchPanel() {
1602
+ this.isSearchPanelVisible = !this.isSearchPanelVisible;
1603
+ this.cdr.markForCheck();
1604
+ }
1605
+ setupEventListeners() {
1606
+ var _a, _b, _c, _d, _e, _f;
1607
+ // Single tap on node - show only the toolbar (quick actions)
1608
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.on("mouseover", "node", (event) => {
1609
+ const node = event.target;
1610
+ this.selectedNodeData = node.data();
1611
+ // Calculate toolbar position relative to the container
1612
+ this.updateToolbarPosition(node);
1613
+ this.isNodeToolbarVisible = true;
1614
+ this.cdr.detectChanges();
1615
+ });
1616
+ (_b = this.cy) === null || _b === void 0 ? void 0 : _b.on("tap", "node", (event) => {
1617
+ const node = event.target;
1618
+ this.clearSelectedEdge();
1619
+ this.selectedNodeData = node.data();
1620
+ this.isSidebarOpen = true;
1621
+ // Hide toolbar when sidebar opens
1622
+ this.isNodeToolbarVisible = false;
1623
+ this.cdr.detectChanges();
1624
+ });
1625
+ (_c = this.cy) === null || _c === void 0 ? void 0 : _c.on("mousemove", "node", (event) => {
1626
+ const node = event.target;
1627
+ this.updateToolbarPosition(node);
1628
+ this.cdr.detectChanges();
1629
+ });
1630
+ // Edge tap - select edge for explicit deletion action
1631
+ (_d = this.cy) === null || _d === void 0 ? void 0 : _d.on("tap", "edge", (event) => {
1632
+ const edge = event.target;
1633
+ this.isSidebarOpen = false;
1634
+ this.hideNodeToolbar();
1635
+ this.selectedNodeData = null;
1636
+ this.selectedEdgeId = edge.id();
1637
+ edge.select();
1638
+ this.updateSelectedEdgeDeleteButtonPosition();
1639
+ this.cdr.detectChanges();
1640
+ });
1641
+ // Canvas tap - hide toolbar and deselect
1642
+ (_e = this.cy) === null || _e === void 0 ? void 0 : _e.on("tap", (event) => {
1643
+ if (event.target === this.cy) {
1644
+ this.clearSelectedEdge();
1645
+ this.isSidebarOpen = false;
1646
+ this.hideNodeToolbar();
1647
+ this.selectedNodeData = null;
1648
+ }
1649
+ });
1650
+ // Pan/zoom events - update toolbar position
1651
+ (_f = this.cy) === null || _f === void 0 ? void 0 : _f.on("pan zoom", () => {
1652
+ var _a;
1653
+ if (this.isNodeToolbarVisible && this.selectedNodeData) {
1654
+ const node = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(this.selectedNodeData.id);
1655
+ if (node === null || node === void 0 ? void 0 : node.length) {
1656
+ this.updateToolbarPosition(node);
1657
+ }
1658
+ }
1659
+ if (this.selectedEdgeId) {
1660
+ this.updateSelectedEdgeDeleteButtonPosition();
1661
+ }
1662
+ this.cdr.detectChanges();
1663
+ });
1664
+ }
1665
+ updateToolbarPosition(node) {
1666
+ const renderedPosition = node.renderedPosition();
1667
+ const renderedWidth = node.renderedWidth();
1668
+ const renderedHeight = node.renderedHeight();
1669
+ // Position toolbar above the node, centered
1670
+ this.nodeToolbarPosition = {
1671
+ x: renderedPosition.x - 30,
1672
+ y: renderedPosition.y - renderedHeight / 2 - 40, // Above the node
1673
+ };
1674
+ }
1675
+ hideNodeToolbar() {
1676
+ this.isNodeToolbarVisible = false;
1677
+ this.cdr.detectChanges();
1678
+ }
1679
+ getStylesheet() {
1680
+ return StyleConfig;
1681
+ }
1682
+ // ==================== Sidebar Events ====================
1683
+ onCloseSidebar() {
1684
+ this.isSidebarOpen = false;
1685
+ this.hideNodeToolbar();
1686
+ this.selectedNodeData = null;
1687
+ // this.cdr.detectChanges();
1688
+ }
1689
+ onDescriptionChange(description) {
1690
+ var _a;
1691
+ if (!this.selectedNodeData || !this.cy)
1692
+ return;
1693
+ const node = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(this.selectedNodeData.id);
1694
+ if (node) {
1695
+ const updatedData = Object.assign(Object.assign({}, this.selectedNodeData), { suggestedProperties: Object.assign(Object.assign({}, this.selectedNodeData.suggestedProperties), { uccxDescription: description }) });
1696
+ this.wxcc2graph.updateActivityData(updatedData);
1697
+ node.data(updatedData);
1698
+ this.selectedNodeData = updatedData;
1699
+ }
1700
+ }
1701
+ onActivityTypeChange(activityType) {
1702
+ var _a;
1703
+ if (!this.selectedNodeData || !this.cy)
1704
+ return;
1705
+ const node = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(this.selectedNodeData.id);
1706
+ if (node) {
1707
+ const updatedData = Object.assign(Object.assign({}, this.selectedNodeData), { wxccActivityName: activityType.activityName, wxccGroup: activityType.group, iconUrl: activityType.icon });
1708
+ this.wxcc2graph.updateActivityData(updatedData);
1709
+ node.data(updatedData);
1710
+ this.selectedNodeData = updatedData;
1711
+ }
1712
+ }
1713
+ // ==================== Node Toolbar Events ====================
1714
+ onDeleteNode() {
1715
+ var _a;
1716
+ if (!this.selectedNodeData || !this.cy)
1717
+ return;
1718
+ const nodeId = this.selectedNodeData.id;
1719
+ // Remove from service and get affected link IDs
1720
+ const { removedLinkIds } = this.wxcc2graph.removeActivity(nodeId);
1721
+ // Remove edges from cytoscape
1722
+ removedLinkIds.forEach((linkId) => {
1723
+ var _a;
1724
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(linkId).remove();
1725
+ });
1726
+ // Remove node from cytoscape
1727
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(nodeId).remove();
1728
+ // Close sidebar and toolbar
1729
+ this.onCloseSidebar();
1730
+ // Re-run layout
1731
+ this.runLayout();
1732
+ }
1733
+ onDeleteSelectedEdge() {
1734
+ var _a;
1735
+ if (!this.selectedEdgeId || !this.cy)
1736
+ return;
1737
+ const edgeId = this.selectedEdgeId;
1738
+ const removed = this.wxcc2graph.removeLink(edgeId);
1739
+ if (!removed)
1740
+ return;
1741
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(edgeId).remove();
1742
+ this.selectedEdgeId = null;
1743
+ this.selectedEdgeDeleteButtonPosition = null;
1744
+ this.cdr.detectChanges();
1745
+ }
1746
+ onLinkNodeRequest() {
1747
+ var _a;
1748
+ if (!this.selectedNodeData || !this.cy)
1749
+ return;
1750
+ const sourceNode = this.selectedNodeData;
1751
+ if (!this.canCreateOutgoingLink(sourceNode.id)) {
1752
+ return;
1753
+ }
1754
+ // Get the cytoscape node to inspect existing connections
1755
+ const cyNode = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(sourceNode.id);
1756
+ // Collect IDs of nodes already connected as targets from this source
1757
+ const existingTargetIds = new Set(cyNode.outgoers('node').map((n) => n.id()));
1758
+ // Build the filtered list of linkable targets:
1759
+ // - Never allow the start node (NewPhoneContact) as a target
1760
+ // - Exclude the source node itself
1761
+ // - Exclude nodes already linked as targets from this source
1762
+ this.availableNodes = this.wxcc2graph.getAllActivities().filter(act => act.id !== sourceNode.id &&
1763
+ act.wxccActivityName !== 'NewPhoneContact' &&
1764
+ !existingTargetIds.has(act.id));
1765
+ const dialogRef = this.dialog.open(LinkNodeDialogComponent, {
1766
+ panelClass: "no-padding-modal",
1767
+ width: "550px",
1768
+ data: {
1769
+ availableNodes: this.availableNodes,
1770
+ sourceNode: this.selectedNodeData,
1771
+ },
1772
+ });
1773
+ dialogRef.afterClosed().subscribe((result) => {
1774
+ if (result) {
1775
+ this.onLinkNodes(result);
1776
+ }
1777
+ });
1778
+ }
1779
+ // ==================== Link Dialog Events ====================
1780
+ onLinkNodes(linkData) {
1781
+ var _a;
1782
+ if (!this.cy)
1783
+ return;
1784
+ if (!this.canCreateOutgoingLink(linkData.sourceNodeId)) {
1785
+ return;
1786
+ }
1787
+ if (this.wxcc2graph.linkExists(linkData.sourceNodeId, linkData.targetNodeId)) {
1788
+ console.warn("Link already exists between these nodes");
1789
+ return;
1790
+ }
1791
+ const edge = this.wxcc2graph.addLink(linkData.sourceNodeId, linkData.targetNodeId, linkData.label);
1792
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.add(edge);
1793
+ this.runLayout();
1794
+ }
1795
+ // ==================== Add Node Dialog Events ====================
1796
+ openAddNodeDialog() {
1797
+ this.availableNodes = this.wxcc2graph.getAllActivities();
1798
+ const dialogRef = this.dialog.open(AddNodeDialogComponent, {
1799
+ panelClass: "no-padding-modal",
1800
+ width: '450px',
1801
+ data: {
1802
+ availableNodes: this.availableNodes,
1803
+ },
1804
+ });
1805
+ dialogRef.afterClosed().subscribe((result) => {
1806
+ if (result) {
1807
+ this.addActivity(result);
1808
+ }
1809
+ });
1810
+ }
1811
+ addActivity(newNodeData) {
1812
+ var _a;
1813
+ if (!this.cy)
1814
+ return;
1815
+ const node = this.wxccActivityCreationService.createAndSync({
1816
+ activityTypeName: newNodeData.activityTypeName,
1817
+ name: newNodeData.name
1818
+ });
1819
+ // Add node to cytoscape
1820
+ (_a = this.cy) === null || _a === void 0 ? void 0 : _a.add({
1821
+ group: "nodes",
1822
+ data: node.data
1823
+ });
1824
+ // Re-run layout to position the new node
1825
+ this.runLayout();
1826
+ }
1827
+ onNodeSelectChange(id) {
1828
+ var _a, _b;
1829
+ const node = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(id);
1830
+ if (node) {
1831
+ (_b = this.cy) === null || _b === void 0 ? void 0 : _b.center(node);
1832
+ // Set highlighted property in node data
1833
+ const originalData = node.data();
1834
+ node.data(Object.assign(Object.assign({}, originalData), { highlighted: true }));
1835
+ node.emit('data');
1836
+ // Remove highlight after 1s
1837
+ setTimeout(() => {
1838
+ const currentData = node.data();
1839
+ if (currentData.highlighted) {
1840
+ // Remove the property completely
1841
+ delete currentData.highlighted;
1842
+ node.data(currentData);
1843
+ node.emit('data');
1844
+ }
1845
+ }, 1000);
1846
+ }
1847
+ }
1848
+ zoomIn() {
1849
+ // this.cytoscapeViewportService.zoomIn(this.cy);
1850
+ }
1851
+ zoomOut() {
1852
+ // this.cytoscapeViewportService.zoomOut(this.cy);
1853
+ }
1854
+ resetView() {
1855
+ // this.cytoscapeViewportService.resetView(this.cy, this.cy?.elements());
1856
+ }
1857
+ runLayout() {
1858
+ var _a;
1859
+ if (!this.cy)
1860
+ return;
1861
+ const layout = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.layout(Object.assign({}, this.layoutOptions)).run();
1862
+ layout.on("layoutstop", () => {
1863
+ // this.cytoscapeViewportService.resetView(this.cy, this.cy?.elements());
1864
+ });
1865
+ }
1866
+ canCreateOutgoingLink(sourceNodeId) {
1867
+ var _a;
1868
+ if (!this.cy)
1869
+ return false;
1870
+ const cyNode = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(sourceNodeId);
1871
+ if (!cyNode || cyNode.length === 0)
1872
+ return false;
1873
+ const sourceActivity = cyNode.data().wxccActivityName;
1874
+ const outgoingEdgeCount = cyNode.outgoers('edge').length;
1875
+ // End-type nodes cannot have outgoing links.
1876
+ const END_NODE_TYPES = ['end', 'disconnect-contact', 'blind-transfer'];
1877
+ if (END_NODE_TYPES.includes(sourceActivity))
1878
+ return false;
1879
+ // Start node can only have one output.
1880
+ if (sourceActivity === 'NewPhoneContact' && outgoingEdgeCount >= 1)
1881
+ return false;
1882
+ // Condition node can only have true/false outputs.
1883
+ if (sourceActivity === 'condition-activity' && outgoingEdgeCount >= 2)
1884
+ return false;
1885
+ return true;
1886
+ }
1887
+ clearSelectedEdge() {
1888
+ var _a;
1889
+ if (!this.selectedEdgeId || !this.cy)
1890
+ return;
1891
+ const edge = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(this.selectedEdgeId);
1892
+ if (edge && edge.length) {
1893
+ edge.unselect();
1894
+ }
1895
+ this.selectedEdgeId = null;
1896
+ this.selectedEdgeDeleteButtonPosition = null;
1897
+ this.cdr.detectChanges();
1898
+ }
1899
+ updateSelectedEdgeDeleteButtonPosition() {
1900
+ var _a;
1901
+ if (!this.cy || !this.selectedEdgeId) {
1902
+ this.selectedEdgeDeleteButtonPosition = null;
1903
+ return;
1904
+ }
1905
+ const edge = (_a = this.cy) === null || _a === void 0 ? void 0 : _a.getElementById(this.selectedEdgeId);
1906
+ if (!edge || edge.length === 0) {
1907
+ this.selectedEdgeDeleteButtonPosition = null;
1908
+ return;
1909
+ }
1910
+ const midpoint = edge.renderedMidpoint();
1911
+ // Slight offset so the icon does not sit exactly on top of the edge line.
1912
+ this.selectedEdgeDeleteButtonPosition = {
1913
+ x: midpoint.x + 12,
1914
+ y: midpoint.y - 12,
1915
+ };
1916
+ }
1917
+ }
1918
+ WxCCFlowchartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartComponent, deps: [{ token: WxCC2GraphService }, { token: i1$2.MatDialog }, { token: WxCCActivityCreationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1919
+ WxCCFlowchartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFlowchartComponent, selector: "wxcc-flowchart", inputs: { flowchart: "flowchart" }, viewQueries: [{ propertyName: "flowchartContainer", first: true, predicate: ["flowchartContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"wxcc-flowchart-container\">\r\n <div #flowchartContainer class=\"flowchart-canvas\"></div>\r\n\r\n <!-- Floating toolbar for viewport controls -->\r\n <graph-floating-toolbar\r\n [visibility]=\"{ export: false }\"\r\n (resetViewChange)=\"resetView()\"\r\n (zoomInChange)=\"zoomIn()\"\r\n (zoomOutChange)=\"zoomOut()\">\r\n </graph-floating-toolbar>\r\n\r\n <!-- Graph Acts -->\r\n <div class=\"graph-actions-wrapper\">\r\n <button\r\n class=\"add-node-btn\"\r\n matTooltip=\"Search workflow\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"toggleSearchPanel()\"\r\n >\r\n <img src=\"assets/wxcc/search.svg\" width=\"28\" height=\"28\" alt=\"\" />\r\n </button>\r\n <button\r\n class=\"add-node-btn\"\r\n matTooltip=\"Add New Node\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"openAddNodeDialog()\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"28\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line>\r\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <button\r\n *ngIf=\"selectedEdgeId && selectedEdgeDeleteButtonPosition\"\r\n class=\"edge-delete-btn\"\r\n matTooltip=\"Delete this edge\"\r\n matTooltipPosition=\"above\"\r\n [style.left.px]=\"selectedEdgeDeleteButtonPosition.x\"\r\n [style.top.px]=\"selectedEdgeDeleteButtonPosition.y\"\r\n (click)=\"onDeleteSelectedEdge()\"\r\n type=\"button\"\r\n aria-label=\"Delete selected edge\"\r\n >\r\n \u00D7\r\n </button>\r\n\r\n <node-search-panel\r\n class=\"fade-in-search-panel\"\r\n [class.visible]=\"isSearchPanelVisible\"\r\n [nodes]=\"activities\"\r\n (selectNodeChange)=\"onNodeSelectChange($event)\"\r\n (searchChange)=\"openAddNodeDialog()\"\r\n >\r\n </node-search-panel>\r\n\r\n <!-- Node action toolbar (floating near selected node) -->\r\n <node-action-toolbar\r\n [isVisible]=\"isNodeToolbarVisible\"\r\n [position]=\"nodeToolbarPosition\"\r\n (deleteNode)=\"onDeleteNode()\"\r\n (linkNode)=\"onLinkNodeRequest()\"\r\n >\r\n </node-action-toolbar>\r\n\r\n <!-- Node details sidebar -->\r\n <node-details-sidebar\r\n [isOpen]=\"isSidebarOpen\"\r\n [nodeData]=\"selectedNodeData\"\r\n (close)=\"onCloseSidebar()\"\r\n (descriptionChange)=\"onDescriptionChange($event)\"\r\n (activityTypeChange)=\"onActivityTypeChange($event)\"\r\n >\r\n </node-details-sidebar>\r\n</div>\r\n", styles: [".fade-in-search-panel{position:absolute;top:0;left:0;right:0;margin:0 auto;z-index:1000;opacity:0;pointer-events:none;transform:translateY(-40px);transition:opacity .4s cubic-bezier(.4,0,.2,1),transform .4s cubic-bezier(.4,0,.2,1)}.fade-in-search-panel.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.close-search-panel{position:absolute;top:10px;right:16px;background:transparent;border:none;font-size:2rem;color:#333;cursor:pointer;z-index:1100}:host ::ng-deep .node-content.highlighted{border-radius:10px;z-index:10}:host ::ng-deep .node-content.highlighted{position:relative;z-index:10}:host ::ng-deep .node-content.highlighted:after{content:\"\";position:absolute;inset:-14px;border:4px solid rgba(110,110,110,.4705882353);border-radius:13px;pointer-events:none;opacity:1}:host ::ng-deep .node-content:not(.highlighted):after{opacity:0}:host{display:block;overflow:hidden;width:100%;height:100%}.wxcc-flowchart-container{display:flex;flex-direction:column;position:relative;background-color:#f8f9fa;border-radius:.5rem;border:1px solid #e1e4e8;box-sizing:border-box;height:100%}.wxcc-flowchart-container .flowchart-canvas{height:100%;background:linear-gradient(90deg,rgba(200,200,200,.1) 1px,transparent 1px),linear-gradient(rgba(200,200,200,.1) 1px,transparent 1px);background-size:20px 20px}.wxcc-flowchart-container .add-node-btn{outline:none;border:none;border-radius:.5rem;background-color:#f6f6f6;padding:.5rem;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;width:40px;height:40px;transition:all .2s ease}.wxcc-flowchart-container .add-node-btn:hover{background-color:#eefff8;transform:scale(1.05)}.wxcc-flowchart-container .add-node-btn:active{transform:scale(.95)}.edge-delete-btn{position:absolute;z-index:1100;transform:translate(-50%,-50%);width:24px;height:24px;border-radius:50%;border:1px solid #cc3d36;background:#fff;color:#cc3d36;font-size:16px;font-weight:700;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px #0000002e}.edge-delete-btn:hover{background:#fff1f0;transform:translate(-50%,-50%) scale(1.08)}.edge-delete-btn:active{transform:translate(-50%,-50%) scale(.95)}:host ::ng-deep .node-content{cursor:pointer;display:flex;justify-content:center;flex-direction:column;gap:.5rem;padding:.5rem;background:white;border-radius:6px;border:1px solid #d8d8d8;border-left:4px solid;min-width:200px;transition:all .2s ease}:host ::ng-deep .node-content header{display:flex;align-items:center;gap:.5rem}:host ::ng-deep .node-content img{width:18px;height:18px}:host ::ng-deep .node-content .node-icon{font-size:24px;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:.5rem;flex-shrink:0}:host ::ng-deep .node-content .node-info{flex:1;min-width:0}:host ::ng-deep .node-content .node-info .node-label{font-size:16px;letter-spacing:.5px;opacity:.7;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}:host ::ng-deep .node-content .node-info .node-activity-name{font-size:12px;color:#99a5b1;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}:host ::ng-deep .node-content .node-details{font-size:12px;color:#000;padding:0 .25rem;display:flex;flex-direction:column;gap:.25rem}:host ::ng-deep .node-content .node-details .node-details-item{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}:host ::ng-deep .node-content .node-details .review-red{background-color:#ffe6e6;border-left-color:#f44336;color:#f44336;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content .node-details .review-green{background-color:#e6ffe6;border-left-color:#4caf50;color:#4caf50;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content .node-details .review-yellow{background-color:#fff9e6;border-left-color:#ff9800;color:#ff9800;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content.node-start{border-left-color:#4caf50}:host ::ng-deep .node-content.node-start .node-icon{background-color:#4caf501a;color:#4caf50}:host ::ng-deep .node-content.node-start .node-label{color:#4caf50}:host ::ng-deep .node-content.node-end{border-left-color:#f44336}:host ::ng-deep .node-content.node-end .node-icon{background-color:#f443361a;color:#f44336}:host ::ng-deep .node-content.node-end .node-label{color:#f44336}:host ::ng-deep .node-content.node-gateway{border-left-color:#ff9800}:host ::ng-deep .node-content.node-gateway .node-icon{background-color:#ff98001a;color:#ff9800}:host ::ng-deep .node-content.node-gateway .node-label{color:#ff9800}:host ::ng-deep .node-content.node-action{border-left-color:#9c27b0}:host ::ng-deep .node-content.node-action .node-icon{background-color:#9c27b01a;color:#9c27b0}:host ::ng-deep .node-content.node-action .node-label{color:#9c27b0}:host ::ng-deep .node-content.node-default{border-left-color:#607d8b}:host ::ng-deep .node-content.node-default .node-icon{background-color:#607d8b1a;color:#607d8b}:host ::ng-deep .node-content.node-default .node-label{color:#607d8b}.graph-actions-wrapper{position:absolute;right:1rem;top:1rem;display:flex;align-items:center;gap:.5rem;box-shadow:2px 4px 15px #0000002d;padding:8px;background-color:#ffffffac;border-radius:1rem;z-index:999}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: FloatingToolBarComponent, selector: "graph-floating-toolbar", inputs: ["visibility"], outputs: ["resetViewChange", "zoomInChange", "zoomOutChange", "exportImageChange"] }, { kind: "component", type: NodeDetailsSidebarComponent, selector: "node-details-sidebar", inputs: ["isOpen", "nodeData"], outputs: ["close", "activityTypeChange", "descriptionChange"] }, { kind: "component", type: NodeActionToolbarComponent, selector: "node-action-toolbar", inputs: ["isVisible", "position"], outputs: ["deleteNode", "linkNode"] }, { kind: "component", type: NodeSearchPanelComponent, selector: "node-search-panel", inputs: ["nodes"], outputs: ["searchChange", "selectNodeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1920
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartComponent, decorators: [{
1921
+ type: Component,
1922
+ args: [{ selector: "wxcc-flowchart", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"wxcc-flowchart-container\">\r\n <div #flowchartContainer class=\"flowchart-canvas\"></div>\r\n\r\n <!-- Floating toolbar for viewport controls -->\r\n <graph-floating-toolbar\r\n [visibility]=\"{ export: false }\"\r\n (resetViewChange)=\"resetView()\"\r\n (zoomInChange)=\"zoomIn()\"\r\n (zoomOutChange)=\"zoomOut()\">\r\n </graph-floating-toolbar>\r\n\r\n <!-- Graph Acts -->\r\n <div class=\"graph-actions-wrapper\">\r\n <button\r\n class=\"add-node-btn\"\r\n matTooltip=\"Search workflow\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"toggleSearchPanel()\"\r\n >\r\n <img src=\"assets/wxcc/search.svg\" width=\"28\" height=\"28\" alt=\"\" />\r\n </button>\r\n <button\r\n class=\"add-node-btn\"\r\n matTooltip=\"Add New Node\"\r\n matTooltipPosition=\"above\"\r\n (click)=\"openAddNodeDialog()\"\r\n >\r\n <svg\r\n width=\"28\"\r\n height=\"28\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line>\r\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <button\r\n *ngIf=\"selectedEdgeId && selectedEdgeDeleteButtonPosition\"\r\n class=\"edge-delete-btn\"\r\n matTooltip=\"Delete this edge\"\r\n matTooltipPosition=\"above\"\r\n [style.left.px]=\"selectedEdgeDeleteButtonPosition.x\"\r\n [style.top.px]=\"selectedEdgeDeleteButtonPosition.y\"\r\n (click)=\"onDeleteSelectedEdge()\"\r\n type=\"button\"\r\n aria-label=\"Delete selected edge\"\r\n >\r\n \u00D7\r\n </button>\r\n\r\n <node-search-panel\r\n class=\"fade-in-search-panel\"\r\n [class.visible]=\"isSearchPanelVisible\"\r\n [nodes]=\"activities\"\r\n (selectNodeChange)=\"onNodeSelectChange($event)\"\r\n (searchChange)=\"openAddNodeDialog()\"\r\n >\r\n </node-search-panel>\r\n\r\n <!-- Node action toolbar (floating near selected node) -->\r\n <node-action-toolbar\r\n [isVisible]=\"isNodeToolbarVisible\"\r\n [position]=\"nodeToolbarPosition\"\r\n (deleteNode)=\"onDeleteNode()\"\r\n (linkNode)=\"onLinkNodeRequest()\"\r\n >\r\n </node-action-toolbar>\r\n\r\n <!-- Node details sidebar -->\r\n <node-details-sidebar\r\n [isOpen]=\"isSidebarOpen\"\r\n [nodeData]=\"selectedNodeData\"\r\n (close)=\"onCloseSidebar()\"\r\n (descriptionChange)=\"onDescriptionChange($event)\"\r\n (activityTypeChange)=\"onActivityTypeChange($event)\"\r\n >\r\n </node-details-sidebar>\r\n</div>\r\n", styles: [".fade-in-search-panel{position:absolute;top:0;left:0;right:0;margin:0 auto;z-index:1000;opacity:0;pointer-events:none;transform:translateY(-40px);transition:opacity .4s cubic-bezier(.4,0,.2,1),transform .4s cubic-bezier(.4,0,.2,1)}.fade-in-search-panel.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.close-search-panel{position:absolute;top:10px;right:16px;background:transparent;border:none;font-size:2rem;color:#333;cursor:pointer;z-index:1100}:host ::ng-deep .node-content.highlighted{border-radius:10px;z-index:10}:host ::ng-deep .node-content.highlighted{position:relative;z-index:10}:host ::ng-deep .node-content.highlighted:after{content:\"\";position:absolute;inset:-14px;border:4px solid rgba(110,110,110,.4705882353);border-radius:13px;pointer-events:none;opacity:1}:host ::ng-deep .node-content:not(.highlighted):after{opacity:0}:host{display:block;overflow:hidden;width:100%;height:100%}.wxcc-flowchart-container{display:flex;flex-direction:column;position:relative;background-color:#f8f9fa;border-radius:.5rem;border:1px solid #e1e4e8;box-sizing:border-box;height:100%}.wxcc-flowchart-container .flowchart-canvas{height:100%;background:linear-gradient(90deg,rgba(200,200,200,.1) 1px,transparent 1px),linear-gradient(rgba(200,200,200,.1) 1px,transparent 1px);background-size:20px 20px}.wxcc-flowchart-container .add-node-btn{outline:none;border:none;border-radius:.5rem;background-color:#f6f6f6;padding:.5rem;cursor:pointer;font-size:1rem;display:flex;align-items:center;justify-content:center;width:40px;height:40px;transition:all .2s ease}.wxcc-flowchart-container .add-node-btn:hover{background-color:#eefff8;transform:scale(1.05)}.wxcc-flowchart-container .add-node-btn:active{transform:scale(.95)}.edge-delete-btn{position:absolute;z-index:1100;transform:translate(-50%,-50%);width:24px;height:24px;border-radius:50%;border:1px solid #cc3d36;background:#fff;color:#cc3d36;font-size:16px;font-weight:700;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px #0000002e}.edge-delete-btn:hover{background:#fff1f0;transform:translate(-50%,-50%) scale(1.08)}.edge-delete-btn:active{transform:translate(-50%,-50%) scale(.95)}:host ::ng-deep .node-content{cursor:pointer;display:flex;justify-content:center;flex-direction:column;gap:.5rem;padding:.5rem;background:white;border-radius:6px;border:1px solid #d8d8d8;border-left:4px solid;min-width:200px;transition:all .2s ease}:host ::ng-deep .node-content header{display:flex;align-items:center;gap:.5rem}:host ::ng-deep .node-content img{width:18px;height:18px}:host ::ng-deep .node-content .node-icon{font-size:24px;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:.5rem;flex-shrink:0}:host ::ng-deep .node-content .node-info{flex:1;min-width:0}:host ::ng-deep .node-content .node-info .node-label{font-size:16px;letter-spacing:.5px;opacity:.7;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}:host ::ng-deep .node-content .node-info .node-activity-name{font-size:12px;color:#99a5b1;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}:host ::ng-deep .node-content .node-details{font-size:12px;color:#000;padding:0 .25rem;display:flex;flex-direction:column;gap:.25rem}:host ::ng-deep .node-content .node-details .node-details-item{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}:host ::ng-deep .node-content .node-details .review-red{background-color:#ffe6e6;border-left-color:#f44336;color:#f44336;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content .node-details .review-green{background-color:#e6ffe6;border-left-color:#4caf50;color:#4caf50;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content .node-details .review-yellow{background-color:#fff9e6;border-left-color:#ff9800;color:#ff9800;padding:.1rem .25rem;border-radius:.25rem;font-size:10px}:host ::ng-deep .node-content.node-start{border-left-color:#4caf50}:host ::ng-deep .node-content.node-start .node-icon{background-color:#4caf501a;color:#4caf50}:host ::ng-deep .node-content.node-start .node-label{color:#4caf50}:host ::ng-deep .node-content.node-end{border-left-color:#f44336}:host ::ng-deep .node-content.node-end .node-icon{background-color:#f443361a;color:#f44336}:host ::ng-deep .node-content.node-end .node-label{color:#f44336}:host ::ng-deep .node-content.node-gateway{border-left-color:#ff9800}:host ::ng-deep .node-content.node-gateway .node-icon{background-color:#ff98001a;color:#ff9800}:host ::ng-deep .node-content.node-gateway .node-label{color:#ff9800}:host ::ng-deep .node-content.node-action{border-left-color:#9c27b0}:host ::ng-deep .node-content.node-action .node-icon{background-color:#9c27b01a;color:#9c27b0}:host ::ng-deep .node-content.node-action .node-label{color:#9c27b0}:host ::ng-deep .node-content.node-default{border-left-color:#607d8b}:host ::ng-deep .node-content.node-default .node-icon{background-color:#607d8b1a;color:#607d8b}:host ::ng-deep .node-content.node-default .node-label{color:#607d8b}.graph-actions-wrapper{position:absolute;right:1rem;top:1rem;display:flex;align-items:center;gap:.5rem;box-shadow:2px 4px 15px #0000002d;padding:8px;background-color:#ffffffac;border-radius:1rem;z-index:999}\n"] }]
1923
+ }], ctorParameters: function () { return [{ type: WxCC2GraphService }, { type: i1$2.MatDialog }, { type: WxCCActivityCreationService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { flowchart: [{
1924
+ type: Input
1925
+ }], flowchartContainer: [{
1926
+ type: ViewChild,
1927
+ args: ["flowchartContainer"]
1928
+ }] } });
1929
+
1930
+ const BASE = '/api/uccx/migration';
1931
+ function buildUrl(customerId, uccxIp, fileName, action, state, format) {
1932
+ return `${BASE}/customer/${customerId}/uccx/${uccxIp}/filename/${fileName}/${action}/type/${state}/wxcc${format ? '/ir' : ''}/json`;
1933
+ }
1934
+ /**
1935
+ * Any WxCC flowchart api endpoint should go here
1936
+ */
1937
+ const WXCC_FLOWCHART_API = {
1938
+ GET_DATA: (params, state = 'ORIG', format) => buildUrl(params.customerId, params.uccxIp, params.fileName, 'get', state, format),
1939
+ SAVE_DRAFT: (params, format) => buildUrl(params.customerId, params.uccxIp, params.fileName, 'save', 'DRAFT', format),
1940
+ RESET_DRAFT: (params, format) => `${BASE}/customer/${params.customerId}/uccx/${params.uccxIp}/filename/${params.fileName}${format ? '' : '/wxcc'}/reset/draft`,
1941
+ COMPLETE_FLOW: (params, format) => buildUrl(params.customerId, params.uccxIp, params.fileName, 'save', 'COMPLETED', format)
1942
+ };
1943
+
1944
+ class WxCCAPIService {
1945
+ constructor(api) {
1946
+ this.api = api;
1947
+ }
1948
+ /**
1949
+ * Fetch original WXCC flow data
1950
+ */
1951
+ fetchWxCCFlowData(params, state = 'ORIG') {
1952
+ const url = WXCC_FLOWCHART_API.GET_DATA(params, state);
1953
+ // @ts-ignore
1954
+ return this.api.fetch(url);
1955
+ }
1956
+ /**
1957
+ * Fetch original WXCC flow data as IR format
1958
+ */
1959
+ fetchWxCCFlowDataIR(params, state = 'ORIG') {
1960
+ const url = WXCC_FLOWCHART_API.GET_DATA(params, state, 'ir');
1961
+ // @ts-ignore
1962
+ return this.api.fetch(url);
1963
+ }
1964
+ /**
1965
+ * Save WXCC flow data as DRAFT
1966
+ */
1967
+ saveWxCCFlowData(params, data) {
1968
+ const url = WXCC_FLOWCHART_API.SAVE_DRAFT(params);
1969
+ // @ts-ignore
1970
+ return this.api.post(url, data);
1971
+ }
1972
+ /**
1973
+ * Save WXCC flow data as DRAFT in IR format
1974
+ */
1975
+ saveWxCCFlowDataIR(params, data) {
1976
+ const url = WXCC_FLOWCHART_API.SAVE_DRAFT(params, 'ir');
1977
+ // @ts-ignore
1978
+ return this.api.post(url, data);
1979
+ }
1980
+ /**
1981
+ * Reset to original WXCC flow data
1982
+ */
1983
+ resetWxCCFlowData(params) {
1984
+ const url = WXCC_FLOWCHART_API.RESET_DRAFT(params);
1985
+ // @ts-ignore
1986
+ return this.api.post(url);
1987
+ }
1988
+ /**
1989
+ * Reset to original WXCC flow data in IR format
1990
+ */
1991
+ resetWxCCFlowDataIR(params) {
1992
+ const url = WXCC_FLOWCHART_API.RESET_DRAFT(params, 'ir');
1993
+ // @ts-ignore
1994
+ return this.api.post(url);
1995
+ }
1996
+ /**
1997
+ * Save WXCC flow data as COMPLETED
1998
+ */
1999
+ completeWxCCFlowData(params, data) {
2000
+ const url = WXCC_FLOWCHART_API.COMPLETE_FLOW(params);
2001
+ // @ts-ignore
2002
+ return this.api.post(url, data);
2003
+ }
2004
+ /**
2005
+ * Save WXCC flow data as COMPLETED in IR format
2006
+ */
2007
+ completeWxCCFlowDataIR(params, data) {
2008
+ const url = WXCC_FLOWCHART_API.COMPLETE_FLOW(params, 'ir');
2009
+ // @ts-ignore
2010
+ return this.api.post(url, data);
2011
+ }
2012
+ }
2013
+ WxCCAPIService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCAPIService, deps: [{ token: APIService }], target: i0.ɵɵFactoryTarget.Injectable });
2014
+ WxCCAPIService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCAPIService });
2015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCAPIService, decorators: [{
2016
+ type: Injectable
2017
+ }], ctorParameters: function () { return [{ type: APIService }]; } });
2018
+
2019
+ class WxCCFileSelectionBarComponent {
2020
+ constructor() {
2021
+ this.fileNameSelectionChange = new EventEmitter();
2022
+ this.hostFileNames = new Map();
2023
+ }
2024
+ ngOnInit() {
2025
+ this.fileNames.forEach(({ fileName, host }) => {
2026
+ var _a;
2027
+ if (!this.hostFileNames.has(host)) {
2028
+ this.hostFileNames.set(host, []);
2029
+ }
2030
+ (_a = this.hostFileNames.get(host)) === null || _a === void 0 ? void 0 : _a.push(fileName);
2031
+ });
2032
+ }
2033
+ get fileNamesByHost() {
2034
+ return this.hostFileNames.get(this.selectedHost);
2035
+ }
2036
+ get hosts() {
2037
+ if (!this.fileNames.length) {
2038
+ return null;
2039
+ }
2040
+ const hostsSet = new Set(this.fileNames.map((file) => file.host));
2041
+ return Array.from(hostsSet).filter(host => host);
2042
+ }
2043
+ onFileSelectionChange(fileName) {
2044
+ this.fileNameSelectionChange.emit({ fileName: fileName, host: this.selectedHost });
2045
+ }
2046
+ onHostSelectionChange(host) {
2047
+ this.selectedHost = host;
2048
+ this.fileNameSelectionChange.emit({
2049
+ host: host,
2050
+ fileName: this.fileNamesByHost[0]
2051
+ });
2052
+ }
2053
+ trackByFileName(_index, fileName) {
2054
+ return fileName;
2055
+ }
2056
+ trackByHost(_index, host) {
2057
+ return host;
2058
+ }
2059
+ }
2060
+ WxCCFileSelectionBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFileSelectionBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2061
+ WxCCFileSelectionBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: { fileNames: "fileNames", selectedFileName: "selectedFileName", selectedHost: "selectedHost" }, outputs: { fileNameSelectionChange: "fileNameSelectionChange" }, ngImport: i0, template: "<div class=\"file-selection-bar\">\r\n <mat-form-field appearance=\"outline\" class=\"host-selection\" *ngIf=\"hosts?.length\">\r\n <!-- <mat-label>Host</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedHost\"\r\n (selectionChange)=\"onHostSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let host of hosts; trackBy: trackByHost\"\r\n title=\"{{ host }}\"\r\n [value]=\"host\">\r\n {{ host }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"file-selection\">\r\n <!-- <mat-label>Script file</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedFileName\"\r\n (selectionChange)=\"onFileSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let name of fileNamesByHost; trackBy: trackByFileName\"\r\n title=\"{{ name }}\"\r\n [value]=\"name\">\r\n {{ name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:0}:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix{padding:.25rem 0 .5rem}:host ::ng-deep .mat-select-trigger{display:block}:host ::ng-deep .mat-select-trigger .mat-select-arrow-wrapper{transform:none}.file-selection-bar{display:flex;gap:1rem}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2062
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFileSelectionBarComponent, decorators: [{
2063
+ type: Component,
2064
+ args: [{ selector: 'wxcc-file-selection-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"file-selection-bar\">\r\n <mat-form-field appearance=\"outline\" class=\"host-selection\" *ngIf=\"hosts?.length\">\r\n <!-- <mat-label>Host</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedHost\"\r\n (selectionChange)=\"onHostSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let host of hosts; trackBy: trackByHost\"\r\n title=\"{{ host }}\"\r\n [value]=\"host\">\r\n {{ host }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n\r\n <mat-form-field appearance=\"outline\" class=\"file-selection\">\r\n <!-- <mat-label>Script file</mat-label> -->\r\n <mat-select\r\n [value]=\"selectedFileName\"\r\n (selectionChange)=\"onFileSelectionChange($event.value)\">\r\n <mat-option\r\n *ngFor=\"let name of fileNamesByHost; trackBy: trackByFileName\"\r\n title=\"{{ name }}\"\r\n [value]=\"name\">\r\n {{ name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n</div>", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:0}:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix{padding:.25rem 0 .5rem}:host ::ng-deep .mat-select-trigger{display:block}:host ::ng-deep .mat-select-trigger .mat-select-arrow-wrapper{transform:none}.file-selection-bar{display:flex;gap:1rem}\n"] }]
2065
+ }], propDecorators: { fileNames: [{
2066
+ type: Input
2067
+ }], selectedFileName: [{
2068
+ type: Input
2069
+ }], selectedHost: [{
2070
+ type: Input
2071
+ }], fileNameSelectionChange: [{
2072
+ type: Output
2073
+ }] } });
2074
+
2075
+ class WxCCActionsBarComponent {
2076
+ constructor() {
2077
+ this.save = new EventEmitter();
2078
+ this.reset = new EventEmitter();
2079
+ this.complete = new EventEmitter();
2080
+ this.exportNonIr = new EventEmitter();
2081
+ }
2082
+ ngOnInit() { }
2083
+ }
2084
+ WxCCActionsBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActionsBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2085
+ WxCCActionsBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCActionsBarComponent, selector: "wxcc-actions-bar", outputs: { save: "save", reset: "reset", complete: "complete", exportNonIr: "exportNonIr" }, ngImport: i0, template: "<div class=\"actions-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"exportNonIr.emit()\">\r\n Export JSON\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"reset.emit()\">\r\n Reset\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"save.emit()\">\r\n Save\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n color=\"primary\"\r\n (click)=\"complete.emit()\">\r\n Complete\r\n </button>\r\n</div>", styles: [".actions-wrapper{display:flex;align-items:center;gap:.5rem}.actions-wrapper button.outline-button{border:none!important}\n"], dependencies: [{ kind: "component", type: i1$4.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2086
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCActionsBarComponent, decorators: [{
2087
+ type: Component,
2088
+ args: [{ selector: 'wxcc-actions-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"actions-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"exportNonIr.emit()\">\r\n Export JSON\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"reset.emit()\">\r\n Reset\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n class=\"outline-button\"\r\n (click)=\"save.emit()\">\r\n Save\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-button\r\n color=\"primary\"\r\n (click)=\"complete.emit()\">\r\n Complete\r\n </button>\r\n</div>", styles: [".actions-wrapper{display:flex;align-items:center;gap:.5rem}.actions-wrapper button.outline-button{border:none!important}\n"] }]
2089
+ }], propDecorators: { save: [{
2090
+ type: Output
2091
+ }], reset: [{
2092
+ type: Output
2093
+ }], complete: [{
2094
+ type: Output
2095
+ }], exportNonIr: [{
2096
+ type: Output
2097
+ }] } });
2098
+
2099
+ var activities = [
2100
+ {
2101
+ id: "8c89c876-e556-3c8c-a1be-77b8cfbd3800",
2102
+ name: "Start_0\nStart",
2103
+ review: {
2104
+ color: "green",
2105
+ level: "confident",
2106
+ reasons: []
2107
+ },
2108
+ suggestedProperties: {
2109
+ uccxDescription: "Start",
2110
+ uccxComment: "Simple Queuing With Calendar Template",
2111
+ closestWxccActivity: "Start Flow",
2112
+ mappingNotes: "In UCCX voice scripts, callers typically hear ringing until an explicit Accept step executes; in WxCC, the Start Flow event fires when the contact arrives at the Entry Point.",
2113
+ migrationInstructions: "The Start Flow activity appears on the Main Flow canvas by default. You cannot delete the Start Flow activity.\n\nNote: There are certain Output Variables associated with the Start Flow activity depend on the selected Flow Trigger Event. These variables store data that is captured at the moment the flow is triggered.",
2114
+ allAudioFilesInFlow: [
2115
+ "ICD\\ICDQueue.wav",
2116
+ "ICD\\ICDWelcome.wav",
2117
+ "ICDQueue.wav",
2118
+ "ICDWelcome.wav"
2119
+ ]
2120
+ },
2121
+ uccxDisplayType: "Start",
2122
+ uccxTypeName: "Start",
2123
+ uccxWfId: 0,
2124
+ unmappedReason: null,
2125
+ wxccActivityId: "start",
2126
+ wxccActivityName: "NewPhoneContact",
2127
+ wxccGroup: "start"
2128
+ },
2129
+ {
2130
+ id: "c535b5fd-5ab9-323f-b1ac-667f4590d801",
2131
+ name: "End_12\nEnd",
2132
+ review: {
2133
+ color: "green",
2134
+ level: "confident",
2135
+ reasons: []
2136
+ },
2137
+ suggestedProperties: {
2138
+ uccxDescription: "End",
2139
+ closestWxccActivity: "End Flow",
2140
+ mappingNotes: "UCCX commonly uses Terminate + End; in Flow Designer, Disconnect Contact + End Flow is the typical pattern.",
2141
+ migrationInstructions: "* Drag and drop the \"End Flow\" Activity to the flow canvas\n* Analyze the UCCX call flow, identify and connect the existing Acvities output branch to the End Flow input.\n\nNote: There is no Output Branch for the End Flow Activity and we can add Multiple End Flow Activity to help with readability of the flow when the flow becomes super big",
2142
+ allAudioFilesInFlow: [
2143
+ "ICD\\ICDQueue.wav",
2144
+ "ICD\\ICDWelcome.wav",
2145
+ "ICDQueue.wav",
2146
+ "ICDWelcome.wav"
2147
+ ]
2148
+ },
2149
+ uccxDisplayType: "End",
2150
+ uccxTypeName: "End",
2151
+ uccxWfId: 12,
2152
+ unmappedReason: null,
2153
+ wxccActivityId: "end",
2154
+ wxccActivityName: "end",
2155
+ wxccGroup: "end"
2156
+ },
2157
+ {
2158
+ id: "78c3dea1-172e-3de9-9c99-3ce92fb4b12e",
2159
+ name: "Play Prompt_16\nPlay Prompt (--Triggering Contact--, WelcomePrompt)",
2160
+ review: {
2161
+ color: "green",
2162
+ level: "confident",
2163
+ reasons: []
2164
+ },
2165
+ suggestedProperties: {
2166
+ uccxDescription: "Play Prompt (--Triggering Contact--, WelcomePrompt)",
2167
+ prompt: "WelcomePrompt",
2168
+ closestWxccActivity: "Play Message",
2169
+ mappingNotes: "Flow Designer Play Message supports mixing audio files and TTS in a single activity; UCCX often builds composite prompts using Prompt steps.",
2170
+ migrationInstructions: "* Drag and drop the Play Message Activity to the Canvas\n* Click the \"Play Message\" Activity to update its property\n* We shall either use Text-to-Speech or Choose play using an Audio Prompt(.WAV)\n* For TTS, Toggle the \"Enable Text-to-Speech\" to utilize TTS, if not, Select the Audio File from the dropdown menu.\n* Optionally, we can also create Local Variables to store the Audio File name if we do not want to point the WAV file directly\n\nNote: When using TTS, the TTS Message field accepts two types of input: raw text (plaintext) or SSML-formatted data. You can use variables also as part of the message to read the dynamic content\n\nNote: If customer would like to utilize the existing Prompts from the UCCX, we can go with selecting Auio files or if the customer would like to go with TTS, then we can turn on the TTS but the we have to input the Text that should be converted to Speech.\n\nFor supported SSML tags for Cisco Cloud Text-to-Speech, see the link: https://help.webex.com/en-us/article/ntkjqhw/Text-to-Speech-(TTS)-in-Webex-Contact-Center#reference-template_b6eff334-4963-4685-b1dc-17184aaaa308",
2171
+ uccxKeyFields: [
2172
+ "promptDTMFExpr",
2173
+ "bargeIn",
2174
+ "continueOnPromptErrors",
2175
+ "flushInputBufferFlag"
2176
+ ],
2177
+ uccxKeyFieldExamples: {
2178
+ flushInputBufferFlag: "true",
2179
+ promptDTMFExpr: "P[1161.wav]",
2180
+ bargeIn: "true",
2181
+ continueOnPromptErrors: "true"
2182
+ },
2183
+ allAudioFilesInFlow: [
2184
+ "ICD\\ICDQueue.wav",
2185
+ "ICD\\ICDWelcome.wav",
2186
+ "ICDQueue.wav",
2187
+ "ICDWelcome.wav"
2188
+ ]
2189
+ },
2190
+ uccxDisplayType: "Play Prompt",
2191
+ uccxTypeName: "Play Prompt",
2192
+ uccxWfId: 16,
2193
+ unmappedReason: null,
2194
+ wxccActivityId: "5f114466ef5cfc454fbbf131",
2195
+ wxccActivityName: "play-message",
2196
+ wxccGroup: "action"
2197
+ },
2198
+ {
2199
+ id: "94eb01a7-71de-3b5b-96b5-02c38e29f58f",
2200
+ name: "Accept_43\nAccept (--Triggering Contact--)",
2201
+ review: {
2202
+ color: "red",
2203
+ level: "must_review",
2204
+ reasons: [
2205
+ "Mapper mappingQuality=red (missing WxCC activity identification)",
2206
+ "IR marked activity as unmapped: No mapper entry or missing activityName"
2207
+ ]
2208
+ },
2209
+ suggestedProperties: {
2210
+ uccxDescription: "Accept (--Triggering Contact--)",
2211
+ closestWxccActivity: "Start Flow (implicit accept)",
2212
+ mappingNotes: "When migrating, ensure any UCCX logic that occurs *before Accept* is still valid; in WxCC, the IVR flow starts upon entry point invocation.",
2213
+ migrationInstructions: "The Start Flow activity appears on the Main Flow canvas by default. You cannot delete the Start Flow activity.\n\nNote: There are certain Output Variables associated with the Start Flow activity depend on the selected Flow Trigger Event. These variables store data that is captured at the moment the flow is triggered.",
2214
+ allAudioFilesInFlow: [
2215
+ "ICD\\ICDQueue.wav",
2216
+ "ICD\\ICDWelcome.wav",
2217
+ "ICDQueue.wav",
2218
+ "ICDWelcome.wav"
2219
+ ]
2220
+ },
2221
+ uccxDisplayType: "Accept",
2222
+ uccxTypeName: "Accept",
2223
+ uccxWfId: 43,
2224
+ unmappedReason: "No mapper entry or missing activityName",
2225
+ wxccActivityId: null,
2226
+ wxccActivityName: "unmapped",
2227
+ wxccGroup: "unmapped"
2228
+ },
2229
+ {
2230
+ id: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2231
+ name: "Calendar_54\nCalendar (cal)",
2232
+ review: {
2233
+ color: "green",
2234
+ level: "confident",
2235
+ reasons: []
2236
+ },
2237
+ suggestedProperties: {
2238
+ uccxDescription: "Calendar (cal)",
2239
+ calendarVarName: "cal",
2240
+ calendarExpr: "cal",
2241
+ closestWxccActivity: "Business Hours",
2242
+ mappingNotes: "We should create the Business Hours first in the WebEx CC Control Hub so that it can be refferenced inside the Business Hours Activity in Flow Designer.\n\nWe need to ensure the \"\"outConnections\"\" of the Calendar Step in UCCX maps correctly in the \"links\" section of the WxCC JSON to connect to the proper Activities.",
2243
+ migrationInstructions: "* Drag and drop the \"Business Hours\" Activity in the Canvas\n* Click the \"Business Hours\" Activity to update its properties\n* Select the configured Busines Hours schedule in the drop down menu under Schedule Details\n* Connect the below output branches to the appropriate Activity in the flow canvas based on the the call flow\n\n • Key UCCX JSON fields to map with WxCC Activites under the \"link\" to ensure the call flow logic follws the UCCX scorrectly\n\n \"Business Hours\" > workingHours\n \"Holidays\", > holidays\n \"The Rest\", > default\n \"Failure\" > error",
2244
+ allAudioFilesInFlow: [
2245
+ "ICD\\ICDQueue.wav",
2246
+ "ICD\\ICDWelcome.wav",
2247
+ "ICDQueue.wav",
2248
+ "ICDWelcome.wav"
2249
+ ]
2250
+ },
2251
+ uccxDisplayType: "Calendar",
2252
+ uccxTypeName: "Calendar",
2253
+ uccxWfId: 54,
2254
+ unmappedReason: null,
2255
+ wxccActivityId: "business-hours",
2256
+ wxccActivityName: "business-hours",
2257
+ wxccGroup: "enum-gateway"
2258
+ },
2259
+ {
2260
+ id: "30eea40d-78b7-32e3-83c6-94738320acab",
2261
+ name: "Play Prompt_87\nPlay Prompt (--Triggering Contact--, FailurePrompt)",
2262
+ review: {
2263
+ color: "green",
2264
+ level: "confident",
2265
+ reasons: []
2266
+ },
2267
+ suggestedProperties: {
2268
+ uccxDescription: "Play Prompt (--Triggering Contact--, FailurePrompt)",
2269
+ prompt: "FailurePrompt",
2270
+ closestWxccActivity: "Play Message",
2271
+ mappingNotes: "Flow Designer Play Message supports mixing audio files and TTS in a single activity; UCCX often builds composite prompts using Prompt steps.",
2272
+ migrationInstructions: "* Drag and drop the Play Message Activity to the Canvas\n* Click the \"Play Message\" Activity to update its property\n* We shall either use Text-to-Speech or Choose play using an Audio Prompt(.WAV)\n* For TTS, Toggle the \"Enable Text-to-Speech\" to utilize TTS, if not, Select the Audio File from the dropdown menu.\n* Optionally, we can also create Local Variables to store the Audio File name if we do not want to point the WAV file directly\n\nNote: When using TTS, the TTS Message field accepts two types of input: raw text (plaintext) or SSML-formatted data. You can use variables also as part of the message to read the dynamic content\n\nNote: If customer would like to utilize the existing Prompts from the UCCX, we can go with selecting Auio files or if the customer would like to go with TTS, then we can turn on the TTS but the we have to input the Text that should be converted to Speech.\n\nFor supported SSML tags for Cisco Cloud Text-to-Speech, see the link: https://help.webex.com/en-us/article/ntkjqhw/Text-to-Speech-(TTS)-in-Webex-Contact-Center#reference-template_b6eff334-4963-4685-b1dc-17184aaaa308",
2273
+ uccxKeyFields: [
2274
+ "promptDTMFExpr",
2275
+ "bargeIn",
2276
+ "continueOnPromptErrors",
2277
+ "flushInputBufferFlag"
2278
+ ],
2279
+ uccxKeyFieldExamples: {
2280
+ flushInputBufferFlag: "true",
2281
+ promptDTMFExpr: "P[1161.wav]",
2282
+ bargeIn: "true",
2283
+ continueOnPromptErrors: "true"
2284
+ },
2285
+ allAudioFilesInFlow: [
2286
+ "ICD\\ICDQueue.wav",
2287
+ "ICD\\ICDWelcome.wav",
2288
+ "ICDQueue.wav",
2289
+ "ICDWelcome.wav"
2290
+ ]
2291
+ },
2292
+ uccxDisplayType: "Play Prompt",
2293
+ uccxTypeName: "Play Prompt",
2294
+ uccxWfId: 87,
2295
+ unmappedReason: null,
2296
+ wxccActivityId: "5f114466ef5cfc454fbbf131",
2297
+ wxccActivityName: "play-message",
2298
+ wxccGroup: "action"
2299
+ },
2300
+ {
2301
+ id: "824f0d8a-01d5-3f21-9563-590427002c86",
2302
+ name: "Play Prompt_107\nPlay Prompt (--Triggering Contact--, NonBusinessHourPrompt)",
2303
+ review: {
2304
+ color: "green",
2305
+ level: "confident",
2306
+ reasons: []
2307
+ },
2308
+ suggestedProperties: {
2309
+ uccxDescription: "Play Prompt (--Triggering Contact--, NonBusinessHourPrompt)",
2310
+ prompt: "NonBusinessHourPrompt",
2311
+ closestWxccActivity: "Play Message",
2312
+ mappingNotes: "Flow Designer Play Message supports mixing audio files and TTS in a single activity; UCCX often builds composite prompts using Prompt steps.",
2313
+ migrationInstructions: "* Drag and drop the Play Message Activity to the Canvas\n* Click the \"Play Message\" Activity to update its property\n* We shall either use Text-to-Speech or Choose play using an Audio Prompt(.WAV)\n* For TTS, Toggle the \"Enable Text-to-Speech\" to utilize TTS, if not, Select the Audio File from the dropdown menu.\n* Optionally, we can also create Local Variables to store the Audio File name if we do not want to point the WAV file directly\n\nNote: When using TTS, the TTS Message field accepts two types of input: raw text (plaintext) or SSML-formatted data. You can use variables also as part of the message to read the dynamic content\n\nNote: If customer would like to utilize the existing Prompts from the UCCX, we can go with selecting Auio files or if the customer would like to go with TTS, then we can turn on the TTS but the we have to input the Text that should be converted to Speech.\n\nFor supported SSML tags for Cisco Cloud Text-to-Speech, see the link: https://help.webex.com/en-us/article/ntkjqhw/Text-to-Speech-(TTS)-in-Webex-Contact-Center#reference-template_b6eff334-4963-4685-b1dc-17184aaaa308",
2314
+ uccxKeyFields: [
2315
+ "promptDTMFExpr",
2316
+ "bargeIn",
2317
+ "continueOnPromptErrors",
2318
+ "flushInputBufferFlag"
2319
+ ],
2320
+ uccxKeyFieldExamples: {
2321
+ flushInputBufferFlag: "true",
2322
+ promptDTMFExpr: "P[1161.wav]",
2323
+ bargeIn: "true",
2324
+ continueOnPromptErrors: "true"
2325
+ },
2326
+ allAudioFilesInFlow: [
2327
+ "ICD\\ICDQueue.wav",
2328
+ "ICD\\ICDWelcome.wav",
2329
+ "ICDQueue.wav",
2330
+ "ICDWelcome.wav"
2331
+ ]
2332
+ },
2333
+ uccxDisplayType: "Play Prompt",
2334
+ uccxTypeName: "Play Prompt",
2335
+ uccxWfId: 107,
2336
+ unmappedReason: null,
2337
+ wxccActivityId: "5f114466ef5cfc454fbbf131",
2338
+ wxccActivityName: "play-message",
2339
+ wxccGroup: "action"
2340
+ },
2341
+ {
2342
+ id: "eb11f7cf-18d7-31aa-936f-68df91fc9c6f",
2343
+ name: "Select Resource_123\nSelect Resource (--Triggering Contact-- from HolidayCSQ)",
2344
+ review: {
2345
+ color: "green",
2346
+ level: "confident",
2347
+ reasons: []
2348
+ },
2349
+ suggestedProperties: {
2350
+ uccxDescription: "Select Resource (--Triggering Contact-- from HolidayCSQ)",
2351
+ queuingExpr: "HolidayCSQ",
2352
+ ringTimeExpr: "12",
2353
+ routingTypeStr: "Contact Service Queue",
2354
+ toQueue: true,
2355
+ toConnect: true,
2356
+ closestWxccActivity: "Queue Contact (agent selection is built-in) or Queue To Agent",
2357
+ mappingNotes: "Avoid reproducing UCCX resource-selection logic step-by-step unless absolutely required; leverage WxCC routing features where possible.",
2358
+ migrationInstructions: "* Drag and drop the \"Queue Contact\" Activity to the canvas\n* Click the added \"Queue Contact\" activity to update its property\n* Select the \"Static Queue\" name if all contacts should go to a single queue or select the \"Variable Queue\" if the queue should change based on the certain parameters or choosen menu options, etc.\n* If we selected the Static Queue whick routes based on Skill then we have to Configure the Skill Requirements or if we choosen Dynamic Queue, we should also choose the reuqired Skill either through static or dynamic.\n\n* We should also select the Fallback Queue. \n\nNote: The Fallback Queue always honors Longest Available Agent routing. If the selected queue uses Skills Based Routing, skills cannot be configured.\n\nNote: Queue should be already created in the WebEx CC Control Hub to be available inside the flow designer to select. Depends on the type of the Queue, we select, there may be additional options to choose from the properties.\n\nNote: UCCX Select Resource does not give any information about the Queue itself like wheather its group or Skill based and manual intervention is required after the flow is created and certain settings shall need to be updated directly on the Flow Designer.",
2359
+ uccxKeyFields: [
2360
+ "queuingExpr",
2361
+ "toQueue",
2362
+ "toConnect",
2363
+ "ringTimeExpr"
2364
+ ],
2365
+ uccxKeyFieldExamples: {
2366
+ ringTimeExpr: "10",
2367
+ toQueue: "true",
2368
+ toConnect: "true",
2369
+ queuingExpr: "\"CSQ_SalesStars\""
2370
+ },
2371
+ allAudioFilesInFlow: [
2372
+ "ICD\\ICDQueue.wav",
2373
+ "ICD\\ICDWelcome.wav",
2374
+ "ICDQueue.wav",
2375
+ "ICDWelcome.wav"
2376
+ ]
2377
+ },
2378
+ uccxDisplayType: "Select Resource",
2379
+ uccxTypeName: "Select Resource",
2380
+ uccxWfId: 123,
2381
+ unmappedReason: null,
2382
+ wxccActivityId: "5f114550ef5cfc454fbbf133",
2383
+ wxccActivityName: "queue-contact",
2384
+ wxccGroup: "action"
2385
+ },
2386
+ {
2387
+ id: "ddb6c20e-1574-3485-8151-f23052f6f6e7",
2388
+ name: "Play Prompt_125\nPlay Prompt (--Triggering Contact--, QueuePrompt)",
2389
+ review: {
2390
+ color: "green",
2391
+ level: "confident",
2392
+ reasons: []
2393
+ },
2394
+ suggestedProperties: {
2395
+ uccxDescription: "Play Prompt (--Triggering Contact--, QueuePrompt)",
2396
+ prompt: "QueuePrompt",
2397
+ closestWxccActivity: "Play Message",
2398
+ mappingNotes: "Flow Designer Play Message supports mixing audio files and TTS in a single activity; UCCX often builds composite prompts using Prompt steps.",
2399
+ migrationInstructions: "* Drag and drop the Play Message Activity to the Canvas\n* Click the \"Play Message\" Activity to update its property\n* We shall either use Text-to-Speech or Choose play using an Audio Prompt(.WAV)\n* For TTS, Toggle the \"Enable Text-to-Speech\" to utilize TTS, if not, Select the Audio File from the dropdown menu.\n* Optionally, we can also create Local Variables to store the Audio File name if we do not want to point the WAV file directly\n\nNote: When using TTS, the TTS Message field accepts two types of input: raw text (plaintext) or SSML-formatted data. You can use variables also as part of the message to read the dynamic content\n\nNote: If customer would like to utilize the existing Prompts from the UCCX, we can go with selecting Auio files or if the customer would like to go with TTS, then we can turn on the TTS but the we have to input the Text that should be converted to Speech.\n\nFor supported SSML tags for Cisco Cloud Text-to-Speech, see the link: https://help.webex.com/en-us/article/ntkjqhw/Text-to-Speech-(TTS)-in-Webex-Contact-Center#reference-template_b6eff334-4963-4685-b1dc-17184aaaa308",
2400
+ uccxKeyFields: [
2401
+ "promptDTMFExpr",
2402
+ "bargeIn",
2403
+ "continueOnPromptErrors",
2404
+ "flushInputBufferFlag"
2405
+ ],
2406
+ uccxKeyFieldExamples: {
2407
+ flushInputBufferFlag: "true",
2408
+ promptDTMFExpr: "P[1161.wav]",
2409
+ bargeIn: "true",
2410
+ continueOnPromptErrors: "true"
2411
+ },
2412
+ allAudioFilesInFlow: [
2413
+ "ICD\\ICDQueue.wav",
2414
+ "ICD\\ICDWelcome.wav",
2415
+ "ICDQueue.wav",
2416
+ "ICDWelcome.wav"
2417
+ ]
2418
+ },
2419
+ uccxDisplayType: "Play Prompt",
2420
+ uccxTypeName: "Play Prompt",
2421
+ uccxWfId: 125,
2422
+ unmappedReason: null,
2423
+ wxccActivityId: "5f114466ef5cfc454fbbf131",
2424
+ wxccActivityName: "play-message",
2425
+ wxccGroup: "action"
2426
+ },
2427
+ {
2428
+ id: "9e093dc4-866c-32ca-bebf-624ae3dcfd62",
2429
+ name: "Delay_126\nDelay DelayWhileQueued sec",
2430
+ review: {
2431
+ color: "green",
2432
+ level: "confident",
2433
+ reasons: []
2434
+ },
2435
+ suggestedProperties: {
2436
+ uccxDescription: "Delay DelayWhileQueued sec",
2437
+ delayExpression: "DelayWhileQueued",
2438
+ expression: "DelayWhileQueued",
2439
+ interruptible: true,
2440
+ closestWxccActivity: "Wait",
2441
+ mappingNotes: "The practical outcome of these two steps is functionally equivalent: they introduce a time-based pause in the call flow\n\nAlthought the Wait Activity is the equivalent of Delay but we don't recommend usage of the Wait activity when an IVR session is active as it may cause the IVR session to time out. In such cases, contact will experience dead air resulting in call failures. We strongly recommend flow designers to use the Wait activity in the CallbackFailed event and specify the wait period.",
2442
+ migrationInstructions: "* Drag and drop the \"wait\" Activity into the canvas\n* Click the Wait Activity to update its properties\n* Enter duration between 00:00:05 - 72:00:00\n\nNote: No Input or Output Variables are applicable on this activity\n\nTypically, in UCCX, Delay Step uses either Variable or it shall be statically configured through Delay Step property",
2443
+ uccxKeyFields: [
2444
+ "delayExpression",
2445
+ "interruptible"
2446
+ ],
2447
+ uccxKeyFieldExamples: {
2448
+ delayExpression: "DelayWhileQueued",
2449
+ interruptible: "true"
2450
+ },
2451
+ allAudioFilesInFlow: [
2452
+ "ICD\\ICDQueue.wav",
2453
+ "ICD\\ICDWelcome.wav",
2454
+ "ICDQueue.wav",
2455
+ "ICDWelcome.wav"
2456
+ ]
2457
+ },
2458
+ uccxDisplayType: "Delay",
2459
+ uccxTypeName: "Delay",
2460
+ uccxWfId: 126,
2461
+ unmappedReason: null,
2462
+ wxccActivityId: "wait-activity",
2463
+ wxccActivityName: "wait-activity",
2464
+ wxccGroup: "action"
2465
+ },
2466
+ {
2467
+ id: "8dd88674-9b03-39f0-803e-1a06ecc32970",
2468
+ name: "Select Resource_133\nSelect Resource (--Triggering Contact-- from BusinessHourCSQ)",
2469
+ review: {
2470
+ color: "green",
2471
+ level: "confident",
2472
+ reasons: []
2473
+ },
2474
+ suggestedProperties: {
2475
+ uccxDescription: "Select Resource (--Triggering Contact-- from BusinessHourCSQ)",
2476
+ queuingExpr: "BusinessHourCSQ",
2477
+ ringTimeExpr: "12",
2478
+ routingTypeStr: "Contact Service Queue",
2479
+ toQueue: true,
2480
+ toConnect: true,
2481
+ closestWxccActivity: "Queue Contact (agent selection is built-in) or Queue To Agent",
2482
+ mappingNotes: "Avoid reproducing UCCX resource-selection logic step-by-step unless absolutely required; leverage WxCC routing features where possible.",
2483
+ migrationInstructions: "* Drag and drop the \"Queue Contact\" Activity to the canvas\n* Click the added \"Queue Contact\" activity to update its property\n* Select the \"Static Queue\" name if all contacts should go to a single queue or select the \"Variable Queue\" if the queue should change based on the certain parameters or choosen menu options, etc.\n* If we selected the Static Queue whick routes based on Skill then we have to Configure the Skill Requirements or if we choosen Dynamic Queue, we should also choose the reuqired Skill either through static or dynamic.\n\n* We should also select the Fallback Queue. \n\nNote: The Fallback Queue always honors Longest Available Agent routing. If the selected queue uses Skills Based Routing, skills cannot be configured.\n\nNote: Queue should be already created in the WebEx CC Control Hub to be available inside the flow designer to select. Depends on the type of the Queue, we select, there may be additional options to choose from the properties.\n\nNote: UCCX Select Resource does not give any information about the Queue itself like wheather its group or Skill based and manual intervention is required after the flow is created and certain settings shall need to be updated directly on the Flow Designer.",
2484
+ uccxKeyFields: [
2485
+ "queuingExpr",
2486
+ "toQueue",
2487
+ "toConnect",
2488
+ "ringTimeExpr"
2489
+ ],
2490
+ uccxKeyFieldExamples: {
2491
+ ringTimeExpr: "10",
2492
+ toQueue: "true",
2493
+ toConnect: "true",
2494
+ queuingExpr: "\"CSQ_SalesStars\""
2495
+ },
2496
+ allAudioFilesInFlow: [
2497
+ "ICD\\ICDQueue.wav",
2498
+ "ICD\\ICDWelcome.wav",
2499
+ "ICDQueue.wav",
2500
+ "ICDWelcome.wav"
2501
+ ]
2502
+ },
2503
+ uccxDisplayType: "Select Resource",
2504
+ uccxTypeName: "Select Resource",
2505
+ uccxWfId: 133,
2506
+ unmappedReason: null,
2507
+ wxccActivityId: "5f114550ef5cfc454fbbf133",
2508
+ wxccActivityName: "queue-contact",
2509
+ wxccGroup: "action"
2510
+ },
2511
+ {
2512
+ id: "7b61caf6-ba3f-3a44-84bb-3dacdbde8b60",
2513
+ name: "Play Prompt_135\nPlay Prompt (--Triggering Contact--, QueuePrompt)",
2514
+ review: {
2515
+ color: "green",
2516
+ level: "confident",
2517
+ reasons: []
2518
+ },
2519
+ suggestedProperties: {
2520
+ uccxDescription: "Play Prompt (--Triggering Contact--, QueuePrompt)",
2521
+ prompt: "QueuePrompt",
2522
+ closestWxccActivity: "Play Message",
2523
+ mappingNotes: "Flow Designer Play Message supports mixing audio files and TTS in a single activity; UCCX often builds composite prompts using Prompt steps.",
2524
+ migrationInstructions: "* Drag and drop the Play Message Activity to the Canvas\n* Click the \"Play Message\" Activity to update its property\n* We shall either use Text-to-Speech or Choose play using an Audio Prompt(.WAV)\n* For TTS, Toggle the \"Enable Text-to-Speech\" to utilize TTS, if not, Select the Audio File from the dropdown menu.\n* Optionally, we can also create Local Variables to store the Audio File name if we do not want to point the WAV file directly\n\nNote: When using TTS, the TTS Message field accepts two types of input: raw text (plaintext) or SSML-formatted data. You can use variables also as part of the message to read the dynamic content\n\nNote: If customer would like to utilize the existing Prompts from the UCCX, we can go with selecting Auio files or if the customer would like to go with TTS, then we can turn on the TTS but the we have to input the Text that should be converted to Speech.\n\nFor supported SSML tags for Cisco Cloud Text-to-Speech, see the link: https://help.webex.com/en-us/article/ntkjqhw/Text-to-Speech-(TTS)-in-Webex-Contact-Center#reference-template_b6eff334-4963-4685-b1dc-17184aaaa308",
2525
+ uccxKeyFields: [
2526
+ "promptDTMFExpr",
2527
+ "bargeIn",
2528
+ "continueOnPromptErrors",
2529
+ "flushInputBufferFlag"
2530
+ ],
2531
+ uccxKeyFieldExamples: {
2532
+ flushInputBufferFlag: "true",
2533
+ promptDTMFExpr: "P[1161.wav]",
2534
+ bargeIn: "true",
2535
+ continueOnPromptErrors: "true"
2536
+ },
2537
+ allAudioFilesInFlow: [
2538
+ "ICD\\ICDQueue.wav",
2539
+ "ICD\\ICDWelcome.wav",
2540
+ "ICDQueue.wav",
2541
+ "ICDWelcome.wav"
2542
+ ]
2543
+ },
2544
+ uccxDisplayType: "Play Prompt",
2545
+ uccxTypeName: "Play Prompt",
2546
+ uccxWfId: 135,
2547
+ unmappedReason: null,
2548
+ wxccActivityId: "5f114466ef5cfc454fbbf131",
2549
+ wxccActivityName: "play-message",
2550
+ wxccGroup: "action"
2551
+ },
2552
+ {
2553
+ id: "f64571d2-a862-3c35-9098-abae0f54b985",
2554
+ name: "Delay_136\nDelay DelayWhileQueued sec",
2555
+ review: {
2556
+ color: "green",
2557
+ level: "confident",
2558
+ reasons: []
2559
+ },
2560
+ suggestedProperties: {
2561
+ uccxDescription: "Delay DelayWhileQueued sec",
2562
+ delayExpression: "DelayWhileQueued",
2563
+ expression: "DelayWhileQueued",
2564
+ interruptible: true,
2565
+ closestWxccActivity: "Wait",
2566
+ mappingNotes: "The practical outcome of these two steps is functionally equivalent: they introduce a time-based pause in the call flow\n\nAlthought the Wait Activity is the equivalent of Delay but we don't recommend usage of the Wait activity when an IVR session is active as it may cause the IVR session to time out. In such cases, contact will experience dead air resulting in call failures. We strongly recommend flow designers to use the Wait activity in the CallbackFailed event and specify the wait period.",
2567
+ migrationInstructions: "* Drag and drop the \"wait\" Activity into the canvas\n* Click the Wait Activity to update its properties\n* Enter duration between 00:00:05 - 72:00:00\n\nNote: No Input or Output Variables are applicable on this activity\n\nTypically, in UCCX, Delay Step uses either Variable or it shall be statically configured through Delay Step property",
2568
+ uccxKeyFields: [
2569
+ "delayExpression",
2570
+ "interruptible"
2571
+ ],
2572
+ uccxKeyFieldExamples: {
2573
+ delayExpression: "DelayWhileQueued",
2574
+ interruptible: "true"
2575
+ },
2576
+ allAudioFilesInFlow: [
2577
+ "ICD\\ICDQueue.wav",
2578
+ "ICD\\ICDWelcome.wav",
2579
+ "ICDQueue.wav",
2580
+ "ICDWelcome.wav"
2581
+ ]
2582
+ },
2583
+ uccxDisplayType: "Delay",
2584
+ uccxTypeName: "Delay",
2585
+ uccxWfId: 136,
2586
+ unmappedReason: null,
2587
+ wxccActivityId: "wait-activity",
2588
+ wxccActivityName: "wait-activity",
2589
+ wxccGroup: "action"
2590
+ }
2591
+ ];
2592
+ var aefFile = "C:\\Windows\\TEMP\\upload-3096504673883630384.aef";
2593
+ var generatedAt = "2026-05-11T11:31:14.143682200Z";
2594
+ var links = [
2595
+ {
2596
+ conditionExpr: "out",
2597
+ id: "fe58c236-9a37-318c-8d4c-0cf6650fdb9d",
2598
+ review: {
2599
+ color: "green",
2600
+ level: "confident",
2601
+ reasons: []
2602
+ },
2603
+ sourceActivityId: "8c89c876-e556-3c8c-a1be-77b8cfbd3800",
2604
+ targetActivityId: "94eb01a7-71de-3b5b-96b5-02c38e29f58f",
2605
+ uccxEdgeIndex: 0,
2606
+ uccxFromWfId: 0,
2607
+ uccxLabel: "",
2608
+ uccxToWfId: 43
2609
+ },
2610
+ {
2611
+ conditionExpr: "default",
2612
+ id: "15d60d2d-a2a7-32b7-9ecd-bc7815f49c24",
2613
+ review: {
2614
+ color: "green",
2615
+ level: "confident",
2616
+ reasons: []
2617
+ },
2618
+ sourceActivityId: "78c3dea1-172e-3de9-9c99-3ce92fb4b12e",
2619
+ targetActivityId: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2620
+ uccxEdgeIndex: 0,
2621
+ uccxFromWfId: 16,
2622
+ uccxLabel: "",
2623
+ uccxToWfId: 54
2624
+ },
2625
+ {
2626
+ conditionExpr: "default",
2627
+ id: "d2257d15-c592-303e-8995-532bc5c5cf83",
2628
+ review: {
2629
+ color: "green",
2630
+ level: "confident",
2631
+ reasons: []
2632
+ },
2633
+ sourceActivityId: "94eb01a7-71de-3b5b-96b5-02c38e29f58f",
2634
+ targetActivityId: "78c3dea1-172e-3de9-9c99-3ce92fb4b12e",
2635
+ uccxEdgeIndex: 0,
2636
+ uccxFromWfId: 43,
2637
+ uccxLabel: "",
2638
+ uccxToWfId: 16
2639
+ },
2640
+ {
2641
+ conditionExpr: "business_hours",
2642
+ id: "3d56441f-0b08-3559-b3a1-9808180504f3",
2643
+ review: {
2644
+ color: "yellow",
2645
+ level: "low_confidence",
2646
+ reasons: [
2647
+ "Non-standard conditionExpr (likely needs manual port selection in Flow Designer)"
2648
+ ]
2649
+ },
2650
+ sourceActivityId: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2651
+ targetActivityId: "8dd88674-9b03-39f0-803e-1a06ecc32970",
2652
+ uccxEdgeIndex: 0,
2653
+ uccxFromWfId: 54,
2654
+ uccxLabel: "Business Hours",
2655
+ uccxToWfId: 133
2656
+ },
2657
+ {
2658
+ conditionExpr: "holidays",
2659
+ id: "2bb98772-9225-3fdf-9646-a3854f1884fd",
2660
+ review: {
2661
+ color: "yellow",
2662
+ level: "low_confidence",
2663
+ reasons: [
2664
+ "Non-standard conditionExpr (likely needs manual port selection in Flow Designer)"
2665
+ ]
2666
+ },
2667
+ sourceActivityId: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2668
+ targetActivityId: "eb11f7cf-18d7-31aa-936f-68df91fc9c6f",
2669
+ uccxEdgeIndex: 1,
2670
+ uccxFromWfId: 54,
2671
+ uccxLabel: "Holidays",
2672
+ uccxToWfId: 123
2673
+ },
2674
+ {
2675
+ conditionExpr: "the_rest",
2676
+ id: "4bf84735-5161-32e2-b94f-3b848390a1ac",
2677
+ review: {
2678
+ color: "yellow",
2679
+ level: "low_confidence",
2680
+ reasons: [
2681
+ "Non-standard conditionExpr (likely needs manual port selection in Flow Designer)"
2682
+ ]
2683
+ },
2684
+ sourceActivityId: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2685
+ targetActivityId: "824f0d8a-01d5-3f21-9563-590427002c86",
2686
+ uccxEdgeIndex: 2,
2687
+ uccxFromWfId: 54,
2688
+ uccxLabel: "The Rest",
2689
+ uccxToWfId: 107
2690
+ },
2691
+ {
2692
+ conditionExpr: "failure",
2693
+ id: "43c91f09-d081-3524-ad2a-7ddf5d0bd3de",
2694
+ review: {
2695
+ color: "green",
2696
+ level: "confident",
2697
+ reasons: []
2698
+ },
2699
+ sourceActivityId: "95c0b5ba-20a8-3062-995f-d01036660cdc",
2700
+ targetActivityId: "30eea40d-78b7-32e3-83c6-94738320acab",
2701
+ uccxEdgeIndex: 3,
2702
+ uccxFromWfId: 54,
2703
+ uccxLabel: "Failure",
2704
+ uccxToWfId: 87
2705
+ },
2706
+ {
2707
+ conditionExpr: "default",
2708
+ id: "3cec80e0-81ac-302c-9ff5-57ff85ecaf2d",
2709
+ review: {
2710
+ color: "green",
2711
+ level: "confident",
2712
+ reasons: []
2713
+ },
2714
+ sourceActivityId: "30eea40d-78b7-32e3-83c6-94738320acab",
2715
+ targetActivityId: "c535b5fd-5ab9-323f-b1ac-667f4590d801",
2716
+ uccxEdgeIndex: 0,
2717
+ uccxFromWfId: 87,
2718
+ uccxLabel: "",
2719
+ uccxToWfId: 12
2720
+ },
2721
+ {
2722
+ conditionExpr: "default",
2723
+ id: "d4d3a905-3b1a-32fe-a90d-43ac44ff2e94",
2724
+ review: {
2725
+ color: "green",
2726
+ level: "confident",
2727
+ reasons: []
2728
+ },
2729
+ sourceActivityId: "824f0d8a-01d5-3f21-9563-590427002c86",
2730
+ targetActivityId: "c535b5fd-5ab9-323f-b1ac-667f4590d801",
2731
+ uccxEdgeIndex: 0,
2732
+ uccxFromWfId: 107,
2733
+ uccxLabel: "",
2734
+ uccxToWfId: 12
2735
+ },
2736
+ {
2737
+ conditionExpr: "default",
2738
+ id: "e9259722-948e-36f0-b292-1cdcbf2fc63c",
2739
+ review: {
2740
+ color: "green",
2741
+ level: "confident",
2742
+ reasons: []
2743
+ },
2744
+ sourceActivityId: "eb11f7cf-18d7-31aa-936f-68df91fc9c6f",
2745
+ targetActivityId: "c535b5fd-5ab9-323f-b1ac-667f4590d801",
2746
+ uccxEdgeIndex: 0,
2747
+ uccxFromWfId: 123,
2748
+ uccxLabel: "Connected",
2749
+ uccxToWfId: 12
2750
+ },
2751
+ {
2752
+ conditionExpr: "queued",
2753
+ id: "1e964ee4-d8d5-3607-9bfb-cae54e07f2cb",
2754
+ review: {
2755
+ color: "yellow",
2756
+ level: "low_confidence",
2757
+ reasons: [
2758
+ "Non-standard conditionExpr (likely needs manual port selection in Flow Designer)"
2759
+ ]
2760
+ },
2761
+ sourceActivityId: "eb11f7cf-18d7-31aa-936f-68df91fc9c6f",
2762
+ targetActivityId: "ddb6c20e-1574-3485-8151-f23052f6f6e7",
2763
+ uccxEdgeIndex: 1,
2764
+ uccxFromWfId: 123,
2765
+ uccxLabel: "Queued",
2766
+ uccxToWfId: 125
2767
+ },
2768
+ {
2769
+ conditionExpr: "default",
2770
+ id: "81f3a025-70c9-3d05-a2a5-de4a981c0715",
2771
+ review: {
2772
+ color: "green",
2773
+ level: "confident",
2774
+ reasons: []
2775
+ },
2776
+ sourceActivityId: "ddb6c20e-1574-3485-8151-f23052f6f6e7",
2777
+ targetActivityId: "9e093dc4-866c-32ca-bebf-624ae3dcfd62",
2778
+ uccxEdgeIndex: 0,
2779
+ uccxFromWfId: 125,
2780
+ uccxLabel: "",
2781
+ uccxToWfId: 126
2782
+ },
2783
+ {
2784
+ conditionExpr: "default",
2785
+ id: "36d5e8cf-ce9d-3acd-bf49-04c1c3d9f69d",
2786
+ review: {
2787
+ color: "green",
2788
+ level: "confident",
2789
+ reasons: []
2790
+ },
2791
+ sourceActivityId: "9e093dc4-866c-32ca-bebf-624ae3dcfd62",
2792
+ targetActivityId: "ddb6c20e-1574-3485-8151-f23052f6f6e7",
2793
+ uccxEdgeIndex: 0,
2794
+ uccxFromWfId: 126,
2795
+ uccxLabel: "",
2796
+ uccxToWfId: 125
2797
+ },
2798
+ {
2799
+ conditionExpr: "default",
2800
+ id: "74d24ec3-31a8-3aef-9359-1eb79b92077c",
2801
+ review: {
2802
+ color: "green",
2803
+ level: "confident",
2804
+ reasons: []
2805
+ },
2806
+ sourceActivityId: "8dd88674-9b03-39f0-803e-1a06ecc32970",
2807
+ targetActivityId: "c535b5fd-5ab9-323f-b1ac-667f4590d801",
2808
+ uccxEdgeIndex: 0,
2809
+ uccxFromWfId: 133,
2810
+ uccxLabel: "Connected",
2811
+ uccxToWfId: 12
2812
+ },
2813
+ {
2814
+ conditionExpr: "queued",
2815
+ id: "d96a9238-fc21-3a9d-a90a-e2af7698d36a",
2816
+ review: {
2817
+ color: "yellow",
2818
+ level: "low_confidence",
2819
+ reasons: [
2820
+ "Non-standard conditionExpr (likely needs manual port selection in Flow Designer)"
2821
+ ]
2822
+ },
2823
+ sourceActivityId: "8dd88674-9b03-39f0-803e-1a06ecc32970",
2824
+ targetActivityId: "7b61caf6-ba3f-3a44-84bb-3dacdbde8b60",
2825
+ uccxEdgeIndex: 1,
2826
+ uccxFromWfId: 133,
2827
+ uccxLabel: "Queued",
2828
+ uccxToWfId: 135
2829
+ },
2830
+ {
2831
+ conditionExpr: "default",
2832
+ id: "4fec8261-a460-3a2b-8a84-934592a62734",
2833
+ review: {
2834
+ color: "green",
2835
+ level: "confident",
2836
+ reasons: []
2837
+ },
2838
+ sourceActivityId: "7b61caf6-ba3f-3a44-84bb-3dacdbde8b60",
2839
+ targetActivityId: "f64571d2-a862-3c35-9098-abae0f54b985",
2840
+ uccxEdgeIndex: 0,
2841
+ uccxFromWfId: 135,
2842
+ uccxLabel: "",
2843
+ uccxToWfId: 136
2844
+ },
2845
+ {
2846
+ conditionExpr: "default",
2847
+ id: "27e9f7a7-875f-34f1-97d7-a277d48035ac",
2848
+ review: {
2849
+ color: "green",
2850
+ level: "confident",
2851
+ reasons: []
2852
+ },
2853
+ sourceActivityId: "f64571d2-a862-3c35-9098-abae0f54b985",
2854
+ targetActivityId: "7b61caf6-ba3f-3a44-84bb-3dacdbde8b60",
2855
+ uccxEdgeIndex: 0,
2856
+ uccxFromWfId: 136,
2857
+ uccxLabel: "",
2858
+ uccxToWfId: 135
2859
+ }
2860
+ ];
2861
+ var prefix = "QueuingWithCalendar_uccx.aef";
2862
+ var resources = {
2863
+ aefFile: "C:\\Windows\\TEMP\\upload-3096504673883630384.aef",
2864
+ audioFiles: [
2865
+ "ICDQueue.wav",
2866
+ "ICDWelcome.wav",
2867
+ "ICD\\ICDQueue.wav",
2868
+ "ICD\\ICDWelcome.wav"
2869
+ ],
2870
+ audioFilesCount: 4,
2871
+ generatedAt: "2026-05-11T11:31:14.128113200Z",
2872
+ variableCount: 10,
2873
+ variables: [
2874
+ {
2875
+ hints: [
2876
+ "default_from_uccx",
2877
+ "prompt"
2878
+ ],
2879
+ isParameter: false,
2880
+ metaAttributes: null,
2881
+ name: "WelcomePrompt",
2882
+ type: "STRING",
2883
+ usedByWfIds: [
2884
+ 16
2885
+ ],
2886
+ value: "ICDWelcome.wav"
2887
+ },
2888
+ {
2889
+ hints: [
2890
+ "calendar",
2891
+ "calendar_expr"
2892
+ ],
2893
+ isParameter: false,
2894
+ metaAttributes: null,
2895
+ name: "cal",
2896
+ type: "STRING",
2897
+ usedByWfIds: [
2898
+ 54
2899
+ ],
2900
+ value: null
2901
+ },
2902
+ {
2903
+ hints: [
2904
+ "prompt"
2905
+ ],
2906
+ isParameter: false,
2907
+ metaAttributes: null,
2908
+ name: "FailurePrompt",
2909
+ type: "STRING",
2910
+ usedByWfIds: [
2911
+ 87
2912
+ ],
2913
+ value: null
2914
+ },
2915
+ {
2916
+ hints: [
2917
+ "prompt"
2918
+ ],
2919
+ isParameter: false,
2920
+ metaAttributes: null,
2921
+ name: "NonBusinessHourPrompt",
2922
+ type: "STRING",
2923
+ usedByWfIds: [
2924
+ 107
2925
+ ],
2926
+ value: null
2927
+ },
2928
+ {
2929
+ hints: [
2930
+ "csq"
2931
+ ],
2932
+ isParameter: false,
2933
+ metaAttributes: null,
2934
+ name: "HolidayCSQ",
2935
+ type: "STRING",
2936
+ usedByWfIds: [
2937
+ 123
2938
+ ],
2939
+ value: null
2940
+ },
2941
+ {
2942
+ hints: [
2943
+ "default_from_uccx",
2944
+ "prompt"
2945
+ ],
2946
+ isParameter: false,
2947
+ metaAttributes: null,
2948
+ name: "QueuePrompt",
2949
+ type: "STRING",
2950
+ usedByWfIds: [
2951
+ 125,
2952
+ 135
2953
+ ],
2954
+ value: "ICDQueue.wav"
2955
+ },
2956
+ {
2957
+ hints: [
2958
+ "csq"
2959
+ ],
2960
+ isParameter: false,
2961
+ metaAttributes: null,
2962
+ name: "BusinessHourCSQ",
2963
+ type: "STRING",
2964
+ usedByWfIds: [
2965
+ 133
2966
+ ],
2967
+ value: null
2968
+ },
2969
+ {
2970
+ hints: [
2971
+ "default_only"
2972
+ ],
2973
+ isParameter: false,
2974
+ metaAttributes: null,
2975
+ name: "resourceID",
2976
+ type: "STRING",
2977
+ usedByWfIds: [],
2978
+ value: null
2979
+ },
2980
+ {
2981
+ hints: [
2982
+ "default_from_uccx",
2983
+ "default_only"
2984
+ ],
2985
+ isParameter: false,
2986
+ metaAttributes: null,
2987
+ name: "DelayWhileQueued",
2988
+ type: "STRING",
2989
+ usedByWfIds: [],
2990
+ value: "30"
2991
+ },
2992
+ {
2993
+ hints: [
2994
+ "default_only"
2995
+ ],
2996
+ isParameter: false,
2997
+ metaAttributes: null,
2998
+ name: "SRS_TempResourceSelectedVar2",
2999
+ type: "STRING",
3000
+ usedByWfIds: [],
3001
+ value: null
3002
+ }
3003
+ ]
3004
+ };
3005
+ var schema = "uccx2wxcc-ir/v1";
3006
+ var warnings = [
3007
+ "Unmapped step: wfId=43 typeName=Accept displayType=Accept"
3008
+ ];
3009
+ var irData = {
3010
+ activities: activities,
3011
+ aefFile: aefFile,
3012
+ generatedAt: generatedAt,
3013
+ links: links,
3014
+ prefix: prefix,
3015
+ resources: resources,
3016
+ schema: schema,
3017
+ warnings: warnings
3018
+ };
3019
+
3020
+ class WxCCFlowchartPageComponent {
3021
+ constructor(api, wxcc2graph) {
3022
+ this.api = api;
3023
+ this.wxcc2graph = wxcc2graph;
3024
+ this.customerId = 0;
3025
+ this.host = "";
3026
+ this.token = "";
3027
+ this.destroy$ = new Subject();
3028
+ this.state = {
3029
+ loading: true
3030
+ };
3031
+ }
3032
+ ngOnInit() {
3033
+ this.subscribeToCustomerChanges();
3034
+ }
3035
+ ngOnDestroy() {
3036
+ this.destroy$.next();
3037
+ this.destroy$.complete();
3038
+ }
3039
+ init() {
3040
+ this.loadMockFlowchart();
3041
+ }
3042
+ subscribeToCustomerChanges() {
3043
+ // if (!this.customer) {
3044
+ // this.customersService.customer$
3045
+ // .pipe(takeUntil(this.destroy$))
3046
+ // .subscribe((customer) => {
3047
+ // if (customer) {
3048
+ this.init();
3049
+ // }
3050
+ // });
3051
+ // } else {
3052
+ // this.init();
3053
+ // }
3054
+ }
3055
+ loadMockFlowchart() {
3056
+ const irDoc = irData;
3057
+ this.state.irDoc = irDoc;
3058
+ this.state.flowchart = this.wxcc2graph.parseWxCC(irDoc);
3059
+ this.setLoading(false);
3060
+ }
3061
+ loadFileNames() {
3062
+ // forkJoin([
3063
+ // this.uccxWorkflowApi.fetchFileNames(this.customerId)
3064
+ // .pipe(filter(fileNames => fileNames && fileNames.length > 0)),
3065
+ // this.contactCenterService.getCallFlowMigrationStatuses()
3066
+ // ]).pipe(takeUntil(this.destroy$))
3067
+ // .subscribe(([fileNames, statuses]) => {
3068
+ // this.state.fileNames = fileNames;
3069
+ // this.state.uccxIp = fileNames[0].host;
3070
+ // this.state.selectedFileName = fileNames[0].fileName;
3071
+ // this.state.statuses = statuses.filter(status => status.uccxIp === this.state.uccxIp);
3072
+ // this.state.selectedFileStatus = this.getStatus(this.state.selectedFileName, this.state.uccxIp);
3073
+ // this.loadWxCCFlowData();
3074
+ // });
3075
+ }
3076
+ loadWxCCFlowData() {
3077
+ forkJoin([
3078
+ this.api.fetchWxCCFlowData(this.baseParams, this.state.selectedFileStatus),
3079
+ this.api.fetchWxCCFlowDataIR(this.baseParams, this.state.selectedFileStatus),
3080
+ ]).pipe(mergeMap(([nonIrDoc, irDoc]) => irDoc !== null ?
3081
+ of({ nonIrDoc, irDoc }) :
3082
+ throwError(() => new Error('No wxcc flow diagram available for this script'))), takeUntil(this.destroy$), finalize$1(() => this.setLoading(false))).subscribe({
3083
+ next: ({ nonIrDoc, irDoc }) => {
3084
+ this.wxcc2graph.setSourceDocuments(irDoc, nonIrDoc);
3085
+ this.state.irDoc = irDoc;
3086
+ this.state.nonIrDoc = nonIrDoc;
3087
+ this.state.flowchart = this.wxcc2graph.parseWxCC(irDoc, nonIrDoc);
3088
+ },
3089
+ error: (error) => {
3090
+ this.state.flowchart = null;
3091
+ this.setError('No wxcc flow diagram available for this script');
3092
+ }
3093
+ });
3094
+ }
3095
+ onSave() {
3096
+ this.setLoading(true);
3097
+ forkJoin([
3098
+ this.api.saveWxCCFlowData(this.baseParams, this.wxcc2graph.wxccNonIRJSON),
3099
+ this.api.saveWxCCFlowDataIR(this.baseParams, this.wxcc2graph.wxccJSON)
3100
+ ]).pipe(takeUntil(this.destroy$), finalize$1(() => this.setLoading(false)), tap(() => {
3101
+ this.state.flowchart = this.wxcc2graph.parseWxCC(this.wxcc2graph.wxccJSON, this.wxcc2graph.wxccNonIRJSON);
3102
+ })).subscribe({
3103
+ next: ([regularResponse, irResponse]) => console.log('Flow data saved as DRAFT', regularResponse, irResponse),
3104
+ error: (error) => console.error('Error while saving wxcc data: ', error)
3105
+ });
3106
+ }
3107
+ onExportNonIr() {
3108
+ if (!this.wxcc2graph.wxccNonIRJSON) {
3109
+ console.error('Non-IR wxcc document is not loaded');
3110
+ return;
3111
+ }
3112
+ const fileStem = (this.state.selectedFileName || 'wxcc-flow').replace(/\.[^/.]+$/, '');
3113
+ const fileName = fileStem + '-non-ir.json';
3114
+ const jsonContent = JSON.stringify(this.wxcc2graph.wxccNonIRJSON, null, 2);
3115
+ const blob = new Blob([jsonContent], { type: 'application/json' });
3116
+ const url = window.URL.createObjectURL(blob);
3117
+ const anchor = document.createElement('a');
3118
+ anchor.href = url;
3119
+ anchor.download = fileName;
3120
+ document.body.appendChild(anchor);
3121
+ anchor.click();
3122
+ document.body.removeChild(anchor);
3123
+ window.URL.revokeObjectURL(url);
3124
+ }
3125
+ onReset() {
3126
+ this.setLoading(true);
3127
+ forkJoin([
3128
+ this.api.resetWxCCFlowData(this.baseParams),
3129
+ this.api.resetWxCCFlowDataIR(this.baseParams)
3130
+ ]).pipe(takeUntil(this.destroy$), finalize$1(() => this.setLoading(false))).subscribe({
3131
+ next: ([nonIrDoc, irDoc]) => {
3132
+ this.wxcc2graph.setSourceDocuments(irDoc, nonIrDoc);
3133
+ this.state.irDoc = irDoc;
3134
+ this.state.nonIrDoc = nonIrDoc;
3135
+ this.state.flowchart = this.wxcc2graph.parseWxCC(irDoc, nonIrDoc);
3136
+ console.log('Flow data reset to original');
3137
+ },
3138
+ error: (error) => {
3139
+ console.error('Error while resetting wxcc data: ', error);
3140
+ }
3141
+ });
3142
+ }
3143
+ onComplete() {
3144
+ this.setLoading(true);
3145
+ forkJoin([
3146
+ this.api.completeWxCCFlowData(this.baseParams, this.wxcc2graph.wxccNonIRJSON),
3147
+ this.api.completeWxCCFlowDataIR(this.baseParams, this.wxcc2graph.wxccJSON)
3148
+ ]).pipe(takeUntil(this.destroy$), finalize$1(() => this.setLoading(false))).subscribe({
3149
+ next: ([regularResponse, irResponse]) => {
3150
+ console.log('Flow data saved as COMPLETED', regularResponse, irResponse);
3151
+ },
3152
+ error: (error) => {
3153
+ console.error('Error while completing wxcc data: ', error);
3154
+ }
3155
+ });
3156
+ }
3157
+ onFileNameSelectionChange(item) {
3158
+ const { fileName, host } = item;
3159
+ this.state.selectedFileName = fileName;
3160
+ this.state.uccxIp = host;
3161
+ this.state.selectedFileStatus = this.getStatus(fileName, this.state.uccxIp);
3162
+ this.setLoading(true);
3163
+ this.loadWxCCFlowData();
3164
+ }
3165
+ getStatus(fileName, uccxIp) {
3166
+ if (!this.state.statuses) {
3167
+ throw Error('File status array is undefined');
3168
+ }
3169
+ const callFlowMigrationStatus = this.state.statuses.find(status => status.uccxIp === uccxIp && status.scriptName === fileName);
3170
+ // if (callFlowMigrationStatus && callFlowMigrationStatus.status) {
3171
+ // return CALL_FLOW_MIGRATION_STATUSES_TO_SCRIPT_STATUS[callFlowMigrationStatus.status];
3172
+ // }
3173
+ }
3174
+ setLoading(loading) {
3175
+ this.state.loading = loading;
3176
+ }
3177
+ setError(error) {
3178
+ this.state.errorMessage = error;
3179
+ }
3180
+ get baseParams() {
3181
+ return {
3182
+ customerId: this.customerId,
3183
+ uccxIp: this.state.uccxIp || '',
3184
+ fileName: this.state.selectedFileName || ''
3185
+ };
3186
+ }
3187
+ }
3188
+ WxCCFlowchartPageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartPageComponent, deps: [{ token: WxCCAPIService }, { token: WxCC2GraphService }], target: i0.ɵɵFactoryTarget.Component });
3189
+ WxCCFlowchartPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: WxCCFlowchartPageComponent, selector: "cc-script-editor", inputs: { customerId: "customerId", host: "host", token: "token" }, ngImport: i0, template: "<div class=\"wxcc-flowchart-wrapper\">\r\n <main class=\"content-box\">\r\n <div class=\"wxcc-flowchart-main\">\r\n <header class=\"wxcc-flowchart-header\">\r\n <wxcc-file-selection-bar\r\n *ngIf=\"state.fileNames && state.fileNames.length\"\r\n [fileNames]=\"state.fileNames\"\r\n [selectedHost]=\"state.uccxIp\"\r\n [selectedFileName]=\"state.selectedFileName\"\r\n (fileNameSelectionChange)=\"onFileNameSelectionChange($event)\">\r\n </wxcc-file-selection-bar>\r\n <wxcc-actions-bar\r\n *ngIf=\"state.flowchart\"\r\n (save)=\"onSave()\"\r\n (reset)=\"onReset()\"\r\n (exportNonIr)=\"onExportNonIr()\"\r\n (complete)=\"onComplete()\">\r\n </wxcc-actions-bar>\r\n </header>\r\n <ng-container *ngIf=\"!state.loading; else loadingTemplate\">\r\n <wxcc-flowchart\r\n *ngIf=\"state.flowchart; else errorTemplate\"\r\n [flowchart]=\"state.flowchart\">\r\n </wxcc-flowchart>\r\n </ng-container>\r\n </div>\r\n </main>\r\n</div>\r\n\r\n<ng-template #loadingTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n <mat-spinner diameter=\"40\"></mat-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n Error loading script\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;width:100%;height:100%}.wxcc-flowchart-wrapper{width:100%;height:100%;display:flex;flex-direction:column}.wxcc-flowchart-wrapper .content-box{flex:1;display:flex;flex-direction:column;overflow:hidden}.wxcc-flowchart-wrapper .wxcc-flowchart-main{flex:1;display:flex;flex-direction:column;gap:.5rem;overflow:hidden}.wxcc-flowchart-wrapper .wxcc-flowchart-main .wxcc-flowchart-header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.wxcc-flowchart-wrapper .wxcc-flowchart-main .placeholder-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: WxCCFlowchartComponent, selector: "wxcc-flowchart", inputs: ["flowchart"] }, { kind: "component", type: WxCCFileSelectionBarComponent, selector: "wxcc-file-selection-bar", inputs: ["fileNames", "selectedFileName", "selectedHost"], outputs: ["fileNameSelectionChange"] }, { kind: "component", type: WxCCActionsBarComponent, selector: "wxcc-actions-bar", outputs: ["save", "reset", "complete", "exportNonIr"] }] });
3190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartPageComponent, decorators: [{
3191
+ type: Component,
3192
+ args: [{ selector: 'cc-script-editor', template: "<div class=\"wxcc-flowchart-wrapper\">\r\n <main class=\"content-box\">\r\n <div class=\"wxcc-flowchart-main\">\r\n <header class=\"wxcc-flowchart-header\">\r\n <wxcc-file-selection-bar\r\n *ngIf=\"state.fileNames && state.fileNames.length\"\r\n [fileNames]=\"state.fileNames\"\r\n [selectedHost]=\"state.uccxIp\"\r\n [selectedFileName]=\"state.selectedFileName\"\r\n (fileNameSelectionChange)=\"onFileNameSelectionChange($event)\">\r\n </wxcc-file-selection-bar>\r\n <wxcc-actions-bar\r\n *ngIf=\"state.flowchart\"\r\n (save)=\"onSave()\"\r\n (reset)=\"onReset()\"\r\n (exportNonIr)=\"onExportNonIr()\"\r\n (complete)=\"onComplete()\">\r\n </wxcc-actions-bar>\r\n </header>\r\n <ng-container *ngIf=\"!state.loading; else loadingTemplate\">\r\n <wxcc-flowchart\r\n *ngIf=\"state.flowchart; else errorTemplate\"\r\n [flowchart]=\"state.flowchart\">\r\n </wxcc-flowchart>\r\n </ng-container>\r\n </div>\r\n </main>\r\n</div>\r\n\r\n<ng-template #loadingTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n <mat-spinner diameter=\"40\"></mat-spinner>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #errorTemplate>\r\n <div class=\"placeholder-wrapper\">\r\n Error loading script\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block;width:100%;height:100%}.wxcc-flowchart-wrapper{width:100%;height:100%;display:flex;flex-direction:column}.wxcc-flowchart-wrapper .content-box{flex:1;display:flex;flex-direction:column;overflow:hidden}.wxcc-flowchart-wrapper .wxcc-flowchart-main{flex:1;display:flex;flex-direction:column;gap:.5rem;overflow:hidden}.wxcc-flowchart-wrapper .wxcc-flowchart-main .wxcc-flowchart-header{display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.wxcc-flowchart-wrapper .wxcc-flowchart-main .placeholder-wrapper{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"] }]
3193
+ }], ctorParameters: function () { return [{ type: WxCCAPIService }, { type: WxCC2GraphService }]; }, propDecorators: { customerId: [{
3194
+ type: Input
3195
+ }], host: [{
3196
+ type: Input
3197
+ }], token: [{
3198
+ type: Input
3199
+ }] } });
3200
+
3201
+ class MaterialModule {
3202
+ }
3203
+ MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3204
+ MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
3205
+ MatTooltipModule,
3206
+ MatTableModule,
3207
+ MatCheckboxModule,
3208
+ MatButtonModule,
3209
+ MatIconModule,
3210
+ MatFormFieldModule,
3211
+ MatInputModule,
3212
+ MatSelectModule], exports: [MatProgressBarModule,
3213
+ MatTooltipModule,
3214
+ MatTableModule,
3215
+ MatCheckboxModule,
3216
+ MatButtonModule,
3217
+ MatIconModule,
3218
+ MatFormFieldModule,
3219
+ MatInputModule,
3220
+ MatSelectModule,
3221
+ MatProgressSpinnerModule] });
3222
+ MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, imports: [MatProgressBarModule,
3223
+ MatTooltipModule,
3224
+ MatTableModule,
3225
+ MatCheckboxModule,
3226
+ MatButtonModule,
3227
+ MatIconModule,
3228
+ MatFormFieldModule,
3229
+ MatInputModule,
3230
+ MatSelectModule, MatProgressBarModule,
3231
+ MatTooltipModule,
3232
+ MatTableModule,
3233
+ MatCheckboxModule,
3234
+ MatButtonModule,
3235
+ MatIconModule,
3236
+ MatFormFieldModule,
3237
+ MatInputModule,
3238
+ MatSelectModule,
3239
+ MatProgressSpinnerModule] });
3240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MaterialModule, decorators: [{
3241
+ type: NgModule,
3242
+ args: [{
3243
+ imports: [
3244
+ MatProgressBarModule,
3245
+ MatTooltipModule,
3246
+ MatTableModule,
3247
+ MatCheckboxModule,
3248
+ MatButtonModule,
3249
+ MatIconModule,
3250
+ MatFormFieldModule,
3251
+ MatInputModule,
3252
+ MatSelectModule
3253
+ ],
3254
+ exports: [
3255
+ MatProgressBarModule,
3256
+ MatTooltipModule,
3257
+ MatTableModule,
3258
+ MatCheckboxModule,
3259
+ MatButtonModule,
3260
+ MatIconModule,
3261
+ MatFormFieldModule,
3262
+ MatInputModule,
3263
+ MatSelectModule,
3264
+ MatProgressSpinnerModule
3265
+ ]
3266
+ }]
3267
+ }] });
3268
+
3269
+ class SharedModule {
3270
+ }
3271
+ SharedModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3272
+ SharedModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, imports: [CommonModule,
3273
+ MaterialModule,
3274
+ NgApexchartsModule,
3275
+ HttpClientModule], exports: [MaterialModule] });
3276
+ SharedModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, imports: [CommonModule,
3277
+ MaterialModule,
3278
+ NgApexchartsModule,
3279
+ HttpClientModule, MaterialModule] });
3280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SharedModule, decorators: [{
3281
+ type: NgModule,
3282
+ args: [{
3283
+ declarations: [],
3284
+ imports: [
3285
+ CommonModule,
3286
+ MaterialModule,
3287
+ NgApexchartsModule,
3288
+ HttpClientModule
3289
+ ],
3290
+ exports: [
3291
+ MaterialModule
3292
+ ]
3293
+ }]
3294
+ }] });
3295
+
3296
+ class FloatingToolbarModule {
3297
+ }
3298
+ FloatingToolbarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolbarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3299
+ FloatingToolbarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolbarModule, declarations: [FloatingToolBarComponent], imports: [CommonModule,
3300
+ MatTooltipModule], exports: [FloatingToolBarComponent] });
3301
+ FloatingToolbarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolbarModule, imports: [CommonModule,
3302
+ MatTooltipModule] });
3303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FloatingToolbarModule, decorators: [{
3304
+ type: NgModule,
3305
+ args: [{
3306
+ declarations: [
3307
+ FloatingToolBarComponent
3308
+ ],
3309
+ imports: [
3310
+ CommonModule,
3311
+ MatTooltipModule
3312
+ ],
3313
+ exports: [
3314
+ FloatingToolBarComponent
3315
+ ]
3316
+ }]
3317
+ }] });
3318
+
3319
+ class WxCCFlowchartModule {
3320
+ }
3321
+ WxCCFlowchartModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3322
+ WxCCFlowchartModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartModule, declarations: [WxCCFlowchartPageComponent,
3323
+ WxCCFlowchartComponent,
3324
+ NodeDetailsSidebarComponent,
3325
+ NodeActionToolbarComponent,
3326
+ LinkNodeDialogComponent,
3327
+ WxCCFileSelectionBarComponent,
3328
+ AddNodeDialogComponent,
3329
+ WxCCActionsBarComponent,
3330
+ NodeSearchPanelComponent], imports: [CommonModule,
3331
+ FormsModule,
3332
+ SharedModule,
3333
+ MaterialModule,
3334
+ FloatingToolbarModule], exports: [WxCCFlowchartPageComponent] });
3335
+ WxCCFlowchartModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartModule, providers: [
3336
+ WxCCAPIService,
3337
+ WxCC2GraphService,
3338
+ WxCCActivityManageService,
3339
+ WxCCActivityCreationService
3340
+ ], imports: [CommonModule,
3341
+ FormsModule,
3342
+ SharedModule,
3343
+ MaterialModule,
3344
+ FloatingToolbarModule] });
3345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: WxCCFlowchartModule, decorators: [{
3346
+ type: NgModule,
3347
+ args: [{
3348
+ declarations: [
3349
+ WxCCFlowchartPageComponent,
3350
+ WxCCFlowchartComponent,
3351
+ NodeDetailsSidebarComponent,
3352
+ NodeActionToolbarComponent,
3353
+ LinkNodeDialogComponent,
3354
+ WxCCFileSelectionBarComponent,
3355
+ AddNodeDialogComponent,
3356
+ WxCCActionsBarComponent,
3357
+ NodeSearchPanelComponent
3358
+ ],
3359
+ imports: [
3360
+ CommonModule,
3361
+ FormsModule,
3362
+ SharedModule,
3363
+ MaterialModule,
3364
+ FloatingToolbarModule
3365
+ ],
3366
+ exports: [
3367
+ WxCCFlowchartPageComponent
3368
+ ],
3369
+ providers: [
3370
+ WxCCAPIService,
3371
+ WxCC2GraphService,
3372
+ WxCCActivityManageService,
3373
+ WxCCActivityCreationService
3374
+ ],
3375
+ entryComponents: [
3376
+ AddNodeDialogComponent,
3377
+ LinkNodeDialogComponent
3378
+ ]
3379
+ }]
3380
+ }] });
3381
+
437
3382
  /**
438
3383
  * Generated bundle index. Do not edit.
439
3384
  */
440
3385
 
441
- export { CcReadinessModule, LicencesRequirementComponent, SummaryGridComponent };
3386
+ export { CcReadinessModule, LicencesRequirementComponent, SummaryGridComponent, WxCCFlowchartModule, WxCCFlowchartPageComponent };
442
3387
  //# sourceMappingURL=tuki-io-tuki-widgets-contact-center.mjs.map