Skip to content
Open
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 @@ -5,6 +5,8 @@
* Github: [PR-547](https://github.com/pegasystems/angular-sdk-components/pull/547)
* **Added support for instructions in the DefaultForm template.**
* Github: [PR-548](https://github.com/pegasystems/angular-sdk-components/pull/548)
* **Added support for conditional Add, Edit, and Delete actions, including record-level conditions, in editable EmbeddedData table.**
* Github: [PR-553](https://github.com/pegasystems/angular-sdk-components/pull/553)


### **Bug fixes**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export const updateFieldLabels = (fields, configFields, primaryFieldsViewIndex,
return labelsOfFields;
};

export const buildFieldsForTable = (configFields, pConnect, showDeleteButton, options) => {
export const buildFieldsForTable = (configFields, pConnect, showActionColumn, options) => {
const { primaryFieldsViewIndex, fields } = options;

// get resolved field labels for primary fields raw config included in configFields
Expand All @@ -260,8 +260,8 @@ export const buildFieldsForTable = (configFields, pConnect, showDeleteButton, op
};
});

// ONLY add DELETE_ICON to fields when the table is requested as EDITABLE
if (showDeleteButton) {
// Add the action column when either edit or delete is available.
if (showActionColumn) {
fieldDefs.push({
type: 'text',
label: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
<h3 *ngIf="label" className="label" style="font-weight: bold">
{{ label }} <span class="results-count">{{ getResultsText() }}</span>
</h3>
<table *ngIf="readOnlyMode || allowEditingInModal" mat-table [dataSource]="elementsData" class="mat-elevation-z8" id="readonly-table" matSort>
<table
*ngIf="readOnlyMode || allowEditingInModal || hideEditRow"
mat-table
[dataSource]="elementsData"
class="mat-elevation-z8"
id="readonly-table"
matSort
>
<ng-container *ngFor="let dCol of processedFields; let i = index" [matColumnDef]="dCol.config.name">
<th mat-header-cell *matHeaderCellDef mat-sort-header (click)="_headerSortClick($event, dCol)" arrowPosition="before">
<div>{{ dCol.config.label }}</div>
Expand Down Expand Up @@ -39,20 +46,25 @@ <h3 *ngIf="label" className="label" style="font-weight: bold">
</td>
</ng-container>
<ng-container matColumnDef="DeleteIcon">
<div *ngIf="allowEditingInModal">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<div class="header-icon">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element; index as j">
<ng-container *ngIf="allowEditingInModal; else deleteOnly">
<div *ngIf="rowActions[j]?.hasAnyAction" class="header-icon">
<button mat-icon-button [matMenuTriggerFor]="utilityMenu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #utilityMenu="matMenu" overlapTrigger="false">
<button mat-menu-item (click)="editRecord(element, element.__originalIndex)">Edit</button>
<button mat-menu-item (click)="deleteRecord(element.__originalIndex)">Delete</button>
<button *ngIf="rowActions[j]?.canEdit" mat-menu-item (click)="editRecord(element, element.__originalIndex)">Edit</button>
<button *ngIf="rowActions[j]?.canDelete" mat-menu-item (click)="deleteRecord(element.__originalIndex)">Delete</button>
</mat-menu>
</div>
</td>
</div>
</ng-container>
<ng-template #deleteOnly>
<button *ngIf="rowActions[j]?.canDelete" id="delete-button" mat-icon-button (click)="deleteRecord(j)">
<mat-icon>delete</mat-icon>
</button>
</ng-template>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
Expand All @@ -62,7 +74,13 @@ <h3 *ngIf="label" className="label" style="font-weight: bold">
</td>
</tr>
</table>
<table *ngIf="editableMode && !allowEditingInModal" mat-table [dataSource]="elementsData" class="mat-elevation-z8" id="editable-table">
<table
*ngIf="editableMode && !allowEditingInModal && !hideEditRow"
mat-table
[dataSource]="elementsData"
class="mat-elevation-z8"
id="editable-table"
>
<ng-container *ngFor="let dCol of fieldDefs; let i = index">
<ng-container *ngIf="dCol.name != 'DeleteIcon'" [matColumnDef]="dCol.name">
<th mat-header-cell *matHeaderCellDef class="psdk-mat-header">{{ dCol.label }}</th>
Expand All @@ -81,7 +99,7 @@ <h3 *ngIf="label" className="label" style="font-weight: bold">
<ng-container matColumnDef="DeleteIcon">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element; index as j">
<button id="delete-button" mat-icon-button (click)="deleteRecord(j)">
<button *ngIf="rowActions[j]?.canDelete" id="delete-button" mat-icon-button (click)="deleteRecord(j)">
<mat-icon>delete</mat-icon>
</button>
</td>
Expand Down
55 changes: 50 additions & 5 deletions ...ponents/src/lib/_components/template/simple-table-manual/simple-table-manual.component.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ interface SimpleTableManualProps {
allowActions?: any;
allowTableEdit?: boolean;
allowRowDelete?: any;
allowRowEdit?: any;
editMode?: string;
addAndEditRowsWithin?: any;
viewForAddAndEditModal?: any;
Expand All @@ -59,6 +60,12 @@ class Group {
}
}

interface RowActions {
canEdit: boolean;
canDelete: boolean;
hasAnyAction: boolean;
}

@Component({
selector: 'app-simple-table-manual',
templateUrl: './simple-table-manual.component.html',
Expand Down Expand Up @@ -168,6 +175,12 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
targetClassLabel: string;
localizedVal = PCore.getLocaleUtils().getLocaleValue;
localeCategory = 'SimpleTable';
hideEditRow: any;
hideDeleteRow: boolean;
showEditButton: boolean;
showDeleteButton: boolean;
showActionColumn: boolean;
rowActions: RowActions[] = [];
constructor(
private angularPConnect: AngularPConnectService,
public utils: Utils,
Expand Down Expand Up @@ -238,7 +251,6 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
presets,
allowActions,
allowTableEdit,
allowRowDelete,
label: labelProp,
propertyLabel,
fieldMetadata,
Expand Down Expand Up @@ -305,9 +317,15 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
this.editableMode = renderMode === 'Editable';
const isDisplayModeEnabled = displayMode === 'DISPLAY_ONLY';
this.showAddRowButton = !this.readOnlyMode && !simpleTableManualProps.hideAddRow;
this.hideEditRow = simpleTableManualProps.hideEditRow;
this.hideDeleteRow = simpleTableManualProps.hideDeleteRow;
this.allowEditingInModal =
(editMode ? editMode === 'modal' : addAndEditRowsWithin === 'modal') && !(renderMode === 'ReadOnly' || isDisplayModeEnabled);
const showDeleteButton = this.editableMode && !simpleTableManualProps.hideDeleteRow && evaluateAllowRowAction(allowRowDelete, this.rowData);
this.showEditButton = this.allowEditingInModal && !this.hideEditRow;
this.showDeleteButton = this.editableMode && !this.hideDeleteRow;
this.showActionColumn = this.showEditButton || this.showDeleteButton;
const { allowRowEdit, allowRowDelete } = this.pConn$.getComponentConfig?.() ?? {};
this.rowActions = this.referenceList.map(row => this.getRowActions(row, allowRowEdit, allowRowDelete));
this.defaultView = editModeConfig ? editModeConfig.defaultView : viewForAddAndEditModal;
this.bUseSeparateViewForEdit = editModeConfig ? editModeConfig.useSeparateViewForEdit : useSeparateViewForEdit;
this.editView = editModeConfig ? editModeConfig.editView : viewForEditModal;
Expand All @@ -326,7 +344,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$, showDeleteButton, {
this.fieldDefs = buildFieldsForTable(rawFields, this.pConn$, this.showActionColumn, {
primaryFieldsViewIndex,
fields: resolvedFields
});
Expand Down Expand Up @@ -364,7 +382,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
}

// for edit and adding rows in modal view and to generate readonly list
if (!isEqual(this.prevReferenceList, this.referenceList) && (this.readOnlyMode || this.allowEditingInModal)) {
if (!isEqual(this.prevReferenceList, this.referenceList) && (this.readOnlyMode || this.allowEditingInModal || this.hideEditRow)) {
this.generateRowsData();
}

Expand Down Expand Up @@ -414,6 +432,31 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
return `${recordsCount || 0} result${recordsCount > 1 ? 's' : ''}`;
}

private getRowActions(row: any, allowRowEdit: any, allowRowDelete: any): RowActions {
const canEdit = this.showEditButton && evaluateAllowRowAction(allowRowEdit, row);
const canDelete = this.showDeleteButton && this.isDeleteAllowedForRow(row, allowRowDelete);

return {
canEdit,
canDelete,
hasAnyAction: canEdit || canDelete
};
}

private isDeleteAllowedForRow(row: any, allowRowDelete: any): boolean {
if (allowRowDelete === undefined || allowRowDelete === true) return true;
if (typeof allowRowDelete === 'string' && allowRowDelete.startsWith('@E ')) {
try {
const expression = allowRowDelete.replace('@E ', '');
// @ts-expect-error - options param is optional per corejs docs
return PCore.getExpressionEngine().evaluate(expression, row);
} catch {
return true;
}
}
return false;
}

sortCompare(a, b): number {
let aValue = a[0][this.compareRef];
let bValue = b[0][this.compareRef];
Expand Down Expand Up @@ -1021,8 +1064,10 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {

buildElementsForTable() {
const context = this.pConn$.getContextName();
const { allowRowEdit } = this.pConn$.getComponentConfig?.() ?? {};
const eleData: any = [];
this.referenceList.forEach((element, index) => {
const isRowEditable = evaluateAllowRowAction(allowRowEdit, element);
const data: any = [];
data.__originalIndex = index;
this.rawFields?.forEach(item => {
Expand All @@ -1032,7 +1077,7 @@ export class SimpleTableManualComponent implements OnInit, OnDestroy {
config: {
...item.config,
label: '',
displayMode: this.readOnlyMode || this.allowEditingInModal ? 'DISPLAY_ONLY' : undefined
displayMode: this.readOnlyMode || this.allowEditingInModal || this.hideEditRow || !isRowEditable ? 'DISPLAY_ONLY' : undefined
}
};
const referenceListData = getReferenceList(this.pConn$);
Expand Down
Loading