Skip to content

Commit

Permalink
refactor status and child bridge widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
bwp91 committed Jan 24, 2025
1 parent 0e6b740 commit cb770ea
Show file tree
Hide file tree
Showing 50 changed files with 515 additions and 541 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to `homebridge-config-ui-x` will be documented in this file.

## BETA

### ⚠️ Status Page Widget Renaming

This version of Homebridge UI renames some widgets. If you update, and see some blank widgets on your home screen, perform a reset of your layout widgets:
- Click the 'Show/Hide Widgets' button in the top right corner of the status screen
- Scroll down to the bottom of the window that appears and click the red 'Reset' button on the right

### ⚠️ Plugin Config Validation

This version of Homebridge UI adds validation to plugin config screens. This does not apply to manual plugin configuration (with raw `JSON`).
Expand All @@ -30,6 +36,13 @@ Plugin developers:
- fix typos in hb/ui settings schemas (#2317) (@dnicolson)
- fix margins in update plugin modal
- add plugin config validation functionality
- refactor status and child bridge widgets
- the existing 'status' widget has been renamed to 'update info' widget
- the existing 'child bridges' widget has been renamed to 'bridges' widget
- the homebridge status (from the old status widget) is now shown as a bridge in the new bridges widget
- node update information has been added to the new update info widget
- a widget option has been added to hide node update information: this may be useful for docker/synology users
- homebridge and ui version information has been moved from the footer to the new update info widget

### Other Changes

Expand Down
22 changes: 0 additions & 22 deletions src/modules/status/status.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { UseGuards } from '@nestjs/common'
import { SubscribeMessage, WebSocketGateway, WsException } from '@nestjs/websockets'

import { WsGuard } from '../../core/auth/guards/ws.guard'
import { ChildBridgesService } from '../child-bridges/child-bridges.service'
import { PluginsService } from '../plugins/plugins.service'
import { StatusService } from './status.service'

Expand All @@ -19,7 +18,6 @@ export class StatusGateway {
constructor(
private statusService: StatusService,
private pluginsService: PluginsService,
private childBridgesService: ChildBridgesService,
) {}

@SubscribeMessage('get-dashboard-layout')
Expand Down Expand Up @@ -153,26 +151,6 @@ export class StatusGateway {
this.statusService.watchStats(client)
}

/**
* @deprecated
*/
@SubscribeMessage('get-homebridge-child-bridge-status')
async getChildBridges() {
try {
return await this.childBridgesService.getChildBridges()
} catch (e) {
return new WsException(e.message)
}
}

/**
* @deprecated
*/
@SubscribeMessage('monitor-child-bridge-status')
async watchChildBridgeStatus(client) {
this.childBridgesService.watchChildBridgeStatus(client)
}

@SubscribeMessage('get-raspberry-pi-throttled-status')
async getRaspberryPiThrottledStatus() {
try {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/status/status.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,12 @@ export class StatusService {
return {
status: this.homebridgeStatus,
consolePort: this.configService.ui.port,
name: this.configService.homebridgeConfig.bridge.name,
port: this.configService.homebridgeConfig.bridge.port,
pin: this.configService.homebridgeConfig.bridge.pin,
setupUri: this.serverService.setupCode,
packageVersion: this.configService.package.version,
paired: this.serverService.paired,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ <h5 class="text-center mb-3">
} @if (!['homebridge', 'homebridge-config-ui-x'].includes(pluginName) && childBridges.length > 0) {
<p class="text-center mb-0">{{ 'restart.child_bridges' | translate }}</p>
} } @if (changeLog) {
<div class="alert pt-3 px-3 pb-0 mt-3">
<div class="alert p-3 pb-1 mt-3">
<markdown class="plugin-md" [data]="changeLog"></markdown>
</div>
} }
Expand Down Expand Up @@ -85,7 +85,7 @@ <h5 class="mb-3 text-center">
} @if (release.name) { {{ release.name }} } @if (!release.name) { v{{ latestVersion }} }
</h5>
}
<div class="alert pt-3 px-3 pb-0 mb-0">
<div class="alert p-3 pb-1 mb-0">
<markdown class="plugin-md" [data]="release.changelog"></markdown>
</div>
</div>
Expand Down
5 changes: 2 additions & 3 deletions ui/src/app/modules/status/default-dashboard-layout.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"component": "HomebridgeStatusWidgetComponent",
"component": "UpdateInfoWidgetComponent",
"x": 0,
"y": 0,
"cols": 5,
Expand All @@ -9,13 +9,12 @@
"hideOnMobile": false
},
{
"component": "ChildBridgeWidgetComponent",
"component": "BridgesWidgetComponent",
"x": 0,
"y": 7,
"cols": 5,
"rows": 7,
"mobileOrder": 35,
"hidePort": true,
"hideOnMobile": false
},
{
Expand Down
12 changes: 6 additions & 6 deletions ui/src/app/modules/status/status.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,20 @@ <h3 class="primary-text m-0">{{ 'menu.label_status' | translate }}</h3>
<!-- The below copyright notice shall be included and displayed on all copies or substantial portions of this software. -->
<small>
&copy; {{ currentYear }} &middot;
<a class="grey-text" target="_blank" rel="noopener noreferrer" href="https://github.com/homebridge">
Homebridge v{{ $settings.env.homebridgeVersion }}</a
>
<a class="grey-text" target="_blank" rel="noopener noreferrer" href="https://github.com/homebridge/homebridge">
Homebridge
</a>
&middot;
<a
class="grey-text"
target="_blank"
rel="noopener noreferrer"
href="https://github.com/homebridge/homebridge-config-ui-x"
>
UI v{{ $settings.env.packageVersion }}</a
>
Homebridge UI
</a>
&middot;
<a class="primary-text" href="javascript: void(0);" (click)="openCreditsModal()">
<a class="grey-text" href="javascript: void(0);" (click)="openCreditsModal()">
<i class="fas fa-fw fa-heart"></i
></a>
</small>
Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/modules/status/status.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ gridster {

gridster {
&.mobile {
#HomebridgeStatusWidgetComponent,
#UpdateInfoWidgetComponent,
#SystemInfoWidgetComponent,
#WeatherWidgetComponent,
#ChildBridgeWidgetComponent,
#BridgesWidgetComponent,
#ClockWidgetComponent {
height: unset !important;
}
Expand Down
4 changes: 2 additions & 2 deletions ui/src/app/modules/status/status.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class StatusComponent implements OnInit, OnDestroy {
$auth = inject(AuthService)
private $modal = inject(NgbModal)
private $notification = inject(NotificationService)
$settings = inject(SettingsService)
private $settings = inject(SettingsService)
private $ws = inject(WsService)

public saveWidgetsEvent = new Subject()
Expand Down Expand Up @@ -126,7 +126,7 @@ export class StatusComponent implements OnInit, OnDestroy {
if (!layout.length) {
return this.resetLayout()
}
this.setLayout(layout)
this.setLayout(layout.map((item: any) => item))
},
)
}
Expand Down
8 changes: 4 additions & 4 deletions ui/src/app/modules/status/status.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ import { StatusComponent } from '@/app/modules/status/status.component'
import { WidgetControlComponent } from '@/app/modules/status/widget-control/widget-control.component'
import { WidgetVisibilityComponent } from '@/app/modules/status/widget-visibility/widget-visibility.component'
import { AccessoriesWidgetComponent } from '@/app/modules/status/widgets/accessories-widget/accessories-widget.component'
import { ChildBridgeWidgetComponent } from '@/app/modules/status/widgets/child-bridge-widget/child-bridge-widget.component'
import { BridgesWidgetComponent } from '@/app/modules/status/widgets/bridges-widget/bridges-widget.component'
import { ClockWidgetComponent } from '@/app/modules/status/widgets/clock-widget/clock-widget.component'
import { CpuWidgetComponent } from '@/app/modules/status/widgets/cpu-widget/cpu-widget.component'
import { HapQrcodeWidgetComponent } from '@/app/modules/status/widgets/hap-qrcode-widget/hap-qrcode-widget.component'
import { HomebridgeLogsWidgetComponent } from '@/app/modules/status/widgets/homebridge-logs-widget/homebridge-logs-widget.component'
import { HomebridgeStatusWidgetComponent } from '@/app/modules/status/widgets/homebridge-status-widget/homebridge-status-widget.component'
import { MemoryWidgetComponent } from '@/app/modules/status/widgets/memory-widget/memory-widget.component'
import { NetworkWidgetComponent } from '@/app/modules/status/widgets/network-widget/network-widget.component'
import { SystemInfoWidgetComponent } from '@/app/modules/status/widgets/system-info-widget/system-info-widget.component'
import { TerminalWidgetComponent } from '@/app/modules/status/widgets/terminal-widget/terminal-widget.component'
import { UpdateInfoWidgetComponent } from '@/app/modules/status/widgets/update-info-widget/update-info-widget.component'
import { UptimeWidgetComponent } from '@/app/modules/status/widgets/uptime-widget/uptime-widget.component'
import { WeatherWidgetComponent } from '@/app/modules/status/widgets/weather-widget/weather-widget.component'
import { WidgetsComponent } from '@/app/modules/status/widgets/widgets.component'
Expand Down Expand Up @@ -53,12 +53,12 @@ import { WidgetsComponent } from '@/app/modules/status/widgets/widgets.component
MemoryWidgetComponent,
NetworkWidgetComponent,
UptimeWidgetComponent,
HomebridgeStatusWidgetComponent,
UpdateInfoWidgetComponent,
SystemInfoWidgetComponent,
WeatherWidgetComponent,
AccessoriesWidgetComponent,
ClockWidgetComponent,
ChildBridgeWidgetComponent,
BridgesWidgetComponent,
CreditsComponent,
],
providers: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,21 @@ <h5 class="modal-title">{{ 'status.widget.title_manage_widget' | translate }}</h
<label for="hideOnMobile" class="rendux-label ml-3"></label>
</div>
</li>
@switch (widget.component) { @case ('WeatherWidgetComponent') {
@switch (widget.component) { @case ('UpdateInfoWidgetComponent') {
<li class="list-group-item d-flex justify-content-between align-items-center flex-row pb-2">
<span class="text-left">{{ 'status.widget.hide_node_info' | translate }}</span>
<div class="text-right grey-text">
<input
type="checkbox"
class="rendux-input"
id="hideNodeInfo"
[(ngModel)]="widget.hideNodeInfo"
[attr.aria-label]="'status.widget.hide_node_info' | translate"
/>
<label for="hideNodeInfo" class="rendux-label ml-3"></label>
</div>
</li>
} @case ('WeatherWidgetComponent') {
<li class="list-group-item d-flex flex-column flex-md-row align-items-center">
<label for="city-search-input" class="mb-2 mb-md-0 w-100 w-md-50">
{{ 'status.widget.weather.label_search_for_your_city' | translate }}
Expand All @@ -52,20 +66,6 @@ <h5 class="modal-title">{{ 'status.widget.title_manage_widget' | translate }}</h
</div>
</li>
<li class="list-group-item muted grey-text text-center">Weather data is provided by OpenWeather.</li>
} @case ('HomebridgeStatusWidgetComponent') {
<li class="list-group-item d-flex justify-content-between align-items-center flex-row pb-2">
<span class="text-left">{{ 'status.widget.homebridge_port' | translate }}</span>
<div class="text-right grey-text">
<input
type="checkbox"
class="rendux-input"
id="hidePort"
[(ngModel)]="widget.hidePort"
[attr.aria-label]="'status.widget.homebridge_port' | translate"
/>
<label for="hidePort" class="rendux-label ml-3"></label>
</div>
</li>
} @case ('HomebridgeLogsWidgetComponent') {
<li class="list-group-item d-flex flex-column flex-md-row align-items-center">
<label class="mb-2 mb-md-0 w-100 w-md-50">{{ 'status.widget.font_size' | translate }}</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export class WidgetVisibilityComponent implements OnInit {
ngOnInit() {
const allWidgets = [
{
name: this.$translate.instant('status.widget.add.label_homebridge_status'),
component: 'HomebridgeStatusWidgetComponent',
name: this.$translate.instant('status.services.updates'),
component: 'UpdateInfoWidgetComponent',
hidden: false,
cols: 10,
rows: 3,
Expand All @@ -55,8 +55,8 @@ export class WidgetVisibilityComponent implements OnInit {
hideOnMobile: false,
},
{
name: 'Child Bridge Status',
component: 'ChildBridgeWidgetComponent',
name: this.$translate.instant('child_bridge.bridges'),
component: 'BridgesWidgetComponent',
hidden: !this.$settings.env.serviceMode,
cols: 5,
rows: 9,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<div class="flex-column d-flex align-items-stretch h-100 w-100 pb-3 overflow-auto no-scrollbars">
<div class="drag-handler p-2" [ngClass]="{ 'widget-cursor': widget.draggable }">
{{ 'child_bridge.bridges' | translate }}
</div>
<div
class="d-flex flex-wrap w-100 mt-0 justify-content-start gridster-item-content overflow-auto no-scrollbars align-items-center"
>
<div class="hb-status-item d-flex flex-row w-100 px-3 mt-2 mb-1" style="min-width: max(25%, 225px)">
<div class="hb-status-icon d-flex align-items-center">
<i
class="fas fa-fw"
[ngClass]="{
'fa-bridge-circle-check green-text': homebridgeStatus.status === 'up',
'fa-bridge-circle-exclamation text-warning': homebridgeStatus.status === 'pending',
'fa-bridge-circle-xmark red-text': homebridgeStatus.status === 'down'
}"
container="body"
placement="right"
openDelay="150"
triggers="hover"
[ngbTooltip]="(homebridgeStatus.status === 'up' ? 'status.services.label_running' : (homebridgeStatus.status ===
'pending' ? 'status.services.label_running' : 'status.services.label_not_running')) | translate"
[attr.aria-label]="(homebridgeStatus.status === 'up' ? 'status.services.label_running' : (homebridgeStatus.status ===
'pending' ? 'status.services.label_running' : 'status.services.label_not_running')) | translate"
></i>
</div>
<div class="align-self-center flex-child px-3">{{ homebridgeStatus.name || 'Homebridge' }}</div>
<div class="grey-text ml-auto d-flex align-items-center">
@if (homebridgeStatus.status === 'up') {
<i
class="icon-button fas fa-fw fa-power-off"
href="javascript:void(0)"
(click)="restartHomebridge()"
[ngbTooltip]="'menu.tooltip_restart' | translate"
container="body"
openDelay="150"
triggers="hover"
placement="left"
></i>
} @if (homebridgeStatus.status !== 'up') {
<i class="fas icon-button fa-fw fa-spinner fa-pulse"></i>
}
<i
class="fas fa-fw ml-2 fa-link"
[ngbTooltip]="(homebridgeStatus.paired ? 'status.widget.qr_paired' : 'status.widget.qr_unpaired') | translate"
container="body"
openDelay="150"
triggers="hover"
placement="left"
[ngClass]="{
'green-text': homebridgeStatus.paired,
'grey-text': !homebridgeStatus.paired
}"
></i>
</div>
</div>
@for (bridge of childBridges; track bridge) {
<div class="hb-status-item d-flex flex-row w-100 px-3 mt-2 mb-1" style="min-width: max(25%, 225px)">
<div class="hb-status-icon d-flex align-items-center">
<i
class="fas fa-fw"
[ngClass]="{
'fa-bridge-circle-check green-text': bridge.status === 'ok',
'fa-bridge-circle-exclamation text-warning': bridge.status === 'pending',
'fa-bridge-circle-xmark red-text': bridge.status === 'down'
}"
container="body"
placement="right"
openDelay="150"
triggers="hover"
[ngbTooltip]="(bridge.status === 'ok' ? 'status.services.label_running' : (bridge.status ===
'pending' ? 'status.services.label_running' : 'status.services.label_not_running')) | translate"
[attr.aria-label]="(bridge.status === 'ok' ? 'status.services.label_running' : (bridge.status ===
'pending' ? 'status.services.label_running' : 'status.services.label_not_running')) | translate"
></i>
</div>
<div class="align-self-center flex-child px-3">{{ bridge.name }}</div>
<div class="grey-text ml-auto d-flex align-items-center">
@if (bridge.status === 'ok') {
<i
class="icon-button fas fa-fw fa-power-off"
href="javascript:void(0)"
(click)="restartChildBridge(bridge)"
[ngbTooltip]="'menu.tooltip_restart' | translate"
container="body"
openDelay="150"
triggers="hover"
placement="left"
></i>
} @if (bridge.status !== 'ok') {
<i class="fas icon-button fa-fw fa-spinner fa-pulse"></i>
}
<i
class="fas fa-fw ml-2 fa-link"
[ngbTooltip]="(bridge.paired ? 'status.widget.qr_paired' : 'status.widget.qr_unpaired') | translate"
container="body"
openDelay="150"
triggers="hover"
placement="left"
[ngClass]="{
'green-text': bridge.paired,
'grey-text': !bridge.paired
}"
></i>
</div>
</div>
}
</div>
</div>
Loading

0 comments on commit cb770ea

Please sign in to comment.