mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
20230102.0 (#14963)
This commit is contained in:
commit
ebb19e4ed5
@ -71,7 +71,6 @@ class HaDemo extends HomeAssistantAppEl {
|
||||
entity_category: null,
|
||||
has_entity_name: false,
|
||||
unique_id: "co2_intensity",
|
||||
aliases: [],
|
||||
},
|
||||
{
|
||||
config_entry_id: "co2signal",
|
||||
@ -87,7 +86,6 @@ class HaDemo extends HomeAssistantAppEl {
|
||||
entity_category: null,
|
||||
has_entity_name: false,
|
||||
unique_id: "grid_fossil_fuel_percentage",
|
||||
aliases: [],
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -197,7 +197,6 @@ const createEntityRegistryEntries = (
|
||||
platform: "updater",
|
||||
has_entity_name: false,
|
||||
unique_id: "updater",
|
||||
aliases: [],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20221230.0"
|
||||
version = "20230102.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -28,7 +28,7 @@ class StateInfo extends LitElement {
|
||||
|
||||
const name = computeStateName(this.stateObj);
|
||||
|
||||
return html` <state-badge
|
||||
return html`<state-badge
|
||||
.stateObj=${this.stateObj}
|
||||
.stateColor=${true}
|
||||
.color=${this.color}
|
||||
|
@ -3,10 +3,12 @@ import { styles } from "@material/mwc-dialog/mwc-dialog.css";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { css, html, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-icon-button";
|
||||
|
||||
const SUPPRESS_DEFAULT_PRESS_SELECTOR = ["button"];
|
||||
|
||||
export const createCloseHeading = (
|
||||
hass: HomeAssistant,
|
||||
title: string | TemplateResult
|
||||
@ -32,6 +34,14 @@ export class HaDialog extends DialogBase {
|
||||
return html`<slot name="heading"> ${super.renderHeading()} </slot>`;
|
||||
}
|
||||
|
||||
protected firstUpdated(): void {
|
||||
super.firstUpdated();
|
||||
this.suppressDefaultPressSelector = [
|
||||
this.suppressDefaultPressSelector,
|
||||
SUPPRESS_DEFAULT_PRESS_SELECTOR,
|
||||
].join(", ");
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
styles,
|
||||
css`
|
||||
|
@ -67,6 +67,9 @@ export class HaFormInteger extends LitElement implements HaFormElement {
|
||||
@change=${this._valueChanged}
|
||||
></ha-slider>
|
||||
</div>
|
||||
${this.helper
|
||||
? html`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`
|
||||
: ""}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ export interface EntityRegistryEntry {
|
||||
original_name?: string;
|
||||
unique_id: string;
|
||||
translation_key?: string;
|
||||
aliases: string[];
|
||||
}
|
||||
|
||||
export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
|
||||
@ -30,6 +29,7 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
|
||||
original_icon?: string;
|
||||
device_class?: string;
|
||||
original_device_class?: string;
|
||||
aliases: string[];
|
||||
}
|
||||
|
||||
export interface UpdateEntityRegistryEntryResult {
|
||||
|
@ -6,6 +6,7 @@ import type { Options, WeekdayStr } from "rrule";
|
||||
import { ByWeekday, RRule, Weekday } from "rrule";
|
||||
import { firstWeekdayIndex } from "../../common/datetime/first_weekday";
|
||||
import { stopPropagation } from "../../common/dom/stop_propagation";
|
||||
import { LocalizeKeys } from "../../common/translations/localize";
|
||||
import "../../components/ha-chip";
|
||||
import "../../components/ha-list-item";
|
||||
import "../../components/ha-select";
|
||||
@ -19,12 +20,10 @@ import {
|
||||
getWeekday,
|
||||
getWeekdays,
|
||||
getMonthlyRepeatItems,
|
||||
intervalSuffix,
|
||||
RepeatEnd,
|
||||
RepeatFrequency,
|
||||
ruleByWeekDay,
|
||||
untilValue,
|
||||
WEEKDAY_NAME,
|
||||
MonthlyRepeatItem,
|
||||
getMonthlyRepeatWeekdayFromRule,
|
||||
getMonthdayRepeatFromRule,
|
||||
@ -174,18 +173,36 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
return html`
|
||||
<ha-select
|
||||
id="freq"
|
||||
label="Repeat"
|
||||
label=${this.hass.localize("ui.components.calendar.event.repeat.label")}
|
||||
@selected=${this._onRepeatSelected}
|
||||
@closed=${stopPropagation}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
.value=${this._freq}
|
||||
>
|
||||
<ha-list-item value="none">None</ha-list-item>
|
||||
<ha-list-item value="yearly">Yearly</ha-list-item>
|
||||
<ha-list-item value="monthly">Monthly</ha-list-item>
|
||||
<ha-list-item value="weekly">Weekly</ha-list-item>
|
||||
<ha-list-item value="daily">Daily</ha-list-item>
|
||||
<ha-list-item value="none">
|
||||
${this.hass.localize("ui.components.calendar.event.repeat.freq.none")}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="yearly">
|
||||
${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.freq.yearly"
|
||||
)}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="monthly">
|
||||
${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.freq.monthly"
|
||||
)}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="weekly">
|
||||
${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.freq.weekly"
|
||||
)}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="daily">
|
||||
${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.freq.daily"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-select>
|
||||
`;
|
||||
}
|
||||
@ -196,7 +213,9 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
${this._monthlyRepeatItems.length > 0
|
||||
? html`<ha-select
|
||||
id="monthly"
|
||||
label="Repeat Monthly"
|
||||
label=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.monthly.label"
|
||||
)}
|
||||
@selected=${this._onMonthlyDetailSelected}
|
||||
.value=${this._monthlyRepeat || this._monthlyRepeatItems[0]?.value}
|
||||
@closed=${stopPropagation}
|
||||
@ -225,7 +244,11 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
.value=${item}
|
||||
class=${classMap({ active: this._weekday.has(item) })}
|
||||
@click=${this._onWeekdayToggle}
|
||||
>${WEEKDAY_NAME[item]}</ha-chip
|
||||
>${this.hass.localize(
|
||||
`ui.components.calendar.event.repeat.weekly.weekday.${
|
||||
item.toLowerCase() as Lowercase<WeekdayStr>
|
||||
}`
|
||||
)}</ha-chip
|
||||
>
|
||||
`
|
||||
)}
|
||||
@ -241,11 +264,16 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
return html`
|
||||
<ha-textfield
|
||||
id="interval"
|
||||
label="Repeat interval"
|
||||
label=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.interval.label"
|
||||
)}
|
||||
type="number"
|
||||
min="1"
|
||||
.value=${this._interval}
|
||||
.suffix=${intervalSuffix(this._freq!)}
|
||||
.suffix=${this.hass.localize(
|
||||
`ui.components.calendar.event.repeat.interval.${this
|
||||
._freq!}` as LocalizeKeys
|
||||
)}
|
||||
@change=${this._onIntervalChange}
|
||||
></ha-textfield>
|
||||
`;
|
||||
@ -255,26 +283,38 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
return html`
|
||||
<ha-select
|
||||
id="end"
|
||||
label="Ends"
|
||||
label=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.end.label"
|
||||
)}
|
||||
.value=${this._end}
|
||||
@selected=${this._onEndSelected}
|
||||
@closed=${stopPropagation}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
>
|
||||
<ha-list-item value="never">Never</ha-list-item>
|
||||
<ha-list-item value="after">After</ha-list-item>
|
||||
<ha-list-item value="on">On</ha-list-item>
|
||||
<ha-list-item value="never">
|
||||
${this.hass.localize("ui.components.calendar.event.repeat.end.never")}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="after">
|
||||
${this.hass.localize("ui.components.calendar.event.repeat.end.after")}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="on">
|
||||
${this.hass.localize("ui.components.calendar.event.repeat.end.on")}
|
||||
</ha-list-item>
|
||||
</ha-select>
|
||||
${this._end === "after"
|
||||
? html`
|
||||
<ha-textfield
|
||||
id="after"
|
||||
label="End after"
|
||||
label=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.end_after.label"
|
||||
)}
|
||||
type="number"
|
||||
min="1"
|
||||
.value=${this._count!}
|
||||
suffix="ocurrences"
|
||||
suffix=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.end_after.ocurrences"
|
||||
)}
|
||||
@change=${this._onCountChange}
|
||||
></ha-textfield>
|
||||
`
|
||||
@ -283,7 +323,9 @@ export class RecurrenceRuleEditor extends LitElement {
|
||||
? html`
|
||||
<ha-date-input
|
||||
id="on"
|
||||
label="End on"
|
||||
label=${this.hass.localize(
|
||||
"ui.components.calendar.event.repeat.end_on.label"
|
||||
)}
|
||||
.locale=${this.locale}
|
||||
.value=${this._until!.toISOString()}
|
||||
@value-changed=${this._onUntilChange}
|
||||
|
@ -42,16 +42,6 @@ export interface MonthlyRepeatItem {
|
||||
label: string;
|
||||
}
|
||||
|
||||
export function intervalSuffix(freq: RepeatFrequency) {
|
||||
if (freq === "monthly") {
|
||||
return "months";
|
||||
}
|
||||
if (freq === "weekly") {
|
||||
return "weeks";
|
||||
}
|
||||
return "days";
|
||||
}
|
||||
|
||||
export function untilValue(freq: RepeatFrequency): Date {
|
||||
const today = new Date();
|
||||
const increment = DEFAULT_COUNT[freq];
|
||||
@ -102,16 +92,6 @@ export const convertRepeatFrequency = (
|
||||
}
|
||||
};
|
||||
|
||||
export const WEEKDAY_NAME = {
|
||||
SU: "Sun",
|
||||
MO: "Mon",
|
||||
TU: "Tue",
|
||||
WE: "Wed",
|
||||
TH: "Thu",
|
||||
FR: "Fri",
|
||||
SA: "Sat",
|
||||
};
|
||||
|
||||
export const WEEKDAYS = [
|
||||
RRule.SU,
|
||||
RRule.MO,
|
||||
|
@ -541,15 +541,10 @@ export class HaAutomationTrace extends LitElement {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
background-color: var(--card-background-color);
|
||||
}
|
||||
|
||||
.linkButton {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.trace-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ export class HaCalendarTrigger extends LitElement implements TriggerElement {
|
||||
],
|
||||
],
|
||||
},
|
||||
{ name: "offset", selector: { duration: { enable_day: true } } },
|
||||
{ name: "offset", selector: { duration: {} } },
|
||||
{
|
||||
name: "offset_type",
|
||||
type: "select",
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
mdiFormatListChecks,
|
||||
mdiSync,
|
||||
} from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
@ -43,20 +42,20 @@ import {
|
||||
} from "../../../../data/cloud";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
getExtendedEntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../../data/entity_registry";
|
||||
import { showDomainTogglerDialog } from "../../../../dialogs/domain-toggler/show-dialog-domain-toggler";
|
||||
import "../../../../layouts/hass-loading-screen";
|
||||
import "../../../../layouts/hass-subpage";
|
||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||
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;
|
||||
const IGNORE_INTERFACES = ["Alexa.EndpointHealth"];
|
||||
|
||||
@customElement("cloud-alexa")
|
||||
class CloudAlexa extends SubscribeMixin(LitElement) {
|
||||
class CloudAlexa extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property()
|
||||
@ -171,10 +170,17 @@ class CloudAlexa extends SubscribeMixin(LitElement) {
|
||||
secondary-line
|
||||
@click=${this._showMoreInfo}
|
||||
>
|
||||
${entity.interfaces
|
||||
.filter((ifc) => !IGNORE_INTERFACES.includes(ifc))
|
||||
.map((ifc) => ifc.replace(/(Alexa.|Controller)/g, ""))
|
||||
.join(", ")}
|
||||
${entity.entity_id in this.hass.entities
|
||||
? html`<button
|
||||
class="link"
|
||||
.entityId=${entity.entity_id}
|
||||
@click=${this._openAliasesSettings}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.alexa.manage_aliases"
|
||||
)}
|
||||
</button>`
|
||||
: ""}
|
||||
</state-info>
|
||||
${!emptyFilter
|
||||
? html`${iconButton}`
|
||||
@ -323,23 +329,33 @@ class CloudAlexa extends SubscribeMixin(LitElement) {
|
||||
if (changedProps.has("cloudStatus")) {
|
||||
this._entityConfigs = this.cloudStatus.prefs.alexa_entity_configs;
|
||||
}
|
||||
if (
|
||||
changedProps.has("hass") &&
|
||||
changedProps.get("hass")?.entities !== this.hass.entities
|
||||
) {
|
||||
const categories = {};
|
||||
|
||||
for (const entry of Object.values(this.hass.entities)) {
|
||||
categories[entry.entity_id] = entry.entity_category;
|
||||
}
|
||||
|
||||
this._entityCategories = categories;
|
||||
}
|
||||
}
|
||||
|
||||
protected override hassSubscribe(): (
|
||||
| UnsubscribeFunc
|
||||
| Promise<UnsubscribeFunc>
|
||||
)[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection, (entries) => {
|
||||
const categories = {};
|
||||
|
||||
for (const entry of entries) {
|
||||
categories[entry.entity_id] = entry.entity_category;
|
||||
}
|
||||
|
||||
this._entityCategories = categories;
|
||||
}),
|
||||
];
|
||||
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() {
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
mdiFormatListChecks,
|
||||
mdiSync,
|
||||
} from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
@ -41,7 +40,8 @@ import {
|
||||
} from "../../../../data/cloud";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
getExtendedEntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../../data/entity_registry";
|
||||
import {
|
||||
fetchCloudGoogleEntities,
|
||||
@ -51,15 +51,15 @@ import { showDomainTogglerDialog } from "../../../../dialogs/domain-toggler/show
|
||||
import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../../layouts/hass-loading-screen";
|
||||
import "../../../../layouts/hass-subpage";
|
||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import { buttonLinkStyle, haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { showToast } from "../../../../util/toast";
|
||||
import { showEntityAliasesDialog } from "../../entities/entity-aliases/show-dialog-entity-aliases";
|
||||
|
||||
const DEFAULT_CONFIG_EXPOSE = true;
|
||||
|
||||
@customElement("cloud-google-assistant")
|
||||
class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
class CloudGoogleAssistant extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public cloudStatus!: CloudStatusLoggedIn;
|
||||
@ -174,15 +174,23 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
secondary-line
|
||||
@click=${this._showMoreInfo}
|
||||
>
|
||||
${entity.traits
|
||||
.map((trait) => trait.substr(trait.lastIndexOf(".") + 1))
|
||||
.join(", ")}
|
||||
${entity.entity_id in this.hass.entities
|
||||
? html`<button
|
||||
class="link"
|
||||
.entityId=${entity.entity_id}
|
||||
@click=${this._openAliasesSettings}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.google.manage_aliases"
|
||||
)}
|
||||
</button>`
|
||||
: ""}
|
||||
</state-info>
|
||||
${!emptyFilter
|
||||
? html`${iconButton}`
|
||||
: html`<ha-button-menu
|
||||
corner="BOTTOM_START"
|
||||
.entityId=${stateObj.entity_id}
|
||||
.entityId=${entity.entity_id}
|
||||
@action=${this._exposeChanged}
|
||||
>
|
||||
${iconButton}
|
||||
@ -308,7 +316,7 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
</h3>
|
||||
${!this.narrow
|
||||
? this.hass!.localize(
|
||||
"ui.panel.config.cloud.alexa.exposed",
|
||||
"ui.panel.config.cloud.google.exposed",
|
||||
"selected",
|
||||
selected
|
||||
)
|
||||
@ -329,7 +337,7 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
</h3>
|
||||
${!this.narrow
|
||||
? this.hass!.localize(
|
||||
"ui.panel.config.cloud.alexa.not_exposed",
|
||||
"ui.panel.config.cloud.google.not_exposed",
|
||||
"selected",
|
||||
this._entities.length - selected
|
||||
)
|
||||
@ -354,23 +362,33 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
if (changedProps.has("cloudStatus")) {
|
||||
this._entityConfigs = this.cloudStatus.prefs.google_entity_configs;
|
||||
}
|
||||
if (
|
||||
changedProps.has("hass") &&
|
||||
changedProps.get("hass")?.entities !== this.hass.entities
|
||||
) {
|
||||
const categories = {};
|
||||
|
||||
for (const entry of Object.values(this.hass.entities)) {
|
||||
categories[entry.entity_id] = entry.entity_category;
|
||||
}
|
||||
|
||||
this._entityCategories = categories;
|
||||
}
|
||||
}
|
||||
|
||||
protected override hassSubscribe(): (
|
||||
| UnsubscribeFunc
|
||||
| Promise<UnsubscribeFunc>
|
||||
)[] {
|
||||
return [
|
||||
subscribeEntityRegistry(this.hass.connection, (entries) => {
|
||||
const categories = {};
|
||||
|
||||
for (const entry of entries) {
|
||||
categories[entry.entity_id] = entry.entity_category;
|
||||
}
|
||||
|
||||
this._entityCategories = categories;
|
||||
}),
|
||||
];
|
||||
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 _configIsDomainExposed(
|
||||
@ -583,6 +601,7 @@ class CloudGoogleAssistant extends SubscribeMixin(LitElement) {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
buttonLinkStyle,
|
||||
css`
|
||||
mwc-list-item > [slot="meta"] {
|
||||
margin-left: 4px;
|
||||
|
@ -57,7 +57,13 @@ export class EntityRegistrySettingsHelper extends LitElement {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has("entry")) {
|
||||
this._error = undefined;
|
||||
this._item = undefined;
|
||||
if (
|
||||
this.entry.unique_id !==
|
||||
(changedProperties.get("entry") as ExtEntityRegistryEntry)?.unique_id
|
||||
) {
|
||||
this._item = undefined;
|
||||
}
|
||||
|
||||
this._getItem();
|
||||
}
|
||||
}
|
||||
|
@ -72,16 +72,21 @@ class DialogEntityAliases extends LitElement {
|
||||
dialogInitialFocus=${index}
|
||||
.index=${index}
|
||||
class="flex-auto"
|
||||
label="Alias"
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases.input_label",
|
||||
{ number: index + 1 }
|
||||
)}
|
||||
.value=${alias}
|
||||
?data-last=${index === this._aliases.length - 1}
|
||||
@change=${this._editAlias}
|
||||
@input=${this._editAlias}
|
||||
@keydown=${this._keyDownAlias}
|
||||
></ha-textfield>
|
||||
<ha-icon-button
|
||||
.index=${index}
|
||||
slot="navigationIcon"
|
||||
label=${this.hass!.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases.remove_alias"
|
||||
"ui.dialogs.entity_registry.editor.aliases.remove_alias",
|
||||
{ number: index + 1 }
|
||||
)}
|
||||
@click=${this._removeAlias}
|
||||
.path=${mdiDeleteOutline}
|
||||
@ -133,6 +138,13 @@ class DialogEntityAliases extends LitElement {
|
||||
this._aliases[index] = (ev.target as any).value;
|
||||
}
|
||||
|
||||
private async _keyDownAlias(ev: KeyboardEvent) {
|
||||
if (ev.key === "Enter") {
|
||||
ev.stopPropagation();
|
||||
this._addAlias();
|
||||
}
|
||||
}
|
||||
|
||||
private async _removeAlias(ev: Event) {
|
||||
const index = (ev.target as any).index;
|
||||
const aliases = [...this._aliases];
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
EntityRegistryEntryUpdateParams,
|
||||
ExtEntityRegistryEntry,
|
||||
} from "../../../../data/entity_registry";
|
||||
|
||||
export interface EntityAliasesDialogParams {
|
||||
entity: EntityRegistryEntry;
|
||||
entity: ExtEntityRegistryEntry;
|
||||
updateEntry: (
|
||||
updates: Partial<EntityRegistryEntryUpdateParams>
|
||||
) => Promise<unknown>;
|
||||
|
@ -1,7 +1,11 @@
|
||||
import "@material/mwc-formfield/mwc-formfield";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiPencil } from "@mdi/js";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import "../../../components/ha-area-picker";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
@ -21,6 +25,7 @@ import {
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { showEntityAliasesDialog } from "./entity-aliases/show-dialog-entity-aliases";
|
||||
|
||||
@customElement("ha-registry-basic-editor")
|
||||
export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
@ -44,6 +49,21 @@ export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
|
||||
@state() private _submitting = false;
|
||||
|
||||
private _handleAliasesClicked(ev: CustomEvent) {
|
||||
if (ev.detail.index !== 0) return;
|
||||
showEntityAliasesDialog(this, {
|
||||
entity: this.entry!,
|
||||
updateEntry: async (updates) => {
|
||||
const result = await updateEntityRegistryEntry(
|
||||
this.hass,
|
||||
this.entry.entity_id,
|
||||
updates
|
||||
);
|
||||
fireEvent(this, "entity-entry-updated", result.entity_entry);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async updateEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
const params: Partial<EntityRegistryEntryUpdateParams> = {
|
||||
@ -247,6 +267,33 @@ export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<div class="label">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases_section"
|
||||
)}
|
||||
</div>
|
||||
<mwc-list class="aliases" @action=${this._handleAliasesClicked}>
|
||||
<mwc-list-item .twoline=${this.entry.aliases.length > 0} hasMeta>
|
||||
<span>
|
||||
${this.entry.aliases.length > 0
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.configured_aliases",
|
||||
{ count: this.entry.aliases.length }
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.no_aliases"
|
||||
)}
|
||||
</span>
|
||||
<span slot="secondary">${this.entry.aliases.join(", ")}</span>
|
||||
<ha-svg-icon slot="meta" .path=${mdiPencil}></ha-svg-icon>
|
||||
</mwc-list-item>
|
||||
</mwc-list>
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.aliases.description"
|
||||
)}
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
}
|
||||
@ -300,6 +347,13 @@ export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
.label {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.aliases {
|
||||
border-radius: 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
--mdc-icon-button-size: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,42 @@ const OVERRIDE_NUMBER_UNITS = {
|
||||
|
||||
const OVERRIDE_SENSOR_UNITS = {
|
||||
current: ["A", "mA"],
|
||||
data_rate: [
|
||||
"bit/s",
|
||||
"kbit/s",
|
||||
"Mbit/s",
|
||||
"Gbit/s",
|
||||
"B/s",
|
||||
"kB/s",
|
||||
"MB/s",
|
||||
"GB/s",
|
||||
"KiB/s",
|
||||
"MiB/s",
|
||||
"GiB/s",
|
||||
],
|
||||
data_size: [
|
||||
"bit",
|
||||
"kbit",
|
||||
"Mbit",
|
||||
"Gbit",
|
||||
"B",
|
||||
"kB",
|
||||
"MB",
|
||||
"GB",
|
||||
"TB",
|
||||
"PB",
|
||||
"EB",
|
||||
"ZB",
|
||||
"YB",
|
||||
"KiB",
|
||||
"MiB",
|
||||
"GiB",
|
||||
"TiB",
|
||||
"PiB",
|
||||
"EiB",
|
||||
"ZiB",
|
||||
"YiB",
|
||||
],
|
||||
distance: ["cm", "ft", "in", "km", "m", "mi", "mm", "yd"],
|
||||
gas: ["CCF", "ft³", "m³"],
|
||||
precipitation: ["cm", "in", "mm"],
|
||||
@ -771,12 +807,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
|
||||
"ui.dialogs.entity_registry.editor.aliases_section"
|
||||
)}
|
||||
</div>
|
||||
<mwc-list class="aliases">
|
||||
<mwc-list-item
|
||||
.twoline=${this.entry.aliases.length > 0}
|
||||
hasMeta
|
||||
@click=${this._openAliasesSettings}
|
||||
>
|
||||
<mwc-list class="aliases" @action=${this._handleAliasesClicked}>
|
||||
<mwc-list-item .twoline=${this.entry.aliases.length > 0} hasMeta>
|
||||
<span>
|
||||
${this.entry.aliases.length > 0
|
||||
? this.hass.localize(
|
||||
@ -979,7 +1011,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
|
||||
});
|
||||
}
|
||||
|
||||
private _openAliasesSettings() {
|
||||
private _handleAliasesClicked(ev: CustomEvent) {
|
||||
if (ev.detail.index !== 0) return;
|
||||
showEntityAliasesDialog(this, {
|
||||
entity: this.entry!,
|
||||
updateEntry: async (updates) => {
|
||||
|
@ -728,7 +728,6 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
selectable: false,
|
||||
entity_category: null,
|
||||
has_entity_name: false,
|
||||
aliases: [],
|
||||
});
|
||||
}
|
||||
if (changed) {
|
||||
|
@ -527,15 +527,10 @@ export class HaScriptTrace extends LitElement {
|
||||
:host([narrow]) .graph {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
background-color: var(--card-background-color);
|
||||
}
|
||||
|
||||
.linkButton {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.trace-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -644,6 +644,33 @@
|
||||
"monthly": "months",
|
||||
"weekly": "weeks",
|
||||
"daily": "days"
|
||||
},
|
||||
"monthly": {
|
||||
"label": "Repeat Monthly"
|
||||
},
|
||||
"weekly": {
|
||||
"weekday": {
|
||||
"su": "Sun",
|
||||
"mo": "Mon",
|
||||
"tu": "Tue",
|
||||
"we": "Wed",
|
||||
"th": "Thu",
|
||||
"fr": "Fri",
|
||||
"sa": "Sat"
|
||||
}
|
||||
},
|
||||
"end": {
|
||||
"label": "End",
|
||||
"never": "Never",
|
||||
"after": "After",
|
||||
"on": "On"
|
||||
},
|
||||
"end_on": {
|
||||
"label": "End On"
|
||||
},
|
||||
"end_after": {
|
||||
"label": "End After",
|
||||
"ocurrences": "ocurrences"
|
||||
}
|
||||
},
|
||||
"rrule": {
|
||||
@ -976,7 +1003,8 @@
|
||||
"aliases": {
|
||||
"heading": "{name} aliases",
|
||||
"description": "Aliases are alternative names used in voice assistants to refer to this entity.",
|
||||
"remove_alias": "Remove alias",
|
||||
"remove_alias": "Remove alias {number}",
|
||||
"input_label": "Alias {number}",
|
||||
"save": "Save",
|
||||
"add_alias": "Add alias",
|
||||
"no_aliases": "No aliases have been added yet",
|
||||
@ -2634,7 +2662,7 @@
|
||||
"enable_state_reporting": "Enable State Reporting",
|
||||
"info_state_reporting": "If you enable state reporting, Home Assistant will send all state changes of exposed entities to Amazon. This allows you to always see the latest states in the Alexa app and use the state changes to create routines.",
|
||||
"state_reporting_error": "Unable to {enable_disable} report state.",
|
||||
"manage_entities": "Manage Entities",
|
||||
"manage_entities": "[%key:ui::panel::config::cloud::account::google::manage_entities%]",
|
||||
"enable": "enable",
|
||||
"disable": "disable",
|
||||
"not_configured_title": "Alexa is not activated",
|
||||
@ -2685,6 +2713,7 @@
|
||||
"follow_domain": "[%key:ui::panel::config::cloud::google::follow_domain%]",
|
||||
"exposed": "[%key:ui::panel::config::cloud::google::exposed%]",
|
||||
"not_exposed": "[%key:ui::panel::config::cloud::google::not_exposed%]",
|
||||
"manage_aliases": "[%key:ui::panel::config::cloud::google::manage_aliases%]",
|
||||
"expose": "Expose to Alexa",
|
||||
"sync_entities": "Synchronize entities",
|
||||
"sync_entities_error": "Failed to sync entities:"
|
||||
@ -2710,6 +2739,7 @@
|
||||
"follow_domain": "Follow domain",
|
||||
"exposed": "{selected} exposed",
|
||||
"not_exposed": "{selected} not exposed",
|
||||
"manage_aliases": "Manage aliases",
|
||||
"sync_to_google": "Synchronizing changes to Google.",
|
||||
"sync_entities": "Synchronize entities",
|
||||
"sync_entities_error": "Failed to sync entities:",
|
||||
|
Loading…
x
Reference in New Issue
Block a user