diff --git a/src/panels/lovelace/editor/config-util.ts b/src/panels/lovelace/editor/config-util.ts index d1f834a2c8..ef05a7f5e7 100644 --- a/src/panels/lovelace/editor/config-util.ts +++ b/src/panels/lovelace/editor/config-util.ts @@ -178,6 +178,22 @@ export const replaceView = ( ), }); +export const swapView = ( + config: LovelaceConfig, + path1: number, + path2: number +): LovelaceConfig => { + const view1 = config.views[path1]; + const view2 = config.views[path2]; + + return { + ...config, + views: config.views.map((origView, index) => + index === path2 ? view1 : index === path1 ? view2 : origView + ), + }; +}; + export const deleteView = ( config: LovelaceConfig, viewIndex: number diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index fb49d9abac..37e839cc83 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -35,6 +35,8 @@ import { LovelaceConfig } from "../../data/lovelace"; import { navigate } from "../../common/navigate"; import { fireEvent } from "../../common/dom/fire_event"; import { computeNotifications } from "./common/compute-notifications"; +import { swapView } from "./editor/config-util"; + import "./components/notifications/hui-notification-drawer"; import "./components/notifications/hui-notifications-button"; import "./hui-view"; @@ -235,6 +237,17 @@ class HUIRoot extends LitElement { ${this.lovelace!.config.views.map( (view) => html` + ${this._editMode + ? html` + + ` + : ""} ${view.icon ? html` + ` : ""} @@ -314,6 +337,9 @@ class HUIRoot extends LitElement { color: var(--accent-color); padding-left: 8px; } + .edit-icon[disabled] { + color: var(--disabled-text-color); + } .edit-icon.view { display: none; } @@ -511,6 +537,22 @@ class HUIRoot extends LitElement { }); } + private _moveViewLeft() { + const lovelace = this.lovelace!; + const oldIndex = this._curView as number; + const newIndex = (this._curView as number) - 1; + this._curView = newIndex; + lovelace.saveConfig(swapView(lovelace.config, oldIndex, newIndex)); + } + + private _moveViewRight() { + const lovelace = this.lovelace!; + const oldIndex = this._curView as number; + const newIndex = (this._curView as number) + 1; + this._curView = newIndex; + lovelace.saveConfig(swapView(lovelace.config, oldIndex, newIndex)); + } + private _addView() { showEditViewDialog(this, { lovelace: this.lovelace!, diff --git a/test-mocha/panels/lovelace/editor/config-util.spec.ts b/test-mocha/panels/lovelace/editor/config-util.spec.ts index fc417e2ca1..bfba395379 100644 --- a/test-mocha/panels/lovelace/editor/config-util.spec.ts +++ b/test-mocha/panels/lovelace/editor/config-util.spec.ts @@ -3,6 +3,7 @@ import * as assert from "assert"; import { swapCard, moveCard, + swapView, } from "../../../../src/panels/lovelace/editor/config-util"; import { LovelaceConfig } from "../../../../src/data/lovelace"; @@ -129,3 +130,65 @@ describe("moveCard", () => { ); }); }); + +describe("swapView", () => { + it("swaps 2 view", () => { + const config: LovelaceConfig = { + views: [ + { + title: "view1", + cards: [], + }, + { + title: "view2", + cards: [], + }, + ], + }; + + const result = swapView(config, 1, 0); + const expected = { + views: [ + { + title: "view2", + cards: [], + }, + { + title: "view1", + cards: [], + }, + ], + }; + assert.deepEqual(expected, result); + }); + + it("swaps the same views", () => { + const config: LovelaceConfig = { + views: [ + { + title: "view1", + cards: [], + }, + { + title: "view2", + cards: [], + }, + ], + }; + + const result = swapView(config, 0, 0); + const expected = { + views: [ + { + title: "view1", + cards: [], + }, + { + title: "view2", + cards: [], + }, + ], + }; + assert.deepEqual(expected, result); + }); +});