Commit 0ee4907567f18768912982cf64f2fffbedbda62a

Authored by Igor Kulikov
1 parent 37fd7f49

Improve queue name selector

@@ -289,6 +289,7 @@ export class DeviceWizardDialogComponent extends @@ -289,6 +289,7 @@ export class DeviceWizardDialogComponent extends
289 const deviceProfile: DeviceProfile = { 289 const deviceProfile: DeviceProfile = {
290 name: this.deviceWizardFormGroup.get('newDeviceProfileTitle').value, 290 name: this.deviceWizardFormGroup.get('newDeviceProfileTitle').value,
291 type: DeviceProfileType.DEFAULT, 291 type: DeviceProfileType.DEFAULT,
  292 + defaultQueueName: this.deviceWizardFormGroup.get('defaultQueueName').value,
292 transportType: this.transportConfigFormGroup.get('transportType').value, 293 transportType: this.transportConfigFormGroup.get('transportType').value,
293 provisionType: deviceProvisionConfiguration.type, 294 provisionType: deviceProvisionConfiguration.type,
294 provisionDeviceKey, 295 provisionDeviceKey,
@@ -34,7 +34,12 @@ @@ -34,7 +34,12 @@
34 #queueAutocomplete="matAutocomplete" 34 #queueAutocomplete="matAutocomplete"
35 [displayWith]="displayQueueFn"> 35 [displayWith]="displayQueueFn">
36 <mat-option *ngFor="let queue of filteredQueues | async" [value]="queue"> 36 <mat-option *ngFor="let queue of filteredQueues | async" [value]="queue">
37 - <span [innerHTML]="queue | highlight:searchText"></span> 37 + <span [innerHTML]="queue.queueName | highlight:searchText"></span>
  38 + </mat-option>
  39 + <mat-option *ngIf="!(filteredQueues | async)?.length" [value]="null">
  40 + <span>
  41 + {{ translate.get('queue.no-queues-matching', {queue: searchText}) | async }}
  42 + </span>
38 </mat-option> 43 </mat-option>
39 </mat-autocomplete> 44 </mat-autocomplete>
40 <mat-error *ngIf="queueFormGroup.get('queue').hasError('required')"> 45 <mat-error *ngIf="queueFormGroup.get('queue').hasError('required')">
@@ -34,6 +34,10 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion'; @@ -34,6 +34,10 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
34 import { QueueService } from '@core/http/queue.service'; 34 import { QueueService } from '@core/http/queue.service';
35 import { ServiceType } from '@shared/models/queue.models'; 35 import { ServiceType } from '@shared/models/queue.models';
36 36
  37 +interface Queue {
  38 + queueName: string;
  39 +}
  40 +
37 @Component({ 41 @Component({
38 selector: 'tb-queue-type-list', 42 selector: 'tb-queue-type-list',
39 templateUrl: './queue-type-list.component.html', 43 templateUrl: './queue-type-list.component.html',
@@ -48,7 +52,7 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft @@ -48,7 +52,7 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
48 52
49 queueFormGroup: FormGroup; 53 queueFormGroup: FormGroup;
50 54
51 - modelValue: string | null; 55 + modelValue: Queue | null;
52 56
53 private requiredValue: boolean; 57 private requiredValue: boolean;
54 get required(): boolean { 58 get required(): boolean {
@@ -67,9 +71,9 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft @@ -67,9 +71,9 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
67 71
68 @ViewChild('queueInput', {static: true}) queueInput: ElementRef<HTMLInputElement>; 72 @ViewChild('queueInput', {static: true}) queueInput: ElementRef<HTMLInputElement>;
69 73
70 - filteredQueues: Observable<Array<string>>; 74 + filteredQueues: Observable<Array<Queue>>;
71 75
72 - queues: Observable<Array<string>>; 76 + queues: Observable<Array<Queue>>;
73 77
74 searchText = ''; 78 searchText = '';
75 79
@@ -99,9 +103,15 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft @@ -99,9 +103,15 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
99 debounceTime(150), 103 debounceTime(150),
100 distinctUntilChanged(), 104 distinctUntilChanged(),
101 tap(value => { 105 tap(value => {
102 - this.updateView(value); 106 + let modelValue;
  107 + if (typeof value === 'string' || !value) {
  108 + modelValue = null;
  109 + } else {
  110 + modelValue = value;
  111 + }
  112 + this.updateView(modelValue);
103 }), 113 }),
104 - map(value => value ? value : ''), 114 + map(value => value ? (typeof value === 'string' ? value : value.queueName) : ''),
105 switchMap(queue => this.fetchQueues(queue) ) 115 switchMap(queue => this.fetchQueues(queue) )
106 ); 116 );
107 } 117 }
@@ -123,8 +133,8 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft @@ -123,8 +133,8 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
123 133
124 writeValue(value: string | null): void { 134 writeValue(value: string | null): void {
125 this.searchText = ''; 135 this.searchText = '';
126 - this.modelValue = value;  
127 - this.queueFormGroup.get('queue').patchValue(value, {emitEvent: false}); 136 + this.modelValue = value ? { queueName: value } : null;
  137 + this.queueFormGroup.get('queue').patchValue(this.modelValue, {emitEvent: false});
128 this.dirty = true; 138 this.dirty = true;
129 } 139 }
130 140
@@ -135,37 +145,42 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft @@ -135,37 +145,42 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
135 } 145 }
136 } 146 }
137 147
138 - updateView(value: string | null) { 148 + updateView(value: Queue | null) {
139 if (this.modelValue !== value) { 149 if (this.modelValue !== value) {
140 this.modelValue = value; 150 this.modelValue = value;
141 - this.propagateChange(this.modelValue); 151 + this.propagateChange(this.modelValue ? this.modelValue.queueName : null);
142 } 152 }
143 } 153 }
144 154
145 - displayQueueFn(queue?: string): string | undefined {  
146 - return queue ? queue : undefined; 155 + displayQueueFn(queue?: Queue): string | undefined {
  156 + return queue ? queue.queueName : undefined;
147 } 157 }
148 158
149 - fetchQueues(searchText?: string): Observable<Array<string>> { 159 + fetchQueues(searchText?: string): Observable<Array<Queue>> {
150 this.searchText = searchText; 160 this.searchText = searchText;
151 return this.getQueues().pipe( 161 return this.getQueues().pipe(
152 - catchError(() => of([])), 162 + catchError(() => of([] as Array<Queue>)),
153 map(queues => { 163 map(queues => {
154 const result = queues.filter( queue => { 164 const result = queues.filter( queue => {
155 - return searchText ? queue.toUpperCase().startsWith(searchText.toUpperCase()) : true; 165 + return searchText ? queue.queueName.toUpperCase().startsWith(searchText.toUpperCase()) : true;
156 }); 166 });
157 if (result.length) { 167 if (result.length) {
158 - result.sort(); 168 + result.sort((q1, q2) => q1.queueName.localeCompare(q2.queueName));
159 } 169 }
160 return result; 170 return result;
161 }) 171 })
162 ); 172 );
163 } 173 }
164 174
165 - getQueues(): Observable<Array<string>> { 175 + getQueues(): Observable<Array<Queue>> {
166 if (!this.queues) { 176 if (!this.queues) {
167 this.queues = this.queueService. 177 this.queues = this.queueService.
168 getTenantQueuesByServiceType(this.queueType, {ignoreLoading: true}).pipe( 178 getTenantQueuesByServiceType(this.queueType, {ignoreLoading: true}).pipe(
  179 + map((queues) => {
  180 + return queues.map((queueName) => {
  181 + return { queueName };
  182 + });
  183 + }),
169 publishReplay(1), 184 publishReplay(1),
170 refCount() 185 refCount()
171 ); 186 );
@@ -1082,7 +1082,7 @@ @@ -1082,7 +1082,7 @@
1082 "default-rule-chain": "Default rule chain", 1082 "default-rule-chain": "Default rule chain",
1083 "mobile-dashboard": "Mobile dashboard", 1083 "mobile-dashboard": "Mobile dashboard",
1084 "mobile-dashboard-hint": "Used by mobile application as a device details dashboard", 1084 "mobile-dashboard-hint": "Used by mobile application as a device details dashboard",
1085 - "select-queue-hint": "Select from a drop-down list or add a custom name.", 1085 + "select-queue-hint": "Select from a drop-down list.",
1086 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", 1086 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
1087 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", 1087 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
1088 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?", 1088 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?",
@@ -2570,7 +2570,8 @@ @@ -2570,7 +2570,8 @@
2570 "queue": { 2570 "queue": {
2571 "select_name": "Select queue name", 2571 "select_name": "Select queue name",
2572 "name": "Queue Name", 2572 "name": "Queue Name",
2573 - "name_required": "Queue name is required!" 2573 + "name_required": "Queue name is required!",
  2574 + "no-queues-matching": "No queues matching '{{queue}}' were found."
2574 }, 2575 },
2575 "tenant": { 2576 "tenant": {
2576 "tenant": "Tenant", 2577 "tenant": "Tenant",
@@ -959,7 +959,7 @@ @@ -959,7 +959,7 @@
959 "profile-configuration": "프로파일 설정", 959 "profile-configuration": "프로파일 설정",
960 "transport-configuration": "전송 설정", 960 "transport-configuration": "전송 설정",
961 "default-rule-chain": "기본 규칙 사슬", 961 "default-rule-chain": "기본 규칙 사슬",
962 - "select-queue-hint": "Select from a drop-down list or add a custom name.", 962 + "select-queue-hint": "Select from a drop-down list.",
963 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", 963 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
964 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", 964 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
965 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 개 장치 프로파일} other {# 개 장치 프로파일} }?", 965 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 개 장치 프로파일} other {# 개 장치 프로파일} }?",
@@ -959,7 +959,7 @@ @@ -959,7 +959,7 @@
959 "profile-configuration": "Profile configuration", 959 "profile-configuration": "Profile configuration",
960 "transport-configuration": "Transport configuration", 960 "transport-configuration": "Transport configuration",
961 "default-rule-chain": "Default rule chain", 961 "default-rule-chain": "Default rule chain",
962 - "select-queue-hint": "Select from a drop-down list or add a custom name.", 962 + "select-queue-hint": "Select from a drop-down list.",
963 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", 963 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
964 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", 964 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
965 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?", 965 "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?",