Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20231027.0 #18448

Merged
merged 10 commits into from
Oct 27, 2023
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "home-assistant-frontend"
version = "20231026.0"
version = "20231027.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion src/common/string/slugify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const slugify = (value: string, delimiter = "_") => {
.toString()
.toLowerCase()
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/(?<=\d),(?=\d)/g, "") // Remove Commas between numbers
.replace(/(\d),(?=\d)/g, "$1") // Remove Commas between numbers
.replace(/[^a-z0-9]+/g, delimiter) // Replace all non-word characters
.replace(new RegExp(`(${delimiter})\\1+`, "g"), "$1") // Replace multiple delimiters with single delimiter
.replace(new RegExp(`^${delimiter}+`), "") // Trim delimiter from start of text
Expand Down
4 changes: 4 additions & 0 deletions src/components/ha-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export class HaButton extends Button {
.trailing-icon {
display: flex;
}
.slot-container {
width: 100%;
overflow: hidden;
}
`,
];
}
Expand Down
14 changes: 9 additions & 5 deletions src/components/ha-date-range-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export class HaDateRangePicker extends LitElement {

@property() public ranges?: DateRangePickerRanges | false;

@state() private _ranges?: DateRangePickerRanges;

@property() public autoApply = false;

@property() public timePicker = true;
Expand Down Expand Up @@ -93,7 +95,7 @@ export class HaDateRangePicker extends LitElement {
}
);

this.ranges = {
this._ranges = {
[this.hass.localize("ui.components.date-range-picker.ranges.today")]: [
calcDate(today, startOfDay, this.hass.locale, this.hass.config, {
weekStartsOn,
Expand Down Expand Up @@ -206,15 +208,15 @@ export class HaDateRangePicker extends LitElement {
.path=${mdiCalendar}
></ha-icon-button>`}
</div>
${this.ranges
${this.ranges !== false && (this.ranges || this._ranges)
? html`<div
slot="ranges"
class="date-range-ranges"
.dir=${this._rtlDirection}
>
<mwc-list @action=${this._setDateRange} activatable>
${Object.keys(this.ranges).map(
(name) => html`<mwc-list-item> ${name} </mwc-list-item>`
${Object.keys(this.ranges || this._ranges!).map(
(name) => html`<mwc-list-item>${name}</mwc-list-item>`
)}
</mwc-list>
</div>`
Expand All @@ -234,7 +236,9 @@ export class HaDateRangePicker extends LitElement {
}

private _setDateRange(ev: CustomEvent<ActionDetail>) {
const dateRange = Object.values(this.ranges!)[ev.detail.index];
const dateRange = Object.values(this.ranges || this._ranges!)[
ev.detail.index
];
const dateRangePicker = this._dateRangePicker;
dateRangePicker.clickRange(dateRange);
dateRangePicker.clickedApply();
Expand Down
2 changes: 2 additions & 0 deletions src/components/ha-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export class HaDialog extends DialogBase {
}
.mdc-dialog__title {
padding: 24px 24px 0 24px;
text-overflow: ellipsis;
overflow: hidden;
}
.mdc-dialog__actions {
padding: 12px 24px 12px 24px;
Expand Down
2 changes: 2 additions & 0 deletions src/panels/config/entities/entity-registry-settings-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ export class EntityRegistrySettingsEditor extends LitElement {

this._name = this.entry.name || "";
this._icon = this.entry.icon || "";
this._deviceClass =
this.entry.device_class || this.entry.original_device_class;
this._origEntityId = this.entry.entity_id;
this._areaId = this.entry.area_id;
this._entityId = this.entry.entity_id;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { mdiPlus } from "@mdi/js";
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import {
css,
CSSResultGroup,
html,
LitElement,
PropertyValues,
TemplateResult,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import memoize from "memoize-one";
import { stringCompare } from "../../../../common/string/compare";
import {
DataTableColumnContainer,
RowClickedEvent,
} from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-card";
import "../../../../components/ha-fab";
import "../../../../components/ha-svg-icon";
import {
Expand All @@ -21,7 +29,9 @@ import {
showConfirmationDialog,
} from "../../../../dialogs/generic/show-dialog-box";
import "../../../../layouts/hass-loading-screen";
import "../../../../layouts/hass-subpage";
import "../../../../layouts/hass-tabs-subpage-data-table";
import { haStyle } from "../../../../resources/styles";
import { HomeAssistant, Route } from "../../../../types";
import { loadLovelaceResources } from "../../../lovelace/common/load-resources";
import { lovelaceTabs } from "../ha-config-lovelace";
Expand Down Expand Up @@ -72,6 +82,36 @@ export class HaConfigLovelaceRescources extends LitElement {
return html` <hass-loading-screen></hass-loading-screen> `;
}

if (this.hass.config.safe_mode) {
return html`
<hass-subpage
.hass=${this.hass}
.narrow=${this.narrow}
back-path="/config"
.header=${this.hass.localize(
"ui.panel.config.lovelace.resources.caption"
)}
>
<div class="content">
<ha-card outlined>
<div class="card-content">
<h2>
${this.hass.localize(
"ui.panel.config.lovelace.resources.unavailable"
)}
</h2>
<p>
${this.hass.localize(
"ui.panel.config.lovelace.resources.unavailable_safe_mode"
)}
</p>
</div>
</ha-card>
</div>
</hass-subpage>
`;
}

return html`
<hass-tabs-subpage-data-table
.hass=${this.hass}
Expand Down Expand Up @@ -192,4 +232,24 @@ export class HaConfigLovelaceRescources extends LitElement {
},
});
}

static get styles(): CSSResultGroup {
return [
haStyle,
css`
.content {
padding: 28px 20px 0;
max-width: 1040px;
margin: 0 auto;
}
h2 {
margin-top: 0;
margin-bottom: 12px;
}
p {
margin: 0;
}
`,
];
}
}
5 changes: 3 additions & 2 deletions src/panels/developer-tools/state/developer-tools-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class HaPanelDevState extends LitElement {
autofocus
.hass=${this.hass}
.value=${this._entityId}
@change=${this._entityIdChanged}
@value-changed=${this._entityIdChanged}
allow-custom-entity
item-label-path="entity_id"
></ha-entity-picker>
Expand Down Expand Up @@ -347,7 +347,8 @@ class HaPanelDevState extends LitElement {
ev.preventDefault();
}

private _entityIdChanged() {
private _entityIdChanged(ev: CustomEvent) {
this._entityId = ev.detail.value;
if (!this._entityId) {
this._entity = undefined;
this._state = "";
Expand Down
3 changes: 3 additions & 0 deletions src/panels/energy/ha-panel-energy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class PanelEnergy extends LitElement {
if (oldHass?.locale !== this.hass.locale) {
this._setLovelace();
}
if (oldHass && oldHass.localize !== this.hass.localize) {
this._reloadView();
}
}

protected render(): TemplateResult {
Expand Down
21 changes: 17 additions & 4 deletions src/panels/lovelace/cards/hui-todo-list-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,14 @@ export class HuiTodoListCard

public hassSubscribe(): Promise<UnsubscribeFunc>[] {
return [
this.hass!.connection.subscribeEvents(
() => this._fetchData(),
"shopping_list_updated"
),
this.hass!.connection.subscribeEvents(() => {
if (
this._entityId &&
this.hass!.entities[this._entityId]?.platform === "shopping_list"
) {
this._fetchData();
}
}, "shopping_list_updated"),
];
}

Expand All @@ -159,6 +163,15 @@ export class HuiTodoListCard
) {
applyThemesOnElement(this, this.hass.themes, this._config.theme);
}

if (
this._entityId &&
oldHass &&
oldHass.states[this._entityId] !== this.hass.states[this._entityId] &&
this.hass.entities[this._entityId]?.platform !== "shopping_list"
) {
this._fetchData();
}
}

protected render() {
Expand Down
5 changes: 0 additions & 5 deletions src/panels/lovelace/common/load-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ export const loadLovelaceResources = (
resources: NonNullable<LovelaceResource[]>,
hass: HomeAssistant
) => {
// Don't load ressources on safe mode
// Sometimes, hass.config is null but it should not.
if (hass.config?.safe_mode) {
return;
}
resources.forEach((resource) => {
const normalizedUrl = new URL(
resource.url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {

@state() _endDate?: Date;

@state() private _ranges?: DateRangePickerRanges;
@state() private _ranges: DateRangePickerRanges = {};

@state() private _compare = false;

Expand Down
35 changes: 26 additions & 9 deletions src/panels/todo/ha-panel-todo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { ResizeController } from "@lit-labs/observers/resize-controller";
import "@material/mwc-list";
import {
mdiChevronDown,
mdiCommentProcessingOutline,
mdiDelete,
mdiDotsVertical,
mdiInformationOutline,
mdiMicrophone,
mdiPlus,
} from "@mdi/js";
import {
Expand Down Expand Up @@ -173,11 +173,13 @@ class PanelTodo extends LitElement {
.x=${this.mobile ? 0 : undefined}
>
<ha-button slot="trigger">
${this._entityId
? this._entityId in this.hass.states
? computeStateName(this.hass.states[this._entityId])
: this._entityId
: ""}
<div>
${this._entityId
? this._entityId in this.hass.states
? computeStateName(this.hass.states[this._entityId])
: this._entityId
: ""}
</div>
<ha-svg-icon
slot="trailingIcon"
.path=${mdiChevronDown}
Expand All @@ -190,7 +192,7 @@ class PanelTodo extends LitElement {
${this.hass.localize("ui.panel.todo.create_list")}
</ha-list-item>
</ha-button-menu>`
: "Lists"}
: this.hass.localize("panel.todo")}
</div>
<mwc-list slot="pane" activatable>${listItems}</mwc-list>
<ha-list-item graphic="icon" slot="pane-footer" @click=${this._addList}>
Expand All @@ -216,8 +218,9 @@ class PanelTodo extends LitElement {
: nothing}
<li divider role="separator"></li>
<ha-list-item graphic="icon" @click=${this._showVoiceCommandDialog}>
<ha-svg-icon .path=${mdiMicrophone} slot="graphic"> </ha-svg-icon>
${this.hass.localize("ui.panel.todo.start_conversation")}
<ha-svg-icon .path=${mdiCommentProcessingOutline} slot="graphic">
</ha-svg-icon>
${this.hass.localize("ui.panel.todo.assist")}
</ha-list-item>
${entityRegistryEntry?.platform === "local_todo"
? html` <li divider role="separator"></li>
Expand Down Expand Up @@ -335,11 +338,18 @@ class PanelTodo extends LitElement {
:host([mobile]) .lists {
--mdc-menu-min-width: 100vw;
}
:host(:not([mobile])) .lists ha-list-item {
max-width: calc(100vw - 120px);
}
:host([mobile]) ha-button-menu {
--mdc-shape-medium: 0 0 var(--mdc-shape-medium)
var(--mdc-shape-medium);
}
ha-button-menu {
max-width: 100%;
}
ha-button-menu ha-button {
max-width: 100%;
--mdc-theme-primary: currentColor;
--mdc-typography-button-text-transform: none;
--mdc-typography-button-font-size: var(
Expand All @@ -360,6 +370,13 @@ class PanelTodo extends LitElement {
);
--button-height: 40px;
}
ha-button-menu ha-button div {
text-overflow: ellipsis;
width: 100%;
overflow: hidden;
white-space: nowrap;
display: block;
}
`,
];
}
Expand Down
4 changes: 4 additions & 0 deletions src/state/connection-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
// on reconnect always fetch config as we might miss an update while we were disconnected
// @ts-ignore
this.hass!.callWS({ type: "get_config" }).then((config: HassConfig) => {
if (config.safe_mode) {
// @ts-ignore Firefox supports forceGet
location.reload(true);
}
this._updateHass({ config });
this.checkDataBaseMigration();
});
Expand Down
Loading
Loading