@pega/angular-sdk-overrides 0.242.6 → 0.242.8
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/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +0 -1
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.html +1 -1
- package/lib/designSystemExtension/material-details-fields/material-details-fields.component.ts +6 -0
- package/lib/designSystemExtension/operator/operator.component.html +1 -1
- package/lib/designSystemExtension/operator/operator.component.scss +10 -2
- package/lib/designSystemExtension/operator/operator.component.ts +4 -3
- package/lib/field/currency/currency.component.ts +19 -13
- package/lib/field/date-time/date-time.component.html +0 -1
- package/lib/field/date-time/date-time.component.ts +17 -3
- package/lib/field/decimal/decimal.component.html +1 -0
- package/lib/field/decimal/decimal.component.ts +38 -15
- package/lib/field/dropdown/dropdown.component.ts +18 -3
- package/lib/field/email/email.component.ts +17 -7
- package/lib/field/integer/integer.component.html +1 -1
- package/lib/field/integer/integer.component.ts +16 -6
- package/lib/field/list-view-action-buttons/list-view-action-buttons.component.html +1 -1
- package/lib/field/percentage/percentage.component.html +1 -1
- package/lib/field/percentage/percentage.component.ts +27 -17
- package/lib/field/phone/phone.component.ts +6 -13
- package/lib/field/rich-text/rich-text.component.ts +12 -3
- package/lib/field/text/text.component.ts +2 -2
- package/lib/field/text-area/text-area.component.html +1 -1
- package/lib/field/text-area/text-area.component.ts +16 -6
- package/lib/field/text-input/text-input.component.html +1 -1
- package/lib/field/text-input/text-input.component.ts +16 -6
- package/lib/field/time/time.component.html +1 -1
- package/lib/field/time/time.component.ts +21 -6
- package/lib/field/url/url.component.html +1 -1
- package/lib/field/url/url.component.ts +16 -6
- package/lib/field/user-reference/user-reference.component.html +40 -38
- package/lib/field/user-reference/user-reference.component.ts +66 -7
- package/lib/infra/Containers/flow-container/flow-container.component.ts +2 -5
- package/lib/infra/Containers/flow-container/helpers.ts +1 -1
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.html +1 -11
- package/lib/infra/Containers/modal-view-container/modal-view-container.component.ts +0 -1
- package/lib/infra/action-buttons/action-buttons.component.html +1 -1
- package/lib/infra/assignment/assignment.component.ts +3 -5
- package/lib/infra/assignment-card/assignment-card.component.ts +4 -32
- package/lib/infra/defer-load/defer-load.component.ts +4 -1
- package/lib/infra/reference/reference.component.ts +77 -90
- package/lib/infra/root-container/root-container.component.ts +24 -17
- package/lib/template/base/form-template-base.ts +2 -2
- package/lib/template/default-form/default-form.component.ts +5 -7
- package/lib/template/field-group-template/field-group-template.component.html +7 -7
- package/lib/template/field-group-template/field-group-template.component.scss +8 -0
- package/lib/template/field-group-template/field-group-template.component.ts +64 -41
- package/lib/template/field-group-template/utils.ts +9 -0
- package/lib/template/field-value-list/field-value-list.component.html +2 -2
- package/lib/template/field-value-list/field-value-list.component.scss +4 -0
- package/lib/template/list-view/list-view.component.html +3 -1
- package/lib/template/list-view/list-view.component.ts +1 -1
- package/lib/template/simple-table-manual/helpers.ts +18 -2
- package/lib/template/simple-table-manual/simple-table-manual.component.html +25 -6
- package/lib/template/simple-table-manual/simple-table-manual.component.scss +7 -3
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +62 -23
- package/lib/widget/todo/todo.component.html +1 -2
- package/lib/widget/todo/todo.component.scss +2 -0
- package/lib/widget/todo/todo.component.ts +4 -3
- package/package.json +1 -1
|
@@ -13,53 +13,42 @@ import { Component } from '@angular/core';
|
|
|
13
13
|
standalone: true
|
|
14
14
|
})
|
|
15
15
|
export class ReferenceComponent {
|
|
16
|
-
referencedComponent: any = null;
|
|
17
|
-
|
|
18
16
|
/* Used to toggle some class-wide logging */
|
|
19
17
|
private static bLogging = false;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// STATIC method to create a normalized PConn (a fully realized View that the 'reference'
|
|
32
|
-
// component refers to) from the given pConn. Has to add in some stuff as in the constructor
|
|
33
|
-
static createFullReferencedViewFromRef(inPConn: any) {
|
|
34
|
-
// BAIL and ERROR if inPConn is NOT a reference!
|
|
19
|
+
/**
|
|
20
|
+
* Creates a normalized PConn from a reference component.
|
|
21
|
+
* Resolves the reference to its fully realized View with proper configuration.
|
|
22
|
+
*
|
|
23
|
+
* @param inPConn - The PConn object that represents a reference component
|
|
24
|
+
* @returns The dereferenced PConnect object, or null if reference can't be resolved
|
|
25
|
+
*/
|
|
26
|
+
static createFullReferencedViewFromRef(inPConn: any): any {
|
|
27
|
+
// Validate that inPConn is a reference component
|
|
35
28
|
if (inPConn.getComponentName() !== 'reference') {
|
|
36
|
-
// debugger;
|
|
37
|
-
|
|
38
29
|
console.error(`Reference component: createFullReferencedViewFromRef inPConn is NOT a reference! ${inPConn.getComponentName()}`);
|
|
30
|
+
return null;
|
|
39
31
|
}
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const referenceConfig = { ...inPConn.getComponentConfig() } || {};
|
|
33
|
+
// Get reference configuration and make a copy
|
|
34
|
+
const referenceConfig = { ...inPConn.getComponentConfig() };
|
|
44
35
|
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// (and also leaving the others in for now) so the referenced View can act on
|
|
48
|
-
// the visibility prop. (The following 3 lines were carried over from React SDK)
|
|
36
|
+
// Remove properties that should not be inherited by the referenced view
|
|
37
|
+
// (Maintained from React SDK implementation)
|
|
49
38
|
delete referenceConfig?.name;
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
delete referenceConfig?.type;
|
|
40
|
+
delete referenceConfig?.visibility;
|
|
52
41
|
|
|
42
|
+
// Get the metadata for the referenced view
|
|
53
43
|
const viewMetadata = inPConn.getReferencedView();
|
|
54
44
|
|
|
45
|
+
// Return null if view metadata is not found
|
|
55
46
|
if (!viewMetadata) {
|
|
56
47
|
console.log('View not found ', inPConn.getComponentConfig());
|
|
57
48
|
return null;
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
//
|
|
61
|
-
// const referencedComponentName = viewMetadata.type;
|
|
62
|
-
|
|
51
|
+
// Create the view object by merging metadata with reference config
|
|
63
52
|
const viewObject = {
|
|
64
53
|
...viewMetadata,
|
|
65
54
|
config: {
|
|
@@ -68,23 +57,31 @@ export class ReferenceComponent {
|
|
|
68
57
|
}
|
|
69
58
|
};
|
|
70
59
|
|
|
60
|
+
// Resolve configuration properties
|
|
61
|
+
const resolvedConfigProps = inPConn.resolveConfigProps(inPConn.getConfigProps());
|
|
62
|
+
const { visibility = true, context, readOnly = false, displayMode = '' } = resolvedConfigProps;
|
|
63
|
+
|
|
64
|
+
// Log debug information if logging is enabled
|
|
71
65
|
if (ReferenceComponent.bLogging) {
|
|
72
|
-
console.log(`Reference: about to call createComponent with pageReference: context: ${
|
|
66
|
+
console.log(`Reference: about to call createComponent with pageReference: context: ${inPConn.getContextName()}`);
|
|
73
67
|
}
|
|
74
68
|
|
|
69
|
+
// Create the component with the right context
|
|
75
70
|
const viewComponent = inPConn.createComponent(viewObject, null, null, {
|
|
76
|
-
pageReference:
|
|
71
|
+
pageReference: context && context.startsWith('@CLASS') ? '' : context
|
|
77
72
|
});
|
|
78
73
|
|
|
79
|
-
//
|
|
74
|
+
// Get the PConnect object from the created component
|
|
80
75
|
const newCompPConnect = viewComponent.getPConnect();
|
|
81
76
|
|
|
77
|
+
// Set inherited configuration on the new component
|
|
82
78
|
newCompPConnect.setInheritedConfig({
|
|
83
79
|
...referenceConfig,
|
|
84
|
-
readOnly
|
|
85
|
-
displayMode
|
|
80
|
+
readOnly,
|
|
81
|
+
displayMode
|
|
86
82
|
});
|
|
87
83
|
|
|
84
|
+
// Log debug information if logging is enabled
|
|
88
85
|
if (ReferenceComponent.bLogging) {
|
|
89
86
|
console.log(
|
|
90
87
|
`Angular Reference component: createFullReferencedViewFromRef -> newCompPConnect configProps: ${JSON.stringify(
|
|
@@ -93,73 +90,63 @@ export class ReferenceComponent {
|
|
|
93
90
|
);
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
|
|
93
|
+
// Return the component if it should be visible, otherwise null
|
|
94
|
+
return visibility !== false ? newCompPConnect : null;
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// inPConn is an object (ex: { getPConnect()} ), so we want to return
|
|
112
|
-
// any referenced view as the object containing the
|
|
113
|
-
// the getPConnect function
|
|
114
|
-
returnObj = true;
|
|
115
|
-
thePConnType = inPConn.getPConnect().getComponentName();
|
|
116
|
-
} else {
|
|
117
|
-
// inPConn is an object with the PConnect function, so we want
|
|
118
|
-
// to return any referenced view as the object containing the
|
|
119
|
-
// the c11n function
|
|
120
|
-
returnObj = false;
|
|
121
|
-
thePConnType = inPConn.getComponentName();
|
|
97
|
+
/**
|
|
98
|
+
* Normalizes a PConn object that might be a 'reference'.
|
|
99
|
+
* If the incoming PConn is a reference, returns its dereferenced View.
|
|
100
|
+
* Otherwise, returns the passed in PConn unchanged.
|
|
101
|
+
*
|
|
102
|
+
* @param inPConn - A PConn object (ex: { getPConnect() } or direct PConnect)
|
|
103
|
+
* @returns The normalized PConn object with references resolved
|
|
104
|
+
*/
|
|
105
|
+
static normalizePConn(inPConn: any): any {
|
|
106
|
+
// Early return for null or undefined input
|
|
107
|
+
if (!inPConn) {
|
|
108
|
+
return inPConn;
|
|
122
109
|
}
|
|
123
110
|
|
|
124
|
-
if
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// console.log(`theFullReference: ${theFullReference}`);
|
|
137
|
-
|
|
138
|
-
return theRefViewPConn;
|
|
111
|
+
// Determine if we have an object with getPConnect method or direct PConnect
|
|
112
|
+
const hasGetPConnectMethod = !!inPConn.getPConnect;
|
|
113
|
+
|
|
114
|
+
// Get the component name in the appropriate way based on the object type
|
|
115
|
+
const componentName = hasGetPConnectMethod ? inPConn.getPConnect().getComponentName() : inPConn.getComponentName();
|
|
116
|
+
|
|
117
|
+
// Only process if this is a reference component
|
|
118
|
+
if (componentName === 'reference') {
|
|
119
|
+
if (hasGetPConnectMethod) {
|
|
120
|
+
// For objects with getPConnect method, get the referenced view and its component
|
|
121
|
+
const refViewPConn = this.createFullReferencedViewFromRef(inPConn.getPConnect());
|
|
122
|
+
return refViewPConn?.getComponent();
|
|
139
123
|
}
|
|
140
|
-
// console.log(`created theFullRefView full reference: ${theFullRefView.getFullReference()}`);
|
|
141
|
-
// debugger;
|
|
142
124
|
|
|
125
|
+
// For direct PConnect objects, just create the referenced view
|
|
143
126
|
return this.createFullReferencedViewFromRef(inPConn);
|
|
144
127
|
}
|
|
128
|
+
|
|
129
|
+
// Not a reference component, return unchanged
|
|
145
130
|
return inPConn;
|
|
146
131
|
}
|
|
147
132
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
static normalizePConnArray(inPConnArray: any) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return inPConnArray;
|
|
133
|
+
/**
|
|
134
|
+
* Normalizes an array of PConn objects by replacing any 'reference' components
|
|
135
|
+
* with their referenced views.
|
|
136
|
+
*
|
|
137
|
+
* @param inPConnArray - Array of PConn objects to normalize
|
|
138
|
+
* @returns Normalized array with references resolved, or empty array if input is invalid
|
|
139
|
+
*/
|
|
140
|
+
static normalizePConnArray(inPConnArray: any[]): any[] {
|
|
141
|
+
// Handle null, undefined, or empty array case
|
|
142
|
+
if (!inPConnArray?.length) {
|
|
143
|
+
return inPConnArray || [];
|
|
159
144
|
}
|
|
160
145
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
146
|
+
// Process array: normalize each item and filter out any null/undefined results
|
|
147
|
+
const normalizedArray = inPConnArray.map(child => ReferenceComponent.normalizePConn(child)).filter(Boolean);
|
|
148
|
+
|
|
149
|
+
// Ensure we always return an array (even if filter removes all items)
|
|
150
|
+
return normalizedArray || [];
|
|
164
151
|
}
|
|
165
152
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy } from '@angular/core';
|
|
1
|
+
import { Component, OnInit, Input, NgZone, forwardRef, OnDestroy, inject } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
4
4
|
import { interval, Subscription } from 'rxjs';
|
|
5
5
|
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
6
|
+
import { ServerConfigService } from '@pega/angular-sdk-components';
|
|
6
7
|
import { ProgressSpinnerService } from '@pega/angular-sdk-components';
|
|
7
8
|
import { ReferenceComponent } from '@pega/angular-sdk-components';
|
|
8
9
|
import { PreviewViewContainerComponent } from '@pega/angular-sdk-components';
|
|
@@ -37,6 +38,8 @@ export class RootContainerComponent implements OnInit, OnDestroy {
|
|
|
37
38
|
@Input() displayOnlyFA$: boolean;
|
|
38
39
|
@Input() isMashup$: boolean;
|
|
39
40
|
|
|
41
|
+
scService = inject(ServerConfigService);
|
|
42
|
+
|
|
40
43
|
// For interaction with AngularPConnect
|
|
41
44
|
angularPConnectData: AngularPConnectData = {};
|
|
42
45
|
|
|
@@ -62,8 +65,6 @@ export class RootContainerComponent implements OnInit, OnDestroy {
|
|
|
62
65
|
) {}
|
|
63
66
|
|
|
64
67
|
ngOnInit(): void {
|
|
65
|
-
const myContext = 'app';
|
|
66
|
-
|
|
67
68
|
const { containers } = PCore.getStore().getState();
|
|
68
69
|
const items = Object.keys(containers).filter(item => item.includes('root'));
|
|
69
70
|
|
|
@@ -84,24 +85,11 @@ export class RootContainerComponent implements OnInit, OnDestroy {
|
|
|
84
85
|
|
|
85
86
|
this.pvConn$ = configObjPreview.getPConnect();
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
meta: {
|
|
89
|
-
type: 'ModalViewContainer',
|
|
90
|
-
config: {
|
|
91
|
-
name: 'modal'
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
options: {
|
|
95
|
-
pageReference: 'pyPortal',
|
|
96
|
-
context: myContext
|
|
97
|
-
}
|
|
98
|
-
});
|
|
88
|
+
this.configureModalContainer();
|
|
99
89
|
|
|
100
90
|
// clear out hasViewContainer
|
|
101
91
|
sessionStorage.setItem('hasViewContainer', 'false');
|
|
102
92
|
|
|
103
|
-
this.mConn$ = configObjModal.getPConnect();
|
|
104
|
-
|
|
105
93
|
// First thing in initialization is registering and subscribing to the AngularPConnect service
|
|
106
94
|
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
107
95
|
|
|
@@ -181,6 +169,25 @@ export class RootContainerComponent implements OnInit, OnDestroy {
|
|
|
181
169
|
}
|
|
182
170
|
}
|
|
183
171
|
|
|
172
|
+
async configureModalContainer() {
|
|
173
|
+
const sdkConfig = await this.scService.getSdkConfig();
|
|
174
|
+
const showModalsInEmbedMode = sdkConfig.serverConfig.showModalsInEmbedMode;
|
|
175
|
+
|
|
176
|
+
if (!this.displayOnlyFA$ || showModalsInEmbedMode) {
|
|
177
|
+
const configObjModal = PCore.createPConnect({
|
|
178
|
+
meta: {
|
|
179
|
+
type: 'ModalViewContainer',
|
|
180
|
+
config: {
|
|
181
|
+
name: 'modal'
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
options
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
this.mConn$ = configObjModal.getPConnect();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
184
191
|
generateViewContainerForNoPortal() {
|
|
185
192
|
// bootstrap loadMashup resolves to here
|
|
186
193
|
const arChildren = this.pConn$.getChildren() as any[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Directive, OnDestroy } from '@angular/core';
|
|
2
|
-
import { AngularPConnectData } from '
|
|
2
|
+
import { AngularPConnectData } from '@pega/angular-sdk-components';
|
|
3
3
|
|
|
4
4
|
@Directive()
|
|
5
5
|
export class FormTemplateBase implements OnDestroy {
|
|
@@ -9,7 +9,7 @@ export class FormTemplateBase implements OnDestroy {
|
|
|
9
9
|
ngOnDestroy(): void {
|
|
10
10
|
PCore.getContextTreeManager().removeContextTreeNode(this.pConn$.getContextName());
|
|
11
11
|
|
|
12
|
-
if (this.angularPConnectData
|
|
12
|
+
if (this.angularPConnectData?.unsubscribeFn) {
|
|
13
13
|
this.angularPConnectData.unsubscribeFn();
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Component, OnInit, Input, forwardRef
|
|
1
|
+
import { Component, OnInit, Input, forwardRef } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormGroup } from '@angular/forms';
|
|
4
|
-
import { ReferenceComponent } from '@pega/angular-sdk-components';
|
|
5
4
|
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
5
|
+
import { ReferenceComponent } from '@pega/angular-sdk-components';
|
|
6
6
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
7
7
|
import { TemplateUtils } from '@pega/angular-sdk-components';
|
|
8
8
|
import { FormTemplateBase } from '@pega/angular-sdk-components';
|
|
@@ -31,7 +31,7 @@ interface DefaultFormProps {
|
|
|
31
31
|
standalone: true,
|
|
32
32
|
imports: [CommonModule, forwardRef(() => ComponentMapperComponent)]
|
|
33
33
|
})
|
|
34
|
-
export class DefaultFormComponent extends FormTemplateBase implements OnInit
|
|
34
|
+
export class DefaultFormComponent extends FormTemplateBase implements OnInit {
|
|
35
35
|
@Input() override pConn$: typeof PConnect;
|
|
36
36
|
@Input() formGroup$: FormGroup;
|
|
37
37
|
|
|
@@ -86,10 +86,8 @@ export class DefaultFormComponent extends FormTemplateBase implements OnInit, On
|
|
|
86
86
|
// normalize them
|
|
87
87
|
const children = ReferenceComponent.normalizePConnArray(kids[0].getPConnect().getChildren());
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (areViewsChanged(this.arChildren$, visibleChildren)) {
|
|
92
|
-
this.arChildren$ = visibleChildren;
|
|
89
|
+
if (areViewsChanged(this.arChildren$, children)) {
|
|
90
|
+
this.arChildren$ = children;
|
|
93
91
|
}
|
|
94
92
|
}
|
|
95
93
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div id="field-group">
|
|
2
|
-
<h3 *ngIf="showLabel$"
|
|
2
|
+
<h3 *ngIf="showLabel$" class="field-group-template-header" style="font-weight: bold">
|
|
3
3
|
{{ label$ }}
|
|
4
4
|
</h3>
|
|
5
5
|
<div *ngIf="readonlyMode; else editable">
|
|
@@ -11,23 +11,23 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
<ng-template #editable>
|
|
13
13
|
<div *ngIf="children && children.length > 0">
|
|
14
|
-
<div *ngFor="let
|
|
14
|
+
<div class="field-group-template-item" *ngFor="let child of children; let i = index">
|
|
15
15
|
<div class="header-div">
|
|
16
16
|
<div style="width: 80%">
|
|
17
|
-
<b>{{
|
|
17
|
+
<b>{{ child.name }}</b>
|
|
18
18
|
</div>
|
|
19
|
-
<div *ngIf="
|
|
19
|
+
<div *ngIf="allowDelete && child.allowRowDelete" style="width: 20%; text-align: right">
|
|
20
20
|
<button id="delete-button" mat-icon-button (click)="deleteFieldGroupItem(i)">
|
|
21
21
|
<img class="psdk-utility-card-action-svg-icon" src="{{ menuIconOverride$ }}" />
|
|
22
22
|
</button>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
|
|
26
|
-
<div *ngIf="
|
|
27
|
-
<component-mapper name="Region" [props]="{ pConn$:
|
|
26
|
+
<div *ngIf="child.children.getPConnect().getRawMetadata().type.toLowerCase() == 'region'">
|
|
27
|
+
<component-mapper name="Region" [props]="{ pConn$: child.children.getPConnect(), formGroup$ }"></component-mapper>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
|
-
<button *ngIf="allowAddEdit !== false" mat-button color="primary" style="font-size: 16px" (click)="addFieldGroupItem()">+ Add</button>
|
|
31
30
|
</div>
|
|
31
|
+
<button *ngIf="allowAdd" mat-button color="primary" style="font-size: 16px" (click)="addFieldGroupItem()">{{ getAddBtnLabel() }}</button>
|
|
32
32
|
</ng-template>
|
|
33
33
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, OnInit, Input, forwardRef, OnDestroy, OnChanges } from '@angular/core';
|
|
1
|
+
import { Component, OnInit, Input, forwardRef, OnDestroy, OnChanges, AfterViewInit } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormGroup } from '@angular/forms';
|
|
4
4
|
import { MatButtonModule } from '@angular/material/button';
|
|
@@ -6,11 +6,14 @@ import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-c
|
|
|
6
6
|
import { buildView, getReferenceList } from '@pega/angular-sdk-components';
|
|
7
7
|
import { Utils } from '@pega/angular-sdk-components';
|
|
8
8
|
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
|
|
9
|
+
import { evaluateAllowRowAction } from './utils';
|
|
9
10
|
|
|
10
11
|
interface FieldGroupTemplateProps {
|
|
11
12
|
// If any, enter additional props that only exist on this component
|
|
12
13
|
label?: string;
|
|
13
|
-
|
|
14
|
+
hideLabel?: boolean;
|
|
15
|
+
allowActions?: any;
|
|
16
|
+
allowRowDelete?: any;
|
|
14
17
|
referenceList?: any[];
|
|
15
18
|
contextClass: string;
|
|
16
19
|
renderMode?: string;
|
|
@@ -19,6 +22,7 @@ interface FieldGroupTemplateProps {
|
|
|
19
22
|
displayMode?: string;
|
|
20
23
|
fieldHeader?: string;
|
|
21
24
|
allowTableEdit: boolean;
|
|
25
|
+
targetClassLabel?: string;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
@Component({
|
|
@@ -28,26 +32,27 @@ interface FieldGroupTemplateProps {
|
|
|
28
32
|
standalone: true,
|
|
29
33
|
imports: [CommonModule, MatButtonModule, forwardRef(() => ComponentMapperComponent)]
|
|
30
34
|
})
|
|
31
|
-
export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges {
|
|
35
|
+
export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
|
32
36
|
@Input() configProps$: FieldGroupTemplateProps;
|
|
33
37
|
@Input() pConn$: typeof PConnect;
|
|
34
38
|
@Input() formGroup$: FormGroup;
|
|
35
39
|
|
|
36
40
|
angularPConnectData: AngularPConnectData = {};
|
|
37
|
-
|
|
41
|
+
|
|
38
42
|
showLabel$?: boolean = true;
|
|
39
43
|
label$?: string;
|
|
40
44
|
readonlyMode: boolean;
|
|
41
45
|
contextClass: any;
|
|
42
|
-
referenceList: any;
|
|
43
|
-
pageReference: any;
|
|
44
46
|
heading: any;
|
|
45
47
|
children: any;
|
|
46
48
|
menuIconOverride$: any;
|
|
47
|
-
|
|
48
|
-
allowAddEdit: boolean;
|
|
49
|
+
referenceListLength: number;
|
|
49
50
|
fieldHeader: any;
|
|
50
51
|
|
|
52
|
+
allowAdd = true;
|
|
53
|
+
allowEdit = true;
|
|
54
|
+
allowDelete = true;
|
|
55
|
+
|
|
51
56
|
constructor(
|
|
52
57
|
private angularPConnect: AngularPConnectService,
|
|
53
58
|
private utils: Utils
|
|
@@ -58,9 +63,21 @@ export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges
|
|
|
58
63
|
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
|
|
59
64
|
this.updateSelf();
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
this.menuIconOverride$ = this.utils.getImageSrc('trash', this.utils.getSDKStaticContentUrl());
|
|
67
|
+
|
|
68
|
+
const { allowActions, allowTableEdit, referenceList } = this.configProps$;
|
|
69
|
+
|
|
70
|
+
if (allowActions && Object.keys(allowActions).length > 0) {
|
|
71
|
+
this.allowAdd = allowActions.allowAdd ?? allowTableEdit ?? true;
|
|
72
|
+
this.allowEdit = allowActions.allowEdit ?? true;
|
|
73
|
+
this.allowDelete = allowActions.allowDelete ?? allowTableEdit ?? true;
|
|
74
|
+
} else {
|
|
75
|
+
this.allowAdd = allowTableEdit ?? true;
|
|
76
|
+
this.allowDelete = allowTableEdit ?? true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (referenceList?.length === 0 && (this.allowAdd || this.allowEdit)) {
|
|
80
|
+
this.pConn$.getListActions().insert({ classID: this.contextClass }, referenceList.length);
|
|
64
81
|
}
|
|
65
82
|
}
|
|
66
83
|
|
|
@@ -85,56 +102,57 @@ export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges
|
|
|
85
102
|
const props = changes.configProps$;
|
|
86
103
|
if (props.currentValue !== props.previousValue) {
|
|
87
104
|
this.configProps$ = props.currentValue;
|
|
105
|
+
|
|
88
106
|
if (changes?.pConn$?.currentValue) {
|
|
89
107
|
this.pConn$ = changes?.pConn$?.currentValue;
|
|
90
108
|
}
|
|
109
|
+
|
|
91
110
|
this.updateSelf();
|
|
92
111
|
}
|
|
93
112
|
}
|
|
94
113
|
}
|
|
95
114
|
|
|
115
|
+
ngAfterViewInit() {
|
|
116
|
+
const resolvedList = getReferenceList(this.pConn$);
|
|
117
|
+
// @ts-ignore - Expected 3 arguments, but got 1
|
|
118
|
+
this.pConn$.getListActions().initDefaultPageInstructions(resolvedList);
|
|
119
|
+
}
|
|
120
|
+
|
|
96
121
|
updateSelf() {
|
|
97
|
-
|
|
98
|
-
this.label$ = this.configProps$.label;
|
|
99
|
-
this.showLabel$ = this.configProps$.showLabel;
|
|
100
|
-
// label & showLabel within inheritedProps takes precedence over configProps
|
|
101
|
-
this.label$ = (this.inheritedProps$ as any).label || this.label$;
|
|
102
|
-
this.showLabel$ = (this.inheritedProps$ as any).showLabel || this.showLabel$;
|
|
122
|
+
const inheritedProps: any = this.pConn$.getInheritedProps();
|
|
103
123
|
|
|
104
|
-
|
|
124
|
+
const { label, hideLabel, allowRowDelete, referenceList, fieldHeader, renderMode, displayMode, heading, contextClass, lookForChildInConfig } =
|
|
125
|
+
this.configProps$;
|
|
126
|
+
|
|
127
|
+
// label within inheritedProps takes precedence over configProps
|
|
128
|
+
this.label$ = inheritedProps.label || label;
|
|
129
|
+
|
|
130
|
+
this.showLabel$ = referenceList?.length === 0 || !hideLabel;
|
|
105
131
|
|
|
106
|
-
const renderMode = this.configProps$.renderMode;
|
|
107
|
-
const displayMode = this.configProps$.displayMode;
|
|
108
132
|
this.readonlyMode = renderMode === 'ReadOnly' || displayMode === 'DISPLAY_ONLY';
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.heading =
|
|
112
|
-
this.fieldHeader =
|
|
133
|
+
|
|
134
|
+
this.contextClass = contextClass;
|
|
135
|
+
this.heading = heading ?? 'Row';
|
|
136
|
+
this.fieldHeader = fieldHeader;
|
|
137
|
+
|
|
113
138
|
const resolvedList = getReferenceList(this.pConn$);
|
|
114
|
-
this.pageReference = `${this.pConn$.getPageReference()}${resolvedList}`;
|
|
115
139
|
this.pConn$.setReferenceList(resolvedList);
|
|
140
|
+
|
|
116
141
|
if (this.readonlyMode) {
|
|
117
142
|
this.pConn$.setInheritedProp('displayMode', 'DISPLAY_ONLY');
|
|
118
143
|
}
|
|
119
|
-
|
|
120
|
-
if (this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (this.referenceList?.length === 0 && this.allowAddEdit !== false) {
|
|
124
|
-
this.addFieldGroupItem();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const children: any = [];
|
|
128
|
-
this.referenceList?.forEach((item, index) => {
|
|
129
|
-
children.push({
|
|
144
|
+
|
|
145
|
+
if (this.referenceListLength != referenceList?.length) {
|
|
146
|
+
this.children = referenceList?.map((item, index) => {
|
|
147
|
+
return {
|
|
130
148
|
id: index,
|
|
131
149
|
name: this.fieldHeader === 'propertyRef' ? this.getDynamicHeader(item, index) : this.getStaticHeader(this.heading, index),
|
|
132
|
-
children: buildView(this.pConn$, index, lookForChildInConfig)
|
|
133
|
-
|
|
150
|
+
children: buildView(this.pConn$, index, lookForChildInConfig),
|
|
151
|
+
allowRowDelete: evaluateAllowRowAction(allowRowDelete, item)
|
|
152
|
+
};
|
|
134
153
|
});
|
|
135
|
-
this.children = children;
|
|
136
154
|
}
|
|
137
|
-
this.
|
|
155
|
+
this.referenceListLength = referenceList?.length || 0;
|
|
138
156
|
}
|
|
139
157
|
|
|
140
158
|
getStaticHeader = (heading, index) => {
|
|
@@ -149,10 +167,15 @@ export class FieldGroupTemplateComponent implements OnInit, OnDestroy, OnChanges
|
|
|
149
167
|
};
|
|
150
168
|
|
|
151
169
|
addFieldGroupItem() {
|
|
152
|
-
this.pConn$.getListActions().insert({ classID: this.contextClass }, this.
|
|
170
|
+
this.pConn$.getListActions().insert({ classID: this.contextClass }, this.referenceListLength);
|
|
153
171
|
}
|
|
154
172
|
|
|
155
173
|
deleteFieldGroupItem(index) {
|
|
156
174
|
this.pConn$.getListActions().deleteEntry(index);
|
|
157
175
|
}
|
|
176
|
+
|
|
177
|
+
getAddBtnLabel() {
|
|
178
|
+
const { targetClassLabel } = this.configProps$;
|
|
179
|
+
return targetClassLabel ? `+ Add ${targetClassLabel}` : '+ Add';
|
|
180
|
+
}
|
|
158
181
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const evaluateAllowRowAction = (allowRowDelete, rowData) => {
|
|
2
|
+
if (allowRowDelete === undefined || allowRowDelete === true) return true;
|
|
3
|
+
if (allowRowDelete.startsWith?.('@E ')) {
|
|
4
|
+
const expression = allowRowDelete.replace('@E ', '');
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
return PCore.getExpressionEngine().evaluate(expression, rowData);
|
|
7
|
+
}
|
|
8
|
+
return false;
|
|
9
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<div *ngIf="displayMode$ === 'DISPLAY_ONLY'; else STACKED_LARGE_VAL"
|
|
2
|
-
<div class="psdk-grid-label">{{ label$ }}</div>
|
|
1
|
+
<div *ngIf="displayMode$ === 'DISPLAY_ONLY'; else STACKED_LARGE_VAL" [ngClass]="label$ ? 'psdk-container-labels-left' : 'psdk-container-nolabels'">
|
|
2
|
+
<div *ngIf="label$" class="psdk-grid-label">{{ label$ }}</div>
|
|
3
3
|
<div class="psdk-val-labels-left">
|
|
4
4
|
<ng-container *ngTemplateOutlet="valueTemplate"></ng-container>
|
|
5
5
|
</div>
|
|
@@ -180,7 +180,9 @@
|
|
|
180
180
|
<tr mat-header-row *matHeaderRowDef="displayedColumns$"></tr>
|
|
181
181
|
</table>
|
|
182
182
|
</div>
|
|
183
|
-
<div class="psdk-no-records" *ngIf="repeatListData?.length === 0">
|
|
183
|
+
<div class="psdk-no-records" *ngIf="repeatListData?.length === 0">
|
|
184
|
+
{{ utils.getGenericFieldsLocalizedValue('CosmosFields.fields.lists', 'No records found.') }}
|
|
185
|
+
</div>
|
|
184
186
|
</div>
|
|
185
187
|
</div>
|
|
186
188
|
</div>
|