diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html
index c20acedecb..d8c67197f4 100644
--- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html
+++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html
@@ -68,35 +68,70 @@
}
- @if (categories.size > 0) {
+ @if (activeType === ItemType.DEVICE) {
@if (!fixedSubType && getSubtypeMap()) {
}
- {{ 'iot-hub.category' | translate }}
+ {{ 'iot-hub.hardware-type' | translate }}
- @for (entry of categories | keyvalue; track entry.key) {
-
- {{ entry.value | translate }}
+ @for (ht of hardwareTypes; track ht) {
+
+ {{ ht }}
}
+
+
+
+ {{ 'iot-hub.connectivity' | translate }}
+
+ @for (group of connectivityGroups; track group.label) {
+ {{ group.label }}
+ @for (val of group.values; track val) {
+
+ {{ val }}
+
+ }
+ }
+
+ } @else {
+ @if (categories.size > 0) {
+ @if (!fixedSubType && getSubtypeMap()) {
+
+ }
+
+
+ {{ 'iot-hub.category' | translate }}
+
+ @for (entry of categories | keyvalue; track entry.key) {
+
+ {{ entry.value | translate }}
+
+ }
+
+ }
}
- @if ((!fixedSubType && getSubtypeMap()) || categories.size > 0) {
+ @if (activeType === ItemType.DEVICE || (!fixedSubType && getSubtypeMap()) || categories.size > 0) {
}
{{ 'iot-hub.use-case' | translate }}
- @for (entry of useCases | keyvalue; track entry.key) {
-
- {{ entry.value | translate }}
-
+ @for (group of useCaseGroups; track group.label) {
+ {{ group.label }}
+ @for (uc of group.values; track uc) {
+
+ {{ uc }}
+
+ }
}
@@ -129,6 +164,18 @@
close
}
+ @for (key of getActiveHardwareTypesArray(); track key) {
+
+ {{ key }}
+ close
+
+ }
+ @for (key of getActiveConnectivityArray(); track key) {
+
+ {{ key }}
+ close
+
+ }
@for (key of getActiveUseCasesArray(); track key) {
{{ getUseCaseLabel(key) }}
@@ -201,6 +248,18 @@
close
}
+ @for (key of getActiveHardwareTypesArray(); track key) {
+
+ {{ key }}
+ close
+
+ }
+ @for (key of getActiveConnectivityArray(); track key) {
+
+ {{ key }}
+ close
+
+ }
@for (key of getActiveUseCasesArray(); track key) {
{{ getUseCaseLabel(key) }}
diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss
index 955233e880..56730ec3a6 100644
--- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss
+++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.scss
@@ -196,6 +196,19 @@
background: rgba(0, 0, 0, 0.04);
}
}
+
+ .tb-iot-hub-filter-group-label {
+ font-size: 12px;
+ font-weight: 500;
+ color: rgba(0, 0, 0, 0.54);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ padding: 12px 0 4px 44px;
+
+ &:first-child {
+ padding-top: 4px;
+ }
+ }
}
// Right content area — Design: flex-1, pr-40, scrollable
diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts
index e0d94228b3..6a2aba27cc 100644
--- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts
+++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts
@@ -23,7 +23,8 @@ import { PageData } from '@shared/models/page/page-data';
import { MpItemVersionQuery, MpItemVersionView } from '@shared/models/iot-hub/iot-hub-version.models';
import {
ItemType,
- getCategoriesForType, useCaseTranslations
+ getCategoriesForType, useCaseTranslations, useCaseGroups, UseCaseGroup,
+ connectivityGroups, ConnectivityGroup, hardwareTypes
} from '@shared/models/iot-hub/iot-hub-item.models';
import { cfTypeTranslations, widgetTypeTranslations, ruleChainTypeTranslations } from '@shared/models/iot-hub/iot-hub-version.models';
import { IotHubInstalledItem } from '@shared/models/iot-hub/iot-hub-installed-item.models';
@@ -93,6 +94,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
activeCfTypes = new Set();
activeWidgetTypes = new Set();
activeRuleChainTypes = new Set();
+ activeConnectivity = new Set();
+ activeHardwareTypes = new Set();
sortOptions: SortOption[] = [
{ value: 'totalInstallCount', label: 'iot-hub.sort-most-installed', direction: Direction.DESC },
@@ -103,6 +106,9 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
categories = new Map();
useCases: Map = useCaseTranslations as Map;
+ useCaseGroups: UseCaseGroup[] = useCaseGroups;
+ connectivityGroups: ConnectivityGroup[] = connectivityGroups;
+ hardwareTypes: string[] = hardwareTypes;
cfTypes: Map = cfTypeTranslations;
widgetTypes: Map = widgetTypeTranslations;
ruleChainTypes: Map = ruleChainTypeTranslations;
@@ -173,6 +179,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeCfTypes.clear();
this.activeWidgetTypes.clear();
this.activeRuleChainTypes.clear();
+ this.activeConnectivity.clear();
+ this.activeHardwareTypes.clear();
this.updateCategories();
this.pageIndex = 0;
if (type === ItemType.WIDGET) {
@@ -271,6 +279,54 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.loadItems();
}
+ onConnectivityToggle(value: string): void {
+ if (this.activeConnectivity.has(value)) {
+ this.activeConnectivity.delete(value);
+ } else {
+ this.activeConnectivity.add(value);
+ }
+ this.pageIndex = 0;
+ this.loadItems();
+ }
+
+ clearConnectivity(): void {
+ this.activeConnectivity.clear();
+ this.pageIndex = 0;
+ this.loadItems();
+ }
+
+ isConnectivityActive(value: string): boolean {
+ return this.activeConnectivity.has(value);
+ }
+
+ onHardwareTypeToggle(value: string): void {
+ if (this.activeHardwareTypes.has(value)) {
+ this.activeHardwareTypes.delete(value);
+ } else {
+ this.activeHardwareTypes.add(value);
+ }
+ this.pageIndex = 0;
+ this.loadItems();
+ }
+
+ clearHardwareTypes(): void {
+ this.activeHardwareTypes.clear();
+ this.pageIndex = 0;
+ this.loadItems();
+ }
+
+ isHardwareTypeActive(value: string): boolean {
+ return this.activeHardwareTypes.has(value);
+ }
+
+ getActiveConnectivityArray(): string[] {
+ return Array.from(this.activeConnectivity);
+ }
+
+ getActiveHardwareTypesArray(): string[] {
+ return Array.from(this.activeHardwareTypes);
+ }
+
getSubtypeMap(): Map | null {
switch (this.activeType) {
case ItemType.WIDGET: return this.widgetTypes;
@@ -365,6 +421,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeCfTypes.clear();
this.activeWidgetTypes.clear();
this.activeRuleChainTypes.clear();
+ this.activeConnectivity.clear();
+ this.activeHardwareTypes.clear();
if (this.fixedSubType) {
this.getActiveSubtypes()?.add(this.fixedSubType);
}
@@ -376,13 +434,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;
+ return subtypeCount + this.activeCategories.size + this.activeUseCases.size +
+ this.activeConnectivity.size + this.activeHardwareTypes.size;
}
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.activeUseCases.size > 0 || subtypeCount > 0 ||
+ this.activeConnectivity.size > 0 || this.activeHardwareTypes.size > 0;
}
hasActiveFilters(): boolean {
@@ -537,7 +597,10 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
this.activeUseCases.size > 0 ? Array.from(this.activeUseCases) : undefined,
this.activeCfTypes.size > 0 ? Array.from(this.activeCfTypes) : undefined,
this.activeWidgetTypes.size > 0 ? Array.from(this.activeWidgetTypes) : undefined,
- this.activeRuleChainTypes.size > 0 ? Array.from(this.activeRuleChainTypes) : undefined
+ 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.iotHubApiService.getPublishedVersions(
query,
diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html
index 3b4ac5e57a..b149a86498 100644
--- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html
+++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.html
@@ -238,31 +238,67 @@
}
-
- @if (item.categories?.length || item.useCases?.length) {
-
-