From a33ff7479abe6fd13bff8961af7b53a6a8c8c78f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 10 Dec 2018 09:48:59 +0100 Subject: [PATCH] Allow moving cards (#2241) --- .../lovelace/components/hui-card-options.ts | 32 +++++++++++ src/panels/lovelace/editor/config-util.ts | 32 +++++++++++ .../lovelace/editor/config-util.spec.ts | 54 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 test-mocha/panels/lovelace/editor/config-util.spec.ts diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index a82af564df..53a8ee0ea9 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -8,6 +8,7 @@ import { confDeleteCard } from "../editor/delete-card"; import { HomeAssistant } from "../../../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { Lovelace } from "../types"; +import { swapCard } from "../editor/config-util"; export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) { public cardConfig?: LovelaceCardConfig; @@ -46,6 +47,19 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) { this.localize("ui.panel.lovelace.editor.edit_card.edit") } + + `; } + private _editCard(): void { showEditCardDialog(this, { lovelace: this.lovelace!, path: this.path!, }); } + + private _cardUp(): void { + const lovelace = this.lovelace!; + const path = this.path!; + lovelace.saveConfig( + swapCard(lovelace.config, path, [path[0], path[1] - 1]) + ); + } + + private _cardDown(): void { + const lovelace = this.lovelace!; + const path = this.path!; + lovelace.saveConfig( + swapCard(lovelace.config, path, [path[0], path[1] + 1]) + ); + } + private _deleteCard(): void { confDeleteCard(this.lovelace!, this.path!); } diff --git a/src/panels/lovelace/editor/config-util.ts b/src/panels/lovelace/editor/config-util.ts index 991aec1f7c..2c87b57737 100644 --- a/src/panels/lovelace/editor/config-util.ts +++ b/src/panels/lovelace/editor/config-util.ts @@ -89,6 +89,38 @@ export const deleteCard = ( }; }; +export const swapCard = ( + config: LovelaceConfig, + path1: [number, number], + path2: [number, number] +): LovelaceConfig => { + const card1 = config.views[path1[0]].cards![path1[1]]; + const card2 = config.views[path2[0]].cards![path2[1]]; + + const origView1 = config.views[path1[0]]; + const newView1 = { + ...origView1, + cards: origView1.cards!.map((origCard, index) => + index === path1[1] ? card2 : origCard + ), + }; + + const origView2 = path1[0] === path2[0] ? newView1 : config.views[path2[0]]; + const newView2 = { + ...origView2, + cards: origView2.cards!.map((origCard, index) => + index === path2[1] ? card1 : origCard + ), + }; + + return { + ...config, + views: config.views.map((origView, index) => + index === path2[0] ? newView2 : index === path1[0] ? newView1 : origView + ), + }; +}; + export const addView = ( config: LovelaceConfig, viewConfig: LovelaceViewConfig diff --git a/test-mocha/panels/lovelace/editor/config-util.spec.ts b/test-mocha/panels/lovelace/editor/config-util.spec.ts new file mode 100644 index 0000000000..b8a9717b21 --- /dev/null +++ b/test-mocha/panels/lovelace/editor/config-util.spec.ts @@ -0,0 +1,54 @@ +import * as assert from "assert"; + +import { swapCard } from "../../../../src/panels/lovelace/editor/config-util"; +import { LovelaceConfig } from "../../../../src/data/lovelace"; + +describe("swapCard", () => { + it("swaps 2 cards in same view", () => { + const config: LovelaceConfig = { + views: [ + {}, + { + cards: [{ type: "card1" }, { type: "card2" }], + }, + ], + }; + + const result = swapCard(config, [1, 0], [1, 1]); + const expected = { + views: [ + {}, + { + cards: [{ type: "card2" }, { type: "card1" }], + }, + ], + }; + assert.deepEqual(expected, result); + }); + + it("swaps 2 cards in different views", () => { + const config: LovelaceConfig = { + views: [ + { + cards: [{ type: "v1-c1" }, { type: "v1-c2" }], + }, + { + cards: [{ type: "v2-c1" }, { type: "v2-c2" }], + }, + ], + }; + + const result = swapCard(config, [0, 0], [1, 1]); + const expected = { + views: [ + { + cards: [{ type: "v2-c2" }, { type: "v1-c2" }], + }, + { + cards: [{ type: "v2-c1" }, { type: "v1-c1" }], + }, + ], + }; + assert.deepEqual(expected, result); + }); +});