Compare commits

...

1 Commits

Author SHA1 Message Date
Paul Bottein
bd7b345fe2 Improve strategy edit mode 2025-08-18 13:43:18 +02:00
7 changed files with 57 additions and 25 deletions

View File

@@ -23,6 +23,7 @@ export interface LovelaceViewElement extends HTMLElement {
badges?: HuiBadge[];
sections?: HuiSection[];
isStrategy: boolean;
allowEdit: boolean;
setConfig(config: LovelaceViewConfig): void;
}
@@ -35,6 +36,7 @@ export interface LovelaceSectionElement extends HTMLElement {
cards?: HuiCard[];
isStrategy: boolean;
importOnly?: boolean;
allowEdit: boolean;
setConfig(config: LovelaceSectionConfig): void;
}

View File

@@ -983,6 +983,7 @@ class HUIRoot extends LitElement {
} else {
view = document.createElement("hui-view");
view.index = viewIndex;
view.allowEdit = !isStrategyDashboard(this.lovelace!.rawConfig);
this._viewCache![viewIndex] = view;
}

View File

@@ -50,6 +50,8 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
@property({ attribute: false }) public isStrategy = false;
@property({ attribute: false }) public allowEdit = false;
@property({ attribute: false }) public cards: HuiCard[] = [];
@property({ attribute: "import-only", type: Boolean })
@@ -80,7 +82,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
const cardsConfig = this._config?.cards ?? [];
const editMode = Boolean(this.lovelace?.editMode && !this.isStrategy);
const editMode = Boolean(this.allowEdit && this.lovelace?.editMode);
const sortableOptions = this.importOnly
? IMPORT_MODE_CARD_SORTABLE_OPTIONS

View File

