1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-28 12:45:45 +01:00

[SM-650] Updating search and select all to work together properly (#5510)

* Updating search and select all to work together properly

* adding comment and moving filtered data below private variables

* thomas suggested changes

* making service-accounts-list the same as projects and secrest list

* changes

* Update service-accounts-list.component.ts

* removing unnecessary code

* setting active filter on set data, adding comment

* removing unused field

* Update libs/components/src/table/table-data-source.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

---------

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
This commit is contained in:
cd-bitwarden 2023-07-08 09:59:35 -04:00 committed by GitHub
parent e6bad5998d
commit 04207647de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 26 deletions

View File

@ -28,6 +28,7 @@ export class ServiceAccountsListComponent implements OnDestroy {
@Input() @Input()
set search(search: string) { set search(search: string) {
this.selection.clear();
this.dataSource.filter = search; this.dataSource.filter = search;
} }
@ -55,15 +56,20 @@ export class ServiceAccountsListComponent implements OnDestroy {
} }
isAllSelected() { isAllSelected() {
const numSelected = this.selection.selected.length; if (this.selection.selected?.length > 0) {
const numRows = this.serviceAccounts.length; const numSelected = this.selection.selected.length;
return numSelected === numRows; const numRows = this.dataSource.filteredData.length;
return numSelected === numRows;
}
return false;
} }
toggleAll() { toggleAll() {
this.isAllSelected() if (this.isAllSelected()) {
? this.selection.clear() this.selection.clear();
: this.selection.select(...this.serviceAccounts.map((s) => s.id)); } else {
this.selection.select(...this.dataSource.filteredData.map((s) => s.id));
}
} }
delete(serviceAccount: ServiceAccountView) { delete(serviceAccount: ServiceAccountView) {

View File

@ -26,6 +26,7 @@ export class ProjectsListComponent {
@Input() @Input()
set search(search: string) { set search(search: string) {
this.selection.clear();
this.dataSource.filter = search; this.dataSource.filter = search;
} }
@ -45,15 +46,20 @@ export class ProjectsListComponent {
) {} ) {}
isAllSelected() { isAllSelected() {
const numSelected = this.selection.selected.length; if (this.selection.selected?.length > 0) {
const numRows = this.projects.length; const numSelected = this.selection.selected.length;
return numSelected === numRows; const numRows = this.dataSource.filteredData.length;
return numSelected === numRows;
}
return false;
} }
toggleAll() { toggleAll() {
this.isAllSelected() if (this.isAllSelected()) {
? this.selection.clear() this.selection.clear();
: this.selection.select(...this.projects.map((s) => s.id)); } else {
this.selection.select(...this.dataSource.filteredData.map((s) => s.id));
}
} }
deleteProject(projectId: string) { deleteProject(projectId: string) {

View File

@ -29,6 +29,7 @@ export class SecretsListComponent implements OnDestroy {
@Input() @Input()
set search(search: string) { set search(search: string) {
this.selection.clear();
this.dataSource.filter = search; this.dataSource.filter = search;
} }
@ -61,15 +62,20 @@ export class SecretsListComponent implements OnDestroy {
} }
isAllSelected() { isAllSelected() {
const numSelected = this.selection.selected.length; if (this.selection.selected?.length > 0) {
const numRows = this.secrets.length; const numSelected = this.selection.selected.length;
return numSelected === numRows; const numRows = this.dataSource.filteredData.length;
return numSelected === numRows;
}
return false;
} }
toggleAll() { toggleAll() {
this.isAllSelected() if (this.isAllSelected()) {
? this.selection.clear() this.selection.clear();
: this.selection.select(...this.secrets.map((s) => s.id)); } else {
this.selection.select(...this.dataSource.filteredData.map((s) => s.id));
}
} }
bulkDeleteSecrets() { bulkDeleteSecrets() {

View File

@ -17,9 +17,16 @@ export class TableDataSource<T> extends DataSource<T> {
private readonly _sort: BehaviorSubject<Sort>; private readonly _sort: BehaviorSubject<Sort>;
private readonly _filter = new BehaviorSubject<string>(""); private readonly _filter = new BehaviorSubject<string>("");
private readonly _renderData = new BehaviorSubject<T[]>([]); private readonly _renderData = new BehaviorSubject<T[]>([]);
private _renderChangesSubscription: Subscription | null = null; private _renderChangesSubscription: Subscription | null = null;
/**
* The filtered set of data that has been matched by the filter string, or all the data if there
* is no filter. Useful for knowing the set of data the table represents.
* For example, a 'selectAll()' function would likely want to select the set of filtered data
* shown to the user rather than all the data.
*/
filteredData: T[];
constructor() { constructor() {
super(); super();
this._data = new BehaviorSubject([]); this._data = new BehaviorSubject([]);
@ -31,7 +38,13 @@ export class TableDataSource<T> extends DataSource<T> {
} }
set data(data: T[]) { set data(data: T[]) {
this._data.next(data ? [...data] : []); data = Array.isArray(data) ? data : [];
this._data.next(data);
// Normally the `filteredData` is updated by the re-render
// subscription, but that won't happen if it's inactive.
if (!this._renderChangesSubscription) {
this.filterData(data);
}
} }
set sort(sort: Sort) { set sort(sort: Sort) {
@ -48,6 +61,11 @@ export class TableDataSource<T> extends DataSource<T> {
set filter(filter: string) { set filter(filter: string) {
this._filter.next(filter); this._filter.next(filter);
// Normally the `filteredData` is updated by the re-render
// subscription, but that won't happen if it's inactive.
if (!this._renderChangesSubscription) {
this.filterData(this.data);
}
} }
connect(): Observable<readonly T[]> { connect(): Observable<readonly T[]> {
@ -65,7 +83,7 @@ export class TableDataSource<T> extends DataSource<T> {
private updateChangeSubscription() { private updateChangeSubscription() {
const filteredData = combineLatest([this._data, this._filter]).pipe( const filteredData = combineLatest([this._data, this._filter]).pipe(
map(([data, filter]) => this.filterData(data, filter)) map(([data]) => this.filterData(data))
); );
const orderedData = combineLatest([filteredData, this._sort]).pipe( const orderedData = combineLatest([filteredData, this._sort]).pipe(
@ -76,12 +94,13 @@ export class TableDataSource<T> extends DataSource<T> {
this._renderChangesSubscription = orderedData.subscribe((data) => this._renderData.next(data)); this._renderChangesSubscription = orderedData.subscribe((data) => this._renderData.next(data));
} }
private filterData(data: T[], filter: string): T[] { private filterData(data: T[]): T[] {
if (filter == null || filter == "") { this.filteredData =
return data; this.filter == null || this.filter === ""
} ? data
: data.filter((obj) => this.filterPredicate(obj, this.filter));
return data.filter((obj) => this.filterPredicate(obj, filter)); return this.filteredData;
} }
private orderData(data: T[], sort: Sort): T[] { private orderData(data: T[], sort: Sort): T[] {