Allow to move card from other view to section view (#22399)

* Allow to move card from other view to section view

* Update src/panels/lovelace/components/hui-card-options.ts

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>

* Move to dedicated section

* Feedbacks

* Update src/translations/en.json

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>

---------

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
Paul Bottein 2024-10-28 15:43:47 +01:00 committed by GitHub
parent 9db1e52a55
commit 6c1937f247
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 9 deletions

View File

@ -28,7 +28,10 @@ import "../../../components/ha-icon-button";
import "../../../components/ha-list-item"; import "../../../components/ha-list-item";
import { LovelaceCardConfig } from "../../../data/lovelace/config/card"; import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import { saveConfig } from "../../../data/lovelace/config/types"; import { saveConfig } from "../../../data/lovelace/config/types";
import { isStrategyView } from "../../../data/lovelace/config/view"; import {
isStrategyView,
type LovelaceViewConfig,
} from "../../../data/lovelace/config/view";
import { import {
showAlertDialog, showAlertDialog,
showPromptDialog, showPromptDialog,
@ -40,12 +43,14 @@ import { computeCardSize } from "../common/compute-card-size";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { import {
addCard, addCard,
addSection,
deleteCard, deleteCard,
moveCardToContainer, moveCardToContainer,
moveCardToIndex, moveCardToIndex,
} from "../editor/config-util"; } from "../editor/config-util";
import { import {
LovelaceCardPath, LovelaceCardPath,
type LovelaceContainerPath,
findLovelaceItems, findLovelaceItems,
getLovelaceContainerPath, getLovelaceContainerPath,
parseLovelaceCardPath, parseLovelaceCardPath,
@ -53,6 +58,7 @@ import {
import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog"; import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog";
import { Lovelace, LovelaceCard } from "../types"; import { Lovelace, LovelaceCard } from "../types";
import { SECTIONS_VIEW_LAYOUT } from "../views/const"; import { SECTIONS_VIEW_LAYOUT } from "../views/const";
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
@customElement("hui-card-options") @customElement("hui-card-options")
export class HuiCardOptions extends LitElement { export class HuiCardOptions extends LitElement {
@ -353,34 +359,79 @@ export class HuiCardOptions extends LitElement {
allowDashboardChange: true, allowDashboardChange: true,
header: this.hass!.localize("ui.panel.lovelace.editor.move_card.header"), header: this.hass!.localize("ui.panel.lovelace.editor.move_card.header"),
viewSelectedCallback: async (urlPath, selectedDashConfig, viewIndex) => { viewSelectedCallback: async (urlPath, selectedDashConfig, viewIndex) => {
const view = selectedDashConfig.views[viewIndex]; const fromView = selectedDashConfig.views[this.path![0]];
let toView = selectedDashConfig.views[viewIndex];
let newConfig = selectedDashConfig;
if (!isStrategyView(view) && view.type === SECTIONS_VIEW_LAYOUT) { if (isStrategyView(toView)) {
showAlertDialog(this, { showAlertDialog(this, {
title: this.hass!.localize( title: this.hass!.localize(
"ui.panel.lovelace.editor.move_card.error_title" "ui.panel.lovelace.editor.move_card.error_title"
), ),
text: this.hass!.localize( text: this.hass!.localize(
"ui.panel.lovelace.editor.move_card.error_text_section" "ui.panel.lovelace.editor.move_card.error_text_strategy"
), ),
warning: true, warning: true,
}); });
return; return;
} }
const isSectionsView = toView.type === SECTIONS_VIEW_LAYOUT;
let toPath: LovelaceContainerPath = [viewIndex];
// If the view is a section view and has no "imported cards" section, adds a default section.
if (isSectionsView) {
const importedCardHeading = fromView.title
? this.hass!.localize(
"ui.panel.lovelace.editor.section.imported_card_section_title_view",
{ view_title: fromView.title }
)
: this.hass!.localize(
"ui.panel.lovelace.editor.section.imported_card_section_title_default"
);
let sectionIndex = toView.sections
? toView.sections.findIndex(
(s) =>
"cards" in s &&
s.cards?.some(
(c) =>
c.type === "heading" && c.heading === importedCardHeading
)
)
: -1;
if (sectionIndex === -1) {
const newSection: LovelaceSectionConfig = {
type: "grid",
cards: [
{
type: "heading",
heading: importedCardHeading,
},
],
};
newConfig = addSection(selectedDashConfig, viewIndex, newSection);
toView = newConfig.views[viewIndex] as LovelaceViewConfig;
sectionIndex = toView.sections!.length - 1;
}
toPath = [viewIndex, sectionIndex];
}
if (urlPath === this.lovelace!.urlPath) { if (urlPath === this.lovelace!.urlPath) {
this.lovelace!.saveConfig( this.lovelace!.saveConfig(
moveCardToContainer(this.lovelace!.config, this.path!, [viewIndex]) moveCardToContainer(newConfig, this.path!, toPath)
); );
showSaveSuccessToast(this, this.hass!); showSaveSuccessToast(this, this.hass!);
return; return;
} }
try { try {
const { cardIndex } = parseLovelaceCardPath(this.path!); const { cardIndex } = parseLovelaceCardPath(this.path!);
const card = this._cards[cardIndex];
await saveConfig( await saveConfig(
this.hass!, this.hass!,
urlPath, urlPath,
addCard(selectedDashConfig, [viewIndex], this._cards[cardIndex]) addCard(newConfig, toPath, card)
); );
this.lovelace!.saveConfig( this.lovelace!.saveConfig(
deleteCard(this.lovelace!.config, this.path!) deleteCard(this.lovelace!.config, this.path!)

View File

@ -5696,8 +5696,8 @@
}, },
"move_card": { "move_card": {
"header": "Choose a view to move the card to", "header": "Choose a view to move the card to",
"error_title": "Impossible to move the card", "strategy_error_title": "Impossible to move the card",
"error_text_section": "Moving a card to a section view is not supported yet. Use copy/cut/paste instead." "strategy_error_text_strategy": "Moving a card to an auto generated view is not supported."
}, },
"change_position": { "change_position": {
"title": "Change card position", "title": "Change card position",
@ -5715,7 +5715,9 @@
"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%]",
"create_section": "Create section", "create_section": "Create section",
"default_section_title": "New section" "default_section_title": "New section",
"imported_card_section_title_view": "Imported cards from ''{view_title}'' view",
"imported_card_section_title_default": "Imported cards from another view"
}, },
"delete_section": { "delete_section": {
"title": "Delete section", "title": "Delete section",