From e54e94e469a3741044942269dcc7e85e13a3d5d3 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 4 Jun 2026 17:38:11 +0300 Subject: [PATCH] refactor(iot-hub): unify dot-pattern previews + rename search results container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop the DEVICE-only `tb-iot-hub-card-preview-device` / `dlg-preview-device` variants in the item card and item detail dialog. The previously-special white-background-with-border treatment is gone — device previews now reuse the same dot-pattern background as widgets / solution templates for a consistent look. - In the home-page iot-hub widget, fold the `tb-iot-hub-widget-card-image-pattern` modifier into the base `.tb-iot-hub-widget-card-image` so every preview card already paints the dot pattern (no opt-in class required). - Rename `.tb-search-categories` to `.tb-results-container` across the iot-hub-search component / search page / creator profile pages so the wrapper class better reflects what it actually contains (browse / search results) and stays consistent between the search component and the screens that embed it. - Pick up incidental browse / search component html / scss tweaks touched alongside the rename. --- .../iot-hub/iot-hub-browse.component.html | 153 ++++++++-------- .../iot-hub/iot-hub-browse.component.scss | 13 +- .../iot-hub/iot-hub-item-card.component.html | 2 +- .../iot-hub/iot-hub-item-card.component.scss | 5 - .../iot-hub-item-detail-dialog.component.html | 3 +- .../iot-hub-item-detail-dialog.component.scss | 5 - .../iot-hub/iot-hub-search.component.html | 165 +++++++++--------- .../iot-hub/iot-hub-search.component.scss | 25 ++- .../home-page/iot-hub-widget.component.html | 2 +- .../home-page/iot-hub-widget.component.scss | 9 +- .../iot-hub-creator-profile.component.scss | 9 +- .../iot-hub/iot-hub-items-page.component.scss | 1 - .../iot-hub-search-page.component.scss | 8 +- 13 files changed, 194 insertions(+), 206 deletions(-) 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 cb59c9f5e9..83b1764afd 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 @@ -405,87 +405,92 @@ - - @if (isLoading) { -
- -
- } +
- - @if (hasError && !isLoading) { -
-
-

{{ 'iot-hub.unable-to-load' | translate }}

-

{{ 'iot-hub.unable-to-load-text' | translate }}

- -
- } - - - @if (!isLoading && !hasError && items.length === 0) { -
-
-

{{ 'iot-hub.no-items-found' | translate }}

-

{{ 'iot-hub.no-items-found-text' | translate }}

- @if (hasActiveFilters()) { - + + @if (hasError) { +
+
+

{{ 'iot-hub.unable-to-load' | translate }}

+

{{ 'iot-hub.unable-to-load-text' | translate }}

+ +
} -
- } - - @if (!isLoading && !hasError && items.length > 0) { -
- @for (item of items; track item.id) { - - + + @if (!hasError && items.length === 0) { +
+
+

{{ 'iot-hub.no-items-found' | translate }}

+

{{ 'iot-hub.no-items-found-text' | translate }}

+ @if (hasActiveFilters()) { + + } +
} -
- -
-
- - @for (p of getPageNumbers(); track p) { - - } - -
-
- {{ 'iot-hub.items-per-page' | translate }}: - - @for (size of pageSizeOptions; track size) { - {{ size }} + + @if (!hasError && items.length > 0) { +
+ @for (item of items; track item.id) { + + } - -
+
+ + +
+
+ + @for (p of getPageNumbers(); track p) { + + } + +
+
+ {{ 'iot-hub.items-per-page' | translate }}: + + @for (size of pageSizeOptions; track size) { + {{ size }} + } + +
+
+ } + + + @if (isLoading) { +
+
+ +
+
+ }
- }
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 b377219bb7..4c058ef5d1 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 @@ -112,7 +112,8 @@ } .tb-iot-hub-filters-wrapper { - position: absolute; + position: sticky; + max-height: calc(100vh - var(--mat-toolbar-standard-height, 64px)); inset: 0; overflow-y: auto; } @@ -146,10 +147,12 @@ width: 60%; max-width: 550px; min-width: 300px; - margin-bottom: -48px; - - .embedded & { - margin-bottom: 0; + &:not(.embedded &) { + position: fixed; + top: var(--mat-toolbar-standard-height, 64px); + @media #{$mat-xs} { + top: var(--mat-toolbar-mobile-height, 56px); + } } } diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html index 70dc7d986e..dc2030b00a 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html @@ -80,7 +80,7 @@ } @else {
-
+
@if (getPreviewUrl(); as previewUrl) { } @else { diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss index 77d363f4ad..d46124d91e 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss @@ -52,11 +52,6 @@ position: relative; overflow: hidden; padding: 12px; - - &.tb-iot-hub-card-preview-device { - background: white; - border-bottom: 1px solid rgba(0, 0, 0, 0.12); - } } .tb-iot-hub-preview-image { 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 c72e209037..6c0318abbc 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 @@ -94,8 +94,7 @@
+ [class.dlg-preview-carousel]="item.type === ItemType.SOLUTION_TEMPLATE && carouselImages.length > 1"> @if (item.type === ItemType.SOLUTION_TEMPLATE && carouselImages.length > 1) {