@pega/sdk 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/package.json +1 -1
  2. package/templates/angular-sdk-reference/angular.json +2 -1
  3. package/templates/angular-sdk-reference/package.json +1 -0
  4. package/templates/angular-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
  5. package/templates/angular-sdk-reference/src/app/app.component.ts +232 -15
  6. package/templates/angular-sdk-reference/src/components/component-map.ts +90 -0
  7. package/templates/angular-sdk-reference/src/components/fields/auto-complete/auto-complete.component.ts +267 -0
  8. package/templates/angular-sdk-reference/src/components/fields/checkbox/checkbox.component.ts +84 -0
  9. package/templates/angular-sdk-reference/src/components/fields/currency/currency.component.ts +97 -0
  10. package/templates/angular-sdk-reference/src/components/fields/date-input/date-input.component.ts +88 -0
  11. package/templates/angular-sdk-reference/src/components/fields/dropdown/dropdown.component.ts +101 -0
  12. package/templates/angular-sdk-reference/src/components/fields/email/email.component.ts +91 -0
  13. package/templates/angular-sdk-reference/src/components/fields/integer/integer.component.ts +93 -0
  14. package/templates/angular-sdk-reference/src/components/fields/phone/phone.component.ts +91 -0
  15. package/templates/angular-sdk-reference/src/components/fields/radio-buttons/radio-buttons.component.ts +102 -0
  16. package/templates/angular-sdk-reference/src/components/fields/text-area/text-area.component.ts +98 -0
  17. package/templates/angular-sdk-reference/src/components/fields/text-input/text-input.component.ts +97 -0
  18. package/templates/angular-sdk-reference/src/components/fields/url-input/url-input.component.ts +94 -0
  19. package/templates/angular-sdk-reference/src/components/infra/assignment/assignment.component.ts +206 -0
  20. package/templates/angular-sdk-reference/src/components/infra/case-summary/case-summary.component.ts +76 -0
  21. package/templates/angular-sdk-reference/src/components/infra/case-view/case-view.component.ts +114 -0
  22. package/templates/angular-sdk-reference/src/components/infra/flow-container/flow-container.component.ts +411 -0
  23. package/templates/angular-sdk-reference/src/components/infra/reference/reference.component.ts +158 -0
  24. package/templates/angular-sdk-reference/src/components/infra/region/region.component.ts +39 -0
  25. package/templates/angular-sdk-reference/src/components/infra/root-container/root-container.component.ts +193 -0
  26. package/templates/angular-sdk-reference/src/components/infra/stages/stages.component.ts +78 -0
  27. package/templates/angular-sdk-reference/src/components/infra/view/view.component.ts +139 -0
  28. package/templates/angular-sdk-reference/src/components/infra/view-container/view-container.component.ts +191 -0
  29. package/templates/angular-sdk-reference/src/components/templates/default-form/default-form.component.ts +101 -0
  30. package/templates/angular-sdk-reference/src/components/templates/narrow-wide/narrow-wide.component.ts +37 -0
  31. package/templates/angular-sdk-reference/src/components/templates/one-column/one-column.component.ts +37 -0
  32. package/templates/angular-sdk-reference/src/components/templates/two-column/two-column.component.ts +37 -0
  33. package/templates/angular-sdk-reference/src/components/templates/wide-narrow/wide-narrow.component.ts +37 -0
  34. package/templates/angular-sdk-reference/src/helpers/event-utils.ts +18 -0
  35. package/templates/angular-sdk-reference/src/helpers/utils.ts +38 -0
  36. package/templates/angular-sdk-reference/src/helpers/versionHelpers.ts +14 -0
  37. package/templates/angular-sdk-reference/tsconfig.json +5 -2
  38. package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +11 -4
  39. package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +7 -0
  40. package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +3 -1
  41. package/templates/react-sdk-reference/.ai-common/skills/field-components.md +75 -29
  42. package/templates/react-sdk-reference/.ai-common/skills/field-skills/AutoComplete.md +133 -101
  43. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedData.md +385 -0
  44. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedDataMulti.md +506 -0
  45. package/templates/react-sdk-reference/.ai-common/skills/field-skills/ObjectReference.md +549 -86
  46. package/templates/react-sdk-reference/.ai-common/skills/field-skills/UserReference.md +181 -83
  47. package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListView.md +125 -153
  48. package/templates/react-sdk-reference/.ai-common/skills/template-skills/SimpleTable.md +90 -81
