Improve strategy editor (#24757)

* Add cancel and delete button

* Implement delete

* Reset gui mode when closing
This commit is contained in:
Paul Bottein 2025-03-24 18:57:10 +01:00 committed by GitHub
parent 3857c53b7f
commit 2ae70e9b54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 39 deletions

View File

@ -1,8 +1,8 @@
import { import {
mdiAccountHardHat, mdiAccountHardHat,
mdiClose, mdiClose,
mdiCodeBraces,
mdiDotsVertical, mdiDotsVertical,
mdiPlaylistEdit,
} from "@mdi/js"; } from "@mdi/js";
import type { CSSResultGroup } from "lit"; import type { CSSResultGroup } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
@ -19,11 +19,11 @@ import type { LovelaceStrategyConfig } from "../../../../../data/lovelace/config
import { haStyleDialog } from "../../../../../resources/styles"; import { haStyleDialog } from "../../../../../resources/styles";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import { showSaveSuccessToast } from "../../../../../util/toast-saved-success"; import { showSaveSuccessToast } from "../../../../../util/toast-saved-success";
import "../hui-dashboard-strategy-element-editor"; import { cleanLegacyStrategyConfig } from "../../../strategies/legacy-strategy";
import type { HuiDashboardStrategyElementEditor } from "../hui-dashboard-strategy-element-editor";
import type { ConfigChangedEvent } from "../../hui-element-editor"; import type { ConfigChangedEvent } from "../../hui-element-editor";
import type { GUIModeChangedEvent } from "../../types"; import type { GUIModeChangedEvent } from "../../types";
import { cleanLegacyStrategyConfig } from "../../../strategies/legacy-strategy"; import "../hui-dashboard-strategy-element-editor";
import type { HuiDashboardStrategyElementEditor } from "../hui-dashboard-strategy-element-editor";
import type { DashboardStrategyEditorDialogParams } from "./show-dialog-dashboard-strategy-editor"; import type { DashboardStrategyEditorDialogParams } from "./show-dialog-dashboard-strategy-editor";
@customElement("dialog-dashboard-strategy-editor") @customElement("dialog-dashboard-strategy-editor")
@ -52,6 +52,8 @@ class DialogDashboardStrategyEditor extends LitElement {
public closeDialog(): void { public closeDialog(): void {
this._params = undefined; this._params = undefined;
this._strategyConfig = undefined; this._strategyConfig = undefined;
this._guiModeAvailable = true;
this._GUImode = true;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
} }
@ -67,10 +69,6 @@ class DialogDashboardStrategyEditor extends LitElement {
this._guiModeAvailable = ev.detail.guiModeAvailable; this._guiModeAvailable = ev.detail.guiModeAvailable;
} }
private _toggleMode(): void {
this._strategyEditorEl?.toggleMode();
}
private _opened() { private _opened() {
this._strategyEditorEl?.focusYamlEditor(); this._strategyEditorEl?.focusYamlEditor();
} }
@ -84,6 +82,39 @@ class DialogDashboardStrategyEditor extends LitElement {
this.closeDialog(); this.closeDialog();
} }
private async _delete(ev) {
ev.stopPropagation();
if (await this._params!.deleteDashboard()) {
this.closeDialog();
}
}
private _cancel(ev): void {
ev.stopPropagation();
this.closeDialog();
}
private _handleAction(ev) {
ev.stopPropagation();
switch (ev.detail.index) {
case 0:
this._toggleMode();
break;
case 1:
this._takeControl();
break;
}
}
private _toggleMode(): void {
this._strategyEditorEl?.toggleMode();
}
private _takeControl() {
this._params!.takeControl();
this.closeDialog();
}
protected render() { protected render() {
if (!this._params || !this._strategyConfig) { if (!this._params || !this._strategyConfig) {
return nothing; return nothing;
@ -118,6 +149,7 @@ class DialogDashboardStrategyEditor extends LitElement {
slot="actionItems" slot="actionItems"
@closed=${stopPropagation} @closed=${stopPropagation}
fixed fixed
@action=${this._handleAction}
> >
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
@ -126,14 +158,17 @@ class DialogDashboardStrategyEditor extends LitElement {
></ha-icon-button> ></ha-icon-button>
<ha-list-item <ha-list-item
graphic="icon" graphic="icon"
@request-selected=${this._showRawConfigEditor} .disabled=${!this._guiModeAvailable && !this._GUImode}
> >
${this.hass.localize( ${this.hass!.localize(
"ui.panel.lovelace.editor.strategy-editor.raw_configuration_editor" `ui.panel.lovelace.editor.edit_view.edit_${!this._GUImode ? "ui" : "yaml"}`
)} )}
<ha-svg-icon slot="graphic" .path=${mdiCodeBraces}></ha-svg-icon> <ha-svg-icon
slot="graphic"
.path=${mdiPlaylistEdit}
></ha-svg-icon>
</ha-list-item> </ha-list-item>
<ha-list-item graphic="icon" @request-selected=${this._takeControl}> <ha-list-item graphic="icon">
${this.hass.localize( ${this.hass.localize(
"ui.panel.lovelace.editor.strategy-editor.take_control" "ui.panel.lovelace.editor.strategy-editor.take_control"
)} )}
@ -155,17 +190,11 @@ class DialogDashboardStrategyEditor extends LitElement {
></hui-dashboard-strategy-element-editor> ></hui-dashboard-strategy-element-editor>
</div> </div>
<ha-button <ha-button class="danger" @click=${this._delete} slot="secondaryAction">
slot="secondaryAction" ${this.hass!.localize("ui.common.delete")}
@click=${this._toggleMode} </ha-button>
.disabled=${!this._guiModeAvailable} <ha-button @click=${this._cancel} slot="primaryAction">
class="gui-mode-button" ${this.hass!.localize("ui.common.cancel")}
>
${this.hass!.localize(
!this._strategyEditorEl || this._GUImode
? "ui.panel.lovelace.editor.strategy-editor.show_code_editor"
: "ui.panel.lovelace.editor.strategy-editor.show_visual_editor"
)}
</ha-button> </ha-button>
<ha-button @click=${this._save} slot="primaryAction"> <ha-button @click=${this._save} slot="primaryAction">
${this.hass!.localize("ui.common.save")} ${this.hass!.localize("ui.common.save")}
@ -174,18 +203,6 @@ class DialogDashboardStrategyEditor extends LitElement {
`; `;
} }
private _takeControl(ev) {
ev.stopPropagation();
this._params!.takeControl();
this.closeDialog();
}
private _showRawConfigEditor(ev) {
ev.stopPropagation();
this._params!.showRawConfigEditor();
this.closeDialog();
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
haStyleDialog, haStyleDialog,
@ -210,6 +227,10 @@ class DialogDashboardStrategyEditor extends LitElement {
--dialog-content-padding: 8px; --dialog-content-padding: 8px;
} }
} }
.danger {
--mdc-theme-primary: var(--error-color);
}
`, `,
]; ];
} }

