From 1599dc9e16eb0491fd6a9f045a979abb074116b8 Mon Sep 17 00:00:00 2001 From: Tomasz Date: Fri, 6 Mar 2020 12:36:34 +0100 Subject: [PATCH] Set view visibility form UI (#4978) * wip * move logic to hui-view-visibility-editor.ts * users will be always set * extra filter to remove deleted users * added better UI. I had to add   to ha-switch to avoid scrollbar * fix for comments * setting default visibility in a better way * simplified logic, addressed comments --- src/panels/lovelace/editor/types.ts | 5 + .../editor/view-editor/hui-edit-view.ts | 31 +++- .../view-editor/hui-view-visibility-editor.ts | 152 ++++++++++++++++++ src/translations/en.json | 3 +- 4 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 src/panels/lovelace/editor/view-editor/hui-view-visibility-editor.ts diff --git a/src/panels/lovelace/editor/types.ts b/src/panels/lovelace/editor/types.ts index c7228422dd..3936d22337 100644 --- a/src/panels/lovelace/editor/types.ts +++ b/src/panels/lovelace/editor/types.ts @@ -2,6 +2,7 @@ import { LovelaceCardConfig, LovelaceViewConfig, ActionConfig, + ShowViewConfig, } from "../../../data/lovelace"; import { EntityConfig } from "../entity-rows/types"; import { InputType } from "zlib"; @@ -19,6 +20,10 @@ export interface ViewEditEvent extends Event { }; } +export interface ViewVisibilityChangeEvent { + visible: ShowViewConfig[]; +} + export interface ConfigValue { format: "json" | "yaml"; value?: string | LovelaceCardConfig; diff --git a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts index ad7db50707..3387326208 100644 --- a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts @@ -22,14 +22,19 @@ import { haStyleDialog } from "../../../../resources/styles"; import "../../components/hui-entity-editor"; import "./hui-view-editor"; +import "./hui-view-visibility-editor"; import { HomeAssistant } from "../../../../types"; import { LovelaceViewConfig, LovelaceCardConfig, LovelaceBadgeConfig, } from "../../../../data/lovelace"; -import { fireEvent } from "../../../../common/dom/fire_event"; -import { EntitiesEditorEvent, ViewEditEvent } from "../types"; +import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; +import { + EntitiesEditorEvent, + ViewEditEvent, + ViewVisibilityChangeEvent, +} from "../types"; import { processEditorEntities } from "../process-editor-entities"; import { navigate } from "../../../../common/navigate"; import { Lovelace } from "../../types"; @@ -125,6 +130,15 @@ export class HuiEditView extends LitElement { > `; break; + case "tab-visibility": + content = html` + + `; + break; case "tab-cards": content = html` Cards @@ -152,6 +166,11 @@ export class HuiEditView extends LitElement { "ui.panel.lovelace.editor.edit_view.tab_badges" )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_visibility" + )} ${content}
@@ -272,6 +291,14 @@ export class HuiEditView extends LitElement { } } + private _viewVisibilityChanged( + ev: HASSDomEvent + ): void { + if (ev.detail.visible && this._config) { + this._config.visible = ev.detail.visible; + } + } + private _badgesChanged(ev: EntitiesEditorEvent): void { if (!this._badges || !this.hass || !ev.detail || !ev.detail.entities) { return; diff --git a/src/panels/lovelace/editor/view-editor/hui-view-visibility-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-visibility-editor.ts new file mode 100644 index 0000000000..82181bff94 --- /dev/null +++ b/src/panels/lovelace/editor/view-editor/hui-view-visibility-editor.ts @@ -0,0 +1,152 @@ +import { + html, + LitElement, + TemplateResult, + customElement, + property, + PropertyValues, + CSSResult, + css, +} from "lit-element"; +import "@polymer/paper-input/paper-input"; + +import { HomeAssistant } from "../../../../types"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { configElementStyle } from "../config-elements/config-elements-style"; +import { LovelaceViewConfig, ShowViewConfig } from "../../../../data/lovelace"; + +import { fetchUsers, User } from "../../../../data/user"; +import memoizeOne from "memoize-one"; +import { compare } from "../../../../common/string/compare"; +import { HaSwitch } from "../../../../components/ha-switch"; + +declare global { + interface HASSDomEvents { + "view-visibility-changed": { + visible: ShowViewConfig[]; + }; + } +} + +@customElement("hui-view-visibility-editor") +export class HuiViewVisibilityEditor extends LitElement { + set config(config: LovelaceViewConfig) { + this._config = config; + this._visible = + this._config.visible === undefined ? true : this._config.visible; + } + + @property() public hass!: HomeAssistant; + @property() public _config!: LovelaceViewConfig; + @property() private _users!: User[]; + @property() private _visible!: boolean | ShowViewConfig[]; + + private _sortedUsers = memoizeOne((users: User[]) => { + return users + .filter((user) => !user.system_generated) + .sort((a, b) => compare(a.name, b.name)); + }); + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + + fetchUsers(this.hass).then((users) => { + this._users = users; + fireEvent(this, "iron-resize"); + }); + } + + protected render(): TemplateResult { + if (!this.hass || !this._users) { + return html``; + } + + return html` + ${configElementStyle} +
+ Select which users should have access to this view + + ${this._sortedUsers(this._users).map( + (user) => html` +
+
${user.name}
+   +
+ ` + )} +
+ `; + } + + protected checkUser(userId: string): boolean { + if (this._visible === undefined) { + return true; + } + if (typeof this._visible === "boolean") { + return this._visible as boolean; + } + return (this._visible as ShowViewConfig[]).some((u) => u.user === userId); + } + + private valChange(ev: Event): void { + const userId = (ev.currentTarget as any).userId; + const checked = (ev.currentTarget as HaSwitch).checked; + + let newVisible: ShowViewConfig[] = []; + + if (typeof this._visible === "boolean") { + const lastValue = this._visible as boolean; + if (lastValue) { + newVisible = this._users.map((u) => { + return { + user: u.id, + }; + }); + } + } else { + newVisible = [...this._visible]; + } + + if (checked === true) { + const newEntry: ShowViewConfig = { + user: userId, + }; + newVisible.push(newEntry); + } else { + newVisible = (newVisible as ShowViewConfig[]).filter( + (c) => c.user !== userId + ); + } + + // this removes users that doesn't exists in system but had view permissions + this._visible = newVisible.filter((c) => + this._users.some((u) => u.id === c.user) + ); + + fireEvent(this, "view-visibility-changed", { visible: this._visible }); + } + + static get styles(): CSSResult { + return css` + .flex { + flex: 1; + margin-left: 16px; + display: flex; + justify-content: space-between; + align-items: center; + min-width: 0; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-view-visibility-editor": HuiViewVisibilityEditor; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index c739c3d6aa..f615545ed8 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1919,7 +1919,8 @@ "move_left": "Move view left", "move_right": "Move view right", "tab_settings": "Settings", - "tab_badges": "Badges" + "tab_badges": "Badges", + "tab_visibility": "Visibility" }, "edit_card": { "header": "Card Configuration",