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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* Github: [PR-577](https://github.com/pegasystems/angular-sdk-components/pull/577)
* **DataReference as Autocomplete supports grouping.**
* Github: [PR-578](https://github.com/pegasystems/angular-sdk-components/pull/578)
* **Added support for primary fields in EmbeddedData and query params for refreshFor action.**
* Github: [PR-584](https://github.com/pegasystems/angular-sdk-components/pull/584)
* **Added support for creating new records for the Autocomplete DataReference and CaseReference components.**
* Github: [PR-585](https://github.com/pegasystems/angular-sdk-components/pull/585)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,14 @@ export class AssignmentComponent implements OnInit, OnDestroy, OnChanges {
refreshProps.forEach(prop => {
PCore.getRefreshManager().registerForRefresh(
'PROP_CHANGE',
this.pConn$.getActionsApi().refreshCaseView.bind(this.pConn$.getActionsApi(), caseKey, '', pageReference, {
...refreshOptions,
refreshFor: prop[0]
}),
// The registered prop is an authored pattern with an empty list index (ex: ".Addons().Type"),
// which the server rejects. The refresh manager hands back the concrete path that changed.
(matchedPath?: string) => {
this.pConn$.getActionsApi().refreshCaseView(caseKey, '', pageReference, {
...refreshOptions,
refreshFor: matchedPath || prop[0]
});
},
`${pageReference}.${prop[1]}`,
`${context}/${pageReference}`,
context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,33 @@ const SUPPORTED_FIELD_TYPES = [
'RichText'
];

// PCore.getNameSpaceUtils() exists at runtime but is missing from the pcore typedefs.
export const getQualifiedPrimaryFieldsName = (): string =>
(PCore as any).getNameSpaceUtils?.()?.getDefaultQualifiedName(PRIMARY_FIELDS) ?? PRIMARY_FIELDS;

export const isPrimaryFieldsValue = (value): boolean => value === PRIMARY_FIELDS || value === getQualifiedPrimaryFieldsName();

/**
* Strips annotation prefixes (ex: "@P .FirstName") and the leading dot from a raw config value.
*/
export const getPropertyNameFromConfigValue = (configValue): string => {
let name = configValue ?? '';
if (name.startsWith('@')) {
name = name.substring(name.indexOf(' ') + 1);
}
if (name.startsWith('.')) {
name = name.substring(1);
}
return name;
};

export const getConfigFields = (rawFields, contextClass, primaryFieldsViewIndex) => {
let primaryFields: any = [];
let configFields: any = [];
const safeRawFields = rawFields || [];

if (primaryFieldsViewIndex > -1) {
let primaryFieldVMD: any = PCore.getMetadataUtils().resolveView(PRIMARY_FIELDS);
let primaryFieldVMD: any = PCore.getMetadataUtils().resolveView(getQualifiedPrimaryFieldsName());
if (Array.isArray(primaryFieldVMD)) {
primaryFieldVMD = primaryFieldVMD.find(primaryFieldView => primaryFieldView.classID === contextClass);
primaryFields = primaryFieldVMD?.children?.[0]?.children || [];
Expand All @@ -166,7 +187,7 @@ export const getConfigFields = (rawFields, contextClass, primaryFieldsViewIndex)
}
}

configFields = [...rawFields.slice(0, primaryFieldsViewIndex), ...primaryFields, ...rawFields.slice(primaryFieldsViewIndex + 1)];
configFields = [...safeRawFields.slice(0, primaryFieldsViewIndex), ...primaryFields, ...safeRawFields.slice(primaryFieldsViewIndex + 1)];
// filter duplicate fields after combining raw fields and primary fields
return configFields.filter((field, index) => configFields.findIndex(_field => field.config?.value === _field.config?.value) === index);
};
Expand Down Expand Up @@ -200,7 +221,7 @@ export const updateFieldLabels = (fields, configFields, primaryFieldsViewIndex,
const { columnsRawConfig = [] } = options;
fields.forEach((field, idx) => {
const rawColumnConfig = columnsRawConfig[idx]?.config;
if (field.config.value === PRIMARY_FIELDS) {
if (isPrimaryFieldsValue(field.config.value)) {
labelsOfFields.push('');
} else if (isFLProperty(rawColumnConfig?.label ?? rawColumnConfig?.caption)) {
labelsOfFields.push(getFieldLabel(rawColumnConfig) || field.config.label || field.config.caption);
Expand Down Expand Up @@ -247,7 +268,7 @@ export const buildFieldsForTable = (configFields, pConnect, showActionColumn, op
label: fieldsLabels[index],
fillAvailableSpace: !!field.config.fillAvailableSpace,
id: `${index}`,
name: field.config.value.substr(4),
name: getPropertyNameFromConfigValue(field.config.value),
cellRenderer: TABLE_CELL,
sort: false,
noContextMenu: true,
Expand All @@ -256,7 +277,7 @@ export const buildFieldsForTable = (configFields, pConnect, showActionColumn, op
...field
},
// BUG-615253: Workaround for autosize in table with lazy loading components
width: getFieldWidth(field, fields[index].config.label)
width: getFieldWidth(field, fieldsLabels[index])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

width is not useful for us in both react and angular

};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ tr.mat-mdc-header-row {
text-align: center;
border: 1px solid var(--mat-sys-outline-variant);
border-top: none;

td.mat-cell {
text-align: center;
}
}

.psdk-utility-card-action-svg-icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ComponentMapperComponent } from '../../../_bridge/component-mapper/comp
import { AngularPConnectData, AngularPConnectService } from '../../../_bridge/angular-pconnect';
import { DatapageService } from '../../../_services/datapage.service';
import { getReferenceList } from '../../../_helpers/field-group-utils';
import { buildFieldsForTable, filterDataByCommonFields, filterDataByDate, getContext } from './helpers';
import { buildFieldsForTable, filterDataByCommonFields, filterDataByDate, getConfigFields, getContext, isPrimaryFieldsValue } from './helpers';
import { evaluateAllowRowAction } from '../utils';
import { Utils } from '../../../_helpers/utils';
import { getSeconds } from '../../../_helpers/common';
Expand Down Expand Up @@ -48,6 +48,7 @@ interface SimpleTableManualProps {
useSeparateViewForEdit: any;
viewForEditModal: any;
targetClassLabel?: string;
uniqueField?: string;
}

class Group {
Expand Down Expand Up @@ -115,6 +116,9 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
elementsData: MatTableDataSource<any>;
originalElementsData: MatTableDataSource<any>;
rawFields: any;
configFields: any[] = [];
uniqueField?: string;
normalizedUniqueField?: string;
label?: string = '';
searchIcon$: string;

Expand Down Expand Up @@ -262,9 +266,15 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
displayMode,
useSeparateViewForEdit,
viewForEditModal,
targetClassLabel
targetClassLabel,
uniqueField
} = this.configProps$;

// uniqueField is authored as a property reference (ex: ".EmbedListUUID__"); page instructions expect it
// with the leading dot while the inserted row payload expects the bare property name.
this.uniqueField = uniqueField;
this.normalizedUniqueField = uniqueField?.startsWith('.') ? uniqueField.substring(1) : uniqueField;

const simpleTableManualProps: any = {};
if (this.checkIfAllowActionsOrRowEditingExist(allowActions) && editMode) {
simpleTableManualProps.hideAddRow = allowActions?.allowAdd === false;
Expand Down Expand Up @@ -335,9 +345,14 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
this.defaultActionId = this.editType === 'action' ? editModeConfig?.defaultAction : undefined;
this.editActionId =
this.editType === 'action' && editModeConfig?.useSeparateActionForEdit ? editModeConfig?.editAction : editModeConfig?.defaultAction;
const primaryFieldsViewIndex = resolvedFields.findIndex(field => field.config.value === 'pyPrimaryFields');
const primaryFieldsViewIndex = resolvedFields?.findIndex(field => isPrimaryFieldsValue(field.config.value)) ?? -1;
// const showDeleteButton = !this.readOnlyMode && !hideDeleteRow;

// "pyPrimaryFields" is a single authored column that expands into several real columns, so the
// resolved/raw children can no longer be used directly - configFields is the expanded column list.
const configFields = getConfigFields(rawFields, contextClass, primaryFieldsViewIndex);
this.configFields = configFields.filter(field => !(field?.config?.hide === true));

// Nebula has other handling for isReadOnlyMode but has Cosmos-specific code
// so ignoring that for now...
// fieldDefs will be an array where each entry will have a "name" which will be the
Expand All @@ -346,7 +361,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
// Nebula does). It will also have the "label", and "meta" contains the original,
// unchanged config info. For now, much of the info here is carried over from
// Nebula and we may not end up using it all.
this.fieldDefs = buildFieldsForTable(rawFields, this.pConn$, this.showActionColumn, {
this.fieldDefs = buildFieldsForTable(configFields, this.pConn$, this.showActionColumn, {
primaryFieldsViewIndex,
fields: resolvedFields
});
Expand All @@ -362,20 +377,17 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
return field.name ? field.name : field.cellRenderer;
});

// And now we can process the resolvedFields to add in the "name"
// And now we can process the configFields to add in the "name"
// from from the fieldDefs. This "name" is the value that
// we'll share to connect things together in the table.

const labelsMap = this.fieldDefs.reduce((acc, curr) => {
return { ...acc, [curr.name]: curr.label };
}, {});

this.processedFields = [];

this.processedFields = resolvedFields.map((field, i) => {
field.config.name = this.displayedColumns[i]; // .config["value"].replace(/ ./g,"_"); // replace space dot with underscore
field.config.label = labelsMap[field.config.name] || field.config.label;
return field;
this.processedFields = this.configFields.map((field, i) => {
const name = this.displayedColumns[i];
return { ...field, config: { ...field.config, name, label: labelsMap[name] || field.config.label } };
});

// for adding rows to table when editable and not modal view
Expand Down Expand Up @@ -421,11 +433,12 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
this.pConn$.getListActions().initDefaultPageInstructions(
this.pConn$.getReferenceList(),
// Temporary filter for attachments to align with constellation payload behavior.
this.fieldDefs.filter(item => item.name && item.meta?.type !== 'Attachment').map(item => item.name)
this.fieldDefs.filter(item => item.name && item.meta?.type !== 'Attachment').map(item => item.name),
this.uniqueField
);
} else {
// @ts-ignore - An argument for 'propertyNames' was not provided.
this.pConn$.getListActions().initDefaultPageInstructions(this.pConn$.getReferenceList());
// @ts-ignore - 'propertyNames' is optional at runtime; uniqueField is passed as the 3rd argument.
this.pConn$.getListActions().initDefaultPageInstructions(this.pConn$.getReferenceList(), undefined, this.uniqueField);
}
}

Expand Down Expand Up @@ -1032,7 +1045,11 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
this.defaultActionId
);
} else {
this.pConn$.getListActions().insert({ classID: this.contextClass }, this.referenceList.length);
const payload: any = { classID: this.contextClass };
if (this.normalizedUniqueField) {
payload[this.normalizedUniqueField] = crypto.randomUUID();
}
this.pConn$.getListActions().insert(payload, this.referenceList.length);
}

this.pConn$.clearErrorMessages({
Expand Down Expand Up @@ -1084,7 +1101,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
const isRowEditable = evaluateAllowRowAction(allowRowEdit, element);
const data: any = [];
data.__originalIndex = index;
this.rawFields?.forEach(item => {
this.configFields?.forEach(item => {
if (!item?.config?.hide) {
item = {
...item,
Expand Down
Loading