Add move card to view (#2262)

* Add move card to view

* Fix style

* Fix style and tests

* last style change

* update tests
This commit is contained in:
Bram Kragten 2018-12-11 19:38:57 +01:00 committed by Paulus Schoutsen
parent e2218f1e6e
commit 2cdb542112
3 changed files with 159 additions and 2 deletions

View File

@ -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;
}
</style>
<slot></slot>
<div>
@ -60,6 +71,29 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
this.path![1] + 1
}"
></paper-icon-button>
<paper-menu-button vertical-offset="48">
<paper-icon-button
title="Move card to a different view"
icon="hass:file-replace"
?disabled="${this.lovelace!.config.views.length === 1}"
slot="dropdown-trigger"
></paper-icon-button>
<paper-listbox on-iron-select="_deselect" slot="dropdown-content">
<paper-item disabled class="header">Move card to view</paper-item>
${
this.lovelace!.config.views.map((view, index) => {
if (index === this.path![0]) {
return;
}
return html`
<paper-item @click="${this._moveCard}" .index="${index}"
>${view.title}</paper-item
>
`;
})
}
</paper-listbox>
</paper-menu-button>
<paper-icon-button
class="delete"
icon="hass:delete"
@ -93,6 +127,14 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
);
}
private _moveCard(ev: MouseEvent): void {
const lovelace = this.lovelace!;
const path = this.path!;
lovelace.saveConfig(
moveCard(lovelace.config, path, [(ev.currentTarget! as any).index])
);
}
private _deleteCard(): void {
confDeleteCard(this.lovelace!, this.path!);
}

View File

@ -121,6 +121,44 @@ export const swapCard = (
};
};
export const moveCard = (
config: LovelaceConfig,
fromPath: [number, number],
toPath: [number]
): LovelaceConfig => {
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

View File

@ -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."
);
});
});