diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
index 6b54de03dd..a9e4e4f45c 100644
--- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
+++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
@@ -1,13 +1,26 @@
import "@material/mwc-button";
+import { ActionDetail } from "@material/mwc-list";
+import { mdiCheck, mdiDotsVertical } from "@mdi/js";
import "@polymer/paper-tabs/paper-tab";
import "@polymer/paper-tabs/paper-tabs";
-import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
-import { customElement, property, state } from "lit/decorators";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ LitElement,
+ PropertyValues,
+ TemplateResult,
+} from "lit";
+import { customElement, property, query, state } from "lit/decorators";
+import { classMap } from "lit/directives/class-map";
import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
+import { stopPropagation } from "../../../../common/dom/stop_propagation";
import { navigate } from "../../../../common/navigate";
+import { deepEqual } from "../../../../common/util/deep-equal";
+import "../../../../components/ha-alert";
import "../../../../components/ha-circular-progress";
import "../../../../components/ha-dialog";
-import "../../../../components/ha-alert";
+import { HaYamlEditor } from "../../../../components/ha-yaml-editor";
import type {
LovelaceBadgeConfig,
LovelaceCardConfig,
@@ -20,6 +33,11 @@ import {
import { haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
import "../../components/hui-entity-editor";
+import {
+ DEFAULT_VIEW_LAYOUT,
+ PANEL_VIEW_LAYOUT,
+ VIEWS_NO_BADGE_SUPPORT,
+} from "../../views/const";
import { addView, deleteView, replaceView } from "../config-util";
import "../hui-badge-preview";
import { processEditorEntities } from "../process-editor-entities";
@@ -31,12 +49,6 @@ import {
import "./hui-view-editor";
import "./hui-view-visibility-editor";
import { EditViewDialogParams } from "./show-edit-view-dialog";
-import {
- DEFAULT_VIEW_LAYOUT,
- PANEL_VIEW_LAYOUT,
- VIEWS_NO_BADGE_SUPPORT,
-} from "../../views/const";
-import { deepEqual } from "../../../../common/util/deep-equal";
@customElement("hui-dialog-edit-view")
export class HuiDialogEditView extends LitElement {
@@ -56,6 +68,10 @@ export class HuiDialogEditView extends LitElement {
@state() private _dirty = false;
+ @state() private _yamlMode = false;
+
+ @query("ha-yaml-editor") private _editor?: HaYamlEditor;
+
private _curTabIndex = 0;
get _type(): string {
@@ -67,6 +83,16 @@ export class HuiDialogEditView extends LitElement {
: this._config.type || DEFAULT_VIEW_LAYOUT;
}
+ protected updated(changedProperties: PropertyValues) {
+ if (this._yamlMode && changedProperties.has("_yamlMode")) {
+ const viewConfig = {
+ ...this._config,
+ badges: this._badges,
+ };
+ this._editor?.setValue(viewConfig);
+ }
+ }
+
public showDialog(params: EditViewDialogParams): void {
this._params = params;
@@ -89,6 +115,7 @@ export class HuiDialogEditView extends LitElement {
this._params = undefined;
this._config = {};
this._badges = [];
+ this._yamlMode = false;
this._dirty = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -111,62 +138,74 @@ export class HuiDialogEditView extends LitElement {
}
let content;
- switch (this._curTab) {
- case "tab-settings":
- content = html`
-
- `;
- break;
- case "tab-badges":
- content = html`
- ${this._badges?.length
- ? html`
- ${VIEWS_NO_BADGE_SUPPORT.includes(this._type)
- ? html`
-
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_badges.view_no_badges"
- )}
-
- `
- : ""}
-
- ${this._badges.map(
- (badgeConfig) => html`
-
- `
- )}
-
- `
- : ""}
-
- `;
- break;
- case "tab-visibility":
- content = html`
-
- `;
- break;
- case "tab-cards":
- content = html` Cards `;
- break;
+
+ if (this._yamlMode) {
+ content = html`
+
+ `;
+ } else {
+ switch (this._curTab) {
+ case "tab-settings":
+ content = html`
+
+ `;
+ break;
+ case "tab-badges":
+ content = html`
+ ${this._badges?.length
+ ? html`
+ ${VIEWS_NO_BADGE_SUPPORT.includes(this._type)
+ ? html`
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_badges.view_no_badges"
+ )}
+
+ `
+ : ""}
+
+ ${this._badges.map(
+ (badgeConfig) => html`
+
+ `
+ )}
+
+ `
+ : ""}
+
+ `;
+ break;
+ case "tab-visibility":
+ content = html`
+
+ `;
+ break;
+ case "tab-cards":
+ content = html` Cards `;
+ break;
+ }
}
+
return html`
${this._viewConfigTitle}
-
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_view.tab_settings"
- )}
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_view.tab_badges"
- )}
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_view.tab_visibility"
- )}
-
+
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_view.edit_ui"
+ )}
+ ${!this._yamlMode
+ ? html``
+ : ``}
+
+
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_view.edit_yaml"
+ )}
+ ${this._yamlMode
+ ? html``
+ : ``}
+
+
+ ${!this._yamlMode
+ ? html`
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_view.tab_settings"
+ )}
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_view.tab_badges"
+ )}
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_view.tab_visibility"
+ )}
+ `
+ : ""}
${content}
${this._params.viewIndex !== undefined
@@ -235,6 +318,19 @@ export class HuiDialogEditView extends LitElement {
`;
}
+ private async _handleAction(ev: CustomEvent) {
+ ev.stopPropagation();
+ ev.preventDefault();
+ switch (ev.detail.index) {
+ case 0:
+ this._yamlMode = false;
+ break;
+ case 1:
+ this._yamlMode = true;
+ break;
+ }
+ }
+
private async _delete(): Promise {
if (!this._params) {
return;
@@ -348,6 +444,17 @@ export class HuiDialogEditView extends LitElement {
this._dirty = true;
}
+ private _viewYamlChanged(ev: CustomEvent) {
+ ev.stopPropagation();
+ if (!ev.detail.isValid) {
+ return;
+ }
+ const { badges = [], ...config } = ev.detail.value;
+ this._config = config;
+ this._badges = badges;
+ this._dirty = true;
+ }
+
private _isConfigChanged(): boolean {
return (
this._creatingView ||
@@ -366,6 +473,9 @@ export class HuiDialogEditView extends LitElement {
return [
haStyleDialog,
css`
+ ha-dialog.yaml-mode {
+ --dialog-content-padding: 0;
+ }
h2 {
display: block;
color: var(--primary-text-color);
@@ -421,6 +531,22 @@ export class HuiDialogEditView extends LitElement {
ha-circular-progress[active] {
display: block;
}
+ ha-button-menu {
+ color: var(--secondary-text-color);
+ position: absolute;
+ right: 16px;
+ top: 14px;
+ inset-inline-end: 16px;
+ inset-inline-start: initial;
+ direction: var(--direction);
+ }
+ ha-button-menu,
+ ha-icon-button {
+ --mdc-theme-text-primary-on-background: var(--primary-text-color);
+ }
+ .selected_menu_item {
+ color: var(--primary-color);
+ }
.hidden {
display: none;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 3aeb0dffa6..0814955467 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3805,7 +3805,9 @@
"subview": "Subview",
"subview_helper": "Subviews don't appear in tabs and have a back button.",
"back_path": "Back path (optional)",
- "back_path_helper": "Only for subviews. If empty, clicking on back button will go to the previous page."
+ "back_path_helper": "Only for subviews. If empty, clicking on back button will go to the previous page.",
+ "edit_ui": "Edit in visual editor",
+ "edit_yaml": "Edit in YAML"
},
"edit_badges": {
"view_no_badges": "Badges are not be supported by the current view type."