From c3c6c631694072f19724b275532e56bbebe5a7b1 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 28 Jun 2023 17:14:10 +0200 Subject: [PATCH] Add move card to position on dashboard editor (#17077) * Add move card to position on dashboard editor * Feedbacks --- .../lovelace/components/hui-card-options.ts | 78 +++++++++++++------ src/panels/lovelace/editor/config-util.ts | 29 +++++++ src/translations/en.json | 6 +- 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 826759cc1e..37d5a4d27e 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -2,28 +2,37 @@ import "@material/mwc-button"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js"; +import deepClone from "deep-clone-simple"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, TemplateResult, + css, + html, + nothing, } from "lit"; import { customElement, property, queryAssignedNodes } from "lit/decorators"; -import deepClone from "deep-clone-simple"; import { storage } from "../../../common/decorators/storage"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-button-menu"; import "../../../components/ha-icon-button"; -import { saveConfig, LovelaceCardConfig } from "../../../data/lovelace"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { LovelaceCardConfig, saveConfig } from "../../../data/lovelace"; +import { + showAlertDialog, + showPromptDialog, +} from "../../../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../types"; import { showSaveSuccessToast } from "../../../util/toast-saved-success"; import { computeCardSize } from "../common/compute-card-size"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; -import { addCard, deleteCard, moveCard, swapCard } from "../editor/config-util"; +import { + addCard, + deleteCard, + moveCard, + moveCardToPosition, + swapCard, +} from "../editor/config-util"; import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog"; import { Lovelace, LovelaceCard } from "../types"; @@ -35,10 +44,10 @@ export class HuiCardOptions extends LitElement { @property() public path?: [number, number]; - @property({ type: Boolean }) public showPosition = false; - @queryAssignedNodes() private _assignedNodes?: NodeListOf; + @property({ type: Boolean }) public showPosition = false; + @storage({ key: "lovelaceClipboard", state: false, @@ -85,20 +94,14 @@ export class HuiCardOptions extends LitElement { this.path![1] + 1} > ${this.showPosition - ? html`
- ${this.path![1] + 1} - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_card.position", - "position", - `${this.path![1] + 1}`, - "total", - `${ - this.lovelace!.config.views[this.path![0]].cards!.length - }` - )} -
` + ? html` +
${this.path![1] + 1}
+
` : nothing} { + const lovelace = this.lovelace!; + const path = this.path!; + + const positionString = await showPromptDialog(this, { + title: this.hass!.localize( + "ui.panel.lovelace.editor.change_position.title" + ), + text: this.hass!.localize( + "ui.panel.lovelace.editor.change_position.text" + ), + inputType: "number", + placeholder: String(path[1] + 1), + }); + + if (!positionString) return; + + const position = parseInt(positionString); + + if (isNaN(position)) return; + + lovelace.saveConfig(moveCardToPosition(lovelace.config, path, position)); + } + private _moveCard(): void { showSelectViewDialog(this, { lovelaceConfig: this.lovelace!.config, diff --git a/src/panels/lovelace/editor/config-util.ts b/src/panels/lovelace/editor/config-util.ts index bf15aafbdc..ce8f11bfbb 100644 --- a/src/panels/lovelace/editor/config-util.ts +++ b/src/panels/lovelace/editor/config-util.ts @@ -185,6 +185,35 @@ export const swapCard = ( }; }; +export const moveCardToPosition = ( + config: LovelaceConfig, + path: [number, number], + position: number +) => { + const view = config.views[path[0]]; + + const oldIndex = path[1]; + const newIndex = Math.max(Math.min(position - 1, view.cards!.length - 1), 0); + + const newCards = [...view.cards!]; + + const card = newCards[oldIndex]; + newCards.splice(oldIndex, 1); + newCards.splice(newIndex, 0, card); + + const newView = { + ...view, + cards: newCards, + }; + + return { + ...config, + views: config.views.map((origView, index) => + index === path[0] ? newView : origView + ), + }; +}; + export const moveCard = ( config: LovelaceConfig, fromPath: [number, number], diff --git a/src/translations/en.json b/src/translations/en.json index 68dd5c721f..2f71088f55 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4479,13 +4479,17 @@ "move_down": "Move card down", "move_before": "Move card before", "move_after": "Move card after", - "position": "Card is in position {position} of {total}", + "change_position": "Change card position", "options": "More options", "search_cards": "Search cards" }, "move_card": { "header": "Choose a view to move the card to" }, + "change_position": { + "title": "Change card position", + "text": "What position do you want to move your card to?" + }, "select_view": { "header": "Choose a view", "dashboard_label": "Dashboard",