@pega/angular-sdk-overrides 0.26.4 → 0.26.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.
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html +48 -42
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss +12 -0
- package/lib/designSystemExtension/material-case-summary/material-case-summary.component.ts +11 -0
- package/lib/designSystemExtension/operator/operator.component.html +5 -3
- package/lib/designSystemExtension/operator/operator.component.scss +7 -0
- package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.html +3 -7
- package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.spec.ts +1 -1
- package/lib/designSystemExtension/rich-text-editor/rich-text-editor.component.ts +19 -3
- package/lib/field/auto-complete/auto-complete.component.ts +1 -1
- package/lib/field/check-box/check-box.component.html +5 -5
- package/lib/field/check-box/check-box.component.ts +0 -2
- package/lib/field/date-time/date-time.component.ts +27 -0
- package/lib/field/dropdown/dropdown.component.ts +9 -4
- package/lib/field/multiselect/multiselect.component.html +1 -1
- package/lib/field/multiselect/multiselect.component.ts +1 -1
- package/lib/field/object-reference/object-reference.component.html +1 -1
- package/lib/field/object-reference/object-reference.component.ts +0 -1
- package/lib/field/rich-text/rich-text.component.spec.ts +1 -1
- package/lib/field/semantic-link/semantic-link.component.ts +4 -2
- package/lib/field/user-reference/user-reference.component.ts +1 -1
- package/lib/infra/Containers/view-container/view-container.component.ts +0 -4
- package/lib/infra/assignment/assignment.component.ts +12 -2
- package/lib/infra/view/view.component.ts +2 -1
- package/lib/template/advanced-search/search-groups/search-groups.component.ts +1 -1
- package/lib/template/data-reference/data-reference.component.ts +1 -1
- package/lib/template/list-view/list-view.component.ts +8 -11
- package/lib/template/simple-table-manual/helpers.ts +52 -5
- package/lib/template/simple-table-manual/simple-table-manual.component.ts +3 -3
- package/lib/template/single-reference-readonly/single-reference-readonly.component.html +1 -1
- package/lib/template/single-reference-readonly/single-reference-readonly.component.scss +0 -1
- package/lib/template/single-reference-readonly/single-reference-readonly.component.ts +4 -5
- package/lib/widget/attachment/AttachmentUtils.ts +1 -1
- package/lib/widget/attachment/attachment.component.ts +2 -2
- package/lib/widget/feed-container/feed-container.component.ts +1 -199
- package/lib/widget/file-utility/file-utility.component.ts +1 -1
- package/package.json +1 -1
package/lib/designSystemExtension/material-case-summary/material-case-summary.component.html
CHANGED
|
@@ -1,67 +1,73 @@
|
|
|
1
1
|
<div class="psdk-case-summary-fields">
|
|
2
2
|
<dl class="psdk-case-summary-fields-primary">
|
|
3
3
|
<div *ngFor="let field of primaryFieldsWithStatus$" class="psdk-csf-primary-field">
|
|
4
|
-
<dt
|
|
4
|
+
<dt
|
|
5
|
+
*ngIf="
|
|
6
|
+
field.type.toLowerCase() !== 'objectreference' && field.type.toLowerCase() !== 'reference' && field.type.toLowerCase() !== 'caseoperator'
|
|
7
|
+
"
|
|
8
|
+
class="psdk-csf-primary-field-header"
|
|
9
|
+
>
|
|
5
10
|
{{ field.config?.label }}
|
|
6
11
|
</dt>
|
|
7
|
-
<dd
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
<dd class="psdk-csf-primary-field-data" [ngSwitch]="field.type.toLowerCase()">
|
|
13
|
+
<span *ngSwitchCase="'textinput'" class="psdk-csf-text-style">{{ field.config.value || '---' }}</span>
|
|
14
|
+
<span *ngSwitchCase="'status'" class="psdk-csf-status-style">{{ field.config.value || '---' }}</span>
|
|
15
|
+
<a *ngSwitchCase="'phone'" class="psdk-primary-color" as="a" href="tel: {{ field.config.value }}">{{ field.config.value || '---' }}</a>
|
|
16
|
+
<a *ngSwitchCase="'email'" class="psdk-primary-color" href="mailto: {{ field.config.value }}">{{ field.config.value || '---' }}</a>
|
|
17
|
+
<span *ngSwitchCase="'date'" class="psdk-csf-text-style">{{ field.config.value || '---' }}</span>
|
|
18
|
+
<div class="psdk-case-summary-operator" *ngSwitchCase="'caseoperator'">
|
|
19
|
+
<component-mapper
|
|
20
|
+
name="Operator"
|
|
21
|
+
[props]="{ pConn$: field?.kid, displayLabel: field?.displayLabel || field?.config.displayLabel }"
|
|
22
|
+
></component-mapper>
|
|
23
|
+
</div>
|
|
24
|
+
<div *ngSwitchCase="'objectreference'">
|
|
25
|
+
<component-mapper name="ObjectReference" [props]="{ pConn$: field.kid }"></component-mapper>
|
|
26
|
+
</div>
|
|
27
|
+
<div *ngSwitchCase="'reference'" class="psdk-csf-object-reference-value">
|
|
28
|
+
<component-mapper name="reference" [props]="{ pConn$: field.kid }"></component-mapper>
|
|
29
|
+
</div>
|
|
30
|
+
<span *ngSwitchDefault class="psdk-csf-text-style">{{ field.config.value || '---' }}</span>
|
|
12
31
|
</dd>
|
|
13
|
-
<ng-template #hasValue>
|
|
14
|
-
<dd class="psdk-csf-primary-field-data" [ngSwitch]="field.type.toLowerCase()">
|
|
15
|
-
<span *ngSwitchCase="'textinput'" class="psdk-csf-text-style">{{ field.config.value }}</span>
|
|
16
|
-
<span *ngSwitchCase="'status'" class="psdk-csf-status-style">{{ field.config.value }}</span>
|
|
17
|
-
<a *ngSwitchCase="'phone'" class="psdk-primary-color" as="a" href="tel: {{ field.config.value }}">{{ field.config.value }}</a>
|
|
18
|
-
<a *ngSwitchCase="'email'" class="psdk-primary-color" href="mailto: {{ field.config.value }}">{{ field.config.value }}</a>
|
|
19
|
-
<span *ngSwitchCase="'date'" class="psdk-csf-text-style">{{ field.config.value }}</span>
|
|
20
|
-
<label *ngSwitchCase="'caseoperator'">operator</label>
|
|
21
|
-
<div *ngSwitchCase="'objectreference'" class="psdk-csf-object-reference-value">
|
|
22
|
-
<component-mapper name="ObjectReference" [props]="{ pConn$: field.kid, displayMode: 'DISPLAY_ONLY', hideLabel: true }"></component-mapper>
|
|
23
|
-
</div>
|
|
24
|
-
<span *ngSwitchDefault class="psdk-csf-text-style">{{ field.config.value }}</span>
|
|
25
|
-
</dd>
|
|
26
|
-
</ng-template>
|
|
27
32
|
</div>
|
|
28
33
|
</dl>
|
|
29
34
|
</div>
|
|
30
35
|
<div class="psdk-case-summary-fields">
|
|
31
36
|
<dl *ngFor="let field of secondaryFields$" class="psdk-case-summary-fields-secondary">
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
@if (
|
|
38
|
+
field?.config?.label?.toLowerCase() == 'create operator' ||
|
|
39
|
+
field?.displayLabel?.toLowerCase() == 'create operator' ||
|
|
40
|
+
field?.config?.label?.toLowerCase() == 'update operator' ||
|
|
41
|
+
field?.displayLabel?.toLowerCase() == 'update operator'
|
|
42
|
+
) {
|
|
43
|
+
<div>
|
|
44
|
+
<component-mapper
|
|
45
|
+
name="Operator"
|
|
46
|
+
[props]="{ pConn$: field?.kid, displayLabel: field?.displayLabel || field?.config.displayLabel }"
|
|
47
|
+
></component-mapper>
|
|
48
|
+
</div>
|
|
49
|
+
} @else if (field.type.toLowerCase() === 'objectreference') {
|
|
50
|
+
<div class="psdk-csf-object-reference-value">
|
|
51
|
+
<component-mapper name="ObjectReference" [props]="{ pConn$: field.kid, displayMode: 'DISPLAY_ONLY', hideLabel: true }"></component-mapper>
|
|
52
|
+
</div>
|
|
53
|
+
} @else if (field.type.toLowerCase() === 'reference') {
|
|
54
|
+
<div class="psdk-csf-object-reference-value">
|
|
55
|
+
<component-mapper name="reference" [props]="{ pConn$: field.kid }"></component-mapper>
|
|
56
|
+
</div>
|
|
57
|
+
} @else {
|
|
47
58
|
<div class="psdk-csf-secondary-field">
|
|
48
59
|
<dt class="psdk-csf-secondary-field-header">
|
|
49
60
|
{{ field.config?.displayLabel || field.config?.label }}
|
|
50
61
|
</dt>
|
|
62
|
+
|
|
51
63
|
<dd class="psdk-csf-secondary-field-data">
|
|
52
64
|
<div [ngSwitch]="field.type.toLowerCase()">
|
|
53
65
|
<label *ngSwitchCase="'userreference'" class="psdk-secondary-value">{{ field.config.value.userName || '---' }}</label>
|
|
54
66
|
<label *ngSwitchCase="'checkbox'" class="psdk-secondary-value">{{ field.config.falseLabel || '---' }}</label>
|
|
55
|
-
<div *ngSwitchCase="'objectreference'" class="psdk-csf-object-reference-value">
|
|
56
|
-
<component-mapper
|
|
57
|
-
name="ObjectReference"
|
|
58
|
-
[props]="{ pConn$: field.kid, displayMode: 'DISPLAY_ONLY', hideLabel: true }"
|
|
59
|
-
></component-mapper>
|
|
60
|
-
</div>
|
|
61
67
|
<label *ngSwitchDefault class="psdk-secondary-value">{{ field.config.value || '---' }}</label>
|
|
62
68
|
</div>
|
|
63
69
|
</dd>
|
|
64
70
|
</div>
|
|
65
|
-
|
|
71
|
+
}
|
|
66
72
|
</dl>
|
|
67
73
|
</div>
|
package/lib/designSystemExtension/material-case-summary/material-case-summary.component.scss
CHANGED
|
@@ -110,3 +110,15 @@ span.psdk-csf-status-style {
|
|
|
110
110
|
.psdk-primary-color {
|
|
111
111
|
color: var(--mat-sys-primary);
|
|
112
112
|
}
|
|
113
|
+
|
|
114
|
+
.psdk-case-summary-operator {
|
|
115
|
+
::ng-deep .psdk-operator {
|
|
116
|
+
flex-direction: column !important;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.psdk-csf-object-reference-value {
|
|
121
|
+
::ng-deep .psdk-grid-label {
|
|
122
|
+
font-size: 0.8125rem !important;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -53,6 +53,17 @@ export class MaterialCaseSummaryComponent implements OnInit, OnChanges {
|
|
|
53
53
|
case 'checkbox':
|
|
54
54
|
field.config.displayLabel = field.config.caption;
|
|
55
55
|
break;
|
|
56
|
+
case 'reference': {
|
|
57
|
+
const referenceLabel = field.kid.getInheritedProps()?.label;
|
|
58
|
+
if (referenceLabel) {
|
|
59
|
+
field.config.label = referenceLabel;
|
|
60
|
+
}
|
|
61
|
+
field.kid.setInheritedProp('displayMode', 'DISPLAY_ONLY');
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case 'objectreference':
|
|
65
|
+
field.kid.setInheritedProp('displayMode', 'DISPLAY_ONLY');
|
|
66
|
+
break;
|
|
56
67
|
default:
|
|
57
68
|
break;
|
|
58
69
|
}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
<div class="psdk-label">
|
|
3
3
|
{{ label$ }}
|
|
4
4
|
</div>
|
|
5
|
-
<div class="psdk-
|
|
6
|
-
<
|
|
5
|
+
<div class="psdk-operator-details">
|
|
6
|
+
<div class="psdk-double">
|
|
7
|
+
<button mat-button color="primary" style="text-decoration: underline" (click)="showOperator()">{{ name$ }}</button>
|
|
8
|
+
</div>
|
|
9
|
+
<div>{{ date$ }}</div>
|
|
7
10
|
</div>
|
|
8
|
-
<div>{{ date$ }}</div>
|
|
9
11
|
</div>
|
|
10
12
|
|
|
11
13
|
<div>
|
|
@@ -2,12 +2,8 @@
|
|
|
2
2
|
<label [ngClass]="{ 'label-required': required === true }" class="rich-text-label">{{ label }}</label>
|
|
3
3
|
|
|
4
4
|
<div class="rich-text-editor" *ngIf="!readonly">
|
|
5
|
-
<div
|
|
6
|
-
class="tiptap-
|
|
7
|
-
[class.disabled]="disabled"
|
|
8
|
-
[class.tiptap-container-invalid]="richText.invalid && (error || richText.touched || richText.dirty)"
|
|
9
|
-
>
|
|
10
|
-
<div #editorEl class="tiptap-editor-area" [attr.aria-invalid]="richText.invalid && (error || richText.touched || richText.dirty)"></div>
|
|
5
|
+
<div class="tiptap-container" [class.disabled]="disabled" [class.tiptap-container-invalid]="showError">
|
|
6
|
+
<div #editorEl class="tiptap-editor-area" [attr.aria-invalid]="showError"></div>
|
|
11
7
|
|
|
12
8
|
<div class="tiptap-toolbar" *ngIf="!disabled" (mousedown)="$event.preventDefault()">
|
|
13
9
|
<mat-form-field class="tiptap-block-select" appearance="outline" subscriptSizing="dynamic">
|
|
@@ -105,7 +101,7 @@
|
|
|
105
101
|
</div>
|
|
106
102
|
</div>
|
|
107
103
|
|
|
108
|
-
<p *ngIf="
|
|
104
|
+
<p *ngIf="showError" [ngClass]="'text-editor-error'">{{ errorMessage }}</p>
|
|
109
105
|
</div>
|
|
110
106
|
|
|
111
107
|
<div *ngIf="readonly">
|
|
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
|
2
2
|
|
|
3
3
|
import { RichTextEditorComponent } from './rich-text-editor.component';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
5
|
+
describe('RichTextEditorComponent', () => {
|
|
6
6
|
let component: RichTextEditorComponent;
|
|
7
7
|
let fixture: ComponentFixture<RichTextEditorComponent>;
|
|
8
8
|
|
|
@@ -86,7 +86,7 @@ export class RichTextEditorComponent implements OnChanges, AfterViewInit, OnDest
|
|
|
86
86
|
this.initializeEditor();
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if (this.editor && changes['value'] && this.value !== this.editor
|
|
89
|
+
if (this.editor && changes['value'] && (this.value ?? '') !== this.getEditorValue(this.editor)) {
|
|
90
90
|
this.editor.commands.setContent(this.value ?? '', { emitUpdate: false });
|
|
91
91
|
}
|
|
92
92
|
if (this.editor && changes['disabled']) {
|
|
@@ -113,7 +113,7 @@ export class RichTextEditorComponent implements OnChanges, AfterViewInit, OnDest
|
|
|
113
113
|
content: this.value || '',
|
|
114
114
|
editable: !this.disabled,
|
|
115
115
|
onUpdate: ({ editor }) => {
|
|
116
|
-
const html =
|
|
116
|
+
const html = this.getEditorValue(editor);
|
|
117
117
|
this.richText.setValue(html, { emitEvent: false });
|
|
118
118
|
this.richText.markAsDirty();
|
|
119
119
|
this.onChange.emit(html);
|
|
@@ -121,7 +121,7 @@ export class RichTextEditorComponent implements OnChanges, AfterViewInit, OnDest
|
|
|
121
121
|
},
|
|
122
122
|
onBlur: ({ editor }) => {
|
|
123
123
|
this.richText.markAsTouched();
|
|
124
|
-
this.onBlur.emit(
|
|
124
|
+
this.onBlur.emit(this.getEditorValue(editor));
|
|
125
125
|
this.cdr.markForCheck();
|
|
126
126
|
},
|
|
127
127
|
onSelectionUpdate: ({ editor }) => {
|
|
@@ -132,6 +132,22 @@ export class RichTextEditorComponent implements OnChanges, AfterViewInit, OnDest
|
|
|
132
132
|
this.updateCurrentBlock(this.editor);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// Tiptap reports an empty document as "<p></p>", which would satisfy Validators.required and the engine's required check.
|
|
136
|
+
private getEditorValue(editor: Editor): string {
|
|
137
|
+
return editor.isEmpty ? '' : editor.getHTML();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get showError(): boolean {
|
|
141
|
+
return !!this.error || (this.richText.invalid && (this.richText.touched || this.richText.dirty));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
get errorMessage(): string {
|
|
145
|
+
if (!this.error && this.richText.hasError('required')) {
|
|
146
|
+
return 'You must enter a value';
|
|
147
|
+
}
|
|
148
|
+
return this.info;
|
|
149
|
+
}
|
|
150
|
+
|
|
135
151
|
private updateCurrentBlock(editor: Editor): void {
|
|
136
152
|
if (editor.isActive('heading', { level: 1 })) this.currentBlock = 'h1';
|
|
137
153
|
else if (editor.isActive('heading', { level: 2 })) this.currentBlock = 'h2';
|
|
@@ -415,7 +415,7 @@ export class AutoCompleteComponent extends FieldBase implements OnInit {
|
|
|
415
415
|
let key = '';
|
|
416
416
|
if (val) {
|
|
417
417
|
const index = this.options$?.findIndex(element => element.value === val);
|
|
418
|
-
key = index > -1 ?
|
|
418
|
+
key = index > -1 ? this.options$[index].key : val;
|
|
419
419
|
}
|
|
420
420
|
const value = key;
|
|
421
421
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
<div [formGroup]="formGroup$" *ngIf="bVisible$">
|
|
13
13
|
<div class="mat-form-field-infix" *ngIf="showLabel$">
|
|
14
14
|
<span>
|
|
15
|
-
<label class="mat-form-field-label psdk-label-readonly" [ngClass]="{ 'label-required': bRequired$ && selectionMode === 'multi' }">
|
|
16
|
-
label$
|
|
17
|
-
|
|
15
|
+
<label class="mat-form-field-label psdk-label-readonly" [ngClass]="{ 'label-required': bRequired$ && selectionMode === 'multi' }">
|
|
16
|
+
{{ label$ }}</label
|
|
17
|
+
>
|
|
18
18
|
</span>
|
|
19
19
|
</div>
|
|
20
20
|
<div *ngIf="selectionMode === 'multi'; else single">
|
|
21
|
-
<mat-option *ngFor="let item of listOfCheckboxes">
|
|
21
|
+
<div class="mat-mdc-option" *ngFor="let item of listOfCheckboxes">
|
|
22
22
|
<mat-checkbox
|
|
23
23
|
[labelPosition]="'after'"
|
|
24
24
|
[checked]="item.selected"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
(blur)="fieldOnBlur($event)"
|
|
29
29
|
>{{ item.text ?? item.value }}
|
|
30
30
|
</mat-checkbox>
|
|
31
|
-
</
|
|
31
|
+
</div>
|
|
32
32
|
</div>
|
|
33
33
|
<ng-template #single>
|
|
34
34
|
<mat-checkbox
|
|
@@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common';
|
|
|
3
3
|
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
4
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
5
5
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
-
import { MatOptionModule } from '@angular/material/core';
|
|
7
6
|
|
|
8
7
|
import { FieldBase } from '@pega/angular-sdk-components';
|
|
9
8
|
import { FieldWarningDirective } from '@pega/angular-sdk-components';
|
|
@@ -39,7 +38,6 @@ interface CheckboxProps extends Omit<PConnFieldProps, 'value'> {
|
|
|
39
38
|
ReactiveFormsModule,
|
|
40
39
|
MatCheckboxModule,
|
|
41
40
|
MatFormFieldModule,
|
|
42
|
-
MatOptionModule,
|
|
43
41
|
FieldWarningDirective,
|
|
44
42
|
forwardRef(() => ComponentMapperComponent)
|
|
45
43
|
]
|
|
@@ -97,6 +97,12 @@ export class DateTimeComponent extends FieldBase implements OnInit, OnDestroy {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
fieldOnDateChange(event: any) {
|
|
100
|
+
// owl picker emits null when the typed text can't be parsed; clear the input instead of defaulting to now
|
|
101
|
+
if (!event.value) {
|
|
102
|
+
this.fieldControl.setValue('');
|
|
103
|
+
handleEvent(this.actionsApi, 'changeNblur', this.propName, '');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
100
106
|
// this comes from the date pop up
|
|
101
107
|
if (typeof event.value === 'object') {
|
|
102
108
|
// convert date to pega "date" format
|
|
@@ -106,4 +112,25 @@ export class DateTimeComponent extends FieldBase implements OnInit, OnDestroy {
|
|
|
106
112
|
}
|
|
107
113
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
|
|
108
114
|
}
|
|
115
|
+
|
|
116
|
+
override getErrorMessage() {
|
|
117
|
+
// look for validation messages for json, pre-defined or just an error pushed from workitem (400)
|
|
118
|
+
if (this.fieldControl.hasError('message')) {
|
|
119
|
+
return this.angularPConnectData.validateMessage ?? '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (this.fieldControl.hasError('required')) {
|
|
123
|
+
return 'You must enter a value';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (this.fieldControl.hasError('owlDateTimeParse')) {
|
|
127
|
+
return `${this.fieldControl.errors?.['owlDateTimeParse'].text} is not a valid date time value`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (this.fieldControl.errors) {
|
|
131
|
+
return 'Invalid date time value';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
109
136
|
}
|
|
@@ -93,9 +93,9 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
|
|
|
93
93
|
set options(options: IOption[]) {
|
|
94
94
|
this.options$ = options;
|
|
95
95
|
if (this.displayMode$) {
|
|
96
|
-
this.value$ = this.options$?.find(option => option.key === this.value$)?.value || this.value$;
|
|
96
|
+
this.value$ = this.value$ === 'Select' ? '' : this.options$?.find(option => option.key === this.value$)?.value || this.value$;
|
|
97
97
|
this.localizedValue = this.pConn$.getLocalizedValue(
|
|
98
|
-
this.value
|
|
98
|
+
this.value$,
|
|
99
99
|
this.localePath,
|
|
100
100
|
this.pConn$.getLocaleRuleNameFromKeys(this.localeClass, this.localeContext, this.localeName)
|
|
101
101
|
);
|
|
@@ -136,7 +136,7 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
|
|
|
136
136
|
|
|
137
137
|
if (this.theDatasource) {
|
|
138
138
|
const optionsList = [...this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject())];
|
|
139
|
-
optionsList?.unshift(
|
|
139
|
+
optionsList?.unshift(this.getPlaceholderOption());
|
|
140
140
|
this.options = optionsList;
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -224,12 +224,17 @@ export class DropdownComponent extends FieldBase implements OnInit, OnDestroy {
|
|
|
224
224
|
};
|
|
225
225
|
optionsData.push(obj);
|
|
226
226
|
});
|
|
227
|
-
optionsData?.unshift(
|
|
227
|
+
optionsData?.unshift(this.getPlaceholderOption());
|
|
228
228
|
this.options = optionsData;
|
|
229
229
|
});
|
|
230
230
|
});
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
// Uses the authored placeholder, falling back to 'Select...' when none is authored
|
|
234
|
+
private getPlaceholderOption(): IOption {
|
|
235
|
+
return { key: 'Select', value: this.pConn$.getLocalizedValue(this.placeholder || 'Select...', '', '') };
|
|
236
|
+
}
|
|
237
|
+
|
|
233
238
|
isSelected(buttonValue: string): boolean {
|
|
234
239
|
return this.value$ === buttonValue;
|
|
235
240
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div [formGroup]="formGroup$">
|
|
2
2
|
<mat-form-field class="psdk-full-width" subscriptSizing="dynamic">
|
|
3
3
|
<mat-label>{{ label$ }}</mat-label>
|
|
4
|
-
<mat-chip-grid #chipGrid>
|
|
4
|
+
<mat-chip-grid #chipGrid [required]="bRequired$">
|
|
5
5
|
<ng-container *ngFor="let select of selectedItems">
|
|
6
6
|
<mat-chip-row (removed)="removeChip(select)">
|
|
7
7
|
{{ select.primary }}
|
|
@@ -90,7 +90,7 @@ export class MultiselectComponent extends FieldBase {
|
|
|
90
90
|
key: 'true'
|
|
91
91
|
}
|
|
92
92
|
];
|
|
93
|
-
let secondaryColumns: any
|
|
93
|
+
let secondaryColumns: any;
|
|
94
94
|
// Read columnsFormatter from raw (unresolved) metadata to get field property paths
|
|
95
95
|
// (e.g. "@P .pyLabel") instead of resolved data values (e.g. "New Complex Fields").
|
|
96
96
|
// This matches Constellation's approach: pConn.getRawMetadata()?.config?.columnsFormatter
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<ng-container *ngIf="bVisible$" [ngSwitch]="renderMode">
|
|
2
2
|
<!-- SingleReferenceReadOnly mode -->
|
|
3
3
|
<div *ngSwitchCase="'singleReferenceReadonly'">
|
|
4
|
-
<component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$,
|
|
4
|
+
<component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$, dataRelationshipContext }"></component-mapper>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<!-- MultiReferenceReadonly mode -->
|
|
@@ -46,7 +46,6 @@ type RenderMode = 'singleReferenceReadonly' | 'multiReferenceReadonly' | 'semant
|
|
|
46
46
|
export class ObjectReferenceComponent implements OnInit, OnDestroy {
|
|
47
47
|
@Input() pConn$: typeof PConnect;
|
|
48
48
|
@Input() formGroup$: FormGroup;
|
|
49
|
-
@Input() isDetails$ = false;
|
|
50
49
|
|
|
51
50
|
angularPConnectData: AngularPConnectData = {};
|
|
52
51
|
configProps: ObjectReferenceProps;
|
|
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
|
2
2
|
|
|
3
3
|
import { RichTextComponent } from './rich-text.component';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
5
|
+
describe('RichTextFieldComponent', () => {
|
|
6
6
|
let component: RichTextComponent;
|
|
7
7
|
let fixture: ComponentFixture<RichTextComponent>;
|
|
8
8
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
|
|
1
|
+
import { ChangeDetectorRef, Component, OnInit, Input, OnDestroy } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormGroup } from '@angular/forms';
|
|
4
4
|
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
|
|
@@ -46,7 +46,8 @@ export class SemanticLinkComponent implements OnInit, OnDestroy {
|
|
|
46
46
|
|
|
47
47
|
constructor(
|
|
48
48
|
private angularPConnect: AngularPConnectService,
|
|
49
|
-
private utils: Utils
|
|
49
|
+
private utils: Utils,
|
|
50
|
+
private cdr: ChangeDetectorRef
|
|
50
51
|
) {}
|
|
51
52
|
|
|
52
53
|
ngOnInit(): void {
|
|
@@ -81,6 +82,7 @@ export class SemanticLinkComponent implements OnInit, OnDestroy {
|
|
|
81
82
|
const isData = this.buildDataPayload();
|
|
82
83
|
this.linkURL = this.buildLinkURL(isData);
|
|
83
84
|
this.isLinkTextEmpty = isLinkTextEmpty(this.value$);
|
|
85
|
+
this.cdr.detectChanges();
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
showDataAction() {
|
|
@@ -234,7 +234,7 @@ export class UserReferenceComponent implements OnInit, OnDestroy {
|
|
|
234
234
|
let key = '';
|
|
235
235
|
if (event?.target?.value) {
|
|
236
236
|
const index = this.options$?.findIndex(element => element.value === event.target.value);
|
|
237
|
-
key = index > -1 ?
|
|
237
|
+
key = index > -1 ? this.options$[index].key : event.target.value;
|
|
238
238
|
}
|
|
239
239
|
const value = key;
|
|
240
240
|
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
|
|
@@ -166,10 +166,6 @@ export class ViewContainerComponent implements OnInit, OnDestroy {
|
|
|
166
166
|
const { accessedOrder, items } = routingInfo;
|
|
167
167
|
if (accessedOrder && items) {
|
|
168
168
|
const key = accessedOrder[accessedOrder.length - 1];
|
|
169
|
-
let componentVisible = accessedOrder.length > 0;
|
|
170
|
-
const { visible } = this.state;
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
172
|
-
componentVisible = visible || componentVisible;
|
|
173
169
|
if (items[key] && items[key].view && Object.keys(items[key].view).length > 0) {
|
|
174
170
|
const latestItem = items[key];
|
|
175
171
|
const rootView = latestItem.view;
|
|
@@ -100,6 +100,9 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
100
100
|
|
|
101
101
|
this.initComponent();
|
|
102
102
|
|
|
103
|
+
// ngOnChanges runs before ngOnInit, so updateChanges() never registers on first render.
|
|
104
|
+
this.registerForRefresh();
|
|
105
|
+
|
|
103
106
|
this.angularPConnect.shouldComponentUpdate(this);
|
|
104
107
|
|
|
105
108
|
this.bInitialized = true;
|
|
@@ -130,6 +133,9 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
130
133
|
// AND removing the "gate" that was put there since shouldComponentUpdate
|
|
131
134
|
// should be the real "gate"
|
|
132
135
|
if (bUpdateSelf) {
|
|
136
|
+
// The engine drops registrations when it cleans the context cache, so re-register on each update (as React does per render).
|
|
137
|
+
this.registerForRefresh();
|
|
138
|
+
|
|
133
139
|
let loadingInfo;
|
|
134
140
|
try {
|
|
135
141
|
// loadingInfo = this.pConn$.getLoadingStatus();
|
|
@@ -491,7 +497,11 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
491
497
|
}
|
|
492
498
|
|
|
493
499
|
registerForRefresh() {
|
|
494
|
-
const
|
|
500
|
+
const caseInfo = this.pConn$.getCaseInfo();
|
|
501
|
+
if (!caseInfo) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const refreshConditions = caseInfo.getActionRefreshConditions();
|
|
495
505
|
const pageReference = this.pConn$.getPageReference();
|
|
496
506
|
const context = this.pConn$.getContextName();
|
|
497
507
|
|
|
@@ -500,7 +510,7 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
|
|
|
500
510
|
|
|
501
511
|
// refresh api registration
|
|
502
512
|
const refreshProps = getRefreshProps(refreshConditions);
|
|
503
|
-
const caseKey =
|
|
513
|
+
const caseKey = caseInfo.getKey();
|
|
504
514
|
const refreshOptions = {
|
|
505
515
|
autoDetectRefresh: true,
|
|
506
516
|
preserveClientChanges: false
|
|
@@ -37,7 +37,7 @@ export function flattenObj(obj: any): any {
|
|
|
37
37
|
export const initializeSearchFields = (searchFields, getPConnect, referenceListClassID, searchFieldRestoreValues = {}) => {
|
|
38
38
|
const filtersProperties = {};
|
|
39
39
|
searchFields?.forEach(field => {
|
|
40
|
-
let val
|
|
40
|
+
let val;
|
|
41
41
|
const { value, defaultValue = '' } = field.config;
|
|
42
42
|
const propPath = PCore.getAnnotationUtils().getPropertyName(value);
|
|
43
43
|
|
|
@@ -265,7 +265,7 @@ export class DataReferenceComponent implements OnInit, OnDestroy {
|
|
|
265
265
|
if (this.pConn$.getContextName().includes('modal') || this.pConn$.getContextName().includes('workarea')) {
|
|
266
266
|
if (hasAssociatedViewConfigured || this.allowImplicitRefresh) {
|
|
267
267
|
const pageReference = this.pConn$.getPageReference();
|
|
268
|
-
let pgRef:
|
|
268
|
+
let pgRef: string;
|
|
269
269
|
if (pageReference.startsWith('objectInfo')) {
|
|
270
270
|
pgRef = pageReference.replace('objectInfo.content', '');
|
|
271
271
|
} else {
|
|
@@ -386,7 +386,7 @@ export class ListViewComponent implements OnInit, OnDestroy {
|
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
getValue(col) {
|
|
389
|
-
return this.
|
|
389
|
+
return this.fields$.find(f => f.config.name === col)?.config.label;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
getListData() {
|
|
@@ -625,11 +625,10 @@ export class ListViewComponent implements OnInit, OnDestroy {
|
|
|
625
625
|
}
|
|
626
626
|
|
|
627
627
|
_getIconStyle(level): string {
|
|
628
|
-
let sReturn = '';
|
|
629
628
|
let nLevel = parseInt(level, 10);
|
|
630
629
|
nLevel--;
|
|
631
630
|
nLevel *= 15;
|
|
632
|
-
sReturn = `padding-left: ${nLevel}px; vertical-align: middle`;
|
|
631
|
+
const sReturn = `padding-left: ${nLevel}px; vertical-align: middle`;
|
|
633
632
|
|
|
634
633
|
return sReturn;
|
|
635
634
|
}
|
|
@@ -1002,16 +1001,14 @@ export class ListViewComponent implements OnInit, OnDestroy {
|
|
|
1002
1001
|
let bKeep = true;
|
|
1003
1002
|
for (const filterObj of this.filterByColumns) {
|
|
1004
1003
|
if (filterObj.containsFilterValue != '' || filterObj.containsFilter == 'null' || filterObj.containsFilter == 'notnull') {
|
|
1005
|
-
let filterValue: any;
|
|
1006
|
-
|
|
1007
1004
|
switch (filterObj.type) {
|
|
1008
1005
|
case 'Date':
|
|
1009
1006
|
case 'DateTime':
|
|
1010
1007
|
case 'Time':
|
|
1011
|
-
bKeep = this.filterDataWithDate(item, filterObj
|
|
1008
|
+
bKeep = this.filterDataWithDate(item, filterObj);
|
|
1012
1009
|
break;
|
|
1013
1010
|
default:
|
|
1014
|
-
bKeep = this.filterDataWithCommonTypes(item, filterObj
|
|
1011
|
+
bKeep = this.filterDataWithCommonTypes(item, filterObj);
|
|
1015
1012
|
break;
|
|
1016
1013
|
}
|
|
1017
1014
|
}
|
|
@@ -1025,10 +1022,10 @@ export class ListViewComponent implements OnInit, OnDestroy {
|
|
|
1025
1022
|
return bKeep;
|
|
1026
1023
|
}
|
|
1027
1024
|
|
|
1028
|
-
filterDataWithDate(item, filterObj
|
|
1025
|
+
filterDataWithDate(item, filterObj) {
|
|
1029
1026
|
let bKeep;
|
|
1030
1027
|
let value = item[filterObj.ref] != null || item[filterObj.ref] != '' ? getSeconds(item[filterObj.ref]) : null;
|
|
1031
|
-
filterValue = filterObj.containsFilterValue != null && filterObj.containsFilterValue != '' ? getSeconds(filterObj.containsFilterValue) : null;
|
|
1028
|
+
let filterValue = filterObj.containsFilterValue != null && filterObj.containsFilterValue != '' ? getSeconds(filterObj.containsFilterValue) : null;
|
|
1032
1029
|
|
|
1033
1030
|
switch (filterObj.containsFilter) {
|
|
1034
1031
|
case 'notequal':
|
|
@@ -1071,10 +1068,10 @@ export class ListViewComponent implements OnInit, OnDestroy {
|
|
|
1071
1068
|
return bKeep;
|
|
1072
1069
|
}
|
|
1073
1070
|
|
|
1074
|
-
filterDataWithCommonTypes(item, filterObj
|
|
1071
|
+
filterDataWithCommonTypes(item, filterObj) {
|
|
1075
1072
|
let bKeep;
|
|
1076
1073
|
const value = item[filterObj.ref].toLowerCase();
|
|
1077
|
-
filterValue = filterObj.containsFilterValue.toLowerCase();
|
|
1074
|
+
const filterValue = filterObj.containsFilterValue.toLowerCase();
|
|
1078
1075
|
|
|
1079
1076
|
switch (filterObj.containsFilter) {
|
|
1080
1077
|
case 'contains':
|
|
@@ -216,6 +216,56 @@ export function getFieldLabel(fieldConfig) {
|
|
|
216
216
|
return fieldLabel;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
function trimAnnotation(anno) {
|
|
220
|
+
if (typeof anno !== 'string' || !anno.startsWith('@')) return anno;
|
|
221
|
+
const spaceIndex = anno.indexOf(' ');
|
|
222
|
+
if (spaceIndex === -1) return anno;
|
|
223
|
+
return anno.substring(spaceIndex + 1);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Resolves an "@FL" label from the data model and localizes it using the property's locale reference.
|
|
228
|
+
*/
|
|
229
|
+
function getLocalizedFieldLabel(fieldConfig, pConnect) {
|
|
230
|
+
const { classID, label, caption } = fieldConfig;
|
|
231
|
+
let fieldLabel = getPropertyNameFromConfigValue(label || caption);
|
|
232
|
+
const fieldMetaData: any = PCore.getMetadataUtils().getEmbeddedPropertyMetadata(fieldLabel, classID) ?? {};
|
|
233
|
+
fieldLabel = fieldMetaData.label ?? fieldMetaData.caption ?? fieldLabel;
|
|
234
|
+
const localeValue = pConnect.getLocalizationService(fieldMetaData.localeReference).getLocalizedText(fieldLabel);
|
|
235
|
+
return localeValue || fieldLabel;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function resolveFieldLabel(fieldViewMetadata, pConnect, classID?) {
|
|
239
|
+
const fieldClassID = classID || fieldViewMetadata.config.classID;
|
|
240
|
+
if (fieldClassID && pConnect) {
|
|
241
|
+
const fieldConfig: any = {
|
|
242
|
+
meta: fieldViewMetadata,
|
|
243
|
+
options: {
|
|
244
|
+
...pConnect.options,
|
|
245
|
+
hasForm: false,
|
|
246
|
+
localeReference: pConnect.getLocaleRuleName()
|
|
247
|
+
},
|
|
248
|
+
useCustomContext: { classID: fieldClassID }
|
|
249
|
+
};
|
|
250
|
+
const fieldPConnect = PCore.createPConnect(fieldConfig).getPConnect();
|
|
251
|
+
const resolvedProps: any = fieldPConnect.resolveConfigProps({
|
|
252
|
+
label: fieldViewMetadata.config.label || fieldViewMetadata.config.caption
|
|
253
|
+
});
|
|
254
|
+
if (resolvedProps.label) return resolvedProps.label;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let label = fieldViewMetadata.config.label || fieldViewMetadata.config.caption;
|
|
258
|
+
if (isFLProperty(label)) {
|
|
259
|
+
label = getLocalizedFieldLabel(fieldViewMetadata.config, pConnect);
|
|
260
|
+
} else {
|
|
261
|
+
label = trimAnnotation(label);
|
|
262
|
+
}
|
|
263
|
+
if (pConnect) {
|
|
264
|
+
label = pConnect.getLocalizedValue(label);
|
|
265
|
+
}
|
|
266
|
+
return label;
|
|
267
|
+
}
|
|
268
|
+
|
|
219
269
|
export const updateFieldLabels = (fields, configFields, primaryFieldsViewIndex, pConnect, options) => {
|
|
220
270
|
const labelsOfFields: any = [];
|
|
221
271
|
const { columnsRawConfig = [] } = options;
|
|
@@ -255,12 +305,9 @@ export const updateFieldLabels = (fields, configFields, primaryFieldsViewIndex,
|
|
|
255
305
|
};
|
|
256
306
|
|
|
257
307
|
export const buildFieldsForTable = (configFields, pConnect, showActionColumn, options) => {
|
|
258
|
-
const {
|
|
308
|
+
const { classID } = options;
|
|
259
309
|
|
|
260
|
-
|
|
261
|
-
const fieldsLabels = updateFieldLabels(fields, configFields, primaryFieldsViewIndex, pConnect, {
|
|
262
|
-
columnsRawConfig: pConnect.getRawConfigProps()?.children?.find(item => item?.name === 'Columns')?.children
|
|
263
|
-
});
|
|
310
|
+
const fieldsLabels = configFields?.map(field => resolveFieldLabel(field, pConnect, classID)) ?? [];
|
|
264
311
|
|
|
265
312
|
const fieldDefs = configFields?.map((field, index) => {
|
|
266
313
|
return {
|
|
@@ -363,7 +363,8 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
|
|
|
363
363
|
// Nebula and we may not end up using it all.
|
|
364
364
|
this.fieldDefs = buildFieldsForTable(configFields, this.pConn$, this.showActionColumn, {
|
|
365
365
|
primaryFieldsViewIndex,
|
|
366
|
-
fields: resolvedFields
|
|
366
|
+
fields: resolvedFields,
|
|
367
|
+
classID: contextClass
|
|
367
368
|
});
|
|
368
369
|
this.fieldDefs = this.fieldDefs?.filter(field => !(field.meta?.config?.hide === true));
|
|
369
370
|
this.initializeDefaultPageInstructions();
|
|
@@ -971,11 +972,10 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
|
|
|
971
972
|
}
|
|
972
973
|
|
|
973
974
|
_getIconStyle(level): string {
|
|
974
|
-
let sReturn = '';
|
|
975
975
|
let nLevel = parseInt(level, 10);
|
|
976
976
|
nLevel--;
|
|
977
977
|
nLevel *= 15;
|
|
978
|
-
sReturn = `padding-left: ${nLevel}px; vertical-align: middle`;
|
|
978
|
+
const sReturn = `padding-left: ${nLevel}px; vertical-align: middle`;
|
|
979
979
|
|
|
980
980
|
return sReturn;
|
|
981
981
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div [ngClass]="displayMode ? 'psdk-grid-display' : 'psdk-grid-nondisplay'"
|
|
1
|
+
<div [ngClass]="displayMode ? 'psdk-grid-display' : 'psdk-grid-nondisplay'">
|
|
2
2
|
<div *ngIf="label" class="psdk-grid-label">{{ label }}</div>
|
|
3
3
|
<component-mapper name="SemanticLink" [props]="{ pConn$: newPconn, formGroup$ }"></component-mapper>
|
|
4
4
|
</div>
|
|
@@ -15,7 +15,6 @@ export class SingleReferenceReadonlyComponent implements OnInit, OnDestroy {
|
|
|
15
15
|
@Input() pConn$: typeof PConnect;
|
|
16
16
|
@Input() formGroup$: FormGroup;
|
|
17
17
|
@Input() dataRelationshipContext: any = null;
|
|
18
|
-
@Input() isDetails$ = false;
|
|
19
18
|
|
|
20
19
|
angularPConnectData: AngularPConnectData = {};
|
|
21
20
|
configProps: any;
|
|
@@ -59,13 +58,13 @@ export class SingleReferenceReadonlyComponent implements OnInit, OnDestroy {
|
|
|
59
58
|
const rawViewMetadata = this.pConn$.getRawMetadata();
|
|
60
59
|
const label = this.configProps.label;
|
|
61
60
|
const showLabel = this.configProps.showLabel;
|
|
62
|
-
const
|
|
63
|
-
const
|
|
61
|
+
const inheritedProps = this.pConn$.getInheritedProps();
|
|
62
|
+
const propsToUse = { label: label || inheritedProps['label'], showLabel: inheritedProps['showLabel'] || showLabel };
|
|
63
|
+
const type = (rawViewMetadata?.config as any)?.componentType ?? rawViewMetadata?.type;
|
|
64
64
|
this.displayMode = this.configProps.displayMode;
|
|
65
65
|
const targetObjectType = this.configProps.targetObjectType;
|
|
66
66
|
const referenceType = targetObjectType === 'case' ? 'Case' : 'Data';
|
|
67
67
|
const hideLabel = this.configProps.hideLabel;
|
|
68
|
-
// const additionalFields = this.configProps.additionalFields;
|
|
69
68
|
const displayAs = this.configProps.displayAs ?? 'readonly';
|
|
70
69
|
const dataRelationshipContext =
|
|
71
70
|
this.dataRelationshipContext ?? getDataRelationshipContextFromKey((rawViewMetadata?.config as any)?.displayField ?? '');
|
|
@@ -77,7 +76,7 @@ export class SingleReferenceReadonlyComponent implements OnInit, OnDestroy {
|
|
|
77
76
|
const editableComponents = ['AutoComplete', 'SimpleTableSelect', 'Dropdown', 'RadioButtons'];
|
|
78
77
|
const config: any = {
|
|
79
78
|
...rawViewMetadata?.config,
|
|
80
|
-
primaryField: (rawViewMetadata?.config as any)?.displayField,
|
|
79
|
+
primaryField: (rawViewMetadata?.config as any)?.displayField ?? (rawViewMetadata?.config as any)?.primaryField,
|
|
81
80
|
label: this.label
|
|
82
81
|
};
|
|
83
82
|
|
|
@@ -49,7 +49,7 @@ export const fileDownloadVar = (content: { data: string; headers: Record<string,
|
|
|
49
49
|
if (!/^(http|https):\/\//.test(data)) {
|
|
50
50
|
data = `//${data}`;
|
|
51
51
|
}
|
|
52
|
-
window.open(
|
|
52
|
+
window.open(data, '_blank');
|
|
53
53
|
} else if (type === 'EMAIL') {
|
|
54
54
|
// Temp Fix: for EMAIL type attachment
|
|
55
55
|
fileDownload(content.data, name, 'html', content.headers);
|
|
@@ -194,8 +194,8 @@ export class AttachmentComponent implements OnInit, OnDestroy {
|
|
|
194
194
|
error: errorFile.props.error || null
|
|
195
195
|
};
|
|
196
196
|
});
|
|
197
|
-
let key
|
|
198
|
-
let updatedAttachments: any
|
|
197
|
+
let key: string;
|
|
198
|
+
let updatedAttachments: any;
|
|
199
199
|
if (this.allowMultiple$ || this.isOldAttachment) {
|
|
200
200
|
key = this.isOldAttachment ? `${this.valueRef}.pxResults` : this.valueRef;
|
|
201
201
|
const existingAttachments = PCore.getStoreValue(`.${key}`, this.pConn$.getPageReference(), this.pConn$.getContextName()) || [];
|
|
@@ -156,204 +156,6 @@ export class FeedContainerComponent implements OnInit, OnDestroy {
|
|
|
156
156
|
}
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
-
/*
|
|
160
|
-
|
|
161
|
-
const { getPConnect, messageIDs } = props;
|
|
162
|
-
const [mentionResults, setMentionResults] = useState([]);
|
|
163
|
-
const [tagResults, setTagResults] = useState([]);
|
|
164
|
-
const [attachments, setAttachments] = useState([]);
|
|
165
|
-
const [feedFilters, setFeedFilters] = useState();
|
|
166
|
-
const {
|
|
167
|
-
fetchMessages,
|
|
168
|
-
postMessage,
|
|
169
|
-
getMentionSuggestions,
|
|
170
|
-
getTagSuggestions
|
|
171
|
-
} = FeedApi(getPConnect());
|
|
172
|
-
const appName = PCore.getEnvironmentInfo().getApplicationName();
|
|
173
|
-
let value = "";
|
|
174
|
-
let feedID = "";
|
|
175
|
-
let feedClass = "";
|
|
176
|
-
if (getPConnect().getCaseSummary().ID) {
|
|
177
|
-
value = getPConnect().getCaseSummary().ID;
|
|
178
|
-
feedID = "pyCaseFeed";
|
|
179
|
-
feedClass = getPConnect().getCaseSummary().content.classID;
|
|
180
|
-
} else {
|
|
181
|
-
value = `DATA-PORTAL $${appName}`;
|
|
182
|
-
feedID = "pyDashboardFeed";
|
|
183
|
-
feedClass = "@baseclass";
|
|
184
|
-
}
|
|
185
|
-
// For cancelling fetchrequest for filetrs
|
|
186
|
-
const fetchMessagesCancelTokenSource = useRef([]);
|
|
187
|
-
|
|
188
|
-
useEffect(() => {
|
|
189
|
-
fetchMessages(
|
|
190
|
-
value,
|
|
191
|
-
feedID,
|
|
192
|
-
feedClass,
|
|
193
|
-
null,
|
|
194
|
-
fetchMessagesCancelTokenSource.current
|
|
195
|
-
).then((res) => {
|
|
196
|
-
setFeedFilters(res);
|
|
197
|
-
});
|
|
198
|
-
PCore.getAssetLoader().getLoader("component-loader")(["Activity"]);
|
|
199
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
200
|
-
}, []);
|
|
201
|
-
|
|
202
|
-
const onUploadProgress = useCallback((file) => {
|
|
203
|
-
return ({ loaded, total }) => {
|
|
204
|
-
file.progress = Math.floor((loaded / total) * 100);
|
|
205
|
-
setAttachments((current) => {
|
|
206
|
-
return current.map((currFile) => {
|
|
207
|
-
return currFile.name === file.name ? file : currFile;
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
}, []);
|
|
212
|
-
|
|
213
|
-
const errorHandler = useCallback((isFetchCanceled, file) => {
|
|
214
|
-
return (error) => {
|
|
215
|
-
if (!isFetchCanceled(error)) {
|
|
216
|
-
let localizedValue = "Upload failed";
|
|
217
|
-
if (
|
|
218
|
-
error.response &&
|
|
219
|
-
error.response.data &&
|
|
220
|
-
error.response.data.errorDetails
|
|
221
|
-
) {
|
|
222
|
-
localizedValue = error.response.data.errorDetails[0].localizedValue;
|
|
223
|
-
}
|
|
224
|
-
delete file.progress;
|
|
225
|
-
setAttachments((current) => {
|
|
226
|
-
return current.map((currFile) => {
|
|
227
|
-
if (currFile.name === file.name) {
|
|
228
|
-
currFile.meta = localizedValue;
|
|
229
|
-
currFile.error = true;
|
|
230
|
-
}
|
|
231
|
-
return currFile;
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
error.isHandled = true;
|
|
235
|
-
}
|
|
236
|
-
throw error;
|
|
237
|
-
};
|
|
238
|
-
}, []);
|
|
239
|
-
|
|
240
|
-
const postComment = ({ value: message, clear }) => {
|
|
241
|
-
const attachmentIDs = [];
|
|
242
|
-
const attachmentUtils = PCore.getAttachmentUtils();
|
|
243
|
-
if (attachments && !!attachments.length) {
|
|
244
|
-
attachments
|
|
245
|
-
.filter((file) => !file.error)
|
|
246
|
-
.map((file) => {
|
|
247
|
-
return attachmentUtils
|
|
248
|
-
.uploadAttachment(file, onUploadProgress, errorHandler)
|
|
249
|
-
.then((fileResponse) => {
|
|
250
|
-
const fileConfig = {
|
|
251
|
-
type: "File",
|
|
252
|
-
category: "File",
|
|
253
|
-
fileName: file.name,
|
|
254
|
-
ID: fileResponse.data.ID
|
|
255
|
-
};
|
|
256
|
-
attachmentIDs.push(fileConfig);
|
|
257
|
-
if (attachments.length === attachmentIDs.length) {
|
|
258
|
-
postMessage(
|
|
259
|
-
value,
|
|
260
|
-
transformMarkdownToMsg(message),
|
|
261
|
-
attachmentIDs
|
|
262
|
-
);
|
|
263
|
-
clear();
|
|
264
|
-
setAttachments([]);
|
|
265
|
-
}
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
.catch(console.error);
|
|
269
|
-
});
|
|
270
|
-
} else {
|
|
271
|
-
postMessage(value, transformMarkdownToMsg(message));
|
|
272
|
-
clear();
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
*/
|
|
277
|
-
|
|
278
|
-
/* On search is called when @ character is entered and will display the mention */
|
|
279
|
-
|
|
280
|
-
/*
|
|
281
|
-
const onSearch = debounce((event) => {
|
|
282
|
-
if (event.type === "mention") {
|
|
283
|
-
getMentionSuggestions({
|
|
284
|
-
pulseContext: value,
|
|
285
|
-
searchFor: event.search
|
|
286
|
-
}).then((res) => {
|
|
287
|
-
setMentionResults(res);
|
|
288
|
-
});
|
|
289
|
-
} else {
|
|
290
|
-
getTagSuggestions({
|
|
291
|
-
searchFor: event.search
|
|
292
|
-
}).then((res) => {
|
|
293
|
-
setTagResults(res);
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}, 150);
|
|
297
|
-
|
|
298
|
-
const userName = getPConnect().getEnvironmentInfo().getOperatorName();
|
|
299
|
-
const imageKey = getPConnect().getEnvironmentInfo().getOperatorImageInsKey();
|
|
300
|
-
|
|
301
|
-
const onFilesAdded = useCallback((newlyAddedFiles) => {
|
|
302
|
-
setAttachments((current) => [
|
|
303
|
-
...newlyAddedFiles.map((file) => {
|
|
304
|
-
if (!validateMaxSize(file, 5)) {
|
|
305
|
-
file.error = true;
|
|
306
|
-
file.meta = "File is too big. Max allowed size is 5MB.";
|
|
307
|
-
}
|
|
308
|
-
file.icon = getIconFromFileType(file.type);
|
|
309
|
-
file.onDelete = () => {
|
|
310
|
-
setAttachments((c) => c.filter((f) => f.name !== file.name));
|
|
311
|
-
};
|
|
312
|
-
return file;
|
|
313
|
-
}),
|
|
314
|
-
...current
|
|
315
|
-
]);
|
|
316
|
-
}, []);
|
|
317
|
-
|
|
318
|
-
const onFilterChange = useCallback(
|
|
319
|
-
(filterID) => {
|
|
320
|
-
const updatedFilters = [...feedFilters];
|
|
321
|
-
const filterToUpdate = updatedFilters.find(
|
|
322
|
-
(feedItem) => feedItem.id === filterID
|
|
323
|
-
);
|
|
324
|
-
filterToUpdate.on = !filterToUpdate.on;
|
|
325
|
-
if (filterID === "All")
|
|
326
|
-
updatedFilters.forEach((feedFilter) => {
|
|
327
|
-
feedFilter.on = filterToUpdate.on;
|
|
328
|
-
});
|
|
329
|
-
else if (
|
|
330
|
-
updatedFilters.find(
|
|
331
|
-
(feedItem) => feedItem.on === false && feedItem.id !== "All"
|
|
332
|
-
)
|
|
333
|
-
)
|
|
334
|
-
updatedFilters.find((feedItem) => feedItem.id === "All").on = false;
|
|
335
|
-
else updatedFilters.find((feedItem) => feedItem.id === "All").on = true;
|
|
336
|
-
setFeedFilters(updatedFilters);
|
|
337
|
-
fetchMessages(
|
|
338
|
-
value,
|
|
339
|
-
feedID,
|
|
340
|
-
feedClass,
|
|
341
|
-
feedFilters,
|
|
342
|
-
fetchMessagesCancelTokenSource.current
|
|
343
|
-
);
|
|
344
|
-
},
|
|
345
|
-
[
|
|
346
|
-
value,
|
|
347
|
-
feedID,
|
|
348
|
-
feedClass,
|
|
349
|
-
feedFilters,
|
|
350
|
-
fetchMessagesCancelTokenSource,
|
|
351
|
-
fetchMessages
|
|
352
|
-
]
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
*/
|
|
356
|
-
|
|
357
159
|
// set up svg images
|
|
358
160
|
this.svgComment$ = this.utils.getImageSrc('chat', this.utils.getSDKStaticContentUrl());
|
|
359
161
|
this.svgLike$ = this.utils.getImageSrc('thumbs-up', this.utils.getSDKStaticContentUrl());
|
|
@@ -545,7 +347,7 @@ export class FeedContainerComponent implements OnInit, OnDestroy {
|
|
|
545
347
|
}
|
|
546
348
|
|
|
547
349
|
likeClick(messageID: string, rMessageID: string, bLikedByMe: boolean, level: string) {
|
|
548
|
-
let pulseMessage
|
|
350
|
+
let pulseMessage: object;
|
|
549
351
|
|
|
550
352
|
if (level === 'top') {
|
|
551
353
|
pulseMessage = {
|
|
@@ -523,7 +523,7 @@ export class FileUtilityComponent implements OnInit, OnDestroy {
|
|
|
523
523
|
if (!/^(http|https):\/\//.test(data)) {
|
|
524
524
|
data = `//${data}`;
|
|
525
525
|
}
|
|
526
|
-
window.open(
|
|
526
|
+
window.open(data, '_blank');
|
|
527
527
|
}
|
|
528
528
|
})
|
|
529
529
|
.catch(console.error);
|