@tuki-io/tuki-widgets 0.0.177 → 0.0.179
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contact-center/cc-script-editor/cc-script-editor.component.d.ts +53 -0
- package/contact-center/cc-script-editor/cc-script-editor.module.d.ts +20 -0
- package/contact-center/cc-script-editor/components/dialogs/add-node-dialog/add-node-dialog.component.d.ts +35 -0
- package/contact-center/cc-script-editor/components/dialogs/link-node-dialog/link-node-dialog.component.d.ts +38 -0
- package/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.component.d.ts +34 -0
- package/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.module.d.ts +9 -0
- package/contact-center/cc-script-editor/components/node-action-toolbar/node-action-toolbar.component.d.ts +27 -0
- package/contact-center/cc-script-editor/components/node-details-sidebar/node-details-sidebar.component.d.ts +27 -0
- package/contact-center/cc-script-editor/components/node-search-panel/node-search-panel.component.d.ts +14 -0
- package/contact-center/cc-script-editor/components/wxcc-actions-bar/wxcc-actions-bar.component.d.ts +11 -0
- package/contact-center/cc-script-editor/components/wxcc-file-selection-bar/wxcc-file-selection-bar.component.d.ts +24 -0
- package/contact-center/cc-script-editor/components/wxcc-flowchart/wxcc-flowchart.component.d.ts +66 -0
- package/contact-center/cc-script-editor/constants/cytoscape.config.d.ts +2 -0
- package/contact-center/cc-script-editor/constants/wxcc-api.constants.d.ts +15 -0
- package/contact-center/cc-script-editor/services/wxcc-activity-creation.service.d.ts +21 -0
- package/contact-center/cc-script-editor/services/wxcc-activity-manage.service.d.ts +8 -0
- package/contact-center/cc-script-editor/services/wxcc-flow-api.service.d.ts +43 -0
- package/contact-center/cc-script-editor/services/wxcc2graph.service.d.ts +42 -0
- package/contact-center/cc-script-editor/types/extended-activity.d.ts +47 -0
- package/contact-center/cc-script-editor/types/wxcc-activity.d.ts +96 -0
- package/contact-center/cc-script-editor/types/wxcc.d.ts +161 -0
- package/contact-center/cc-script-editor/utils/node-html-template.d.ts +3 -0
- package/contact-center/cc-script-editor/utils/node-mappings.d.ts +54 -0
- package/contact-center/public-api.d.ts +2 -0
- package/esm2020/contact-center/cc-script-editor/cc-script-editor.component.mjs +193 -0
- package/esm2020/contact-center/cc-script-editor/cc-script-editor.module.mjs +83 -0
- package/esm2020/contact-center/cc-script-editor/components/dialogs/add-node-dialog/add-node-dialog.component.mjs +60 -0
- package/esm2020/contact-center/cc-script-editor/components/dialogs/link-node-dialog/link-node-dialog.component.mjs +83 -0
- package/esm2020/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.component.mjs +104 -0
- package/esm2020/contact-center/cc-script-editor/components/floating-toolbar/floating-toolbar.module.mjs +28 -0
- package/esm2020/contact-center/cc-script-editor/components/node-action-toolbar/node-action-toolbar.component.mjs +65 -0
- package/esm2020/contact-center/cc-script-editor/components/node-details-sidebar/node-details-sidebar.component.mjs +97 -0
- package/esm2020/contact-center/cc-script-editor/components/node-search-panel/node-search-panel.component.mjs +43 -0
- package/esm2020/contact-center/cc-script-editor/components/wxcc-actions-bar/wxcc-actions-bar.component.mjs +27 -0
- package/esm2020/contact-center/cc-script-editor/components/wxcc-file-selection-bar/wxcc-file-selection-bar.component.mjs +61 -0
- package/esm2020/contact-center/cc-script-editor/components/wxcc-flowchart/wxcc-flowchart.component.mjs +434 -0
- package/esm2020/contact-center/cc-script-editor/constants/cytoscape.config.mjs +72 -0
- package/esm2020/contact-center/cc-script-editor/constants/wxcc-api.constants.mjs +14 -0
- package/esm2020/contact-center/cc-script-editor/mock/data/QWC_ir.json +912 -0
- package/esm2020/contact-center/cc-script-editor/services/wxcc-activity-creation.service.mjs +82 -0
- package/esm2020/contact-center/cc-script-editor/services/wxcc-activity-manage.service.mjs +162 -0
- package/esm2020/contact-center/cc-script-editor/services/wxcc-flow-api.service.mjs +79 -0
- package/esm2020/contact-center/cc-script-editor/services/wxcc2graph.service.mjs +144 -0
- package/esm2020/contact-center/cc-script-editor/types/extended-activity.mjs +4 -0
- package/esm2020/contact-center/cc-script-editor/types/wxcc-activity.mjs +2 -0
- package/esm2020/contact-center/cc-script-editor/types/wxcc.mjs +6 -0
- package/esm2020/contact-center/cc-script-editor/utils/node-html-template.mjs +76 -0
- package/esm2020/contact-center/cc-script-editor/utils/node-mappings.mjs +109 -0
- package/esm2020/contact-center/public-api.mjs +3 -1
- package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs +2948 -3
- package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
- package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs +2974 -3
- package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs.map +1 -1
- 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, '<')
|
|
644
|
+
.replace(/>/g, '>')
|
|
645
|
+
.replace(/"/g, '"')
|
|
646
|
+
.replace(/'/g, ''');
|
|
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>×</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>×</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
|