From 03ea08f98c7202989897a69a2b42dc197f1da140 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 18 Nov 2024 07:53:01 +0100 Subject: [PATCH] Create a section when dropping card on the create section button (#22790) * Create a section when dropping card on the create section button * Add translations * Add title by default * And case when moving a heading card --- .../lovelace/views/hui-sections-view.ts | 170 +++++++++++++++--- src/translations/en.json | 1 + 2 files changed, 144 insertions(+), 27 deletions(-) diff --git a/src/panels/lovelace/views/hui-sections-view.ts b/src/panels/lovelace/views/hui-sections-view.ts index 8dff28e127..944e3a1632 100644 --- a/src/panels/lovelace/views/hui-sections-view.ts +++ b/src/panels/lovelace/views/hui-sections-view.ts @@ -7,7 +7,7 @@ import { mdiViewGridPlus, } from "@mdi/js"; import type { CSSResultGroup, PropertyValues } from "lit"; -import { LitElement, css, html, nothing } from "lit"; +import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { repeat } from "lit/directives/repeat"; @@ -20,6 +20,7 @@ import "../../../components/ha-sortable"; import "../../../components/ha-svg-icon"; import type { LovelaceViewElement } from "../../../data/lovelace"; import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; +import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section"; import type { LovelaceViewConfig } from "../../../data/lovelace/config/view"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import type { HomeAssistant } from "../../../types"; @@ -27,8 +28,19 @@ 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 { addSection, deleteSection, moveSection } from "../editor/config-util"; -import { findLovelaceContainer } from "../editor/lovelace-path"; +import { + addSection, + deleteSection, + moveCard, + moveSection, +} from "../editor/config-util"; +import type { LovelaceCardPath } from "../editor/lovelace-path"; +import { + findLovelaceContainer, + findLovelaceItems, + getLovelaceContainerPath, + parseLovelaceCardPath, +} from "../editor/lovelace-path"; import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog"; import type { HuiSection } from "../sections/hui-section"; import type { Lovelace } from "../types"; @@ -231,19 +243,35 @@ export class SectionsView extends LitElement implements LovelaceViewElement { )} ${editMode ? html` - +
+ + +
+ ` : nothing} ${editMode && this._config?.cards?.length @@ -280,6 +308,52 @@ export class SectionsView extends LitElement implements LovelaceViewElement { `; } + private _defaultSection(includeHeading: boolean): LovelaceSectionConfig { + return { + type: "grid", + cards: includeHeading + ? [ + { + type: "heading", + heading: this.hass!.localize( + "ui.panel.lovelace.editor.section.default_section_title" + ), + }, + ] + : [], + }; + } + + private _handleCardAdded(ev) { + const { data } = ev.detail; + const oldPath = data as LovelaceCardPath; + + const { cardIndex } = parseLovelaceCardPath(oldPath); + const containerPath = getLovelaceContainerPath(oldPath); + const cards = findLovelaceItems( + "cards", + this.lovelace!.config, + containerPath + ); + const cardConfig = cards![cardIndex]; + + const configWithNewSection = addSection( + this.lovelace!.config, + this.index!, + this._defaultSection(cardConfig.type !== "heading") // If we move a heading card, we don't want to include a heading in the new section + ); + const viewConfig = configWithNewSection.views[ + this.index! + ] as LovelaceViewConfig; + const newPath = [ + this.index!, + viewConfig.sections!.length - 1, + 1, + ] as LovelaceCardPath; + const newConfig = moveCard(configWithNewSection, oldPath, newPath); + this.lovelace!.saveConfig(newConfig); + } + private _importedCardSectionConfig = memoizeOne( (cards: LovelaceCardConfig[]) => ({ type: "grid", @@ -288,17 +362,11 @@ export class SectionsView extends LitElement implements LovelaceViewElement { ); private _createSection(): void { - const newConfig = addSection(this.lovelace!.config, this.index!, { - type: "grid", - cards: [ - { - type: "heading", - heading: this.hass!.localize( - "ui.panel.lovelace.editor.section.default_section_title" - ), - }, - ], - }); + const newConfig = addSection( + this.lovelace!.config, + this.index!, + this._defaultSection(true) + ); this.lovelace!.saveConfig(newConfig); } @@ -415,8 +483,55 @@ export class SectionsView extends LitElement implements LovelaceViewElement { padding: 8px; } - .create-section { + .create-section-container { + position: relative; + display: flex; + flex-direction: column; margin-top: 36px; + } + + .create-section-container .card { + display: none; + } + + .create-section-container:has(.card) .drop-helper { + display: flex; + } + .create-section-container:has(.card) .create-section { + display: none; + } + + .drop-helper { + display: none; + flex-direction: column; + align-items: center; + justify-content: center; + position: relative; + outline: none; + background: none; + cursor: pointer; + border-radius: var(--ha-card-border-radius, 12px); + border: 2px dashed var(--primary-color); + height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px)); + padding: 8px; + box-sizing: border-box; + width: 100%; + --ha-ripple-color: var(--primary-color); + --ha-ripple-hover-opacity: 0.04; + --ha-ripple-pressed-opacity: 0.12; + } + + .drop-helper p { + color: var(--primary-text-color); + font-size: 16px; + font-weight: 400; + line-height: 24px; + text-align: center; + } + + .create-section { + display: block; + position: relative; outline: none; background: none; cursor: pointer; @@ -426,6 +541,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement { height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px)); padding: 8px; box-sizing: border-box; + width: 100%; --ha-ripple-color: var(--primary-color); --ha-ripple-hover-opacity: 0.04; --ha-ripple-pressed-opacity: 0.12; diff --git a/src/translations/en.json b/src/translations/en.json index df961152e8..8d775b4ce5 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5895,6 +5895,7 @@ "section": { "add_badge": "Add badge", "add_card": "[%key:ui::panel::lovelace::editor::edit_card::add%]", + "drop_card_create_section": "Drop card here to create a new section", "create_section": "Create section", "default_section_title": "New section", "imported_cards_title": "Imported cards",