@pega/sdk 0.0.12 → 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 (62) hide show
  1. package/README.md +32 -11
  2. package/package.json +1 -1
  3. package/templates/angular-sdk-reference/angular.json +2 -1
  4. package/templates/angular-sdk-reference/package.json +1 -0
  5. package/templates/angular-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
  6. package/templates/angular-sdk-reference/src/app/app.component.ts +232 -15
  7. package/templates/angular-sdk-reference/src/components/component-map.ts +90 -0
  8. package/templates/angular-sdk-reference/src/components/fields/auto-complete/auto-complete.component.ts +267 -0
  9. package/templates/angular-sdk-reference/src/components/fields/checkbox/checkbox.component.ts +84 -0
  10. package/templates/angular-sdk-reference/src/components/fields/currency/currency.component.ts +97 -0
  11. package/templates/angular-sdk-reference/src/components/fields/date-input/date-input.component.ts +88 -0
  12. package/templates/angular-sdk-reference/src/components/fields/dropdown/dropdown.component.ts +101 -0
  13. package/templates/angular-sdk-reference/src/components/fields/email/email.component.ts +91 -0
  14. package/templates/angular-sdk-reference/src/components/fields/integer/integer.component.ts +93 -0
  15. package/templates/angular-sdk-reference/src/components/fields/phone/phone.component.ts +91 -0
  16. package/templates/angular-sdk-reference/src/components/fields/radio-buttons/radio-buttons.component.ts +102 -0
  17. package/templates/angular-sdk-reference/src/components/fields/text-area/text-area.component.ts +98 -0
  18. package/templates/angular-sdk-reference/src/components/fields/text-input/text-input.component.ts +97 -0
  19. package/templates/angular-sdk-reference/src/components/fields/url-input/url-input.component.ts +94 -0
  20. package/templates/angular-sdk-reference/src/components/infra/assignment/assignment.component.ts +206 -0
  21. package/templates/angular-sdk-reference/src/components/infra/case-summary/case-summary.component.ts +76 -0
  22. package/templates/angular-sdk-reference/src/components/infra/case-view/case-view.component.ts +114 -0
  23. package/templates/angular-sdk-reference/src/components/infra/flow-container/flow-container.component.ts +411 -0
  24. package/templates/angular-sdk-reference/src/components/infra/reference/reference.component.ts +158 -0
  25. package/templates/angular-sdk-reference/src/components/infra/region/region.component.ts +39 -0
  26. package/templates/angular-sdk-reference/src/components/infra/root-container/root-container.component.ts +193 -0
  27. package/templates/angular-sdk-reference/src/components/infra/stages/stages.component.ts +78 -0
  28. package/templates/angular-sdk-reference/src/components/infra/view/view.component.ts +139 -0
  29. package/templates/angular-sdk-reference/src/components/infra/view-container/view-container.component.ts +191 -0
  30. package/templates/angular-sdk-reference/src/components/templates/default-form/default-form.component.ts +101 -0
  31. package/templates/angular-sdk-reference/src/components/templates/narrow-wide/narrow-wide.component.ts +37 -0
  32. package/templates/angular-sdk-reference/src/components/templates/one-column/one-column.component.ts +37 -0
  33. package/templates/angular-sdk-reference/src/components/templates/two-column/two-column.component.ts +37 -0
  34. package/templates/angular-sdk-reference/src/components/templates/wide-narrow/wide-narrow.component.ts +37 -0
  35. package/templates/angular-sdk-reference/src/helpers/event-utils.ts +18 -0
  36. package/templates/angular-sdk-reference/src/helpers/utils.ts +38 -0
  37. package/templates/angular-sdk-reference/src/helpers/versionHelpers.ts +14 -0
  38. package/templates/angular-sdk-reference/tsconfig.json +5 -2
  39. package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +20 -13
  40. package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions-embedded.md +2 -2
  41. package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions.md +1 -1
  42. package/templates/react-sdk-reference/.ai-common/instructions/dse-component.md +1 -1
  43. package/templates/react-sdk-reference/.ai-common/instructions/embedded-component.md +1 -1
  44. package/templates/react-sdk-reference/.ai-common/instructions/field-component.md +1 -1
  45. package/templates/react-sdk-reference/.ai-common/instructions/infra-component.md +1 -1
  46. package/templates/react-sdk-reference/.ai-common/instructions/template-component.md +1 -1
  47. package/templates/react-sdk-reference/.ai-common/instructions/widget-component.md +1 -1
  48. package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +7 -0
  49. package/templates/react-sdk-reference/.ai-common/prompts/embedded-component-manifest.md +2 -2
  50. package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +4 -2
  51. package/templates/react-sdk-reference/.ai-common/prompts/generate-embedded-components.md +10 -11
  52. package/templates/react-sdk-reference/.ai-common/skills/connect-pega-server.md +84 -31
  53. package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/analyze-customer-repo.md +11 -2
  54. package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/wire-integration.md +6 -6
  55. package/templates/react-sdk-reference/.ai-common/skills/field-components.md +75 -29
  56. package/templates/react-sdk-reference/.ai-common/skills/field-skills/AutoComplete.md +133 -101
  57. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedData.md +385 -0
  58. package/templates/react-sdk-reference/.ai-common/skills/field-skills/EmbeddedDataMulti.md +506 -0
  59. package/templates/react-sdk-reference/.ai-common/skills/field-skills/ObjectReference.md +549 -86
  60. package/templates/react-sdk-reference/.ai-common/skills/field-skills/UserReference.md +181 -83
  61. package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListView.md +125 -153
  62. package/templates/react-sdk-reference/.ai-common/skills/template-skills/SimpleTable.md +90 -81
