Merge pull request #9692 from home-assistant/dev

This commit is contained in:
Paulus Schoutsen 2021-08-02 21:10:24 -07:00 committed by GitHub
commit e09ef7862e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 127 additions and 47 deletions

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup( setup(
name="home-assistant-frontend", name="home-assistant-frontend",
version="20210802.0", version="20210803.0",
description="The Home Assistant frontend", description="The Home Assistant frontend",
url="https://github.com/home-assistant/frontend", url="https://github.com/home-assistant/frontend",
author="The Home Assistant Authors", author="The Home Assistant Authors",

View File

@ -8,6 +8,7 @@ import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import type { LocalizeFunc } from "../common/translations/localize"; import type { LocalizeFunc } from "../common/translations/localize";
import { createCurrencyListEl } from "../components/currency-datalist";
import "../components/map/ha-locations-editor"; import "../components/map/ha-locations-editor";
import type { MarkerLocation } from "../components/map/ha-locations-editor"; import type { MarkerLocation } from "../components/map/ha-locations-editor";
import { createTimezoneListEl } from "../components/timezone-datalist"; import { createTimezoneListEl } from "../components/timezone-datalist";
@ -16,11 +17,12 @@ import {
detectCoreConfig, detectCoreConfig,
saveCoreConfig, saveCoreConfig,
} from "../data/core"; } from "../data/core";
import { SYMBOL_TO_ISO } from "../data/currency";
import { onboardCoreConfigStep } from "../data/onboarding"; import { onboardCoreConfigStep } from "../data/onboarding";
import type { PolymerChangedEvent } from "../polymer-types"; import type { PolymerChangedEvent } from "../polymer-types";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
const amsterdam = [52.3731339, 4.8903147]; const amsterdam: [number, number] = [52.3731339, 4.8903147];
const mql = matchMedia("(prefers-color-scheme: dark)"); const mql = matchMedia("(prefers-color-scheme: dark)");
@customElement("onboarding-core-config") @customElement("onboarding-core-config")
@ -31,15 +33,17 @@ class OnboardingCoreConfig extends LitElement {
@state() private _working = false; @state() private _working = false;
@state() private _name!: ConfigUpdateValues["location_name"]; @state() private _name?: ConfigUpdateValues["location_name"];
@state() private _location!: [number, number]; @state() private _location?: [number, number];
@state() private _elevation!: string; @state() private _elevation?: string;
@state() private _unitSystem!: ConfigUpdateValues["unit_system"]; @state() private _unitSystem?: ConfigUpdateValues["unit_system"];
@state() private _timeZone!: string; @state() private _currency?: ConfigUpdateValues["currency"];
@state() private _timeZone?: string;
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
@ -159,6 +163,35 @@ class OnboardingCoreConfig extends LitElement {
</paper-radio-group> </paper-radio-group>
</div> </div>
<div class="row">
<div class="flex">
${this.hass.localize(
"ui.panel.config.core.section.core.core_config.currency"
)}<br />
<a
href="https://en.wikipedia.org/wiki/ISO_4217#Active_codes"
target="_blank"
rel="noopener noreferrer"
>${this.hass.localize(
"ui.panel.config.core.section.core.core_config.find_currency_value"
)}</a
>
</div>
<paper-input
class="flex"
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.currency"
)}
name="currency"
list="currencies"
.disabled=${this._working}
.value=${this._currencyValue}
@value-changed=${this._handleChange}
></paper-input>
</div>
</div>
<div class="footer"> <div class="footer">
<mwc-button @click=${this._save} .disabled=${this._working}> <mwc-button @click=${this._save} .disabled=${this._working}>
${this.onboardingLocalize( ${this.onboardingLocalize(
@ -180,10 +213,15 @@ class OnboardingCoreConfig extends LitElement {
this._save(ev); this._save(ev);
} }
}); });
const input = this.shadowRoot!.querySelector( const tzInput = this.shadowRoot!.querySelector(
"[name=timeZone]" "[name=timeZone]"
) as PaperInputElement; ) as PaperInputElement;
input.inputElement.appendChild(createTimezoneListEl()); tzInput.inputElement.appendChild(createTimezoneListEl());
const cInput = this.shadowRoot!.querySelector(
"[name=currency]"
) as PaperInputElement;
cInput.inputElement.appendChild(createCurrencyListEl());
} }
private get _nameValue() { private get _nameValue() {
@ -210,6 +248,10 @@ class OnboardingCoreConfig extends LitElement {
return this._unitSystem !== undefined ? this._unitSystem : "metric"; return this._unitSystem !== undefined ? this._unitSystem : "metric";
} }
private get _currencyValue() {
return this._currency !== undefined ? this._currency : "";
}
private _markerLocation = memoizeOne( private _markerLocation = memoizeOne(
(location: [number, number]): MarkerLocation[] => [ (location: [number, number]): MarkerLocation[] => [
{ {
@ -223,7 +265,16 @@ class OnboardingCoreConfig extends LitElement {
private _handleChange(ev: PolymerChangedEvent<string>) { private _handleChange(ev: PolymerChangedEvent<string>) {
const target = ev.currentTarget as PaperInputElement; const target = ev.currentTarget as PaperInputElement;
this[`_${target.name}`] = target.value;
let value = target.value;
if (target.name === "currency" && value) {
if (value in SYMBOL_TO_ISO) {
value = SYMBOL_TO_ISO[value];
}
}
this[`_${target.name}`] = value;
} }
private _locationChanged(ev) { private _locationChanged(ev) {
@ -240,6 +291,7 @@ class OnboardingCoreConfig extends LitElement {
this._working = true; this._working = true;
try { try {
const values = await detectCoreConfig(this.hass); const values = await detectCoreConfig(this.hass);
if (values.latitude && values.longitude) { if (values.latitude && values.longitude) {
this._location = [Number(values.latitude), Number(values.longitude)]; this._location = [Number(values.latitude), Number(values.longitude)];
} }
@ -252,6 +304,9 @@ class OnboardingCoreConfig extends LitElement {
if (values.time_zone) { if (values.time_zone) {
this._timeZone = values.time_zone; this._timeZone = values.time_zone;
} }
if (values.currency) {
this._currency = values.currency;
}
} catch (err) { } catch (err) {
alert(`Failed to detect location information: ${err.message}`); alert(`Failed to detect location information: ${err.message}`);
} finally { } finally {
@ -271,6 +326,7 @@ class OnboardingCoreConfig extends LitElement {
elevation: Number(this._elevationValue), elevation: Number(this._elevationValue),
unit_system: this._unitSystemValue, unit_system: this._unitSystemValue,
time_zone: this._timeZoneValue || "UTC", time_zone: this._timeZoneValue || "UTC",
currency: this._currencyValue || "EUR",
}); });
const result = await onboardCoreConfigStep(this.hass); const result = await onboardCoreConfigStep(this.hass);
fireEvent(this, "onboarding-step", { fireEvent(this, "onboarding-step", {
@ -311,6 +367,9 @@ class OnboardingCoreConfig extends LitElement {
margin-top: 16px; margin-top: 16px;
text-align: right; text-align: right;
} }
a {
color: var(--primary-color);
}
`; `;
} }
} }

View File

@ -58,6 +58,11 @@ export class DialogEnergyDeviceSettings
@closed=${this.closeDialog} @closed=${this.closeDialog}
> >
${this._error ? html`<p class="error">${this._error}</p>` : ""} ${this._error ? html`<p class="error">${this._error}</p>` : ""}
<div>
${this.hass.localize(
`ui.panel.config.energy.device_consumption.dialog.selected_stat_intro`
)}
</div>
<ha-statistic-picker <ha-statistic-picker
.hass=${this.hass} .hass=${this.hass}

View File

@ -13,7 +13,6 @@ import {
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import "../../components/ha-menu-button"; import "../../components/ha-menu-button";
import "../../layouts/ha-app-layout"; import "../../layouts/ha-app-layout";
import { mdiCog } from "@mdi/js";
import { haStyle } from "../../resources/styles"; import { haStyle } from "../../resources/styles";
import "../lovelace/views/hui-view"; import "../lovelace/views/hui-view";
@ -60,13 +59,11 @@ class PanelEnergy extends LitElement {
<ha-app-layout> <ha-app-layout>
<app-header fixed slot="header"> <app-header fixed slot="header">
<app-toolbar> <app-toolbar>
<div class="nav-title"> <ha-menu-button
<ha-menu-button .hass=${this.hass}
.hass=${this.hass} .narrow=${this.narrow}
.narrow=${this.narrow} ></ha-menu-button>
></ha-menu-button> <div main-title>${this.hass.localize("panel.energy")}</div>
<div main-title>${this.hass.localize("panel.energy")}</div>
</div>
${this.narrow ${this.narrow
? "" ? ""
: html` : html`
@ -75,11 +72,6 @@ class PanelEnergy extends LitElement {
collectionKey="energy_dashboard" collectionKey="energy_dashboard"
></hui-energy-period-selector> ></hui-energy-period-selector>
`} `}
<a href="/config/energy?historyBack=1">
<mwc-icon-button>
<ha-svg-icon .path=${mdiCog}></ha-svg-icon>
</mwc-icon-button>
</a>
</app-toolbar> </app-toolbar>
</app-header> </app-header>
<hui-view <hui-view
@ -128,12 +120,9 @@ class PanelEnergy extends LitElement {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.nav-title {
display: flex;
align-items: center;
}
hui-energy-period-selector { hui-energy-period-selector {
width: 300px; width: 100%;
padding-left: 16px;
} }
`, `,
]; ];

View File

@ -1,5 +1,5 @@
import { mdiChevronLeft, mdiChevronRight } from "@mdi/js"; import { mdiChevronLeft, mdiChevronRight } from "@mdi/js";
import { endOfToday, addDays, endOfDay, isToday, isYesterday } from "date-fns"; import { endOfToday, addDays, endOfDay, isToday, startOfToday } from "date-fns";
import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
@ -9,6 +9,7 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import "@material/mwc-icon-button/mwc-icon-button"; import "@material/mwc-icon-button/mwc-icon-button";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import "@material/mwc-button/mwc-button";
@customElement("hui-energy-period-selector") @customElement("hui-energy-period-selector")
export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
@ -33,29 +34,34 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
return html``; return html``;
} }
const isStartToday = isToday(this._startDate);
let label;
if (isStartToday) {
label = "Today";
} else if (isYesterday(this._startDate)) {
label = "Yesterday";
} else {
label = formatDate(this._startDate, this.hass.locale);
}
return html` return html`
<div class="row"> <div class="row">
<div class="label">
${formatDate(this._startDate, this.hass.locale)}
</div>
<mwc-icon-button label="Previous Day" @click=${this._pickPreviousDay}> <mwc-icon-button label="Previous Day" @click=${this._pickPreviousDay}>
<ha-svg-icon .path=${mdiChevronLeft}></ha-svg-icon> <ha-svg-icon .path=${mdiChevronLeft}></ha-svg-icon>
</mwc-icon-button> </mwc-icon-button>
<div class="label">${label}</div>
<mwc-icon-button label="Next Day" @click=${this._pickNextDay}> <mwc-icon-button label="Next Day" @click=${this._pickNextDay}>
<ha-svg-icon .path=${mdiChevronRight}></ha-svg-icon> <ha-svg-icon .path=${mdiChevronRight}></ha-svg-icon>
</mwc-icon-button> </mwc-icon-button>
<mwc-button
dense
outlined
.disabled=${isToday(this._startDate)}
@click=${this._pickToday}
>Today</mwc-button
>
</div> </div>
`; `;
} }
private _pickToday() {
this._setDate(startOfToday());
}
private _pickPreviousDay() { private _pickPreviousDay() {
this._setDate(addDays(this._startDate!, -1)); this._setDate(addDays(this._startDate!, -1));
} }
@ -83,12 +89,30 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
.row { .row {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end;
} }
.label { .label {
flex: 1; padding: 0 8px;
text-align: center; text-align: center;
font-size: 20px; font-size: 20px;
} }
mwc-icon-button {
--mdc-icon-button-size: 28px;
}
mwc-button {
padding-left: 8px;
--mdc-theme-primary: currentColor;
--mdc-button-outline-color: currentColor;
--mdc-button-disabled-outline-color: rgba(
var(--rgb-text-primary-color),
0.5
);
--mdc-button-disabled-ink-color: rgba(
var(--rgb-text-primary-color),
0.5
);
}
`; `;
} }
} }

View File

@ -60,9 +60,9 @@ export class HuiViewEditor extends LitElement {
get _type(): string { get _type(): string {
if (!this._config) { if (!this._config) {
return "masonary"; return "masonry";
} }
return this._config.panel ? "panel" : this._config.type || "masonary"; return this._config.panel ? "panel" : this._config.type || "masonry";
} }
set config(config: LovelaceViewConfig) { set config(config: LovelaceViewConfig) {
@ -125,7 +125,7 @@ export class HuiViewEditor extends LitElement {
attr-for-selected="type" attr-for-selected="type"
@iron-select=${this._typeChanged} @iron-select=${this._typeChanged}
> >
${["masonary", "sidebar", "panel"].map( ${["masonry", "sidebar", "panel"].map(
(type) => html`<paper-item .type=${type}> (type) => html`<paper-item .type=${type}>
${this.hass.localize( ${this.hass.localize(
`ui.panel.lovelace.editor.edit_view.types.${type}` `ui.panel.lovelace.editor.edit_view.types.${type}`
@ -167,7 +167,7 @@ export class HuiViewEditor extends LitElement {
...this._config, ...this._config,
}; };
delete newConfig.panel; delete newConfig.panel;
if (selected === "masonary") { if (selected === "masonry") {
delete newConfig.type; delete newConfig.type;
} else { } else {
newConfig.type = selected; newConfig.type = selected;

View File

@ -1052,7 +1052,10 @@
"sub": "Tracking the energy usage of individual devices allows Home Assistant to break down your energy usage by device.", "sub": "Tracking the energy usage of individual devices allows Home Assistant to break down your energy usage by device.",
"learn_more": "More information on how to get started.", "learn_more": "More information on how to get started.",
"add_stat": "Pick entity to track energy of", "add_stat": "Pick entity to track energy of",
"selected_stat": "Tracking energy for" "selected_stat": "Tracking energy for",
"dialog": {
"selected_stat_intro": "Select the entity that represents the device energy usage."
}
} }
}, },
"helpers": { "helpers": {
@ -2943,7 +2946,7 @@
}, },
"type": "View type", "type": "View type",
"types": { "types": {
"masonary": "Masonary (default)", "masonry": "Masonry (default)",
"sidebar": "Sidebar", "sidebar": "Sidebar",
"panel": "Panel (1 card)" "panel": "Panel (1 card)"
} }