Improve queue name selector

This commit is contained in:
Igor Kulikov 2021-08-26 16:22:35 +03:00
parent 37fd7f4988
commit 0ee4907567
6 changed files with 43 additions and 21 deletions

View File

@ -289,6 +289,7 @@ export class DeviceWizardDialogComponent extends
const deviceProfile: DeviceProfile = { const deviceProfile: DeviceProfile = {
name: this.deviceWizardFormGroup.get('newDeviceProfileTitle').value, name: this.deviceWizardFormGroup.get('newDeviceProfileTitle').value,
type: DeviceProfileType.DEFAULT, type: DeviceProfileType.DEFAULT,
defaultQueueName: this.deviceWizardFormGroup.get('defaultQueueName').value,
transportType: this.transportConfigFormGroup.get('transportType').value, transportType: this.transportConfigFormGroup.get('transportType').value,
provisionType: deviceProvisionConfiguration.type, provisionType: deviceProvisionConfiguration.type,
provisionDeviceKey, provisionDeviceKey,

View File

@ -34,7 +34,12 @@
#queueAutocomplete="matAutocomplete" #queueAutocomplete="matAutocomplete"
[displayWith]="displayQueueFn"> [displayWith]="displayQueueFn">
<mat-option *ngFor="let queue of filteredQueues | async" [value]="queue"> <mat-option *ngFor="let queue of filteredQueues | async" [value]="queue">
<span [innerHTML]="queue | highlight:searchText"></span> <span [innerHTML]="queue.queueName | highlight:searchText"></span>
</mat-option>
<mat-option *ngIf="!(filteredQueues | async)?.length" [value]="null">
<span>
{{ translate.get('queue.no-queues-matching', {queue: searchText}) | async }}
</span>
</mat-option> </mat-option>
</mat-autocomplete> </mat-autocomplete>
<mat-error *ngIf="queueFormGroup.get('queue').hasError('required')"> <mat-error *ngIf="queueFormGroup.get('queue').hasError('required')">

View File

@ -34,6 +34,10 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { QueueService } from '@core/http/queue.service'; import { QueueService } from '@core/http/queue.service';
import { ServiceType } from '@shared/models/queue.models'; import { ServiceType } from '@shared/models/queue.models';
interface Queue {
queueName: string;
}
@Component({ @Component({
selector: 'tb-queue-type-list', selector: 'tb-queue-type-list',
templateUrl: './queue-type-list.component.html', templateUrl: './queue-type-list.component.html',
@ -48,7 +52,7 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
queueFormGroup: FormGroup; queueFormGroup: FormGroup;
modelValue: string | null; modelValue: Queue | null;
private requiredValue: boolean; private requiredValue: boolean;
get required(): boolean { get required(): boolean {
@ -67,9 +71,9 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
@ViewChild('queueInput', {static: true}) queueInput: ElementRef<HTMLInputElement>; @ViewChild('queueInput', {static: true}) queueInput: ElementRef<HTMLInputElement>;
filteredQueues: Observable<Array<string>>; filteredQueues: Observable<Array<Queue>>;
queues: Observable<Array<string>>; queues: Observable<Array<Queue>>;
searchText = ''; searchText = '';
@ -99,9 +103,15 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
debounceTime(150), debounceTime(150),
distinctUntilChanged(), distinctUntilChanged(),
tap(value => { tap(value => {
this.updateView(value); let modelValue;
if (typeof value === 'string' || !value) {
modelValue = null;
} else {
modelValue = value;
}
this.updateView(modelValue);
}), }),
map(value => value ? value : ''), map(value => value ? (typeof value === 'string' ? value : value.queueName) : ''),
switchMap(queue => this.fetchQueues(queue) ) switchMap(queue => this.fetchQueues(queue) )
); );
} }
@ -123,8 +133,8 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
writeValue(value: string | null): void { writeValue(value: string | null): void {
this.searchText = ''; this.searchText = '';
this.modelValue = value; this.modelValue = value ? { queueName: value } : null;
this.queueFormGroup.get('queue').patchValue(value, {emitEvent: false}); this.queueFormGroup.get('queue').patchValue(this.modelValue, {emitEvent: false});
this.dirty = true; this.dirty = true;
} }
@ -135,37 +145,42 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
} }
} }
updateView(value: string | null) { updateView(value: Queue | null) {
if (this.modelValue !== value) { if (this.modelValue !== value) {
this.modelValue = value; this.modelValue = value;
this.propagateChange(this.modelValue); this.propagateChange(this.modelValue ? this.modelValue.queueName : null);
} }
} }
displayQueueFn(queue?: string): string | undefined { displayQueueFn(queue?: Queue): string | undefined {
return queue ? queue : undefined; return queue ? queue.queueName : undefined;
} }
fetchQueues(searchText?: string): Observable<Array<string>> { fetchQueues(searchText?: string): Observable<Array<Queue>> {
this.searchText = searchText; this.searchText = searchText;
return this.getQueues().pipe( return this.getQueues().pipe(
catchError(() => of([])), catchError(() => of([] as Array<Queue>)),
map(queues => { map(queues => {
const result = queues.filter( queue => { const result = queues.filter( queue => {
return searchText ? queue.toUpperCase().startsWith(searchText.toUpperCase()) : true; return searchText ? queue.queueName.toUpperCase().startsWith(searchText.toUpperCase()) : true;
}); });
if (result.length) { if (result.length) {
result.sort(); result.sort((q1, q2) => q1.queueName.localeCompare(q2.queueName));
} }
return result; return result;
}) })
); );
} }
getQueues(): Observable<Array<string>> { getQueues(): Observable<Array<Queue>> {
if (!this.queues) { if (!this.queues) {
this.queues = this.queueService. this.queues = this.queueService.
getTenantQueuesByServiceType(this.queueType, {ignoreLoading: true}).pipe( getTenantQueuesByServiceType(this.queueType, {ignoreLoading: true}).pipe(
map((queues) => {
return queues.map((queueName) => {
return { queueName };
});
}),
publishReplay(1), publishReplay(1),
refCount() refCount()
); );

View File

@ -1082,7 +1082,7 @@
"default-rule-chain": "Default rule chain", "default-rule-chain": "Default rule chain",
"mobile-dashboard": "Mobile dashboard", "mobile-dashboard": "Mobile dashboard",
"mobile-dashboard-hint": "Used by mobile application as a device details dashboard", "mobile-dashboard-hint": "Used by mobile application as a device details dashboard",
"select-queue-hint": "Select from a drop-down list or add a custom name.", "select-queue-hint": "Select from a drop-down list.",
"delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
"delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
"delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?", "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?",
@ -2570,7 +2570,8 @@
"queue": { "queue": {
"select_name": "Select queue name", "select_name": "Select queue name",
"name": "Queue Name", "name": "Queue Name",
"name_required": "Queue name is required!" "name_required": "Queue name is required!",
"no-queues-matching": "No queues matching '{{queue}}' were found."
}, },
"tenant": { "tenant": {
"tenant": "Tenant", "tenant": "Tenant",

View File

@ -959,7 +959,7 @@
"profile-configuration": "프로파일 설정", "profile-configuration": "프로파일 설정",
"transport-configuration": "전송 설정", "transport-configuration": "전송 설정",
"default-rule-chain": "기본 규칙 사슬", "default-rule-chain": "기본 규칙 사슬",
"select-queue-hint": "Select from a drop-down list or add a custom name.", "select-queue-hint": "Select from a drop-down list.",
"delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
"delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
"delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 개 장치 프로파일} other {# 개 장치 프로파일} }?", "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 개 장치 프로파일} other {# 개 장치 프로파일} }?",

View File

@ -959,7 +959,7 @@
"profile-configuration": "Profile configuration", "profile-configuration": "Profile configuration",
"transport-configuration": "Transport configuration", "transport-configuration": "Transport configuration",
"default-rule-chain": "Default rule chain", "default-rule-chain": "Default rule chain",
"select-queue-hint": "Select from a drop-down list or add a custom name.", "select-queue-hint": "Select from a drop-down list.",
"delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?", "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
"delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.", "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
"delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?", "delete-device-profiles-title": "Are you sure you want to delete { count, plural, 1 {1 device profile} other {# device profiles} }?",