@@ -0,0 +1,267 @@
1
+ /**
2
+ * AutoComplete — typeahead/autocomplete field.
3
+ *
4
+ * Supports associated lists (options from datasource prop) and data page lists
5
+ * (options fetched via PCore.getDataPageUtils). Also handles deferDatasource mode
6
+ * where datasourceMetadata transforms into a data page call.
7
+ *
8
+ * Pattern reference: angular-sdk-components AutoCompleteComponent + sdk-react AutoComplete
9
+ */
10
+
11
+ /* eslint-disable @typescript-eslint/no-explicit-any */
12
+ import { Component, Input } from '@angular/core';
13
+ import type { OnInit, OnChanges, SimpleChanges } from '@angular/core';
14
+ import { CommonModule } from '@angular/common';
15
+ import { FormsModule } from '@angular/forms';
16
+ import { handleEvent } from '../../../helpers/event-utils';
17
+ import { getOptionList } from '../../../helpers/utils';
18
+
19
+ interface IOption {
20
+ key: string;
21
+ value: string;
22
+ }
23
+
24
+ @Component({
25
+ selector: 'pega-auto-complete',
26
+ standalone: true,
27
+ imports: [CommonModule, FormsModule],
28
+ template: `
29
+ <!-- Read-only / display mode -->
30
+ <div *ngIf="readOnly || isDisplayMode" style="margin-bottom: 1rem;">
31
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
32
+ <div style="font-size: 0.875rem;">{{ displayValue }}</div>
33
+ </div>
34
+
35
+ <!-- Editable mode -->
36
+ <div *ngIf="!readOnly && !isDisplayMode" style="margin-bottom: 1rem; position: relative;">
37
+ <label *ngIf="label" style="display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem;">
38
+ {{ label }}<span *ngIf="required" style="color: #dc2626; margin-left: 0.25rem;">*</span>
39
+ </label>
40
+ <input
41
+ type="text"
42
+ [attr.data-testid]="testId"
43
+ [value]="inputValue"
44
+ [placeholder]="placeholder"
45
+ [disabled]="disabled"
46
+ [required]="required"
47
+ (input)="onInput($event)"
48
+ (focus)="showDropdown = true"
49
+ (blur)="onBlur()"
50
+ autocomplete="off"
51
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem; box-sizing: border-box;"
52
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
53
+ />
54
+ <!-- Dropdown list -->
55
+ <ul
56
+ *ngIf="showDropdown && filteredOptions.length > 0"
57
+ style="position: absolute; z-index: 10; width: 100%; max-height: 12rem; overflow-y: auto; background: #fff; border: 1px solid #d1d5db; border-radius: 0.375rem; margin-top: 0.125rem; padding: 0; list-style: none; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);"
58
+ >
59
+ <li
60
+ *ngFor="let opt of filteredOptions"
61
+ (mousedown)="selectOption(opt)"
62
+ style="padding: 0.5rem 0.75rem; cursor: pointer; font-size: 0.875rem;"
63
+ >
64
+ {{ opt.value }}
65
+ </li>
66
+ </ul>
67
+ <div
68
+ *ngIf="helperTextToDisplay"
69
+ style="font-size: 0.75rem; margin-top: 0.25rem;"
70
+ [style.color]="validatemessage ? '#dc2626' : '#6b7280'"
71
+ >
72
+ {{ helperTextToDisplay }}
73
+ </div>
74
+ </div>
75
+ `,
76
+ })
77
+ export class AutoCompleteComponent implements OnInit, OnChanges {
78
+ @Input() props: any;
79
+
80
+ label = '';
81
+ value = '';
82
+ placeholder = '';
83
+ testId = '';
84
+ required = false;
85
+ disabled = false;
86
+ readOnly = false;
87
+ validatemessage = '';
88
+ helperText = '';
89
+ isDisplayMode = false;
90
+ displayValue = '';
91
+ inputValue = '';
92
+ showDropdown = false;
93
+ options: IOption[] = [];
94
+ filteredOptions: IOption[] = [];
95
+ helperTextToDisplay = '';
96
+
97
+ private actions: any;
98
+ private propName = '';
99
+ private pConn: any;
100
+ private listType = '';
101
+
102
+ ngOnInit(): void {
103
+ this.updateFromProps();
104
+ this.loadOptions();
105
+ }
106
+
107
+ ngOnChanges(changes: SimpleChanges): void {
108
+ if (changes['props']) {
109
+ this.updateFromProps();
110
+ this.loadOptions();
111
+ }
112
+ }
113
+
114
+ private updateFromProps(): void {
115
+ const p = this.props;
116
+ this.label = p.label ?? '';
117
+ this.value = p.value ?? '';
118
+ this.placeholder = p.placeholder ?? '';
119
+ this.testId = p.testId ?? '';
120
+ this.required = p.required ?? false;
121
+ this.disabled = p.disabled ?? false;
122
+ this.readOnly = p.readOnly ?? false;
123
+ this.validatemessage = p.validatemessage ?? '';
124
+ this.helperText = p.helperText ?? '';
125
+ this.helperTextToDisplay = this.validatemessage || this.helperText;
126
+ this.isDisplayMode = p.displayMode === 'DISPLAY_ONLY' || p.displayMode === 'STACKED_LARGE_VAL';
127
+
128
+ this.pConn = p.getPConnect?.();
129
+ this.actions = this.pConn?.getActionsApi?.();
130
+ this.propName = ((this.pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
131
+
132
+ // Resolve display value from current options
133
+ this.updateDisplayValue();
134
+ }
135
+
136
+ private updateDisplayValue(): void {
137
+ const match = this.options.find((o) => o.key === this.value);
138
+ this.displayValue = match?.value ?? this.value ?? '';
139
+ if (!this.inputValue || this.inputValue !== this.displayValue) {
140
+ this.inputValue = this.displayValue;
141
+ }
142
+ this.filterOptions();
143
+ }
144
+
145
+ private filterOptions(): void {
146
+ const text = (this.inputValue ?? '').toLowerCase();
147
+ this.filteredOptions = text ? this.options.filter((o) => o.value?.toLowerCase().includes(text)) : [...this.options];
148
+ }
149
+
150
+ private loadOptions(): void {
151
+ const p = this.props;
152
+ let { listType, parameters, datasource, columns = [] } = p;
153
+
154
+ // Handle deferDatasource
155
+ if (p.deferDatasource && p.datasourceMetadata?.datasource?.name) {
156
+ listType = 'datapage';
157
+ datasource = p.datasourceMetadata.datasource.name;
158
+ const meta = p.datasourceMetadata.datasource;
159
+ parameters = this.flattenParameters(meta.parameters);
160
+ const displayProp = meta.propertyForDisplayText?.startsWith('@P')
161
+ ? meta.propertyForDisplayText.substring(3)
162
+ : meta.propertyForDisplayText;
163
+ const valueProp = meta.propertyForValue?.startsWith('@P')
164
+ ? meta.propertyForValue.substring(3)
165
+ : meta.propertyForValue;
166
+ columns = [
167
+ { key: 'true', setProperty: 'Associated property', value: valueProp },
168
+ {
169
+ display: 'true',
170
+ primary: 'true',
171
+ useForSearch: 'true',
172
+ value: displayProp,
173
+ },
174
+ ];
175
+ }
176
+
177
+ this.listType = listType ?? '';
178
+ const processedColumns = this.preProcessColumns(columns ?? []);
179
+
180
+ if (this.listType === 'associated') {
181
+ const dataObject = this.pConn?.getDataObject?.('') ?? {};
182
+ const optList = getOptionList(p as Record<string, unknown>, dataObject as Record<string, unknown>);
183
+ this.setOptions(optList.map((o) => ({ key: o.value, value: o.text ?? o.value })));
184
+ } else if (this.listType === 'datapage' && datasource) {
185
+ const context = this.pConn?.getContextName?.() ?? '';
186
+ const flatParams =
187
+ typeof parameters === 'object' && !Array.isArray(parameters) ? this.flattenParameters(parameters) : {};
188
+ (PCore.getDataPageUtils() as any)
189
+ .getDataAsync(datasource, context, flatParams)
190
+ .then((response: any) => {
191
+ const results = Array.isArray(response) ? response : (response?.data ?? []);
192
+ const displayColumn = this.getDisplayFieldsMetaData(processedColumns);
193
+ const optionsData: IOption[] = results.map((element: Record<string, unknown>) => ({
194
+ key: String(element[displayColumn.key] ?? element['pyGUID'] ?? ''),
195
+ value: String(element[displayColumn.primary] ?? ''),
196
+ }));
197
+ this.setOptions(optionsData);
198
+ })
199
+ .catch(() => {
200
+ // Data page fetch failed
201
+ });
202
+ }
203
+ }
204
+
205
+ private setOptions(opts: IOption[]): void {
206
+ this.options = opts;
207
+ this.updateDisplayValue();
208
+ }
209
+
210
+ private flattenParameters(params: Record<string, any> = {}): Record<string, unknown> {
211
+ const flat: Record<string, unknown> = {};
212
+ for (const key of Object.keys(params)) {
213
+ const { name, value: val } = params[key];
214
+ flat[name] = val;
215
+ }
216
+ return flat;
217
+ }
218
+
219
+ private preProcessColumns(columnList: Array<Record<string, string>>): Array<Record<string, string>> {
220
+ return columnList.map((col) => {
221
+ const temp = { ...col };
222
+ temp.value = col.value && col.value.startsWith('.') ? col.value.substring(1) : col.value;
223
+ return temp;
224
+ });
225
+ }
226
+
227
+ private getDisplayFieldsMetaData(columnList: Array<Record<string, string>>): {
228
+ key: string;
229
+ primary: string;
230
+ secondary: string[];
231
+ } {
232
+ const displayColumns = columnList.filter((col) => col['display'] === 'true');
233
+ const metaData = { key: '', primary: '', secondary: [] as string[] };
234
+ const keyCol = columnList.filter((col) => col['key'] === 'true');
235
+ metaData.key = keyCol.length > 0 ? keyCol[0].value : 'auto';
236
+ for (const col of displayColumns) {
237
+ if (col['primary'] === 'true') {
238
+ metaData.primary = col.value;
239
+ } else {
240
+ metaData.secondary.push(col.value);
241
+ }
242
+ }
243
+ return metaData;
244
+ }
245
+
246
+ onInput(event: Event): void {
247
+ const target = event.target as HTMLInputElement;
248
+ this.inputValue = target.value;
249
+ this.showDropdown = true;
250
+ this.filterOptions();
251
+ }
252
+
253
+ onBlur(): void {
254
+ // Delay to allow click on an option
255
+ setTimeout(() => {
256
+ this.showDropdown = false;
257
+ }, 200);
258
+ }
259
+
260
+ selectOption(opt: IOption): void {
261
+ this.inputValue = opt.value;
262
+ this.showDropdown = false;
263
+ if (this.actions && this.propName) {
264
+ handleEvent(this.actions, 'changeNblur', this.propName, opt.key);
265
+ }
266
+ }
267
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Checkbox — boolean checkbox field.
3
+ *
4
+ * Pattern reference: sdk-react Checkbox
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-checkbox',
15
+ standalone: true,
16
+ imports: [CommonModule],
17
+ template: `
18
+ <div style="margin-bottom: 1rem;">
19
+ <label
20
+ style="display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem;"
21
+ [style.cursor]="disabled || readOnly ? 'default' : 'pointer'"
22
+ >
23
+ <input
24
+ type="checkbox"
25
+ [attr.data-testid]="testId"
26
+ [checked]="checked"
27
+ [disabled]="disabled || readOnly"
28
+ (change)="onCheckChange($event)"
29
+ />
30
+ {{ label }}
31
+ <span *ngIf="required" style="color: #dc2626;">*</span>
32
+ </label>
33
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
34
+ {{ validatemessage }}
35
+ </div>
36
+ </div>
37
+ `,
38
+ })
39
+ export class CheckboxComponent implements OnInit, OnChanges {
40
+ @Input() props: any;
41
+
42
+ label = '';
43
+ checked = false;
44
+ testId = '';
45
+ required = false;
46
+ disabled = false;
47
+ readOnly = false;
48
+ validatemessage = '';
49
+
50
+ private actions: any;
51
+ private propName = '';
52
+
53
+ ngOnInit(): void {
54
+ this.updateFromProps();
55
+ }
56
+
57
+ ngOnChanges(changes: SimpleChanges): void {
58
+ if (changes['props']) {
59
+ this.updateFromProps();
60
+ }
61
+ }
62
+
63
+ private updateFromProps(): void {
64
+ const p = this.props;
65
+ this.label = p.label ?? '';
66
+ this.checked = p.value === true || p.value === 'true';
67
+ this.testId = p.testId ?? '';
68
+ this.required = p.required ?? false;
69
+ this.disabled = p.disabled ?? false;
70
+ this.readOnly = p.readOnly ?? false;
71
+ this.validatemessage = p.validatemessage ?? '';
72
+
73
+ const pConn = p.getPConnect?.();
74
+ this.actions = pConn?.getActionsApi?.();
75
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
76
+ }
77
+
78
+ onCheckChange(event: Event): void {
79
+ const target = event.target as HTMLInputElement;
80
+ if (this.actions && this.propName) {
81
+ handleEvent(this.actions, 'changeNblur', this.propName, target.checked);
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Currency — currency input field with formatting.
3
+ *
4
+ * Pattern reference: sdk-react Currency
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-currency',
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
+ <div style="display: flex; align-items: center;">
24
+ <span style="margin-right: 0.25rem; font-size: 0.875rem;">{{ currencySymbol }}</span>
25
+ <input
26
+ type="number"
27
+ step="0.01"
28
+ [attr.data-testid]="testId"
29
+ [value]="value"
30
+ [placeholder]="placeholder"
31
+ [disabled]="disabled"
32
+ [required]="required"
33
+ (blur)="onBlur($event)"
34
+ style="flex: 1; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem;"
35
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
36
+ />
37
+ </div>
38
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
39
+ {{ validatemessage }}
40
+ </div>
41
+ </div>
42
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
43
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
44
+ <div style="font-size: 0.875rem;">{{ currencySymbol }}{{ value }}</div>
45
+ </div>
46
+ `,
47
+ })
48
+ export class CurrencyComponent implements OnInit, OnChanges {
49
+ @Input() props: any;
50
+
51
+ label = '';
52
+ value: any = '';
53
+ placeholder = '';
54
+ testId = '';
55
+ required = false;
56
+ disabled = false;
57
+ readOnly = false;
58
+ validatemessage = '';
59
+ currencySymbol = '$';
60
+
61
+ private actions: any;
62
+ private propName = '';
63
+
64
+ ngOnInit(): void {
65
+ this.updateFromProps();
66
+ }
67
+
68
+ ngOnChanges(changes: SimpleChanges): void {
69
+ if (changes['props']) {
70
+ this.updateFromProps();
71
+ }
72
+ }
73
+
74
+ private updateFromProps(): void {
75
+ const p = this.props;
76
+ this.label = p.label ?? '';
77
+ this.value = p.value ?? '';
78
+ this.placeholder = p.placeholder ?? '';
79
+ this.testId = p.testId ?? '';
80
+ this.required = p.required ?? false;
81
+ this.disabled = p.disabled ?? false;
82
+ this.readOnly = p.readOnly ?? false;
83
+ this.validatemessage = p.validatemessage ?? '';
84
+ this.currencySymbol = p.currencyISOCode ?? p.currencySymbol ?? '$';
85
+
86
+ const pConn = p.getPConnect?.();
87
+ this.actions = pConn?.getActionsApi?.();
88
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
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,88 @@
1
+ /**
2
+ * DateInput — date picker field.
3
+ *
4
+ * Pattern reference: sdk-react DateInput
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-date-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="date"
25
+ [attr.data-testid]="testId"
26
+ [value]="value"
27
+ [disabled]="disabled"
28
+ [required]="required"
29
+ (change)="onDateChange($event)"
30
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem;"
31
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
32
+ />
33
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
34
+ {{ validatemessage }}
35
+ </div>
36
+ </div>
37
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
38
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
39
+ <div style="font-size: 0.875rem;">{{ value }}</div>
40
+ </div>
41
+ `,
42
+ })
43
+ export class DateInputComponent implements OnInit, OnChanges {
44
+ @Input() props: any;
45
+
46
+ label = '';
47
+ value = '';
48
+ testId = '';
49
+ required = false;
50
+ disabled = false;
51
+ readOnly = false;
52
+ validatemessage = '';
53
+
54
+ private actions: any;
55
+ private propName = '';
56
+
57
+ ngOnInit(): void {
58
+ this.updateFromProps();
59
+ }
60
+
61
+ ngOnChanges(changes: SimpleChanges): void {
62
+ if (changes['props']) {
63
+ this.updateFromProps();
64
+ }
65
+ }
66
+
67
+ private updateFromProps(): void {
68
+ const p = this.props;
69
+ this.label = p.label ?? '';
70
+ this.value = p.value ?? '';
71
+ this.testId = p.testId ?? '';
72
+ this.required = p.required ?? false;
73
+ this.disabled = p.disabled ?? false;
74
+ this.readOnly = p.readOnly ?? false;
75
+ this.validatemessage = p.validatemessage ?? '';
76
+
77
+ const pConn = p.getPConnect?.();
78
+ this.actions = pConn?.getActionsApi?.();
79
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
80
+ }
81
+
82
+ onDateChange(event: Event): void {
83
+ const target = event.target as HTMLInputElement;
84
+ if (this.actions && this.propName) {
85
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Dropdown — select/dropdown field.
3
+ *
4
+ * Pattern reference: sdk-react Dropdown
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-dropdown',
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
+ <select
24
+ [attr.data-testid]="testId"
25
+ [disabled]="disabled"
26
+ [required]="required"
27
+ (change)="onSelectChange($event)"
28
+ style="width: 100%; padding: 0.5rem 0.75rem; border-radius: 0.375rem; font-size: 0.875rem;"
29
+ [style.border]="validatemessage ? '1px solid #dc2626' : '1px solid #d1d5db'"
30
+ >
31
+ <option value="" [selected]="!value">
32
+ {{ placeholder || 'Select...' }}
33
+ </option>
34
+ <option *ngFor="let opt of options" [value]="opt.value" [selected]="opt.value === value">
35
+ {{ opt.text || opt.value }}
36
+ </option>
37
+ </select>
38
+ <div *ngIf="validatemessage" style="color: #dc2626; font-size: 0.75rem; margin-top: 0.25rem;">
39
+ {{ validatemessage }}
40
+ </div>
41
+ </div>
42
+ <div *ngIf="readOnly" style="margin-bottom: 1rem;">
43
+ <span style="font-size: 0.75rem; color: #6b7280;">{{ label }}</span>
44
+ <div style="font-size: 0.875rem;">{{ displayValue }}</div>
45
+ </div>
46
+ `,
47
+ })
48
+ export class DropdownComponent implements OnInit, OnChanges {
49
+ @Input() props: any;
50
+
51
+ label = '';
52
+ value: any = '';
53
+ placeholder = '';
54
+ testId = '';
55
+ required = false;
56
+ disabled = false;
57
+ readOnly = false;
58
+ validatemessage = '';
59
+ options: Array<{ value: string; text?: string }> = [];
60
+ displayValue = '';
61
+
62
+ private actions: any;
63
+ private propName = '';
64
+
65
+ ngOnInit(): void {
66
+ this.updateFromProps();
67
+ }
68
+
69
+ ngOnChanges(changes: SimpleChanges): void {
70
+ if (changes['props']) {
71
+ this.updateFromProps();
72
+ }
73
+ }
74
+
75
+ private updateFromProps(): void {
76
+ const p = this.props;
77
+ this.label = p.label ?? '';
78
+ this.value = p.value ?? '';
79
+ this.placeholder = p.placeholder ?? '';
80
+ this.testId = p.testId ?? '';
81
+ this.required = p.required ?? false;
82
+ this.disabled = p.disabled ?? false;
83
+ this.readOnly = p.readOnly ?? false;
84
+ this.validatemessage = p.validatemessage ?? '';
85
+ this.options = Array.isArray(p.datasource) ? p.datasource : [];
86
+
87
+ const match = this.options.find((o) => o.value === this.value);
88
+ this.displayValue = match?.text ?? match?.value ?? String(this.value);
89
+
90
+ const pConn = p.getPConnect?.();
91
+ this.actions = pConn?.getActionsApi?.();
92
+ this.propName = ((pConn?.getStateProps?.() as Record<string, unknown>)?.value as string) ?? '';
93
+ }
94
+
95
+ onSelectChange(event: Event): void {
96
+ const target = event.target as HTMLSelectElement;
97
+ if (this.actions && this.propName) {
98
+ handleEvent(this.actions, 'changeNblur', this.propName, target.value);
99
+ }
100
+ }
101
+ }