mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-30 06:23:04 +00:00
Compare commits
5 Commits
code-edito
...
dashboard-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fe8153bcb | ||
|
|
b515c75957 | ||
|
|
4cb4597e24 | ||
|
|
d3e83db984 | ||
|
|
bd0676ccda |
@@ -2,12 +2,15 @@ import type { Connection } from "home-assistant-js-websocket";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { LovelaceResource } from "../resource";
|
||||
import type { LovelaceStrategyConfig } from "./strategy";
|
||||
import type { LovelaceViewRawConfig } from "./view";
|
||||
import type {
|
||||
LovelaceDashboardBackgroundConfig,
|
||||
LovelaceViewRawConfig,
|
||||
} from "./view";
|
||||
|
||||
export interface LovelaceDashboardBaseConfig {}
|
||||
|
||||
export interface LovelaceConfig extends LovelaceDashboardBaseConfig {
|
||||
background?: string;
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
views: LovelaceViewRawConfig[];
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ export interface LovelaceViewBackgroundConfig {
|
||||
attachment?: "scroll" | "fixed";
|
||||
}
|
||||
|
||||
export type LovelaceDashboardBackgroundConfig =
|
||||
| string
|
||||
| LovelaceViewBackgroundConfig;
|
||||
|
||||
export interface LovelaceViewHeaderConfig {
|
||||
card?: LovelaceCardConfig;
|
||||
layout?: "start" | "center" | "responsive";
|
||||
@@ -60,7 +64,7 @@ export interface LovelaceBaseViewConfig {
|
||||
show_icon_and_title?: boolean;
|
||||
theme?: string;
|
||||
panel?: boolean;
|
||||
background?: string | LovelaceViewBackgroundConfig;
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
visible?: boolean | ShowViewConfig[];
|
||||
subview?: boolean;
|
||||
back_path?: string;
|
||||
|
||||
@@ -1,24 +1,35 @@
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import {
|
||||
fireEvent,
|
||||
type HASSDomEvent,
|
||||
} from "../../../../common/dom/fire_event";
|
||||
import { slugify } from "../../../../common/string/slugify";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-dialog-footer";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-tab-group";
|
||||
import "../../../../components/ha-tab-group-tab";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type {
|
||||
LovelaceDashboard,
|
||||
LovelaceDashboardCreateParams,
|
||||
LovelaceDashboardMutableParams,
|
||||
} from "../../../../data/lovelace/dashboard";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import type { LovelaceDashboard } from "../../../../data/lovelace/dashboard";
|
||||
import {
|
||||
haStyleDialog,
|
||||
haStyleDialogFixedTop,
|
||||
} from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import "../../../lovelace/editor/view-editor/hui-view-background-editor";
|
||||
import type { LovelaceDashboardDetailsDialogParams } from "./show-dialog-lovelace-dashboard-detail";
|
||||
import { pickAvailableDashboardUrlPath } from "./pick-available-dashboard-url-path";
|
||||
|
||||
const TABS = ["tab-settings", "tab-background"] as const;
|
||||
|
||||
@customElement("dialog-lovelace-dashboard-detail")
|
||||
export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@@ -35,35 +46,41 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
|
||||
@state() private _submitting = false;
|
||||
|
||||
public showDialog(params: LovelaceDashboardDetailsDialogParams): void {
|
||||
@state() private _currTab: (typeof TABS)[number] = TABS[0];
|
||||
|
||||
@state() private _backgroundConfig?: LovelaceConfig;
|
||||
|
||||
public showDialog(params: LovelaceDashboardDetailsDialogParams) {
|
||||
this._params = params;
|
||||
this._error = undefined;
|
||||
this._urlPathChanged = false;
|
||||
this._currTab = TABS[0];
|
||||
this._backgroundConfig = params.lovelaceConfig;
|
||||
this._open = true;
|
||||
if (this._params.dashboard) {
|
||||
this._data = this._params.dashboard;
|
||||
} else {
|
||||
const suggestions = this._params.suggestions;
|
||||
this._data = {
|
||||
show_in_sidebar: true,
|
||||
icon: suggestions?.icon,
|
||||
title: suggestions?.title ?? "",
|
||||
icon: this._params.suggestions?.icon,
|
||||
title: this._params.suggestions?.title ?? "",
|
||||
require_admin: false,
|
||||
mode: "storage",
|
||||
};
|
||||
if (suggestions?.title) {
|
||||
this._fillUrlPath(suggestions.title);
|
||||
if (this._params.suggestions?.title) {
|
||||
this._fillUrlPath(this._params.suggestions.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
public closeDialog() {
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private _dialogClosed(): void {
|
||||
private _dialogClosed() {
|
||||
this._params = undefined;
|
||||
this._data = undefined;
|
||||
this._backgroundConfig = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
@@ -73,6 +90,18 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
|
||||
const titleInvalid = !this._data.title || !this._data.title.trim();
|
||||
const dialogTitle = this._params.urlPath
|
||||
? this._data.title ||
|
||||
this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.edit_dashboard"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.new_dashboard"
|
||||
);
|
||||
const showBackgroundTab =
|
||||
this._params.dashboard?.mode !== "yaml" &&
|
||||
Boolean(this._params.lovelaceConfig) &&
|
||||
Boolean(this._params.saveConfig);
|
||||
|
||||
const cancelButton = html`
|
||||
<ha-button
|
||||
@@ -88,37 +117,41 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
<ha-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${this._params.urlPath
|
||||
? this._data.title ||
|
||||
this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.edit_dashboard"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.new_dashboard"
|
||||
)}
|
||||
header-title=${showBackgroundTab ? nothing : dialogTitle}
|
||||
width=${showBackgroundTab ? "large" : "medium"}
|
||||
prevent-scrim-close
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<div>
|
||||
${this._params.dashboard?.mode === "yaml"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.cant_edit_yaml"
|
||||
)
|
||||
: html`
|
||||
<ha-form
|
||||
autofocus
|
||||
.schema=${this._schema(
|
||||
this._params,
|
||||
this._data?.require_admin
|
||||
${showBackgroundTab
|
||||
? html`
|
||||
<ha-dialog-header show-border slot="header">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
@click=${this.closeDialog}
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<h2 slot="title">${dialogTitle}</h2>
|
||||
<ha-tab-group @wa-tab-show=${this._handleTabChanged}>
|
||||
${TABS.map(
|
||||
(tab) => html`
|
||||
<ha-tab-group-tab
|
||||
slot="nav"
|
||||
.panel=${tab}
|
||||
.active=${this._currTab === tab}
|
||||
>
|
||||
${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_view.${tab.replace("-", "_")}`
|
||||
)}
|
||||
</ha-tab-group-tab>
|
||||
`
|
||||
)}
|
||||
.data=${this._data}
|
||||
.hass=${this.hass}
|
||||
.error=${this._error}
|
||||
.computeLabel=${this._computeLabel}
|
||||
.computeHelper=${this._computeHelper}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`}
|
||||
</ha-tab-group>
|
||||
</ha-dialog-header>
|
||||
`
|
||||
: nothing}
|
||||
<div>
|
||||
${this._renderContent(this._params, this._data, showBackgroundTab)}
|
||||
</div>
|
||||
<ha-dialog-footer slot="footer">
|
||||
${this._params.urlPath
|
||||
@@ -163,6 +196,41 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderContent(
|
||||
params: LovelaceDashboardDetailsDialogParams,
|
||||
data: Partial<LovelaceDashboard>,
|
||||
showBackgroundTab: boolean
|
||||
): string | TemplateResult<1> | typeof nothing {
|
||||
if (params.dashboard?.mode === "yaml") {
|
||||
return this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.cant_edit_yaml"
|
||||
);
|
||||
}
|
||||
|
||||
if (this._currTab === "tab-background" && showBackgroundTab) {
|
||||
return html`
|
||||
<hui-view-background-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._backgroundConfig}
|
||||
@background-config-changed=${this._backgroundConfigChanged}
|
||||
></hui-view-background-editor>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
autofocus
|
||||
.schema=${this._schema(params, data.require_admin)}
|
||||
.data=${data}
|
||||
.hass=${this.hass}
|
||||
.error=${this._error}
|
||||
.computeLabel=${this._computeLabel}
|
||||
.computeHelper=${this._computeHelper}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`;
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(params: LovelaceDashboardDetailsDialogParams, requireAdmin?: boolean) =>
|
||||
[
|
||||
@@ -229,15 +297,16 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
)
|
||||
: "";
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
private _valueChanged(
|
||||
ev: HASSDomEvent<{ value: Partial<LovelaceDashboard> }>
|
||||
) {
|
||||
this._error = undefined;
|
||||
const value = ev.detail.value;
|
||||
if (value.url_path !== this._data?.url_path) {
|
||||
if (ev.detail.value.url_path !== this._data?.url_path) {
|
||||
this._urlPathChanged = true;
|
||||
if (
|
||||
!value.url_path ||
|
||||
value.url_path === "lovelace" ||
|
||||
!/^[a-zA-Z0-9_-]+-[a-zA-Z0-9_-]+$/.test(value.url_path)
|
||||
!ev.detail.value.url_path ||
|
||||
ev.detail.value.url_path === "lovelace" ||
|
||||
!/^[a-zA-Z0-9_-]+-[a-zA-Z0-9_-]+$/.test(ev.detail.value.url_path)
|
||||
) {
|
||||
this._error = {
|
||||
url_path: this.hass.localize(
|
||||
@@ -246,14 +315,22 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
};
|
||||
}
|
||||
}
|
||||
if (value.title !== this._data?.title) {
|
||||
this._data = value;
|
||||
this._fillUrlPath(value.title);
|
||||
if (ev.detail.value.title !== this._data?.title) {
|
||||
this._data = ev.detail.value;
|
||||
if (ev.detail.value.title) {
|
||||
this._fillUrlPath(ev.detail.value.title);
|
||||
}
|
||||
} else {
|
||||
this._data = value;
|
||||
this._data = ev.detail.value;
|
||||
}
|
||||
}
|
||||
|
||||
private _backgroundConfigChanged(
|
||||
ev: HASSDomEvent<{ config: LovelaceConfig }>
|
||||
) {
|
||||
this._backgroundConfig = ev.detail.config;
|
||||
}
|
||||
|
||||
private _fillUrlPath(title: string) {
|
||||
if (this._urlPathChanged || !title) {
|
||||
return;
|
||||
@@ -263,35 +340,51 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
const baseSlug = slugifyTitle.includes("-")
|
||||
? slugifyTitle
|
||||
: `dashboard-${slugifyTitle}`;
|
||||
const taken = this._params?.takenUrlPaths;
|
||||
this._data = {
|
||||
...this._data,
|
||||
url_path:
|
||||
taken !== undefined
|
||||
? pickAvailableDashboardUrlPath(baseSlug, taken)
|
||||
this._params?.takenUrlPaths !== undefined
|
||||
? pickAvailableDashboardUrlPath(baseSlug, this._params.takenUrlPaths)
|
||||
: baseSlug,
|
||||
};
|
||||
}
|
||||
|
||||
private async _updateDashboard() {
|
||||
if (this._params?.urlPath && this._params.dashboard?.mode === "yaml") {
|
||||
if (!this._params || !this._data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._params.urlPath && this._params.dashboard?.mode === "yaml") {
|
||||
this.closeDialog();
|
||||
return;
|
||||
}
|
||||
this._submitting = true;
|
||||
try {
|
||||
if (this._params!.dashboard) {
|
||||
const values: Partial<LovelaceDashboardMutableParams> = {
|
||||
require_admin: this._data!.require_admin,
|
||||
show_in_sidebar: this._data!.show_in_sidebar,
|
||||
icon: this._data!.icon || undefined,
|
||||
title: this._data!.title,
|
||||
};
|
||||
await this._params!.updateDashboard(values);
|
||||
} else if (this._params!.createDashboard) {
|
||||
await this._params!.createDashboard(
|
||||
this._data as LovelaceDashboardCreateParams
|
||||
);
|
||||
if (
|
||||
this._backgroundConfig &&
|
||||
this._params.saveConfig &&
|
||||
this._params.lovelaceConfig &&
|
||||
this._backgroundConfig.background !==
|
||||
this._params.lovelaceConfig.background
|
||||
) {
|
||||
await this._params.saveConfig(this._backgroundConfig);
|
||||
}
|
||||
if (this._params.dashboard) {
|
||||
await this._params.updateDashboard({
|
||||
require_admin: this._data.require_admin ?? false,
|
||||
show_in_sidebar: this._data.show_in_sidebar ?? true,
|
||||
icon: this._data.icon || undefined,
|
||||
title: this._data.title ?? "",
|
||||
});
|
||||
} else if (this._params.createDashboard) {
|
||||
await this._params.createDashboard({
|
||||
require_admin: this._data.require_admin ?? false,
|
||||
show_in_sidebar: this._data.show_in_sidebar ?? true,
|
||||
icon: this._data.icon || undefined,
|
||||
title: this._data.title ?? "",
|
||||
url_path: this._data.url_path ?? "",
|
||||
mode: "storage",
|
||||
});
|
||||
}
|
||||
this.closeDialog();
|
||||
} catch (err: any) {
|
||||
@@ -314,10 +407,25 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleTabChanged(
|
||||
ev: HASSDomEvent<{
|
||||
name: (typeof TABS)[number];
|
||||
}>
|
||||
) {
|
||||
if (ev.detail.name === this._currTab) {
|
||||
return;
|
||||
}
|
||||
this._currTab = ev.detail.name;
|
||||
}
|
||||
|
||||
private async _deleteDashboard() {
|
||||
if (!this._params) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._submitting = true;
|
||||
try {
|
||||
if (await this._params!.removeDashboard()) {
|
||||
if (await this._params.removeDashboard()) {
|
||||
this.closeDialog();
|
||||
}
|
||||
} finally {
|
||||
@@ -326,7 +434,30 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [haStyleDialog, css``];
|
||||
return [
|
||||
haStyleDialog,
|
||||
haStyleDialogFixedTop,
|
||||
css`
|
||||
ha-dialog {
|
||||
--dialog-content-padding: var(--ha-space-6);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
ha-tab-group-tab {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
ha-tab-group-tab::part(base) {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import type {
|
||||
LovelaceDashboard,
|
||||
LovelaceDashboardCreateParams,
|
||||
@@ -17,6 +18,8 @@ export interface LovelaceDashboardDetailsDialogParams {
|
||||
* auto-generated paths avoid collisions by appending -2, -3, and so on.
|
||||
*/
|
||||
takenUrlPaths?: ReadonlySet<string>;
|
||||
lovelaceConfig?: LovelaceConfig;
|
||||
saveConfig?: (config: LovelaceConfig) => Promise<void>;
|
||||
createDashboard?: (values: LovelaceDashboardCreateParams) => Promise<unknown>;
|
||||
updateDashboard: (
|
||||
updates: Partial<LovelaceDashboardMutableParams>
|
||||
|
||||
@@ -183,7 +183,7 @@ export class HuiDialogEditView extends LitElement {
|
||||
<hui-view-background-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._config}
|
||||
@view-config-changed=${this._viewConfigChanged}
|
||||
@background-config-changed=${this._viewConfigChanged}
|
||||
></hui-view-background-editor>
|
||||
`;
|
||||
break;
|
||||
|
||||
@@ -2,135 +2,139 @@ import memoizeOne from "memoize-one";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import {
|
||||
fireEvent,
|
||||
type HASSDomEvent,
|
||||
} from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
import type {
|
||||
LovelaceDashboardBackgroundConfig,
|
||||
LovelaceViewBackgroundConfig,
|
||||
} from "../../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
|
||||
import {
|
||||
isMediaSourceContentId,
|
||||
resolveMediaSource,
|
||||
} from "../../../../data/media_source";
|
||||
|
||||
export interface BackgroundConfigTarget {
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
}
|
||||
|
||||
@customElement("hui-view-background-editor")
|
||||
export class HuiViewBackgroundEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _config!: LovelaceViewConfig;
|
||||
@property({ attribute: false }) public config?: BackgroundConfigTarget;
|
||||
|
||||
@state({ attribute: false }) private _resolvedImage?: string;
|
||||
|
||||
set config(config: LovelaceViewConfig) {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
private _localizeValueCallback = (key: string) =>
|
||||
this.hass.localize(key as any);
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(localize: LocalizeFunc, showSettings: boolean) =>
|
||||
[
|
||||
{
|
||||
name: "image",
|
||||
selector: {
|
||||
media: {
|
||||
accept: ["image/*"] as string[],
|
||||
clearable: true,
|
||||
image_upload: true,
|
||||
hide_content_type: true,
|
||||
content_id_helper: localize(
|
||||
"ui.panel.lovelace.editor.card.picture.content_id_helper"
|
||||
),
|
||||
},
|
||||
private _schema(showSettings: boolean) {
|
||||
return [
|
||||
{
|
||||
name: "image",
|
||||
selector: {
|
||||
media: {
|
||||
accept: ["image/*"] as string[],
|
||||
clearable: true,
|
||||
image_upload: true,
|
||||
hide_content_type: true,
|
||||
content_id_helper: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.card.picture.content_id_helper"
|
||||
),
|
||||
},
|
||||
},
|
||||
...(showSettings
|
||||
? ([
|
||||
{
|
||||
name: "settings",
|
||||
flatten: true,
|
||||
expanded: true,
|
||||
type: "expandable" as const,
|
||||
schema: [
|
||||
{
|
||||
name: "opacity",
|
||||
selector: {
|
||||
number: { min: 0, max: 100, mode: "slider", step: 10 },
|
||||
},
|
||||
...(showSettings
|
||||
? ([
|
||||
{
|
||||
name: "settings",
|
||||
flatten: true,
|
||||
expanded: true,
|
||||
type: "expandable" as const,
|
||||
schema: [
|
||||
{
|
||||
name: "opacity",
|
||||
selector: {
|
||||
number: { min: 0, max: 100, mode: "slider", step: 10 },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "attachment",
|
||||
selector: {
|
||||
button_toggle: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.attachment",
|
||||
options: ["scroll", "fixed"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "attachment",
|
||||
selector: {
|
||||
button_toggle: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.attachment",
|
||||
options: ["scroll", "fixed"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "size",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.size",
|
||||
options: ["auto", "cover", "contain"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "size",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.size",
|
||||
options: ["auto", "cover", "contain"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "alignment",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.alignment",
|
||||
options: [
|
||||
"top left",
|
||||
"top center",
|
||||
"top right",
|
||||
"center left",
|
||||
"center",
|
||||
"center right",
|
||||
"bottom left",
|
||||
"bottom center",
|
||||
"bottom right",
|
||||
],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "alignment",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.alignment",
|
||||
options: [
|
||||
"top left",
|
||||
"top center",
|
||||
"top right",
|
||||
"center left",
|
||||
"center",
|
||||
"center right",
|
||||
"bottom left",
|
||||
"bottom center",
|
||||
"bottom right",
|
||||
],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "repeat",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.repeat",
|
||||
options: ["repeat", "no-repeat"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "repeat",
|
||||
required: true,
|
||||
selector: {
|
||||
select: {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.repeat",
|
||||
options: ["repeat", "no-repeat"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const)
|
||||
: []),
|
||||
] as const
|
||||
);
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const)
|
||||
: []),
|
||||
] as const;
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
protected updated(changedProps: PropertyValues<this>) {
|
||||
if (
|
||||
this._config &&
|
||||
this.config &&
|
||||
this.hass &&
|
||||
(changedProps.has("_config") ||
|
||||
(changedProps.has("config") ||
|
||||
(changedProps.has("hass") && !changedProps.get("hass")))
|
||||
) {
|
||||
const background = this._backgroundData(this._config);
|
||||
const background = this._backgroundData(this.config);
|
||||
this.style.setProperty(
|
||||
"--picture-opacity",
|
||||
`${(background.opacity ?? 100) / 100}`
|
||||
@@ -156,7 +160,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const background = this._backgroundData(this._config);
|
||||
const background = this._backgroundData(this.config);
|
||||
|
||||
return html`
|
||||
${this._resolvedImage
|
||||
@@ -172,7 +176,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${background}
|
||||
.schema=${this._schema(this.hass.localize, true)}
|
||||
.schema=${this._schema(true)}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
@value-changed=${this._valueChanged}
|
||||
.localizeValue=${this._localizeValueCallback}
|
||||
@@ -181,7 +185,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
}
|
||||
|
||||
private _backgroundData = memoizeOne(
|
||||
(backgroundConfig?: LovelaceViewConfig) => {
|
||||
(backgroundConfig?: BackgroundConfigTarget) => {
|
||||
let background = backgroundConfig?.background;
|
||||
if (typeof background === "string") {
|
||||
const backgroundUrl = background.match(
|
||||
@@ -218,12 +222,15 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
}
|
||||
);
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
const config = {
|
||||
...this._config,
|
||||
background: ev.detail.value,
|
||||
};
|
||||
fireEvent(this, "view-config-changed", { config });
|
||||
private _valueChanged(
|
||||
ev: HASSDomEvent<{ value: LovelaceViewBackgroundConfig }>
|
||||
) {
|
||||
fireEvent(this, "background-config-changed", {
|
||||
config: {
|
||||
...(this.config || {}),
|
||||
background: ev.detail.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@@ -290,4 +297,10 @@ declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-view-background-editor": HuiViewBackgroundEditor;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
"background-config-changed": {
|
||||
config: BackgroundConfigTarget;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,6 +1045,8 @@ class HUIRoot extends LitElement {
|
||||
showDashboardDetailDialog(this, {
|
||||
dashboard,
|
||||
urlPath,
|
||||
lovelaceConfig: this.lovelace?.config,
|
||||
saveConfig: this.lovelace?.saveConfig,
|
||||
updateDashboard: async (values) => {
|
||||
await updateDashboard(this.hass!, dashboard!.id, values);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user