mirror of
https://github.com/home-assistant/frontend.git
synced 2026-02-04 01:10:33 -06:00
Move section edit logic to its own component (#27017)
This commit is contained in:
parent
7082646fe5
commit
0eaf9ead9e
152
src/panels/lovelace/components/hui-section-edit-mode.ts
Normal file
152
src/panels/lovelace/components/hui-section-edit-mode.ts
Normal file
@ -0,0 +1,152 @@
|
||||
import { mdiDelete, mdiDrag, mdiPencil } from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { deleteSection } from "../editor/config-util";
|
||||
import { findLovelaceContainer } from "../editor/lovelace-path";
|
||||
import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
|
||||
import type { Lovelace } from "../types";
|
||||
|
||||
@customElement("hui-section-edit-mode")
|
||||
export class HuiSectionEditMode extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public lovelace!: Lovelace;
|
||||
|
||||
@property({ attribute: false, type: Number }) public index!: number;
|
||||
|
||||
@property({ attribute: false, type: Number }) public viewIndex!: number;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class="section-header">
|
||||
<div class="section-actions">
|
||||
<ha-svg-icon
|
||||
aria-hidden="true"
|
||||
class="handle"
|
||||
.path=${mdiDrag}
|
||||
></ha-svg-icon>
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize("ui.common.edit")}
|
||||
@click=${this._editSection}
|
||||
.path=${mdiPencil}
|
||||
></ha-icon-button>
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize("ui.common.delete")}
|
||||
@click=${this._deleteSection}
|
||||
.path=${mdiDelete}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section-wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _editSection(ev) {
|
||||
ev.stopPropagation();
|
||||
showEditSectionDialog(this, {
|
||||
lovelace: this.lovelace!,
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveConfig: (newConfig) => {
|
||||
this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
viewIndex: this.viewIndex,
|
||||
sectionIndex: this.index,
|
||||
});
|
||||
}
|
||||
|
||||
private async _deleteSection(ev) {
|
||||
ev.stopPropagation();
|
||||
const path = [this.viewIndex, this.index] as [number, number];
|
||||
|
||||
const section = findLovelaceContainer(this.lovelace!.config, path);
|
||||
|
||||
const cardCount = "cards" in section && section.cards?.length;
|
||||
|
||||
if (cardCount) {
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.delete_section.title"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
`ui.panel.lovelace.editor.delete_section.text`
|
||||
),
|
||||
confirmText: this.hass.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
});
|
||||
|
||||
if (!confirm) return;
|
||||
}
|
||||
|
||||
const newConfig = deleteSection(
|
||||
this.lovelace!.config,
|
||||
this.viewIndex,
|
||||
this.index
|
||||
);
|
||||
this.lovelace!.saveConfig(newConfig);
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.section-header {
|
||||
position: relative;
|
||||
height: 34px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.section-actions {
|
||||
position: absolute;
|
||||
height: 36px;
|
||||
bottom: -2px;
|
||||
right: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: initial;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
background: var(--secondary-background-color);
|
||||
--mdc-icon-button-size: 36px;
|
||||
--mdc-icon-size: 20px;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: grab;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.section-wrapper {
|
||||
padding: 8px;
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
border-start-end-radius: 0;
|
||||
border: 2px dashed var(--divider-color);
|
||||
min-height: var(--row-height);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-section-edit-mode": HuiSectionEditMode;
|
||||
}
|
||||
}
|
||||
@ -99,12 +99,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||
@item-removed=${this._cardRemoved}
|
||||
invert-swap
|
||||
>
|
||||
<div
|
||||
class="container ${classMap({
|
||||
"edit-mode": editMode,
|
||||
"import-only": this.importOnly,
|
||||
})}"
|
||||
>
|
||||
<div class="container">
|
||||
${repeat(
|
||||
cardsConfig,
|
||||
(cardConfig) => this._getKey(cardConfig),
|
||||
@ -238,19 +233,6 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.container.edit-mode {
|
||||
padding: 8px;
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
border-start-end-radius: 0;
|
||||
border: 2px dashed var(--divider-color);
|
||||
min-height: var(--row-height);
|
||||
}
|
||||
|
||||
.container.import-only {
|
||||
border: none;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
position: relative;
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import {
|
||||
mdiDelete,
|
||||
mdiDrag,
|
||||
mdiEyeOff,
|
||||
mdiPencil,
|
||||
mdiViewGridPlus,
|
||||
} from "@mdi/js";
|
||||
import { mdiEyeOff, mdiViewGridPlus } from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@ -22,28 +16,21 @@ 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";
|
||||
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 {
|
||||
addSection,
|
||||
deleteSection,
|
||||
moveCard,
|
||||
moveSection,
|
||||
} from "../editor/config-util";
|
||||
import "../components/hui-section-edit-mode";
|
||||
import { addSection, 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";
|
||||
import "./hui-view-header";
|
||||
|
||||
export const DEFAULT_MAX_COLUMNS = 4;
|
||||
|
||||
@ -205,41 +192,19 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
})}
|
||||
>
|
||||
${
|
||||
this.lovelace?.editMode
|
||||
editMode
|
||||
? html`
|
||||
<div class="section-header">
|
||||
${editMode
|
||||
? html`
|
||||
<div class="section-actions">
|
||||
<ha-svg-icon
|
||||
aria-hidden="true"
|
||||
class="handle"
|
||||
.path=${mdiDrag}
|
||||
></ha-svg-icon>
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize(
|
||||
"ui.common.edit"
|
||||
)}
|
||||
@click=${this._editSection}
|
||||
.index=${idx}
|
||||
.path=${mdiPencil}
|
||||
></ha-icon-button>
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize(
|
||||
"ui.common.delete"
|
||||
)}
|
||||
@click=${this._deleteSection}
|
||||
.index=${idx}
|
||||
.path=${mdiDelete}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
<hui-section-edit-mode
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this.lovelace}
|
||||
.index=${idx}
|
||||
.viewIndex=${this.index}
|
||||
>
|
||||
${section}
|
||||
</hui-section-edit-mode>
|
||||
`
|
||||
: nothing
|
||||
: section
|
||||
}
|
||||
${section}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -375,48 +340,6 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
this.lovelace!.saveConfig(newConfig);
|
||||
}
|
||||
|
||||
private async _editSection(ev) {
|
||||
const index = ev.currentTarget.index;
|
||||
|
||||
showEditSectionDialog(this, {
|
||||
lovelace: this.lovelace!,
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveConfig: (newConfig) => {
|
||||
this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
viewIndex: this.index!,
|
||||
sectionIndex: index,
|
||||
});
|
||||
}
|
||||
|
||||
private async _deleteSection(ev) {
|
||||
const index = ev.currentTarget.index;
|
||||
|
||||
const path = [this.index!, index] as [number, number];
|
||||
|
||||
const section = findLovelaceContainer(this.lovelace!.config, path);
|
||||
|
||||
const cardCount = "cards" in section && section.cards?.length;
|
||||
|
||||
if (cardCount) {
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.delete_section.title"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
`ui.panel.lovelace.editor.delete_section.text`
|
||||
),
|
||||
confirmText: this.hass.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
});
|
||||
|
||||
if (!confirm) return;
|
||||
}
|
||||
|
||||
const newConfig = deleteSection(this.lovelace!.config, this.index!, index);
|
||||
this.lovelace!.saveConfig(newConfig);
|
||||
}
|
||||
|
||||
private _sectionMoved(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
const { oldIndex, newIndex } = ev.detail;
|
||||
@ -486,11 +409,6 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
grid-auto-flow: row dense;
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: grab;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.create-section-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@ -574,35 +492,6 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
position: relative;
|
||||
height: 34px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.section-actions {
|
||||
position: absolute;
|
||||
height: 36px;
|
||||
bottom: -2px;
|
||||
right: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: initial;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
background: var(--secondary-background-color);
|
||||
--mdc-icon-button-size: 36px;
|
||||
--mdc-icon-size: 20px;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
.imported-cards {
|
||||
--column-span: var(--column-count);
|
||||
--row-span: 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user