Skip to content

Commit 348cebf

Browse files
committed
Add bulk actions to console
1 parent 9f22f2e commit 348cebf

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

console-webapp/src/app/domains/domainList.component.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,34 @@ <h1>No domains found</h1>
6565
/>
6666
</mat-form-field>
6767

68+
<div class="console-app__domains-selection" [ngClass]="{'active': selection.hasValue()}">
69+
<div class="console-app__domains-selection-text">{{selection.selected.length}} Selected</div>
70+
<div class="console-app__domains-selection-actions"></div>
71+
</div>
72+
6873
<mat-table
6974
[dataSource]="dataSource"
7075
class="mat-elevation-z0"
7176
class="console-app__domains-table"
7277
>
78+
<!-- Checkbox Column -->
79+
<ng-container matColumnDef="select">
80+
<mat-header-cell *matHeaderCellDef>
81+
<mat-checkbox (change)="$event ? toggleAllRows() : null"
82+
[checked]="selection.hasValue() && isAllSelected"
83+
[indeterminate]="selection.hasValue() && !isAllSelected"
84+
[aria-label]="checkboxLabel()">
85+
</mat-checkbox>
86+
</mat-header-cell>
87+
<mat-cell *matCellDef="let row">
88+
<mat-checkbox (click)="$event.stopPropagation()"
89+
(change)="$event ? selection.toggle(row) : null"
90+
[checked]="selection.isSelected(row)"
91+
[aria-label]="checkboxLabel(row)">
92+
</mat-checkbox>
93+
</mat-cell>
94+
</ng-container>
95+
7396
<ng-container matColumnDef="domainName">
7497
<mat-header-cell *matHeaderCellDef>Domain Name</mat-header-cell>
7598
<mat-cell *matCellDef="let element">{{

console-webapp/src/app/domains/domainList.component.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
}
1313
}
1414

15+
&__domains-selection {
16+
height: 30px;
17+
max-height: 0;
18+
transition: max-height .2s linear;
19+
&.active {
20+
max-height: 30px;
21+
}
22+
}
23+
1524
&-domains__download {
1625
position: absolute;
1726
top: -55px;
@@ -41,6 +50,10 @@
4150
overflow: hidden;
4251
word-break: break-word;
4352
}
53+
.mat-column-select {
54+
max-width: 60px;
55+
padding-left: 15px;
56+
}
4457
}
4558

4659
&__domains-spinner {

console-webapp/src/app/domains/domainList.component.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import { SelectionModel } from '@angular/cdk/collections';
1516
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
1617
import { Component, ViewChild, effect } from '@angular/core';
1718
import { MatPaginator, PageEvent } from '@angular/material/paginator';
@@ -31,8 +32,10 @@ import { RegistryLockService } from './registryLock.service';
3132
export class DomainListComponent {
3233
public static PATH = 'domain-list';
3334
private readonly DEBOUNCE_MS = 500;
35+
isAllSelected = false;
3436

3537
displayedColumns: string[] = [
38+
'select',
3639
'domainName',
3740
'creationTime',
3841
'registrationExpirationTime',
@@ -42,6 +45,7 @@ export class DomainListComponent {
4245
];
4346

4447
dataSource: MatTableDataSource<Domain> = new MatTableDataSource();
48+
selection = new SelectionModel<Domain>(true, [], undefined, this.isChecked());
4549
isLoading = true;
4650

4751
searchTermSubject = new Subject<string>();
@@ -136,4 +140,32 @@ export class DomainListComponent {
136140
this.resultsPerPage = event.pageSize;
137141
this.reloadData();
138142
}
143+
144+
toggleAllRows() {
145+
if (this.isAllSelected) {
146+
this.selection.clear();
147+
this.isAllSelected = false;
148+
return;
149+
}
150+
151+
this.selection.select(...this.dataSource.data);
152+
this.isAllSelected = true;
153+
}
154+
155+
checkboxLabel(row?: Domain): string {
156+
if (!row) {
157+
return `${this.isAllSelected ? 'deselect' : 'select'} all`;
158+
}
159+
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.domainName + 1}`;
160+
}
161+
162+
private isChecked(): ((o1: Domain, o2: Domain) => boolean) | undefined {
163+
return (o1: Domain, o2: Domain) => {
164+
if (!o1.domainName || !o2.domainName) {
165+
return false;
166+
}
167+
168+
return this.isAllSelected || o1.domainName === o2.domainName;
169+
};
170+
}
139171
}

0 commit comments

Comments
 (0)