Fix localize key errors for helpers (#14496)

This commit is contained in:
Steve Repsher 2022-12-05 08:22:17 -05:00 committed by GitHub
parent 7e58bd59c3
commit 00274ebf66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 47 additions and 30 deletions

View File

@ -0,0 +1,5 @@
// Creates a type predicate function for determining if an array literal includes a given value
export const arrayLiteralIncludes =
<T extends readonly unknown[]>(array: T) =>
(searchElement: unknown, fromIndex?: number): searchElement is T[number] =>
array.includes(searchElement as T[number], fromIndex);

View File

@ -30,7 +30,6 @@ export type LocalizeKeys =
| `ui.panel.config.dashboard.${string}` | `ui.panel.config.dashboard.${string}`
| `ui.panel.config.devices.${string}` | `ui.panel.config.devices.${string}`
| `ui.panel.config.energy.${string}` | `ui.panel.config.energy.${string}`
| `ui.panel.config.helpers.${string}`
| `ui.panel.config.info.${string}` | `ui.panel.config.info.${string}`
| `ui.panel.config.logs.${string}` | `ui.panel.config.logs.${string}`
| `ui.panel.config.lovelace.${string}` | `ui.panel.config.lovelace.${string}`

View File

@ -3,7 +3,7 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { ensureArray } from "../../common/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { stringCompare } from "../../common/string/compare"; import { stringCompare } from "../../common/string/compare";
import { import {

View File

@ -18,7 +18,7 @@ import { css, CSSResultGroup, html, LitElement, unsafeCSS } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { ensureArray } from "../common/ensure-array"; import { ensureArray } from "../common/array/ensure-array";
import { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
import { computeStateName } from "../common/entity/compute_state_name"; import { computeStateName } from "../common/entity/compute_state_name";
import { import {

View File

@ -25,7 +25,7 @@ import {
import { css, html, LitElement, PropertyValues } from "lit"; import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { ensureArray } from "../../common/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import { Condition, Trigger } from "../../data/automation"; import { Condition, Trigger } from "../../data/automation";
import { import {
Action, Action,

View File

@ -1,6 +1,6 @@
import { formatDuration } from "../common/datetime/format_duration"; import { formatDuration } from "../common/datetime/format_duration";
import secondsToDuration from "../common/datetime/seconds_to_duration"; import secondsToDuration from "../common/datetime/seconds_to_duration";
import { ensureArray } from "../common/ensure-array"; import { ensureArray } from "../common/array/ensure-array";
import { computeStateName } from "../common/entity/compute_state_name"; import { computeStateName } from "../common/entity/compute_state_name";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
import { Condition, Trigger } from "./automation"; import { Condition, Trigger } from "./automation";

View File

@ -15,6 +15,7 @@ import {
Describe, Describe,
boolean, boolean,
} from "superstruct"; } from "superstruct";
import { arrayLiteralIncludes } from "../common/array/literal-includes";
import { navigate } from "../common/navigate"; import { navigate } from "../common/navigate";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { import {
@ -28,11 +29,7 @@ import { BlueprintInput } from "./blueprint";
export const MODES = ["single", "restart", "queued", "parallel"] as const; export const MODES = ["single", "restart", "queued", "parallel"] as const;
export const MODES_MAX = ["queued", "parallel"] as const; export const MODES_MAX = ["queued", "parallel"] as const;
export const isMaxMode = arrayLiteralIncludes(MODES_MAX);
export const isMaxMode = (
mode: typeof MODES[number]
): mode is typeof MODES_MAX[number] =>
MODES_MAX.includes(mode as typeof MODES_MAX[number]);
export const baseActionStruct = object({ export const baseActionStruct = object({
alias: optional(string()), alias: optional(string()),

View File

@ -1,6 +1,6 @@
import { formatDuration } from "../common/datetime/format_duration"; import { formatDuration } from "../common/datetime/format_duration";
import secondsToDuration from "../common/datetime/seconds_to_duration"; import secondsToDuration from "../common/datetime/seconds_to_duration";
import { ensureArray } from "../common/ensure-array"; import { ensureArray } from "../common/array/ensure-array";
import { computeStateName } from "../common/entity/compute_state_name"; import { computeStateName } from "../common/entity/compute_state_name";
import { isTemplate } from "../common/string/has-template"; import { isTemplate } from "../common/string/has-template";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";

View File

@ -2,7 +2,7 @@ import { mdiDelete, mdiPlus } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement } from "lit"; import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import { ensureArray } from "../../../../../common/ensure-array"; import { ensureArray } from "../../../../../common/array/ensure-array";
import "../../../../../components/ha-icon-button"; import "../../../../../components/ha-icon-button";
import { Condition } from "../../../../../data/automation"; import { Condition } from "../../../../../data/automation";
import { Action, ChooseAction } from "../../../../../data/script"; import { Action, ChooseAction } from "../../../../../data/script";

View File

@ -10,7 +10,7 @@ import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
import "../../../../../components/ha-duration-input"; import "../../../../../components/ha-duration-input";
import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { TimeChangedEvent } from "../../../../../components/ha-base-time-input"; import { TimeChangedEvent } from "../../../../../components/ha-base-time-input";
import { ensureArray } from "../../../../../common/ensure-array"; import { ensureArray } from "../../../../../common/array/ensure-array";
@customElement("ha-automation-action-wait_for_trigger") @customElement("ha-automation-action-wait_for_trigger")
export class HaWaitForTriggerAction export class HaWaitForTriggerAction

View File

@ -3,7 +3,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { html, LitElement } from "lit"; import { html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import { ensureArray } from "../../../../../common/ensure-array"; import { ensureArray } from "../../../../../common/array/ensure-array";
import "../../../../../components/ha-select"; import "../../../../../components/ha-select";
import type { import type {
AutomationConfig, AutomationConfig,

View File

@ -11,7 +11,7 @@ import {
union, union,
} from "superstruct"; } from "superstruct";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { ensureArray } from "../../../../../common/ensure-array"; import { ensureArray } from "../../../../../common/array/ensure-array";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template"; import { hasTemplate } from "../../../../../common/string/has-template";
import { StateTrigger } from "../../../../../data/automation"; import { StateTrigger } from "../../../../../data/automation";

View File

@ -1,3 +1,4 @@
import { arrayLiteralIncludes } from "../../../common/array/literal-includes";
import type { Counter } from "../../../data/counter"; import type { Counter } from "../../../data/counter";
import type { InputBoolean } from "../../../data/input_boolean"; import type { InputBoolean } from "../../../data/input_boolean";
import type { InputButton } from "../../../data/input_button"; import type { InputButton } from "../../../data/input_button";
@ -18,7 +19,10 @@ export const HELPER_DOMAINS = [
"counter", "counter",
"timer", "timer",
"schedule", "schedule",
]; ] as const;
export type HelperDomain = typeof HELPER_DOMAINS[number];
export const isHelperDomain = arrayLiteralIncludes(HELPER_DOMAINS);
export type Helper = export type Helper =
| InputBoolean | InputBoolean

View File

@ -25,7 +25,7 @@ import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-c
import { haStyleDialog } from "../../../resources/styles"; import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url"; import { brandsUrl } from "../../../util/brands-url";
import { Helper } from "./const"; import { Helper, HelperDomain } from "./const";
import "./forms/ha-counter-form"; import "./forms/ha-counter-form";
import "./forms/ha-input_boolean-form"; import "./forms/ha-input_boolean-form";
import "./forms/ha-input_button-form"; import "./forms/ha-input_button-form";
@ -37,7 +37,18 @@ import "./forms/ha-schedule-form";
import "./forms/ha-timer-form"; import "./forms/ha-timer-form";
import type { ShowDialogHelperDetailParams } from "./show-dialog-helper-detail"; import type { ShowDialogHelperDetailParams } from "./show-dialog-helper-detail";
const HELPERS = { type HelperCreators = {
[domain in HelperDomain]: (
hass: HomeAssistant,
// Not properly typed because there is currently a mismatch for this._item between:
// 1. Type passed to form should be Helper
// 2. Type received by creator should be MutableParams version
// The two are not compatible.
params: any
) => Promise<Helper>;
};
const HELPERS: HelperCreators = {
input_boolean: createInputBoolean, input_boolean: createInputBoolean,
input_button: createInputButton, input_button: createInputButton,
input_text: createInputText, input_text: createInputText,
@ -57,7 +68,7 @@ export class DialogHelperDetail extends LitElement {
@state() private _opened = false; @state() private _opened = false;
@state() private _domain?: string; @state() private _domain?: HelperDomain;
@state() private _error?: string; @state() private _error?: string;
@ -127,7 +138,7 @@ export class DialogHelperDetail extends LitElement {
} else { } else {
const items: [string, string][] = []; const items: [string, string][] = [];
for (const helper of Object.keys(HELPERS)) { for (const helper of Object.keys(HELPERS) as (keyof typeof HELPERS)[]) {
items.push([ items.push([
helper, helper,
this.hass.localize(`ui.panel.config.helpers.types.${helper}`) || this.hass.localize(`ui.panel.config.helpers.types.${helper}`) ||

View File

@ -35,7 +35,7 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { HomeAssistant, Route } from "../../../types"; import { HomeAssistant, Route } from "../../../types";
import { configSections } from "../ha-panel-config"; import { configSections } from "../ha-panel-config";
import "../integrations/ha-integration-overflow-menu"; import "../integrations/ha-integration-overflow-menu";
import { HELPER_DOMAINS } from "./const"; import { HelperDomain, isHelperDomain } from "./const";
import { showHelperDetailDialog } from "./show-dialog-helper-detail"; import { showHelperDetailDialog } from "./show-dialog-helper-detail";
// This groups items by a key but only returns last entry per key. // This groups items by a key but only returns last entry per key.
@ -118,7 +118,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
sortable: true, sortable: true,
width: "25%", width: "25%",
filterable: true, filterable: true,
template: (type, row) => template: (type: HelperDomain, row) =>
row.configEntry row.configEntry
? domainToName(localize, type) ? domainToName(localize, type)
: html` : html`
@ -243,7 +243,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
if (!domain) { if (!domain) {
return; return;
} }
if (HELPER_DOMAINS.includes(domain)) { if (isHelperDomain(domain)) {
showHelperDetailDialog(this, { showHelperDetailDialog(this, {
domain, domain,
}); });
@ -330,7 +330,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
const newStates = Object.values(this.hass!.states).filter( const newStates = Object.values(this.hass!.states).filter(
(entity) => (entity) =>
extraEntities.has(entity.entity_id) || extraEntities.has(entity.entity_id) ||
HELPER_DOMAINS.includes(computeStateDomain(entity)) isHelperDomain(computeStateDomain(entity))
); );
if ( if (

View File

@ -1,10 +1,11 @@
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { DataEntryFlowDialogParams } from "../../../dialogs/config-flow/show-dialog-data-entry-flow"; import { DataEntryFlowDialogParams } from "../../../dialogs/config-flow/show-dialog-data-entry-flow";
import { HelperDomain } from "./const";
export const loadHelperDetailDialog = () => import("./dialog-helper-detail"); export const loadHelperDetailDialog = () => import("./dialog-helper-detail");
export interface ShowDialogHelperDetailParams { export interface ShowDialogHelperDetailParams {
domain?: string; domain?: HelperDomain;
// Only used for config entries // Only used for config entries
dialogClosedCallback?: DataEntryFlowDialogParams["dialogClosedCallback"]; dialogClosedCallback?: DataEntryFlowDialogParams["dialogClosedCallback"];
} }

View File

@ -70,7 +70,7 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import type { HomeAssistant, Route } from "../../../types"; import type { HomeAssistant, Route } from "../../../types";
import { configSections } from "../ha-panel-config"; import { configSections } from "../ha-panel-config";
import { HELPER_DOMAINS } from "../helpers/const"; import { isHelperDomain } from "../helpers/const";
import "./ha-config-flow-card"; import "./ha-config-flow-card";
import "./ha-ignored-config-entry-card"; import "./ha-ignored-config-entry-card";
import "./ha-integration-card"; import "./ha-integration-card";
@ -785,7 +785,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
} }
// If not an integration or supported brand, try helper else show alert // If not an integration or supported brand, try helper else show alert
if (HELPER_DOMAINS.includes(domain)) { if (isHelperDomain(domain)) {
navigate(`/config/helpers/add?domain=${domain}`, { navigate(`/config/helpers/add?domain=${domain}`, {
replace: true, replace: true,
}); });

View File

@ -18,7 +18,7 @@ import { css, html, LitElement, PropertyValues } from "lit";
import { property, state } from "lit/decorators"; import { property, state } from "lit/decorators";
import { firstWeekdayIndex } from "../../common/datetime/first_weekday"; import { firstWeekdayIndex } from "../../common/datetime/first_weekday";
import { LocalStorage } from "../../common/decorators/local-storage"; import { LocalStorage } from "../../common/decorators/local-storage";
import { ensureArray } from "../../common/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import { navigate } from "../../common/navigate"; import { navigate } from "../../common/navigate";
import { import {
createSearchParam, createSearchParam,

View File

@ -1,7 +1,7 @@
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { ensureArray } from "../../common/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { throttle } from "../../common/util/throttle"; import { throttle } from "../../common/util/throttle";
import "../../components/ha-circular-progress"; import "../../components/ha-circular-progress";

View File

@ -20,7 +20,7 @@ import {
union, union,
} from "superstruct"; } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { ensureArray } from "../../../../common/ensure-array"; import { ensureArray } from "../../../../common/array/ensure-array";
import type { LocalizeFunc } from "../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../common/translations/localize";
import { deepEqual } from "../../../../common/util/deep-equal"; import { deepEqual } from "../../../../common/util/deep-equal";
import { import {