@@ -44,7 +44,8 @@ export class HuiSection extends ReactiveElement {
@property({ attribute: false }) public lovelace?: Lovelace;
@property({ type: Boolean, reflect: true }) public preview = false;
@property({ type: Boolean, attribute: "force-preview" })
public forcePreview = false;
@property({ type: Boolean, attribute: "import-only" })
public importOnly = false;
@@ -53,6 +54,8 @@ export class HuiSection extends ReactiveElement {
@property({ attribute: false, type: Number }) public viewIndex!: number;
@property({ attribute: false }) public allowEdit = false;
@state() private _cards: HuiCard[] = [];
private _layoutElementType?: string;
@@ -136,10 +139,17 @@ export class HuiSection extends ReactiveElement {
if (changedProperties.has("lovelace")) {
this._layoutElement.lovelace = this.lovelace;
}
if (changedProperties.has("preview")) {
this._layoutElement.preview = this.preview;
if (
changedProperties.has("forcePreview") ||
changedProperties.has("lovelace") ||
changedProperties.has("allowEdit")
) {
const preview =
this.forcePreview ||
(this.allowEdit && Boolean(this.lovelace?.editMode));
this._layoutElement.preview = preview;
this._cards.forEach((element) => {
element.preview = this.preview;
element.preview = preview;
});
}
if (changedProperties.has("importOnly")) {
@@ -208,6 +218,7 @@ export class HuiSection extends ReactiveElement {
this._createCards(sectionConfig);
this._layoutElement!.isStrategy = isStrategy;
this._layoutElement!.allowEdit = this.allowEdit && !isStrategy;
this._layoutElement!.hass = this.hass;
this._layoutElement!.lovelace = this.lovelace;
this._layoutElement!.index = this.index;

View File

@@ -25,7 +25,6 @@ import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../types";
import type { HuiBadge } from "../badges/hui-badge";
import "./hui-view-header";
import type { HuiCard } from "../cards/hui-card";
import "../components/hui-badge-edit-mode";
import {
@@ -44,6 +43,7 @@ import {
import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
import type { HuiSection } from "../sections/hui-section";
import type { Lovelace } from "../types";
import "./hui-view-header";
export const DEFAULT_MAX_COLUMNS = 4;
@@ -59,6 +59,8 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
@property({ attribute: false }) public isStrategy = false;
@property({ attribute: false }) public allowEdit = false;
@property({ attribute: false }) public sections: HuiSection[] = [];
@property({ attribute: false }) public cards: HuiCard[] = [];
@@ -149,7 +151,8 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
const sections = this.sections;
const totalSectionCount =
this._sectionColumnCount + (this.lovelace?.editMode ? 1 : 0);
const editMode = this.lovelace.editMode;
const editMode = Boolean(this.allowEdit && this.lovelace.editMode);
const maxColumnCount = this._columnsController.value ?? 1;
@@ -163,6 +166,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
.hass=${this.hass}
.badges=${this.badges}
.lovelace=${this.lovelace}
.editMode=${editMode}
.viewIndex=${this.index}
.config=${this._config?.header}
style=${styleMap({
@@ -205,7 +209,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
})}
>
${
this.lovelace?.editMode
editMode
? html`
<div class="section-header">
${editMode

View File

@@ -3,6 +3,7 @@ import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { DragScrollController } from "../../../common/controllers/drag-scroll-controller";
import "../../../components/ha-ripple";
import "../../../components/ha-sortable";
import "../../../components/ha-svg-icon";
@@ -16,11 +17,10 @@ import type { HuiBadge } from "../badges/hui-badge";
import "../badges/hui-view-badges";
import type { HuiCard } from "../cards/hui-card";
import "../components/hui-badge-edit-mode";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { replaceView } from "../editor/config-util";
import { showEditViewHeaderDialog } from "../editor/view-header/show-edit-view-header-dialog";
import type { Lovelace } from "../types";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { DragScrollController } from "../../../common/controllers/drag-scroll-controller";
export const DEFAULT_VIEW_HEADER_LAYOUT = "center";
export const DEFAULT_VIEW_HEADER_BADGES_POSITION = "bottom";
@@ -32,6 +32,8 @@ export class HuiViewHeader extends LitElement {
@property({ attribute: false }) public lovelace!: Lovelace;
@property({ attribute: false }) public editMode = false;
@property({ attribute: false }) public card?: HuiCard;
@property({ attribute: false }) public badges: HuiBadge[] = [];
@@ -43,7 +45,7 @@ export class HuiViewHeader extends LitElement {
private _checkHidden() {
const allHidden =
!this.card &&
!this.lovelace.editMode &&
!this.editMode &&
this.badges.every((badges) => badges.hidden);
this.toggleAttribute("hidden", allHidden);
}
@@ -76,15 +78,15 @@ export class HuiViewHeader extends LitElement {
willUpdate(changedProperties: PropertyValues<typeof this>): void {
if (
changedProperties.has("badges") ||
changedProperties.has("lovelace") ||
changedProperties.has("editMode") ||
changedProperties.has("card")
) {
this._checkHidden();
}
if (changedProperties.has("config") || changedProperties.has("lovelace")) {
if (changedProperties.has("config") || changedProperties.has("editMode")) {
this._dragScrollController.enabled =
!this.lovelace.editMode && this.config?.badges_wrap === "scroll";
!this.editMode && this.config?.badges_wrap === "scroll";
}
if (changedProperties.has("config")) {
@@ -101,8 +103,8 @@ export class HuiViewHeader extends LitElement {
if (changedProperties.has("hass")) {
this.card.hass = this.hass;
}
if (changedProperties.has("lovelace")) {
this.card.preview = this.lovelace.editMode;
if (changedProperties.has("editMode")) {
this.card.preview = this.editMode;
}
}
}
@@ -110,7 +112,7 @@ export class HuiViewHeader extends LitElement {
private _createCardElement(cardConfig: LovelaceCardConfig) {
const element = document.createElement("hui-card");
element.hass = this.hass;
element.preview = this.lovelace.editMode;
element.preview = this.editMode;
element.config = cardConfig;
element.load();
return element;
@@ -193,7 +195,7 @@ export class HuiViewHeader extends LitElement {
render() {
if (!this.lovelace) return nothing;
const editMode = Boolean(this.lovelace?.editMode);
const editMode = this.editMode;
const card = this.card;

View File

@@ -80,6 +80,8 @@ export class HUIView extends ReactiveElement {
@property({ type: Number }) public index!: number;
@property({ attribute: false }) public allowEdit = false;
@state() private _cards: HuiCard[] = [];
@state() private _badges: HuiBadge[] = [];
@@ -105,7 +107,7 @@ export class HUIView extends ReactiveElement {
private _createCardElement(cardConfig: LovelaceCardConfig) {
const element = document.createElement("hui-card");
element.hass = this.hass;
element.preview = this.lovelace.editMode;
element.preview = this.allowEdit && this.lovelace.editMode;
element.config = cardConfig;
element.addEventListener("card-updated", (ev: Event) => {
ev.stopPropagation();
@@ -118,7 +120,7 @@ export class HUIView extends ReactiveElement {
public createBadgeElement(badgeConfig: LovelaceBadgeConfig) {
const element = document.createElement("hui-badge");
element.hass = this.hass;
element.preview = this.lovelace.editMode;
element.preview = this.allowEdit && this.lovelace.editMode;
element.config = badgeConfig;
element.addEventListener("badge-updated", (ev: Event) => {
ev.stopPropagation();
@@ -130,12 +132,13 @@ export class HUIView extends ReactiveElement {
// Public to make demo happy
public createSectionElement(sectionConfig: LovelaceSectionConfig) {
const viewConfig = this.lovelace.config.views[this.index];
const element = document.createElement("hui-section");
element.hass = this.hass;
element.lovelace = this.lovelace;
element.config = sectionConfig;
element.viewIndex = this.index;
element.preview = this.lovelace.editMode;
element.allowEdit = this.allowEdit && !isStrategyView(viewConfig);
element.addEventListener(
"ll-rebuild",
(ev: Event) => {
@@ -276,20 +279,26 @@ export class HUIView extends ReactiveElement {
}
if (changedProperties.has("lovelace")) {
this._layoutElement.lovelace = this.lovelace;
}
if (
changedProperties.has("lovelace") ||
changedProperties.has("allowEdit")
) {
const preview = this.allowEdit && this.lovelace.editMode;
this._sections.forEach((element) => {
try {
element.hass = this.hass;
element.lovelace = this.lovelace;
element.preview = this.lovelace.editMode;
element.preview = preview;
} catch (e: any) {
this._rebuildSection(element, createErrorSectionConfig(e.message));
}
});
this._cards.forEach((element) => {
element.preview = this.lovelace.editMode;
element.preview = preview;
});
this._badges.forEach((element) => {
element.preview = this.lovelace.editMode;
element.preview = preview;
});
}
if (changedProperties.has("_cards")) {
@@ -337,6 +346,7 @@ export class HUIView extends ReactiveElement {
this._createCards(viewConfig);
this._createSections(viewConfig);
this._layoutElement!.isStrategy = isStrategy;
this._layoutElement!.allowEdit = this.allowEdit && !isStrategy;
this._layoutElement!.hass = this.hass;
this._layoutElement!.narrow = this.narrow;
this._layoutElement!.lovelace = this.lovelace;
@@ -357,7 +367,7 @@ export class HUIView extends ReactiveElement {
const rawConfig = this.lovelace.config.views[this.index];
const viewConfig = await this._generateConfig(rawConfig);
const isStrategy = isStrategyView(viewConfig);
const isStrategy = isStrategyView(rawConfig);
this._setConfig(viewConfig, isStrategy);
}