mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 11:16:35 +00:00
Use fire-event for copy, cut and duplicate (#24486)
* Add event for duplicate * Update new events in card option and card edit mode * Add copy event
This commit is contained in:
parent
dbe5bffe22
commit
5a37087231
@ -1,4 +1,3 @@
|
||||
import "@material/mwc-button";
|
||||
import {
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
@ -8,29 +7,18 @@ import {
|
||||
mdiPencil,
|
||||
mdiPlusCircleMultipleOutline,
|
||||
} from "@mdi/js";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
import { addCard } from "../editor/config-util";
|
||||
import type { LovelaceCardPath } from "../editor/lovelace-path";
|
||||
import {
|
||||
findLovelaceContainer,
|
||||
findLovelaceItems,
|
||||
getLovelaceContainerPath,
|
||||
parseLovelaceCardPath,
|
||||
} from "../editor/lovelace-path";
|
||||
import type { Lovelace } from "../types";
|
||||
|
||||
@customElement("hui-card-edit-mode")
|
||||
@ -62,19 +50,6 @@ export class HuiCardEditMode extends LitElement {
|
||||
@state()
|
||||
public _focused = false;
|
||||
|
||||
@storage({
|
||||
key: "dashboardCardClipboard",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
storage: "sessionStorage",
|
||||
})
|
||||
protected _clipboard?: LovelaceCardConfig;
|
||||
|
||||
private get _cards() {
|
||||
const containerPath = getLovelaceContainerPath(this.path!);
|
||||
return findLovelaceItems("cards", this.lovelace!.config, containerPath)!;
|
||||
}
|
||||
|
||||
private _touchStarted = false;
|
||||
|
||||
protected firstUpdated(): void {
|
||||
@ -274,25 +249,7 @@ export class HuiCardEditMode extends LitElement {
|
||||
}
|
||||
|
||||
private _duplicateCard(): void {
|
||||
const { cardIndex, sectionIndex } = parseLovelaceCardPath(this.path!);
|
||||
const containerPath = getLovelaceContainerPath(this.path!);
|
||||
const sectionConfig =
|
||||
sectionIndex !== undefined
|
||||
? findLovelaceContainer(this.lovelace!.config, containerPath)
|
||||
: undefined;
|
||||
|
||||
const cardConfig = this._cards![cardIndex];
|
||||
|
||||
showEditCardDialog(this, {
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveCardConfig: async (config) => {
|
||||
const newConfig = addCard(this.lovelace!.config, containerPath, config);
|
||||
await this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
cardConfig,
|
||||
sectionConfig,
|
||||
isNew: true,
|
||||
});
|
||||
fireEvent(this, "ll-duplicate-card", { path: this.path! });
|
||||
}
|
||||
|
||||
private _editCard(): void {
|
||||
@ -300,14 +257,12 @@ export class HuiCardEditMode extends LitElement {
|
||||
}
|
||||
|
||||
private _cutCard(): void {
|
||||
this._copyCard();
|
||||
fireEvent(this, "ll-copy-card", { path: this.path! });
|
||||
fireEvent(this, "ll-delete-card", { path: this.path!, silent: true });
|
||||
}
|
||||
|
||||
private _copyCard(): void {
|
||||
const { cardIndex } = parseLovelaceCardPath(this.path!);
|
||||
const cardConfig = this._cards[cardIndex];
|
||||
this._clipboard = deepClone(cardConfig);
|
||||
fireEvent(this, "ll-copy-card", { path: this.path! });
|
||||
}
|
||||
|
||||
private _deleteCard(): void {
|
||||
|
@ -10,13 +10,13 @@ import {
|
||||
mdiPlus,
|
||||
mdiPlusCircleMultipleOutline,
|
||||
} from "@mdi/js";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, queryAssignedNodes } from "lit/decorators";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list-item";
|
||||
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
@ -29,7 +29,6 @@ import {
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
import {
|
||||
addCard,
|
||||
deleteCard,
|
||||
@ -267,24 +266,13 @@ export class HuiCardOptions extends LitElement {
|
||||
this._cutCard();
|
||||
break;
|
||||
case 4:
|
||||
this._deleteCard({ silent: false });
|
||||
this._deleteCard();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private _duplicateCard(): void {
|
||||
const { cardIndex } = parseLovelaceCardPath(this.path!);
|
||||
const containerPath = getLovelaceContainerPath(this.path!);
|
||||
const cardConfig = this._cards![cardIndex];
|
||||
showEditCardDialog(this, {
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveCardConfig: async (config) => {
|
||||
const newConfig = addCard(this.lovelace!.config, containerPath, config);
|
||||
await this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
cardConfig,
|
||||
isNew: true,
|
||||
});
|
||||
fireEvent(this, "ll-duplicate-card", { path: this.path! });
|
||||
}
|
||||
|
||||
private _editCard(): void {
|
||||
@ -292,14 +280,16 @@ export class HuiCardOptions extends LitElement {
|
||||
}
|
||||
|
||||
private _cutCard(): void {
|
||||
this._copyCard();
|
||||
this._deleteCard({ silent: true });
|
||||
fireEvent(this, "ll-copy-card", { path: this.path! });
|
||||
fireEvent(this, "ll-delete-card", { path: this.path!, silent: true });
|
||||
}
|
||||
|
||||
private _copyCard(): void {
|
||||
const { cardIndex } = parseLovelaceCardPath(this.path!);
|
||||
const cardConfig = this._cards[cardIndex];
|
||||
this._clipboard = deepClone(cardConfig);
|
||||
fireEvent(this, "ll-copy-card", { path: this.path! });
|
||||
}
|
||||
|
||||
private _deleteCard(): void {
|
||||
fireEvent(this, "ll-delete-card", { path: this.path!, silent: false });
|
||||
}
|
||||
|
||||
private _decreaseCardPosiion(): void {
|
||||
@ -420,10 +410,6 @@ export class HuiCardOptions extends LitElement {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _deleteCard({ silent }: { silent: boolean }): void {
|
||||
fireEvent(this, "ll-delete-card", { path: this.path!, silent });
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -7,6 +7,7 @@ import { repeat } from "lit/directives/repeat";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-ripple";
|
||||
import "../../../components/ha-sortable";
|
||||
import type { HaSortableOptions } from "../../../components/ha-sortable";
|
||||
import type { LovelaceSectionElement } from "../../../data/lovelace";
|
||||
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
|
@ -1,6 +1,8 @@
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { ReactiveElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import type { MediaQueriesListener } from "../../../common/dom/media_query";
|
||||
import "../../../components/ha-svg-icon";
|
||||
@ -21,7 +23,7 @@ import {
|
||||
import { createSectionElement } from "../create-element/create-section-element";
|
||||
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
import { replaceCard } from "../editor/config-util";
|
||||
import { addCard, replaceCard } from "../editor/config-util";
|
||||
import { performDeleteCard } from "../editor/delete-card";
|
||||
import { parseLovelaceCardPath } from "../editor/lovelace-path";
|
||||
import { generateLovelaceSectionStrategy } from "../strategies/get-strategy";
|
||||
@ -59,6 +61,14 @@ export class HuiSection extends ReactiveElement {
|
||||
|
||||
private _listeners: MediaQueriesListener[] = [];
|
||||
|
||||
@storage({
|
||||
key: "dashboardCardClipboard",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
storage: "sessionStorage",
|
||||
})
|
||||
protected _clipboard?: LovelaceCardConfig;
|
||||
|
||||
private _createCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = document.createElement("hui-card");
|
||||
element.hass = this.hass;
|
||||
@ -278,6 +288,43 @@ export class HuiSection extends ReactiveElement {
|
||||
if (!this.lovelace) return;
|
||||
performDeleteCard(this.hass, this.lovelace, ev.detail);
|
||||
});
|
||||
this._layoutElement.addEventListener("ll-duplicate-card", (ev) => {
|
||||
ev.stopPropagation();
|
||||
if (!this.lovelace) return;
|
||||
const { cardIndex } = parseLovelaceCardPath(ev.detail.path);
|
||||
const sectionConfig = this.config;
|
||||
if (isStrategySection(sectionConfig)) {
|
||||
return;
|
||||
}
|
||||
const cardConfig = sectionConfig.cards![cardIndex];
|
||||
|
||||
showEditCardDialog(this, {
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveCardConfig: async (newCardConfig) => {
|
||||
const newConfig = addCard(
|
||||
this.lovelace!.config,
|
||||
[this.viewIndex, this.index],
|
||||
newCardConfig
|
||||
);
|
||||
await this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
cardConfig,
|
||||
sectionConfig,
|
||||
isNew: true,
|
||||
});
|
||||
});
|
||||
this._layoutElement.addEventListener("ll-copy-card", (ev) => {
|
||||
ev.stopPropagation();
|
||||
if (!this.lovelace) return;
|
||||
const { cardIndex } = parseLovelaceCardPath(ev.detail.path);
|
||||
const sectionConfig = this.config;
|
||||
|
||||
if (isStrategySection(sectionConfig)) {
|
||||
return;
|
||||
}
|
||||
const cardConfig = sectionConfig.cards![cardIndex];
|
||||
this._clipboard = deepClone(cardConfig);
|
||||
});
|
||||
}
|
||||
|
||||
private _createCards(config: LovelaceSectionConfig): void {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { ReactiveElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/entity/ha-state-label-badge";
|
||||
import "../../../components/ha-svg-icon";
|
||||
@ -21,7 +23,7 @@ import { showCreateBadgeDialog } from "../editor/badge-editor/show-create-badge-
|
||||
import { showEditBadgeDialog } from "../editor/badge-editor/show-edit-badge-dialog";
|
||||
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
|
||||
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
|
||||
import { replaceCard } from "../editor/config-util";
|
||||
import { addCard, replaceCard } from "../editor/config-util";
|
||||
import {
|
||||
type DeleteBadgeParams,
|
||||
performDeleteBadge,
|
||||
@ -45,6 +47,8 @@ declare global {
|
||||
"ll-create-card": { suggested?: string[] } | undefined;
|
||||
"ll-edit-card": { path: LovelaceCardPath };
|
||||
"ll-delete-card": DeleteCardParams;
|
||||
"ll-duplicate-card": { path: LovelaceCardPath };
|
||||
"ll-copy-card": { path: LovelaceCardPath };
|
||||
"ll-create-badge": undefined;
|
||||
"ll-edit-badge": { path: LovelaceCardPath };
|
||||
"ll-delete-badge": DeleteBadgeParams;
|
||||
@ -53,6 +57,8 @@ declare global {
|
||||
"ll-create-card": HASSDomEvent<HASSDomEvents["ll-create-card"]>;
|
||||
"ll-edit-card": HASSDomEvent<HASSDomEvents["ll-edit-card"]>;
|
||||
"ll-delete-card": HASSDomEvent<HASSDomEvents["ll-delete-card"]>;
|
||||
"ll-duplicate-card": HASSDomEvent<HASSDomEvents["ll-duplicate-card"]>;
|
||||
"ll-copy-card": HASSDomEvent<HASSDomEvents["ll-copy-card"]>;
|
||||
"ll-create-badge": HASSDomEvent<HASSDomEvents["ll-create-badge"]>;
|
||||
"ll-edit-badge": HASSDomEvent<HASSDomEvents["ll-edit-badge"]>;
|
||||
"ll-delete-badge": HASSDomEvent<HASSDomEvents["ll-delete-badge"]>;
|
||||
@ -79,6 +85,14 @@ export class HUIView extends ReactiveElement {
|
||||
|
||||
private _layoutElement?: LovelaceViewElement;
|
||||
|
||||
@storage({
|
||||
key: "dashboardCardClipboard",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
storage: "sessionStorage",
|
||||
})
|
||||
protected _clipboard?: LovelaceCardConfig;
|
||||
|
||||
private _createCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = document.createElement("hui-card");
|
||||
element.hass = this.hass;
|
||||
@ -313,6 +327,37 @@ export class HUIView extends ReactiveElement {
|
||||
if (!this.lovelace) return;
|
||||
performDeleteBadge(this.hass, this.lovelace, ev.detail);
|
||||
});
|
||||
this._layoutElement.addEventListener("ll-duplicate-card", (ev) => {
|
||||
const { cardIndex } = parseLovelaceCardPath(ev.detail.path);
|
||||
const viewConfig = this.lovelace!.config.views[this.index];
|
||||
if (isStrategyView(viewConfig)) {
|
||||
return;
|
||||
}
|
||||
const cardConfig = viewConfig.cards![cardIndex];
|
||||
showEditCardDialog(this, {
|
||||
lovelaceConfig: this.lovelace!.config,
|
||||
saveCardConfig: async (newCardConfig) => {
|
||||
const newConfig = addCard(
|
||||
this.lovelace!.config,
|
||||
[this.index],
|
||||
newCardConfig
|
||||
);
|
||||
await this.lovelace!.saveConfig(newConfig);
|
||||
},
|
||||
cardConfig,
|
||||
isNew: true,
|
||||
});
|
||||
});
|
||||
this._layoutElement.addEventListener("ll-copy-card", (ev) => {
|
||||
if (!this.lovelace) return;
|
||||
const { cardIndex } = parseLovelaceCardPath(ev.detail.path);
|
||||
const viewConfig = this.lovelace!.config.views[this.index];
|
||||
if (isStrategyView(viewConfig)) {
|
||||
return;
|
||||
}
|
||||
const cardConfig = viewConfig.cards![cardIndex];
|
||||
this._clipboard = deepClone(cardConfig);
|
||||
});
|
||||
}
|
||||
|
||||
private _createBadges(config: LovelaceViewConfig): void {
|
||||
|
Loading…
x
Reference in New Issue
Block a user