Browse Source

feat(iot-hub): add setup guide button on device card in browse page

Show a document icon button (📄) next to the "Installed" chip on
device cards that have stored install state. Clicking opens the
read-only review dialog with tabs (same as from Installed Items).

Visible in both "same version" and "update available" card states.
Tooltip: "View setup guide". Only shown for DEVICE items with
installState in their descriptor.
pull/15508/head
Andrii Shvaika 6 months ago
parent
commit
f6adbf74cc
  1. 3
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.html
  2. 31
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-browse.component.ts
  3. 12
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html
  4. 27
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss
  5. 14
      ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts
  6. 1
      ui-ngx/src/assets/locale/locale.constant-en_US.json

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

@ -353,7 +353,8 @@
(installClick)="installItem($event)"
(updateClick)="updateItem($event)"
(deleteClick)="deleteInstalledItem($event)"
(addClick)="onItemAdd($event)">
(addClick)="onItemAdd($event)"
(guideClick)="openInstallGuide($event)">
</tb-iot-hub-item-card>
}
</div>

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

@ -27,8 +27,10 @@ import {
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';
import { IotHubInstalledItem, DeviceInstalledItemDescriptor } from '@shared/models/iot-hub/iot-hub-installed-item.models';
import { IotHubApiService } from '@core/http/iot-hub-api.service';
import { TbDeviceInstallDialogComponent, DeviceInstallDialogData } from './device-install-dialog/device-install-dialog.component';
import { MatDialog } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core';
import { ActivatedRoute, Router } from '@angular/router';
import { IotHubActionsService } from '@home/components/iot-hub/iot-hub-actions.service';
@ -126,7 +128,8 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
private iotHubActions: IotHubActionsService,
private translate: TranslateService,
private router: Router,
private route: ActivatedRoute
private route: ActivatedRoute,
private dialog: MatDialog
) {}
ngOnInit(): void {
@ -559,6 +562,30 @@ export class TbIotHubBrowseComponent implements OnInit, OnDestroy {
});
}
openInstallGuide(item: MpItemVersionView): void {
const installedItem = this.getInstalledItem(item);
if (!installedItem) { return; }
const descriptor = installedItem.descriptor as DeviceInstalledItemDescriptor;
if (!descriptor?.installState || !descriptor?.selectedInstallMethod) { return; }
this.iotHubApiService.getVersionFileData(installedItem.itemVersionId, { ignoreLoading: true, ignoreErrors: true }).subscribe({
next: async (blob: Blob) => {
const zipData = await blob.arrayBuffer();
this.dialog.open(TbDeviceInstallDialogComponent, {
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
disableClose: false,
autoFocus: false,
data: {
item,
zipData,
reviewMode: true,
selectedInstallMethod: descriptor.selectedInstallMethod,
installState: descriptor.installState
} as DeviceInstallDialogData
});
}
});
}
navigateToCreator(creatorId: string): void {
this.router.navigate(['/iot-hub/creator', creatorId]);
}

12
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.html

@ -45,11 +45,23 @@
} @else if (isInstalled()) {
@if (isSameVersion()) {
<span class="tb-iot-hub-card-installed-chip"><tb-icon>check</tb-icon>{{ 'iot-hub.installed' | translate }}</span>
@if (hasInstallGuide()) {
<button class="tb-iot-hub-card-guide-btn" (click)="onGuideClick($event)"
[matTooltip]="'iot-hub.view-setup-guide' | translate" matTooltipPosition="above">
<tb-icon>description</tb-icon>
</button>
}
<button class="tb-iot-hub-card-remove-btn" (click)="onDeleteClick($event)">
<tb-icon>mdi:trash-can-outline</tb-icon>
</button>
} @else {
<button class="tb-iot-hub-card-update-btn" (click)="onUpdateClick($event)">{{ 'iot-hub.update' | translate }}</button>
@if (hasInstallGuide()) {
<button class="tb-iot-hub-card-guide-btn" (click)="onGuideClick($event)"
[matTooltip]="'iot-hub.view-setup-guide' | translate" matTooltipPosition="above">
<tb-icon>description</tb-icon>
</button>
}
<button class="tb-iot-hub-card-remove-btn" (click)="onDeleteClick($event)">
<tb-icon>mdi:trash-can-outline</tb-icon>
</button>

27
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.scss

@ -350,6 +350,33 @@
}
}
// Guide icon button
.tb-iot-hub-card-guide-btn {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 4px;
border: none;
background: none;
cursor: pointer;
flex-shrink: 0;
border-radius: 50%;
transition: background 0.15s;
tb-icon {
font-size: 20px;
width: 20px;
height: 20px;
color: rgba(0, 0, 0, 0.54);
}
&:hover {
background: rgba(0, 0, 0, 0.04);
}
}
// Remove icon button — Design: trash-can-outline 24px, rgba(0,0,0,0.54)
.tb-iot-hub-card-remove-btn {
display: flex;

14
ui-ngx/src/app/modules/home/components/iot-hub/iot-hub-item-card.component.ts

@ -45,6 +45,7 @@ export class TbIotHubItemCardComponent {
@Output() updateClick = new EventEmitter<MpItemVersionView>();
@Output() deleteClick = new EventEmitter<MpItemVersionView>();
@Output() addClick = new EventEmitter<MpItemVersionView>();
@Output() guideClick = new EventEmitter<MpItemVersionView>();
typeTranslations = itemTypeTranslations;
@ -223,6 +224,19 @@ export class TbIotHubItemCardComponent {
this.deleteClick.emit(this.item);
}
hasInstallGuide(): boolean {
if (!this.installedItem || this.installedItem.itemType !== 'DEVICE') {
return false;
}
const descriptor = this.installedItem.descriptor as any;
return !!descriptor?.installState && !!descriptor?.selectedInstallMethod;
}
onGuideClick(event: MouseEvent): void {
event.stopPropagation();
this.guideClick.emit(this.item);
}
onCreatorClick(event: MouseEvent): void {
event.stopPropagation();
this.creatorClick.emit(this.item.creatorId);

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

@ -3760,6 +3760,7 @@
"use-case": "Use case",
"vendor": "Vendor",
"vendor-placeholder": "Filter by vendor...",
"view-setup-guide": "View setup guide",
"hardware-type": "Hardware Type",
"connectivity": "Connectivity",
"clear-all-filters": "Clear all filters",

Loading…
Cancel
Save