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 { EmbeddedDataMultiComponent } from '../../_components/field/embedded-data-multi/embedded-data-multi.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';
Expand Down Expand Up @@ -175,6 +176,7 @@ const pegaSdkComponentMap = {
Dropdown: DropdownComponent,
DynamicTabs: DynamicTabsComponent,
Email: EmailComponent,
EmbeddedDataMulti: EmbeddedDataMultiComponent,
ErrorBoundary: ErrorBoundaryComponent,
FeedContainer: FeedContainerComponent,
FieldGroup: FieldGroupComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</span>
</div>
<div *ngIf="selectionMode === 'multi'; else single">
<mat-option *ngFor="let item of listOfCheckboxes" (click)="handleChangeMultiMode($event, item)">
<mat-option *ngFor="let item of listOfCheckboxes">
<mat-checkbox
[labelPosition]="'after'"
[checked]="item.selected"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div *ngIf="bVisible$ && simpleTableComponentName">
<component-mapper [name]="simpleTableComponentName" [props]="{ pConn$: simpleTablePConn, formGroup$ }"></component-mapper>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import { CommonModule } from '@angular/common';
import { Component, Input, OnInit, OnDestroy, forwardRef } from '@angular/core';
import { FormGroup } from '@angular/forms';

import { AngularPConnectData, AngularPConnectService } from '../../../_bridge/angular-pconnect';
import { ComponentMapperComponent } from '../../../_bridge/component-mapper/component-mapper.component';

interface EmbeddedDataMultiProps {
addEditAction?: string;
addEditView?: string;
displayAs?: string;
editAction?: string;
editMode?: string;
editType?: string;
editView?: string;
readOnly?: boolean;
repeatingView?: string;
targetObjectClass?: string;
useSeparateActionForEdit?: boolean;
useSeparateViewForEdit?: boolean;
visibility?: boolean;
}

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

angularPConnectData: AngularPConnectData = {};
simpleTablePConn: typeof PConnect;
simpleTableComponentName = '';
bVisible$ = true;

constructor(private angularPConnect: AngularPConnectService) {}

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

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

onStateChange = () => {
this.checkAndUpdate();
};

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

updateSelf() {
const configProps = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as EmbeddedDataMultiProps;
const {
addEditAction,
addEditView,
displayAs,
editAction,
editMode,
editType,
editView,
readOnly = false,
repeatingView,
targetObjectClass,
useSeparateActionForEdit,
useSeparateViewForEdit,
visibility = true
} = configProps;

this.bVisible$ = visibility !== false;

const rawMetadata = this.pConn$.getRawMetadata();
const rawMetadataConfig = rawMetadata?.config as any;

if (!rawMetadataConfig) {
return;
}

const renderMode = readOnly ? 'ReadOnly' : 'Editable';

let columnsChildren;
if (displayAs === 'table' || displayAs === 'simpleTable') {
columnsChildren = [
{
children: rawMetadataConfig.columns || [],
name: 'Columns',
type: 'Region'
}
];
}

let regionWithView: any[] = [];
if (displayAs === 'repeatingView') {
regionWithView = [
{
children: [
{
type: 'reference',
config: {
type: 'view',
name: repeatingView
}
}
],
name: 'view',
type: 'Region'
}
];
}

const { pagelistValue } = rawMetadataConfig;
const authorContext = pagelistValue?.startsWith('@P') ? pagelistValue?.substring(3) : pagelistValue;

const componentConfig = {
type: 'View',
config: {
template: 'SimpleTable',
type: 'multirecordlist',
authorContext,
name: authorContext?.substring(1),
renderMode,
multiRecordDisplayAs: displayAs === 'repeatingView' ? 'fieldGroup' : displayAs,
referenceList: pagelistValue,
contextClass: targetObjectClass,
editMode,
editModeConfig: {
editType,
defaultView: addEditView,
defaultAction: addEditAction,
useSeparateViewForEdit,
useSeparateActionForEdit,
editView,
editAction
},
label: rawMetadataConfig.label,
hideLabel: rawMetadataConfig.hideLabel,
children: columnsChildren,
displayField: rawMetadataConfig.displayField,
uniqueField: rawMetadataConfig.uniqueField,
targetClassLabel: rawMetadataConfig.targetClassLabel,
targetClassLabelOption: rawMetadataConfig.targetClassLabelOption,
fieldHeader: rawMetadataConfig.repeatingViewHeadingSource,
heading: rawMetadataConfig.repeatingViewHeading,
allowActions: {
allowAdd: rawMetadataConfig.allowAdd ?? true,
allowEdit: rawMetadataConfig.allowEdit ?? true,
allowDelete: rawMetadataConfig.allowDelete ?? true,
allowDragDrop: rawMetadataConfig.allowDragDrop ?? true
},
allowRowDelete: rawMetadataConfig.allowRowDelete ?? true,
allowRowEdit: rawMetadataConfig.allowRowEdit ?? true
},
children: regionWithView
};

const component = this.pConn$.createComponent(componentConfig as any, '', 0, {});
if (component) {
this.simpleTablePConn = component.getPConnect();
this.simpleTableComponentName = this.simpleTablePConn.getComponentName() ?? '';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,32 @@ export class MultiselectComponent extends FieldBase {
}
];
let secondaryColumns: any = [];
if (secondaryFields) {
secondaryColumns = secondaryFields.map(secondaryField => ({
value: secondaryField,
// Read columnsFormatter from raw (unresolved) metadata to get field property paths
// (e.g. "@P .pyLabel") instead of resolved data values (e.g. "New Complex Fields").
// This matches Constellation's approach: pConn.getRawMetadata()?.config?.columnsFormatter
const columnsFormatter = (this.pConn$.getRawMetadata()?.config as any)?.columnsFormatter;
const secondaryFieldsFromFormatter = columnsFormatter
? columnsFormatter
.map(item => {
const property = item?.config?.value;
if (typeof property === 'string') {
if (property.startsWith('@USER ')) return property.substring(6);
if (property.startsWith('@P ')) return property.substring(3);
return property;
}
return undefined;
})
.filter(Boolean)
: undefined;
const updatedSecondaryFields = secondaryFieldsFromFormatter || secondaryFields;
if (updatedSecondaryFields) {
secondaryColumns = updatedSecondaryFields.map(secondaryField => ({
value: typeof secondaryField === 'string' ? secondaryField : undefined,
display: 'true',
secondary: 'true',
useForSearch: 'true'
}));
secondaryColumns = secondaryColumns.filter(col => col.value);
} else {
secondaryColumns = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ export function setVisibilityForList(c11nEnv, visibility) {
function preProcessColumns(columns) {
return columns?.map(col => {
const tempColObj = { ...col };
tempColObj.value = col.value && col.value.startsWith('.') ? col.value.substring(1) : col.value;
if (tempColObj.setProperty) {
tempColObj.setProperty = col.setProperty && col.setProperty.startsWith('.') ? col.setProperty.substring(1) : col.setProperty;
if (typeof col.value === 'string') {
tempColObj.value = col.value.startsWith('.') ? col.value.substring(1) : col.value;
}
if (typeof col.setProperty === 'string') {
tempColObj.setProperty = col.setProperty.startsWith('.') ? col.setProperty.substring(1) : col.setProperty;
}
return tempColObj;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
<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">
<ng-container *ngIf="bVisible$" [ngSwitch]="renderMode">
<!-- SingleReferenceReadOnly mode -->
<div *ngSwitchCase="'singleReferenceReadonly'">
<component-mapper name="SingleReferenceReadOnly" [props]="{ pConn$ }"></component-mapper>
</div>

<!-- MultiReferenceReadonly mode -->
<div *ngSwitchCase="'multiReferenceReadonly'">
<component-mapper name="MultiReferenceReadOnly" [props]="{ pConn$ }"></component-mapper>
</div>

<!-- SemanticLink mode -->
<div *ngSwitchCase="'semanticLink'">
<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>

<!-- SearchAndSelect mode -->
<div *ngSwitchCase="'searchAndSelect'">
<component-mapper name="SearchForm" [props]="{ pConn$, formGroup$, searchSelectCacheKey, type: 'ObjectReference' }"></component-mapper>
</div>

<!-- Dynamic component mode (Cards, Map, CheckboxGroup, Table, Multiselect, Dropdown, AutoComplete, etc.) -->
<div *ngSwitchCase="'dynamicComponent'">
<component-mapper
*ngIf="newComponentName"
[name]="newComponentName"
[props]="{ pConn$: newPconn, formGroup$ }"
[parent]="this"
[outputEvents]="useOutputEvents ? { onRecordChange: onRecordChange } : undefined"
></component-mapper>
</div>
</ng-container>
Loading
Loading