Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { GroupComponent } from '../../_components/field/group/group.component';
import { IntegerComponent } from '../../_components/field/integer/integer.component';
import { ListViewActionButtonsComponent } from '../../_components/field/list-view-action-buttons/list-view-action-buttons.component';
import { LocationComponent } from '../../_components/field/location/location.component';
import { ObjectReferenceComponent } from '../../_components/field/object-reference/object-reference.component';
import { PercentageComponent } from '../../_components/field/percentage/percentage.component';
import { PhoneComponent } from '../../_components/field/phone/phone.component';
import { RadioButtonsComponent } from '../../_components/field/radio-buttons/radio-buttons.component';
Expand Down Expand Up @@ -74,6 +75,7 @@ import { ListViewComponent } from '../../_components/template/list-view/list-vie
import { MultiReferenceReadonlyComponent } from '../../_components/template/multi-reference-readonly/multi-reference-readonly.component';
import { MultiselectComponent } from '../../_components/field/multiselect/multiselect.component';
import { NarrowWideFormComponent } from '../../_components/template/narrow-wide-form/narrow-wide-form.component';
import { ObjectPageComponent } from '../../_components/template/object-page/object-page.component';
import { OneColumnComponent } from '../../_components/template/one-column/one-column.component';
import { OneColumnPageComponent } from '../../_components/template/one-column-page/one-column-page.component';
import { OneColumnTabComponent } from '../../_components/template/one-column-tab/one-column-tab.component';
Expand Down Expand Up @@ -200,6 +202,8 @@ const pegaSdkComponentMap = {
NarrowWideForm: NarrowWideFormComponent,
// 'NarrowWidePage': NarrowWidePage,
NavBar: NavbarComponent,
ObjectPage: ObjectPageComponent,
ObjectReference: ObjectReferenceComponent,
OneColumn: OneColumnComponent,
OneColumnPage: OneColumnPageComponent,
OneColumnTab: OneColumnTabComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy, Output, EventEmitter } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatOptionModule } from '@angular/material/core';
Expand Down Expand Up @@ -47,6 +47,7 @@ interface AutoCompleteProps extends PConnFieldProps {
export class AutoCompleteComponent implements OnInit, OnDestroy {
@Input() pConn$: typeof PConnect;
@Input() formGroup$: FormGroup;
@Output() onRecordChange: EventEmitter<any> = new EventEmitter();

// Used with AngularPConnect
angularPConnectData: AngularPConnectData = {};
Expand Down Expand Up @@ -331,8 +332,9 @@ export class AutoCompleteComponent implements OnInit, OnDestroy {
}
const value = key;
handleEvent(this.actionsApi, 'changeNblur', this.propName, value);
if (this.configProps$?.onRecordChange) {
this.configProps$.onRecordChange(event);

if (this.onRecordChange) {
this.onRecordChange.emit(value);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy, EventEmitter, Output } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatOptionModule } from '@angular/material/core';
Expand Down Expand Up @@ -73,6 +73,7 @@ interface DropdownProps extends PConnFieldProps {
export class DropdownComponent implements OnInit, OnDestroy {
@Input() pConn$: typeof PConnect;
@Input() formGroup$: FormGroup;
@Output() onRecordChange: EventEmitter<any> = new EventEmitter();

// Used with AngularPConnect
angularPConnectData: AngularPConnectData = {};
Expand Down Expand Up @@ -336,12 +337,13 @@ export class DropdownComponent implements OnInit, OnDestroy {
event.value = '';
}
handleEvent(this.actionsApi, 'changeNblur', this.propName, event.value);
if (this.configProps$?.onRecordChange) {
this.configProps$.onRecordChange(event);
}

this.pConn$.clearErrorMessages({
property: this.propName
});
if (this.onRecordChange) {
this.onRecordChange.emit(event.value);
}
}

getLocalizedOptionValue(opt: IOption) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div *ngIf="isDisplayModeEnabled && !canBeChangedInReviewMode; else semanticLinkCheck">
<component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$ }"></component-mapper>
</div>
<ng-template #semanticLinkCheck>
<div *ngIf="type === 'SemanticLink' && !canBeChangedInReviewMode; else loadDynamicComp">
<component-mapper name="SemanticLink" [props]="{ pConn$: newPconn }"></component-mapper>
</div>
</ng-template>
<ng-template #loadDynamicComp>
<component-mapper
*ngIf="newComponentName"
[name]="newComponentName"
[props]="{ pConn$: newPconn, formGroup$ }"
[parent]="this"
[outputEvents]="{ onRecordChange: onRecordChange }"
></component-mapper>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ObjectReferenceComponent } from './object-reference.component';

describe('ObjectReferenceComponent', () => {
let component: ObjectReferenceComponent;
let fixture: ComponentFixture<ObjectReferenceComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ObjectReferenceComponent]
}).compileComponents();