@@ -0,0 +1,102 @@
1
+ /**
2
+ * RadioButtons — radio button group field.
3
+ *
4
+ * Pattern reference: sdk-react RadioButtons
5
+ */
6
+
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ import { Component, Input } from '@angular/core';
9
+ import type { OnInit, OnChanges, SimpleChanges } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { handleEvent } from '../../../helpers/event-utils';
12
+
13
+ @Component({
14
+ selector: 'pega-radio-buttons',
15
+ standalone: true,
16
+ imports: [CommonModule],
17
+ template: `
18
+ <div *ngIf="!readOnly" style="margin-bottom: 1rem;">
19
+ <fieldset style="border: none; padding: 0; margin: 0;">
20
+ <legend *ngIf="label" style="display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem;">
21
+ {{ label }}<span *ngIf="required" style="color: #dc2626; margin-left: 0.25rem;">*</span>
22
+ </legend>
23
+ <div style="display: flex; flex-direction: column; gap: 0.5rem;">
24
+ <label
25
+ *ngFor="let opt of options"
26
+ style="display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; cursor: pointer;"
27
+ >
28
+ <input
29
+ type="radio"
30
+ [attr.data-testid]="testId"
31
+ [name]="propName"
32
+ [value]="opt.value"
33
+ [checked]="opt.value === value"
34
+ [disabled]="disabled"
35
+ (change)="onRadioChange($event)"
36
+ />
37
+ {{ opt.text || opt.value }}
38
+ </label>
39
+ </div>
40
+ </fieldset>
41
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
42
+ {{ validatemessage }}
43
+ </div>
44
+ </div>
45
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
46
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
47
+ <div style="font-size: 0.875rem;">{{ displayValue }}</div>
48
+ </div>
49
+ `,
50
+ })
51
+ export class RadioButtonsComponent implements OnInit, OnChanges {
52
+ @Input() props: any;
53
+
54
+ label = '';
55
+ value: any = '';
56
+ testId = '';
57
+ required = false;
58
+ disabled = false;
59
+ readOnly = false;
60
+ validatemessage = '';
61
+ options: Array<{ value: string; text?: string }> = [];
62
+ displayValue = '';
63
+ propName = '';
64
+
65
+ private actions: any;
66
+
67
+ ngOnInit(): void {
68
+ this.updateFromProps();
69
+ }
70
+
71
+ ngOnChanges(changes: SimpleChanges): void {
72
+ if (changes['props']) {
73
+ this.updateFromProps();
74
+ }
75
+ }
76
+
77
+ private updateFromProps(): void {
78
+ const p = this.props;
79
+ this.label = p.label ?? '';
80
+ this.value = p.value ?? '';
81
+ this.testId = p.testId ?? '';
82
+ this.required = p.required ?? false;
83
+ this.disabled = p.disabled ?? false;
84
+ this.readOnly = p.readOnly ?? false;
85
+ this.validatemessage = p.validatemessage ?? '';
86
+ this.options = Array.isArray(p.datasource) ? p.datasource : [];
87
+
88
+ const match = this.options.find((o) => o.value === this.value);
89
+ this.displayValue = match?.text ?? match?.value ?? String(this.value);
90
+
91
+ const pConn = p.getPConnect?.();
92
+ this.actions = pConn?.getActionsApi?.();
93
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
94
+ }
95
+
96
+ onRadioChange(event: Event): void {
97
+ const target = event.target as HTMLInputElement;
98
+ if (this.actions && this.propName) {
99
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * TextArea — multi-line text input field.
3
+ *
4
+ * Pattern reference: sdk-react TextArea
5
+ */
6
+
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ import { Component, Input } from '@angular/core';
9
+ import type { OnInit, OnChanges, SimpleChanges } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { FormsModule } from '@angular/forms';
12
+ import { handleEvent } from '../../../helpers/event-utils';
13
+
14
+ @Component({
15
+ selector: 'pega-text-area',
16
+ standalone: true,
17
+ imports: [CommonModule, FormsModule],
18
+ template: `
19
+ <div *ngIf="!readOnly" style="margin-bottom: 1rem;">
20
+ <label *ngIf="label" style="display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem;">
21
+ {{ label }}<span *ngIf="required" style="color: #dc2626; margin-left: 0.25rem;">*</span>
22
+ </label>
23
+ <textarea
24
+ [attr.data-testid]="testId"
25
+ [value]="value"
26
+ [placeholder]="placeholder"
27
+ [disabled]="disabled"
28
+ [required]="required"
29
+ (change)="onChange($event)"
30
+ (blur)="onBlur($event)"
31
+ rows="3"
32
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem; resize: vertical;"
33
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
34
+ >
35
+ </textarea>
36
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
37
+ {{ validatemessage }}
38
+ </div>
39
+ </div>
40
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
41
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
42
+ <div style="font-size: 0.875rem; white-space: pre-wrap;">{{ value }}</div>
43
+ </div>
44
+ `,
45
+ })
46
+ export class TextAreaComponent implements OnInit, OnChanges {
47
+ @Input() props: any;
48
+
49
+ label = '';
50
+ value = '';
51
+ placeholder = '';
52
+ testId = '';
53
+ required = false;
54
+ disabled = false;
55
+ readOnly = false;
56
+ validatemessage = '';
57
+
58
+ private actions: any;
59
+ private propName = '';
60
+
61
+ ngOnInit(): void {
62
+ this.updateFromProps();
63
+ }
64
+
65
+ ngOnChanges(changes: SimpleChanges): void {
66
+ if (changes['props']) {
67
+ this.updateFromProps();
68
+ }
69
+ }
70
+
71
+ private updateFromProps(): void {
72
+ const p = this.props;
73
+ this.label = p.label ?? '';
74
+ this.value = p.value ?? '';
75
+ this.placeholder = p.placeholder ?? '';
76
+ this.testId = p.testId ?? '';
77
+ this.required = p.required ?? false;
78
+ this.disabled = p.disabled ?? false;
79
+ this.readOnly = p.readOnly ?? false;
80
+ this.validatemessage = p.validatemessage ?? '';
81
+
82
+ const pConn = p.getPConnect?.();
83
+ this.actions = pConn?.getActionsApi?.();
84
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
85
+ }
86
+
87
+ onChange(event: Event): void {
88
+ const target = event.target as HTMLTextAreaElement;
89
+ this.value = target.value;
90
+ }
91
+
92
+ onBlur(event: Event): void {
93
+ const target = event.target as HTMLTextAreaElement;
94
+ if (this.actions && this.propName) {
95
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * TextInput — standard text input field.
3
+ *
4
+ * Pattern reference: angular-sdk-components TextInputComponent + sdk-react TextInput
5
+ */
6
+
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ import { Component, Input } from '@angular/core';
9
+ import type { OnInit, OnChanges, SimpleChanges } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { FormsModule } from '@angular/forms';
12
+ import { handleEvent } from '../../../helpers/event-utils';
13
+
14
+ @Component({
15
+ selector: 'pega-text-input',
16
+ standalone: true,
17
+ imports: [CommonModule, FormsModule],
18
+ template: `
19
+ <div *ngIf="!readOnly" style="margin-bottom: 1rem;">
20
+ <label *ngIf="label" style="display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem;">
21
+ {{ label }}<span *ngIf="required" style="color: #dc2626; margin-left: 0.25rem;">*</span>
22
+ </label>
23
+ <input
24
+ type="text"
25
+ [attr.data-testid]="testId"
26
+ [value]="value"
27
+ [placeholder]="placeholder"
28
+ [disabled]="disabled"
29
+ [required]="required"
30
+ (change)="onChange($event)"
31
+ (blur)="onBlur($event)"
32
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem;"
33
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
34
+ />
35
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
36
+ {{ validatemessage }}
37
+ </div>
38
+ </div>
39
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
40
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
41
+ <div style="font-size: 0.875rem;">{{ value }}</div>
42
+ </div>
43
+ `,
44
+ })
45
+ export class TextInputComponent implements OnInit, OnChanges {
46
+ @Input() props: any;
47
+
48
+ label = '';
49
+ value = '';
50
+ placeholder = '';
51
+ testId = '';
52
+ required = false;
53
+ disabled = false;
54
+ readOnly = false;
55
+ validatemessage = '';
56
+
57
+ private actions: any;
58
+ private propName = '';
59
+
60
+ ngOnInit(): void {
61
+ this.updateFromProps();
62
+ }
63
+
64
+ ngOnChanges(changes: SimpleChanges): void {
65
+ if (changes['props']) {
66
+ this.updateFromProps();
67
+ }
68
+ }
69
+
70
+ private updateFromProps(): void {
71
+ const p = this.props;
72
+ this.label = p.label ?? '';
73
+ this.value = p.value ?? '';
74
+ this.placeholder = p.placeholder ?? '';
75
+ this.testId = p.testId ?? '';
76
+ this.required = p.required ?? false;
77
+ this.disabled = p.disabled ?? false;
78
+ this.readOnly = p.readOnly ?? false;
79
+ this.validatemessage = p.validatemessage ?? '';
80
+
81
+ const pConn = p.getPConnect?.();
82
+ this.actions = pConn?.getActionsApi?.();
83
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
84
+ }
85
+
86
+ onChange(event: Event): void {
87
+ const target = event.target as HTMLInputElement;
88
+ this.value = target.value;
89
+ }
90
+
91
+ onBlur(event: Event): void {
92
+ const target = event.target as HTMLInputElement;
93
+ if (this.actions && this.propName) {
94
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * URLInput — URL input field.
3
+ *
4
+ * Pattern reference: sdk-react URL
5
+ */
6
+
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ import { Component, Input } from '@angular/core';
9
+ import type { OnInit, OnChanges, SimpleChanges } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { FormsModule } from '@angular/forms';
12
+ import { handleEvent } from '../../../helpers/event-utils';
13
+
14
+ @Component({
15
+ selector: 'pega-url-input',
16
+ standalone: true,
17
+ imports: [CommonModule, FormsModule],
18
+ template: `
19
+ <div *ngIf="!readOnly" style="margin-bottom: 1rem;">
20
+ <label *ngIf="label" style="display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem;">
21
+ {{ label }}<span *ngIf="required" style="color: #dc2626; margin-left: 0.25rem;">*</span>
22
+ </label>
23
+ <input
24
+ type="url"
25
+ [attr.data-testid]="testId"
26
+ [value]="value"
27
+ [placeholder]="placeholder"
28
+ [disabled]="disabled"
29
+ [required]="required"
30
+ (blur)="onBlur($event)"
31
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem;"
32
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
33
+ />
34
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
35
+ {{ validatemessage }}
36
+ </div>
37
+ </div>
38
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
39
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
40
+ <div style="font-size: 0.875rem;">
41
+ <a *ngIf="value" [href]="value" target="_blank" rel="noopener noreferrer">{{ value }}</a>
42
+ <span *ngIf="!value">—</span>
43
+ </div>
44
+ </div>
45
+ `,
46
+ })
47
+ export class URLInputComponent implements OnInit, OnChanges {
48
+ @Input() props: any;
49
+
50
+ label = '';
51
+ value = '';
52
+ placeholder = '';
53
+ testId = '';
54
+ required = false;
55
+ disabled = false;
56
+ readOnly = false;
57
+ validatemessage = '';
58
+
59
+ private actions: any;
60
+ private propName = '';
61
+
62
+ ngOnInit(): void {
63
+ this.updateFromProps();
64
+ }
65
+
66
+ ngOnChanges(changes: SimpleChanges): void {
67
+ if (changes['props']) {
68
+ this.updateFromProps();
69
+ }
70
+ }
71
+
72
+ private updateFromProps(): void {
73
+ const p = this.props;
74
+ this.label = p.label ?? '';
75
+ this.value = p.value ?? '';
76
+ this.placeholder = p.placeholder ?? '';
77
+ this.testId = p.testId ?? '';
78
+ this.required = p.required ?? false;
79
+ this.disabled = p.disabled ?? false;
80
+ this.readOnly = p.readOnly ?? false;
81
+ this.validatemessage = p.validatemessage ?? '';
82
+
83
+ const pConn = p.getPConnect?.();
84
+ this.actions = pConn?.getActionsApi?.();
85
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
86
+ }
87
+
88
+ onBlur(event: Event): void {
89
+ const target = event.target as HTMLInputElement;
90
+ if (this.actions && this.propName) {
91
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Assignment — renders the current assignment step and its action buttons.
3
+ *
4
+ * Receives assignment children (the form to fill) and action buttons from the
5
+ * case's actionButtons metadata. Delegates form rendering to children and
6
+ * handles submit/cancel/save/navigate actions via the actionsAPI.
7
+ *
8
+ * In the component hierarchy, FlowContainer renders Assignment explicitly,
9
+ * passing routed view children and itemKey. Assignment wraps those children
10
+ * with action buttons below — matching the reference angular-sdk pattern.
11
+ *
12
+ * Pattern reference: angular-sdk-components AssignmentComponent + sdk-react Assignment
13
+ */
14
+
15
+ /* eslint-disable @typescript-eslint/no-explicit-any */
16
+ import { Component, Input, ChangeDetectorRef, NgZone } from '@angular/core';
17
+ import type { OnInit, OnDestroy } from '@angular/core';
18
+ import { CommonModule } from '@angular/common';
19
+ import { PConnectBridgeComponent } from '@pega/sdk-angular';
20
+
21
+ @Component({
22
+ selector: 'pega-assignment',
23
+ standalone: true,
24
+ imports: [CommonModule, PConnectBridgeComponent],
25
+ template: `
26
+ <div *ngIf="bReady">
27
+ <!-- Render assignment children (the form) -->
28
+ <div *ngFor="let child of childGetters">
29
+ <pconnect-bridge [getPConnect]="child"></pconnect-bridge>
30
+ </div>
31
+
32
+ <!-- Action buttons -->
33
+ <div
34
+ *ngIf="arMainButtons.length > 0 || arSecondaryButtons.length > 0"
35
+ style="display: flex; gap: 0.5rem; margin-top: 1rem; justify-content: flex-end;"
36
+ >
37
+ <button
38
+ *ngFor="let btn of arSecondaryButtons"
39
+ (click)="buttonPress(btn.jsAction, 'secondary')"
40
+ style="padding: 0.5rem 1rem; border: 1px solid #d1d5db; border-radius: 0.375rem; background: white; cursor: pointer;"
41
+ >
42
+ {{ btn.name }}
43
+ </button>
44
+ <button
45
+ *ngFor="let btn of arMainButtons"
46
+ (click)="buttonPress(btn.jsAction, 'primary')"
47
+ style="padding: 0.5rem 1rem; border: none; border-radius: 0.375rem; background: #2563eb; color: white; cursor: pointer;"
48
+ >
49
+ {{ btn.name }}
50
+ </button>
51
+ </div>
52
+ </div>
53
+ `,
54
+ })
55
+ export class AssignmentComponent implements OnInit, OnDestroy {
56
+ @Input() props: any;
57
+
58
+ bReady = false;
59
+ childGetters: Array<() => typeof PConnect> = [];
60
+ arMainButtons: any[] = [];
61
+ arSecondaryButtons: any[] = [];
62
+
63
+ private pConn: any;
64
+ private actionsAPI: any;
65
+ private itemKey = '';
66
+ private storeUnsub: (() => void) | undefined;
67
+
68
+ constructor(
69
+ private ngZone: NgZone,
70
+ private cdr: ChangeDetectorRef,
71
+ ) {}
72
+
73
+ ngOnInit(): void {
74
+ this.pConn = this.props.getPConnect();
75
+ this.itemKey = this.props.itemKey ?? '';
76
+
77
+ this.initComponent();
78
+
79
+ // Subscribe to store for updates (action buttons may change between steps)
80
+ this.storeUnsub = PCore.getStore().subscribe(() => {
81
+ this.updateSelf();
82
+ });
83
+ }
84
+
85
+ ngOnDestroy(): void {
86
+ this.storeUnsub?.();
87
+ }
88
+
89
+ private initComponent(): void {
90
+ const baseContext = this.pConn.getContextName?.() ?? '';
91
+ const acName = this.pConn.getContainerName?.() ?? '';
92
+ if (!this.itemKey) {
93
+ this.itemKey = `${baseContext}/${acName}`;
94
+ }
95
+
96
+ this.pConn.isBoundToState();
97
+ this.updateSelf();
98
+ }
99
+
100
+ private updateSelf(): void {
101
+ // Children come from FlowContainer's arChildren prop (the routed view PConnect),
102
+ // matching the reference pattern where FlowContainer passes arChildren$ to Assignment.
103
+ const arChildrenFromProps = this.props.arChildren;
104
+ if (arChildrenFromProps && arChildrenFromProps.length > 0) {
105
+ this.childGetters = arChildrenFromProps.map((child: any) => {
106
+ return child.getPConnect ?? (() => child);
107
+ });
108
+ } else {
109
+ // Fallback: get children from pConn
110
+ const children = this.pConn.getChildren?.() ?? [];
111
+ this.childGetters = children.map((child: any) => {
112
+ return child.getPConnect ?? (() => child);
113
+ });
114
+ }
115
+
116
+ // Update itemKey from props if changed
117
+ if (this.props.itemKey) {
118
+ this.itemKey = this.props.itemKey;
119
+ }
120
+
121
+ // Extract action buttons from case data.
122
+ // Reference pattern: Assignment gets caseInfo from its own pConn's data object,
123
+ // and actionsAPI from the first child work item's pConn.
124
+ this.extractActionButtons();
125
+
126
+ this.ngZone.run(() => {
127
+ this.bReady = true;
128
+ this.cdr.detectChanges();
129
+ });
130
+ }
131
+
132
+ private extractActionButtons(): void {
133
+ // Get action buttons from the Assignment's own pConn case data
134
+ const oData = this.pConn.getDataObject?.() ?? {};
135
+ const caseInfo = oData?.caseInfo;
136
+
137
+ if (caseInfo?.actionButtons) {
138
+ this.arMainButtons = caseInfo.actionButtons.main ?? [];
139
+ this.arSecondaryButtons = caseInfo.actionButtons.secondary ?? [];
140
+ }
141
+
142
+ // Get actionsAPI from the Assignment's own pConn (not from child).
143
+ // The Assignment pConn has the correct context for finishAssignment/cancelAssignment.
144
+ try {
145
+ this.actionsAPI = this.pConn.getActionsApi?.() ?? null;
146
+ } catch {
147
+ // actionsApi may not be available
148
+ }
149
+ }
150
+
151
+ buttonPress(sAction: string, sButtonType: string): void {
152
+ if (!this.actionsAPI) return;
153
+
154
+ const finishAssignment = this.actionsAPI.finishAssignment?.bind(
155
+ this.actionsAPI,
156
+ );
157
+ const cancelAssignment = this.actionsAPI.cancelAssignment?.bind(
158
+ this.actionsAPI,
159
+ );
160
+ const navigateToStep = this.actionsAPI.navigateToStep?.bind(
161
+ this.actionsAPI,
162
+ );
163
+ const saveAssignment = this.actionsAPI.saveAssignment?.bind(
164
+ this.actionsAPI,
165
+ );
166
+
167
+ if (sButtonType === 'secondary') {
168
+ switch (sAction) {
169
+ case 'navigateToStep':
170
+ navigateToStep?.('previous', this.itemKey)?.catch(() => {
171
+ console.error('Assignment: Navigation failed');
172
+ });
173
+ break;
174
+ case 'saveAssignment':
175
+ saveAssignment?.(this.itemKey)?.catch(() => {
176
+ console.error('Assignment: Save failed');
177
+ });
178
+ break;
179
+ case 'cancelAssignment': {
180
+ const { PUB_SUB_EVENTS } = PCore.getConstants() as any;
181
+ const { publish } = PCore.getPubSubUtils();
182
+ cancelAssignment?.(this.itemKey, false)
183
+ ?.then((data: any) => {
184
+ publish(PUB_SUB_EVENTS.EVENT_CANCEL, data);
185
+ })
186
+ ?.catch(() => {
187
+ console.error('Assignment: Cancel failed');
188
+ });
189
+ break;
190
+ }
191
+ default:
192
+ break;
193
+ }
194
+ } else if (sButtonType === 'primary') {
195
+ switch (sAction) {
196
+ case 'finishAssignment':
197
+ finishAssignment?.(this.itemKey)?.catch(() => {
198
+ console.error('Assignment: Submit failed');
199
+ });
200
+ break;
201
+ default:
202
+ break;
203
+ }
204
+ }
205
+ }
206
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * CaseSummary — renders case summary header with status badge.
3
+ *
4
+ * Pattern reference: angular-sdk-components CaseSummaryComponent + sdk-react CaseSummary
5
+ */
6
+
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ import { Component, Input, ChangeDetectorRef, NgZone } from '@angular/core';
9
+ import type { OnInit, OnDestroy } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import type { Unsubscribe } from '@pega/sdk-angular';
12
+
13
+ @Component({
14
+ selector: 'pega-case-summary',
15
+ standalone: true,
16
+ imports: [CommonModule],
17
+ template: `
18
+ <div
19
+ style="display: flex; justify-content: space-between; align-items: center;
20
+ padding: 0.75rem 1rem; background: #f9fafb; border-radius: 0.375rem; margin-bottom: 1rem;"
21
+ >
22
+ <span style="font-weight: 600; font-size: 0.875rem;">
23
+ {{ header || 'Case' }}
24
+ </span>
25
+ <span
26
+ *ngIf="status"
27
+ style="font-size: 0.75rem; padding: 0.25rem 0.5rem; background: #dbeafe; color: #1d4ed8; border-radius: 1rem;"
28
+ >
29
+ {{ status }}
30
+ </span>
31
+ </div>
32
+ `,
33
+ })
34
+ export class CaseSummaryComponent implements OnInit, OnDestroy {
35
+ @Input() props: any;
36
+
37
+ header = '';
38
+ status = '';
39
+
40
+ private pConn: any;
41
+ private observable: any;
42
+ private storeUnsub: Unsubscribe | undefined;
43
+
44
+ constructor(
45
+ private ngZone: NgZone,
46
+ private cdr: ChangeDetectorRef,
47
+ ) {}
48
+
49
+ ngOnInit(): void {
50
+ // @ts-ignore
51
+ const { PConnectObservable } = PCore.getInitialiser().getSdkCore() as any;
52
+
53
+ this.pConn = this.props.getPConnect();
54
+ this.observable = new PConnectObservable(this.pConn);
55
+ this.updateSelf();
56
+
57
+ this.storeUnsub = this.observable.subscribe(() => {
58
+ this.updateSelf();
59
+ });
60
+ }
61
+
62
+ ngOnDestroy(): void {
63
+ this.storeUnsub?.();
64
+ this.observable?.destroy();
65
+ }
66
+
67
+ private updateSelf(): void {
68
+ const configProps = this.pConn.resolveConfigProps(this.pConn.getConfigProps());
69
+ this.header = configProps.header ?? '';
70
+ this.status = configProps.status ?? '';
71
+
72
+ this.ngZone.run(() => {
73
+ this.cdr.detectChanges();
74
+ });
75
+ }
76
+ }