mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-12 18:59:26 +00:00
Compare commits
5 Commits
blocking-u
...
checkbox-s
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0bfeb22209 | ||
![]() |
0e3eed0563 | ||
![]() |
1b1676cecc | ||
![]() |
d911fe6a0b | ||
![]() |
22253a3385 |
@@ -1,4 +1,5 @@
|
||||
// Tasks to run webpack.
|
||||
const fs = require("fs");
|
||||
const gulp = require("gulp");
|
||||
const webpack = require("webpack");
|
||||
const WebpackDevServer = require("webpack-dev-server");
|
||||
@@ -18,6 +19,11 @@ const bothBuilds = (createConfigFunc, params) => [
|
||||
createConfigFunc({ ...params, latestBuild: false }),
|
||||
];
|
||||
|
||||
const isWsl = fs
|
||||
.readFileSync("/proc/version", "utf-8")
|
||||
.toLocaleLowerCase()
|
||||
.includes("microsoft");
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* compiler: import("webpack").Compiler,
|
||||
@@ -79,7 +85,7 @@ const prodBuild = (conf) =>
|
||||
gulp.task("webpack-watch-app", () => {
|
||||
// This command will run forever because we don't close compiler
|
||||
webpack(createAppConfig({ isProdBuild: false, latestBuild: true })).watch(
|
||||
{ ignored: /build-translations/ },
|
||||
{ ignored: /build-translations/, poll: isWsl },
|
||||
doneHandler()
|
||||
);
|
||||
gulp.watch(
|
||||
@@ -137,7 +143,7 @@ gulp.task("webpack-watch-hassio", () => {
|
||||
isProdBuild: false,
|
||||
latestBuild: true,
|
||||
})
|
||||
).watch({ ignored: /build-translations/ }, doneHandler());
|
||||
).watch({ ignored: /build-translations/, poll: isWsl }, doneHandler());
|
||||
|
||||
gulp.watch(
|
||||
path.join(paths.translations_src, "en.json"),
|
||||
|
@@ -977,6 +977,7 @@ class HassioAddonInfo extends LitElement {
|
||||
showDialogSupervisorUpdate(this, {
|
||||
supervisor: this.supervisor,
|
||||
name: this.addon.name,
|
||||
slug: this.addon.slug,
|
||||
version: this.addon.version_latest,
|
||||
snapshotParams: {
|
||||
name: `addon_${this.addon.slug}_${this.addon.version}`,
|
||||
|
@@ -161,6 +161,7 @@ export class HassioUpdate extends LitElement {
|
||||
showDialogSupervisorUpdate(this, {
|
||||
supervisor: this.supervisor,
|
||||
name: "Home Assistant Core",
|
||||
slug: "core",
|
||||
version: this.supervisor.core.version_latest,
|
||||
snapshotParams: {
|
||||
name: `core_${this.supervisor.core.version}`,
|
||||
@@ -220,29 +221,10 @@ export class HassioUpdate extends LitElement {
|
||||
}
|
||||
|
||||
private async _updateCore(): Promise<void> {
|
||||
try {
|
||||
await updateCore(this.hass);
|
||||
} catch (err) {
|
||||
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
||||
showAlertDialog(this, {
|
||||
title: this.supervisor.localize(
|
||||
"common.failed_to_update_name",
|
||||
"name",
|
||||
"Home Assistant Core"
|
||||
),
|
||||
text: extractApiErrorMessage(err),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await updateCore(this.hass);
|
||||
fireEvent(this, "supervisor-collection-refresh", {
|
||||
collection: "core",
|
||||
});
|
||||
fireEvent(this, "supervisor-applying-update", {
|
||||
name: "Home Assistant Core",
|
||||
version: this.supervisor.core.version_latest,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
@@ -2,16 +2,32 @@ import "@material/mwc-button/mwc-button";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-checkbox";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-settings-row";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import "../../../../src/components/ha-switch";
|
||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||
import {
|
||||
extractApiErrorMessage,
|
||||
ignoreSupervisorError,
|
||||
} from "../../../../src/data/hassio/common";
|
||||
import {
|
||||
SupervisorFrontendPrefrences,
|
||||
fetchSupervisorFrontendPreferences,
|
||||
saveSupervisorFrontendPreferences,
|
||||
} from "../../../../src/data/supervisor/supervisor";
|
||||
import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot";
|
||||
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import { SupervisorDialogSupervisorUpdateParams } from "./show-dialog-update";
|
||||
import memoizeOne from "memoize-one";
|
||||
|
||||
const snapshot_before_update = memoizeOne(
|
||||
(slug: string, frontendPrefrences: SupervisorFrontendPrefrences) =>
|
||||
slug in frontendPrefrences.snapshot_before_update
|
||||
? frontendPrefrences.snapshot_before_update[slug]
|
||||
: true
|
||||
);
|
||||
|
||||
@customElement("dialog-supervisor-update")
|
||||
class DialogSupervisorUpdate extends LitElement {
|
||||
@@ -19,12 +35,12 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
|
||||
@state() private _opened = false;
|
||||
|
||||
@state() private _createSnapshot = true;
|
||||
|
||||
@state() private _action: "snapshot" | "update" | null = null;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
@state() private _frontendPrefrences?: SupervisorFrontendPrefrences;
|
||||
|
||||
@state()
|
||||
private _dialogParams?: SupervisorDialogSupervisorUpdateParams;
|
||||
|
||||
@@ -33,14 +49,17 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
): Promise<void> {
|
||||
this._opened = true;
|
||||
this._dialogParams = params;
|
||||
this._frontendPrefrences = await fetchSupervisorFrontendPreferences(
|
||||
this.hass
|
||||
);
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._action = null;
|
||||
this._createSnapshot = true;
|
||||
this._error = undefined;
|
||||
this._dialogParams = undefined;
|
||||
this._frontendPrefrences = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
@@ -53,7 +72,7 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._dialogParams) {
|
||||
if (!this._dialogParams || !this._frontendPrefrences) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
@@ -79,6 +98,16 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
</div>
|
||||
|
||||
<ha-settings-row>
|
||||
<ha-checkbox
|
||||
.checked=${snapshot_before_update(
|
||||
this._dialogParams.slug,
|
||||
this._frontendPrefrences
|
||||
)}
|
||||
haptic
|
||||
@click=${this._toggleSnapshot}
|
||||
slot="prefix"
|
||||
>
|
||||
</ha-checkbox>
|
||||
<span slot="heading">
|
||||
${this._dialogParams.supervisor.localize(
|
||||
"dialog.update.snapshot"
|
||||
@@ -91,12 +120,6 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
this._dialogParams.name
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.checked=${this._createSnapshot}
|
||||
haptic
|
||||
@click=${this._toggleSnapshot}
|
||||
>
|
||||
</ha-switch>
|
||||
</ha-settings-row>
|
||||
<mwc-button @click=${this.closeDialog} slot="secondaryAction">
|
||||
${this._dialogParams.supervisor.localize("common.cancel")}
|
||||
@@ -130,12 +153,27 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _toggleSnapshot() {
|
||||
this._createSnapshot = !this._createSnapshot;
|
||||
private async _toggleSnapshot(): Promise<void> {
|
||||
this._frontendPrefrences!.snapshot_before_update[
|
||||
this._dialogParams!.slug
|
||||
] = !snapshot_before_update(
|
||||
this._dialogParams!.slug,
|
||||
this._frontendPrefrences!
|
||||
);
|
||||
|
||||
await saveSupervisorFrontendPreferences(
|
||||
this.hass,
|
||||
this._frontendPrefrences!
|
||||
);
|
||||
}
|
||||
|
||||
private async _update() {
|
||||
if (this._createSnapshot) {
|
||||
if (
|
||||
snapshot_before_update(
|
||||
this._dialogParams!.slug,
|
||||
this._frontendPrefrences!
|
||||
)
|
||||
) {
|
||||
this._action = "snapshot";
|
||||
try {
|
||||
await createHassioPartialSnapshot(
|
||||
@@ -150,7 +188,16 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
}
|
||||
|
||||
this._action = "update";
|
||||
await this._dialogParams!.updateHandler!();
|
||||
try {
|
||||
await this._dialogParams!.updateHandler!();
|
||||
} catch (err) {
|
||||
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
||||
this._error = extractApiErrorMessage(err);
|
||||
}
|
||||
this._action = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
|
@@ -1,18 +1,18 @@
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import { HassioPartialSnapshotCreateParams } from "../../../../src/data/hassio/snapshot";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
|
||||
export interface SupervisorDialogSupervisorUpdateParams {
|
||||
supervisor: Supervisor;
|
||||
name: string;
|
||||
version: string;
|
||||
snapshotParams: HassioPartialSnapshotCreateParams;
|
||||
slug: string;
|
||||
snapshotParams: any;
|
||||
updateHandler: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const showDialogSupervisorUpdate = (
|
||||
element: HTMLElement,
|
||||
dialogParams: Partial<SupervisorDialogSupervisorUpdateParams>
|
||||
dialogParams: SupervisorDialogSupervisorUpdateParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-supervisor-update",
|
||||
|
@@ -1,26 +1,12 @@
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import {
|
||||
Supervisor,
|
||||
supervisorApplyUpdateDetails,
|
||||
supervisorCollection,
|
||||
} from "../../src/data/supervisor/supervisor";
|
||||
import { HomeAssistant, Route } from "../../src/types";
|
||||
import "./hassio-panel-router";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"supervisor-applying-update": supervisorApplyUpdateDetails;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("hassio-panel")
|
||||
class HassioPanel extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@@ -31,16 +17,6 @@ class HassioPanel extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@state() private _applyingUpdate?: supervisorApplyUpdateDetails;
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._applyingUpdate = undefined;
|
||||
this.addEventListener("supervisor-applying-update", (ev) => {
|
||||
this._applyingUpdate = ev.detail;
|
||||
});
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass) {
|
||||
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||
@@ -53,16 +29,6 @@ class HassioPanel extends LitElement {
|
||||
) {
|
||||
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||
}
|
||||
|
||||
if (this._applyingUpdate !== undefined) {
|
||||
return html`<hass-loading-screen no-toolbar>
|
||||
${this.supervisor.localize("dialog.update.updating", {
|
||||
name: this._applyingUpdate.name,
|
||||
version: this._applyingUpdate.version,
|
||||
})}
|
||||
</hass-loading-screen>`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<hassio-panel-router
|
||||
.hass=${this.hass}
|
||||
|
@@ -11,7 +11,6 @@ import {
|
||||
extractApiErrorMessage,
|
||||
fetchHassioStats,
|
||||
HassioStats,
|
||||
ignoreSupervisorError,
|
||||
} from "../../../src/data/hassio/common";
|
||||
import { restartCore, updateCore } from "../../../src/data/supervisor/core";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
@@ -151,7 +150,7 @@ class HassioCoreInfo extends LitElement {
|
||||
title: this.supervisor.localize(
|
||||
"common.failed_to_restart_name",
|
||||
"name",
|
||||
"Home Assistant Core"
|
||||
"Home AssistantCore"
|
||||
),
|
||||
text: extractApiErrorMessage(err),
|
||||
});
|
||||
@@ -165,6 +164,7 @@ class HassioCoreInfo extends LitElement {
|
||||
showDialogSupervisorUpdate(this, {
|
||||
supervisor: this.supervisor,
|
||||
name: "Home Assistant Core",
|
||||
slug: "core",
|
||||
version: this.supervisor.core.version_latest,
|
||||
snapshotParams: {
|
||||
name: `core_${this.supervisor.core.version}`,
|
||||
@@ -176,29 +176,10 @@ class HassioCoreInfo extends LitElement {
|
||||
}
|
||||
|
||||
private async _updateCore(): Promise<void> {
|
||||
try {
|
||||
await updateCore(this.hass);
|
||||
} catch (err) {
|
||||
if (this.hass.connection.connected && !ignoreSupervisorError(err)) {
|
||||
showAlertDialog(this, {
|
||||
title: this.supervisor.localize(
|
||||
"common.failed_to_update_name",
|
||||
"name",
|
||||
"Home Assistant Core"
|
||||
),
|
||||
text: extractApiErrorMessage(err),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await updateCore(this.hass);
|
||||
fireEvent(this, "supervisor-collection-refresh", {
|
||||
collection: "core",
|
||||
});
|
||||
fireEvent(this, "supervisor-applying-update", {
|
||||
name: "Home Assistant Core",
|
||||
version: this.supervisor.core.version_latest,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
|
@@ -2,6 +2,7 @@ import { Connection, getCollection } from "home-assistant-js-websocket";
|
||||
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||
import { LocalizeFunc } from "../../common/translations/localize";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { fetchFrontendUserData, saveFrontendUserData } from "../frontend";
|
||||
import { HassioAddonsInfo } from "../hassio/addon";
|
||||
import { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
|
||||
import { NetworkInfo } from "../hassio/network";
|
||||
@@ -13,11 +14,28 @@ import {
|
||||
} from "../hassio/supervisor";
|
||||
import { SupervisorStore } from "./store";
|
||||
|
||||
export interface supervisorApplyUpdateDetails {
|
||||
name: string;
|
||||
version: string;
|
||||
export interface SupervisorFrontendPrefrences {
|
||||
snapshot_before_update: Record<string, boolean>;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface FrontendUserData {
|
||||
supervisor: SupervisorFrontendPrefrences;
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchSupervisorFrontendPreferences = async (
|
||||
hass: HomeAssistant
|
||||
): Promise<SupervisorFrontendPrefrences> => {
|
||||
const stored = await fetchFrontendUserData(hass.connection, "supervisor");
|
||||
return stored || { snapshot_before_update: {} };
|
||||
};
|
||||
|
||||
export const saveSupervisorFrontendPreferences = (
|
||||
hass: HomeAssistant,
|
||||
data: SupervisorFrontendPrefrences
|
||||
) => saveFrontendUserData(hass.connection, "supervisor", data);
|
||||
|
||||
export const supervisorWSbaseCommand = {
|
||||
type: "supervisor/api",
|
||||
method: "GET",
|
||||
|
@@ -108,12 +108,28 @@ export const showOptionsFlowDialog = (
|
||||
`;
|
||||
},
|
||||
|
||||
renderShowFormProgressHeader(_hass, _step) {
|
||||
return "";
|
||||
renderShowFormProgressHeader(hass, step) {
|
||||
return (
|
||||
hass.localize(
|
||||
`component.${configEntry.domain}.options.step.${step.step_id}.title`
|
||||
) || hass.localize(`component.${configEntry.domain}.title`)
|
||||
);
|
||||
},
|
||||
|
||||
renderShowFormProgressDescription(_hass, _step) {
|
||||
return "";
|
||||
renderShowFormProgressDescription(hass, step) {
|
||||
const description = hass.localize(
|
||||
`component.${configEntry.domain}.options.progress.${step.progress_action}`,
|
||||
step.description_placeholders
|
||||
);
|
||||
return description
|
||||
? html`
|
||||
<ha-markdown
|
||||
allowsvg
|
||||
breaks
|
||||
.content=${description}
|
||||
></ha-markdown>
|
||||
`
|
||||
: "";
|
||||
},
|
||||
}
|
||||
);
|
||||
|
@@ -39,7 +39,6 @@ class HassLoadingScreen extends LitElement {
|
||||
</div>`}
|
||||
<div class="content">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -77,7 +76,6 @@ class HassLoadingScreen extends LitElement {
|
||||
.content {
|
||||
height: calc(100% - var(--header-height));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
@@ -3822,7 +3822,7 @@
|
||||
"faq_link": "[%key:ui::panel::my::faq_link%]",
|
||||
"error": "[%key:ui::panel::my::error%]",
|
||||
"error_addon_not_found": "Add-on not found",
|
||||
"error_addon_not_started": "The requested add-on are not running. Please start it first",
|
||||
"error_addon_not_started": "The requested add-on is not running. Please start it first",
|
||||
"error_addon_not_installed": "The requested add-on is not installed. Please install it first",
|
||||
"error_addon_no_ingress": "The requested add-on does not support ingress"
|
||||
},
|
||||
|
@@ -1138,6 +1138,7 @@
|
||||
},
|
||||
"zha_reconfigure_device": {
|
||||
"attribute": "Атрибут",
|
||||
"battery_device_warning": "Ще трябва да събудите устройствата, захранвани с батерии, преди да започнете процеса на преконфигуриране. Вижте ръководствата на вашите устройства за инструкции как да ги събудите.",
|
||||
"bind_header": "Обвързване",
|
||||
"button_hide": "Скрийте детайлите",
|
||||
"button_show": "Покажи детайли",
|
||||
@@ -1147,6 +1148,7 @@
|
||||
"configuring_alt": "Конфигуриране",
|
||||
"heading": "Преконфигуриране на устройство",
|
||||
"in_progress": "Устройството се преконфигурира. Това може да отнеме известно време.",
|
||||
"introduction": "Преконфигуриране на устройство във вашата Zigbee мрежа. Използвайте тази функция, ако устройството ви не функционира правилно.",
|
||||
"min_max_change": "мин/макс/промяна",
|
||||
"reporting_header": "Отчитане",
|
||||
"run_in_background": "Можете да затворите този диалогов прозорец и преконфигурирането ще продължи във фонов режим.",
|
||||
@@ -2658,6 +2660,7 @@
|
||||
"header": "Z-Wave конфигурация на устройството",
|
||||
"introduction": "Управление и настройване на специфични конфигурационни параметри на подбраното устройството (възел, node)",
|
||||
"parameter_is_read_only": "Този параметър е само за четене.",
|
||||
"set_param_accepted": "Параметърът е актуализиран.",
|
||||
"set_param_error": "Възникна грешка.",
|
||||
"zwave_js_device_database": "Z-Wave JS база данни с устройства"
|
||||
},
|
||||
|
Reference in New Issue
Block a user