mirror of
https://github.com/home-assistant/frontend.git
synced 2026-10-27 08:04:18 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aba8ff5c3d |
No files matched your search
@@ -5,31 +5,15 @@ import {
|
||||
mdiPencil,
|
||||
} from "@mdi/js";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { HassEntities } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing, type PropertyValues } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import { consume } from "../../common/decorators/consume";
|
||||
import { transform } from "../../common/decorators/transform";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import {
|
||||
formattersContext,
|
||||
internationalizationContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../data/context";
|
||||
import type { ObjectSelector } from "../../data/selector";
|
||||
import {
|
||||
formatSelectorValue,
|
||||
type FormatSelectorValueOptions,
|
||||
} from "../../data/selector/format_selector_value";
|
||||
import { formatSelectorValue } from "../../data/selector/format_selector_value";
|
||||
import { showFormDialog } from "../../dialogs/form/show-form-dialog";
|
||||
import type {
|
||||
HomeAssistantFormatters,
|
||||
HomeAssistantInternationalization,
|
||||
HomeAssistantRegistries,
|
||||
} from "../../types";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { computeInitialHaFormData } from "../ha-form/compute-initial-ha-form-data";
|
||||
import type { HaFormSchema } from "../ha-form/types";
|
||||
import "../ha-input-helper-text";
|
||||
@@ -42,6 +26,8 @@ import { deepEqual } from "../../common/util/deep-equal";
|
||||
|
||||
@customElement("ha-selector-object")
|
||||
export class HaObjectSelector extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public selector!: ObjectSelector;
|
||||
|
||||
@property() public value?: any;
|
||||
@@ -61,28 +47,6 @@ export class HaObjectSelector extends LitElement {
|
||||
values?: Record<string, string>
|
||||
) => string;
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: HomeAssistantInternationalization;
|
||||
|
||||
@state()
|
||||
@consume({ context: registriesContext, subscribe: true })
|
||||
private _registries!: HomeAssistantRegistries;
|
||||
|
||||
@state()
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private _states!: HassEntities;
|
||||
|
||||
@state()
|
||||
@consume({ context: formattersContext, subscribe: true })
|
||||
@transform<
|
||||
HomeAssistantFormatters,
|
||||
HomeAssistantFormatters["formatEntityName"]
|
||||
>({
|
||||
transformer: (formatters) => formatters?.formatEntityName,
|
||||
})
|
||||
private _formatEntityName!: HomeAssistantFormatters["formatEntityName"];
|
||||
|
||||
@query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor;
|
||||
|
||||
private _valueChangedFromChild = false;
|
||||
@@ -119,12 +83,7 @@ export class HaObjectSelector extends LitElement {
|
||||
private _formatField(item: any, field: string): string {
|
||||
const fields = this.selector.object!.fields!;
|
||||
const value = formatSelectorValue(
|
||||
this._formatOptions(
|
||||
this._i18n,
|
||||
this._registries,
|
||||
this._states,
|
||||
this._formatEntityName
|
||||
),
|
||||
this.hass,
|
||||
item[field],
|
||||
fields[field]?.selector
|
||||
);
|
||||
@@ -189,14 +148,14 @@ export class HaObjectSelector extends LitElement {
|
||||
slot="end"
|
||||
.item=${item}
|
||||
.index=${index}
|
||||
.label=${this._i18n.localize("ui.common.edit")}
|
||||
.label=${this.hass.localize("ui.common.edit")}
|
||||
.path=${mdiPencil}
|
||||
@click=${this._editItem}
|
||||
></ha-icon-button>
|
||||
<ha-icon-button
|
||||
slot="end"
|
||||
.index=${index}
|
||||
.label=${this._i18n.localize("ui.common.delete")}
|
||||
.label=${this.hass.localize("ui.common.delete")}
|
||||
.path=${multiple ? mdiDelete : mdiClose}
|
||||
@click=${this._deleteItem}
|
||||
></ha-icon-button>
|
||||
@@ -221,7 +180,7 @@ export class HaObjectSelector extends LitElement {
|
||||
</ha-list-base>
|
||||
</ha-sortable>
|
||||
<ha-button appearance="filled" @click=${this._addItem}>
|
||||
${this._i18n.localize("ui.common.add")}
|
||||
${this.hass.localize("ui.common.add")}
|
||||
</ha-button>
|
||||
</div>
|
||||
`;
|
||||
@@ -237,7 +196,7 @@ export class HaObjectSelector extends LitElement {
|
||||
</ha-list-base>`
|
||||
: html`
|
||||
<ha-button appearance="filled" @click=${this._addItem}>
|
||||
${this._i18n.localize("ui.common.add")}
|
||||
${this.hass.localize("ui.common.add")}
|
||||
</ha-button>
|
||||
`
|
||||
}
|
||||
@@ -260,23 +219,6 @@ export class HaObjectSelector extends LitElement {
|
||||
} `;
|
||||
}
|
||||
|
||||
private _formatOptions = memoizeOne(
|
||||
(
|
||||
i18n: HomeAssistantInternationalization,
|
||||
registries: HomeAssistantRegistries,
|
||||
states: HassEntities,
|
||||
formatEntityName: HomeAssistantFormatters["formatEntityName"]
|
||||
): FormatSelectorValueOptions => ({
|
||||
locale: i18n.locale,
|
||||
localize: i18n.localize,
|
||||
states,
|
||||
devices: registries.devices,
|
||||
areas: registries.areas,
|
||||
floors: registries.floors,
|
||||
formatEntityName,
|
||||
})
|
||||
);
|
||||
|
||||
private _schema = memoizeOne((selector: ObjectSelector) => {
|
||||
if (!selector.object || !selector.object.fields) {
|
||||
return [];
|
||||
@@ -320,12 +262,12 @@ export class HaObjectSelector extends LitElement {
|
||||
};
|
||||
|
||||
const newItem = await showFormDialog(this, {
|
||||
title: this._i18n.localize("ui.common.add"),
|
||||
title: this.hass.localize("ui.common.add"),
|
||||
schema,
|
||||
data,
|
||||
computeLabel: this._computeLabel,
|
||||
computeHelper: this._computeHelper,
|
||||
submitText: this._i18n.localize("ui.common.add"),
|
||||
submitText: this.hass.localize("ui.common.add"),
|
||||
});
|
||||
|
||||
if (newItem === null) {
|
||||
@@ -348,12 +290,12 @@ export class HaObjectSelector extends LitElement {
|
||||
const index = ev.currentTarget.index;
|
||||
|
||||
const updatedItem = await showFormDialog(this, {
|
||||
title: this._i18n.localize("ui.common.edit"),
|
||||
title: this.hass.localize("ui.common.edit"),
|
||||
schema: this._schema(this.selector),
|
||||
data: item,
|
||||
computeLabel: this._computeLabel,
|
||||
computeHelper: this._computeHelper,
|
||||
submitText: this._i18n.localize("ui.common.save"),
|
||||
submitText: this.hass.localize("ui.common.save"),
|
||||
});
|
||||
|
||||
if (updatedItem === null) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { HassEntities } from "home-assistant-js-websocket";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import { createDurationData } from "../../common/datetime/create_duration_data";
|
||||
import { formatDurationLong } from "../../common/datetime/format_duration";
|
||||
@@ -6,27 +5,12 @@ import { normalizeDuration } from "../../common/datetime/normalize_duration";
|
||||
import { computeAreaName } from "../../common/entity/compute_area_name";
|
||||
import { DEFAULT_ENTITY_NAME } from "../../common/entity/compute_entity_name_display";
|
||||
import { blankBeforeUnit } from "../../common/translations/blank_before_unit";
|
||||
import type { LocalizeFunc } from "../../common/translations/localize";
|
||||
import type { HomeAssistantFormatters } from "../../types";
|
||||
import type { AreaRegistryEntry } from "../area/area_registry";
|
||||
import type { DeviceRegistryEntry } from "../device/device_registry";
|
||||
import type { FloorRegistryEntry } from "../floor_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import type { Selector } from "../selector";
|
||||
import { getDurationSelectorMode, getDurationSelectorUnits } from "../selector";
|
||||
import type { FrontendLocaleData } from "../translation";
|
||||
|
||||
export interface FormatSelectorValueOptions {
|
||||
locale: FrontendLocaleData;
|
||||
localize: LocalizeFunc;
|
||||
states: HassEntities;
|
||||
devices: Record<string, DeviceRegistryEntry>;
|
||||
areas: Record<string, AreaRegistryEntry>;
|
||||
floors: Record<string, FloorRegistryEntry>;
|
||||
formatEntityName: HomeAssistantFormatters["formatEntityName"];
|
||||
}
|
||||
|
||||
export const formatSelectorValue = (
|
||||
options: FormatSelectorValueOptions,
|
||||
hass: HomeAssistant,
|
||||
value: any,
|
||||
selector?: Selector
|
||||
) => {
|
||||
@@ -63,7 +47,7 @@ export const formatSelectorValue = (
|
||||
return number;
|
||||
}
|
||||
return unit_of_measurement
|
||||
? `${num}${blankBeforeUnit(unit_of_measurement, options.locale)}${unit_of_measurement}`
|
||||
? `${num}${blankBeforeUnit(unit_of_measurement, hass.locale)}${unit_of_measurement}`
|
||||
: num.toString();
|
||||
})
|
||||
.join(", ");
|
||||
@@ -73,7 +57,7 @@ export const formatSelectorValue = (
|
||||
const floors = ensureArray(value);
|
||||
return floors
|
||||
.map((floorId) => {
|
||||
const floor = options.floors[floorId];
|
||||
const floor = hass.floors[floorId];
|
||||
if (!floor) {
|
||||
return floorId;
|
||||
}
|
||||
@@ -86,7 +70,7 @@ export const formatSelectorValue = (
|
||||
const areas = ensureArray(value);
|
||||
return areas
|
||||
.map((areaId) => {
|
||||
const area = options.areas[areaId];
|
||||
const area = hass.areas[areaId];
|
||||
if (!area) {
|
||||
return areaId;
|
||||
}
|
||||
@@ -99,11 +83,11 @@ export const formatSelectorValue = (
|
||||
const entities = ensureArray(value);
|
||||
return entities
|
||||
.map((entityId) => {
|
||||
const stateObj = options.states[entityId];
|
||||
const stateObj = hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
return entityId;
|
||||
}
|
||||
const name = options.formatEntityName(stateObj, DEFAULT_ENTITY_NAME);
|
||||
const name = hass.formatEntityName(stateObj, DEFAULT_ENTITY_NAME);
|
||||
return name || entityId;
|
||||
})
|
||||
.join(", ");
|
||||
@@ -113,7 +97,7 @@ export const formatSelectorValue = (
|
||||
const devices = ensureArray(value);
|
||||
return devices
|
||||
.map((deviceId) => {
|
||||
const device = options.devices[deviceId];
|
||||
const device = hass.devices[deviceId];
|
||||
if (!device) {
|
||||
return deviceId;
|
||||
}
|
||||
@@ -141,7 +125,7 @@ export const formatSelectorValue = (
|
||||
return Object.entries(fields)
|
||||
.filter(([key]) => key in item && item[key] != null)
|
||||
.map(([key, field]) =>
|
||||
formatSelectorValue(options, item[key], field.selector)
|
||||
formatSelectorValue(hass, item[key], field.selector)
|
||||
)
|
||||
.join(" = ");
|
||||
}
|
||||
@@ -159,13 +143,13 @@ export const formatSelectorValue = (
|
||||
data,
|
||||
getDurationSelectorUnits(selector.duration)
|
||||
);
|
||||
const formatted = formatDurationLong(options.locale, duration);
|
||||
const formatted = formatDurationLong(hass.locale, duration);
|
||||
const mode = getDurationSelectorMode(selector.duration);
|
||||
if (!formatted || mode === "positive") {
|
||||
return formatted;
|
||||
}
|
||||
const sign = negative ? "negative" : "positive";
|
||||
return options.localize(
|
||||
return hass.localize(
|
||||
`ui.components.selectors.duration.summary.${mode}_${sign}`,
|
||||
{ duration: formatted }
|
||||
);
|
||||
|
||||
@@ -481,27 +481,39 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
return html`
|
||||
${
|
||||
!this.hideName && this._device
|
||||
? html`<ha-row-item>
|
||||
? html`<ha-row-item class="main-entity">
|
||||
<span slot="headline"
|
||||
>${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.use_device_name"
|
||||
)}
|
||||
(${computeDeviceNameDisplay(this._device, this.hass.localize)})</span
|
||||
"ui.dialogs.entity_registry.editor.main_entity",
|
||||
{
|
||||
device: computeDeviceNameDisplay(
|
||||
this._device,
|
||||
this.hass.localize
|
||||
),
|
||||
}
|
||||
)}</span
|
||||
>
|
||||
<span slot="supporting-text"
|
||||
>${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.change_device_settings",
|
||||
{
|
||||
link: html`<button
|
||||
class="link"
|
||||
@click=${this._openDeviceSettings}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.change_device_name_link"
|
||||
)}
|
||||
</button>`,
|
||||
}
|
||||
)}</span
|
||||
"ui.dialogs.entity_registry.editor.main_entity_description"
|
||||
)}
|
||||
${
|
||||
this._useDeviceName
|
||||
? this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.change_device_settings",
|
||||
{
|
||||
link: html`<button
|
||||
class="link"
|
||||
@click=${this._openDeviceSettings}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.change_device_name_link"
|
||||
)}
|
||||
</button>`,
|
||||
}
|
||||
)
|
||||
: nothing
|
||||
}</span
|
||||
>
|
||||
<ha-switch
|
||||
slot="end"
|
||||
@@ -1912,6 +1924,7 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
ha-row-item.main-entity::part(supporting-text),
|
||||
ha-row-item.device-area::part(supporting-text) {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
@@ -2151,7 +2151,8 @@
|
||||
"faq": "documentation",
|
||||
"editor": {
|
||||
"name": "Name",
|
||||
"use_device_name": "Use device name",
|
||||
"main_entity": "Main entity of the device ({device})",
|
||||
"main_entity_description": "Main entities are shown with the device name only.",
|
||||
"change_device_name_link": "change the device name",
|
||||
"restore_name": "Restore default name",
|
||||
"icon": "Icon",
|
||||
@@ -2262,8 +2263,8 @@
|
||||
"note": "Note: This might not work yet with all integrations.",
|
||||
"use_device_area": "Use device area",
|
||||
"use_device_area_confirm_title": "Use the area of the device?",
|
||||
"use_device_area_confirm_text": "This entity is in {area}. Because it has no name of its own, it will use the area of its device instead.",
|
||||
"use_device_area_required": "An entity without its own name always uses the area of its device. You can {link} in the device settings.",
|
||||
"use_device_area_confirm_text": "This entity is in {area}. As a main entity, it will use the area of its device instead.",
|
||||
"use_device_area_required": "A main entity always uses the area of its device. You can {link} in the device settings.",
|
||||
"change_device_settings": "You can {link} in the device settings",
|
||||
"change_device_area_link": "change the device area",
|
||||
"configure_state": "{integration} options",
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import { ContextProvider } from "@lit/context";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
formattersContext,
|
||||
internationalizationContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../../src/data/context";
|
||||
import type { ObjectSelector } from "../../../src/data/selector";
|
||||
import type {
|
||||
HomeAssistantFormatters,
|
||||
HomeAssistantInternationalization,
|
||||
} from "../../../src/types";
|
||||
import type { HomeAssistant } from "../../../src/types";
|
||||
import type { HaObjectSelector } from "../../../src/components/ha-selector/ha-selector-object";
|
||||
import type {
|
||||
FormDialogData,
|
||||
@@ -43,6 +33,16 @@ vi.mock("../../../src/components/ha-yaml-editor", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const hass = {
|
||||
localize: (key: string) => key,
|
||||
locale: "en-US",
|
||||
floors: {},
|
||||
areas: {},
|
||||
devices: {},
|
||||
states: {},
|
||||
formatEntityName: () => "",
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
const selectorConfig = {
|
||||
object: {
|
||||
multiple: true,
|
||||
@@ -67,32 +67,13 @@ const mountSelector = async (
|
||||
value: FormDialogData | FormDialogData[] | "",
|
||||
config: ObjectSelector = selectorConfig
|
||||
) => {
|
||||
const host = document.createElement("div");
|
||||
new ContextProvider(host, {
|
||||
context: internationalizationContext,
|
||||
initialValue: {
|
||||
localize: (key: string) => key,
|
||||
locale: { language: "en" },
|
||||
} as unknown as HomeAssistantInternationalization,
|
||||
});
|
||||
new ContextProvider(host, {
|
||||
context: registriesContext,
|
||||
initialValue: { entities: {}, devices: {}, areas: {}, floors: {} },
|
||||
});
|
||||
new ContextProvider(host, { context: statesContext, initialValue: {} });
|
||||
new ContextProvider(host, {
|
||||
context: formattersContext,
|
||||
initialValue: {
|
||||
formatEntityName: () => "",
|
||||
} as unknown as HomeAssistantFormatters,
|
||||
});
|
||||
const selector = document.createElement(
|
||||
"ha-selector-object"
|
||||
) as HaObjectSelector;
|
||||
selector.hass = hass;
|
||||
selector.selector = config;
|
||||
selector.value = value;
|
||||
host.append(selector);
|
||||
document.body.append(host);
|
||||
document.body.append(selector);
|
||||
await selector.updateComplete;
|
||||
return selector;
|
||||
};
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
formatSelectorValue,
|
||||
type FormatSelectorValueOptions,
|
||||
} from "../../src/data/selector/format_selector_value";
|
||||
import { formatSelectorValue } from "../../src/data/selector/format_selector_value";
|
||||
import type { HomeAssistant } from "../../src/types";
|
||||
|
||||
// These selectors read none of the options.
|
||||
const options = {} as FormatSelectorValueOptions;
|
||||
// formatSelectorValue only touches hass for floor/area/entity/device
|
||||
// selectors, none of which these tests exercise.
|
||||
const hass = {} as HomeAssistant;
|
||||
|
||||
describe("formatSelectorValue", () => {
|
||||
it("returns an empty string for nullish values", () => {
|
||||
expect(formatSelectorValue(options, null)).toBe("");
|
||||
expect(formatSelectorValue(options, undefined)).toBe("");
|
||||
expect(formatSelectorValue(hass, null)).toBe("");
|
||||
expect(formatSelectorValue(hass, undefined)).toBe("");
|
||||
});
|
||||
|
||||
it("renders a plain text value", () => {
|
||||
expect(
|
||||
formatSelectorValue(options, "hello", { text: { type: "text" } })
|
||||
).toBe("hello");
|
||||
expect(formatSelectorValue(hass, "hello", { text: { type: "text" } })).toBe(
|
||||
"hello"
|
||||
);
|
||||
});
|
||||
|
||||
it("applies prefix and suffix for text selectors", () => {
|
||||
expect(
|
||||
formatSelectorValue(options, "5", {
|
||||
formatSelectorValue(hass, "5", {
|
||||
text: { type: "text", prefix: "$", suffix: " each" },
|
||||
})
|
||||
).toBe("$5 each");
|
||||
});
|
||||
|
||||
it("masks a password text value instead of revealing it", () => {
|
||||
const result = formatSelectorValue(options, "hunter2", {
|
||||
const result = formatSelectorValue(hass, "hunter2", {
|
||||
text: { type: "password" },
|
||||
});
|
||||
expect(result).not.toContain("hunter2");
|
||||
@@ -36,7 +35,7 @@ describe("formatSelectorValue", () => {
|
||||
});
|
||||
|
||||
it("masks every value of a multiple password selector", () => {
|
||||
const result = formatSelectorValue(options, ["one", "two"], {
|
||||
const result = formatSelectorValue(hass, ["one", "two"], {
|
||||
text: { type: "password" },
|
||||
});
|
||||
expect(result).not.toContain("one");
|
||||
@@ -46,7 +45,7 @@ describe("formatSelectorValue", () => {
|
||||
|
||||
it("masks a nested password field in an object selector preview", () => {
|
||||
const result = formatSelectorValue(
|
||||
options,
|
||||
hass,
|
||||
{ username: "admin", password: "hunter2" },
|
||||
{
|
||||
object: {
|
||||
@@ -64,7 +63,7 @@ describe("formatSelectorValue", () => {
|
||||
});
|
||||
|
||||
describe("formatSelectorValue duration selector", () => {
|
||||
const localizedOptions = {
|
||||
const localizedHass = {
|
||||
locale: { language: "en" },
|
||||
localize: (key: string, values?: Record<string, unknown>) => {
|
||||
const suffix = key.split("ui.components.selectors.duration.summary.")[1];
|
||||
@@ -75,12 +74,12 @@ describe("formatSelectorValue duration selector", () => {
|
||||
signed_positive: `+${values?.duration}`,
|
||||
}[suffix]!;
|
||||
},
|
||||
} as unknown as FormatSelectorValueOptions;
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
it("formats a positive duration without a sign", () => {
|
||||
expect(
|
||||
formatSelectorValue(
|
||||
localizedOptions,
|
||||
localizedHass,
|
||||
{ hours: 1, minutes: 30 },
|
||||
{ duration: {} }
|
||||
)
|
||||
@@ -90,13 +89,13 @@ describe("formatSelectorValue duration selector", () => {
|
||||
it("formats signed durations with an explicit sign", () => {
|
||||
expect(
|
||||
formatSelectorValue(
|
||||
localizedOptions,
|
||||
localizedHass,
|
||||
{ minutes: -30 },
|
||||
{ duration: { mode: "signed" } }
|
||||
)
|
||||
).toBe("-30 minutes");
|
||||
expect(
|
||||
formatSelectorValue(localizedOptions, "00:30:00", {
|
||||
formatSelectorValue(localizedHass, "00:30:00", {
|
||||
duration: { allow_negative: true },
|
||||
})
|
||||
).toBe("+30 minutes");
|
||||
@@ -105,24 +104,22 @@ describe("formatSelectorValue duration selector", () => {
|
||||
it("formats offsets as before or after", () => {
|
||||
expect(
|
||||
formatSelectorValue(
|
||||
localizedOptions,
|
||||
localizedHass,
|
||||
{ hours: -1, minutes: -30 },
|
||||
{ duration: { mode: "offset" } }
|
||||
)
|
||||
).toBe("1 hour, 30 minutes before");
|
||||
expect(
|
||||
formatSelectorValue(localizedOptions, "-00:10:00", {
|
||||
formatSelectorValue(localizedHass, "-00:10:00", {
|
||||
duration: { mode: "offset" },
|
||||
})
|
||||
).toBe("10 minutes before");
|
||||
expect(
|
||||
formatSelectorValue(localizedOptions, 45, {
|
||||
duration: { mode: "offset" },
|
||||
})
|
||||
formatSelectorValue(localizedHass, 45, { duration: { mode: "offset" } })
|
||||
).toBe("45 seconds after");
|
||||
expect(
|
||||
formatSelectorValue(
|
||||
localizedOptions,
|
||||
localizedHass,
|
||||
{ minutes: -5 },
|
||||
{ duration: { mode: "offset" } }
|
||||
)
|
||||
@@ -132,7 +129,7 @@ describe("formatSelectorValue duration selector", () => {
|
||||
it("returns an empty string for a zero offset", () => {
|
||||
expect(
|
||||
formatSelectorValue(
|
||||
localizedOptions,
|
||||
localizedHass,
|
||||
{ hours: 0, minutes: 0, seconds: 0 },
|
||||
{ duration: { mode: "offset" } }
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user