Browse Source

feat(iot-hub): add Vendor filter for Device Library browse

Add Vendor as the first filter for DEVICE type in browse page:
- Text input with debounced search (400ms)
- Clear button when filter is active
- Passes vendor param to IoT Hub API query
- Included in filter count and clearAllFilters
- Positioned above Hardware Type and Connectivity filters
pull/15508/head
Andrii Shvaika 3 months ago
parent
commit
9760da5bbb
  1. 17
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html
  2. 5
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss
  3. 28
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts
  4. 2
      ui-ngx/src/assets/locale/locale.constant-en_US.json

17
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html

@ -72,6 +72,23 @@
@if (!fixedSubType && getSubtypeMap()) {
<div class="tb-iot-hub-filter-divider"></div>
}
<mat-expansion-panel [expanded]="true" class="tb-iot-hub-filter-panel">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'iot-hub.vendor' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<mat-form-field appearance="outline" class="tb-vendor-filter-field">
<input matInput
[value]="vendorFilter"
(input)="onVendorInput($event)"
placeholder="{{ 'iot-hub.vendor-placeholder' | translate }}">
@if (vendorFilter) {
<button mat-icon-button matSuffix (click)="clearVendorFilter()">
<mat-icon>close</mat-icon>
</button>
}
</mat-form-field>
</mat-expansion-panel>
<div class="tb-iot-hub-filter-divider"></div>
<mat-expansion-panel [expanded]="true" class="tb-iot-hub-filter-panel">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'iot-hub.hardware-type' | translate }}</mat-panel-title>

5
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss

@ -197,6 +197,11 @@
}
}
.tb-vendor-filter-field {
width: 100%;
margin-top: 4px;
}
.tb-iot-hub-filter-group-label {
font-size: 12px;
font-weight: 500;

28
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts

@ -96,6 +96,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
activeRuleChainTypes = new Set<string>();
activeConnectivity = new Set<string>();
activeHardwareTypes = new Set<string>();
vendorFilter = '';
private vendorDebounceTimer: any;
sortOptions: SortOption[] = [
{ value: 'totalInstallCount', label: 'iot-hub.sort-most-installed', direction: Direction.DESC },
@ -181,6 +183,7 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeRuleChainTypes.clear();
this.activeConnectivity.clear();
this.activeHardwareTypes.clear();
this.vendorFilter = '';
this.updateCategories();
this.pageIndex = 0;
if (type === ItemType.WIDGET) {
@ -319,6 +322,22 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
return this.activeHardwareTypes.has(value);
}
onVendorInput(event: Event): void {
const value = (event.target as HTMLInputElement).value?.trim() || '';
this.vendorFilter = value;
clearTimeout(this.vendorDebounceTimer);
this.vendorDebounceTimer = setTimeout(() => {
this.pageIndex = 0;
this.loadItems();
}, 400);
}
clearVendorFilter(): void {
this.vendorFilter = '';
this.pageIndex = 0;
this.loadItems();
}
getActiveConnectivityArray(): string[] {
return Array.from(this.activeConnectivity);
}
@ -423,6 +442,7 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeRuleChainTypes.clear();
this.activeConnectivity.clear();
this.activeHardwareTypes.clear();
this.vendorFilter = '';
if (this.fixedSubType) {
this.getActiveSubtypes()?.add(this.fixedSubType);
}
@ -435,14 +455,15 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
get activeFilterCount(): number {
const subtypeCount = this.fixedSubType ? this.getActiveSubtypesArray().length : (this.getActiveSubtypes()?.size || 0);
return subtypeCount + this.activeCategories.size + this.activeUseCases.size +
this.activeConnectivity.size + this.activeHardwareTypes.size;
this.activeConnectivity.size + this.activeHardwareTypes.size + (this.vendorFilter ? 1 : 0);
}
hasActiveDropdownFilters(): boolean {
const subtypeCount = this.fixedSubType ? this.getActiveSubtypesArray().length : (this.getActiveSubtypes()?.size || 0);
return this.activeCategories.size > 0 ||
this.activeUseCases.size > 0 || subtypeCount > 0 ||
this.activeConnectivity.size > 0 || this.activeHardwareTypes.size > 0;
this.activeConnectivity.size > 0 || this.activeHardwareTypes.size > 0 ||
!!this.vendorFilter;
}
hasActiveFilters(): boolean {
@ -600,7 +621,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeRuleChainTypes.size > 0 ? Array.from(this.activeRuleChainTypes) : undefined,
undefined,
this.activeHardwareTypes.size > 0 ? Array.from(this.activeHardwareTypes) : undefined,
this.activeConnectivity.size > 0 ? Array.from(this.activeConnectivity) : undefined
this.activeConnectivity.size > 0 ? Array.from(this.activeConnectivity) : undefined,
this.vendorFilter || undefined
);
this.iotHubApiService.getPublishedVersions(
query,

2
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -3758,6 +3758,8 @@
"type-filter-label": "Type",
"category": "Category",
"use-case": "Use case",
"vendor": "Vendor",
"vendor-placeholder": "Filter by vendor...",
"hardware-type": "Hardware Type",
"connectivity": "Connectivity",
"clear-all-filters": "Clear all filters",

Loading…
Cancel
Save