fixture = TestBed.createComponent(ObjectReferenceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
import { CommonModule } from '@angular/common';
import { Component, Input, OnInit, forwardRef, OnDestroy } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ComponentMetadataConfig } from '@pega/pcore-pconnect-typedefs/interpreter/types';
import { AngularPConnectData, AngularPConnectService } from '../../../_bridge/angular-pconnect';
import { ComponentMapperComponent } from '../../../_bridge/component-mapper/component-mapper.component';
import { generateColumns, getDataRelationshipContextFromKey } from '../../../_helpers/objectReference-utils';
import { PConnFieldProps } from '../../../_types/PConnProps.interface';

interface ObjectReferenceProps extends PConnFieldProps {
showPromotedFilters: boolean;
inline: boolean;
parameters: Object;
mode: string;
targetObjectType: any;
allowAndPersistChangesInReviewMode: boolean;
}

@Component({
selector: 'app-object-reference',
imports: [CommonModule, forwardRef(() => ComponentMapperComponent)],
templateUrl: './object-reference.component.html',
styleUrl: './object-reference.component.scss'
})
export class ObjectReferenceComponent implements OnInit, OnDestroy {
@Input() pConn$: typeof PConnect;
@Input() formGroup$: FormGroup;

angularPConnectData: AngularPConnectData = {};
configProps: ObjectReferenceProps;
value: { [key: string]: any };
readOnly: boolean;
isForm: boolean;
type: string;
isDisplayModeEnabled: boolean;
canBeChangedInReviewMode: boolean;
newComponentName: string;
newPconn: typeof PConnect;
rawViewMetadata: ComponentMetadataConfig | undefined;

constructor(private angularPConnect: AngularPConnectService) {}

ngOnInit() {
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
this.checkAndUpdate();
}

onStateChange() {
this.checkAndUpdate();
}

ngOnDestroy() {
if (this.angularPConnectData.unsubscribeFn) {
this.angularPConnectData.unsubscribeFn();
}
}

checkAndUpdate() {
const shouldUpdate = this.angularPConnect.shouldComponentUpdate(this);
if (shouldUpdate) {
this.updateSelf();
}
}

updateSelf() {
this.configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as ObjectReferenceProps;
const displayMode = this.configProps.displayMode;
const editableInReview = this.configProps.allowAndPersistChangesInReviewMode ?? false;
const targetObjectType = this.configProps.targetObjectType;
const mode = this.configProps.mode;
const parameters = this.configProps.parameters;
const hideLabel = this.configProps.hideLabel;
const inline = this.configProps.inline;
const showPromotedFilters = this.configProps.showPromotedFilters;
const referenceType: string = targetObjectType === 'case' ? 'Case' : 'Data';
this.rawViewMetadata = this.pConn$.getRawMetadata();
const refFieldMetadata = this.pConn$.getFieldMetadata(this.rawViewMetadata?.config?.value?.split('.', 2)[1] ?? '');

// Destructured properties
const propsToUse = { ...this.pConn$.getInheritedProps(), ...this.configProps };

// Computed variables
this.isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY';
this.canBeChangedInReviewMode = editableInReview && ['Autocomplete', 'Dropdown'].includes((this.rawViewMetadata?.config as any)?.componentType);
// componentType is not defined in ComponentMetadataConfig type so using any
this.type = (this.rawViewMetadata?.config as any)?.componentType;

if (this.type === 'SemanticLink' && !this.canBeChangedInReviewMode) {
const config: any = {
...this.rawViewMetadata?.config,
primaryField: (this.rawViewMetadata?.config as any).displayField
};
config.caseClass = (this.rawViewMetadata?.config as any).targetObjectClass;
config.text = config.primaryField;
config.caseID = config.value;
config.contextPage = `@P .${
(this.rawViewMetadata?.config as any)?.displayField
? getDataRelationshipContextFromKey((this.rawViewMetadata?.config as any).displayField)
: null
}`;
config.resourceParams = {
workID: config.value
};
config.resourcePayload = {
caseClassName: config.caseClass
};

const component = this.pConn$.createComponent(
{
type: 'SemanticLink',
config: {
...config,
displayMode,
referenceType,
hideLabel,
dataRelationshipContext: (this.rawViewMetadata?.config as any)?.displayField
? getDataRelationshipContextFromKey((this.rawViewMetadata?.config as any).displayField)
: null
}
},
'',
0,
{}
);
this.newPconn = component?.getPConnect();
}

if (this.type !== 'SemanticLink' && !this.isDisplayModeEnabled) {
// 1) Set datasource
const config: any = { ...this.rawViewMetadata?.config };
generateColumns(config, this.pConn$, referenceType);
config.deferDatasource = true;
config.listType = 'datapage';
if (['Dropdown', 'AutoComplete'].includes(this.type) && !config.placeholder) {
config.placeholder = '@L Select...';
}

// 2) Pass through configs
config.showPromotedFilters = showPromotedFilters;

if (!this.canBeChangedInReviewMode) {
config.displayMode = displayMode;
}

// 3) Define field meta

const fieldMetaData = {
datasourceMetadata: {
datasource: {
parameters: {},
propertyForDisplayText: false,
propertyForValue: false,
name: ''
}
}
};
if (config?.parameters) {
fieldMetaData.datasourceMetadata.datasource.parameters = parameters;
}
fieldMetaData.datasourceMetadata.datasource.propertyForDisplayText = config?.datasource?.fields?.text?.startsWith('@P')
? config?.datasource?.fields?.text?.substring(3)
: config?.datasource?.fields?.text;
fieldMetaData.datasourceMetadata.datasource.propertyForValue = config?.datasource?.fields?.value?.startsWith('@P')
? config?.datasource?.fields?.value?.substring(3)
: config?.datasource?.fields?.value;
fieldMetaData.datasourceMetadata.datasource.name = config?.referenceList ?? '';

const component = this.pConn$.createComponent(
{
type: this.type,
config: {
...config,
descriptors: mode === 'single' ? refFieldMetadata?.descriptors : null,
datasourceMetadata: fieldMetaData?.datasourceMetadata,
required: propsToUse.required,
visibility: propsToUse.visibility,
disabled: propsToUse.disabled,
label: propsToUse.label,
parameters: config.parameters,
readOnly: false,
localeReference: config.localeReference,
...(mode === 'single' ? { referenceType } : ''),
contextClass: config.targetObjectClass,
primaryField: config?.displayField,
dataRelationshipContext: config?.displayField ? getDataRelationshipContextFromKey(config.displayField) : null,
hideLabel,
inline
}
},
'',
0,
{}
);
this.newComponentName = component?.getPConnect().getComponentName();
this.newPconn = component?.getPConnect();
if (this.rawViewMetadata?.config) {
this.rawViewMetadata.config = config ? { ...config } : this.rawViewMetadata.config;
}
}
}

onRecordChange(value) {
const caseKey = this.pConn$.getCaseInfo().getKey() ?? '';
const refreshOptions = { autoDetectRefresh: true, propertyName: '' };
refreshOptions.propertyName = this.rawViewMetadata?.config?.value ?? '';

if (!this.canBeChangedInReviewMode || !this.pConn$.getValue('__currentPageTabViewName')) {
const pgRef = this.pConn$.getPageReference().replace('caseInfo.content', '') ?? '';
const viewName = this.rawViewMetadata?.name;
if (viewName && viewName.length > 0) {
getPConnect().getActionsApi().refreshCaseView(caseKey, viewName, pgRef, refreshOptions);
}
}

const propValue = value;
const propName =
this.rawViewMetadata?.type === 'SimpleTableSelect' && this.configProps.mode === 'multi'
? PCore.getAnnotationUtils().getPropertyName(this.rawViewMetadata?.config?.selectionList ?? '')
: PCore.getAnnotationUtils().getPropertyName(this.rawViewMetadata?.config?.value ?? '');

if (propValue && this.canBeChangedInReviewMode && this.isDisplayModeEnabled) {
PCore.getCaseUtils()
.getCaseEditLock(caseKey, '')
.then(caseResponse => {
const pageTokens = this.pConn$.getPageReference().replace('caseInfo.content', '').split('.');
let curr = {};
const commitData = curr;

pageTokens?.forEach(el => {
if (el !== '') {
curr[el] = {};
curr = curr[el];
}
});

// expecting format like {Customer: {pyID:"C-100"}}
const propArr = propName.split('.');
propArr.forEach((element, idx) => {
if (idx + 1 === propArr.length) {
curr[element] = propValue;
} else {
curr[element] = {};
curr = curr[element];
}
});

PCore.getCaseUtils()
.updateCaseEditFieldsData(caseKey, { [caseKey]: commitData }, caseResponse.headers.etag, this.pConn$?.getContextName() ?? '')
.then(response => {
PCore.getContainerUtils().updateParentLastUpdateTime(this.pConn$.getContextName() ?? '', response.data.data.caseInfo.lastUpdateTime);
PCore.getContainerUtils().updateRelatedContextEtag(this.pConn$.getContextName() ?? '', response.headers.etag);
});
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class SelectableCardComponent implements OnInit, OnDestroy {

this.selectionList = this.configProps$.selectionList;
this.selectedvalues = this.configProps$.readonlyContextList;
this.showNoValue = this.readOnly && this.selectedvalues.length === 0; // not used
this.showNoValue = this.readOnly && this.selectedvalues?.length === 0; // not used
this.primaryField = this.configProps$.primaryField;
}

Expand Down
Loading