Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix auto select of single items in multi filter list #3306

Merged
merged 1 commit into from
Jan 9, 2019
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<div class="list-component__header__left--multi-filters" [hidden]="(!(hasRows$ | async) && !filter) || (isAddingOrSelecting$ | async)">
<ng-container *ngFor="let multiFilterManager of multiFilterManagers; first as isFirst">
<mat-form-field *ngIf="!isFirst || !(multiFilterManager.hasOneItem$ | async)" [floatLabel]="'never'">
<mat-select id="{{multiFilterManager.filterKey}}" matInput [(value)]="multiFilterManager.initialValue" [disabled]="!(multiFilterManager.filterIsReady$ | async)" (selectionChange)="multiFilterManager.selectItem($event.value)">
<mat-select id="{{multiFilterManager.filterKey}}" matInput [(value)]="multiFilterManager.value" [disabled]="!(multiFilterManager.filterIsReady$ | async)" (selectionChange)="multiFilterManager.selectItem($event.value)">
<mat-option>{{ multiFilterManager.allLabel }}</mat-option>
<mat-option *ngFor="let selectItem of multiFilterManager.filterItems$ | async" [value]="selectItem.value">
{{selectItem.label}}
Expand Down
21 changes: 11 additions & 10 deletions src/frontend/app/shared/components/list/list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ export class ListComponent<T> implements OnInit, OnChanges, OnDestroy, AfterView
value: null
};
private filterString = '';
private multiFilters = {};
private sortColumns: ITableColumn<T>[];

private paginationWidgetToStore: Subscription;
Expand Down Expand Up @@ -381,34 +380,36 @@ export class ListComponent<T> implements OnInit, OnChanges, OnDestroy, AfterView

const filterStoreToWidget = this.paginationController.filter$.pipe(tap((paginationFilter: ListFilter) => {
this.filterString = paginationFilter.string;
this.multiFilters = { ...paginationFilter.items };
// Pipe store values to filter managers. This ensures any changes such as automatically selected orgs/spaces are shown in the drop
// downs (change org to one with one space results in that space being selected)
Object.values(this.multiFilterManagers).forEach((filterManager: MultiFilterManager<T>, index: number) => {
filterManager.applyValue(paginationFilter.items);
});
}));

// Multi filters (e.g. cf/org/space)
// - Ensure the initial value is correct
// - Pass any multi filter changes made by the user to the pagination controller and thus the store
// - If the first multi filter has one value it's not shown, ensure it's automatically selected to ensure other filters are correct
this.multiFilterWidgetObservables = new Array<Subscription>();
filterStoreToWidget.pipe(
first(),
tap(() => {
Object.values(this.multiFilterManagers).forEach((filterConfig: MultiFilterManager<T>, index: number) => {
// Pipe initial store value to the widget
filterConfig.applyInitialValue(this.multiFilters);
Object.values(this.multiFilterManagers).forEach((filterManager: MultiFilterManager<T>, index: number) => {
// The first filter will be hidden if there's only one filter option.
// To ensure subsequent filters behave correctly automatically select it
if (index === 0 && this.multiFilterManagers.length > 1) {
filterConfig.filterItems$.pipe(
filterManager.filterItems$.pipe(
first()
).subscribe(list => {
if (list && list.length === 1) {
filterConfig.selectItem(list[0].value);
filterManager.selectItem(list[0].value);
}
});
}

// Pipe changes in the widgets to the store
const sub = filterConfig.multiFilterConfig.select.asObservable().pipe(tap((filterItem: string) => {
this.paginationController.multiFilter(filterConfig.multiFilterConfig, filterItem);
const sub = filterManager.multiFilterConfig.select.asObservable().pipe(tap((filterItem: string) => {
this.paginationController.multiFilter(filterManager.multiFilterConfig, filterItem);
}));
this.multiFilterWidgetObservables.push(sub.subscribe());
});
Expand Down
13 changes: 7 additions & 6 deletions src/frontend/app/shared/components/list/list.component.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class MultiFilterManager<T> {
public filterItems$: Observable<IListMultiFilterConfigItem[]>;
public hasItems$: Observable<boolean>;
public hasOneItem$: Observable<boolean>;
public initialValue: string;
public value: string;

public filterKey: string;
public allLabel: string;
Expand Down Expand Up @@ -200,15 +200,16 @@ export class MultiFilterManager<T> {
);
}

public applyInitialValue(multiFilters: {}) {
const initialValue = multiFilters[this.multiFilterConfig.key];
if (initialValue) {
this.initialValue = initialValue;
this.selectItem(initialValue);
public applyValue(multiFilters: {}) {
const value = multiFilters[this.multiFilterConfig.key];
if (value) {
this.value = value;
this.selectItem(value);
}
}

public selectItem(itemValue: string) {
this.multiFilterConfig.select.next(itemValue);
this.value = itemValue;
}
}