mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 19:26:36 +00:00
20231027.0 (#18448)
This commit is contained in:
commit
3d674cf237
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "home-assistant-frontend"
|
name = "home-assistant-frontend"
|
||||||
version = "20231026.0"
|
version = "20231027.0"
|
||||||
license = {text = "Apache-2.0"}
|
license = {text = "Apache-2.0"}
|
||||||
description = "The Home Assistant frontend"
|
description = "The Home Assistant frontend"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -14,7 +14,7 @@ export const slugify = (value: string, delimiter = "_") => {
|
|||||||
.toString()
|
.toString()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
|
.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(/[^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})\\1+`, "g"), "$1") // Replace multiple delimiters with single delimiter
|
||||||
.replace(new RegExp(`^${delimiter}+`), "") // Trim delimiter from start of text
|
.replace(new RegExp(`^${delimiter}+`), "") // Trim delimiter from start of text
|
||||||
|
@ -20,6 +20,10 @@ export class HaButton extends Button {
|
|||||||
.trailing-icon {
|
.trailing-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
.slot-container {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ export class HaDateRangePicker extends LitElement {
|
|||||||
|
|
||||||
@property() public ranges?: DateRangePickerRanges | false;
|
@property() public ranges?: DateRangePickerRanges | false;
|
||||||
|
|
||||||
|
@state() private _ranges?: DateRangePickerRanges;
|
||||||
|
|
||||||
@property() public autoApply = false;
|
@property() public autoApply = false;
|
||||||
|
|
||||||
@property() public timePicker = true;
|
@property() public timePicker = true;
|
||||||
@ -93,7 +95,7 @@ export class HaDateRangePicker extends LitElement {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.ranges = {
|
this._ranges = {
|
||||||
[this.hass.localize("ui.components.date-range-picker.ranges.today")]: [
|
[this.hass.localize("ui.components.date-range-picker.ranges.today")]: [
|
||||||
calcDate(today, startOfDay, this.hass.locale, this.hass.config, {
|
calcDate(today, startOfDay, this.hass.locale, this.hass.config, {
|
||||||
weekStartsOn,
|
weekStartsOn,
|
||||||
@ -206,15 +208,15 @@ export class HaDateRangePicker extends LitElement {
|
|||||||
.path=${mdiCalendar}
|
.path=${mdiCalendar}
|
||||||
></ha-icon-button>`}
|
></ha-icon-button>`}
|
||||||
</div>
|
</div>
|
||||||
${this.ranges
|
${this.ranges !== false && (this.ranges || this._ranges)
|
||||||
? html`<div
|
? html`<div
|
||||||
slot="ranges"
|
slot="ranges"
|
||||||
class="date-range-ranges"
|
class="date-range-ranges"
|
||||||
.dir=${this._rtlDirection}
|
.dir=${this._rtlDirection}
|
||||||
>
|
>
|
||||||
<mwc-list @action=${this._setDateRange} activatable>
|
<mwc-list @action=${this._setDateRange} activatable>
|
||||||
${Object.keys(this.ranges).map(
|
${Object.keys(this.ranges || this._ranges!).map(
|
||||||
(name) => html`<mwc-list-item> ${name} </mwc-list-item>`
|
(name) => html`<mwc-list-item>${name}</mwc-list-item>`
|
||||||
)}
|
)}
|
||||||
</mwc-list>
|
</mwc-list>
|
||||||
</div>`
|
</div>`
|
||||||
@ -234,7 +236,9 @@ export class HaDateRangePicker extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _setDateRange(ev: CustomEvent<ActionDetail>) {
|
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;
|
const dateRangePicker = this._dateRangePicker;
|
||||||
dateRangePicker.clickRange(dateRange);
|
dateRangePicker.clickRange(dateRange);
|
||||||
dateRangePicker.clickedApply();
|
dateRangePicker.clickedApply();
|
||||||
|
@ -94,6 +94,8 @@ export class HaDialog extends DialogBase {
|
|||||||
}
|
}
|
||||||
.mdc-dialog__title {
|
.mdc-dialog__title {
|
||||||
padding: 24px 24px 0 24px;
|
padding: 24px 24px 0 24px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.mdc-dialog__actions {
|
.mdc-dialog__actions {
|
||||||
padding: 12px 24px 12px 24px;
|
padding: 12px 24px 12px 24px;
|
||||||
|
@ -200,6 +200,8 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
|||||||
|
|
||||||
this._name = this.entry.name || "";
|
this._name = this.entry.name || "";
|
||||||
this._icon = this.entry.icon || "";
|
this._icon = this.entry.icon || "";
|
||||||
|
this._deviceClass =
|
||||||
|
this.entry.device_class || this.entry.original_device_class;
|
||||||
this._origEntityId = this.entry.entity_id;
|
this._origEntityId = this.entry.entity_id;
|
||||||
this._areaId = this.entry.area_id;
|
this._areaId = this.entry.area_id;
|
||||||
this._entityId = this.entry.entity_id;
|
this._entityId = this.entry.entity_id;
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import { mdiPlus } from "@mdi/js";
|
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 { customElement, property, state } from "lit/decorators";
|
||||||
import memoize from "memoize-one";
|
import memoize from "memoize-one";
|
||||||
import { stringCompare } from "../../../../common/string/compare";
|
import { stringCompare } from "../../../../common/string/compare";
|
||||||
@ -7,6 +14,7 @@ import {
|
|||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
} from "../../../../components/data-table/ha-data-table";
|
} from "../../../../components/data-table/ha-data-table";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
import "../../../../components/ha-fab";
|
import "../../../../components/ha-fab";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
@ -21,7 +29,9 @@ import {
|
|||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
} from "../../../../dialogs/generic/show-dialog-box";
|
} from "../../../../dialogs/generic/show-dialog-box";
|
||||||
import "../../../../layouts/hass-loading-screen";
|
import "../../../../layouts/hass-loading-screen";
|
||||||
|
import "../../../../layouts/hass-subpage";
|
||||||
import "../../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../../layouts/hass-tabs-subpage-data-table";
|
||||||
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import { HomeAssistant, Route } from "../../../../types";
|
import { HomeAssistant, Route } from "../../../../types";
|
||||||
import { loadLovelaceResources } from "../../../lovelace/common/load-resources";
|
import { loadLovelaceResources } from "../../../lovelace/common/load-resources";
|
||||||
import { lovelaceTabs } from "../ha-config-lovelace";
|
import { lovelaceTabs } from "../ha-config-lovelace";
|
||||||
@ -72,6 +82,36 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
return html` <hass-loading-screen></hass-loading-screen> `;
|
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`
|
return html`
|
||||||
<hass-tabs-subpage-data-table
|
<hass-tabs-subpage-data-table
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ class HaPanelDevState extends LitElement {
|
|||||||
autofocus
|
autofocus
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._entityId}
|
.value=${this._entityId}
|
||||||
@change=${this._entityIdChanged}
|
@value-changed=${this._entityIdChanged}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
item-label-path="entity_id"
|
item-label-path="entity_id"
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
@ -347,7 +347,8 @@ class HaPanelDevState extends LitElement {
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityIdChanged() {
|
private _entityIdChanged(ev: CustomEvent) {
|
||||||
|
this._entityId = ev.detail.value;
|
||||||
if (!this._entityId) {
|
if (!this._entityId) {
|
||||||
this._entity = undefined;
|
this._entity = undefined;
|
||||||
this._state = "";
|
this._state = "";
|
||||||
|
@ -48,6 +48,9 @@ class PanelEnergy extends LitElement {
|
|||||||
if (oldHass?.locale !== this.hass.locale) {
|
if (oldHass?.locale !== this.hass.locale) {
|
||||||
this._setLovelace();
|
this._setLovelace();
|
||||||
}
|
}
|
||||||
|
if (oldHass && oldHass.localize !== this.hass.localize) {
|
||||||
|
this._reloadView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
@ -135,10 +135,14 @@ export class HuiTodoListCard
|
|||||||
|
|
||||||
public hassSubscribe(): Promise<UnsubscribeFunc>[] {
|
public hassSubscribe(): Promise<UnsubscribeFunc>[] {
|
||||||
return [
|
return [
|
||||||
this.hass!.connection.subscribeEvents(
|
this.hass!.connection.subscribeEvents(() => {
|
||||||
() => this._fetchData(),
|
if (
|
||||||
"shopping_list_updated"
|
this._entityId &&
|
||||||
),
|
this.hass!.entities[this._entityId]?.platform === "shopping_list"
|
||||||
|
) {
|
||||||
|
this._fetchData();
|
||||||
|
}
|
||||||
|
}, "shopping_list_updated"),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +163,15 @@ export class HuiTodoListCard
|
|||||||
) {
|
) {
|
||||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
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() {
|
protected render() {
|
||||||
|
@ -10,11 +10,6 @@ export const loadLovelaceResources = (
|
|||||||
resources: NonNullable<LovelaceResource[]>,
|
resources: NonNullable<LovelaceResource[]>,
|
||||||
hass: HomeAssistant
|
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) => {
|
resources.forEach((resource) => {
|
||||||
const normalizedUrl = new URL(
|
const normalizedUrl = new URL(
|
||||||
resource.url,
|
resource.url,
|
||||||
|
@ -65,7 +65,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() _endDate?: Date;
|
@state() _endDate?: Date;
|
||||||
|
|
||||||
@state() private _ranges?: DateRangePickerRanges;
|
@state() private _ranges: DateRangePickerRanges = {};
|
||||||
|
|
||||||
@state() private _compare = false;
|
@state() private _compare = false;
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ import { ResizeController } from "@lit-labs/observers/resize-controller";
|
|||||||
import "@material/mwc-list";
|
import "@material/mwc-list";
|
||||||
import {
|
import {
|
||||||
mdiChevronDown,
|
mdiChevronDown,
|
||||||
|
mdiCommentProcessingOutline,
|
||||||
mdiDelete,
|
mdiDelete,
|
||||||
mdiDotsVertical,
|
mdiDotsVertical,
|
||||||
mdiInformationOutline,
|
mdiInformationOutline,
|
||||||
mdiMicrophone,
|
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
@ -173,11 +173,13 @@ class PanelTodo extends LitElement {
|
|||||||
.x=${this.mobile ? 0 : undefined}
|
.x=${this.mobile ? 0 : undefined}
|
||||||
>
|
>
|
||||||
<ha-button slot="trigger">
|
<ha-button slot="trigger">
|
||||||
${this._entityId
|
<div>
|
||||||
? this._entityId in this.hass.states
|
${this._entityId
|
||||||
? computeStateName(this.hass.states[this._entityId])
|
? this._entityId in this.hass.states
|
||||||
: this._entityId
|
? computeStateName(this.hass.states[this._entityId])
|
||||||
: ""}
|
: this._entityId
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
slot="trailingIcon"
|
slot="trailingIcon"
|
||||||
.path=${mdiChevronDown}
|
.path=${mdiChevronDown}
|
||||||
@ -190,7 +192,7 @@ class PanelTodo extends LitElement {
|
|||||||
${this.hass.localize("ui.panel.todo.create_list")}
|
${this.hass.localize("ui.panel.todo.create_list")}
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</ha-button-menu>`
|
</ha-button-menu>`
|
||||||
: "Lists"}
|
: this.hass.localize("panel.todo")}
|
||||||
</div>
|
</div>
|
||||||
<mwc-list slot="pane" activatable>${listItems}</mwc-list>
|
<mwc-list slot="pane" activatable>${listItems}</mwc-list>
|
||||||
<ha-list-item graphic="icon" slot="pane-footer" @click=${this._addList}>
|
<ha-list-item graphic="icon" slot="pane-footer" @click=${this._addList}>
|
||||||
@ -216,8 +218,9 @@ class PanelTodo extends LitElement {
|
|||||||
: nothing}
|
: nothing}
|
||||||
<li divider role="separator"></li>
|
<li divider role="separator"></li>
|
||||||
<ha-list-item graphic="icon" @click=${this._showVoiceCommandDialog}>
|
<ha-list-item graphic="icon" @click=${this._showVoiceCommandDialog}>
|
||||||
<ha-svg-icon .path=${mdiMicrophone} slot="graphic"> </ha-svg-icon>
|
<ha-svg-icon .path=${mdiCommentProcessingOutline} slot="graphic">
|
||||||
${this.hass.localize("ui.panel.todo.start_conversation")}
|
</ha-svg-icon>
|
||||||
|
${this.hass.localize("ui.panel.todo.assist")}
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
${entityRegistryEntry?.platform === "local_todo"
|
${entityRegistryEntry?.platform === "local_todo"
|
||||||
? html` <li divider role="separator"></li>
|
? html` <li divider role="separator"></li>
|
||||||
@ -335,11 +338,18 @@ class PanelTodo extends LitElement {
|
|||||||
:host([mobile]) .lists {
|
:host([mobile]) .lists {
|
||||||
--mdc-menu-min-width: 100vw;
|
--mdc-menu-min-width: 100vw;
|
||||||
}
|
}
|
||||||
|
:host(:not([mobile])) .lists ha-list-item {
|
||||||
|
max-width: calc(100vw - 120px);
|
||||||
|
}
|
||||||
:host([mobile]) ha-button-menu {
|
:host([mobile]) ha-button-menu {
|
||||||
--mdc-shape-medium: 0 0 var(--mdc-shape-medium)
|
--mdc-shape-medium: 0 0 var(--mdc-shape-medium)
|
||||||
var(--mdc-shape-medium);
|
var(--mdc-shape-medium);
|
||||||
}
|
}
|
||||||
|
ha-button-menu {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
ha-button-menu ha-button {
|
ha-button-menu ha-button {
|
||||||
|
max-width: 100%;
|
||||||
--mdc-theme-primary: currentColor;
|
--mdc-theme-primary: currentColor;
|
||||||
--mdc-typography-button-text-transform: none;
|
--mdc-typography-button-text-transform: none;
|
||||||
--mdc-typography-button-font-size: var(
|
--mdc-typography-button-font-size: var(
|
||||||
@ -360,6 +370,13 @@ class PanelTodo extends LitElement {
|
|||||||
);
|
);
|
||||||
--button-height: 40px;
|
--button-height: 40px;
|
||||||
}
|
}
|
||||||
|
ha-button-menu ha-button div {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -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
|
// on reconnect always fetch config as we might miss an update while we were disconnected
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.hass!.callWS({ type: "get_config" }).then((config: HassConfig) => {
|
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._updateHass({ config });
|
||||||
this.checkDataBaseMigration();
|
this.checkDataBaseMigration();
|
||||||
});
|
});
|
||||||
|
@ -2140,6 +2140,8 @@
|
|||||||
"js": "JavaScript file (deprecated)",
|
"js": "JavaScript file (deprecated)",
|
||||||
"module": "JavaScript module"
|
"module": "JavaScript module"
|
||||||
},
|
},
|
||||||
|
"unavailable": "Resources unavailable",
|
||||||
|
"unavailable_safe_mode": "Resources are not available in safe mode",
|
||||||
"picker": {
|
"picker": {
|
||||||
"headers": {
|
"headers": {
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
@ -4520,7 +4522,6 @@
|
|||||||
"never_triggered": "Never triggered"
|
"never_triggered": "Never triggered"
|
||||||
},
|
},
|
||||||
"todo-list": {
|
"todo-list": {
|
||||||
"lists": "To-do Lists",
|
|
||||||
"checked_items": "Checked items",
|
"checked_items": "Checked items",
|
||||||
"clear_items": "Clear checked items",
|
"clear_items": "Clear checked items",
|
||||||
"add_item": "Add item",
|
"add_item": "Add item",
|
||||||
@ -5094,7 +5095,7 @@
|
|||||||
"description": "The Sensor card gives you a quick overview of your sensors state with an optional graph to visualize change over time."
|
"description": "The Sensor card gives you a quick overview of your sensors state with an optional graph to visualize change over time."
|
||||||
},
|
},
|
||||||
"todo-list": {
|
"todo-list": {
|
||||||
"name": "Todo list",
|
"name": "To-do list",
|
||||||
"description": "The to-do list card allows you to add, edit, check-off, and clear items from your to-do list.",
|
"description": "The to-do list card allows you to add, edit, check-off, and clear items from your to-do list.",
|
||||||
"integration_not_loaded": "This card requires the `todo` integration to be set up."
|
"integration_not_loaded": "This card requires the `todo` integration to be set up."
|
||||||
},
|
},
|
||||||
@ -5515,7 +5516,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"todo": {
|
"todo": {
|
||||||
"start_conversation": "Start conversation",
|
"assist": "[%key:ui::panel::lovelace::menu::assist%]",
|
||||||
"create_list": "Create list",
|
"create_list": "Create list",
|
||||||
"delete_list": "Delete list",
|
"delete_list": "Delete list",
|
||||||
"information": "Information",
|
"information": "Information",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user