mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-10 01:57:20 +00:00
Compare commits
1 Commits
floating-p
...
show-proto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30ae2a1053 |
@@ -101,10 +101,6 @@ const Component = Vue.extend({
|
||||
type: String,
|
||||
default: "en",
|
||||
},
|
||||
opensVertical: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
render(createElement) {
|
||||
// @ts-expect-error
|
||||
@@ -133,11 +129,6 @@ const Component = Vue.extend({
|
||||
},
|
||||
expression: "dateRange",
|
||||
},
|
||||
on: {
|
||||
toggle: (open: boolean) => {
|
||||
fireEvent(this.$el as HTMLElement, "toggle", { open });
|
||||
},
|
||||
},
|
||||
scopedSlots: {
|
||||
input() {
|
||||
return createElement("slot", {
|
||||
@@ -318,10 +309,6 @@ class DateRangePickerElement extends WrappedElement {
|
||||
min-width: unset !important;
|
||||
display: block !important;
|
||||
}
|
||||
:host([opens-vertical="up"]) .daterangepicker {
|
||||
bottom: 100%;
|
||||
top: auto !important;
|
||||
}
|
||||
`;
|
||||
if (mainWindow.document.dir === "rtl") {
|
||||
style.innerHTML += `
|
||||
@@ -353,7 +340,4 @@ declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"date-range-picker": DateRangePickerElement;
|
||||
}
|
||||
interface HASSDomEvents {
|
||||
toggle: { open: boolean };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +74,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
@property({ attribute: "extended-presets", type: Boolean })
|
||||
public extendedPresets = false;
|
||||
|
||||
@property({ attribute: "vertical-opening-direction" })
|
||||
public verticalOpeningDirection?: "up" | "down";
|
||||
|
||||
@property({ attribute: false }) public openingDirection?:
|
||||
| "right"
|
||||
| "left"
|
||||
@@ -130,7 +127,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
opening-direction=${ifDefined(
|
||||
this.openingDirection || this._calcedOpeningDirection
|
||||
)}
|
||||
opens-vertical=${ifDefined(this.verticalOpeningDirection)}
|
||||
first-day=${firstWeekdayIndex(this.hass.locale)}
|
||||
language=${this.hass.locale.language}
|
||||
@change=${this._handleChange}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { mdiDragHorizontalVariant, mdiTextureBox } from "@mdi/js";
|
||||
import { mdiClose, mdiDragHorizontalVariant, mdiTextureBox } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import {
|
||||
type AreasFloorHierarchy,
|
||||
@@ -11,10 +11,12 @@ import {
|
||||
} from "../../../common/areas/areas-floor-hierarchy";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dialog-footer";
|
||||
import "../../../components/ha-dialog-header";
|
||||
import "../../../components/ha-floor-icon";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-wa-dialog";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../components/ha-md-dialog";
|
||||
import "../../../components/ha-md-list";
|
||||
import "../../../components/ha-md-list-item";
|
||||
import "../../../components/ha-sortable";
|
||||
@@ -47,6 +49,8 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
|
||||
@state() private _saving = false;
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
public async showDialog(
|
||||
_params: AreasFloorsOrderDialogParams
|
||||
): Promise<void> {
|
||||
@@ -62,8 +66,7 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._saving = false;
|
||||
this._open = false;
|
||||
this._dialog?.close();
|
||||
}
|
||||
|
||||
private _dialogClosed(): void {
|
||||
@@ -74,7 +77,7 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._hierarchy) {
|
||||
if (!this._open || !this._hierarchy) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
@@ -86,13 +89,17 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
);
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${dialogTitle}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<div class="content">
|
||||
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
@click=${this.closeDialog}
|
||||
></ha-icon-button>
|
||||
<span slot="title" .title=${dialogTitle}>${dialogTitle}</span>
|
||||
</ha-dialog-header>
|
||||
<div slot="content" class="content">
|
||||
<ha-sortable
|
||||
handle-selector=".floor-handle"
|
||||
draggable-selector=".floor"
|
||||
@@ -109,23 +116,15 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
</ha-sortable>
|
||||
${this._renderUnassignedAreas()}
|
||||
</div>
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-button
|
||||
slot="secondaryAction"
|
||||
@click=${this.closeDialog}
|
||||
appearance="plain"
|
||||
>
|
||||
<div slot="actions">
|
||||
<ha-button @click=${this.closeDialog} appearance="plain">
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
@click=${this._save}
|
||||
.disabled=${this._saving}
|
||||
>
|
||||
<ha-button @click=${this._save} .disabled=${this._saving}>
|
||||
${this.hass.localize("ui.common.save")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-wa-dialog>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -392,13 +391,15 @@ class DialogAreasFloorsOrder extends LitElement {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-wa-dialog {
|
||||
ha-md-dialog {
|
||||
min-width: 600px;
|
||||
max-height: 90%;
|
||||
--dialog-content-padding: var(--ha-space-2) var(--ha-space-6);
|
||||
--dialog-content-padding: 8px 24px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 580px), all and (max-height: 500px) {
|
||||
ha-wa-dialog {
|
||||
@media all and (max-width: 600px), all and (max-height: 500px) {
|
||||
ha-md-dialog {
|
||||
--md-dialog-container-shape: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { mdiClose, mdiContentCopy, mdiDownload } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-dialog-footer";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-button-prev";
|
||||
import "../../../../components/ha-wa-dialog";
|
||||
import "../../../../components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||
import "../../../../components/ha-md-list";
|
||||
import "../../../../components/ha-md-list-item";
|
||||
import "../../../../components/ha-password-field";
|
||||
@@ -30,18 +31,20 @@ type Step = (typeof STEPS)[number];
|
||||
class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _open = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
@state() private _step?: Step;
|
||||
|
||||
@state() private _params?: ChangeBackupEncryptionKeyDialogParams;
|
||||
|
||||
@query("ha-md-dialog") private _dialog!: HaMdDialog;
|
||||
|
||||
@state() private _newEncryptionKey?: string;
|
||||
|
||||
public showDialog(params: ChangeBackupEncryptionKeyDialogParams): void {
|
||||
this._params = params;
|
||||
this._step = STEPS[0];
|
||||
this._open = true;
|
||||
this._opened = true;
|
||||
this._newEncryptionKey = generateEncryptionKey();
|
||||
}
|
||||
|
||||
@@ -49,10 +52,10 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
if (this._params!.cancel) {
|
||||
this._params!.cancel();
|
||||
}
|
||||
if (this._open) {
|
||||
if (this._opened) {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
this._open = false;
|
||||
this._opened = false;
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
this._newEncryptionKey = undefined;
|
||||
@@ -61,7 +64,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
|
||||
private _done() {
|
||||
this._params?.submit!(true);
|
||||
this.closeDialog();
|
||||
this._dialog.close();
|
||||
}
|
||||
|
||||
private _previousStep() {
|
||||
@@ -81,6 +84,10 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._opened || !this._params) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const dialogTitle =
|
||||
this._step === "current" || this._step === "new"
|
||||
? this.hass.localize(
|
||||
@@ -89,40 +96,36 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
: "";
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${dialogTitle}
|
||||
prevent-scrim-close
|
||||
@closed=${this.closeDialog}
|
||||
>
|
||||
${this._step === "new"
|
||||
? html`
|
||||
<ha-icon-button-prev
|
||||
slot="headerNavigationIcon"
|
||||
@click=${this._previousStep}
|
||||
></ha-icon-button-prev>
|
||||
`
|
||||
: html`
|
||||
<ha-icon-button
|
||||
slot="headerNavigationIcon"
|
||||
data-dialog="close"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
`}
|
||||
${this._renderStepContent()}
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-md-dialog disable-cancel-action open @closed=${this.closeDialog}>
|
||||
<ha-dialog-header slot="headline">
|
||||
${this._step === "new"
|
||||
? html`
|
||||
<ha-icon-button-prev
|
||||
slot="navigationIcon"
|
||||
@click=${this._previousStep}
|
||||
></ha-icon-button-prev>
|
||||
`
|
||||
: html`
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
@click=${this.closeDialog}
|
||||
></ha-icon-button>
|
||||
`}
|
||||
<span slot="title">${dialogTitle}</span>
|
||||
</ha-dialog-header>
|
||||
<div slot="content">${this._renderStepContent()}</div>
|
||||
<div slot="actions">
|
||||
${this._step === "current"
|
||||
? html`
|
||||
<ha-button slot="primaryAction" @click=${this._nextStep}>
|
||||
<ha-button @click=${this._nextStep}>
|
||||
${this.hass.localize("ui.common.next")}
|
||||
</ha-button>
|
||||
`
|
||||
: this._step === "new"
|
||||
? html`
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
@click=${this._submit}
|
||||
.disabled=${!this._newEncryptionKey}
|
||||
variant="danger"
|
||||
@@ -133,14 +136,14 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
</ha-button>
|
||||
`
|
||||
: html`
|
||||
<ha-button slot="primaryAction" @click=${this._done}>
|
||||
<ha-button @click=${this._done}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.change_encryption_key.actions.done"
|
||||
)}
|
||||
</ha-button>
|
||||
`}
|
||||
</ha-dialog-footer>
|
||||
</ha-wa-dialog>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -284,8 +287,10 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-wa-dialog {
|
||||
--dialog-content-padding: var(--ha-space-2) var(--ha-space-6);
|
||||
ha-md-dialog {
|
||||
width: 90vw;
|
||||
max-width: 560px;
|
||||
--dialog-content-padding: 8px 24px;
|
||||
}
|
||||
ha-md-list {
|
||||
background: none;
|
||||
@@ -316,7 +321,14 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
flex: none;
|
||||
margin: -16px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-md-dialog {
|
||||
max-width: none;
|
||||
}
|
||||
div[slot="content"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-dialog-footer";
|
||||
import "../../../../components/ha-wa-dialog";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-next";
|
||||
import "../../../../components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||
import "../../../../components/ha-md-list";
|
||||
import "../../../../components/ha-md-list-item";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import "../../../../components/ha-password-field";
|
||||
import "../../../../components/ha-alert";
|
||||
import {
|
||||
canDecryptBackupOnDownload,
|
||||
getPreferredAgentForDownload,
|
||||
@@ -21,96 +27,102 @@ import type { DownloadDecryptedBackupDialogParams } from "./show-dialog-download
|
||||
class DialogDownloadDecryptedBackup extends LitElement implements HassDialog {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _open = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
@state() private _params?: DownloadDecryptedBackupDialogParams;
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
@state() private _encryptionKey = "";
|
||||
|
||||
@state() private _error = "";
|
||||
|
||||
public showDialog(params: DownloadDecryptedBackupDialogParams): void {
|
||||
this._open = true;
|
||||
this._opened = true;
|
||||
this._params = params;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._open = false;
|
||||
this._dialog?.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
private _dialogClosed() {
|
||||
if (this._open) {
|
||||
if (this._opened) {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
this._open = false;
|
||||
this._opened = false;
|
||||
this._params = undefined;
|
||||
this._encryptionKey = "";
|
||||
this._error = "";
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._params) {
|
||||
if (!this._opened || !this._params) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.title"
|
||||
)}
|
||||
prevent-scrim-close
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.description"
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.download_backup_encrypted",
|
||||
{
|
||||
download_it_encrypted: html`<button
|
||||
class="link"
|
||||
@click=${this._downloadEncrypted}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.download_it_encrypted"
|
||||
)}
|
||||
</button>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
<ha-md-dialog open @closed=${this._dialogClosed} disable-cancel-action>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
@click=${this.closeDialog}
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.title"
|
||||
)}
|
||||
</span>
|
||||
</ha-dialog-header>
|
||||
|
||||
<ha-password-field
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.encryption_key"
|
||||
)}
|
||||
@input=${this._keyChanged}
|
||||
></ha-password-field>
|
||||
<div slot="content">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.description"
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.download_backup_encrypted",
|
||||
{
|
||||
download_it_encrypted: html`<button
|
||||
class="link"
|
||||
@click=${this._downloadEncrypted}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.download_it_encrypted"
|
||||
)}
|
||||
</button>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: nothing}
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-button
|
||||
slot="secondaryAction"
|
||||
appearance="plain"
|
||||
@click=${this._cancel}
|
||||
>
|
||||
<ha-password-field
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.encryption_key"
|
||||
)}
|
||||
@input=${this._keyChanged}
|
||||
></ha-password-field>
|
||||
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: nothing}
|
||||
</div>
|
||||
<div slot="actions">
|
||||
<ha-button appearance="plain" @click=${this._cancel}>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
|
||||
<ha-button slot="primaryAction" @click=${this._submit}>
|
||||
<ha-button @click=${this._submit}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.download.download"
|
||||
)}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-wa-dialog>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -179,8 +191,17 @@ class DialogDownloadDecryptedBackup extends LitElement implements HassDialog {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-wa-dialog {
|
||||
--dialog-content-padding: var(--ha-space-2) var(--ha-space-6);
|
||||
ha-md-dialog {
|
||||
--dialog-content-padding: 8px 24px;
|
||||
max-width: 500px;
|
||||
}
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-md-dialog {
|
||||
max-width: none;
|
||||
}
|
||||
div[slot="content"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
button.link {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { mdiClose, mdiContentCopy, mdiDownload } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-dialog-footer";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-button-prev";
|
||||
import "../../../../components/ha-wa-dialog";
|
||||
import "../../../../components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||
import "../../../../components/ha-md-list";
|
||||
import "../../../../components/ha-md-list-item";
|
||||
import "../../../../components/ha-password-field";
|
||||
@@ -23,83 +24,89 @@ import type { ShowBackupEncryptionKeyDialogParams } from "./show-dialog-show-bac
|
||||
class DialogShowBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _open = false;
|
||||
|
||||
@state() private _params?: ShowBackupEncryptionKeyDialogParams;
|
||||
|
||||
@query("ha-md-dialog") private _dialog!: HaMdDialog;
|
||||
|
||||
public showDialog(params: ShowBackupEncryptionKeyDialogParams): void {
|
||||
this._params = params;
|
||||
this._open = true;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
if (this._open) {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
this._open = false;
|
||||
this._params = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
return true;
|
||||
}
|
||||
|
||||
private _closeDialog() {
|
||||
this._dialog.close();
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._params) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.show_encryption_key.title"
|
||||
)}
|
||||
prevent-scrim-close
|
||||
@closed=${this.closeDialog}
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="headerNavigationIcon"
|
||||
data-dialog="close"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.show_encryption_key.description"
|
||||
)}
|
||||
</p>
|
||||
<div class="encryption-key">
|
||||
<p>${this._params?.currentKey}</p>
|
||||
<ha-md-dialog disable-cancel-action open @closed=${this.closeDialog}>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
.path=${mdiContentCopy}
|
||||
@click=${this._copyKeyToClipboard}
|
||||
slot="navigationIcon"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
@click=${this._closeDialog}
|
||||
></ha-icon-button>
|
||||
<span slot="title">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.show_encryption_key.title"
|
||||
)}
|
||||
</span>
|
||||
</ha-dialog-header>
|
||||
<div slot="content">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.dialogs.show_encryption_key.description"
|
||||
)}
|
||||
</p>
|
||||
<div class="encryption-key">
|
||||
<p>${this._params?.currentKey}</p>
|
||||
<ha-icon-button
|
||||
.path=${mdiContentCopy}
|
||||
@click=${this._copyKeyToClipboard}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit"
|
||||
)}
|
||||
</span>
|
||||
<span slot="supporting-text">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit_description"
|
||||
)}
|
||||
</span>
|
||||
<ha-button
|
||||
size="small"
|
||||
appearance="plain"
|
||||
slot="end"
|
||||
@click=${this._download}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit_action"
|
||||
)}
|
||||
</ha-button>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
</div>
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit"
|
||||
)}
|
||||
</span>
|
||||
<span slot="supporting-text">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit_description"
|
||||
)}
|
||||
</span>
|
||||
<ha-button slot="end" @click=${this._download}>
|
||||
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.encryption_key.download_emergency_kit_action"
|
||||
)}
|
||||
</ha-button>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
<div slot="actions">
|
||||
<ha-button @click=${this._closeDialog}>
|
||||
${this.hass.localize("ui.common.close")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-wa-dialog>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -128,8 +135,10 @@ class DialogShowBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-wa-dialog {
|
||||
--dialog-content-padding: var(--ha-space-2) var(--ha-space-6);
|
||||
ha-md-dialog {
|
||||
width: 90vw;
|
||||
max-width: 560px;
|
||||
--dialog-content-padding: 8px 24px;
|
||||
}
|
||||
ha-md-list {
|
||||
background: none;
|
||||
@@ -160,7 +169,14 @@ class DialogShowBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
flex: none;
|
||||
margin: -16px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-md-dialog {
|
||||
max-width: none;
|
||||
}
|
||||
div[slot="content"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import {
|
||||
} from "../../../dialogs/quick-bar/show-dialog-quick-bar";
|
||||
import { showRestartDialog } from "../../../dialogs/restart/show-dialog-restart";
|
||||
import { showShortcutsDialog } from "../../../dialogs/shortcuts/show-shortcuts-dialog";
|
||||
import type { PageNavigation } from "../../../layouts/hass-tabs-subpage";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
@@ -164,21 +163,24 @@ class HaConfigDashboard extends SubscribeMixin(LitElement) {
|
||||
total: 0,
|
||||
};
|
||||
|
||||
private _pages = memoizeOne((cloudStatus, isCloudLoaded) => {
|
||||
const pages: PageNavigation[] = [];
|
||||
if (isCloudLoaded) {
|
||||
pages.push({
|
||||
component: "cloud",
|
||||
path: "/config/cloud",
|
||||
name: "Home Assistant Cloud",
|
||||
info: cloudStatus,
|
||||
iconPath: mdiCloudLock,
|
||||
iconColor: "#3B808E",
|
||||
translationKey: "cloud",
|
||||
});
|
||||
}
|
||||
return [...pages, ...configSections.dashboard];
|
||||
});
|
||||
private _pages = memoizeOne((cloudStatus, isCloudLoaded) => [
|
||||
isCloudLoaded
|
||||
? [
|
||||
{
|
||||
component: "cloud",
|
||||
path: "/config/cloud",
|
||||
name: "Home Assistant Cloud",
|
||||
info: cloudStatus,
|
||||
iconPath: mdiCloudLock,
|
||||
iconColor: "#3B808E",
|
||||
translationKey: "cloud",
|
||||
},
|
||||
...configSections.dashboard,
|
||||
]
|
||||
: configSections.dashboard,
|
||||
configSections.dashboard_2,
|
||||
configSections.dashboard_3,
|
||||
]);
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
@@ -308,18 +310,21 @@ class HaConfigDashboard extends SubscribeMixin(LitElement) {
|
||||
: ""}
|
||||
</ha-card>`
|
||||
: ""}
|
||||
|
||||
<ha-card outlined>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${this._pages(
|
||||
this.cloudStatus,
|
||||
isComponentLoaded(this.hass, "cloud")
|
||||
)}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
${this._pages(
|
||||
this.cloudStatus,
|
||||
isComponentLoaded(this.hass, "cloud")
|
||||
).map(
|
||||
(categoryPages) => html`
|
||||
<ha-card outlined>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${categoryPages}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
<ha-tip .hass=${this.hass}>${this._tip}</ha-tip>
|
||||
</ha-config-section>
|
||||
</ha-top-app-bar-fixed>
|
||||
|
||||
@@ -3,14 +3,17 @@ import {
|
||||
mdiAccount,
|
||||
mdiBackupRestore,
|
||||
mdiBadgeAccountHorizontal,
|
||||
mdiBluetooth,
|
||||
mdiCellphoneCog,
|
||||
mdiCog,
|
||||
mdiDatabase,
|
||||
mdiDevices,
|
||||
mdiFlask,
|
||||
mdiHub,
|
||||
mdiInformation,
|
||||
mdiInformationOutline,
|
||||
mdiLabel,
|
||||
mdiLan,
|
||||
mdiLightningBolt,
|
||||
mdiMapMarkerRadius,
|
||||
mdiMathLog,
|
||||
@@ -20,15 +23,19 @@ import {
|
||||
mdiNfcVariant,
|
||||
mdiPalette,
|
||||
mdiPaletteSwatch,
|
||||
mdiProtocol,
|
||||
mdiPuzzle,
|
||||
mdiRobot,
|
||||
mdiScrewdriver,
|
||||
mdiScriptText,
|
||||
mdiShape,
|
||||
mdiSofa,
|
||||
mdiStore,
|
||||
mdiTools,
|
||||
mdiUpdate,
|
||||
mdiViewDashboard,
|
||||
mdiZigbee,
|
||||
mdiZWave,
|
||||
} from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { PropertyValues } from "lit";
|
||||
@@ -101,6 +108,72 @@ export const configSections: Record<string, PageNavigation[]> = {
|
||||
iconPath: mdiMicrophone,
|
||||
iconColor: "#3263C3",
|
||||
},
|
||||
],
|
||||
dashboard_2: [
|
||||
{
|
||||
path: "/config/zwave_js",
|
||||
name: "Z-Wave",
|
||||
iconPath: mdiZWave,
|
||||
iconColor: "#153163",
|
||||
component: "zwave_js",
|
||||
translationKey: "zwave_js",
|
||||
},
|
||||
{
|
||||
path: "/config/zha",
|
||||
name: "Zigbee",
|
||||
iconPath: mdiZigbee,
|
||||
iconColor: "#E74011",
|
||||
component: "zha",
|
||||
translationKey: "zha",
|
||||
},
|
||||
{
|
||||
path: "/config/matter",
|
||||
name: "Matter",
|
||||
iconPath: mdiHub,
|
||||
iconColor: "#2458B3",
|
||||
component: "matter",
|
||||
translationKey: "matter",
|
||||
},
|
||||
{
|
||||
path: "/config/thread",
|
||||
name: "Thread",
|
||||
iconPath: mdiProtocol,
|
||||
iconColor: "#ED7744",
|
||||
component: "thread",
|
||||
translationKey: "thread",
|
||||
},
|
||||
{
|
||||
path: "/config/bluetooth",
|
||||
name: "Bluetooth",
|
||||
iconPath: mdiBluetooth,
|
||||
iconColor: "#0082FC",
|
||||
component: "bluetooth",
|
||||
translationKey: "bluetooth",
|
||||
},
|
||||
{
|
||||
path: "/knx",
|
||||
name: "KNX",
|
||||
iconPath: mdiLan,
|
||||
iconColor: "#4EAA66",
|
||||
component: "knx",
|
||||
translationKey: "knx",
|
||||
},
|
||||
{
|
||||
path: "/insteon",
|
||||
name: "Insteon",
|
||||
iconPath: mdiLan,
|
||||
iconColor: "#E4002C",
|
||||
component: "insteon",
|
||||
translationKey: "insteon",
|
||||
},
|
||||
{
|
||||
path: "/hacs",
|
||||
name: "Home Assistant Community Store",
|
||||
iconPath: mdiStore,
|
||||
iconColor: "#41BDF5",
|
||||
component: "hacs",
|
||||
translationKey: "hacs",
|
||||
},
|
||||
{
|
||||
path: "/config/tags",
|
||||
translationKey: "tags",
|
||||
@@ -108,6 +181,8 @@ export const configSections: Record<string, PageNavigation[]> = {
|
||||
iconColor: "#616161",
|
||||
component: "tag",
|
||||
},
|
||||
],
|
||||
dashboard_3: [
|
||||
{
|
||||
path: "/config/person",
|
||||
translationKey: "people",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dialog-footer";
|
||||
import "../../../components/ha-wa-dialog";
|
||||
import type { HaMdDialog } from "../../../components/ha-md-dialog";
|
||||
import "../../../components/ha-md-dialog";
|
||||
import "../../../components/ha-md-list";
|
||||
import "../../../components/ha-md-list-item";
|
||||
import type { HaSwitch } from "../../../components/ha-switch";
|
||||
@@ -30,14 +30,13 @@ export class DialogLabsPreviewFeatureEnable
|
||||
|
||||
@state() private _createBackup = false;
|
||||
|
||||
@state() private _open = false;
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
public async showDialog(
|
||||
params: LabsPreviewFeatureEnableDialogParams
|
||||
): Promise<void> {
|
||||
this._params = params;
|
||||
this._createBackup = false;
|
||||
this._open = true;
|
||||
this._fetchBackupConfig();
|
||||
if (isComponentLoaded(this.hass, "hassio")) {
|
||||
this._fetchUpdateBackupConfig();
|
||||
@@ -45,7 +44,7 @@ export class DialogLabsPreviewFeatureEnable
|
||||
}
|
||||
|
||||
public closeDialog(): boolean {
|
||||
this._open = false;
|
||||
this._dialog?.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -144,69 +143,72 @@ export class DialogLabsPreviewFeatureEnable
|
||||
const createBackupTexts = this._computeCreateBackupTexts();
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize("ui.panel.config.labs.enable_title")}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
`component.${this._params.preview_feature.domain}.preview_features.${this._params.preview_feature.preview_feature}.enable_confirmation`
|
||||
) || this.hass.localize("ui.panel.config.labs.enable_confirmation")}
|
||||
</p>
|
||||
${createBackupTexts
|
||||
? html`
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">${createBackupTexts.title}</span>
|
||||
${createBackupTexts.description
|
||||
? html`
|
||||
<span slot="supporting-text">
|
||||
${createBackupTexts.description}
|
||||
</span>
|
||||
`
|
||||
: nothing}
|
||||
<ha-switch
|
||||
slot="end"
|
||||
.checked=${this._createBackup}
|
||||
@change=${this._createBackupChanged}
|
||||
></ha-switch>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
`
|
||||
: nothing}
|
||||
<ha-dialog-footer slot="footer">
|
||||
<ha-button
|
||||
slot="secondaryAction"
|
||||
appearance="plain"
|
||||
@click=${this._handleCancel}
|
||||
>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
appearance="filled"
|
||||
variant="brand"
|
||||
@click=${this._handleConfirm}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.labs.enable")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-wa-dialog>
|
||||
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||
<span slot="headline">
|
||||
${this.hass.localize("ui.panel.config.labs.enable_title")}
|
||||
</span>
|
||||
<div slot="content">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
`component.${this._params.preview_feature.domain}.preview_features.${this._params.preview_feature.preview_feature}.enable_confirmation`
|
||||
) || this.hass.localize("ui.panel.config.labs.enable_confirmation")}
|
||||
</p>
|
||||
</div>
|
||||
<div slot="actions">
|
||||
${createBackupTexts
|
||||
? html`
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">${createBackupTexts.title}</span>
|
||||
${createBackupTexts.description
|
||||
? html`
|
||||
<span slot="supporting-text">
|
||||
${createBackupTexts.description}
|
||||
</span>
|
||||
`
|
||||
: nothing}
|
||||
<ha-switch
|
||||
slot="end"
|
||||
.checked=${this._createBackup}
|
||||
@change=${this._createBackupChanged}
|
||||
></ha-switch>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
`
|
||||
: nothing}
|
||||
<div>
|
||||
<ha-button appearance="plain" @click=${this._handleCancel}>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
appearance="filled"
|
||||
variant="brand"
|
||||
@click=${this._handleConfirm}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.labs.enable")}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static readonly styles = css`
|
||||
ha-wa-dialog {
|
||||
--dialog-content-padding: var(--ha-space-0);
|
||||
ha-md-dialog {
|
||||
--dialog-content-padding: var(--ha-space-6);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 var(--ha-space-6) var(--ha-space-6);
|
||||
margin: 0;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
div[slot="actions"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ha-md-list {
|
||||
background: none;
|
||||
--md-list-item-leading-space: var(--ha-space-6);
|
||||
@@ -215,6 +217,13 @@ export class DialogLabsPreviewFeatureEnable
|
||||
padding: 0;
|
||||
border-top: var(--ha-border-width-sm) solid var(--divider-color);
|
||||
}
|
||||
|
||||
div[slot="actions"] > div {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: var(--ha-space-2);
|
||||
padding: var(--ha-space-4) var(--ha-space-6);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-wa-dialog";
|
||||
import "../../../components/ha-md-dialog";
|
||||
import "../../../components/ha-spinner";
|
||||
import type { HassDialog } from "../../../dialogs/make-dialog-manager";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
@@ -39,36 +39,36 @@ export class DialogLabsProgress
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
<ha-md-dialog
|
||||
.open=${this._open}
|
||||
prevent-scrim-close
|
||||
disable-cancel-action
|
||||
@closed=${this._handleClosed}
|
||||
>
|
||||
<div slot="header"></div>
|
||||
<div class="summary">
|
||||
<ha-spinner></ha-spinner>
|
||||
<div class="content">
|
||||
<p class="heading">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.labs.progress.creating_backup"
|
||||
)}
|
||||
</p>
|
||||
<p class="description">
|
||||
${this.hass.localize(
|
||||
this._params.enabled
|
||||
? "ui.panel.config.labs.progress.backing_up_before_enabling"
|
||||
: "ui.panel.config.labs.progress.backing_up_before_disabling"
|
||||
)}
|
||||
</p>
|
||||
<div slot="content">
|
||||
<div class="summary">
|
||||
<ha-spinner></ha-spinner>
|
||||
<div class="content">
|
||||
<p class="heading">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.labs.progress.creating_backup"
|
||||
)}
|
||||
</p>
|
||||
<p class="description">
|
||||
${this.hass.localize(
|
||||
this._params.enabled
|
||||
? "ui.panel.config.labs.progress.backing_up_before_enabling"
|
||||
: "ui.panel.config.labs.progress.backing_up_before_disabling"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ha-wa-dialog>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static readonly styles = css`
|
||||
ha-wa-dialog {
|
||||
ha-md-dialog {
|
||||
--dialog-content-padding: var(--ha-space-6);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,7 @@ import {
|
||||
getSummedData,
|
||||
} from "../../data/energy";
|
||||
import type { LovelaceConfig } from "../../data/lovelace/config/types";
|
||||
import {
|
||||
isStrategyView,
|
||||
type LovelaceViewConfig,
|
||||
} from "../../data/lovelace/config/view";
|
||||
import type { LovelaceViewConfig } from "../../data/lovelace/config/view";
|
||||
import type { StatisticValue } from "../../data/recorder";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import type { HomeAssistant, PanelInfo } from "../../types";
|
||||
@@ -51,7 +48,6 @@ const OVERVIEW_VIEW = {
|
||||
strategy: {
|
||||
type: "energy-overview",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
show_period_selector: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
@@ -60,7 +56,6 @@ const ENERGY_VIEW = {
|
||||
strategy: {
|
||||
type: "energy",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
show_period_selector: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
@@ -69,7 +64,6 @@ const WATER_VIEW = {
|
||||
strategy: {
|
||||
type: "water",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
show_period_selector: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
@@ -78,7 +72,6 @@ const GAS_VIEW = {
|
||||
strategy: {
|
||||
type: "gas",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
show_period_selector: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
@@ -230,11 +223,6 @@ class PanelEnergy extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const routePath = this.route?.path?.split("/")[1] || "";
|
||||
const currentView = this._lovelace.config.views.find(
|
||||
(view) => view.path === routePath
|
||||
);
|
||||
|
||||
return html`
|
||||
<hui-root
|
||||
.hass=${this.hass}
|
||||
@@ -245,17 +233,6 @@ class PanelEnergy extends LitElement {
|
||||
.extraActionItems=${this._extraActionItems}
|
||||
@reload-energy-panel=${this._reloadConfig}
|
||||
></hui-root>
|
||||
${currentView &&
|
||||
isStrategyView(currentView) &&
|
||||
currentView.strategy?.show_period_selector
|
||||
? html`<ha-card raised class="period-selector">
|
||||
<hui-energy-period-selector
|
||||
.hass=${this.hass}
|
||||
.collectionKey=${DEFAULT_ENERGY_COLLECTION_KEY}
|
||||
vertical-opening-direction="up"
|
||||
></hui-energy-period-selector>
|
||||
</ha-card>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -654,8 +631,23 @@ class PanelEnergy extends LitElement {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
:host:has([datepicker-open]) hui-root {
|
||||
filter: blur(4px);
|
||||
.toolbar {
|
||||
height: var(--header-height);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
font-size: var(--ha-font-size-xl);
|
||||
padding: 0px 12px;
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host([narrow]) .toolbar {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.main-title {
|
||||
margin: var(--margin-title);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
flex-grow: 1;
|
||||
}
|
||||
.centered {
|
||||
width: 100%;
|
||||
@@ -664,12 +656,6 @@ class PanelEnergy extends LitElement {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.period-selector {
|
||||
position: sticky;
|
||||
bottom: var(--ha-space-2);
|
||||
margin: 0 auto;
|
||||
max-width: calc(min(450px, 100% - var(--ha-space-4)));
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getEnergyDataCollection } from "../../../data/energy";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
||||
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
|
||||
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||
import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
|
||||
|
||||
@customElement("energy-overview-view-strategy")
|
||||
@@ -63,20 +64,24 @@ export class EnergyOverviewViewStrategy extends ReactiveElement {
|
||||
(source.type === "grid" && source.power?.length)
|
||||
);
|
||||
|
||||
const overviewSection: LovelaceSectionConfig = {
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
allow_compare: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
if (hasGrid || hasBattery || hasSolar) {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_distribution_title"
|
||||
),
|
||||
type: "energy-distribution",
|
||||
collection_key: collectionKey,
|
||||
},
|
||||
],
|
||||
overviewSection.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_distribution_title"),
|
||||
type: "energy-distribution",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
}
|
||||
view.sections!.push(overviewSection);
|
||||
|
||||
if (prefs.energy_sources.length) {
|
||||
view.sections!.push({
|
||||
|
||||
@@ -53,6 +53,10 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
(d) => d.included_in_stat
|
||||
);
|
||||
|
||||
view.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
view.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: "energy_dashboard",
|
||||
|
||||
@@ -40,6 +40,10 @@ export class GasViewStrategy extends ReactiveElement {
|
||||
|
||||
const section = view.sections![0] as LovelaceSectionConfig;
|
||||
|
||||
section.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
section.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: collectionKey,
|
||||
|
||||
@@ -41,6 +41,10 @@ export class WaterViewStrategy extends ReactiveElement {
|
||||
|
||||
const section = view.sections![0] as LovelaceSectionConfig;
|
||||
|
||||
section.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
section.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: collectionKey,
|
||||
|
||||
@@ -69,12 +69,6 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
|
||||
@property({ type: Boolean, attribute: "allow-compare" }) public allowCompare =
|
||||
true;
|
||||
|
||||
@property({ attribute: "vertical-opening-direction" })
|
||||
public verticalOpeningDirection?: "up" | "down";
|
||||
|
||||
@property({ type: Boolean, reflect: true, attribute: "datepicker-open" })
|
||||
public datepickerOpen = false;
|
||||
|
||||
@state() _startDate?: Date;
|
||||
|
||||
@state() _endDate?: Date;
|
||||
@@ -208,10 +202,8 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
|
||||
.ranges=${this._ranges}
|
||||
@value-changed=${this._dateRangeChanged}
|
||||
@preset-selected=${this._presetSelected}
|
||||
@toggle=${this._handleDatepickerToggle}
|
||||
minimal
|
||||
header-position
|
||||
.verticalOpeningDirection=${this.verticalOpeningDirection}
|
||||
></ha-date-range-picker>
|
||||
</div>
|
||||
|
||||
@@ -454,10 +446,6 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
|
||||
this._endDate = energyData.end || endOfToday();
|
||||
}
|
||||
|
||||
private _handleDatepickerToggle(ev: CustomEvent<{ open: boolean }>) {
|
||||
this.datepickerOpen = ev.detail.open;
|
||||
}
|
||||
|
||||
private _toggleCompare(ev: CustomEvent<RequestSelectedDetail>) {
|
||||
if (ev.detail.source !== "interaction") {
|
||||
return;
|
||||
|
||||
@@ -2308,6 +2308,30 @@
|
||||
},
|
||||
"cloud": {
|
||||
"secondary": "Loading..."
|
||||
},
|
||||
"zwave_js": {
|
||||
"secondary": "Manage your Z-Wave network"
|
||||
},
|
||||
"zha": {
|
||||
"secondary": "Manage your Zigbee network"
|
||||
},
|
||||
"matter": {
|
||||
"secondary": "Manage your Matter network"
|
||||
},
|
||||
"thread": {
|
||||
"secondary": "Manage your Thread network"
|
||||
},
|
||||
"bluetooth": {
|
||||
"secondary": "Manage your Bluetooth devices"
|
||||
},
|
||||
"knx": {
|
||||
"secondary": "Manage your KNX network"
|
||||
},
|
||||
"insteon": {
|
||||
"secondary": "Manage your Insteon network"
|
||||
},
|
||||
"hacs": {
|
||||
"secondary": "Manage community integrations and frontend modules"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
|
||||
Reference in New Issue
Block a user