@pega/angular-sdk-overrides 0.25.4 → 0.25.6

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.
@@ -9,7 +9,7 @@
9
9
  </div>
10
10
  <div
11
11
  [ngClass]="{
12
- 'psdk-grid-filter-1': this.layout$ === 'two-column',
12
+ 'psdk-grid-filter-2': this.layout$ === 'two-column',
13
13
  'psdk-grid-filter-wide-narrow': this.layout$ === 'wide-narrow',
14
14
  'psdk-grid-filter-narrow-wide': this.layout$ === 'narrow-wide'
15
15
  }"
@@ -1,6 +1,6 @@
1
1
  .psdk-grid-filter-1 {
2
2
  display: grid;
3
- grid-template-columns: repeat(3, minmax(0, 1fr));
3
+ grid-template-columns: repeat(1, minmax(0, 1fr));
4
4
  column-gap: calc(2 * 0.5rem);
5
5
  row-gap: calc(2 * 0.5rem);
6
6
  align-items: start;
@@ -8,7 +8,7 @@
8
8
 
9
9
  .psdk-grid-filter-2 {
10
10
  display: grid;
11
- grid-template-columns: repeat(3, minmax(0, 1fr));
11
+ grid-template-columns: repeat(2, minmax(0, 1fr));
12
12
  column-gap: calc(2 * 0.5rem);
13
13
  row-gap: calc(2 * 0.5rem);
14
14
  align-items: start;
@@ -20,6 +20,10 @@
20
20
  column-gap: calc(2 * 0.5rem);
21
21
  row-gap: calc(2 * 0.5rem);
22
22
  align-items: start;
23
+
24
+ & > *:nth-child(1) {
25
+ min-width: 0;
26
+ }
23
27
  }
24
28
 
25
29
  .psdk-grid-filter-narrow-wide {
@@ -4,9 +4,7 @@ import { ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatDatepickerModule } from '@angular/material/datepicker';
5
5
  import { MatInputModule } from '@angular/material/input';
6
6
  import { MatFormFieldModule } from '@angular/material/form-field';
7
-
8
7
  import { ScrollStrategyOptions } from '@angular/cdk/overlay';
9
-
10
8
  import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';
11
9
  import dayjs from 'dayjs';
12
10
 
@@ -6,13 +6,13 @@
6
6
  matInput
7
7
  type="text"
8
8
  [placeholder]="placeholder"
9
- [formControl]="searchControl"
9
+ [formControl]="fieldControl"
10
10
  [required]="bRequired$"
11
11
  [matAutocomplete]="auto"
12
12
  [attr.data-test-id]="testId"
13
13
  (blur)="fieldOnBlur()"
14
14
  />
15
- <mat-error *ngIf="searchControl.invalid">{{ getErrorMessage() }}</mat-error>
15
+ <mat-error *ngIf="fieldControl.invalid">{{ getErrorMessage() }}</mat-error>
16
16
  <button
17
17
  mat-icon-button
18
18
  matSuffix
@@ -1,6 +1,6 @@
1
- import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
1
+ import { Component, inject } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
- import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
3
+ import { ReactiveFormsModule } from '@angular/forms';
4
4
  import { MatFormFieldModule } from '@angular/material/form-field';
5
5
  import { MatInputModule } from '@angular/material/input';
6
6
  import { MatAutocompleteModule } from '@angular/material/autocomplete';
@@ -8,12 +8,10 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
8
8
  import { MatIconModule } from '@angular/material/icon';
9
9
  import { MatButtonModule } from '@angular/material/button';
10
10
  import { GoogleMapsModule } from '@angular/google-maps';
11
+ import { debounceTime, from, of, switchMap } from 'rxjs';
11
12
 
12
- import { debounceTime, from, interval, of, switchMap } from 'rxjs';
13
-
14
- import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
13
+ import { FieldBase } from '@pega/angular-sdk-components';
15
14
  import { GoogleMapsLoaderService } from '@pega/angular-sdk-components';
16
- import { Utils } from '@pega/angular-sdk-components';
17
15
  import { handleEvent } from '@pega/angular-sdk-components';
18
16
 
19
17
  import { PConnFieldProps } from '@pega/angular-sdk-components';
@@ -41,9 +39,8 @@ interface LocationProps extends PConnFieldProps {
41
39
  templateUrl: './location.component.html',
42
40
  styleUrl: './location.component.scss'
43
41
  })
44
- export class LocationComponent implements OnInit, OnDestroy {
45
- @Input() pConn$: typeof PConnect;
46
- @Input() formGroup$: FormGroup;
42
+ export class LocationComponent extends FieldBase {
43
+ private loader = inject(GoogleMapsLoaderService);
47
44
 
48
45
  private autocompleteService!: google.maps.places.AutocompleteService;
49
46
  private geocoder!: google.maps.Geocoder;
@@ -51,137 +48,52 @@ export class LocationComponent implements OnInit, OnDestroy {
51
48
  // Dom variables
52
49
  mapReady = false;
53
50
  isLocating = false;
54
- searchControl = new FormControl('');
55
51
  showMap = true;
56
52
  filteredOptions: string[] = [];
57
53
  center: google.maps.LatLngLiteral;
58
54
  markerPosition: google.maps.LatLngLiteral | null = null;
59
55
 
60
- // Used with AngularPConnect
61
- angularPConnectData: AngularPConnectData = {};
62
56
  configProps$: LocationProps;
63
- label$ = '';
64
57
  onlyCoordinates: boolean;
65
58
  coordinates: string;
66
- bRequired$ = false;
67
- bReadonly$ = false;
68
59
  showMapReadOnly$: boolean;
69
- bDisabled$ = false;
70
- bVisible$ = true;
71
- controlName$: string;
72
- bHasForm$ = true;
73
- testId = '';
74
- helperText: string;
75
- placeholder: string;
76
- actionsApi: object;
77
60
  valueProp: string;
78
61
  coordinatesProp: string;
79
62
 
80
- constructor(
81
- private loader: GoogleMapsLoaderService,
82
- private angularPConnect: AngularPConnectService,
83
- private utils: Utils,
84
- private cdRef: ChangeDetectorRef
85
- ) {}
63
+ override async ngOnInit() {
64
+ super.ngOnInit();
86
65
 
87
- async ngOnInit() {
88
66
  // Loading map
89
67
  const apiKey = this.pConn$.getGoogleMapsAPIKey();
90
68
  await this.loader.load(apiKey);
91
69
  this.mapReady = true;
92
70
  this.initializeGoogleServices();
93
71
  this.getPlacePredictions();
94
-
95
- this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
96
- this.controlName$ = this.angularPConnect.getComponentID(this);
97
- this.checkAndUpdate();
98
-
99
- if (this.formGroup$) {
100
- // add control to formGroup
101
- this.formGroup$.addControl(this.controlName$, this.searchControl);
102
- this.bHasForm$ = true;
103
- } else {
104
- this.bReadonly$ = true;
105
- this.bHasForm$ = false;
106
- }
107
72
  }
108
73
 
109
- ngOnDestroy(): void {
110
- if (this.formGroup$) {
111
- this.formGroup$.removeControl(this.controlName$);
112
- }
113
-
114
- if (this.angularPConnectData.unsubscribeFn) {
115
- this.angularPConnectData.unsubscribeFn();
116
- }
117
- }
118
-
119
- checkAndUpdate() {
120
- const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
121
- if (bUpdateSelf) {
122
- this.updateSelf();
123
- }
124
- }
74
+ /**
75
+ * Updates the component when there are changes in the state.
76
+ */
77
+ override updateSelf(): void {
78
+ // Resolve configuration properties
79
+ this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as LocationProps;
125
80
 
126
- onStateChange() {
127
- setTimeout(() => {
128
- this.checkAndUpdate();
129
- }, 0);
130
- }
81
+ // Update component common properties
82
+ this.updateComponentCommonProperties(this.configProps$);
131
83
 
132
- updateSelf(): void {
133
- this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as LocationProps;
134
- if (this.configProps$.visibility != null) {
135
- this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility);
136
- }
137
84
  this.onlyCoordinates = !!this.configProps$.onlyCoordinates;
138
- this.label$ = this.configProps$.label;
139
- this.testId = this.configProps$.testId;
140
-
141
- this.helperText = this.configProps$.helperText || '';
142
- this.placeholder = this.configProps$.placeholder || '';
143
85
  this.showMapReadOnly$ = !!this.configProps$.showMapReadOnly;
144
- if (this.configProps$.readOnly != null) {
145
- this.bReadonly$ = this.utils.getBooleanValue(this.configProps$.readOnly);
146
- }
147
86
  this.showMap = this.bReadonly$ ? this.showMapReadOnly$ : !!this.configProps$.showMap;
87
+
148
88
  if (this.configProps$.coordinates) {
149
89
  const latAndLong: number[] = this.configProps$.coordinates.split(',').map(Number);
150
90
  const latitude = Number(latAndLong[0]);
151
91
  const longitude = Number(latAndLong[1]);
152
92
  this.updateMap(latitude, longitude, this.configProps$.value);
153
93
  }
154
- // // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError
155
- setTimeout(() => {
156
- if (this.configProps$.required != null) {
157
- this.bRequired$ = this.utils.getBooleanValue(this.configProps$.required);
158
- }
159
- this.cdRef.detectChanges();
160
- });
161
- // // disabled
162
- if (this.configProps$.disabled != undefined) {
163
- this.bDisabled$ = this.utils.getBooleanValue(this.configProps$.disabled);
164
- }
165
94
 
166
- if (this.bDisabled$ || this.bReadonly$) {
167
- this.searchControl.disable();
168
- } else {
169
- this.searchControl.enable();
170
- }
171
-
172
- this.actionsApi = this.pConn$.getActionsApi();
173
95
  this.valueProp = this.pConn$.getStateProps().value;
174
96
  this.coordinatesProp = this.pConn$.getStateProps().coordinates;
175
-
176
- // // trigger display of error message with field control
177
- if (this.angularPConnectData.validateMessage != null && this.angularPConnectData.validateMessage != '') {
178
- const timer = interval(100).subscribe(() => {
179
- this.searchControl.setErrors({ message: true });
180
- this.searchControl.markAsTouched();
181
-
182
- timer.unsubscribe();
183
- });
184
- }
185
97
  }
186
98
 
187
99
  onOptionSelected(event: any) {
@@ -236,23 +148,6 @@ export class LocationComponent implements OnInit, OnDestroy {
236
148
  }
237
149
  }
238
150
 
239
- getErrorMessage() {
240
- let errMessage = '';
241
-
242
- // look for validation messages for json, pre-defined or just an error pushed from workitem (400)
243
- if (this.searchControl.hasError('message')) {
244
- errMessage = this.angularPConnectData.validateMessage ?? '';
245
- return errMessage;
246
- }
247
- if (this.searchControl.hasError('required')) {
248
- errMessage = 'You must enter a value';
249
- } else if (this.searchControl.errors) {
250
- errMessage = this.searchControl.errors.toString();
251
- }
252
-
253
- return errMessage;
254
- }
255
-
256
151
  private tryGetLocation(retryCount: number) {
257
152
  navigator.geolocation.getCurrentPosition(
258
153
  position => {
@@ -312,7 +207,7 @@ export class LocationComponent implements OnInit, OnDestroy {
312
207
  }
313
208
 
314
209
  private getPlacePredictions() {
315
- this.searchControl.valueChanges
210
+ this.fieldControl.valueChanges
316
211
  .pipe(
317
212
  debounceTime(300),
318
213
  switchMap(value => this.getSuggestions(value || ''))
@@ -371,7 +266,7 @@ export class LocationComponent implements OnInit, OnDestroy {
371
266
  }
372
267
 
373
268
  private updateProps() {
374
- handleEvent(this.actionsApi, 'change', this.valueProp, this.searchControl.value);
269
+ handleEvent(this.actionsApi, 'change', this.valueProp, this.fieldControl.value);
375
270
  handleEvent(this.actionsApi, 'change', this.coordinatesProp, this.coordinates);
376
271
  }
377
272
 
@@ -380,6 +275,6 @@ export class LocationComponent implements OnInit, OnDestroy {
380
275
  }
381
276
 
382
277
  private setLocationValue(value: string) {
383
- this.searchControl.setValue(value, { emitEvent: false });
278
+ this.fieldControl.setValue(value, { emitEvent: false });
384
279
  }
385
280
  }
@@ -18,6 +18,11 @@ function getRefreshProps(refreshConditions) {
18
18
  return refreshConditions.filter(item => item.event && item.event === 'Changes').map(item => [item.field, item.field?.substring(1)]) || [];
19
19
  }
20
20
 
21
+ function scrollToTop() {
22
+ const scrollElement = document.querySelector('.psdk-view-container-top');
23
+ scrollElement?.scrollIntoView();
24
+ }
25
+
21
26
  interface AssignmentProps {
22
27
  // If any, enter additional props that only exist on this component
23
28
  template: string;
@@ -140,6 +145,8 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
140
145
  }
141
146
 
142
147
  updateChanges() {
148
+ scrollToTop();
149
+
143
150
  this.registerForRefresh();
144
151
 
145
152
  // pConn$ may be a 'reference' component, so normalize it
@@ -36,17 +36,15 @@
36
36
  </mat-list-item>
37
37
  </mat-list>
38
38
  <div class="psdk-nav-divider"></div>
39
- <div>
40
- <mat-list id="profile">
41
- <mat-list-item [matMenuTriggerFor]="menu" class="psdk-profile-list-item">
42
- <div class="flex-box">
43
- <div class="psdk-nav-oper-avatar">{{ portalOperatorInitials$ }}</div>
44
- <span class="psdk-nav-button-span">{{ portalOperator$ }}</span>
45
- </div>
46
- </mat-list-item>
47
- <mat-menu #menu="matMenu">
48
- <button mat-menu-item (click)="navPanelLogoutClick()">{{ localizedVal('Log off', localeCategory) }}</button>
49
- </mat-menu>
50
- </mat-list>
51
- </div>
39
+ <mat-list id="profile" class="psdk-logout-button">
40
+ <mat-list-item [matMenuTriggerFor]="menu" class="psdk-profile-list-item">
41
+ <div class="flex-box">
42
+ <div class="psdk-nav-oper-avatar">{{ portalOperatorInitials$ }}</div>
43
+ <span class="psdk-nav-button-span">{{ portalOperator$ }}</span>
44
+ </div>
45
+ </mat-list-item>
46
+ <mat-menu #menu="matMenu">
47
+ <button mat-menu-item (click)="navPanelLogoutClick()">{{ localizedVal('Log off', localeCategory) }}</button>
48
+ </mat-menu>
49
+ </mat-list>
52
50
  </div>
@@ -163,3 +163,8 @@ mat-list-item {
163
163
  height: 24px;
164
164
  border-radius: 50%;
165
165
  }
166
+
167
+ .psdk-logout-button {
168
+ flex: 1;
169
+ align-content: flex-end;
170
+ }
@@ -71,6 +71,11 @@ export class ReferenceComponent {
71
71
  pageReference: context && context.startsWith('@CLASS') ? '' : context
72
72
  });
73
73
 
74
+ if (referenceConfig.inheritedProps && referenceConfig.inheritedProps.length > 0) {
75
+ const inheritedProps = inPConn.getInheritedProps();
76
+ referenceConfig.inheritedProps = Object.keys(inheritedProps).map(prop => ({ prop, value: inheritedProps[prop] }));
77
+ }
78
+
74
79
  // Get the PConnect object from the created component
75
80
  const newCompPConnect = viewComponent.getPConnect();
76
81
 
@@ -1,7 +1,7 @@
1
1
  <div>
2
2
  <div *ngIf="showConfirmView">
3
3
  <h2 id="confirm-label" class="confirm-label">{{ label }}</h2>
4
- <div *ngIf="showDetails">
4
+ <div *ngIf="showDetails" class="confirmation-details">
5
5
  <component-mapper name="Details" [props]="{ pConn$ }"></component-mapper>
6
6
  </div>
7
7
  <div *ngIf="showTasks && toDoList?.length > 0">
@@ -46,6 +46,7 @@ interface ListViewProps {
46
46
  displayAs?: string;
47
47
  showRecords: boolean;
48
48
  viewName?: string;
49
+ localeReference?: any;
49
50
  }
50
51
 
51
52
  export class Group {
@@ -516,6 +517,7 @@ export class ListViewComponent implements OnInit, OnDestroy {
516
517
  const arReturn = arFields;
517
518
  arReturn.forEach((field, i) => {
518
519
  field.config = { ...field.config, ...fields[i], name: fields[i].id };
520
+ field.config.label = PCore.getLocaleUtils().getLocaleValue(field.config.label, this.configProps$.localeReference);
519
521
  });
520
522
  return arReturn;
521
523
  }
@@ -1,4 +1,4 @@
1
- <mat-toolbar style="margin-bottom: 5px; background-color: #262626">
1
+ <mat-toolbar>
2
2
  <mat-toolbar-row mat-icon-button>
3
3
  <div class="psdk-nav-header" (click)="navPanelButtonClick(homePage)">
4
4
  <div>
@@ -15,8 +15,6 @@
15
15
  padding-top: 0.625rem;
16
16
  cursor: pointer;
17
17
  padding-right: 1rem;
18
- &:hover {
19
- }
20
18
  align-items: center;
21
19
  }
22
20
 
@@ -106,13 +104,11 @@
106
104
 
107
105
  .psdk-nav-button-span {
108
106
  padding: 0 1rem;
109
- color: var(--app-nav-color);
110
-
111
- &:hover {
112
- }
113
107
  }
114
108
 
115
109
  .psdk-nav-oper-avatar {
110
+ border-radius: 100%;
111
+ background-color: var(--mat-sys-primary);
116
112
  margin: 0rem;
117
113
  padding: 0rem;
118
114
  min-width: 2.5rem;
@@ -128,6 +124,11 @@
128
124
  font-size: 1rem;
129
125
  }
130
126
 
127
+ mat-toolbar {
128
+ margin-bottom: 5px;
129
+ background-color: var(--mat-sys-surface-variant);
130
+ }
131
+
131
132
  mat-list {
132
133
  padding: 0;
133
134
  }
@@ -142,9 +143,6 @@ mat-list-item {
142
143
  cursor: pointer !important;
143
144
  height: auto !important;
144
145
 
145
- &:hover {
146
- }
147
-
148
146
  .flex-box {
149
147
  display: flex;
150
148
  align-items: center;
@@ -24,7 +24,7 @@
24
24
  }
25
25
 
26
26
  .psdk-modal-file-selector {
27
- border: 1px dashed var(--app-neutral-dark-color);
27
+ border: 1px dashed var(--mat-sys-neutral-variant20);
28
28
  width: 100%;
29
29
  padding: 0.3rem;
30
30
  text-align: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/angular-sdk-overrides",
3
- "version": "0.25.4",
3
+ "version": "0.25.6",
4
4
  "description": "Angular SDK - Code for overriding components",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"