From 1d15f81b6c5721f54fae598bc61bd4d65c42c3c9 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 10 Jan 2023 18:28:07 +0100 Subject: [PATCH 1/6] Fixes moon badge icon (#15015) --- src/components/entity/ha-state-label-badge.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts index c51309ccfb..155294ef75 100644 --- a/src/components/entity/ha-state-label-badge.ts +++ b/src/components/entity/ha-state-label-badge.ts @@ -22,6 +22,7 @@ import { isNumericState, } from "../../common/number/format_number"; import { isUnavailableState, UNAVAILABLE, UNKNOWN } from "../../data/entity"; +import { EntityRegistryEntry } from "../../data/entity_registry"; import { timerTimeRemaining } from "../../data/timer"; import { HomeAssistant } from "../../types"; import "../ha-label-badge"; @@ -103,8 +104,10 @@ export class HaStateLabelBadge extends LitElement { // 4. Icon determined via entity state // 5. Value string as fallback const domain = computeStateDomain(entityState); + const entry = this.hass?.entities[entityState.entity_id]; - const showIcon = this.icon || this._computeShowIcon(domain, entityState); + const showIcon = + this.icon || this._computeShowIcon(domain, entityState, entry); const image = this.icon ? "" : this.image @@ -112,7 +115,9 @@ export class HaStateLabelBadge extends LitElement { : entityState.attributes.entity_picture_local || entityState.attributes.entity_picture; const value = - !image && !showIcon ? this._computeValue(domain, entityState) : undefined; + !image && !showIcon + ? this._computeValue(domain, entityState, entry) + : undefined; return html` Date: Tue, 10 Jan 2023 18:28:34 +0100 Subject: [PATCH 2/6] Fixes multiple domains target selector in blueprint (#15054) * Fixes multiple domains target selector in blueprint * Fixes lint --- src/components/ha-selector/ha-selector-target.ts | 3 ++- src/panels/config/automation/blueprint-automation-editor.ts | 2 +- src/panels/config/script/blueprint-script-editor.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/ha-selector/ha-selector-target.ts b/src/components/ha-selector/ha-selector-target.ts index e4cf47278d..9853d1552e 100644 --- a/src/components/ha-selector/ha-selector-target.ts +++ b/src/components/ha-selector/ha-selector-target.ts @@ -9,6 +9,7 @@ import { } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; +import { ensureArray } from "../../common/array/ensure-array"; import { DeviceRegistryEntry, getDeviceIntegrationLookup, @@ -78,7 +79,7 @@ export class HaTargetSelector extends LitElement { ? [this.selector.target?.entity.device_class] : undefined} .includeDomains=${this.selector.target?.entity?.domain - ? [this.selector.target?.entity.domain] + ? ensureArray(this.selector.target.entity.domain as string | string[]) : undefined} .disabled=${this.disabled} >`; diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 8eb563bd10..43b0ccf681 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -184,7 +184,7 @@ export class HaBlueprintAutomationEditor extends LitElement { ev.stopPropagation(); const target = ev.target as any; const key = target.key; - const value = ev.detail?.value ?? target.value; + const value = ev.detail ? ev.detail.value : target.value; if ( (this.config.use_blueprint.input && this.config.use_blueprint.input[key] === value) || diff --git a/src/panels/config/script/blueprint-script-editor.ts b/src/panels/config/script/blueprint-script-editor.ts index 3e4f3e8ec8..20746fcdbb 100644 --- a/src/panels/config/script/blueprint-script-editor.ts +++ b/src/panels/config/script/blueprint-script-editor.ts @@ -158,7 +158,7 @@ export class HaBlueprintScriptEditor extends LitElement { ev.stopPropagation(); const target = ev.target as any; const key = target.key; - const value = ev.detail?.value ?? target.value; + const value = ev.detail ? ev.detail.value : target.value; if ( (this.config.use_blueprint.input && this.config.use_blueprint.input[key] === value) || From 747f47524e1b05a53d5b913c25d8464a4b10b767 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 9 Jan 2023 03:28:31 -0800 Subject: [PATCH 3/6] Fix UNTIL values to be inclusive of last event and bug in populating recurrence rules when editing calendar events (#15024) * Fix bug in populating recurrence rules when editing calendar events * Set UNTIL value to be inclusive of the last instance * Fix lint errors --- .../calendar/ha-recurrence-rule-editor.ts | 74 ++++++++++++------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/panels/calendar/ha-recurrence-rule-editor.ts b/src/panels/calendar/ha-recurrence-rule-editor.ts index 5d8af6c2a9..ae70453935 100644 --- a/src/panels/calendar/ha-recurrence-rule-editor.ts +++ b/src/panels/calendar/ha-recurrence-rule-editor.ts @@ -1,4 +1,5 @@ import type { SelectedDetail } from "@material/mwc-list"; +import { formatInTimeZone, toDate } from "date-fns-tz"; import { css, html, LitElement, PropertyValues } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -64,7 +65,7 @@ export class RecurrenceRuleEditor extends LitElement { @state() private _count?: number; - @state() private _until?: Date; + @state() private _untilDay?: Date; @query("#monthly") private _monthlyRepeatSelect!: HaSelect; @@ -97,15 +98,17 @@ export class RecurrenceRuleEditor extends LitElement { } if ( - changedProps.has("timezone") || - changedProps.has("_freq") || - changedProps.has("_interval") || - changedProps.has("_weekday") || - changedProps.has("_monthlyRepeatWeekday") || - changedProps.has("_monthday") || - changedProps.has("_end") || - changedProps.has("_count") || - changedProps.has("_until") + !changedProps.has("value") && + (changedProps.has("dtstart") || + changedProps.has("timezone") || + changedProps.has("_freq") || + changedProps.has("_interval") || + changedProps.has("_weekday") || + changedProps.has("_monthlyRepeatWeekday") || + changedProps.has("_monthday") || + changedProps.has("_end") || + changedProps.has("_count") || + changedProps.has("_untilDay")) ) { this._updateRule(); return; @@ -122,7 +125,7 @@ export class RecurrenceRuleEditor extends LitElement { this._monthlyRepeatWeekday = undefined; this._end = "never"; this._count = undefined; - this._until = undefined; + this._untilDay = undefined; this._computedRRule = this.value; if (this.value === "") { @@ -162,7 +165,7 @@ export class RecurrenceRuleEditor extends LitElement { } if (rrule.until) { this._end = "on"; - this._until = rrule.until; + this._untilDay = toDate(rrule.until, { timeZone: this.timezone }); } else if (rrule.count) { this._end = "after"; this._count = rrule.count; @@ -327,7 +330,7 @@ export class RecurrenceRuleEditor extends LitElement { "ui.components.calendar.event.repeat.end_on.label" )} .locale=${this.locale} - .value=${this._until!.toISOString()} + .value=${this._formatDate(this._untilDay!)} @value-changed=${this._onUntilChange} > ` @@ -393,15 +396,15 @@ export class RecurrenceRuleEditor extends LitElement { switch (this._end) { case "after": this._count = DEFAULT_COUNT[this._freq!]; - this._until = undefined; + this._untilDay = undefined; break; case "on": this._count = undefined; - this._until = untilValue(this._freq!); + this._untilDay = untilValue(this._freq!); break; default: this._count = undefined; - this._until = undefined; + this._untilDay = undefined; } e.stopPropagation(); } @@ -412,7 +415,9 @@ export class RecurrenceRuleEditor extends LitElement { private _onUntilChange(e: CustomEvent) { e.stopPropagation(); - this._until = new Date(e.detail.value); + this._untilDay = toDate(e.detail.value + "T00:00:00", { + timeZone: this.timezone, + }); } // Reset the weekday selected when there is only a single value @@ -441,18 +446,27 @@ export class RecurrenceRuleEditor extends LitElement { freq: convertRepeatFrequency(this._freq!)!, interval: this._interval > 1 ? this._interval : undefined, count: this._count, - until: this._until, - tzid: this.timezone, byweekday: byweekday, bymonthday: bymonthday, }; let contentline = RRule.optionsToString(options); - if (this._until && this.allDay) { - // rrule.js only computes UNTIL values as DATE-TIME however rfc5545 says - // The value of the UNTIL rule part MUST have the same value type as the - // "DTSTART" property. If needed, strip off any time values as a workaround - // This converts "UNTIL=20220512T060000" to "UNTIL=20220512" - contentline = contentline.replace(/(UNTIL=\d{8})T\d{6}Z?/, "$1"); + if (this._untilDay) { + // The UNTIL value should be inclusive of the last event instance + const until = toDate( + this._formatDate(this._untilDay!) + + "T" + + this._formatTime(this.dtstart!), + { timeZone: this.timezone } + ); + // rrule.js can't compute some UNTIL variations so we compute that ourself. Must be + // in the same format as dtstart. + const format = this.allDay ? "yyyyMMdd" : "yyyyMMdd'T'HHmmss"; + const newUntilValue = formatInTimeZone( + until, + this.hass.config.time_zone, + format + ); + contentline += `;UNTIL=${newUntilValue}`; } return contentline.slice(6); // Strip "RRULE:" prefix } @@ -472,6 +486,16 @@ export class RecurrenceRuleEditor extends LitElement { ); } + // Formats a date in browser display timezone + private _formatDate(date: Date): string { + return formatInTimeZone(date, this.timezone!, "yyyy-MM-dd"); + } + + // Formats a time in browser display timezone + private _formatTime(date: Date): string { + return formatInTimeZone(date, this.timezone!, "HH:mm:ss"); + } + static styles = css` ha-textfield, ha-select { From 135af5bcaa73aa238dd6817e36496ee065430b65 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 6 Jan 2023 12:15:45 +0100 Subject: [PATCH 4/6] Remove aliases configuration from alexa cloud page (#15003) --- src/panels/config/cloud/alexa/cloud-alexa.ts | 35 ++------------------ 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/panels/config/cloud/alexa/cloud-alexa.ts b/src/panels/config/cloud/alexa/cloud-alexa.ts index e498f49fa4..8c666890dc 100644 --- a/src/panels/config/cloud/alexa/cloud-alexa.ts +++ b/src/panels/config/cloud/alexa/cloud-alexa.ts @@ -40,17 +40,12 @@ import { updateCloudAlexaEntityConfig, updateCloudPref, } from "../../../../data/cloud"; -import { - EntityRegistryEntry, - getExtendedEntityRegistryEntry, - updateEntityRegistryEntry, -} from "../../../../data/entity_registry"; +import { EntityRegistryEntry } from "../../../../data/entity_registry"; import { showDomainTogglerDialog } from "../../../../dialogs/domain-toggler/show-dialog-domain-toggler"; import "../../../../layouts/hass-loading-screen"; import "../../../../layouts/hass-subpage"; import { haStyle } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; -import { showEntityAliasesDialog } from "../../entities/entity-aliases/show-dialog-entity-aliases"; const DEFAULT_CONFIG_EXPOSE = true; @@ -167,20 +162,8 @@ class CloudAlexa extends LitElement { - ${entity.entity_id in this.hass.entities - ? html`` - : ""} ${!emptyFilter ? html`${iconButton}` @@ -343,21 +326,6 @@ class CloudAlexa extends LitElement { } } - private async _openAliasesSettings(ev) { - ev.stopPropagation(); - const entityId = ev.target.entityId; - const entry = await getExtendedEntityRegistryEntry(this.hass, entityId); - if (!entry) { - return; - } - showEntityAliasesDialog(this, { - entity: entry, - updateEntry: async (updates) => { - await updateEntityRegistryEntry(this.hass, entry.entity_id, updates); - }, - }); - } - private async _fetchData() { const entities = await fetchCloudAlexaEntities(this.hass); entities.sort((a, b) => { @@ -558,6 +526,7 @@ class CloudAlexa extends LitElement { } state-info { cursor: pointer; + height: 40px; } ha-switch { padding: 8px 0; From ba9551b61e9769fb42960fb6f8a3b8f8c605c5a3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 6 Jan 2023 08:04:45 +0100 Subject: [PATCH 5/6] Fixes weekday calendar chips toggle (#14990) --- src/panels/calendar/ha-recurrence-rule-editor.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/calendar/ha-recurrence-rule-editor.ts b/src/panels/calendar/ha-recurrence-rule-editor.ts index ae70453935..b7b3c03f5e 100644 --- a/src/panels/calendar/ha-recurrence-rule-editor.ts +++ b/src/panels/calendar/ha-recurrence-rule-editor.ts @@ -384,6 +384,7 @@ export class RecurrenceRuleEditor extends LitElement { } else { this._weekday.delete(value); } + this.requestUpdate("_weekday"); } private _onEndSelected(e: CustomEvent>) { From 604c452ff4559a27ccfc7dbbabcbf5a706fc2dce Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 10 Jan 2023 19:04:27 +0100 Subject: [PATCH 6/6] Bumped version to 20230110.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9ecc1b760d..03523eb7c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20230104.0" +version = "20230110.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md"