mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 16:26:43 +00:00
Change config navigation to tabs (#4630)
* Change config navigation to tabs * Update ha-menu-button.ts * Icons * update * Review comments * configSections -> object instead of array
This commit is contained in:
parent
6e624b394b
commit
1c9eab7ca0
@ -8,7 +8,7 @@ import { DEFAULT_DOMAIN_ICON } from "../const";
|
||||
const fixedIcons = {
|
||||
alert: "hass:alert",
|
||||
alexa: "hass:amazon-alexa",
|
||||
automation: "hass:playlist-play",
|
||||
automation: "hass:robot",
|
||||
calendar: "hass:calendar",
|
||||
camera: "hass:video",
|
||||
climate: "hass:thermostat",
|
||||
@ -36,8 +36,8 @@ const fixedIcons = {
|
||||
plant: "hass:flower",
|
||||
proximity: "hass:apple-safari",
|
||||
remote: "hass:remote",
|
||||
scene: "hass:google-pages",
|
||||
script: "hass:file-document",
|
||||
scene: "hass:palette",
|
||||
script: "hass:script-text",
|
||||
sensor: "hass:eye",
|
||||
simple_alarm: "hass:bell",
|
||||
sun: "hass:white-balance-sunny",
|
||||
@ -48,7 +48,7 @@ const fixedIcons = {
|
||||
water_heater: "hass:thermometer",
|
||||
weather: "hass:weather-cloudy",
|
||||
weblink: "hass:open-in-new",
|
||||
zone: "hass:map-marker",
|
||||
zone: "hass:map-marker-radius",
|
||||
};
|
||||
|
||||
export const domainIcon = (domain: string, state?: string): string => {
|
||||
|
@ -135,7 +135,7 @@ class HaMenuButton extends LitElement {
|
||||
top: 5px;
|
||||
right: 2px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--primary-color);
|
||||
border: 2px solid var(--app-header-background-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
@ -50,6 +50,11 @@ class HassLoadingScreen extends LitElement {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background-color: var(--primary-background-color);
|
||||
}
|
||||
.content {
|
||||
height: calc(100% - 64px);
|
||||
display: flex;
|
||||
|
@ -59,6 +59,7 @@ class HassSubpage extends LitElement {
|
||||
background-color: var(--app-header-background-color);
|
||||
font-weight: 400;
|
||||
color: var(--app-header-text-color, white);
|
||||
border-bottom: var(--app-header-border-bottom, none);
|
||||
}
|
||||
|
||||
ha-menu-button,
|
||||
|
239
src/layouts/hass-tabs-subpage.ts
Normal file
239
src/layouts/hass-tabs-subpage.ts
Normal file
@ -0,0 +1,239 @@
|
||||
import {
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
html,
|
||||
customElement,
|
||||
css,
|
||||
CSSResult,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import "../components/ha-menu-button";
|
||||
import "../components/ha-paper-icon-button-arrow-prev";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { Route, HomeAssistant } from "../types";
|
||||
import { navigate } from "../common/navigate";
|
||||
import "@material/mwc-ripple";
|
||||
import { isComponentLoaded } from "../common/config/is_component_loaded";
|
||||
|
||||
export interface PageNavigation {
|
||||
path: string;
|
||||
translationKey?: string;
|
||||
component?: string;
|
||||
name?: string;
|
||||
core?: boolean;
|
||||
exportOnly?: boolean;
|
||||
icon?: string;
|
||||
info?: any;
|
||||
}
|
||||
|
||||
@customElement("hass-tabs-subpage")
|
||||
class HassTabsSubpage extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property({ type: String, attribute: "back-path" }) public backPath?: string;
|
||||
@property() public backCallback?: () => void;
|
||||
@property({ type: Boolean }) public hassio = false;
|
||||
@property({ type: Boolean }) public showAdvanced = false;
|
||||
@property() public route!: Route;
|
||||
@property() public tabs!: PageNavigation[];
|
||||
@property({ type: Boolean, reflect: true }) public narrow = false;
|
||||
@property() private _activeTab: number = -1;
|
||||
|
||||
protected updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has("route")) {
|
||||
this._activeTab = this.tabs.findIndex((tab) =>
|
||||
this.route.prefix.includes(tab.path)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class="toolbar">
|
||||
<ha-paper-icon-button-arrow-prev
|
||||
aria-label="Back"
|
||||
.hassio=${this.hassio}
|
||||
@click=${this._backTapped}
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
<div id="tabbar" class=${classMap({ "bottom-bar": this.narrow })}>
|
||||
${this.tabs.map((page, index) =>
|
||||
(!page.component ||
|
||||
page.core ||
|
||||
isComponentLoaded(this.hass, page.component)) &&
|
||||
(!page.exportOnly || this.showAdvanced)
|
||||
? html`
|
||||
<div
|
||||
class="tab ${classMap({
|
||||
active: index === this._activeTab,
|
||||
})}"
|
||||
@click=${this._tabTapped}
|
||||
.path=${page.path}
|
||||
>
|
||||
${this.narrow
|
||||
? html`
|
||||
<ha-icon .icon=${page.icon}></ha-icon>
|
||||
`
|
||||
: ""}
|
||||
${!this.narrow || index === this._activeTab
|
||||
? html`
|
||||
<span class="name"
|
||||
>${page.translationKey
|
||||
? this.hass.localize(page.translationKey)
|
||||
: name}</span
|
||||
>
|
||||
`
|
||||
: ""}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</div>
|
||||
`
|
||||
: ""
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div id="toolbar-icon">
|
||||
<slot name="toolbar-icon"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _tabTapped(ev: MouseEvent): void {
|
||||
navigate(this, (ev.currentTarget as any).path, true);
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
if (this.backPath) {
|
||||
navigate(this, this.backPath);
|
||||
return;
|
||||
}
|
||||
if (this.backCallback) {
|
||||
this.backCallback();
|
||||
return;
|
||||
}
|
||||
history.back();
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background-color: var(--primary-background-color);
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
height: 64px;
|
||||
background-color: var(--sidebar-background-color);
|
||||
font-weight: 400;
|
||||
color: var(--sidebar-text-color);
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
padding: 0 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:host([narrow]) .toolbar {
|
||||
background-color: var(--primary-background-color);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#tabbar {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#tabbar.bottom-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0 16px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--sidebar-background-color);
|
||||
border-top: 1px solid var(--divider-color);
|
||||
justify-content: space-between;
|
||||
z-index: 1;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#tabbar:not(.bottom-bar) {
|
||||
margin: auto;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 0 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
#tabbar:not(.bottom-bar) .tab.active {
|
||||
border-bottom: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.bottom-bar .tab {
|
||||
padding: 0 16px;
|
||||
width: 20%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
ha-menu-button,
|
||||
ha-paper-icon-button-arrow-prev,
|
||||
::slotted([slot="toolbar-icon"]) {
|
||||
pointer-events: auto;
|
||||
color: var(--sidebar-icon-color);
|
||||
}
|
||||
|
||||
[main-title] {
|
||||
margin: 0 0 0 24px;
|
||||
line-height: 20px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 64px);
|
||||
overflow-y: auto;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
#toolbar-icon {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
:host([narrow]) .content {
|
||||
height: calc(100% - 128px);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hass-tabs-subpage": HassTabsSubpage;
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import {
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import {
|
||||
AreaRegistryEntry,
|
||||
updateAreaRegistryEntry,
|
||||
@ -20,7 +20,7 @@ import {
|
||||
} from "../../../data/area_registry";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../ha-config-section";
|
||||
import {
|
||||
@ -30,11 +30,14 @@ import {
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-areas")
|
||||
export class HaConfigAreas extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() private _areas?: AreaRegistryEntry[];
|
||||
private _unsubAreas?: UnsubscribeFunc;
|
||||
|
||||
@ -52,9 +55,12 @@ export class HaConfigAreas extends LitElement {
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<hass-subpage
|
||||
.header="${this.hass.localize("ui.panel.config.areas.caption")}"
|
||||
.showBackButton=${!this.isWide}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.persons}
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
@ -95,10 +101,11 @@ export class HaConfigAreas extends LitElement {
|
||||
: html``}
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
|
||||
<ha-fab
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title="${this.hass.localize("ui.panel.config.areas.create_area")}"
|
||||
@click=${this._createArea}
|
||||
@ -162,6 +169,10 @@ All devices in this area will become unassigned.`)
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
hass-loading-screen {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
--app-header-text-color: var(--sidebar-text-color);
|
||||
}
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
@ -189,7 +200,9 @@ All devices in this area will become unassigned.`)
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab.rtl {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import "../../../components/ha-fab";
|
||||
@ -31,15 +30,19 @@ import {
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/ha-app-layout";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import "./action/ha-automation-action";
|
||||
import "./condition/ha-automation-condition";
|
||||
import "./trigger/ha-automation-trigger";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
export class HaAutomationEditor extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public automation!: AutomationEntity;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public creatingNew?: boolean;
|
||||
@property() private _config?: AutomationConfig;
|
||||
@property() private _dirty?: boolean;
|
||||
@ -47,169 +50,159 @@ export class HaAutomationEditor extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-paper-icon-button-arrow-prev
|
||||
@click=${this._backTapped}
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
<div main-title>
|
||||
${this.automation
|
||||
? computeStateName(this.automation)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.default_name"
|
||||
)}
|
||||
</div>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.automation.picker.delete_automation"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class="content">
|
||||
${this._errors
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
slot="toolbar-icon"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.automation.picker.delete_automation"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
${this._errors
|
||||
? html`
|
||||
<div class="errors">${this._errors}</div>
|
||||
`
|
||||
: ""}
|
||||
<div
|
||||
class="${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
>
|
||||
${this._config
|
||||
? html`
|
||||
<div class="errors">${this._errors}</div>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
<div
|
||||
class="${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
>
|
||||
${this._config
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
</div>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide="${this.isWide}"
|
||||
?narrow="${this.narrow}"
|
||||
?dirty="${this._dirty}"
|
||||
icon="hass:content-save"
|
||||
.title="${this.hass.localize(
|
||||
@ -220,7 +213,7 @@ export class HaAutomationEditor extends LitElement {
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
></ha-fab>
|
||||
</ha-app-layout>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -409,7 +402,10 @@ export class HaAutomationEditor extends LitElement {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
margin-bottom: -140px;
|
||||
}
|
||||
ha-fab[dirty] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
@ -22,7 +22,7 @@ import "../ha-config-section";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import {
|
||||
AutomationEntity,
|
||||
showAutomationEditor,
|
||||
@ -32,18 +32,24 @@ import format_date_time from "../../../common/datetime/format_date_time";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { showThingtalkDialog } from "./show-dialog-thingtalk";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-automation-picker")
|
||||
class HaAutomationPicker extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public automations!: AutomationEntity[];
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.showBackButton=${!this.isWide}
|
||||
.header=${this.hass.localize("ui.panel.config.automation.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
@ -150,6 +156,7 @@ class HaAutomationPicker extends LitElement {
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.automation.picker.add_automation"
|
||||
@ -158,7 +165,7 @@ class HaAutomationPicker extends LitElement {
|
||||
@click=${this._createNew}
|
||||
></ha-fab>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -221,7 +228,9 @@ class HaAutomationPicker extends LitElement {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[rtl] {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
|
@ -33,6 +33,8 @@ class HaConfigAutomation extends PolymerElement {
|
||||
hass="[[hass]]"
|
||||
automations="[[automations]]"
|
||||
is-wide="[[isWide]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
></ha-automation-picker>
|
||||
</template>
|
||||
|
||||
@ -41,6 +43,8 @@ class HaConfigAutomation extends PolymerElement {
|
||||
hass="[[hass]]"
|
||||
automation="[[automation]]"
|
||||
is-wide="[[isWide]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
creating-new="[[_creatingNew]]"
|
||||
></ha-automation-editor>
|
||||
</template>
|
||||
@ -52,6 +56,7 @@ class HaConfigAutomation extends PolymerElement {
|
||||
hass: Object,
|
||||
route: Object,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
_routeData: Object,
|
||||
_routeMatches: Boolean,
|
||||
_creatingNew: Boolean,
|
||||
|
@ -63,10 +63,7 @@ class CloudAccount extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
<hass-subpage
|
||||
show-back-button="[[!isWide]]"
|
||||
header="[[localize('ui.panel.config.cloud.caption')]]"
|
||||
>
|
||||
<hass-subpage header="[[localize('ui.panel.config.cloud.caption')]]">
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header"
|
||||
|
@ -346,7 +346,7 @@ class CloudAlexa extends LitElement {
|
||||
}
|
||||
ha-card {
|
||||
margin: 4px;
|
||||
flex-basis: 300px;
|
||||
width: 300px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.card-content {
|
||||
|
@ -369,7 +369,7 @@ class CloudGoogleAssistant extends LitElement {
|
||||
}
|
||||
ha-card {
|
||||
margin: 4px;
|
||||
flex-basis: 300px;
|
||||
width: 300px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.card-content {
|
||||
|
@ -72,10 +72,7 @@ class CloudLogin extends LocalizeMixin(
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
</style>
|
||||
<hass-subpage
|
||||
show-back-button="[[!isWide]]"
|
||||
header="[[localize('ui.panel.config.cloud.caption')]]"
|
||||
>
|
||||
<hass-subpage header="[[localize('ui.panel.config.cloud.caption')]]">
|
||||
<div class="content">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header"
|
||||
|
@ -4,11 +4,13 @@ import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../resources/ha-style";
|
||||
|
||||
import "./ha-config-section-core";
|
||||
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
|
||||
/*
|
||||
@ -33,9 +35,13 @@ class HaConfigCore extends LocalizeMixin(PolymerElement) {
|
||||
}
|
||||
</style>
|
||||
|
||||
<hass-subpage
|
||||
header="[[localize('ui.panel.config.core.caption')]]"
|
||||
show-back-button="[[!isWide]]"
|
||||
<hass-tabs-subpage
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
back-path="/config"
|
||||
tabs="[[_computeTabs()]]"
|
||||
show-advanced="[[showAdvanced]]"
|
||||
>
|
||||
<div class$="[[computeClasses(isWide)]]">
|
||||
<ha-config-section-core
|
||||
@ -44,7 +50,7 @@ class HaConfigCore extends LocalizeMixin(PolymerElement) {
|
||||
hass="[[hass]]"
|
||||
></ha-config-section-core>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -52,10 +58,16 @@ class HaConfigCore extends LocalizeMixin(PolymerElement) {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
showAdvanced: Boolean,
|
||||
route: Object,
|
||||
};
|
||||
}
|
||||
|
||||
_computeTabs() {
|
||||
return configSections.general;
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? "content" : "content narrow";
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import "@polymer/app-layout/app-header-layout/app-header-layout";
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../resources/ha-style";
|
||||
import "../../../components/ha-paper-icon-button-arrow-prev";
|
||||
|
||||
@ -17,6 +15,8 @@ import { computeStateDomain } from "../../../common/entity/compute_state_domain"
|
||||
import { sortStatesByName } from "../../../common/entity/states_sort_by_name";
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
@ -29,19 +29,14 @@ class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
|
||||
}
|
||||
</style>
|
||||
|
||||
<app-header-layout has-scrolling-region="">
|
||||
<app-header slot="header" fixed="">
|
||||
<app-toolbar>
|
||||
<ha-paper-icon-button-arrow-prev
|
||||
hide$="[[isWide]]"
|
||||
on-click="_backTapped"
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
<div main-title="">
|
||||
[[localize('ui.panel.config.customize.caption')]]
|
||||
</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<hass-tabs-subpage
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
back-path="/config"
|
||||
tabs="[[_computeTabs()]]"
|
||||
show-advanced="[[showAdvanced]]"
|
||||
>
|
||||
<div class$="[[computeClasses(isWide)]]">
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<span slot="header">
|
||||
@ -59,7 +54,7 @@ class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
|
||||
</ha-entity-config>
|
||||
</ha-config-section>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -67,7 +62,9 @@ class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
|
||||
narrow: Boolean,
|
||||
route: Object,
|
||||
showAdvanced: Boolean,
|
||||
entities: {
|
||||
type: Array,
|
||||
computed: "computeEntities(hass)",
|
||||
@ -95,6 +92,10 @@ class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
|
||||
history.back();
|
||||
}
|
||||
|
||||
_computeTabs() {
|
||||
return configSections.general;
|
||||
}
|
||||
|
||||
computeEntities(hass) {
|
||||
return Object.keys(hass.states)
|
||||
.map((key) => hass.states[key])
|
||||
|
@ -15,7 +15,7 @@ import "../../../components/ha-menu-button";
|
||||
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { CloudStatus, CloudStatusLoggedIn } from "../../../data/cloud";
|
||||
import { CloudStatus } from "../../../data/cloud";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
@ -23,6 +23,7 @@ import "../../../components/ha-icon-next";
|
||||
|
||||
import "../ha-config-section";
|
||||
import "./ha-config-navigation";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-dashboard")
|
||||
class HaConfigDashboard extends LitElement {
|
||||
@ -41,7 +42,6 @@ class HaConfigDashboard extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
></ha-menu-button>
|
||||
<div main-title>${this.hass.localize("panel.config")}</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
@ -57,68 +57,33 @@ class HaConfigDashboard extends LitElement {
|
||||
${this.cloudStatus && isComponentLoaded(this.hass, "cloud")
|
||||
? html`
|
||||
<ha-card>
|
||||
<a href="/config/cloud" tabindex="-1">
|
||||
<paper-item>
|
||||
<paper-item-body two-line="">
|
||||
${this.hass.localize("ui.panel.config.cloud.caption")}
|
||||
${this.cloudStatus.logged_in
|
||||
? html`
|
||||
<div secondary="">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.description_login",
|
||||
"email",
|
||||
(this.cloudStatus as CloudStatusLoggedIn)
|
||||
.email
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<div secondary="">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.description_features"
|
||||
)}
|
||||
</div>
|
||||
`}
|
||||
</paper-item-body>
|
||||
<ha-icon-next></ha-icon-next>
|
||||
</paper-item>
|
||||
</a>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${[
|
||||
{
|
||||
component: "cloud",
|
||||
path: "/config/cloud",
|
||||
translationKey: "ui.panel.config.cloud.caption",
|
||||
info: this.cloudStatus,
|
||||
icon: "hass:cloud-lock",
|
||||
},
|
||||
]}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${[
|
||||
{ page: "integrations", core: true },
|
||||
{ page: "devices", core: true },
|
||||
{ page: "entities", core: true },
|
||||
{ page: "automation" },
|
||||
{ page: "script" },
|
||||
{ page: "scene" },
|
||||
]}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
<ha-card>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${[
|
||||
{ page: "core", core: true },
|
||||
{ page: "server_control", core: true },
|
||||
{ page: "areas", core: true },
|
||||
{ page: "zone" },
|
||||
{ page: "person" },
|
||||
{ page: "users", core: true },
|
||||
{ page: "zha" },
|
||||
{ page: "zwave" },
|
||||
{ page: "customize", core: true, advanced: true },
|
||||
]}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
|
||||
${Object.values(configSections).map(
|
||||
(section) => html`
|
||||
<ha-card>
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.showAdvanced=${this.showAdvanced}
|
||||
.pages=${section}
|
||||
></ha-config-navigation>
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
${!this.showAdvanced
|
||||
? html`
|
||||
<div class="promo-advanced">
|
||||
@ -142,9 +107,15 @@ class HaConfigDashboard extends LitElement {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
app-header {
|
||||
--app-header-background-color: var(--primary-background-color);
|
||||
}
|
||||
ha-config-navigation:last-child {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
ha-config-section {
|
||||
margin-top: -20px;
|
||||
}
|
||||
ha-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import "@polymer/iron-icon/iron-icon";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
|
||||
@ -17,70 +17,65 @@ import {
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { CloudStatus, CloudStatusLoggedIn } from "../../../data/cloud";
|
||||
|
||||
export interface ConfigPageNavigation {
|
||||
page: string;
|
||||
core?: boolean;
|
||||
advanced?: boolean;
|
||||
info?: any;
|
||||
}
|
||||
import { PageNavigation } from "../../../layouts/hass-tabs-subpage";
|
||||
|
||||
@customElement("ha-config-navigation")
|
||||
class HaConfigNavigation extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public showAdvanced!: boolean;
|
||||
@property() public pages!: ConfigPageNavigation[];
|
||||
@property() public curPage!: string;
|
||||
@property() public pages!: PageNavigation[];
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<paper-listbox attr-for-selected="data-page" .selected=${this.curPage}>
|
||||
${this.pages.map(({ page, core, advanced, info }) =>
|
||||
(core || isComponentLoaded(this.hass, page)) &&
|
||||
(!advanced || this.showAdvanced)
|
||||
? html`
|
||||
<a
|
||||
href=${`/config/${page}`}
|
||||
aria-role="option"
|
||||
data-page="${page}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<paper-item>
|
||||
<paper-item-body two-line>
|
||||
${this.hass.localize(`ui.panel.config.${page}.caption`)}
|
||||
${page === "cloud" && (info as CloudStatus)
|
||||
? info.logged_in
|
||||
? html`
|
||||
<div secondary>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.description_login",
|
||||
"email",
|
||||
(info as CloudStatusLoggedIn).email
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<div secondary>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.description_features"
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
${this.pages.map((page) =>
|
||||
(!page.component ||
|
||||
page.core ||
|
||||
isComponentLoaded(this.hass, page.component)) &&
|
||||
(!page.exportOnly || this.showAdvanced)
|
||||
? html`
|
||||
<a
|
||||
href=${`/config/${page.component}`}
|
||||
aria-role="option"
|
||||
tabindex="-1"
|
||||
>
|
||||
<paper-icon-item>
|
||||
<ha-icon .icon=${page.icon} slot="item-icon"></ha-icon>
|
||||
<paper-item-body two-line>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.${page.component}.caption`
|
||||
)}
|
||||
${page.component === "cloud" && (page.info as CloudStatus)
|
||||
? page.info.logged_in
|
||||
? html`
|
||||
<div secondary>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.description_login",
|
||||
"email",
|
||||
(page.info as CloudStatusLoggedIn).email
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<div secondary>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.${page}.description`
|
||||
"ui.panel.config.cloud.description_features"
|
||||
)}
|
||||
</div>
|
||||
`}
|
||||
</paper-item-body>
|
||||
<ha-icon-next></ha-icon-next>
|
||||
</paper-item>
|
||||
</a>
|
||||
`
|
||||
: ""
|
||||
)}
|
||||
</paper-listbox>
|
||||
`
|
||||
: html`
|
||||
<div secondary>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.${page.component}.description`
|
||||
)}
|
||||
</div>
|
||||
`}
|
||||
</paper-item-body>
|
||||
<ha-icon-next></ha-icon-next>
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
`
|
||||
: ""
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
@ -93,6 +88,10 @@ class HaConfigNavigation extends LitElement {
|
||||
display: block;
|
||||
outline: 0;
|
||||
}
|
||||
ha-icon,
|
||||
ha-icon-next {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.iron-selected paper-item::before,
|
||||
a:not(.iron-selected):focus::before {
|
||||
position: absolute;
|
||||
@ -105,10 +104,6 @@ class HaConfigNavigation extends LitElement {
|
||||
transition: opacity 15ms linear;
|
||||
will-change: opacity;
|
||||
}
|
||||
.iron-selected paper-item::before {
|
||||
background-color: var(--sidebar-selected-icon-color);
|
||||
opacity: 0.12;
|
||||
}
|
||||
a:not(.iron-selected):focus::before {
|
||||
background-color: currentColor;
|
||||
opacity: var(--dark-divider-opacity);
|
||||
@ -117,12 +112,6 @@ class HaConfigNavigation extends LitElement {
|
||||
.iron-selected:focus paper-item::before {
|
||||
opacity: 0.2;
|
||||
}
|
||||
.iron-selected paper-item[pressed]::before {
|
||||
opacity: 0.37;
|
||||
}
|
||||
paper-listbox {
|
||||
padding: 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
|
||||
import memoizeOne from "memoize-one";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../layouts/hass-error-screen";
|
||||
import "../ha-config-section";
|
||||
|
||||
@ -18,7 +18,7 @@ import "./device-detail/ha-device-triggers-card";
|
||||
import "./device-detail/ha-device-conditions-card";
|
||||
import "./device-detail/ha-device-actions-card";
|
||||
import "./device-detail/ha-device-entities-card";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
@ -45,6 +45,7 @@ import {
|
||||
import { compare } from "../../../common/string/compare";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { createValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
|
||||
stateName?: string;
|
||||
@ -60,6 +61,7 @@ export class HaConfigDevicePage extends LitElement {
|
||||
@property() public deviceId!: string;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public showAdvanced!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() private _triggers: DeviceTrigger[] = [];
|
||||
@property() private _conditions: DeviceCondition[] = [];
|
||||
@property() private _actions: DeviceAction[] = [];
|
||||
@ -133,7 +135,12 @@ export class HaConfigDevicePage extends LitElement {
|
||||
const entities = this._entities(this.deviceId, this.entities);
|
||||
|
||||
return html`
|
||||
<hass-subpage .header=${device.name_by_user || device.name}>
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.tabs=${configSections.integrations}
|
||||
.route=${this.route}
|
||||
>
|
||||
<paper-icon-button
|
||||
slot="toolbar-icon"
|
||||
icon="hass:settings"
|
||||
@ -201,7 +208,7 @@ export class HaConfigDevicePage extends LitElement {
|
||||
`
|
||||
: html``}
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "./ha-devices-data-table";
|
||||
|
||||
import {
|
||||
@ -10,11 +10,12 @@ import {
|
||||
CSSResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
import { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-devices-dashboard")
|
||||
export class HaConfigDeviceDashboard extends LitElement {
|
||||
@ -26,12 +27,16 @@ export class HaConfigDeviceDashboard extends LitElement {
|
||||
@property() public entities!: EntityRegistryEntry[];
|
||||
@property() public areas!: AreaRegistryEntry[];
|
||||
@property() public domain!: string;
|
||||
@property() public route!: Route;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.showBackButton=${!this.isWide}
|
||||
.header=${this.hass.localize("ui.panel.config.devices.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.tabs=${configSections.integrations}
|
||||
.route=${this.route}
|
||||
>
|
||||
<div class="content">
|
||||
<ha-devices-data-table
|
||||
@ -44,7 +49,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
||||
.domain=${this.domain}
|
||||
></ha-devices-data-table>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ class HaConfigDevices extends HassRouterPage {
|
||||
pageEl.narrow = this.narrow;
|
||||
pageEl.isWide = this.isWide;
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
pageEl.route = this.routeTail;
|
||||
}
|
||||
|
||||
private _loadData() {
|
||||
|
@ -1,32 +1,29 @@
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
css,
|
||||
CSSResult,
|
||||
TemplateResult,
|
||||
property,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
|
||||
import "../../../components/ha-switch";
|
||||
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
// tslint:disable-next-line: no-duplicate-imports
|
||||
import { HaSwitch } from "../../../components/ha-switch";
|
||||
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/ha-switch";
|
||||
// tslint:disable-next-line: no-duplicate-imports
|
||||
import { HaSwitch } from "../../../components/ha-switch";
|
||||
import {
|
||||
updateEntityRegistryEntry,
|
||||
removeEntityRegistryEntry,
|
||||
EntityRegistryEntry,
|
||||
removeEntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
@customElement("entity-registry-settings")
|
||||
export class EntityRegistrySettings extends LitElement {
|
||||
|
@ -1,59 +1,59 @@
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
css,
|
||||
CSSResult,
|
||||
property,
|
||||
query,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
|
||||
import "@polymer/paper-checkbox/paper-checkbox";
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
computeEntityRegistryName,
|
||||
subscribeEntityRegistry,
|
||||
removeEntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-icon";
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import memoize from "memoize-one";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import {
|
||||
showEntityRegistryDetailDialog,
|
||||
loadEntityRegistryDetailDialog,
|
||||
} from "./show-dialog-entity-registry-detail";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import memoize from "memoize-one";
|
||||
import "../../../components/data-table/ha-data-table";
|
||||
// tslint:disable-next-line
|
||||
import {
|
||||
DataTableColumnContainer,
|
||||
DataTableColumnData,
|
||||
HaDataTable,
|
||||
RowClickedEvent,
|
||||
SelectionChangedEvent,
|
||||
HaDataTable,
|
||||
DataTableColumnData,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-icon";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
EntityRegistryEntry,
|
||||
removeEntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { DialogEntityRegistryDetail } from "./dialog-entity-registry-detail";
|
||||
import {
|
||||
loadEntityRegistryDetailDialog,
|
||||
showEntityRegistryDetailDialog,
|
||||
} from "./show-dialog-entity-registry-detail";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-entities")
|
||||
export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() private _entities?: EntityRegistryEntry[];
|
||||
@property() private _showDisabled = false;
|
||||
@property() private _showUnavailable = true;
|
||||
@ -224,9 +224,12 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<hass-subpage
|
||||
.header="${this.hass.localize("ui.panel.config.entities.caption")}"
|
||||
.showBackButton=${!this.isWide}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.integrations}
|
||||
>
|
||||
<div class="content">
|
||||
<div class="intro">
|
||||
@ -367,7 +370,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
</div>
|
||||
</ha-data-table>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -490,6 +493,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
hass-loading-screen {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
--app-header-text-color: var(--sidebar-text-color);
|
||||
}
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
@ -1,177 +0,0 @@
|
||||
import { property, customElement } from "lit-element";
|
||||
import "../../layouts/hass-loading-screen";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { CloudStatus } from "../../data/cloud";
|
||||
import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
|
||||
import { PolymerElement } from "@polymer/polymer";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"ha-refresh-cloud-status": undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("ha-config-router")
|
||||
class HaConfigRouter extends HassRouterPage {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public wideSidebar: boolean = false;
|
||||
@property() public wide: boolean = false;
|
||||
@property() public isWide: boolean = false;
|
||||
@property() public showAdvanced: boolean = false;
|
||||
@property() public cloudStatus?: CloudStatus;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "dashboard",
|
||||
cacheAll: true,
|
||||
preloadAll: true,
|
||||
routes: {
|
||||
areas: {
|
||||
tag: "ha-config-areas",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-areas" */ "./areas/ha-config-areas"
|
||||
),
|
||||
},
|
||||
automation: {
|
||||
tag: "ha-config-automation",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-automation" */ "./automation/ha-config-automation"
|
||||
),
|
||||
},
|
||||
cloud: {
|
||||
tag: "ha-config-cloud",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-cloud" */ "./cloud/ha-config-cloud"
|
||||
),
|
||||
},
|
||||
core: {
|
||||
tag: "ha-config-core",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-core" */ "./core/ha-config-core"
|
||||
),
|
||||
},
|
||||
devices: {
|
||||
tag: "ha-config-devices",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-devices" */ "./devices/ha-config-devices"
|
||||
),
|
||||
},
|
||||
server_control: {
|
||||
tag: "ha-config-server-control",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-server-control" */ "./server_control/ha-config-server-control"
|
||||
),
|
||||
},
|
||||
customize: {
|
||||
tag: "ha-config-customize",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-customize" */ "./customize/ha-config-customize"
|
||||
),
|
||||
},
|
||||
dashboard: {
|
||||
tag: "ha-config-dashboard",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-dashboard" */ "./dashboard/ha-config-dashboard"
|
||||
),
|
||||
},
|
||||
entities: {
|
||||
tag: "ha-config-entities",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-entities" */ "./entities/ha-config-entities"
|
||||
),
|
||||
},
|
||||
integrations: {
|
||||
tag: "ha-config-integrations",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-integrations" */ "./integrations/ha-config-integrations"
|
||||
),
|
||||
},
|
||||
person: {
|
||||
tag: "ha-config-person",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-person" */ "./person/ha-config-person"
|
||||
),
|
||||
},
|
||||
script: {
|
||||
tag: "ha-config-script",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-script" */ "./script/ha-config-script"
|
||||
),
|
||||
},
|
||||
scene: {
|
||||
tag: "ha-config-scene",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-scene" */ "./scene/ha-config-scene"
|
||||
),
|
||||
},
|
||||
users: {
|
||||
tag: "ha-config-users",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-users" */ "./users/ha-config-users"
|
||||
),
|
||||
},
|
||||
zone: {
|
||||
tag: "ha-config-zone",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zone" */ "./zone/ha-config-zone"
|
||||
),
|
||||
},
|
||||
zha: {
|
||||
tag: "zha-config-dashboard-router",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zha" */ "./zha/zha-config-dashboard-router"
|
||||
),
|
||||
},
|
||||
zwave: {
|
||||
tag: "ha-config-zwave",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zwave" */ "./zwave/ha-config-zwave"
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
protected updatePageEl(el) {
|
||||
if ("setProperties" in el) {
|
||||
// As long as we have Polymer panels
|
||||
(el as PolymerElement).setProperties({
|
||||
route: this.routeTail,
|
||||
hass: this.hass,
|
||||
showAdvanced: this.showAdvanced,
|
||||
isWide: this.isWide,
|
||||
narrow: this.narrow,
|
||||
cloudStatus: this.cloudStatus,
|
||||
});
|
||||
} else {
|
||||
el.route = this.routeTail;
|
||||
el.hass = this.hass;
|
||||
el.showAdvanced = this.showAdvanced;
|
||||
el.isWide = this.isWide;
|
||||
el.narrow = this.narrow;
|
||||
el.cloudStatus = this.cloudStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-config-router": HaConfigRouter;
|
||||
}
|
||||
}
|
@ -1,18 +1,59 @@
|
||||
import { customElement } from "lit-element";
|
||||
import { customElement, LitElement, html, css, property } from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
|
||||
@customElement("ha-config-section")
|
||||
export class HaConfigSection extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: "open" });
|
||||
this.shadowRoot!.innerHTML = `
|
||||
<style>
|
||||
export class HaConfigSection extends LitElement {
|
||||
@property() public isWide: boolean = false;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<div
|
||||
class="content ${classMap({
|
||||
narrow: !this.isWide,
|
||||
})}"
|
||||
>
|
||||
<div class="header"><slot name="header"></slot></div>
|
||||
<div
|
||||
class="together layout ${classMap({
|
||||
narrow: !this.isWide,
|
||||
vertical: !this.isWide,
|
||||
horizontal: this.isWide,
|
||||
})}"
|
||||
>
|
||||
<div class="intro"><slot name="introduction"></slot></div>
|
||||
<div class="panel flex-auto"><slot></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.content {
|
||||
padding: 28px 20px 0;
|
||||
max-width: 640px;
|
||||
max-width: 1040px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.layout {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.horizontal {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-auto {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family: var(--paper-font-headline_-_font-family);
|
||||
-webkit-font-smoothing: var(
|
||||
@ -26,7 +67,7 @@ export class HaConfigSection extends HTMLElement {
|
||||
}
|
||||
|
||||
.together {
|
||||
margin-top: 20px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
@ -37,8 +78,8 @@ export class HaConfigSection extends HTMLElement {
|
||||
font-weight: var(--paper-font-subhead_-_font-weight);
|
||||
line-height: var(--paper-font-subhead_-_line-height);
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
max-width: 400px;
|
||||
margin-right: 40px;
|
||||
opacity: var(--dark-primary-opacity);
|
||||
font-size: 14px;
|
||||
padding-bottom: 20px;
|
||||
@ -52,14 +93,18 @@ export class HaConfigSection extends HTMLElement {
|
||||
margin-top: 24px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<div class="content">
|
||||
<div class="header"><slot name="header"></slot></div>
|
||||
<div class="together">
|
||||
<div class="intro"><slot name="introduction"></slot></div>
|
||||
<div class="panel"><slot></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
.narrow.content {
|
||||
max-width: 640px;
|
||||
}
|
||||
.narrow .together {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.narrow .intro {
|
||||
padding-bottom: 20px;
|
||||
margin-right: 0;
|
||||
max-width: 500px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,4 @@
|
||||
import {
|
||||
property,
|
||||
PropertyValues,
|
||||
customElement,
|
||||
LitElement,
|
||||
html,
|
||||
CSSResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { property, PropertyValues, customElement } from "lit-element";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "../../layouts/hass-loading-screen";
|
||||
@ -18,9 +10,9 @@ import {
|
||||
getOptimisticFrontendUserDataCollection,
|
||||
CoreFrontendUserData,
|
||||
} from "../../data/frontend";
|
||||
import "./ha-config-router";
|
||||
import "./dashboard/ha-config-navigation";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
|
||||
import { PolymerElement } from "@polymer/polymer";
|
||||
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
@ -29,14 +21,252 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
const NO_SIDEBAR_PAGES = ["zone"];
|
||||
export const configSections: { [name: string]: PageNavigation[] } = {
|
||||
integrations: [
|
||||
{
|
||||
component: "integrations",
|
||||
path: "/config/integrations",
|
||||
translationKey: "ui.panel.config.integrations.caption",
|
||||
icon: "hass:puzzle",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "devices",
|
||||
path: "/config/devices",
|
||||
translationKey: "ui.panel.config.devices.caption",
|
||||
icon: "hass:devices",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "entities",
|
||||
path: "/config/entities",
|
||||
translationKey: "ui.panel.config.entities.caption",
|
||||
icon: "hass:shape",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "areas",
|
||||
path: "/config/areas",
|
||||
translationKey: "ui.panel.config.areas.caption",
|
||||
icon: "hass:sofa",
|
||||
core: true,
|
||||
},
|
||||
],
|
||||
automation: [
|
||||
{
|
||||
component: "automation",
|
||||
path: "/config/automation",
|
||||
translationKey: "ui.panel.config.automation.caption",
|
||||
icon: "hass:robot",
|
||||
},
|
||||
{
|
||||
component: "scene",
|
||||
path: "/config/scene",
|
||||
translationKey: "ui.panel.config.scene.caption",
|
||||
icon: "hass:palette",
|
||||
},
|
||||
{
|
||||
component: "script",
|
||||
path: "/config/script",
|
||||
translationKey: "ui.panel.config.script.caption",
|
||||
icon: "hass:script-text",
|
||||
},
|
||||
],
|
||||
persons: [
|
||||
{
|
||||
component: "person",
|
||||
path: "/config/person",
|
||||
translationKey: "ui.panel.config.person.caption",
|
||||
icon: "hass:account",
|
||||
},
|
||||
{
|
||||
component: "zone",
|
||||
path: "/config/zone",
|
||||
translationKey: "ui.panel.config.zone.caption",
|
||||
icon: "hass:map-marker-radius",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "users",
|
||||
path: "/config/users",
|
||||
translationKey: "ui.panel.config.users.caption",
|
||||
icon: "hass:account-badge-horizontal",
|
||||
core: true,
|
||||
},
|
||||
],
|
||||
general: [
|
||||
{
|
||||
component: "core",
|
||||
path: "/config/core",
|
||||
translationKey: "ui.panel.config.core.caption",
|
||||
icon: "hass:home-assistant",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "server_control",
|
||||
path: "/config/server_control",
|
||||
translationKey: "ui.panel.config.server_control.caption",
|
||||
icon: "hass:server",
|
||||
core: true,
|
||||
},
|
||||
{
|
||||
component: "customize",
|
||||
path: "/config/customize",
|
||||
translationKey: "ui.panel.config.customize.caption",
|
||||
icon: "hass:pencil",
|
||||
core: true,
|
||||
exportOnly: true,
|
||||
},
|
||||
],
|
||||
other: [
|
||||
{
|
||||
component: "zha",
|
||||
path: "/config/zha",
|
||||
translationKey: "ui.panel.config.zha.caption",
|
||||
icon: "hass:zigbee",
|
||||
},
|
||||
{
|
||||
component: "zwave",
|
||||
path: "/config/zwave",
|
||||
translationKey: "ui.panel.config.zwave.caption",
|
||||
icon: "hass:z-wave",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@customElement("ha-panel-config")
|
||||
class HaPanelConfig extends LitElement {
|
||||
class HaPanelConfig extends HassRouterPage {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "dashboard",
|
||||
cacheAll: true,
|
||||
preloadAll: true,
|
||||
routes: {
|
||||
areas: {
|
||||
tag: "ha-config-areas",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-areas" */ "./areas/ha-config-areas"
|
||||
),
|
||||
},
|
||||
automation: {
|
||||
tag: "ha-config-automation",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-automation" */ "./automation/ha-config-automation"
|
||||
),
|
||||
},
|
||||
cloud: {
|
||||
tag: "ha-config-cloud",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-cloud" */ "./cloud/ha-config-cloud"
|
||||
),
|
||||
},
|
||||
core: {
|
||||
tag: "ha-config-core",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-core" */ "./core/ha-config-core"
|
||||
),
|
||||
},
|
||||
devices: {
|
||||
tag: "ha-config-devices",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-devices" */ "./devices/ha-config-devices"
|
||||
),
|
||||
},
|
||||
server_control: {
|
||||
tag: "ha-config-server-control",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-server-control" */ "./server_control/ha-config-server-control"
|
||||
),
|
||||
},
|
||||
customize: {
|
||||
tag: "ha-config-customize",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-customize" */ "./customize/ha-config-customize"
|
||||
),
|
||||
},
|
||||
dashboard: {
|
||||
tag: "ha-config-dashboard",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-dashboard" */ "./dashboard/ha-config-dashboard"
|
||||
),
|
||||
},
|
||||
entities: {
|
||||
tag: "ha-config-entities",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-entities" */ "./entities/ha-config-entities"
|
||||
),
|
||||
},
|
||||
integrations: {
|
||||
tag: "ha-config-integrations",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-integrations" */ "./integrations/ha-config-integrations"
|
||||
),
|
||||
},
|
||||
person: {
|
||||
tag: "ha-config-person",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-person" */ "./person/ha-config-person"
|
||||
),
|
||||
},
|
||||
script: {
|
||||
tag: "ha-config-script",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-script" */ "./script/ha-config-script"
|
||||
),
|
||||
},
|
||||
scene: {
|
||||
tag: "ha-config-scene",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-scene" */ "./scene/ha-config-scene"
|
||||
),
|
||||
},
|
||||
users: {
|
||||
tag: "ha-config-users",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-users" */ "./users/ha-config-users"
|
||||
),
|
||||
},
|
||||
zone: {
|
||||
tag: "ha-config-zone",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zone" */ "./zone/ha-config-zone"
|
||||
),
|
||||
},
|
||||
zha: {
|
||||
tag: "zha-config-dashboard-router",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zha" */ "./zha/zha-config-dashboard-router"
|
||||
),
|
||||
},
|
||||
zwave: {
|
||||
tag: "ha-config-zwave",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-zwave" */ "./zwave/ha-config-zwave"
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@property() private _wideSidebar: boolean = false;
|
||||
@property() private _wide: boolean = false;
|
||||
@property() private _coreUserData?: CoreFrontendUserData;
|
||||
@ -85,64 +315,42 @@ class HaPanelConfig extends LitElement {
|
||||
this.addEventListener("ha-refresh-cloud-status", () =>
|
||||
this._updateCloudStatus()
|
||||
);
|
||||
this.style.setProperty(
|
||||
"--app-header-background-color",
|
||||
"var(--sidebar-background-color)"
|
||||
);
|
||||
this.style.setProperty(
|
||||
"--app-header-text-color",
|
||||
"var(--sidebar-text-color)"
|
||||
);
|
||||
this.style.setProperty(
|
||||
"--app-header-border-bottom",
|
||||
"1px solid var(--divider-color)"
|
||||
);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const dividerPos = this.route.path.indexOf("/", 1);
|
||||
const curPage =
|
||||
dividerPos === -1
|
||||
? this.route.path.substr(1)
|
||||
: this.route.path.substr(1, dividerPos - 1);
|
||||
|
||||
protected updatePageEl(el) {
|
||||
const isWide =
|
||||
this.hass.dockedSidebar === "docked" ? this._wideSidebar : this._wide;
|
||||
|
||||
const showSidebar = isWide && !NO_SIDEBAR_PAGES.includes(curPage);
|
||||
return html`
|
||||
${showSidebar
|
||||
? html`
|
||||
<div class="side-bar">
|
||||
<div class="toolbar">Configuration</div>
|
||||
<div class="navigation">
|
||||
<ha-config-navigation
|
||||
.hass=${this.hass}
|
||||
.showAdvanced=${this._showAdvanced}
|
||||
.curPage=${curPage}
|
||||
.pages=${[
|
||||
{ page: "cloud", info: this._cloudStatus },
|
||||
{ page: "integrations", core: true },
|
||||
{ page: "devices", core: true },
|
||||
{ page: "entities", core: true },
|
||||
{ page: "automation" },
|
||||
{ page: "script" },
|
||||
{ page: "scene" },
|
||||
{ page: "core", core: true },
|
||||
{ page: "areas", core: true },
|
||||
{ page: "zone" },
|
||||
{ page: "person" },
|
||||
{ page: "users", core: true },
|
||||
{ page: "server_control", core: true },
|
||||
{ page: "zha" },
|
||||
{ page: "zwave" },
|
||||
{ page: "customize", core: true, advanced: true },
|
||||
]}
|
||||
></ha-config-navigation>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
<ha-config-router
|
||||
.hass=${this.hass}
|
||||
.route=${this.route}
|
||||
.narrow=${this.narrow}
|
||||
.isWide=${isWide}
|
||||
.wide=${this._wide}
|
||||
.wideSidebar=${this._wideSidebar}
|
||||
.showAdvanced=${this._showAdvanced}
|
||||
.cloudStatus=${this._cloudStatus}
|
||||
class=${classMap({ "wide-config": showSidebar })}
|
||||
></ha-config-router>
|
||||
`;
|
||||
if ("setProperties" in el) {
|
||||
// As long as we have Polymer panels
|
||||
(el as PolymerElement).setProperties({
|
||||
route: this.routeTail,
|
||||
hass: this.hass,
|
||||
showAdvanced: this._showAdvanced,
|
||||
isWide,
|
||||
narrow: this.narrow,
|
||||
cloudStatus: this._cloudStatus,
|
||||
});
|
||||
} else {
|
||||
el.route = this.routeTail;
|
||||
el.hass = this.hass;
|
||||
el.showAdvanced = this._showAdvanced;
|
||||
el.isWide = isWide;
|
||||
el.narrow = this.narrow;
|
||||
el.cloudStatus = this._cloudStatus;
|
||||
}
|
||||
}
|
||||
|
||||
private async _updateCloudStatus() {
|
||||
@ -152,54 +360,6 @@ class HaPanelConfig extends LitElement {
|
||||
setTimeout(() => this._updateCloudStatus(), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background-color: var(--primary-background-color);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
.side-bar {
|
||||
border-right: 1px solid var(--divider-color);
|
||||
background: white;
|
||||
width: 320px;
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
height: 64px;
|
||||
padding: 0 16px 0 16px;
|
||||
pointer-events: none;
|
||||
background-color: var(--primary-background-color);
|
||||
font-weight: 400;
|
||||
color: var(--primary-text-color);
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
.wide-config {
|
||||
float: right;
|
||||
width: calc(100% - 320px);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
height: calc(100vh - 64px);
|
||||
overflow: auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -12,7 +12,7 @@ import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/entity/ha-state-icon";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../resources/ha-style";
|
||||
import "../../../components/ha-icon";
|
||||
|
||||
@ -38,18 +38,21 @@ import {
|
||||
css,
|
||||
CSSResult,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { ConfigEntry, deleteConfigEntry } from "../../../data/config_entries";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { DataEntryFlowProgress } from "../../../data/data_entry_flow";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-entries-dashboard")
|
||||
export class HaConfigManagerDashboard extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public showAdvanced!: boolean;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
|
||||
@property() private configEntries!: ConfigEntry[];
|
||||
|
||||
@ -72,9 +75,12 @@ export class HaConfigManagerDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.showBackButton=${!this.isWide}
|
||||
.header=${this.hass.localize("ui.panel.config.integrations.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.integrations}
|
||||
>
|
||||
<paper-menu-button
|
||||
close-on-activate
|
||||
@ -247,8 +253,9 @@ export class HaConfigManagerDashboard extends LitElement {
|
||||
title=${this.hass.localize("ui.panel.config.integrations.new")}
|
||||
@click=${this._createFlow}
|
||||
?rtl=${computeRTL(this.hass!)}
|
||||
?narrow=${this.narrow}
|
||||
></ha-fab>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -361,7 +368,9 @@ export class HaConfigManagerDashboard extends LitElement {
|
||||
right: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[rtl] {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
|
@ -104,7 +104,7 @@ class HaConfigIntegrations extends HassRouterPage {
|
||||
pageEl.narrow = this.narrow;
|
||||
pageEl.isWide = this.isWide;
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
|
||||
pageEl.route = this.routeTail;
|
||||
if (this._currentPage === "dashboard") {
|
||||
pageEl.configEntriesInProgress = this._configEntriesInProgress;
|
||||
return;
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import {
|
||||
Person,
|
||||
fetchPersons,
|
||||
@ -19,7 +19,7 @@ import {
|
||||
} from "../../../data/person";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import { compare } from "../../../common/string/compare";
|
||||
import "../ha-config-section";
|
||||
@ -28,10 +28,13 @@ import {
|
||||
loadPersonDetailDialog,
|
||||
} from "./show-dialog-person-detail";
|
||||
import { User, fetchUsers } from "../../../data/user";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
class HaConfigPerson extends LitElement {
|
||||
@property() public hass?: HomeAssistant;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow?: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() private _storageItems?: Person[];
|
||||
@property() private _configItems?: Person[];
|
||||
private _usersLoad?: Promise<User[]>;
|
||||
@ -48,9 +51,12 @@ class HaConfigPerson extends LitElement {
|
||||
}
|
||||
const hass = this.hass;
|
||||
return html`
|
||||
<hass-subpage
|
||||
.header=${hass.localize("ui.panel.config.person.caption")}
|
||||
.showBackButton=${!this.isWide}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
back-path="/config"
|
||||
.tabs=${configSections.persons}
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header"
|
||||
@ -109,10 +115,11 @@ class HaConfigPerson extends LitElement {
|
||||
`
|
||||
: ""}
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
|
||||
<ha-fab
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title="${hass.localize("ui.panel.config.person.add_person")}"
|
||||
@click=${this._createPerson}
|
||||
@ -231,7 +238,9 @@ ${this.hass!.localize("ui.panel.config.person.confirm_delete2")}`)
|
||||
right: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[is-wide] {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
|
@ -54,6 +54,7 @@ class HaConfigScene extends HassRouterPage {
|
||||
pageEl.hass = this.hass;
|
||||
pageEl.narrow = this.narrow;
|
||||
pageEl.isWide = this.isWide;
|
||||
pageEl.route = this.routeTail;
|
||||
pageEl.showAdvanced = this.showAdvanced;
|
||||
|
||||
if (this.hass) {
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
@ -20,24 +20,29 @@ import "../ha-config-section";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { SceneEntity, activateScene } from "../../../data/scene";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { forwardHaptic } from "../../../data/haptics";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-scene-dashboard")
|
||||
class HaSceneDashboard extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public scenes!: SceneEntity[];
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.showBackButton=${!this.isWide}
|
||||
.header=${this.hass.localize("ui.panel.config.scene.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
@ -72,8 +77,7 @@ class HaSceneDashboard extends LitElement {
|
||||
`
|
||||
: this.scenes.map(
|
||||
(scene) => html`
|
||||
|
||||
<div class='scene'>
|
||||
<div class="scene">
|
||||
<paper-icon-button
|
||||
.scene=${scene}
|
||||
icon="hass:play"
|
||||
@ -82,46 +86,44 @@ class HaSceneDashboard extends LitElement {
|
||||
)}"
|
||||
@click=${this._activateScene}
|
||||
></paper-icon-button>
|
||||
<paper-item-body two-line>
|
||||
<div>${computeStateName(scene)}</div>
|
||||
</paper-item-body>
|
||||
<a
|
||||
href=${ifDefined(
|
||||
scene.attributes.id
|
||||
? `/config/scene/edit/${scene.attributes.id}`
|
||||
: undefined
|
||||
)}
|
||||
>
|
||||
<paper-icon-button
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.edit_scene"
|
||||
)}"
|
||||
icon="hass:pencil"
|
||||
.disabled=${!scene.attributes.id}
|
||||
></paper-icon-button>
|
||||
${
|
||||
!scene.attributes.id
|
||||
? html`
|
||||
<paper-tooltip position="left">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.only_editable"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
</a>
|
||||
<paper-item-body two-line>
|
||||
<div>${computeStateName(scene)}</div>
|
||||
</paper-item-body>
|
||||
<div class="actions">
|
||||
<a
|
||||
href=${ifDefined(
|
||||
scene.attributes.id
|
||||
? `/config/scene/edit/${scene.attributes.id}`
|
||||
: undefined
|
||||
)}
|
||||
>
|
||||
<paper-icon-button
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.edit_scene"
|
||||
)}"
|
||||
icon="hass:pencil"
|
||||
.disabled=${!scene.attributes.id}
|
||||
></paper-icon-button>
|
||||
${!scene.attributes.id
|
||||
? html`
|
||||
<paper-tooltip position="left">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.only_editable"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
`
|
||||
: ""}
|
||||
</a>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<a href="/config/scene/edit/new">
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide=${!this.narrow}
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.add_scene"
|
||||
@ -129,7 +131,7 @@ class HaSceneDashboard extends LitElement {
|
||||
?rtl=${computeRTL(this.hass)}
|
||||
></ha-fab>
|
||||
</a>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -152,13 +154,11 @@ class HaSceneDashboard extends LitElement {
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
hass-subpage {
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ha-card {
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 56px;
|
||||
}
|
||||
|
||||
@ -173,6 +173,10 @@ class HaSceneDashboard extends LitElement {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
ha-entity-toggle {
|
||||
margin-right: 16px;
|
||||
}
|
||||
@ -188,7 +192,9 @@ class HaSceneDashboard extends LitElement {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[rtl] {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
|
@ -26,7 +26,7 @@ import "../../../layouts/ha-app-layout";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import {
|
||||
@ -55,6 +55,7 @@ import memoizeOne from "memoize-one";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { HassEvent } from "home-assistant-js-websocket";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
interface DeviceEntities {
|
||||
id: string;
|
||||
@ -69,7 +70,9 @@ interface DeviceEntitiesLookup {
|
||||
@customElement("ha-scene-editor")
|
||||
export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public scene?: SceneEntity;
|
||||
@property() public creatingNew?: boolean;
|
||||
@property() public showAdvanced!: boolean;
|
||||
@ -157,39 +160,36 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
this._deviceRegistryEntries
|
||||
);
|
||||
return html`
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-paper-icon-button-arrow-prev
|
||||
@click=${this._backTapped}
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
<div main-title>
|
||||
${this.scene
|
||||
? computeStateName(this.scene)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.scene.editor.default_name"
|
||||
)}
|
||||
</div>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.delete_scene"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteTapped}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
|
||||
<div class="content">
|
||||
${this._errors
|
||||
? html`
|
||||
<div class="errors">${this._errors}</div>
|
||||
`
|
||||
: ""}
|
||||
${
|
||||
this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
slot="toolbar-icon"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.scene.picker.delete_scene"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteTapped}
|
||||
></paper-icon-button>
|
||||
`
|
||||
}
|
||||
|
||||
${
|
||||
this._errors
|
||||
? html`
|
||||
<div class="errors">${this._errors}</div>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<div
|
||||
id="root"
|
||||
class="${classMap({
|
||||
@ -198,11 +198,13 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.scene
|
||||
? computeStateName(this.scene)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.scene.editor.default_name"
|
||||
)}
|
||||
${
|
||||
this.scene
|
||||
? computeStateName(this.scene)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.scene.editor.default_name"
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
@ -291,87 +293,88 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
${this.showAdvanced
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.header"
|
||||
)}
|
||||
</div>
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.introduction"
|
||||
)}
|
||||
</div>
|
||||
${entities.length
|
||||
? html`
|
||||
<ha-card
|
||||
class="entities"
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.without_device"
|
||||
)}
|
||||
>
|
||||
${entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
.entityId=${entityId}
|
||||
.title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.delete"
|
||||
)}"
|
||||
@click=${this._deleteEntity}
|
||||
></paper-icon-button>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${
|
||||
this.showAdvanced
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.device_entities"
|
||||
"ui.panel.config.scene.editor.entities.header"
|
||||
)}
|
||||
<ha-entity-picker
|
||||
@value-changed=${this._entityPicked}
|
||||
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
||||
.hass=${this.hass}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.introduction"
|
||||
)}
|
||||
</div>
|
||||
${entities.length
|
||||
? html`
|
||||
<ha-card
|
||||
class="entities"
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.without_device"
|
||||
)}
|
||||
>
|
||||
${entities.map((entityId) => {
|
||||
const stateObj = this.hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<paper-icon-item
|
||||
.entityId=${entityId}
|
||||
@click=${this._showMoreInfo}
|
||||
class="device-entity"
|
||||
>
|
||||
<state-badge
|
||||
.stateObj=${stateObj}
|
||||
slot="item-icon"
|
||||
></state-badge>
|
||||
<paper-item-body>
|
||||
${computeStateName(stateObj)}
|
||||
</paper-item-body>
|
||||
<paper-icon-button
|
||||
icon="hass:delete"
|
||||
.entityId=${entityId}
|
||||
.title="${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.delete"
|
||||
)}"
|
||||
@click=${this._deleteEntity}
|
||||
></paper-icon-button>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.device_entities"
|
||||
)}
|
||||
<ha-entity-picker
|
||||
@value-changed=${this._entityPicked}
|
||||
.excludeDomains=${SCENE_IGNORED_DOMAINS}
|
||||
.hass=${this.hass}
|
||||
label=${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.entities.add"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide="${this.isWide}"
|
||||
?narrow="${this.narrow}"
|
||||
?dirty="${this._dirty}"
|
||||
icon="hass:content-save"
|
||||
.title="${this.hass.localize("ui.panel.config.scene.editor.save")}"
|
||||
@ -706,7 +709,10 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
margin-bottom: -140px;
|
||||
}
|
||||
ha-fab[dirty] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ class HaConfigScript extends PolymerElement {
|
||||
hass="[[hass]]"
|
||||
scripts="[[scripts]]"
|
||||
is-wide="[[isWide]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
></ha-script-picker>
|
||||
</template>
|
||||
|
||||
@ -42,6 +44,8 @@ class HaConfigScript extends PolymerElement {
|
||||
hass="[[hass]]"
|
||||
script="[[script]]"
|
||||
is-wide="[[isWide]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
creating-new="[[_creatingNew]]"
|
||||
></ha-script-editor>
|
||||
</template>
|
||||
@ -53,6 +57,7 @@ class HaConfigScript extends PolymerElement {
|
||||
hass: Object,
|
||||
route: Object,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
_routeData: Object,
|
||||
_routeMatches: Boolean,
|
||||
_creatingNew: Boolean,
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import "../../../components/ha-fab";
|
||||
@ -25,14 +24,17 @@ import {
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/ha-app-layout";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import "../automation/action/ha-automation-action";
|
||||
import { computeObjectId } from "../../../common/entity/compute_object_id";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
export class HaScriptEditor extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public script!: ScriptEntity;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public creatingNew?: boolean;
|
||||
@property() private _config?: ScriptConfig;
|
||||
@property() private _dirty?: boolean;
|
||||
@ -40,32 +42,25 @@ export class HaScriptEditor extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-app-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-paper-icon-button-arrow-prev
|
||||
@click=${this._backTapped}
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
<div main-title>
|
||||
${this.script
|
||||
? computeStateName(this.script)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.script.editor.default_name"
|
||||
)}
|
||||
</div>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.script.editor.delete_script"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${() => this._backTapped()}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<paper-icon-button
|
||||
slot="toolbar-icon"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.script.editor.delete_script"
|
||||
)}"
|
||||
icon="hass:delete"
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
|
||||
<div class="content">
|
||||
${this._errors
|
||||
@ -134,9 +129,9 @@ export class HaScriptEditor extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide="${this.isWide}"
|
||||
?dirty="${this._dirty}"
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
?dirty=${this._dirty}
|
||||
icon="hass:content-save"
|
||||
.title="${this.hass.localize("ui.common.save")}"
|
||||
@click=${this._saveScript}
|
||||
@ -144,7 +139,7 @@ export class HaScriptEditor extends LitElement {
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
></ha-fab>
|
||||
</ha-app-layout>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -301,7 +296,10 @@ export class HaScriptEditor extends LitElement {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
margin-bottom: -140px;
|
||||
}
|
||||
ha-fab[dirty] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
|
||||
@ -22,21 +22,27 @@ import "../ha-config-section";
|
||||
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { triggerScript } from "../../../data/script";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-script-picker")
|
||||
class HaScriptPicker extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public scripts!: HassEntity[];
|
||||
@property() public isWide!: boolean;
|
||||
@property() public narrow!: boolean;
|
||||
@property() public route!: Route;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.showBackButton=${!this.isWide}
|
||||
.header=${this.hass.localize("ui.panel.config.script.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.automation}
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
@ -99,8 +105,8 @@ class HaScriptPicker extends LitElement {
|
||||
|
||||
<a href="/config/script/new">
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title="${this.hass.localize(
|
||||
"ui.panel.config.script.picker.add_script"
|
||||
@ -108,7 +114,7 @@ class HaScriptPicker extends LitElement {
|
||||
?rtl=${computeRTL(this.hass)}
|
||||
></ha-fab>
|
||||
</a>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -169,7 +175,9 @@ class HaScriptPicker extends LitElement {
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[rtl] {
|
||||
right: auto;
|
||||
left: 16px;
|
||||
|
@ -4,12 +4,13 @@ import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../resources/ha-style";
|
||||
|
||||
import "./ha-config-section-server-control";
|
||||
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
@ -33,9 +34,13 @@ class HaConfigServerControl extends LocalizeMixin(PolymerElement) {
|
||||
}
|
||||
</style>
|
||||
|
||||
<hass-subpage
|
||||
header="[[localize('ui.panel.config.server_control.caption')]]"
|
||||
show-back-button="[[!isWide]]"
|
||||
<hass-tabs-subpage
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
back-path="/config"
|
||||
tabs="[[_computeTabs()]]"
|
||||
show-advanced="[[showAdvanced]]"
|
||||
>
|
||||
<div class$="[[computeClasses(isWide)]]">
|
||||
<ha-config-section-server-control
|
||||
@ -44,7 +49,7 @@ class HaConfigServerControl extends LocalizeMixin(PolymerElement) {
|
||||
hass="[[hass]]"
|
||||
></ha-config-section-server-control>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -52,10 +57,16 @@ class HaConfigServerControl extends LocalizeMixin(PolymerElement) {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
route: Object,
|
||||
showAdvanced: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
_computeTabs() {
|
||||
return configSections.general;
|
||||
}
|
||||
|
||||
computeClasses(isWide) {
|
||||
return isWide ? "content" : "content narrow";
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import "@polymer/paper-item/paper-item-body";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
@ -13,6 +13,7 @@ import NavigateMixin from "../../../mixins/navigate-mixin";
|
||||
import { EventsMixin } from "../../../mixins/events-mixin";
|
||||
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
let registeredDialog = false;
|
||||
|
||||
@ -41,6 +42,9 @@ class HaUserPicker extends EventsMixin(
|
||||
right: auto;
|
||||
left: 16px;
|
||||
}
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
ha-fab[rtl][is-wide] {
|
||||
bottom: 24px;
|
||||
right: auto;
|
||||
@ -58,9 +62,12 @@ class HaUserPicker extends EventsMixin(
|
||||
}
|
||||
</style>
|
||||
|
||||
<hass-subpage
|
||||
header="[[localize('ui.panel.config.users.picker.title')]]"
|
||||
show-back-button="[[!isWide]]"
|
||||
<hass-tabs-subpage
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
back-path="/config"
|
||||
tabs="[[_computeTabs()]]"
|
||||
>
|
||||
<ha-card>
|
||||
<template is="dom-repeat" items="[[users]]" as="user">
|
||||
@ -84,12 +91,13 @@ class HaUserPicker extends EventsMixin(
|
||||
|
||||
<ha-fab
|
||||
is-wide$="[[isWide]]"
|
||||
narrow$="[[narrow]]"
|
||||
icon="hass:plus"
|
||||
title="[[localize('ui.panel.config.users.picker.add_user')]]"
|
||||
on-click="_addUser"
|
||||
rtl$="[[rtl]]"
|
||||
></ha-fab>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -98,6 +106,8 @@ class HaUserPicker extends EventsMixin(
|
||||
hass: Object,
|
||||
users: Array,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
route: Object,
|
||||
rtl: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true,
|
||||
@ -138,6 +148,10 @@ class HaUserPicker extends EventsMixin(
|
||||
return computeRTL(hass);
|
||||
}
|
||||
|
||||
_computeTabs() {
|
||||
return configSections.persons;
|
||||
}
|
||||
|
||||
_addUser() {
|
||||
this.fire("show-add-user", {
|
||||
hass: this.hass,
|
||||
|
@ -28,6 +28,8 @@ class HaConfigUsers extends NavigateMixin(PolymerElement) {
|
||||
hass="[[hass]]"
|
||||
users="[[_users]]"
|
||||
is-wide="[[isWide]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
></ha-config-user-picker>
|
||||
</template>
|
||||
<template
|
||||
@ -38,6 +40,8 @@ class HaConfigUsers extends NavigateMixin(PolymerElement) {
|
||||
<ha-user-editor
|
||||
hass="[[hass]]"
|
||||
user="[[_computeUser(_users, _routeData.user)]]"
|
||||
narrow="[[narrow]]"
|
||||
route="[[route]]"
|
||||
></ha-user-editor>
|
||||
</template>
|
||||
`;
|
||||
@ -47,6 +51,7 @@ class HaConfigUsers extends NavigateMixin(PolymerElement) {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
narrow: Boolean,
|
||||
route: {
|
||||
type: Object,
|
||||
observer: "_checkRoute",
|
||||
|
@ -10,10 +10,10 @@ import {
|
||||
import { until } from "lit-html/directives/until";
|
||||
import "@material/mwc-button";
|
||||
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import "../../../components/ha-card";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import {
|
||||
@ -29,6 +29,7 @@ import {
|
||||
showConfirmationDialog,
|
||||
showPromptDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
@ -42,6 +43,8 @@ const GROUPS = [SYSTEM_GROUP_ID_USER, SYSTEM_GROUP_ID_ADMIN];
|
||||
class HaUserEditor extends LitElement {
|
||||
@property() public hass?: HomeAssistant;
|
||||
@property() public user?: User;
|
||||
@property() public narrow?: boolean;
|
||||
@property() public route!: Route;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const hass = this.hass;
|
||||
@ -51,8 +54,11 @@ class HaUserEditor extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<hass-subpage
|
||||
.header=${hass.localize("ui.panel.config.users.editor.caption")}
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.persons}
|
||||
>
|
||||
<ha-card .header=${this._name}>
|
||||
<table class="card-content">
|
||||
@ -130,7 +136,7 @@ class HaUserEditor extends LitElement {
|
||||
: ""}
|
||||
</div>
|
||||
</ha-card>
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -225,7 +231,7 @@ class HaUserEditor extends LitElement {
|
||||
}
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 0 auto 16px;
|
||||
margin: 16px auto 16px;
|
||||
}
|
||||
hass-subpage ha-card:first-of-type {
|
||||
direction: ltr;
|
||||
|
@ -16,10 +16,10 @@ import "@polymer/paper-tooltip/paper-tooltip";
|
||||
|
||||
import "../../../components/map/ha-locations-editor";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import { compare } from "../../../common/string/compare";
|
||||
import "../ha-config-section";
|
||||
@ -42,12 +42,14 @@ import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { subscribeEntityRegistry } from "../../../data/entity_registry";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
|
||||
@customElement("ha-config-zone")
|
||||
export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide?: boolean;
|
||||
@property() public narrow?: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() private _storageItems?: Zone[];
|
||||
@property() private _stateItems?: HassEntity[];
|
||||
@property() private _activeEntry: string = "";
|
||||
@ -179,7 +181,13 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
`;
|
||||
|
||||
return html`
|
||||
<hass-subpage .header=${hass.localize("ui.panel.config.zone.caption")}>
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
back-path="/config"
|
||||
.tabs=${configSections.persons}
|
||||
>
|
||||
${this.narrow
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
@ -206,10 +214,11 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</hass-subpage>
|
||||
</hass-tabs-subpage>
|
||||
|
||||
<ha-fab
|
||||
?is-wide=${this.isWide}
|
||||
?narrow=${this.narrow}
|
||||
icon="hass:plus"
|
||||
title="${hass.localize("ui.panel.config.zone.add_zone")}"
|
||||
@click=${this._createZone}
|
||||
@ -389,6 +398,10 @@ ${this.hass!.localize("ui.panel.config.zone.confirm_delete2")}`)
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
hass-loading-screen {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
--app-header-text-color: var(--sidebar-text-color);
|
||||
}
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
@ -449,6 +462,9 @@ ${this.hass!.localize("ui.panel.config.zone.confirm_delete2")}`)
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
ha-fab[narrow] {
|
||||
bottom: 84px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user