Skip to content

Commit

Permalink
fix: bulk actions UI (#2086)
Browse files Browse the repository at this point in the history
  • Loading branch information
sleidig authored Nov 20, 2023
1 parent 12b5855 commit b523e99
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
matSort
class="full-width table"
>
<ng-container matColumnDef="select">
<ng-container [matColumnDef]="COLUMN_ROW_SELECT">
<th mat-header-cell *matHeaderCellDef style="width: 0"></th>
<td mat-cell *matCellDef="let row">
<mat-checkbox
(change)="selectRow(row, $event)"
[checked]="selectedRecords.includes(row.record)"
[checked]="selectedRecords?.includes(row.record)"
></mat-checkbox>
</td>
</ng-container>
Expand Down Expand Up @@ -137,13 +137,10 @@
</div>
</td>
</ng-container>
<tr
mat-header-row
*matHeaderRowDef="columnsToDisplay.concat('select')"
></tr>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr
mat-row
*matRowDef="let row; columns: columnsToDisplay.concat('select')"
*matRowDef="let row; columns: columnsToDisplay"
[style.background-color]="getBackgroundColor?.(row.record)"
class="table-row"
></tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ export class EntitySubrecordComponent<T extends Entity> implements OnChanges {
@Input() isLoading: boolean;
@Input() clickMode: "popup" | "navigate" | "none" = "popup";

/** outputs an event containing an array of currently selected records (checkmarked by the user) */
/**
* outputs an event containing an array of currently selected records (checkmarked by the user)
*
* Checkboxes to select rows are only displayed if you set "selectable" also.
*/
@Output() selectedRecordsChange: EventEmitter<T[]> = new EventEmitter<T[]>();
@Input() selectedRecords: T[] = [];
readonly COLUMN_ROW_SELECT = "_selectRows";
@Input() selectable: boolean = false;

@Input() showInactive = false;
@Output() showInactiveChange = new EventEmitter<boolean>();
Expand Down Expand Up @@ -263,6 +269,13 @@ export class EntitySubrecordComponent<T extends Entity> implements OnChanges {
}
if (changes.hasOwnProperty("columnsToDisplay")) {
this.mediaSubscription.unsubscribe();
resetupTable = true;
}
if (
changes.hasOwnProperty("editable") ||
changes.hasOwnProperty("selectable")
) {
resetupTable = true;
}

if (reinitDataSource) {
Expand Down Expand Up @@ -327,10 +340,9 @@ export class EntitySubrecordComponent<T extends Entity> implements OnChanges {

private inferDefaultSort(): Sort {
// initial sorting by first column, ensure that not the 'action' column is used
const sortBy =
this.columnsToDisplay[0] === "actions"
? this.columnsToDisplay[1]
: this.columnsToDisplay[0];
const sortBy = this.columnsToDisplay.filter(
(c) => c !== "actions" && c !== this.COLUMN_ROW_SELECT,
)[0];
const sortByColumn = this._columns.find((c) => c.id === sortBy);

let sortDirection: SortDirection = "asc";
Expand Down Expand Up @@ -448,12 +460,33 @@ export class EntitySubrecordComponent<T extends Entity> implements OnChanges {
* resets columnsToDisplay depending on current screensize
*/
private setupTable() {
if (this._columns !== undefined && this.screenWidth !== undefined) {
this.columnsToDisplay = this._columns
.filter((col) => this.isVisible(col))
.map((col) => col.id);
this.columnsToDisplay.unshift("actions");
let columns = [];

if (
!(this.columnsToDisplay?.length > 0) &&
this._columns !== undefined &&
this.screenWidth !== undefined
) {
columns = [
...this._columns
.filter((col) => this.isVisible(col))
.map((col) => col.id),
];
} else {
columns = this.columnsToDisplay.filter((c) =>
this._columns.some((column) => column.id === c),
);
}

if (this.editable) {
columns.unshift("actions");
}
if (this.selectable) {
// only show selection checkboxes if Output is used in parent
columns.unshift(this.COLUMN_ROW_SELECT);
}

this.columnsToDisplay = [...columns];
}

/**
Expand Down
41 changes: 34 additions & 7 deletions src/app/core/entity-list/entity-list/entity-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
</app-view-title>

<div class="flex-row gap-regular">
<ng-container *ngTemplateOutlet="bulkActions"></ng-container>

<button
mat-stroked-button
color="accent"
Expand Down Expand Up @@ -84,6 +86,8 @@ <h2>{{ title }}</h2>
</button>
</div>

<ng-container *ngTemplateOutlet="bulkActions"></ng-container>

<ng-container *ngTemplateOutlet="subrecord"></ng-container>
</div>

Expand Down Expand Up @@ -127,6 +131,7 @@ <h2>{{ title }}</h2>
[filter]="filterObj"
[defaultSort]="defaultSort"
[(selectedRecords)]="selectedRows"
[selectable]="!!selectedRows"
[showInactive]="showInactive"
(filteredRecordsChange)="filteredData = $event"
></app-entity-subrecord>
Expand Down Expand Up @@ -220,19 +225,41 @@ <h2>{{ title }}</h2>

<button
mat-menu-item
(click)="duplicateRecords()"
[disabled]="selectedRows.length === 0"
matTooltip="Please select rows"
[matTooltipDisabled]="selectedRows.length > 0"
(click)="selectedRows = []"
matTooltip="Select multiple records for bulk actions like duplicating or deleting"
i18n-matTooltip
>
<fa-icon
class="color-accent standard-icon-with-text"
aria-label="duplicates record"
icon="copy"
aria-label="bulk actions"
icon="list-check"
></fa-icon>
<span i18n> Duplicate selected records </span>
<span i18n> Bulk Actions </span>
</button>

<ng-content select="[mat-menu-item]"></ng-content>
</mat-menu>

<ng-template #bulkActions>
<div *ngIf="!!selectedRows" class="bulk-action-button">
<div>Actions on selected records:</div>

<div class="flex-row gap-small bulk-action-button">
<button
mat-raised-button
(click)="duplicateRecords()"
[disabled]="selectedRows.length === 0"
matTooltip="Select rows to clone"
i18n-matTooltip
color="accent"
i18n="bulk action button"
>
Duplicate
</button>

<button mat-raised-button (click)="selectedRows = undefined" i18n>
Cancel
</button>
</div>
</div>
</ng-template>
11 changes: 11 additions & 0 deletions src/app/core/entity-list/entity-list/entity-list.component.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@use "../../../../styles/variables/breakpoints";
@use "src/styles/variables/sizes";
@use "src/styles/variables/colors";

/**
* Aligns the baseline of the filter-field with the baseline
Expand All @@ -16,3 +18,12 @@
background-color: white !important;
height: 100%;
}

.bulk-action-button {
position: fixed;
right: sizes.$large;
z-index: 999;

padding: sizes.$regular;
background-color: colors.$background;
}
4 changes: 2 additions & 2 deletions src/app/core/entity-list/entity-list/entity-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class EntityListComponent<T extends Entity>

@Output() elementClick = new EventEmitter<T>();
@Output() addNewClick = new EventEmitter();
selectedRows: T[] = [];
selectedRows: T[];

@ViewChild(EntitySubrecordComponent) entityTable: EntitySubrecordComponent<T>;

Expand Down Expand Up @@ -320,6 +320,6 @@ export class EntityListComponent<T extends Entity>

duplicateRecords() {
this.duplicateRecord.duplicateRecord(this.selectedRows);
this.selectedRows = [];
this.selectedRows = undefined;
}
}

0 comments on commit b523e99

Please sign in to comment.