diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.html b/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.html index 733ed0a906..402381ad67 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.html @@ -164,8 +164,8 @@ @if (loading) { -
- +
+
} @else {
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 e784b11898..761395ee9c 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 @@ -53,10 +53,10 @@ import { InstallStepType, stepTypeAliasMap } from '@shared/models/iot-hub/device-package.models'; +import { mergeMap } from 'rxjs/operators'; export interface DeviceInstallDialogData { item: MpItemVersionView; - zipData: ArrayBuffer; reviewMode?: boolean; selectedInstallMethod?: string; installState?: Record; @@ -138,8 +138,11 @@ export class TbDeviceInstallDialogComponent extends DialogComponent { try { + const zipData = await firstValueFrom(this.iotHubApiService.getVersionFileData(this.data.item.id, { ignoreLoading: true }).pipe( + mergeMap((blob: Blob) => blob.arrayBuffer()) + )); const JSZip = (await import('jszip')).default; - const zip = await JSZip.loadAsync(this.data.zipData); + const zip = await JSZip.loadAsync(zipData); const imageExtensions = new Set(['png', 'jpg', 'jpeg', 'gif', 'svg']); for (const [path, entry] of Object.entries(zip.files) as [string, any][]) { if (!entry.dir) { diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts index ee32245eb1..e8c82637ed 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-actions.service.ts @@ -118,34 +118,24 @@ export class IotHubActionsService { } installDevice(item: MpItemVersionView): Observable { - return this.fetchZipData(item).pipe( - mergeMap((zipData: ArrayBuffer) => this.openDeviceInstallDialog(item, zipData)) - ); + return this.openDeviceInstallDialog(item); } reviewDevice(item: MpItemVersionView, deviceDescriptor: DeviceInstalledItemDescriptor): Observable { - return this.fetchZipData(item).pipe( - mergeMap((zipData: ArrayBuffer) => this.openDeviceInstallDialog(item, zipData, { + return this.openDeviceInstallDialog(item, { reviewMode: true, selectedInstallMethod: deviceDescriptor.selectedInstallMethod, installState: deviceDescriptor.installState - })) - ); - } - - private fetchZipData(item: MpItemVersionView): Observable { - return this.iotHubApiService.getVersionFileData(item.id as string, { ignoreLoading: true }).pipe( - mergeMap((blob: Blob) => blob.arrayBuffer()) - ); + }); } - private openDeviceInstallDialog(item: MpItemVersionView, zipData: ArrayBuffer, + private openDeviceInstallDialog(item: MpItemVersionView, options?: { reviewMode?: boolean; selectedInstallMethod?: string; installState?: any }): Observable { - return this.dialog.open(TbDeviceInstallDialogComponent, { + return this.dialog.open(TbDeviceInstallDialogComponent, { panelClass: ['tb-dialog', 'tb-fullscreen-dialog-lt-md'], disableClose: true, autoFocus: false, - data: { item, zipData, ...options } as DeviceInstallDialogData + data: { item, ...options } }).afterClosed(); } } 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 d46124d91e..71f3ea051d 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 @@ -285,6 +285,7 @@ font-weight: 500; color: rgba(0, 0, 0, 0.54); text-transform: uppercase; + margin-right: 8px; tb-icon { font-size: 12px; diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts index bdf50acddf..2d9c13d8d7 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts @@ -62,8 +62,8 @@ export class TbIotHubItemCardComponent { return null; } const [path, query] = this.item.image.split('?'); - const original = path.endsWith('/preview') ? path.slice(0, -'/preview'.length) : path; - const resolved = query ? `${original}?${query}` : original; + const withPreview = path.endsWith('/preview') ? path : `${path}/preview`; + const resolved = query ? `${withPreview}?${query}` : withPreview; return this.iotHubApiService.resolveResourceUrl(resolved); } 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 3827599242..e42f1521aa 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 @@ -69,12 +69,16 @@ } } -
+ +
@@ -163,7 +167,7 @@
@if (showCreator) { -
+
{{ 'iot-hub.creator' | translate }}
verified }
- {{ item.creatorDisplayName }} + {{ item.creatorDisplayName }}
} diff --git a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.scss b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.scss index 0622ce4af5..5b7a182a01 100644 --- a/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-detail-dialog.component.scss @@ -54,6 +54,21 @@ } +.dlg-close-btn-desktop { + @media #{$mat-lt-sm} { + display: none; + } +} + +.dlg-close-btn-mobile { + position: absolute; + top: 16px; + right: 12px; + @media #{$mat-gt-xs} { + display: none; + } +} + // Header icon for CF/RC — Design: 64px, rounded-8, colored bg, white icon 36px .dlg-header-icon { width: 64px; @@ -250,21 +265,25 @@ display: grid; gap: 24px; padding: 16px 24px 12px; - grid-template-columns: max-content minmax(0, max-content) minmax(auto, max-content) minmax(auto, 1fr) max-content; + grid-template-columns: minmax(0, max-content) minmax(0, max-content) minmax(auto, max-content) minmax(auto, 1fr) max-content; &.dlg-meta-4-col { - grid-template-columns: max-content minmax(auto, max-content) minmax(auto, 1fr) max-content; + grid-template-columns: minmax(0, max-content) minmax(auto, max-content) minmax(auto, 1fr) max-content; } .dlg-meta-details { display: none; } + .dlg-meta-creator-section { + min-width: 0; + } + @media #{$mat-lt-md} { - grid-template-columns: max-content max-content max-content; + grid-template-columns: minmax(0, 1fr) max-content max-content; &.dlg-meta-4-col { - grid-template-columns: max-content max-content max-content; + grid-template-columns: minmax(0, 1fr) max-content max-content; } .dlg-meta-details-section {