mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-14 12:56:37 +00:00
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
This commit is contained in:
parent
1f5f6c5f8a
commit
03ea08f98c
@ -7,7 +7,7 @@ import {
|
|||||||
mdiViewGridPlus,
|
mdiViewGridPlus,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
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 { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
@ -20,6 +20,7 @@ import "../../../components/ha-sortable";
|
|||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import type { LovelaceViewElement } from "../../../data/lovelace";
|
import type { LovelaceViewElement } from "../../../data/lovelace";
|
||||||
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
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 type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
|
||||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
@ -27,8 +28,19 @@ import type { HuiBadge } from "../badges/hui-badge";
|
|||||||
import "../badges/hui-view-badges";
|
import "../badges/hui-view-badges";
|
||||||
import type { HuiCard } from "../cards/hui-card";
|
import type { HuiCard } from "../cards/hui-card";
|
||||||
import "../components/hui-badge-edit-mode";
|
import "../components/hui-badge-edit-mode";
|
||||||
import { addSection, deleteSection, moveSection } from "../editor/config-util";
|
import {
|
||||||
import { findLovelaceContainer } from "../editor/lovelace-path";
|
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 { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
|
||||||
import type { HuiSection } from "../sections/hui-section";
|
import type { HuiSection } from "../sections/hui-section";
|
||||||
import type { Lovelace } from "../types";
|
import type { Lovelace } from "../types";
|
||||||
@ -231,19 +243,35 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
)}
|
)}
|
||||||
${editMode
|
${editMode
|
||||||
? html`
|
? html`
|
||||||
<button
|
<ha-sortable
|
||||||
class="create-section"
|
group="card"
|
||||||
@click=${this._createSection}
|
@item-added=${this._handleCardAdded}
|
||||||
aria-label=${this.hass.localize(
|
filter="button"
|
||||||
"ui.panel.lovelace.editor.section.create_section"
|
.rollback=${false}
|
||||||
)}
|
|
||||||
.title=${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.editor.section.create_section"
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<ha-ripple></ha-ripple>
|
<div class="create-section-container">
|
||||||
<ha-svg-icon .path=${mdiViewGridPlus}></ha-svg-icon>
|
<div class="drop-helper" aria-hidden="true">
|
||||||
</button>
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.section.drop_card_create_section"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="create-section"
|
||||||
|
@click=${this._createSection}
|
||||||
|
aria-label=${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.section.create_section"
|
||||||
|
)}
|
||||||
|
.title=${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.section.create_section"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-ripple></ha-ripple>
|
||||||
|
<ha-svg-icon .path=${mdiViewGridPlus}></ha-svg-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ha-sortable>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
${editMode && this._config?.cards?.length
|
${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(
|
private _importedCardSectionConfig = memoizeOne(
|
||||||
(cards: LovelaceCardConfig[]) => ({
|
(cards: LovelaceCardConfig[]) => ({
|
||||||
type: "grid",
|
type: "grid",
|
||||||
@ -288,17 +362,11 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private _createSection(): void {
|
private _createSection(): void {
|
||||||
const newConfig = addSection(this.lovelace!.config, this.index!, {
|
const newConfig = addSection(
|
||||||
type: "grid",
|
this.lovelace!.config,
|
||||||
cards: [
|
this.index!,
|
||||||
{
|
this._defaultSection(true)
|
||||||
type: "heading",
|
);
|
||||||
heading: this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.section.default_section_title"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
this.lovelace!.saveConfig(newConfig);
|
this.lovelace!.saveConfig(newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,8 +483,55 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-section {
|
.create-section-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
margin-top: 36px;
|
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;
|
outline: none;
|
||||||
background: none;
|
background: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -426,6 +541,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px));
|
height: calc(var(--row-height) + 2 * (var(--row-gap) + 2px));
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
--ha-ripple-color: var(--primary-color);
|
--ha-ripple-color: var(--primary-color);
|
||||||
--ha-ripple-hover-opacity: 0.04;
|
--ha-ripple-hover-opacity: 0.04;
|
||||||
--ha-ripple-pressed-opacity: 0.12;
|
--ha-ripple-pressed-opacity: 0.12;
|
||||||
|
@ -5895,6 +5895,7 @@
|
|||||||
"section": {
|
"section": {
|
||||||
"add_badge": "Add badge",
|
"add_badge": "Add badge",
|
||||||
"add_card": "[%key:ui::panel::lovelace::editor::edit_card::add%]",
|
"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",
|
"create_section": "Create section",
|
||||||
"default_section_title": "New section",
|
"default_section_title": "New section",
|
||||||
"imported_cards_title": "Imported cards",
|
"imported_cards_title": "Imported cards",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user