Skip to content

Commit

Permalink
4.50.5 (#1524)
Browse files Browse the repository at this point in the history
* Add singular plug-in label (#1458)

* Document the default port/address that you can access the UI in your web browser (#1252)

* Improve translations (#1459)

* Fix capitalization (#1496)

* Update zh-CN.json (#1503)

* Fixed nested arrays settings (#1504)

* Fixed nested arrays settings #2 (#1510)

* Fixed nested arrays;
Fixed lint;

* Removed console.log()

* Fixed nested arrays #3 (#1511)

* Wait for custom UI (#1522)

* Wait for custom UI (#1523)

---------

Co-authored-by: Dave Nicolson <david.nicolson@gmail.com>
Co-authored-by: Adam Coulombe <adamcoulombe187@hotmail.com>
Co-authored-by: Aiden <9078877+aiden0w0@users.noreply.github.com>
Co-authored-by: Artem Kononenko <slonick2012@gmail.com>
  • Loading branch information
5 people committed Aug 19, 2023
1 parent 8f4674d commit 1a9d76d
Show file tree
Hide file tree
Showing 39 changed files with 1,197 additions and 1,027 deletions.
1,613 changes: 814 additions & 799 deletions CHANGELOG.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ For detailed instructions on how to setup Node.js and Homebridge with Homebridge

If your platform is not listed above, or you want to use your own service manager, see the [Manual Configuration](https://github.com/homebridge/homebridge-config-ui-x/wiki/Manual-Configuration) wiki article for instructions on setting up the Homebridge UI to run as a Homebridge plugin instead of a service.

The default username is `admin` and the default password is `admin`.

The UI can be accessed via web browser by default on port `8581` (eg. `http://localhost:8581`).

# Usage

### Status Screen
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"hb-service": "./dist/bin/hb-service.js"
},
"engines": {
"node": ">=16.20.0",
"node": ">=16.20.2",
"homebridge": ">=1.6.0"
},
"scripts": {
Expand Down Expand Up @@ -151,4 +151,4 @@
"smart home",
"hb-service"
]
}
}
14 changes: 7 additions & 7 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@angular/platform-browser-dynamic": "^14.1.1",
"@angular/router": "^14.1.1",
"@auth0/angular-jwt": "^5.0.2",
"@homebridge/plugin-ui-utils": "0.0.19",
"@homebridge/plugin-ui-utils": "0.1.0",
"@ng-bootstrap/ng-bootstrap": "^11.0.1",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ng-container>
<json-schema-form *ngIf="configSchema.schema" [options]="jsonFormOptions" [schema]="configSchema.schema"
<json-schema-form *ngIf="configSchema.schema" [jsfPatch]="configSchema.fixArrays" [options]="jsonFormOptions" [schema]="configSchema.schema"
[layout]="configSchema.layout" [form]="configSchema.form" [data]="currentData" framework="bootstrap-4"
(onChanges)="onChanges($event)" (isValid)="validChange($event)" class="ng-bs4-validate">
</json-schema-form>
</ng-container>
</ng-container>
3 changes: 3 additions & 0 deletions ui/src/app/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ConfirmComponent } from './components/confirm/confirm.component';
import { SchemaFormComponent } from './components/schema-form/schema-form.component';
import { QrcodeComponent } from './components/qrcode/qrcode.component';
import { RtlDirective } from './directives/rtl.directive';
import { JsonSchemaFormPatchDirective } from './directives/json-schema-form-patch.directive';

@NgModule({
declarations: [
Expand All @@ -26,6 +27,7 @@ import { RtlDirective } from './directives/rtl.directive';
HrefTargetBlankDirective,
LongClickDirective,
RtlDirective,
JsonSchemaFormPatchDirective,
BackupRestoreComponent,
ScheduledBackupsComponent,
ConfirmComponent,
Expand All @@ -47,6 +49,7 @@ import { RtlDirective } from './directives/rtl.directive';
HrefTargetBlankDirective,
LongClickDirective,
RtlDirective,
JsonSchemaFormPatchDirective,
],
})
export class CoreModule { }
119 changes: 119 additions & 0 deletions ui/src/app/core/directives/json-schema-form-patch.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {Directive, Host, Input, Optional, Self} from '@angular/core';
import {JsonSchemaFormComponent} from '@oznu/ngx-bs4-jsonform';
import {cloneDeep, merge, uniqueId} from 'lodash-es';

@Directive({
selector: '[jsfPatch]',
})
export class JsonSchemaFormPatchDirective {
@Input() jsfPatch = false;

constructor(
@Host() @Self() @Optional() public jsonSchemaForm: JsonSchemaFormComponent) {

const buildLayoutOriginal = jsonSchemaForm.jsf.buildLayout.bind(jsonSchemaForm.jsf);

jsonSchemaForm.jsf.buildLayout = (widgetLibrary: any) => {

buildLayoutOriginal(widgetLibrary);
if (jsonSchemaForm.jsf.formValues && this.jsfPatch) {
return this.fixNestedArrayLayout(
jsonSchemaForm.jsf.layout,
jsonSchemaForm.jsf.formValues,
);
}
};

}

private fixNestedArrayLayout(builtLayout: any[], formData: any) {
this.fixArray(builtLayout, formData, '');
return builtLayout;
}

private fixArray(items: any | any[], formData: any, refPointer: string) {
if (Array.isArray(items)) {
const configItems = items.filter(x => x.name !== '_bridge');
const nestedItems = configItems
.filter(x => x.items && Array.isArray(x.items))
.flatMap(x => x.items)
.filter(x => x.dataType === 'array' || x.arrayItem);

const allItems = configItems.concat(nestedItems);
allItems.filter(x => x.dataType === 'array' || x.arrayItem).forEach(item => {
this.fixNestedArray(item, formData, refPointer);
});
} else {
this.fixNestedArray(items, formData, refPointer);
}
}

private fixNestedArray(item: any, formData: any, refPointer: string) {
if (item.items && Array.isArray(item.items)) {

const ref = item.items.find(x => x.type === '$ref');
if (ref) {

const dataItems = item.items.filter(x => x.type === 'section' || x.type === 'div');

const template = dataItems.length > 0
? dataItems.reduce((a, b) => a.id > b.id ? a : b)
: this.getItemTemplateFromRef(ref);

const data = this.getDataFromPointer(formData, ref.dataPointer.replace(refPointer, ''));

if (data === null) {
return;
}

if (Array.isArray(data)) {
// add missing items
while (item.items.length - 1 < data.length) {
const newItem = cloneDeep(template);
newItem._id = uniqueId('new_');

item.items.unshift(newItem);
}

data.forEach((d: any, index: number) => {
this.fixArray(item.items[index], d, ref.dataPointer);
});
} else {
this.fixArray(item.items, formData, ref.dataPointer);
}
} else {
this.fixArray(item.items, formData, refPointer);
}

item.items.filter(i => i.items && Array.isArray(i.items)).forEach(i => {
this.fixArray(i.items, formData, refPointer);
});
}
}

private getDataFromPointer(data: any, dataPointer: string) {
let value = data;

dataPointer.substring(1).split(/\//).filter(x => x !== '-')
.forEach((key: string) => {
try {
value = value[key];
} catch {
value = null;
}
});

return value;
}

private getItemTemplateFromRef(ref: any) {
const templateNode: { type: string; items: any[] } = {
type: 'section',
items: [],
};

const item = cloneDeep(ref);
merge(item, templateNode);
return item;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ <h5 class="modal-title">{{ plugin.displayName || plugin.name }}</h5>
style="border: 0;">
</iframe>

<div *ngIf="pluginConfig.length && schema.singular && showSchemaForm" class="card card-body">
<div *ngIf="uiLoaded && pluginConfig.length && schema.singular && showSchemaForm" class="card card-body">
<app-schema-form [configSchema]="schema" [(data)]="pluginConfig[0]"
(dataChanged)="schemaFormUpdatedSubject.next($event)">
</app-schema-form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class CustomPluginsComponent implements OnInit, OnDestroy {
public loading = true;
public saveInProgress = false;
public pluginSpinner = false;
public uiLoaded = false;

private basePath: string;
private iframe: HTMLIFrameElement;
Expand Down Expand Up @@ -130,6 +131,7 @@ export class CustomPluginsComponent implements OnInit, OnDestroy {
case 'loaded':
this.injectDefaultStyles(e);
this.confirmReady(e);
this.uiLoaded = true;
break;
case 'request': {
this.handleRequest(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<br>

<a routerLink="/plugins" class="primary-text" *ngIf="homebridgePluginStatus.length">
{{ homebridgePluginStatus.length }} {{ 'status.plugins_out_of_date' | translate }}
{{ homebridgePluginStatus.length }} {{ homebridgePluginStatus.length === 1 ? ('status.plugin_out_of_date' | translate) : ('status.plugins_out_of_date' | translate) }}
</a>
<a class="grey-text card-link" routerLink="/plugins" *ngIf="!homebridgePluginStatus.length"
[translate]="'status.services.label_not_running'">
Expand Down
15 changes: 8 additions & 7 deletions ui/src/i18n/bg.json
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
"backup.button_restore_backup": "Restore Backup",
"backup.label_archive_name": "Archive Name",
"backup.label_backup_time": "Backup Time",
"backup.label_choose_backup_file_to_restore": "Choose backup file to restore...",
"backup.label_uploading": "Uploading...",
"backup.label_choose_backup_file_to_restore": "Choose backup file to restore",
"backup.label_uploading": "Uploading",
"backup.message_backup_archive_created": "Backup Archive Created",
"backup.message_backup_download_failed": "Backup Download Failed",
"backup.message_backup_help_one": "Download a backup archive of your entire Homebridge environment. This will backup the entire contents of your Homebridge storage directory which you can later restore on any platform capable of running Homebridge UI.",
Expand All @@ -77,7 +77,7 @@
"backup.title_backup_restore": "Backup / Restore",
"backup.title_restore": "Restore",
"backup.title_scheduled_backups": "Scheduled Backups",
"child_bridge.label_bridge_connect_to_homekit": "Connect to Homekit",
"child_bridge.label_bridge_connect_to_homekit": "Connect to HomeKit",
"child_bridge.label_bridge_paired": "Bridge Paired",
"child_bridge.label_bridge_restart_child_bridges": "Restart Child Bridges",
"child_bridge.label_bridge_settings": "Bridge Settings",
Expand Down Expand Up @@ -209,7 +209,7 @@
"plugins.node_update.title": "Node.js Version",
"plugins.node_update.update_anyway": "Update Anyway",
"plugins.node_update_homebridge_upgrade_and_try_again": "Please upgrade Node.js before updating Homebridge.",
"plugins.placeholder_search_plugin": "Търсете добавки, които да инсталирате...",
"plugins.placeholder_search_plugin": "Търсете добавки, които да инсталирате",
"plugins.settings.custom.homebridge-gsh.label_account_linked": "Account Linked",
"plugins.settings.custom.homebridge-gsh.label_link_account": "Link Account",
"plugins.settings.custom.homebridge-gsh.label_unlink_account": "Unlink Account",
Expand Down Expand Up @@ -255,7 +255,7 @@
"reset.toast_clear_cached_accessories_success": "Restarting Homebridge and clearing accessory cache.",
"reset.toast_failed_to_delete_cached_accessory": "Failed to delete accessory.",
"reset.toast_failed_to_reset": "Неуспешно нулиране на Homebridge. Виж лог.",
"reset.toast_removing_cached_accessory_please_wait": "Removing accessory from cache, please wait...",
"reset.toast_removing_cached_accessory_please_wait": "Removing accessory from cache, please wait",
"restart.label_restart_command_executed": "Командата за рестартиране е изпълнена",
"restart.message_homebridge_service_ready": "Homebridge Server Ready",
"restart.message_homebridge_ui_online": "Homebridge UI Online",
Expand Down Expand Up @@ -293,7 +293,7 @@
"status.cpu.label_load": "Използва",
"status.cpu.label_temp": "Темп.",
"status.cpu.title_cpu": "Процесор",
"status.homebridge.label_checking_for_updates": "Преверява се за актуализация...",
"status.homebridge.label_checking_for_updates": "Преверява се за актуализация",
"status.homebridge.label_up_to_date": "Актуален",
"status.homebridge.label_update_available": "{{latestVersion}} налична актуализация",
"status.homebridge.label_version": "Версия",
Expand All @@ -305,13 +305,14 @@
"status.network.label_received_per_second": "Received",
"status.network.label_sent_per_second": "Sent",
"status.network.title_network": "Network Activity",
"status.plugin_out_of_date": "Добавката е остаряла",
"status.plugins_out_of_date": "Добавките са остарели",
"status.services.label_console": "Конзола",
"status.services.label_listening_on_port": "Слуша на порт {{port}}",
"status.services.label_not_running": "Не работи",
"status.services.label_running": "Работи",
"status.services.label_running_on_port": "Работи на порт {{port}}",
"status.services.label_starting": "Starting...",
"status.services.label_starting": "Starting",
"status.services.title_services": "Услуги",
"status.title_server_status": "Статус на сървъра",
"status.uptime.label_days": "Дни",
Expand Down
Loading

0 comments on commit 1a9d76d

Please sign in to comment.