diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts
index 53a8ee0ea9..26c0d4b707 100644
--- a/src/panels/lovelace/components/hui-card-options.ts
+++ b/src/panels/lovelace/components/hui-card-options.ts
@@ -1,6 +1,8 @@
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
import "@polymer/paper-button/paper-button";
+import "@polymer/paper-menu-button/paper-menu-button";
import "@polymer/paper-icon-button/paper-icon-button";
+import "@polymer/paper-listbox/paper-listbox";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin";
@@ -8,7 +10,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";
+import { swapCard, moveCard } from "../editor/config-util";
export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
public cardConfig?: LovelaceCardConfig;
@@ -35,10 +37,19 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
color: var(--primary-color);
font-weight: 500;
}
+ paper-icon-button {
+ color: var(--primary-text-color);
+ }
paper-icon-button.delete {
color: var(--secondary-text-color);
float: right;
}
+ paper-item.header {
+ color: var(--primary-text-color);
+ text-transform: uppercase;
+ font-weight: 500;
+ font-size: 14px;
+ }
@@ -60,6 +71,29 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
this.path![1] + 1
}"
>
+
+
+
+
+ ${
+ this.lovelace!.config.views.map((view, index) => {
+ if (index === this.path![0]) {
+ return;
+ }
+ return html`
+ ${view.title}
+ `;
+ })
+ }
+
+
{
+ if (fromPath[0] === toPath[0]) {
+ throw new Error("You can not move a card to the view it is in.");
+ }
+ const fromView = config.views[fromPath[0]];
+ const card = fromView.cards![fromPath[1]];
+
+ const newView1 = {
+ ...fromView,
+ cards: (fromView.cards || []).filter(
+ (_origConf, ind) => ind !== fromPath[1]
+ ),
+ };
+
+ const toView = config.views[toPath[0]];
+ const cards = toView.cards ? [...toView.cards, card] : [card];
+
+ const newView2 = {
+ ...toView,
+ cards,
+ };
+
+ return {
+ ...config,
+ views: config.views.map((origView, index) =>
+ index === toPath[0]
+ ? newView2
+ : index === fromPath[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
index b8a9717b21..dac981de04 100644
--- a/test-mocha/panels/lovelace/editor/config-util.spec.ts
+++ b/test-mocha/panels/lovelace/editor/config-util.spec.ts
@@ -1,6 +1,9 @@
import * as assert from "assert";
-import { swapCard } from "../../../../src/panels/lovelace/editor/config-util";
+import {
+ swapCard,
+ moveCard,
+} from "../../../../src/panels/lovelace/editor/config-util";
import { LovelaceConfig } from "../../../../src/data/lovelace";
describe("swapCard", () => {
@@ -52,3 +55,77 @@ describe("swapCard", () => {
assert.deepEqual(expected, result);
});
});
+
+describe("moveCard", () => {
+ it("move a card to an empty view", () => {
+ const config: LovelaceConfig = {
+ views: [
+ {},
+ {
+ cards: [{ type: "card1" }, { type: "card2" }],
+ },
+ ],
+ };
+
+ const result = moveCard(config, [1, 0], [0]);
+ const expected = {
+ views: [
+ {
+ cards: [{ type: "card1" }],
+ },
+ {
+ cards: [{ type: "card2" }],
+ },
+ ],
+ };
+ assert.deepEqual(expected, result);
+ });
+
+ it("move a card to different view", () => {
+ const config: LovelaceConfig = {
+ views: [
+ {
+ cards: [{ type: "v1-c1" }, { type: "v1-c2" }],
+ },
+ {
+ cards: [{ type: "v2-c1" }, { type: "v2-c2" }],
+ },
+ ],
+ };
+
+ const result = moveCard(config, [1, 0], [0]);
+ const expected = {
+ views: [
+ {
+ cards: [{ type: "v1-c1" }, { type: "v1-c2" }, { type: "v2-c1" }],
+ },
+ {
+ cards: [{ type: "v2-c2" }],
+ },
+ ],
+ };
+ assert.deepEqual(expected, result);
+ });
+
+ it("move a card to the same view", () => {
+ const config: LovelaceConfig = {
+ views: [
+ {
+ cards: [{ type: "v1-c1" }, { type: "v1-c2" }],
+ },
+ {
+ cards: [{ type: "v2-c1" }, { type: "v2-c2" }],
+ },
+ ],
+ };
+
+ const result = function() {
+ moveCard(config, [1, 0], [1]);
+ };
+ assert.throws(
+ result,
+ Error,
+ "You can not move a card to the view it is in."
+ );
+ });
+});