From 402732377abdb11dc7f5144142454bb2d6689b8f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Jun 2026 19:57:54 +0300 Subject: [PATCH 1/3] refactor(iot-hub): use blob object URLs for device package zip images Switch from base64 data URLs to URL.createObjectURL for images extracted from the device package zip. Revokes them in ngOnDestroy to avoid leaking memory, and avoids embedding multi-megabyte data URLs in the DOM. --- .../device-install-dialog.component.ts | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts index e4df929fd2..c94bb477f3 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { ChangeDetectorRef, Component, Inject, OnInit, Type, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { @@ -40,9 +40,6 @@ import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; import { EntityId } from '@shared/models/id/entity-id'; import { generateSecret } from '@core/utils'; import { - installMethodIcons as INSTALL_METHOD_ICONS, - installMethodLabels as INSTALL_METHOD_LABELS, - peOnlyInstallMethods, DeviceInstallStep, DevicePackageInfo, ENTITY_STEP_TYPES, @@ -50,7 +47,10 @@ import { EntityStepProgress, FormFieldDefinition, FormFieldType, + installMethodIcons as INSTALL_METHOD_ICONS, + installMethodLabels as INSTALL_METHOD_LABELS, InstallStepType, + peOnlyInstallMethods, stepTypeAliasMap } from '@shared/models/iot-hub/device-package.models'; import { mergeMap } from 'rxjs/operators'; @@ -89,7 +89,7 @@ const DEFAULT_RANDOM_SIZE = 20; templateUrl: './device-install-dialog.component.html', styleUrls: ['./device-install-dialog.component.scss'] }) -export class TbDeviceInstallDialogComponent extends DialogComponent implements OnInit { +export class TbDeviceInstallDialogComponent extends DialogComponent implements OnInit, OnDestroy { @ViewChild('installStepper', {static: false}) stepper: MatStepper; @@ -148,9 +148,9 @@ export class TbDeviceInstallDialogComponent extends DialogComponent Date: Fri, 12 Jun 2026 19:57:57 +0300 Subject: [PATCH 2/3] style(iot-hub): add bottom margin to markdown doc-link buttons so they wrap cleanly --- .../modules/home/components/iot-hub/iot-hub-markdown.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-markdown.utils.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-markdown.utils.ts index 6685a898f5..6db27ce352 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-markdown.utils.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-markdown.utils.ts @@ -54,7 +54,7 @@ export function resolveDocLinkPlaceholders( function buildDocLinkButton(url: string, text: string, icon: string): string { const safeUrl = escapeHtmlAttr(url); const safeText = escapeHtml(text); - return `` + + return `` + `${icon}${safeText}`; } From 772a9cda7c833c4e31c4395551c573c3c95bd988 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Jun 2026 19:58:01 +0300 Subject: [PATCH 3/3] style(photoswipe): drop hard-coded image size caps and align zoom button with close button Remove the 90vw/78vh caps so the image scales naturally inside the viewport, and apply the same 40x40 sizing to the zoom button as the close button. --- .../app/shared/directives/photoswipe-gallery.directive.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/shared/directives/photoswipe-gallery.directive.ts b/ui-ngx/src/app/shared/directives/photoswipe-gallery.directive.ts index f4bd39e72b..22eb3c76dd 100644 --- a/ui-ngx/src/app/shared/directives/photoswipe-gallery.directive.ts +++ b/ui-ngx/src/app/shared/directives/photoswipe-gallery.directive.ts @@ -62,8 +62,6 @@ const PHOTO_GALLERY_STYLE = '\n' + '.pswp__item img.pswp__img {\n' + ' display: block;\n' + - ' max-width: 90vw;\n' + - ' max-height: 78vh;\n' + ' object-fit: contain;\n' + ' border-radius: 4px; \n' + ' box-shadow: 0 20px 60px #00000080;\n' + @@ -90,14 +88,14 @@ const PHOTO_GALLERY_STYLE = ' outline: none;\n' + '}\n' + '\n' + - '.pswp__button.pswp__button--close {\n' + + '.pswp__button.pswp__button--close, .pswp__button.pswp__button--zoom {\n' + ' width: 40px;\n' + ' height: 40px;\n' + ' margin-top: 16px;\n' + ' margin-right: 16px;\n' + '}\n' + '\n' + - '.pswp__button.pswp__button--close .pswp__icn {\n' + + '.pswp__button.pswp__button--close .pswp__icn, .pswp__button.pswp__button--zoom .pswp__icn {\n' + ' width: 24px;\n' + ' height: 24px;\n' + ' top: 7px;\n' +