@pega/dx-component-builder-sdk
Version:
Utility for building custom UI components
232 lines (194 loc) • 8.26 kB
text/typescript
import { Component, OnInit, Input, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormGroup } from '@angular/forms';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { interval } from 'rxjs';
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
import { Utils } from '@pega/angular-sdk-components';
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
interface CaseViewProps {
// If any, enter additional props that only exist on this component
icon: string;
subheader: string;
header: string;
}
export class CaseViewComponent implements OnInit, OnDestroy {
pConn$: typeof PConnect;
formGroup$: FormGroup;
// Used with AngularPConnect
angularPConnectData: AngularPConnectData = {};
configProps$: CaseViewProps;
arChildren$: any[];
heading$ = '';
id$ = '';
status$ = '';
caseTabs$: any[] = [];
svgCase$: string;
tabData$: any;
mainTabs: any;
mainTabData: any;
arAvailableActions$: any[] = [];
arAvailabeProcesses$: any[] = [];
caseSummaryPConn$: any;
currentCaseID = '';
editAction: boolean;
bHasNewAttachments = false;
localizedVal: any;
localeCategory = 'CaseView';
localeKey: string;
constructor(
private cdRef: ChangeDetectorRef,
private angularPConnect: AngularPConnectService,
private utils: Utils
) {}
ngOnInit(): void {
// First thing in initialization is registering and subscribing to the AngularPConnect service
this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);
// this.updateSelf();
this.checkAndUpdate();
this.localizedVal = PCore.getLocaleUtils().getLocaleValue;
}
ngOnDestroy(): void {
if (this.angularPConnectData.unsubscribeFn) {
this.angularPConnectData.unsubscribeFn();
}
}
// Callback passed when subscribing to store change
onStateChange() {
this.checkAndUpdate();
}
checkAndUpdate() {
// Should always check the bridge to see if the component should update itself (re-render)
const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);
// ONLY call updateSelf when the component should update
// AND removing the "gate" that was put there since shouldComponentUpdate
// should be the real "gate"
if (bUpdateSelf) {
// generally, don't want to refresh everything when data changes in caseView, it is usually the
// case summary. But check if the case ID changes, this means a different case and we should
// update all.
if (this.hasCaseIDChanged()) {
this.fullUpdate();
// update okToInitFlowContainer, because case view was drawn, flow container will need to be init
// to match Nebula/Constellation
sessionStorage.setItem('okToInitFlowContainer', 'true');
} else {
this.updateHeaderAndSummary();
}
}
}
hasCaseIDChanged(): boolean {
if (this.currentCaseID !== this.pConn$.getDataObject().caseInfo.ID) {
this.currentCaseID = this.pConn$.getDataObject().caseInfo.ID;
return true;
}
return false;
}
updateHeaderAndSummary() {
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as CaseViewProps;
const hasNewAttachments = this.pConn$.getDataObject().caseInfo?.hasNewAttachments;
if (hasNewAttachments !== this.bHasNewAttachments) {
this.bHasNewAttachments = hasNewAttachments;
if (this.bHasNewAttachments) {
PCore.getPubSubUtils().publish(PCore.getEvents().getCaseEvent().CASE_ATTACHMENTS_UPDATED_FROM_CASEVIEW, true);
}
}
const kids = this.pConn$.getChildren() as any[];
for (const kid of kids) {
const meta = kid.getPConnect().getRawMetadata();
if (meta.type.toLowerCase() == 'region' && meta.name.toLowerCase() == 'summary') {
this.caseSummaryPConn$ = kid.getPConnect().getChildren()[0].getPConnect();
}
}
// have to put in a timeout, otherwise get an angular change event error
const timer = interval(100).subscribe(() => {
timer.unsubscribe();
this.heading$ = PCore.getLocaleUtils().getLocaleValue(this.configProps$.header, '', this.localeKey);
this.id$ = this.configProps$.subheader;
this.status$ = this.pConn$.getValue('.pyStatusWork');
});
}
fullUpdate() {
this.caseTabs$ = [];
this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as CaseViewProps;
// let caseTypeID = this.configProps$.ruleClass;
// let caseTypeName = this.configProps$.header;
// this.localeKey = `${caseTypeID}!CASE!${caseTypeName}`.toUpperCase();
this.localeKey = `${this.pConn$.getCaseInfo().getClassName()}!CASE!${this.pConn$.getCaseInfo().getName()}`.toUpperCase();
this.updateHeaderAndSummary();
this.arChildren$ = this.pConn$.getChildren() as any[];
const caseInfo = this.pConn$.getDataObject().caseInfo;
this.currentCaseID = caseInfo.ID;
this.arAvailableActions$ = caseInfo?.availableActions ? caseInfo.availableActions : [];
this.editAction = this.arAvailableActions$.find(action => action.ID === 'pyUpdateCaseDetails');
this.arAvailabeProcesses$ = caseInfo?.availableProcesses ? caseInfo.availableProcesses : [];
this.svgCase$ = this.utils.getImageSrc(this.configProps$.icon, this.utils.getSDKStaticContentUrl());
for (const kid of this.arChildren$) {
const kidPConn = kid.getPConnect();
if (kidPConn.getRawMetadata().name == 'Tabs') {
this.mainTabs = kid;
this.mainTabData = this.mainTabs.getPConnect().getChildren();
}
}
this.generateTabsData();
}
generateTabsData() {
this.mainTabs
.getPConnect()
.getChildren()
?.forEach((child, i) => {
const config = child.getPConnect().resolveConfigProps(child.getPConnect().getRawMetadata()).config;
let { label } = config;
const { inheritedProps, visibility } = config;
// For some tabs, "label" property is not avaialable in theTabCompConfig, so will get them from inheritedProps
if (!label) {
inheritedProps.forEach((inheritedProp: any) => {
if (inheritedProp.prop === 'label') {
label = inheritedProp.value;
}
});
}
// We'll display the tabs when either visibility property doesn't exist or is true(if exists)
if (visibility === undefined || visibility === true) {
this.caseTabs$.push({ name: label, id: i });
// To make first visible tab display at the beginning
if (!this.tabData$) {
this.tabData$ = { type: 'DeferLoad', config: child.getPConnect().getRawMetadata().config };
}
}
});
}
updateSelf() {
this.fullUpdate();
}
onTabClick(tab: any) {
this.tabData$ = this.mainTabData[tab].getPConnect().getRawMetadata();
this.cdRef.detectChanges();
}
_editClick() {
const editAction = this.arAvailableActions$.find(action => action.ID === 'pyUpdateCaseDetails');
const actionsAPI = this.pConn$.getActionsApi();
const openLocalAction = actionsAPI.openLocalAction.bind(actionsAPI);
openLocalAction(editAction.ID, { ...editAction, containerName: 'modal', type: 'express' });
}
_menuActionClick(data) {
const actionsAPI = this.pConn$.getActionsApi();
const openLocalAction = actionsAPI.openLocalAction.bind(actionsAPI);
openLocalAction(data.ID, { ...data, containerName: 'modal', type: 'express' });
}
_menuProcessClick(data) {
const actionsAPI = this.pConn$.getActionsApi();
const openProcessAction = actionsAPI.openProcessAction.bind(actionsAPI);
openProcessAction(data.ID, { ...data });
}
}