Skip to content
This repository was archived by the owner on Mar 25, 2023. It is now read-only.

Commit 3352c11

Browse files
huadreambwsw
authored andcommitted
add search input to mat-select (#1669)
* feature(time-zone): add searching for the selector * feature(filter): add searching for the account selector * fix(i18n): add translations for ru * fix(sg-filter): fix property missing
1 parent 7819105 commit 3352c11

25 files changed

Lines changed: 343 additions & 25 deletions

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"ng2-dragula": "1.5.0",
6262
"ngx-clipboard": "^11.1.7",
6363
"ngx-infinite-scroll": "^6.0.1",
64+
"ngx-mat-select-search": "^1.7.6",
6465
"resize-observer-polyfill": "^1.5.0",
6566
"rxjs": "^6.3.3",
6667
"showdown": "^1.8.4",

src/app/events/components/event-list.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,17 @@
3939
[(ngModel)]="selectedAccountIds"
4040
(selectionChange)="accountChanged.emit($event.value)"
4141
>
42-
<mat-option *ngFor="let account of accounts" [value]="account.id"
42+
<mat-option>
43+
<ngx-mat-select-search
44+
[placeholderLabel]="'SELECT_SEARCH.SEARCH' | translate"
45+
[noEntriesFoundLabel]="'SELECT_SEARCH.NO_MATCH' | translate"
46+
[ngModel]="accountQuery"
47+
(ngModelChange)="onAccountQueryChanged($event)"
48+
>
49+
<mat-icon ngxMatSelectSearchClear class="mdi-close"></mat-icon>
50+
</ngx-mat-select-search>
51+
</mat-option>
52+
<mat-option *ngFor="let account of accountsFiltered" [value]="account.id"
4353
>{{ account.fullDomain }}{{ account.name }}
4454
</mat-option>
4555
</mat-select>

src/app/events/components/event-list.component.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export class EventListComponent implements OnChanges {
5555
@Output()
5656
public accountChanged = new EventEmitter<string[]>();
5757

58+
public accountsFiltered: Account[] = [];
59+
public accountQuery = '';
5860
public dataSource: MatTableDataSource<Event>;
5961
public tableColumns = ['description', 'level', 'type', 'time'];
6062
public levels = ['INFO', 'WARN', 'ERROR'];
@@ -72,8 +74,19 @@ export class EventListComponent implements OnChanges {
7274

7375
public ngOnChanges(changes: SimpleChanges) {
7476
const events = changes['events'];
77+
const accounts = changes['accounts'];
7578
if (events) {
7679
this.dataSource.data = events.currentValue;
7780
}
81+
if (accounts) {
82+
this.onAccountQueryChanged(this.accountQuery);
83+
}
84+
}
85+
86+
public onAccountQueryChanged(accountQuery: string) {
87+
const queryLower = accountQuery && accountQuery.toLowerCase();
88+
this.accountsFiltered = this.accounts.filter(
89+
account => !accountQuery || account.name.toLowerCase().includes(queryLower),
90+
);
7891
}
7992
}

src/app/security-group/sg-filter/sg-filter.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,17 @@
3030
[ngModel]="selectedAccountIds"
3131
(selectionChange)="accountsChanged.emit($event.value)"
3232
>
33-
<mat-option *ngFor="let account of accounts" [value]="account.id"
33+
<mat-option>
34+
<ngx-mat-select-search
35+
[placeholderLabel]="'SELECT_SEARCH.SEARCH' | translate"
36+
[noEntriesFoundLabel]="'SELECT_SEARCH.NO_MATCH' | translate"
37+
[ngModel]="accountQuery"
38+
(ngModelChange)="onAccountQueryChanged($event)"
39+
>
40+
<mat-icon ngxMatSelectSearchClear class="mdi-close"></mat-icon>
41+
</ngx-mat-select-search>
42+
</mat-option>
43+
<mat-option *ngFor="let account of accountsFiltered" [value]="account.id"
3444
>{{ account.fullDomain }}{{ account.name }}
3545
</mat-option>
3646
</mat-select>

src/app/security-group/sg-filter/sg-filter.component.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { Component, EventEmitter, Input, Output } from '@angular/core';
1+
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
22
import { SecurityGroupViewMode } from '../sg-view-mode';
3+
import { Account } from '../../shared/models';
34

45
export interface SecurityGroupFilter {
56
viewMode: SecurityGroupViewMode;
@@ -13,7 +14,7 @@ export interface SecurityGroupFilter {
1314
templateUrl: 'sg-filter.component.html',
1415
styleUrls: ['sg-filter.component.scss'],
1516
})
16-
export class SgFilterComponent {
17+
export class SgFilterComponent implements OnChanges {
1718
@Input()
1819
public accounts: Account[];
1920
@Input()
@@ -32,6 +33,8 @@ export class SgFilterComponent {
3233
public viewMode: SecurityGroupViewMode;
3334
public query: string;
3435
public selectedAccountIds: string[];
36+
public accountsFiltered: Account[] = [];
37+
public accountQuery = '';
3538

3639
@Input()
3740
public set filters(filter: SecurityGroupFilter) {
@@ -44,4 +47,18 @@ export class SgFilterComponent {
4447
public get SecurityGroupViewMode() {
4548
return SecurityGroupViewMode;
4649
}
50+
51+
public ngOnChanges(changes: SimpleChanges) {
52+
const accounts = changes['accounts'];
53+
if (accounts) {
54+
this.onAccountQueryChanged(this.accountQuery);
55+
}
56+
}
57+
58+
public onAccountQueryChanged(accountQuery: string) {
59+
const queryLower = accountQuery && accountQuery.toLowerCase();
60+
this.accountsFiltered = this.accounts.filter(
61+
account => !accountQuery || account.name.toLowerCase().includes(queryLower),
62+
);
63+
}
4764
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<mat-form-field class="full-width-input">
22
<mat-select [placeholder]="'SNAPSHOT_POLICIES.TIME_ZONE' | translate" [(ngModel)]="timeZone">
3+
<mat-option>
4+
<ngx-mat-select-search
5+
[placeholderLabel]="'SELECT_SEARCH.SEARCH' | translate"
6+
[noEntriesFoundLabel]="'SELECT_SEARCH.NO_MATCH' | translate"
7+
[ngModel]="query"
8+
(ngModelChange)="queryChanged($event)"
9+
>
10+
<mat-icon ngxMatSelectSearchClear class="mdi-close"></mat-icon>
11+
</ngx-mat-select-search>
12+
</mat-option>
313
<mat-option *ngFor="let tz of timeZones" [value]="tz"> {{ timeZoneToString(tz) }} </mat-option>
414
</mat-select>
515
</mat-form-field>

src/app/shared/components/time-zone/time-zone.component.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ export class TimeZoneComponent implements ControlValueAccessor, OnInit {
1818
// tslint:disable-next-line:variable-name
1919
public _timeZone: TimeZone;
2020
public timeZones: TimeZone[];
21+
public timeZonesAll: TimeZone[];
22+
public query = '';
2123

2224
constructor(private timeZoneService: TimeZoneService) {}
2325

2426
public ngOnInit(): void {
2527
this.timeZoneService.get().subscribe(timeZones => {
28+
this.timeZonesAll = timeZones;
2629
this.timeZones = timeZones;
2730
this.timeZone = timeZones[0];
2831
});
@@ -52,6 +55,16 @@ export class TimeZoneComponent implements ControlValueAccessor, OnInit {
5255
}
5356
}
5457

58+
public queryChanged(query: string) {
59+
const queryLower = query && query.toLowerCase();
60+
this.timeZones = this.timeZonesAll.filter(
61+
timezone =>
62+
!query ||
63+
timezone.geo.toLowerCase().includes(queryLower) ||
64+
timezone.zone.toLowerCase().includes(queryLower),
65+
);
66+
}
67+
5568
public timeZoneToString(timeZone: TimeZone): string {
5669
return `${timeZone.geo} (${timeZone.zone})`;
5770
}

src/app/shared/shared.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ import { RequestResourcesButtonComponent } from './components/vm-statistics/requ
156156
import { RequestResourcesButtonContainerComponent } from './components/vm-statistics/request-resources-button.container';
157157
import { ApiLogService } from './services/api-log.service';
158158
import { LogViewGuard } from './services/log-view-guard.service';
159+
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
159160

160161
const SHARED_DIRECTIVES = [UrlDirective, SidebarTabNavDirective, InputTypeNumberDirective];
161162

@@ -179,6 +180,7 @@ const SHARED_COMPONENTS = [
179180
TranslateModule,
180181
MatBadgeModule,
181182
MatExpansionModule,
183+
NgxMatSelectSearchModule,
182184
StoreModule.forFeature('zones', zoneReducers),
183185
StoreModule.forFeature('disk-offerings', diskOfferingReducers),
184186
StoreModule.forFeature('affinity-groups', affinityGroupReducers),
@@ -256,6 +258,7 @@ const SHARED_COMPONENTS = [
256258
RequestResourcesButtonComponent,
257259
RequestResourcesButtonContainerComponent,
258260
MatExpansionModule,
261+
NgxMatSelectSearchModule,
259262
],
260263
entryComponents: [
261264
DatePickerDialogComponent,

src/app/snapshot/snapshots-page/snapshot-filter/vm-snapshot-filter.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,17 @@
99
[ngModel]="selectedAccounts"
1010
(selectionChange)="selectedAccountsChange.emit($event.value)"
1111
>
12-
<mat-option *ngFor="let account of accounts" [value]="account.name"
12+
<mat-option>
13+
<ngx-mat-select-search
14+
[placeholderLabel]="'SELECT_SEARCH.SEARCH' | translate"
15+
[noEntriesFoundLabel]="'SELECT_SEARCH.NO_MATCH' | translate"
16+
[ngModel]="accountQuery"
17+
(ngModelChange)="onAccountQueryChanged($event)"
18+
>
19+
<mat-icon ngxMatSelectSearchClear class="mdi-close"></mat-icon>
20+
</ngx-mat-select-search>
21+
</mat-option>
22+
<mat-option *ngFor="let account of accountsFiltered" [value]="account.name"
1323
>{{ account.fullDomain }}{{ account.name }}
1424
</mat-option>
1525
</mat-select>

src/app/snapshot/snapshots-page/snapshot-filter/vm-snapshot-filter.component.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, EventEmitter, Input, Output } from '@angular/core';
1+
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
22
import { TranslateService } from '@ngx-translate/core';
33

44
import { Account } from '../../../shared/models';
@@ -11,7 +11,7 @@ import { SnapshotPageViewMode } from '../../types';
1111
selector: 'cs-vm-snapshots-filter',
1212
templateUrl: './vm-snapshot-filter.component.html',
1313
})
14-
export class VmSnapshotFilterComponent {
14+
export class VmSnapshotFilterComponent implements OnChanges {
1515
@Input()
1616
public isLoading: boolean;
1717
@Input()
@@ -39,6 +39,9 @@ export class VmSnapshotFilterComponent {
3939
@Output()
4040
public viewModeChange = new EventEmitter<SnapshotPageViewMode>();
4141

42+
public accountsFiltered: Account[] = [];
43+
public accountQuery = '';
44+
4245
public get locale(): Language {
4346
return this.translate.currentLang as Language;
4447
}
@@ -47,4 +50,18 @@ export class VmSnapshotFilterComponent {
4750
private translate: TranslateService,
4851
public dateTimeFormatterService: DateTimeFormatterService,
4952
) {}
53+
54+
public ngOnChanges(changes: SimpleChanges) {
55+
const accounts = changes['accounts'];
56+
if (accounts) {
57+
this.onAccountQueryChanged(this.accountQuery);
58+
}
59+
}
60+
61+
public onAccountQueryChanged(accountQuery: string) {
62+
const queryLower = accountQuery && accountQuery.toLowerCase();
63+
this.accountsFiltered = this.accounts.filter(
64+
account => !accountQuery || account.name.toLowerCase().includes(queryLower),
65+
);
66+
}
5067
}

0 commit comments

Comments
 (0)