Browse Source

Update item detail dialog info section to match design exactly

- Installed badge: pill shape, rgba(25,128,56,0.06) bg, 12px Regular, #198038
- Open details link: 12px Medium, open_in_new icon 16px, $tb-primary-color
- Status row: flex justify-between (badge left, link right)
- Author: 12px Medium with 16px person icon
- Info section: gap-32 between text-container and action buttons
- Action buttons: justify-between (Update left, Remove right)
- Solution templates: separate links row for instructions + dashboard
- Proper dlg-info-text wrapper with gap-16 for content elements
pull/15508/head
Igor Kulikov 3 months ago
parent
commit
368ed00fec
  1. 103
      ui-ngx/src/app/modules/home/pages/iot-hub/iot-hub-item-detail-dialog.component.html
  2. 88
      ui-ngx/src/app/modules/home/pages/iot-hub/iot-hub-item-detail-dialog.component.scss

103
ui-ngx/src/app/modules/home/pages/iot-hub/iot-hub-item-detail-dialog.component.html

@ -55,26 +55,28 @@
@if (item.type === ItemType.CALCULATED_FIELD || item.type === ItemType.RULE_CHAIN || item.type === ItemType.DEVICE) {
<!-- CF/RC/Device: description + author (no image) -->
<div class="dlg-info">
@if (isInstalled()) {
<div class="dlg-info-status-row">
<span class="dlg-installed-badge">
<mat-icon>check</mat-icon>
{{ 'iot-hub.installed' | translate }} v{{ installedItem.version }}
</span>
<a class="dlg-info-link" (click)="openEntityDetails()">
<mat-icon>open_in_new</mat-icon>
{{ 'iot-hub.open-item-type-details' | translate:{ type: getTypeLabel() } }}
</a>
</div>
}
@if (item.description) {
<div class="dlg-description">
<tb-markdown [data]="item.description"></tb-markdown>
<div class="dlg-info-text">
@if (isInstalled()) {
<div class="dlg-info-status-row">
<span class="dlg-installed-badge">
<mat-icon>check</mat-icon>
{{ 'iot-hub.installed' | translate }} v{{ installedItem.version }}
</span>
<a class="dlg-info-link" (click)="openEntityDetails()">
<mat-icon>open_in_new</mat-icon>
{{ 'iot-hub.open-item-type-details' | translate:{ type: getTypeLabel() } }}
</a>
</div>
}
@if (item.description) {
<div class="dlg-description">
<tb-markdown [data]="item.description"></tb-markdown>
</div>
}
<div class="dlg-author" (click)="navigateToCreator()">
<tb-icon>person</tb-icon>
<span>{{ item.creatorDisplayName }}</span>
</div>
}
<div class="dlg-author" (click)="navigateToCreator()">
<tb-icon>person</tb-icon>
<span>{{ item.creatorDisplayName }}</span>
</div>
<div class="dlg-info-actions">
@if (!isInstalled()) {
@ -87,7 +89,6 @@
</button>
}
@if (isInstalled()) {
<span class="dlg-info-actions-spacer"></span>
<button mat-stroked-button color="warn" (click)="deleteItem()">
<mat-icon>delete</mat-icon>
{{ 'iot-hub.remove' | translate }}
@ -144,37 +145,44 @@
}
</div>
<div class="dlg-info">
<!-- Installed status + links row -->
@if (isInstalled()) {
<div class="dlg-info-status-row">
<span class="dlg-installed-badge">
<mat-icon>check</mat-icon>
{{ 'iot-hub.installed' | translate }} v{{ installedItem.version }}
</span>
@if (isSameVersion() && item.type === ItemType.SOLUTION_TEMPLATE) {
<a class="dlg-info-link" (click)="openSolutionInstructions()">
<mat-icon>info_outline</mat-icon>
{{ 'iot-hub.solution-instructions' | translate }}
</a>
}
<a class="dlg-info-link" (click)="openEntityDetails()">
<mat-icon>open_in_new</mat-icon>
<div class="dlg-info-text">
<!-- Installed status + links row -->
@if (isInstalled()) {
<div class="dlg-info-status-row">
<span class="dlg-installed-badge">
<mat-icon>check</mat-icon>
{{ 'iot-hub.installed' | translate }} v{{ installedItem.version }}
</span>
@if (item.type === ItemType.SOLUTION_TEMPLATE) {
{{ 'iot-hub.goto-main-dashboard' | translate }}
<div class="dlg-info-links-row">
@if (isSameVersion()) {
<a class="dlg-info-link" (click)="openSolutionInstructions()">
<mat-icon>info_outline</mat-icon>
{{ 'iot-hub.solution-instructions' | translate }}
</a>
}
<a class="dlg-info-link" (click)="openEntityDetails()">
<mat-icon>open_in_new</mat-icon>
{{ 'iot-hub.goto-main-dashboard' | translate }}
</a>
</div>
} @else {
{{ 'iot-hub.open-item-type-details' | translate:{ type: getTypeLabel() } }}
<a class="dlg-info-link" (click)="openEntityDetails()">
<mat-icon>open_in_new</mat-icon>
{{ 'iot-hub.open-item-type-details' | translate:{ type: getTypeLabel() } }}
</a>
}
</a>
</div>
}
@if (item.description) {
<div class="dlg-description">
<tb-markdown [data]="item.description"></tb-markdown>
</div>
}
@if (item.description) {
<div class="dlg-description">
<tb-markdown [data]="item.description"></tb-markdown>
</div>
}
<div class="dlg-author" (click)="navigateToCreator()">
<tb-icon>person</tb-icon>
<span>{{ item.creatorDisplayName }}</span>
</div>
}
<div class="dlg-author" (click)="navigateToCreator()">
<tb-icon>person</tb-icon>
<span>{{ item.creatorDisplayName }}</span>
</div>
<!-- Action buttons -->
<div class="dlg-info-actions">
@ -188,7 +196,6 @@
</button>
}
@if (isInstalled()) {
<span class="dlg-info-actions-spacer"></span>
<button mat-stroked-button color="warn" (click)="deleteItem()">
<mat-icon>delete</mat-icon>
{{ 'iot-hub.remove' | translate }}

88
ui-ngx/src/app/modules/home/pages/iot-hub/iot-hub-item-detail-dialog.component.scss

@ -153,15 +153,6 @@
}
}
// Info panel (right side) Design: flex-1, flex-col, gap-16
.dlg-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 16px;
justify-content: center;
}
// Description rendered via tb-markdown, same overrides as dlg-readme
.dlg-description {
@ -183,7 +174,7 @@
}
}
// Author Design: person icon 20px + name 14px Medium $tb-primary-color
// Author Design: person icon 16px + name 12px Medium $tb-primary-color
.dlg-author {
display: flex;
align-items: center;
@ -191,16 +182,16 @@
cursor: pointer;
tb-icon {
font-size: 20px;
width: 20px;
height: 20px;
font-size: 16px;
width: 16px;
height: 16px;
color: rgba(0, 0, 0, 0.54);
}
span {
font-size: 14px;
font-size: 12px;
font-weight: 500;
line-height: 20px;
line-height: 16px;
letter-spacing: 0.25px;
color: $tb-primary-color;
}
@ -471,43 +462,70 @@
&.active { background: rgba(0, 0, 0, 0.6); }
}
// Info status row "Installed v1.0.0" badge + links
// Info panel Design: flex-col, gap-32 between text-container and buttons, py-16
.dlg-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 32px;
justify-content: center;
padding: 16px 0;
}
// Text container Design: flex-col, gap-16
.dlg-info-text {
display: flex;
flex-direction: column;
gap: 16px;
}
// Installed status row Design: flex, justify-between, full width
.dlg-info-status-row {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
justify-content: space-between;
width: 100%;
}
// Installed badge Design: pill, bg rgba(25,128,56,0.06), rounded-16, px-8 py-4
.dlg-installed-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 14px;
font-weight: 500;
color: #2e7d32;
padding: 4px 8px;
border-radius: 16px;
background: rgba(25, 128, 56, 0.06);
font-size: 12px;
font-weight: 400;
line-height: 16px;
letter-spacing: 0.4px;
color: #198038;
mat-icon {
font-size: 18px;
width: 18px;
height: 18px;
font-size: 14px;
width: 14px;
height: 14px;
}
}
// Open details / Solution instructions link Design: 12px Medium, $tb-primary-color
.dlg-info-link {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 14px;
font-size: 12px;
font-weight: 500;
line-height: 16px;
letter-spacing: 0.25px;
color: $tb-primary-color;
cursor: pointer;
text-decoration: none;
mat-icon {
font-size: 18px;
width: 18px;
height: 18px;
font-size: 16px;
width: 16px;
height: 16px;
}
&:hover {
@ -515,15 +533,19 @@
}
}
// Action buttons row in info section
.dlg-info-actions {
// Solution template links row
.dlg-info-links-row {
display: flex;
align-items: center;
gap: 8px;
gap: 16px;
}
.dlg-info-actions-spacer {
flex: 1;
// Action buttons row Design: flex, justify-between, full width
.dlg-info-actions {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
// Footer only Close button

Loading…
Cancel
Save