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:
parent
e6bad5998d
commit
04207647de
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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() {
|
||||||
|
@ -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[] {
|
||||||
|
Loading…
Reference in New Issue
Block a user