View File

@ -5,7 +5,7 @@ export interface DashboardStrategyEditorDialogParams {
config: LovelaceDashboardStrategyConfig; config: LovelaceDashboardStrategyConfig;
saveConfig: (config: LovelaceDashboardStrategyConfig) => void; saveConfig: (config: LovelaceDashboardStrategyConfig) => void;
takeControl: () => void; takeControl: () => void;
showRawConfigEditor: () => void; deleteDashboard: () => Promise<boolean>;
} }
export const loadDashboardStrategyEditorDialog = () => export const loadDashboardStrategyEditorDialog = () =>

View File

@ -763,6 +763,12 @@ class HUIRoot extends LitElement {
}); });
return; return;
} }
const urlPath = this.route?.prefix.slice(1);
await this.hass.loadFragmentTranslation("config");
const dashboards = await fetchDashboards(this.hass);
const dashboard = dashboards.find((d) => d.url_path === urlPath);
showDashboardStrategyEditorDialog(this, { showDashboardStrategyEditorDialog(this, {
config: this.lovelace!.rawConfig, config: this.lovelace!.rawConfig,
saveConfig: this.lovelace!.saveConfig, saveConfig: this.lovelace!.saveConfig,
@ -773,8 +779,27 @@ class HUIRoot extends LitElement {
narrow: this.narrow!, narrow: this.narrow!,
}); });
}, },
showRawConfigEditor: () => { deleteDashboard: async () => {
this.lovelace!.enableFullEditMode(); const confirm = await showConfirmationDialog(this, {
title: this.hass!.localize(
"ui.panel.config.lovelace.dashboards.confirm_delete_title",
{ dashboard_title: dashboard!.title }
),
text: this.hass!.localize(
"ui.panel.config.lovelace.dashboards.confirm_delete_text"
),
confirmText: this.hass!.localize("ui.common.delete"),
destructive: true,
});
if (!confirm) {
return false;
}
try {
await deleteDashboard(this.hass!, dashboard!.id);
return true;
} catch (_err: any) {
return false;
}
}, },
}); });
return; return;