mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-13 06:04:38 +00:00
Compare commits
12 Commits
migrate-ha
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880b226d10 | ||
|
|
031e6ea789 | ||
|
|
d025a842c4 | ||
|
|
775f145c9f | ||
|
|
f9caf5365e | ||
|
|
b1419b7761 | ||
|
|
be0a673d4e | ||
|
|
8e31316692 | ||
|
|
f9db26166f | ||
|
|
7ceba8d231 | ||
|
|
2a0b4c8f18 | ||
|
|
6c762e0105 |
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -3,6 +3,9 @@ contact_links:
|
||||
- name: Request a feature for the UI / Dashboards
|
||||
url: https://github.com/orgs/home-assistant/discussions
|
||||
about: Request a new feature for the Home Assistant frontend.
|
||||
- name: Discuss UI or UX design
|
||||
url: https://github.com/OpenHomeFoundation/ux-design/discussions
|
||||
about: Share design feedback and discuss visual or UX changes with the design team.
|
||||
- name: Report a bug that is NOT related to the UI / Dashboards
|
||||
url: https://github.com/home-assistant/core/issues
|
||||
about: This is the issue tracker for our frontend. Please report other issues in the backend ("core") repository.
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -57,4 +57,4 @@ test/coverage/
|
||||
# AI tooling
|
||||
.claude
|
||||
.cursor
|
||||
|
||||
.opencode
|
||||
|
||||
@@ -10,7 +10,7 @@ import "../../../../src/components/input/ha-input";
|
||||
import "../../../../src/components/input/ha-input-copy";
|
||||
import "../../../../src/components/input/ha-input-multi";
|
||||
import "../../../../src/components/input/ha-input-search";
|
||||
import { localizeContext } from "../../../../src/data/context";
|
||||
import { internationalizationContext } from "../../../../src/data/context";
|
||||
|
||||
const LOCALIZE_KEYS: Record<string, string> = {
|
||||
"ui.common.copy": "Copy",
|
||||
@@ -26,11 +26,19 @@ const LOCALIZE_KEYS: Record<string, string> = {
|
||||
export class DemoHaInput extends LitElement {
|
||||
constructor() {
|
||||
super();
|
||||
// Provides localizeContext for ha-input-copy, ha-input-multi and ha-input-search
|
||||
// Provides internationalizationContext for ha-input-copy, ha-input-multi and ha-input-search
|
||||
// eslint-disable-next-line no-new
|
||||
new ContextProvider(this, {
|
||||
context: localizeContext,
|
||||
initialValue: ((key: string) => LOCALIZE_KEYS[key] ?? key) as any,
|
||||
context: internationalizationContext,
|
||||
initialValue: {
|
||||
localize: ((key: string) => LOCALIZE_KEYS[key] ?? key) as any,
|
||||
language: "en",
|
||||
selectedLanguage: null,
|
||||
locale: {} as any,
|
||||
translationMetadata: {} as any,
|
||||
loadBackendTranslation: (async () => (key: string) => key) as any,
|
||||
loadFragmentTranslation: (async () => (key: string) => key) as any,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
10
package.json
10
package.json
@@ -164,7 +164,7 @@
|
||||
"@types/sortablejs": "1.15.9",
|
||||
"@types/tar": "7.0.87",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@vitest/coverage-v8": "4.1.2",
|
||||
"@vitest/coverage-v8": "4.1.4",
|
||||
"babel-loader": "10.1.1",
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"browserslist-useragent-regexp": "4.1.4",
|
||||
@@ -197,17 +197,17 @@
|
||||
"lodash.template": "4.5.0",
|
||||
"map-stream": "0.0.7",
|
||||
"pinst": "3.0.0",
|
||||
"prettier": "3.8.1",
|
||||
"prettier": "3.8.2",
|
||||
"rspack-manifest-plugin": "5.2.1",
|
||||
"serve": "14.2.6",
|
||||
"sinon": "21.0.3",
|
||||
"sinon": "21.1.0",
|
||||
"tar": "7.5.13",
|
||||
"terser-webpack-plugin": "5.4.0",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "6.0.2",
|
||||
"typescript-eslint": "8.58.0",
|
||||
"typescript-eslint": "8.58.1",
|
||||
"vite-tsconfig-paths": "6.1.1",
|
||||
"vitest": "4.1.2",
|
||||
"vitest": "4.1.4",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
"workbox-build": "patch:workbox-build@npm%3A7.4.0#~/.yarn/patches/workbox-build-npm-7.4.0-c84561662c.patch"
|
||||
|
||||
@@ -18,15 +18,16 @@ import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import { getAllGraphColors } from "../../common/color/colors";
|
||||
import { transform } from "../../common/decorators/transform";
|
||||
import type { HASSDomEvent } from "../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { listenMediaQuery } from "../../common/dom/media_query";
|
||||
import { afterNextRender } from "../../common/util/render-status";
|
||||
import { filterXSS } from "../../common/util/xss";
|
||||
import { themesContext } from "../../data/context";
|
||||
import { uiContext } from "../../data/context";
|
||||
import type { Themes } from "../../data/ws-themes";
|
||||
import type { ECOption } from "../../resources/echarts/echarts";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import type { HomeAssistant, HomeAssistantUI } from "../../types";
|
||||
import { isMac } from "../../util/is_mac";
|
||||
import "../chips/ha-assist-chip";
|
||||
import "../ha-icon-button";
|
||||
@@ -74,8 +75,11 @@ export class HaChartBase extends LitElement {
|
||||
public extraComponents?: any[];
|
||||
|
||||
@state()
|
||||
@consume({ context: themesContext, subscribe: true })
|
||||
_themes!: Themes;
|
||||
@consume({ context: uiContext, subscribe: true })
|
||||
@transform<HomeAssistantUI, Themes>({
|
||||
transformer: ({ themes }) => themes,
|
||||
})
|
||||
private _themes!: Themes;
|
||||
|
||||
@state() private _isZoomed = false;
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@ import memoizeOne from "memoize-one";
|
||||
import { STRINGS_SEPARATOR_DOT } from "../../common/const";
|
||||
import { restoreScroll } from "../../common/decorators/restore-scroll";
|
||||
import { deepActiveElement } from "../../common/dom/deep-active-element";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type {
|
||||
HASSDomCurrentTargetEvent,
|
||||
HASSDomTargetEvent,
|
||||
} from "../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { stringCompare } from "../../common/string/compare";
|
||||
import type { LocalizeFunc } from "../../common/translations/localize";
|
||||
import { debounce } from "../../common/util/debounce";
|
||||
import { groupBy } from "../../common/util/group-by";
|
||||
import { nextRender } from "../../common/util/render-status";
|
||||
import { localeContext, localizeContext } from "../../data/context";
|
||||
import { internationalizationContext } from "../../data/context";
|
||||
import type { FrontendLocaleData } from "../../data/translation";
|
||||
import { haStyleScrollbar } from "../../resources/styles";
|
||||
import { loadVirtualizer } from "../../resources/virtualizer";
|
||||
@@ -113,12 +113,8 @@ const AUTO_FOCUS_ALLOWED_ACTIVE_TAGS = ["BODY", "HTML", "HOME-ASSISTANT"];
|
||||
@customElement("ha-data-table")
|
||||
export class HaDataTable extends LitElement {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private _localize?: ContextType<typeof localizeContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private _locale?: ContextType<typeof localeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n?: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@@ -531,7 +527,9 @@ export class HaDataTable extends LitElement {
|
||||
<div class="mdc-data-table__row" role="row">
|
||||
<div class="mdc-data-table__cell grows center" role="cell">
|
||||
${this.noDataText ||
|
||||
this._localize?.("ui.components.data-table.no-data") ||
|
||||
this._i18n?.localize?.(
|
||||
"ui.components.data-table.no-data"
|
||||
) ||
|
||||
"No data"}
|
||||
</div>
|
||||
</div>
|
||||
@@ -545,8 +543,8 @@ export class HaDataTable extends LitElement {
|
||||
@scroll=${this._saveScrollPos}
|
||||
.items=${this._groupData(
|
||||
this._filteredData,
|
||||
this._localize,
|
||||
this._locale,
|
||||
this._i18n?.localize,
|
||||
this._i18n?.locale,
|
||||
this.appendRow,
|
||||
this.groupColumn,
|
||||
this.groupOrder,
|
||||
@@ -716,7 +714,7 @@ export class HaDataTable extends LitElement {
|
||||
this._sortColumns[this.sortColumn],
|
||||
this.sortDirection,
|
||||
this.sortColumn,
|
||||
this._locale?.language
|
||||
this._i18n?.locale?.language
|
||||
)
|
||||
: filteredData;
|
||||
|
||||
@@ -896,8 +894,8 @@ export class HaDataTable extends LitElement {
|
||||
|
||||
const groupedData = this._groupData(
|
||||
this._filteredData,
|
||||
this._localize,
|
||||
this._locale,
|
||||
this._i18n?.localize,
|
||||
this._i18n?.locale,
|
||||
this.appendRow,
|
||||
this.groupColumn,
|
||||
this.groupOrder,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { consume, type ContextType } from "@lit/context";
|
||||
import type { ActionDetail } from "@material/mwc-list";
|
||||
import { mdiCalendarToday } from "@mdi/js";
|
||||
import "cally";
|
||||
import type { HassConfig } from "home-assistant-js-websocket/dist/types";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, queryAll, state } from "lit/decorators";
|
||||
import { firstWeekdayIndex } from "../../common/datetime/first_weekday";
|
||||
@@ -12,16 +13,13 @@ import {
|
||||
formatDateYear,
|
||||
formatISODateOnly,
|
||||
} from "../../common/datetime/format_date";
|
||||
import { transform } from "../../common/decorators/transform";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import {
|
||||
configContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
} from "../../data/context";
|
||||
import { configContext, internationalizationContext } from "../../data/context";
|
||||
import { TimeZone } from "../../data/translation";
|
||||
import { MobileAwareMixin } from "../../mixins/mobile-aware-mixin";
|
||||
import { haStyleScrollbar } from "../../resources/styles";
|
||||
import type { ValueChangedEvent } from "../../types";
|
||||
import type { HomeAssistantConfig, ValueChangedEvent } from "../../types";
|
||||
import "../chips/ha-chip-set";
|
||||
import "../chips/ha-filter-chip";
|
||||
import type { HaFilterChip } from "../chips/ha-filter-chip";
|
||||
@@ -48,16 +46,15 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
public timePicker = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private locale!: ContextType<typeof localeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: configContext, subscribe: true })
|
||||
private hassConfig!: ContextType<typeof configContext>;
|
||||
@transform<HomeAssistantConfig, HassConfig>({
|
||||
transformer: ({ config }) => config,
|
||||
})
|
||||
private _hassConfig!: HassConfig;
|
||||
|
||||
/** used to show month in calendar-range header */
|
||||
@state() private _pickerMonth?: string;
|
||||
@@ -87,12 +84,20 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
? formatCallyDateRange(
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n?.locale,
|
||||
this._hassConfig
|
||||
)
|
||||
: undefined;
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
|
||||
if (this.timePicker && this.startDate && this.endDate) {
|
||||
this._timeValue = {
|
||||
@@ -144,12 +149,12 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
<div class="range">
|
||||
<calendar-range
|
||||
.value=${this._dateValue}
|
||||
.locale=${this.locale.language}
|
||||
.locale=${this._i18n.locale.language}
|
||||
.focusedDate=${this._focusDate}
|
||||
@focusday=${this._focusChanged}
|
||||
@change=${this._handleChange}
|
||||
show-outside-days
|
||||
.firstDayOfWeek=${firstWeekdayIndex(this.locale)}
|
||||
.firstDayOfWeek=${firstWeekdayIndex(this._i18n.locale)}
|
||||
>
|
||||
<ha-icon-button-prev
|
||||
tabindex="-1"
|
||||
@@ -162,7 +167,7 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
<ha-icon-button
|
||||
@click=${this._focusToday}
|
||||
.path=${mdiCalendarToday}
|
||||
.label=${this.localize("ui.dialogs.date-picker.today")}
|
||||
.label=${this._i18n.localize("ui.dialogs.date-picker.today")}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
<ha-icon-button-next
|
||||
@@ -176,9 +181,9 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
<div class="times">
|
||||
<ha-time-input
|
||||
.value=${`${this._timeValue.from.hours}:${this._timeValue.from.minutes}`}
|
||||
.locale=${this.locale}
|
||||
.locale=${this._i18n.locale}
|
||||
@value-changed=${this._handleChangeTime}
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.components.date-range-picker.time_from"
|
||||
)}
|
||||
id="from"
|
||||
@@ -187,9 +192,9 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
></ha-time-input>
|
||||
<ha-time-input
|
||||
.value=${`${this._timeValue.to.hours}:${this._timeValue.to.minutes}`}
|
||||
.locale=${this.locale}
|
||||
.locale=${this._i18n.locale}
|
||||
@value-changed=${this._handleChangeTime}
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.components.date-range-picker.time_to"
|
||||
)}
|
||||
id="to"
|
||||
@@ -203,19 +208,33 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
</div>
|
||||
<div class="footer">
|
||||
<ha-button appearance="plain" @click=${this._cancel}
|
||||
>${this.localize("ui.common.cancel")}</ha-button
|
||||
>${this._i18n.localize("ui.common.cancel")}</ha-button
|
||||
>
|
||||
<ha-button .disabled=${!this._dateValue} @click=${this._save}
|
||||
>${this.localize("ui.components.date-range-picker.select")}</ha-button
|
||||
>${this._i18n.localize(
|
||||
"ui.components.date-range-picker.select"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private _focusToday() {
|
||||
const date = new Date();
|
||||
this._focusDate = formatISODateOnly(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._focusDate = formatISODateOnly(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
}
|
||||
|
||||
private _cancel() {
|
||||
@@ -255,12 +274,12 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.locale.time_zone === TimeZone.server) {
|
||||
if (this._i18n.locale.time_zone === TimeZone.server) {
|
||||
startDate = new Date(
|
||||
new TZDate(startDate, this.hassConfig.time_zone).getTime()
|
||||
new TZDate(startDate, this._hassConfig.time_zone).getTime()
|
||||
);
|
||||
endDate = new Date(
|
||||
new TZDate(endDate, this.hassConfig.time_zone).getTime()
|
||||
new TZDate(endDate, this._hassConfig.time_zone).getTime()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -286,8 +305,16 @@ export class DateRangePicker extends MobileAwareMixin(LitElement) {
|
||||
|
||||
private _focusChanged(ev: CustomEvent<Date>) {
|
||||
const date = ev.detail;
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._focusDate = undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiCalendar } from "@mdi/js";
|
||||
import "cally";
|
||||
import { isThisYear } from "date-fns";
|
||||
import type { HassConfig } from "home-assistant-js-websocket/dist/types";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
@@ -14,12 +15,10 @@ import {
|
||||
formatShortDateTime,
|
||||
formatShortDateTimeWithYear,
|
||||
} from "../../common/datetime/format_date_time";
|
||||
import { transform } from "../../common/decorators/transform";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import {
|
||||
configContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
} from "../../data/context";
|
||||
import { configContext, internationalizationContext } from "../../data/context";
|
||||
import type { HomeAssistantConfig } from "../../types";
|
||||
import "../ha-bottom-sheet";
|
||||
import "../ha-icon-button";
|
||||
import "../ha-icon-button-next";
|
||||
@@ -43,16 +42,15 @@ const EXTENDED_RANGE_KEYS: DateRange[] = [
|
||||
@customElement("ha-date-range-picker")
|
||||
export class HaDateRangePicker extends LitElement {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private locale!: ContextType<typeof localeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: configContext, subscribe: true })
|
||||
private hassConfig!: ContextType<typeof configContext>;
|
||||
@transform<HomeAssistantConfig, HassConfig>({
|
||||
transformer: ({ config }) => config,
|
||||
})
|
||||
private _hassConfig!: HassConfig;
|
||||
|
||||
@property({ attribute: false }) public startDate!: Date;
|
||||
|
||||
@@ -117,8 +115,8 @@ export class HaDateRangePicker extends LitElement {
|
||||
this._ranges = {};
|
||||
rangeKeys.forEach((key) => {
|
||||
this._ranges![
|
||||
this.localize(`ui.components.date-range-picker.ranges.${key}`)
|
||||
] = calcDateRange(this.locale, this.hassConfig, key);
|
||||
this._i18n.localize(`ui.components.date-range-picker.ranges.${key}`)
|
||||
] = calcDateRange(this._i18n.locale, this._hassConfig, key);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,41 +138,43 @@ export class HaDateRangePicker extends LitElement {
|
||||
.value=${(isThisYear(this.startDate)
|
||||
? formatShortDateTime(
|
||||
this.startDate,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
)
|
||||
: formatShortDateTimeWithYear(
|
||||
this.startDate,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
)) +
|
||||
(window.innerWidth >= 459 ? " - " : " - \n") +
|
||||
(isThisYear(this.endDate)
|
||||
? formatShortDateTime(
|
||||
this.endDate,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
)
|
||||
: formatShortDateTimeWithYear(
|
||||
this.endDate,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
))}
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.components.date-range-picker.start_date"
|
||||
) +
|
||||
" - " +
|
||||
this.localize("ui.components.date-range-picker.end_date")}
|
||||
this._i18n.localize(
|
||||
"ui.components.date-range-picker.end_date"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
readonly
|
||||
></ha-textarea>
|
||||
<ha-icon-button-prev
|
||||
.label=${this.localize("ui.common.previous")}
|
||||
.label=${this._i18n.localize("ui.common.previous")}
|
||||
@click=${this._handlePrev}
|
||||
>
|
||||
</ha-icon-button-prev>
|
||||
<ha-icon-button-next
|
||||
.label=${this.localize("ui.common.next")}
|
||||
.label=${this._i18n.localize("ui.common.next")}
|
||||
@click=${this._handleNext}
|
||||
>
|
||||
</ha-icon-button-next>`
|
||||
@@ -182,7 +182,7 @@ export class HaDateRangePicker extends LitElement {
|
||||
@click=${this._openPicker}
|
||||
.disabled=${this.disabled}
|
||||
id="field"
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.components.date-range-picker.select_date_range"
|
||||
)}
|
||||
.path=${mdiCalendar}
|
||||
@@ -290,8 +290,8 @@ export class HaDateRangePicker extends LitElement {
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
forward,
|
||||
this.locale,
|
||||
this.hassConfig
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this.startDate = start;
|
||||
this.endDate = end;
|
||||
|
||||
@@ -2,6 +2,7 @@ import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiBackspace, mdiCalendarToday } from "@mdi/js";
|
||||
import "cally";
|
||||
import type { HassConfig } from "home-assistant-js-websocket/dist/types";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import {
|
||||
@@ -10,12 +11,10 @@ import {
|
||||
formatDateYear,
|
||||
formatISODateOnly,
|
||||
} from "../../common/datetime/format_date";
|
||||
import {
|
||||
configContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
} from "../../data/context";
|
||||
import { transform } from "../../common/decorators/transform";
|
||||
import { configContext, internationalizationContext } from "../../data/context";
|
||||
import { DialogMixin } from "../../dialogs/dialog-mixin";
|
||||
import type { HomeAssistantConfig } from "../../types";
|
||||
import "../ha-button";
|
||||
import type { DatePickerDialogParams } from "../ha-date-input";
|
||||
import "../ha-dialog";
|
||||
@@ -40,16 +39,15 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
LitElement
|
||||
) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private locale!: ContextType<typeof localeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: configContext, subscribe: true })
|
||||
private hassConfig!: ContextType<typeof configContext>;
|
||||
@transform<HomeAssistantConfig, HassConfig>({
|
||||
transformer: ({ config }) => config,
|
||||
})
|
||||
private _hassConfig!: HassConfig;
|
||||
|
||||
@state() private _value?: {
|
||||
year: string;
|
||||
@@ -74,14 +72,26 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
? new Date(`${this.params.value.split("T")[0]}T00:00:00`)
|
||||
: new Date();
|
||||
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
|
||||
this._value = this.params.value
|
||||
? {
|
||||
year: this._pickerYear,
|
||||
title: formatDateShort(date, this.locale, this.hassConfig),
|
||||
dateString: formatISODateOnly(date, this.locale, this.hassConfig),
|
||||
title: formatDateShort(date, this._i18n.locale, this._hassConfig),
|
||||
dateString: formatISODateOnly(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
),
|
||||
}
|
||||
: undefined;
|
||||
}
|
||||
@@ -95,7 +105,7 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
open
|
||||
width="small"
|
||||
.headerTitle=${this._value?.title ||
|
||||
this.localize("ui.dialogs.date-picker.title")}
|
||||
this._i18n.localize("ui.dialogs.date-picker.title")}
|
||||
.headerSubtitle=${this._value?.year}
|
||||
header-subtitle-position="above"
|
||||
>
|
||||
@@ -103,7 +113,7 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
? html`
|
||||
<ha-icon-button
|
||||
.path=${mdiBackspace}
|
||||
.label=${this.localize("ui.dialogs.date-picker.clear")}
|
||||
.label=${this._i18n.localize("ui.dialogs.date-picker.clear")}
|
||||
slot="headerActionItems"
|
||||
@click=${this._clear}
|
||||
></ha-icon-button>
|
||||
@@ -131,7 +141,7 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
<ha-icon-button
|
||||
@click=${this._setToday}
|
||||
.path=${mdiCalendarToday}
|
||||
.label=${this.localize("ui.dialogs.date-picker.today")}
|
||||
.label=${this._i18n.localize("ui.dialogs.date-picker.today")}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
<ha-icon-button-next tabindex="-1" slot="next"></ha-icon-button-next>
|
||||
@@ -143,10 +153,10 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
slot="secondaryAction"
|
||||
@click=${this.closeDialog}
|
||||
>
|
||||
${this.localize("ui.common.cancel")}
|
||||
${this._i18n.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button slot="primaryAction" @click=${this._setValue}>
|
||||
${this.localize("ui.common.ok")}
|
||||
${this._i18n.localize("ui.common.ok")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-dialog>`;
|
||||
@@ -164,23 +174,39 @@ export class HaDialogDatePicker extends DialogMixin<DatePickerDialogParams>(
|
||||
? new Date(`${value.split("T")[0]}T00:00:00`)
|
||||
: new Date();
|
||||
this._value = {
|
||||
year: formatDateYear(date, this.locale, this.hassConfig),
|
||||
title: formatDateShort(date, this.locale, this.hassConfig),
|
||||
year: formatDateYear(date, this._i18n.locale, this._hassConfig),
|
||||
title: formatDateShort(date, this._i18n.locale, this._hassConfig),
|
||||
dateString:
|
||||
value || formatISODateOnly(date, this.locale, this.hassConfig),
|
||||
value || formatISODateOnly(date, this._i18n.locale, this._hassConfig),
|
||||
};
|
||||
|
||||
if (setFocusDay) {
|
||||
this._focusDate = this._value.dateString;
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private _focusChanged(ev: CustomEvent<Date>) {
|
||||
const date = ev.detail;
|
||||
this._pickerMonth = formatDateMonth(date, this.locale, this.hassConfig);
|
||||
this._pickerYear = formatDateYear(date, this.locale, this.hassConfig);
|
||||
this._pickerMonth = formatDateMonth(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._pickerYear = formatDateYear(
|
||||
date,
|
||||
this._i18n.locale,
|
||||
this._hassConfig
|
||||
);
|
||||
this._focusDate = undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import memoizeOne from "memoize-one";
|
||||
import { computeCssColor, THEME_COLORS } from "../common/color/compute-color";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import type { LocalizeKeys } from "../common/translations/localize";
|
||||
import { localizeContext } from "../data/context";
|
||||
import { internationalizationContext } from "../data/context";
|
||||
import type { UiColorExtraOption } from "../data/selector";
|
||||
import type { ValueChangedEvent } from "../types";
|
||||
import "./ha-combo-box-item";
|
||||
@@ -55,8 +55,8 @@ export class HaColorPicker extends LitElement {
|
||||
@property({ type: Boolean }) public required = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
render() {
|
||||
const effectiveValue = this.value ?? this.defaultColor ?? "";
|
||||
@@ -73,7 +73,7 @@ export class HaColorPicker extends LitElement {
|
||||
.rowRenderer=${this._rowRenderer}
|
||||
.valueRenderer=${this._valueRenderer}
|
||||
@value-changed=${this._valueChanged}
|
||||
.notFoundLabel=${this.localize?.(
|
||||
.notFoundLabel=${this._i18n?.localize?.(
|
||||
"ui.components.color-picker.no_colors_found"
|
||||
)}
|
||||
.getAdditionalItems=${this._getAdditionalItems}
|
||||
@@ -103,7 +103,7 @@ export class HaColorPicker extends LitElement {
|
||||
{
|
||||
id: searchString,
|
||||
primary:
|
||||
this.localize?.("ui.components.color-picker.custom_color") ||
|
||||
this._i18n?.localize?.("ui.components.color-picker.custom_color") ||
|
||||
"Custom color",
|
||||
secondary: searchString,
|
||||
},
|
||||
@@ -130,14 +130,15 @@ export class HaColorPicker extends LitElement {
|
||||
const items: PickerComboBoxItem[] = [];
|
||||
|
||||
const defaultSuffix =
|
||||
this.localize?.("ui.components.color-picker.default") || "Default";
|
||||
this._i18n?.localize?.("ui.components.color-picker.default") ||
|
||||
"Default";
|
||||
|
||||
const addDefaultSuffix = (label: string, isDefault: boolean) =>
|
||||
isDefault && defaultSuffix ? `${label} (${defaultSuffix})` : label;
|
||||
|
||||
if (includeNone) {
|
||||
const noneLabel =
|
||||
this.localize?.("ui.components.color-picker.none") || "None";
|
||||
this._i18n?.localize?.("ui.components.color-picker.none") || "None";
|
||||
items.push({
|
||||
id: "none",
|
||||
primary: addDefaultSuffix(noneLabel, defaultColor === "none"),
|
||||
@@ -147,7 +148,7 @@ export class HaColorPicker extends LitElement {
|
||||
|
||||
if (includeState) {
|
||||
const stateLabel =
|
||||
this.localize?.("ui.components.color-picker.state") || "State";
|
||||
this._i18n?.localize?.("ui.components.color-picker.state") || "State";
|
||||
items.push({
|
||||
id: "state",
|
||||
primary: addDefaultSuffix(stateLabel, defaultColor === "state"),
|
||||
@@ -170,7 +171,7 @@ export class HaColorPicker extends LitElement {
|
||||
|
||||
Array.from(THEME_COLORS).forEach((color) => {
|
||||
const themeLabel =
|
||||
this.localize?.(
|
||||
this._i18n?.localize?.(
|
||||
`ui.components.color-picker.colors.${color}` as LocalizeKeys
|
||||
) || color;
|
||||
items.push({
|
||||
@@ -227,7 +228,7 @@ export class HaColorPicker extends LitElement {
|
||||
return html`
|
||||
<ha-svg-icon slot="start" .path=${mdiInvertColorsOff}></ha-svg-icon>
|
||||
<span slot="headline">
|
||||
${this.localize?.("ui.components.color-picker.none") || "None"}
|
||||
${this._i18n?.localize?.("ui.components.color-picker.none") || "None"}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
@@ -235,7 +236,8 @@ export class HaColorPicker extends LitElement {
|
||||
return html`
|
||||
<ha-svg-icon slot="start" .path=${mdiPalette}></ha-svg-icon>
|
||||
<span slot="headline">
|
||||
${this.localize?.("ui.components.color-picker.state") || "State"}
|
||||
${this._i18n?.localize?.("ui.components.color-picker.state") ||
|
||||
"State"}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
@@ -243,7 +245,7 @@ export class HaColorPicker extends LitElement {
|
||||
const extraOption = this.extraOptions?.find((o) => o.value === value);
|
||||
const label =
|
||||
extraOption?.label ||
|
||||
this.localize?.(
|
||||
this._i18n?.localize?.(
|
||||
`ui.components.color-picker.colors.${value}` as LocalizeKeys
|
||||
) ||
|
||||
value;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import type { HASSDomEvent } from "../common/dom/fire_event";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { withViewTransition } from "../common/util/view-transition";
|
||||
import { localizeContext } from "../data/context";
|
||||
import { internationalizationContext } from "../data/context";
|
||||
import { ScrollableFadeMixin } from "../mixins/scrollable-fade-mixin";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import "./ha-dialog-header";
|
||||
@@ -123,13 +123,13 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
@query(".body") public bodyContainer!: HTMLDivElement;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
// disabled till iOS app fix the "focus_element" implementation
|
||||
// @state()
|
||||
// @consume({ context: authContext, subscribe: true })
|
||||
// private auth?: ContextType<typeof authContext>;
|
||||
// @consume({ context: configContext, subscribe: true })
|
||||
// private _hassConfig?: ContextType<typeof configContext>;
|
||||
|
||||
@state()
|
||||
private _bodyScrolled = false;
|
||||
@@ -184,7 +184,7 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
<slot name="headerNavigationIcon" slot="navigationIcon">
|
||||
<ha-icon-button
|
||||
data-dialog="close"
|
||||
.label=${this.localize?.("ui.common.close") ?? "Close"}
|
||||
.label=${this._i18n?.localize("ui.common.close") ?? "Close"}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
</slot>
|
||||
@@ -222,13 +222,13 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
// disabled till iOS app fix the "focus_element" implementation
|
||||
// if (this.auth?.external && isIosApp(this.auth.external)) {
|
||||
// if (this._hassConfig?.auth.external && isIosApp(this._hassConfig.auth.external)) {
|
||||
// const element = this.querySelector("[autofocus]");
|
||||
// if (element !== null) {
|
||||
// if (!element.id) {
|
||||
// element.id = "ha-dialog-autofocus";
|
||||
// }
|
||||
// this.auth.external.fireMessage({
|
||||
// this._hassConfig.auth.external.fireMessage({
|
||||
// type: "focus_element",
|
||||
// payload: {
|
||||
// element_id: element.id,
|
||||
|
||||
@@ -2,12 +2,7 @@ import { consume, type ContextType } from "@lit/context";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { until } from "lit/directives/until";
|
||||
import {
|
||||
authContext,
|
||||
configContext,
|
||||
connectionContext,
|
||||
themesContext,
|
||||
} from "../data/context";
|
||||
import { configContext, connectionContext, uiContext } from "../data/context";
|
||||
import {
|
||||
DEFAULT_DOMAIN_ICON,
|
||||
domainIcon,
|
||||
@@ -38,12 +33,8 @@ export class HaDomainIcon extends LitElement {
|
||||
private _connection?: ContextType<typeof connectionContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: themesContext, subscribe: true })
|
||||
private _themes?: ContextType<typeof themesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: authContext, subscribe: true })
|
||||
private _auth?: ContextType<typeof authContext>;
|
||||
@consume({ context: uiContext, subscribe: true })
|
||||
private _hassUi?: ContextType<typeof uiContext>;
|
||||
|
||||
protected render() {
|
||||
if (this.icon) {
|
||||
@@ -59,8 +50,8 @@ export class HaDomainIcon extends LitElement {
|
||||
}
|
||||
|
||||
const icon = domainIcon(
|
||||
this._connection,
|
||||
this._hassConfig,
|
||||
this._connection.connection,
|
||||
this._hassConfig.config,
|
||||
this.domain,
|
||||
this.deviceClass,
|
||||
this.state
|
||||
@@ -86,9 +77,9 @@ export class HaDomainIcon extends LitElement {
|
||||
{
|
||||
domain: this.domain!,
|
||||
type: "icon",
|
||||
darkOptimized: this._themes?.darkMode,
|
||||
darkOptimized: this._hassUi?.themes.darkMode,
|
||||
},
|
||||
this._auth?.data.hassUrl
|
||||
this._hassConfig?.auth.data.hassUrl
|
||||
);
|
||||
return html`
|
||||
<img
|
||||
|
||||
@@ -8,7 +8,7 @@ import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||
import { titleCase } from "../common/string/title-case";
|
||||
import { getConfigEntries, type ConfigEntry } from "../data/config_entries";
|
||||
import { fetchConfig } from "../data/lovelace/config/types";
|
||||
import { getPanelIcon, getPanelTitle } from "../data/panel";
|
||||
import { getPanelIcon, getPanelTitle, SYSTEM_PANELS } from "../data/panel";
|
||||
import { findRelated, type RelatedResult } from "../data/search";
|
||||
import { PANEL_DASHBOARDS } from "../panels/config/lovelace/dashboards/ha-config-lovelace-dashboards";
|
||||
import { computeAreaPath } from "../panels/lovelace/strategies/areas/helpers/areas-strategy-helper";
|
||||
@@ -274,6 +274,7 @@ export class HaNavigationPicker extends LitElement {
|
||||
const otherRoutes: NavigationItem[] = [];
|
||||
|
||||
for (const panel of panels) {
|
||||
if (SYSTEM_PANELS.includes(panel.id)) continue;
|
||||
const path = `/${panel.url_path}`;
|
||||
const panelTitle = getPanelTitle(this.hass, panel);
|
||||
const primary = panelTitle || path;
|
||||
|
||||
@@ -15,7 +15,7 @@ import memoizeOne from "memoize-one";
|
||||
import { tinykeys } from "tinykeys";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||
import { localeContext, localizeContext } from "../data/context";
|
||||
import { internationalizationContext } from "../data/context";
|
||||
import { ScrollableFadeMixin } from "../mixins/scrollable-fade-mixin";
|
||||
import {
|
||||
multiTermSortedSearch,
|
||||
@@ -162,12 +162,8 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
@query("ha-input-search") private _searchFieldElement?: HaInputSearch;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private locale!: ContextType<typeof localeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state() private _items: PickerComboBoxItem[] = [];
|
||||
|
||||
@@ -222,9 +218,9 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
const searchLabel =
|
||||
this.label ??
|
||||
(this.allowCustomValue
|
||||
? (this.localize?.("ui.components.combo-box.search_or_custom") ??
|
||||
? (this.i18n.localize?.("ui.components.combo-box.search_or_custom") ??
|
||||
"Search | Add custom value")
|
||||
: (this.localize?.("ui.common.search") ?? "Search"));
|
||||
: (this.i18n.localize?.("ui.common.search") ?? "Search"));
|
||||
|
||||
return html`<ha-input-search
|
||||
appearance="outlined"
|
||||
@@ -351,7 +347,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
return caseInsensitiveStringCompare(
|
||||
sortLabelA,
|
||||
sortLabelB,
|
||||
this.locale?.language ?? navigator.language
|
||||
this.i18n.locale?.language ?? navigator.language
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -368,7 +364,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
id: this._search,
|
||||
primary:
|
||||
this.customValueLabel ??
|
||||
this.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
this.i18n.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
"Add custom item",
|
||||
secondary: `"${this._search}"`,
|
||||
icon_path: mdiPlus,
|
||||
@@ -402,10 +398,10 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
? typeof this.notFoundLabel === "function"
|
||||
? this.notFoundLabel(this._search)
|
||||
: this.notFoundLabel ||
|
||||
this.localize?.("ui.components.combo-box.no_match") ||
|
||||
this.i18n.localize?.("ui.components.combo-box.no_match") ||
|
||||
"No matching items found"
|
||||
: this.emptyLabel ||
|
||||
this.localize?.("ui.components.combo-box.no_items") ||
|
||||
this.i18n.localize?.("ui.components.combo-box.no_items") ||
|
||||
"No items available"}</span
|
||||
>
|
||||
</ha-combo-box-item>
|
||||
@@ -497,7 +493,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
id: searchString,
|
||||
primary:
|
||||
this.customValueLabel ??
|
||||
this.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
this.i18n.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
"Add custom item",
|
||||
secondary: `"${searchString}"`,
|
||||
icon_path: mdiPlus,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiClose, mdiMenuDown } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
@@ -11,9 +11,8 @@ import {
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { localizeContext } from "../data/context";
|
||||
import { internationalizationContext } from "../data/context";
|
||||
import { PickerMixin } from "../mixins/picker-mixin";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-combo-box-item";
|
||||
import type { HaComboBoxItem } from "./ha-combo-box-item";
|
||||
import "./ha-icon";
|
||||
@@ -34,8 +33,8 @@ export class HaPickerField extends PickerMixin(LitElement) {
|
||||
@query("ha-combo-box-item", true) public item!: HaComboBoxItem;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: HomeAssistant["localize"];
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
public async focus() {
|
||||
await this.updateComplete;
|
||||
@@ -89,7 +88,7 @@ export class HaPickerField extends PickerMixin(LitElement) {
|
||||
${this.unknown
|
||||
? html`<div slot="supporting-text" class="unknown">
|
||||
${this.unknownItemText ||
|
||||
this.localize("ui.components.combo-box.unknown_item")}
|
||||
this._i18n?.localize("ui.components.combo-box.unknown_item")}
|
||||
</div>`
|
||||
: nothing}
|
||||
${showClearIcon
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mdiContentCopy, mdiEye, mdiEyeOff } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { copyToClipboard } from "../../common/util/copy-clipboard";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { internationalizationContext } from "../../data/context";
|
||||
import { showToast } from "../../util/toast";
|
||||
import "../ha-button";
|
||||
import "../ha-icon-button";
|
||||
@@ -59,8 +59,8 @@ export class HaInputCopy extends LitElement {
|
||||
false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state() private _showMasked = true;
|
||||
|
||||
@@ -90,7 +90,7 @@ export class HaInputCopy extends LitElement {
|
||||
? html`<ha-icon-button
|
||||
slot="end"
|
||||
class="toggle-unmasked"
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
`ui.common.${this._showMasked ? "show" : "hide"}`
|
||||
)}
|
||||
@click=${this._toggleMasked}
|
||||
@@ -101,7 +101,7 @@ export class HaInputCopy extends LitElement {
|
||||
</div>
|
||||
<ha-button @click=${this._copy} appearance="plain" size="small">
|
||||
<ha-svg-icon slot="start" .path=${mdiContentCopy}></ha-svg-icon>
|
||||
${this.label || this.localize("ui.common.copy")}
|
||||
${this.label || this._i18n.localize("ui.common.copy")}
|
||||
</ha-button>
|
||||
</div>
|
||||
`;
|
||||
@@ -119,7 +119,7 @@ export class HaInputCopy extends LitElement {
|
||||
private async _copy(): Promise<void> {
|
||||
await copyToClipboard(this.value);
|
||||
showToast(this, {
|
||||
message: this.localize("ui.common.copied_clipboard"),
|
||||
message: this._i18n.localize("ui.common.copied_clipboard"),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { internationalizationContext } from "../../data/context";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import "../ha-button";
|
||||
import "../ha-icon-button";
|
||||
@@ -64,8 +64,8 @@ class HaInputMulti extends LitElement {
|
||||
public updateOnBlur = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize?: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n?: ContextType<typeof internationalizationContext>;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
@@ -109,7 +109,7 @@ class HaInputMulti extends LitElement {
|
||||
.index=${index}
|
||||
slot="navigationIcon"
|
||||
.label=${this.removeLabel ??
|
||||
this.localize?.("ui.common.remove") ??
|
||||
this._i18n?.localize("ui.common.remove") ??
|
||||
"Remove"}
|
||||
@click=${this._removeItem}
|
||||
.path=${mdiDeleteOutline}
|
||||
@@ -137,10 +137,10 @@ class HaInputMulti extends LitElement {
|
||||
<ha-svg-icon slot="start" .path=${mdiPlus}></ha-svg-icon>
|
||||
${this.addLabel ??
|
||||
(this.label
|
||||
? this.localize?.("ui.components.multi-textfield.add_item", {
|
||||
? this._i18n?.localize("ui.components.multi-textfield.add_item", {
|
||||
item: this.label,
|
||||
})
|
||||
: this.localize?.("ui.common.add")) ??
|
||||
: this._i18n?.localize("ui.common.add")) ??
|
||||
"Add"}
|
||||
</ha-button>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiMagnify } from "@mdi/js";
|
||||
import { html, type PropertyValues } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { internationalizationContext } from "../../data/context";
|
||||
import { HaInput } from "./ha-input";
|
||||
|
||||
/**
|
||||
@@ -18,8 +18,8 @@ import { HaInput } from "./ha-input";
|
||||
@customElement("ha-input-search")
|
||||
export class HaInputSearch extends HaInput {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -33,9 +33,9 @@ export class HaInputSearch extends HaInput {
|
||||
if (
|
||||
!this.label &&
|
||||
!this.placeholder &&
|
||||
(!this.hasUpdated || changedProps.has("localize"))
|
||||
(!this.hasUpdated || changedProps.has("_i18n"))
|
||||
) {
|
||||
this.placeholder = this.localize("ui.common.search");
|
||||
this.placeholder = this._i18n.localize("ui.common.search");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,14 @@ import { customElement, property } from "lit/decorators";
|
||||
* Supports regular, indeterminate, and loading states with Home Assistant theming.
|
||||
*
|
||||
* @cssprop --ha-progress-bar-indicator-color - Color of the filled progress indicator.
|
||||
* @cssprop --ha-progress-bar-indicator-background - Background of the filled progress indicator. Overrides `--ha-progress-bar-indicator-color` when set (accepts any CSS background value, e.g. gradients).
|
||||
* @cssprop --ha-progress-bar-track-color - Color of the progress track.
|
||||
* @cssprop --ha-progress-bar-track-height - Height of the progress track. Defaults to `16px`.
|
||||
* @cssprop --ha-progress-bar-border-radius - Border radius of the progress bar. Defaults to `var(--ha-border-radius-pill)`.
|
||||
* @cssprop --ha-progress-bar-animation-duration - Animation duration for indeterminate/loading highlight. Defaults to `2.5s`.
|
||||
* @cssprop --ha-progress-bar-indicator-highlight-image - Image shown at the progress indicator tip (accepts any CSS `background-image` value). Hidden during indeterminate state.
|
||||
* @cssprop --ha-progress-bar-indicator-highlight-width - Width of the indicator highlight element. Defaults to `calc(var(--track-height) * 2)`.
|
||||
* @cssprop --ha-progress-bar-indicator-highlight-height - Height of the indicator highlight element. Defaults to `calc(var(--track-height) * 2)`.
|
||||
*
|
||||
* @attr {boolean} loading - Shows the loading highlight animation on top of the indicator.
|
||||
* @attr {boolean} indeterminate - Shows indeterminate progress animation (inherited from ProgressBar).
|
||||
@@ -42,6 +46,7 @@ export class HaProgressBar extends ProgressBar {
|
||||
);
|
||||
--track-height: var(--ha-progress-bar-track-height, 16px);
|
||||
--wa-transition-slow: var(--ha-animation-duration-slow);
|
||||
position: relative;
|
||||
}
|
||||
.progress-bar {
|
||||
border-radius: var(
|
||||
@@ -49,36 +54,70 @@ export class HaProgressBar extends ProgressBar {
|
||||
var(--ha-border-radius-pill)
|
||||
);
|
||||
}
|
||||
@keyframes slide-highlight {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
.indicator {
|
||||
background: var(
|
||||
--ha-progress-bar-indicator-background,
|
||||
var(--indicator-color)
|
||||
);
|
||||
}
|
||||
:host([indeterminate]) .indicator {
|
||||
animation: wa-progress-indeterminate
|
||||
var(--ha-progress-bar-animation-duration, 2.5s) infinite
|
||||
cubic-bezier(0.37, 0, 0.63, 1);
|
||||
}
|
||||
:host([indeterminate]) .indicator::after,
|
||||
:host([loading]) .indicator::after {
|
||||
@keyframes slide-highlight {
|
||||
0% {
|
||||
transform: translateX(-200%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
}
|
||||
:host([loading]:not([indeterminate])) .progress-bar::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
var(--ha-color-fill-primary-normal-hover) 45%,
|
||||
var(--ha-color-fill-primary-normal-active) 50%,
|
||||
var(--ha-color-fill-primary-normal-hover) 55%,
|
||||
oklch(from var(--indicator-color) 85% c h) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
opacity: 0.4;
|
||||
opacity: 0.5;
|
||||
animation: slide-highlight
|
||||
var(--ha-progress-bar-animation-duration, 2.5s) infinite
|
||||
cubic-bezier(0.37, 0, 0.63, 1);
|
||||
width: 50%;
|
||||
}
|
||||
:host::after {
|
||||
--width: var(
|
||||
--ha-progress-bar-indicator-highlight-width,
|
||||
calc(var(--track-height) * 2)
|
||||
);
|
||||
width: var(--width);
|
||||
height: var(
|
||||
--ha-progress-bar-indicator-highlight-height,
|
||||
calc(var(--track-height) * 2)
|
||||
);
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset-inline-start: clamp(
|
||||
var(--width) / 2,
|
||||
var(--percentage, 0%),
|
||||
calc(100% - var(--width) / 2)
|
||||
);
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-image: var(--ha-progress-bar-indicator-highlight-image);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
pointer-events: none;
|
||||
transition: inset-inline-start var(--wa-transition-slow, 200ms)
|
||||
var(--wa-transition-easing, ease);
|
||||
}
|
||||
:host([indeterminate])::after {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@@ -5,6 +5,8 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time";
|
||||
import type { Trigger } from "../../data/automation";
|
||||
import { migrateAutomationTrigger } from "../../data/automation";
|
||||
import { describeCondition, describeTrigger } from "../../data/automation_i18n";
|
||||
import { fullEntitiesContext, labelsContext } from "../../data/context";
|
||||
import type { EntityRegistryEntry } from "../../data/entity/entity_registry";
|
||||
@@ -24,8 +26,6 @@ import "../ha-icon-button";
|
||||
import "./hat-logbook-note";
|
||||
import type { NodeInfo } from "./hat-script-graph";
|
||||
import { traceTabStyles } from "./trace-tab-styles";
|
||||
import type { Trigger } from "../../data/automation";
|
||||
import { migrateAutomationTrigger } from "../../data/automation";
|
||||
|
||||
const TRACE_PATH_TABS = [
|
||||
"step_config",
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import { createContext } from "@lit/context";
|
||||
import type { HassConfig } from "home-assistant-js-websocket";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import type { ConfigEntry } from "./config_entries";
|
||||
import type { EntityRegistryEntry } from "./entity/entity_registry";
|
||||
import type { LabelRegistryEntry } from "./label/label_registry";
|
||||
|
||||
export const connectionContext =
|
||||
createContext<HomeAssistant["connection"]>("connection");
|
||||
export const statesContext = createContext<HomeAssistant["states"]>("states");
|
||||
export const entitiesContext =
|
||||
createContext<HomeAssistant["entities"]>("entities");
|
||||
export const devicesContext =
|
||||
createContext<HomeAssistant["devices"]>("devices");
|
||||
export const areasContext = createContext<HomeAssistant["areas"]>("areas");
|
||||
export const localizeContext =
|
||||
createContext<HomeAssistant["localize"]>("localize");
|
||||
export const localeContext = createContext<HomeAssistant["locale"]>("locale");
|
||||
export const configContext = createContext<HassConfig>("config");
|
||||
export const themesContext = createContext<HomeAssistant["themes"]>("themes");
|
||||
export const selectedThemeContext =
|
||||
createContext<HomeAssistant["selectedTheme"]>("selectedTheme");
|
||||
export const userContext = createContext<HomeAssistant["user"]>("user");
|
||||
export const userDataContext =
|
||||
createContext<HomeAssistant["userData"]>("userData");
|
||||
export const panelsContext = createContext<HomeAssistant["panels"]>("panels");
|
||||
|
||||
export const fullEntitiesContext =
|
||||
createContext<EntityRegistryEntry[]>("extendedEntities");
|
||||
|
||||
export const floorsContext = createContext<HomeAssistant["floors"]>("floors");
|
||||
|
||||
export const labelsContext = createContext<LabelRegistryEntry[]>("labels");
|
||||
|
||||
export const configEntriesContext =
|
||||
createContext<ConfigEntry[]>("configEntries");
|
||||
|
||||
export const authContext = createContext<HomeAssistant["auth"]>("auth");
|
||||
148
src/data/context/index.ts
Normal file
148
src/data/context/index.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import { createContext } from "@lit/context";
|
||||
import type { HassConfig } from "home-assistant-js-websocket";
|
||||
import type {
|
||||
HomeAssistant,
|
||||
HomeAssistantApi,
|
||||
HomeAssistantConfig,
|
||||
HomeAssistantConnection,
|
||||
HomeAssistantInternationalization,
|
||||
HomeAssistantRegistries,
|
||||
HomeAssistantUI,
|
||||
} from "../../types";
|
||||
import type { ConfigEntry } from "../config_entries";
|
||||
import type { EntityRegistryEntry } from "../entity/entity_registry";
|
||||
import type { LabelRegistryEntry } from "../label/label_registry";
|
||||
|
||||
/**
|
||||
* Entity, device, area, and floor registries
|
||||
*/
|
||||
export const registriesContext =
|
||||
createContext<HomeAssistantRegistries>("hassRegistries");
|
||||
|
||||
/**
|
||||
* Live map of all entity states, keyed by entity ID.
|
||||
*/
|
||||
export const statesContext = createContext<HomeAssistant["states"]>("states");
|
||||
|
||||
/**
|
||||
* Provides the map of all available Home Assistant services, keyed by domain.
|
||||
*/
|
||||
export const servicesContext =
|
||||
createContext<HomeAssistant["services"]>("services");
|
||||
|
||||
/**
|
||||
* i18n state: active language, locale settings, the `localize` function, translation metadata, and the
|
||||
* `loadBackendTranslation` / `loadFragmentTranslation` loaders.
|
||||
*/
|
||||
export const internationalizationContext =
|
||||
createContext<HomeAssistantInternationalization>("hassInternationalization");
|
||||
|
||||
/**
|
||||
* HTTP and WebSocket API surface: `callService`, `callApi`,
|
||||
* `callApiRaw`, `callWS`, `sendWS`, `fetchWithAuth`, and `hassUrl`.
|
||||
*/
|
||||
export const apiContext = createContext<HomeAssistantApi>("hassApi");
|
||||
|
||||
/**
|
||||
* WebSocket connection state: `connection`, `connected`, and `debugConnection`.
|
||||
*/
|
||||
export const connectionContext =
|
||||
createContext<HomeAssistantConnection>("hassConnection");
|
||||
|
||||
/**
|
||||
* UI preferences and global UI state: themes, selected theme,
|
||||
* panels, sidebar mode, kiosk mode, shortcuts, vibration, and
|
||||
* `suspendWhenHidden`.
|
||||
*/
|
||||
export const uiContext = createContext<HomeAssistantUI>("hassUi");
|
||||
|
||||
/**
|
||||
* HA core configuration together with user session data:
|
||||
* `auth`, `config` (core HA config), `user`, `userData`, and `systemData`.
|
||||
*/
|
||||
export const configContext = createContext<HomeAssistantConfig>("hassConfig");
|
||||
|
||||
/**
|
||||
* Map of all entities in the entity registry, keyed by entity ID.
|
||||
*/
|
||||
export const entitiesContext =
|
||||
createContext<HomeAssistant["entities"]>("entities");
|
||||
|
||||
/**
|
||||
* Map of all devices in the device registry, keyed by device ID.
|
||||
*/
|
||||
export const devicesContext =
|
||||
createContext<HomeAssistant["devices"]>("devices");
|
||||
|
||||
/**
|
||||
* Map of all areas in the area registry, keyed by area ID.
|
||||
*/
|
||||
export const areasContext = createContext<HomeAssistant["areas"]>("areas");
|
||||
|
||||
/**
|
||||
* Map of all floors in the floor registry, keyed by floor ID.
|
||||
*/
|
||||
export const floorsContext = createContext<HomeAssistant["floors"]>("floors");
|
||||
|
||||
// #region lazy-contexts
|
||||
|
||||
/**
|
||||
* Lazy contexts are not subscribed to by default. They are only subscribed to when a provider is consumed with at least one consumer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lazy loaded labels registry, keyed by label ID.
|
||||
*/
|
||||
export const labelsContext = createContext<LabelRegistryEntry[]>("labels");
|
||||
|
||||
/**
|
||||
* Lazy loaded entity registry array
|
||||
*/
|
||||
export const fullEntitiesContext =
|
||||
createContext<EntityRegistryEntry[]>("extendedEntities");
|
||||
|
||||
/**
|
||||
* Lazy loaded config entries array
|
||||
*/
|
||||
export const configEntriesContext =
|
||||
createContext<ConfigEntry[]>("configEntries");
|
||||
|
||||
// #endregion lazy-contexts
|
||||
|
||||
// #region deprecated-contexts
|
||||
|
||||
/** @deprecated Use `connectionContext` instead. */
|
||||
export const connectionSingleContext =
|
||||
createContext<HomeAssistant["connection"]>("connection");
|
||||
|
||||
/** @deprecated Use `internationalizationContext` instead. */
|
||||
export const localizeContext =
|
||||
createContext<HomeAssistant["localize"]>("localize");
|
||||
|
||||
/** @deprecated Use `internationalizationContext` instead. */
|
||||
export const localeContext = createContext<HomeAssistant["locale"]>("locale");
|
||||
|
||||
/** @deprecated Use `configContext` instead. */
|
||||
export const configSingleContext = createContext<HassConfig>("config");
|
||||
|
||||
/** @deprecated Use `uiContext` instead. */
|
||||
export const themesContext = createContext<HomeAssistant["themes"]>("themes");
|
||||
|
||||
/** @deprecated Use `uiContext` instead. */
|
||||
export const selectedThemeContext =
|
||||
createContext<HomeAssistant["selectedTheme"]>("selectedTheme");
|
||||
|
||||
/** @deprecated Use `configContext` instead. */
|
||||
export const userContext = createContext<HomeAssistant["user"]>("user");
|
||||
|
||||
/** @deprecated Use `configContext` instead. */
|
||||
export const userDataContext =
|
||||
createContext<HomeAssistant["userData"]>("userData");
|
||||
|
||||
/** @deprecated Use `uiContext` instead. */
|
||||
export const panelsContext = createContext<HomeAssistant["panels"]>("panels");
|
||||
|
||||
/** @deprecated Use `configContext` instead. */
|
||||
export const authContext = createContext<HomeAssistant["auth"]>("auth");
|
||||
|
||||
// #endregion deprecated-contexts
|
||||
166
src/data/context/updateContext.ts
Normal file
166
src/data/context/updateContext.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
import type {
|
||||
HomeAssistant,
|
||||
HomeAssistantApi,
|
||||
HomeAssistantConfig,
|
||||
HomeAssistantConnection,
|
||||
HomeAssistantInternationalization,
|
||||
HomeAssistantRegistries,
|
||||
HomeAssistantUI,
|
||||
} from "../../types";
|
||||
|
||||
const updateRegistries = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantRegistries
|
||||
): HomeAssistantRegistries => {
|
||||
if (
|
||||
!value ||
|
||||
value.entities !== hass.entities ||
|
||||
value.devices !== hass.devices ||
|
||||
value.areas !== hass.areas ||
|
||||
value.floors !== hass.floors
|
||||
) {
|
||||
return {
|
||||
entities: hass.entities,
|
||||
devices: hass.devices,
|
||||
areas: hass.areas,
|
||||
floors: hass.floors,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const updateInternationalization = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantInternationalization
|
||||
): HomeAssistantInternationalization => {
|
||||
if (
|
||||
!value ||
|
||||
value.localize !== hass.localize ||
|
||||
value.locale !== hass.locale ||
|
||||
value.loadBackendTranslation !== hass.loadBackendTranslation ||
|
||||
value.loadFragmentTranslation !== hass.loadFragmentTranslation ||
|
||||
value.language !== hass.language ||
|
||||
value.selectedLanguage !== hass.selectedLanguage ||
|
||||
value.translationMetadata !== hass.translationMetadata
|
||||
) {
|
||||
return {
|
||||
localize: hass.localize,
|
||||
locale: hass.locale,
|
||||
loadBackendTranslation: hass.loadBackendTranslation,
|
||||
loadFragmentTranslation: hass.loadFragmentTranslation,
|
||||
language: hass.language,
|
||||
selectedLanguage: hass.selectedLanguage,
|
||||
translationMetadata: hass.translationMetadata,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const updateApi = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantApi
|
||||
): HomeAssistantApi => {
|
||||
if (
|
||||
!value ||
|
||||
value.callService !== hass.callService ||
|
||||
value.callApi !== hass.callApi ||
|
||||
value.callApiRaw !== hass.callApiRaw ||
|
||||
value.callWS !== hass.callWS ||
|
||||
value.sendWS !== hass.sendWS ||
|
||||
value.fetchWithAuth !== hass.fetchWithAuth
|
||||
) {
|
||||
return {
|
||||
callService: hass.callService,
|
||||
callApi: hass.callApi,
|
||||
callApiRaw: hass.callApiRaw,
|
||||
callWS: hass.callWS,
|
||||
sendWS: hass.sendWS,
|
||||
fetchWithAuth: hass.fetchWithAuth,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const updateConnection = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantConnection
|
||||
): HomeAssistantConnection => {
|
||||
if (
|
||||
!value ||
|
||||
value.connection !== hass.connection ||
|
||||
value.connected !== hass.connected ||
|
||||
value.debugConnection !== hass.debugConnection ||
|
||||
value.hassUrl !== hass.hassUrl
|
||||
) {
|
||||
return {
|
||||
connection: hass.connection,
|
||||
connected: hass.connected,
|
||||
debugConnection: hass.debugConnection,
|
||||
hassUrl: hass.hassUrl,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const updateUi = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantUI
|
||||
): HomeAssistantUI => {
|
||||
if (
|
||||
!value ||
|
||||
value.themes !== hass.themes ||
|
||||
value.selectedTheme !== hass.selectedTheme ||
|
||||
value.panels !== hass.panels ||
|
||||
value.panelUrl !== hass.panelUrl ||
|
||||
value.dockedSidebar !== hass.dockedSidebar ||
|
||||
value.kioskMode !== hass.kioskMode ||
|
||||
value.enableShortcuts !== hass.enableShortcuts ||
|
||||
value.vibrate !== hass.vibrate ||
|
||||
value.suspendWhenHidden !== hass.suspendWhenHidden
|
||||
) {
|
||||
return {
|
||||
themes: hass.themes,
|
||||
selectedTheme: hass.selectedTheme,
|
||||
panels: hass.panels,
|
||||
panelUrl: hass.panelUrl,
|
||||
dockedSidebar: hass.dockedSidebar,
|
||||
kioskMode: hass.kioskMode,
|
||||
enableShortcuts: hass.enableShortcuts,
|
||||
vibrate: hass.vibrate,
|
||||
suspendWhenHidden: hass.suspendWhenHidden,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const updateConfig = (
|
||||
hass: HomeAssistant,
|
||||
value?: HomeAssistantConfig
|
||||
): HomeAssistantConfig => {
|
||||
if (
|
||||
!value ||
|
||||
value.auth !== hass.auth ||
|
||||
value.config !== hass.config ||
|
||||
value.user !== hass.user ||
|
||||
value.userData !== hass.userData ||
|
||||
value.systemData !== hass.systemData
|
||||
) {
|
||||
return {
|
||||
auth: hass.auth,
|
||||
config: hass.config,
|
||||
user: hass.user,
|
||||
userData: hass.userData,
|
||||
systemData: hass.systemData,
|
||||
};
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
export const updateHassGroups = {
|
||||
registries: updateRegistries,
|
||||
internationalization: updateInternationalization,
|
||||
api: updateApi,
|
||||
connection: updateConnection,
|
||||
ui: updateUi,
|
||||
config: updateConfig,
|
||||
};
|
||||
@@ -12,11 +12,16 @@ import type { LocalizeKeys } from "../common/translations/localize";
|
||||
import type { PageNavigation } from "../layouts/hass-tabs-subpage";
|
||||
import type { HomeAssistant, PanelInfo } from "../types";
|
||||
|
||||
export const APP_PANEL = "app";
|
||||
export const HOME_PANEL = "home";
|
||||
export const MY_REDIRECT_PANEL = "_my_redirect";
|
||||
export const NOT_FOUND_PANEL = "notfound";
|
||||
export const PROFILE_PANEL = "profile";
|
||||
export const LOVELACE_PANEL = "lovelace";
|
||||
|
||||
/** Panels that are internal/system-level and should not appear in user-facing navigation UIs. */
|
||||
export const SYSTEM_PANELS = [MY_REDIRECT_PANEL, NOT_FOUND_PANEL, APP_PANEL];
|
||||
|
||||
/** Panel to show when no panel is picked. */
|
||||
export const DEFAULT_PANEL = HOME_PANEL;
|
||||
|
||||
|
||||
@@ -18,7 +18,11 @@ import type { FuseWeightedKey } from "../resources/fuseMultiTerm";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import type { HassioAddonInfo } from "./hassio/addon";
|
||||
import { domainToName } from "./integration";
|
||||
import { getPanelIcon, getPanelNameTranslationKey } from "./panel";
|
||||
import {
|
||||
getPanelIcon,
|
||||
getPanelNameTranslationKey,
|
||||
SYSTEM_PANELS,
|
||||
} from "./panel";
|
||||
|
||||
export interface NavigationComboBoxItem extends PickerComboBoxItem {
|
||||
path: string;
|
||||
@@ -51,12 +55,7 @@ const generateNavigationPanelCommands = (
|
||||
apps?: HassioAddonInfo[]
|
||||
): BaseNavigationCommand[] =>
|
||||
Object.entries(panels)
|
||||
.filter(
|
||||
([panelKey]) =>
|
||||
panelKey !== "_my_redirect" &&
|
||||
panelKey !== "hassio" &&
|
||||
panelKey !== "app"
|
||||
)
|
||||
.filter(([panelKey]) => !SYSTEM_PANELS.includes(panelKey))
|
||||
.map(([_panelKey, panel]) => {
|
||||
const translationKey = getPanelNameTranslationKey(panel);
|
||||
const icon = getPanelIcon(panel) || "mdi:view-dashboard";
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { LocalizeKeys } from "../../common/translations/localize";
|
||||
import "../../components/ha-alert";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-svg-icon";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { internationalizationContext } from "../../data/context";
|
||||
import { isMac } from "../../util/is_mac";
|
||||
import { DialogMixin } from "../dialog-mixin";
|
||||
|
||||
@@ -168,8 +168,8 @@ const _SHORTCUTS: Section[] = [
|
||||
@customElement("dialog-shortcuts")
|
||||
class DialogShortcuts extends DialogMixin(LitElement) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
private _renderShortcut(
|
||||
shortcutKeys: ShortcutString[],
|
||||
@@ -183,13 +183,15 @@ class DialogShortcuts extends DialogMixin(LitElement) {
|
||||
>${shortcutKey === CTRL_CMD
|
||||
? isMac
|
||||
? "⌘"
|
||||
: this.localize("ui.dialogs.shortcuts.keys.ctrl")
|
||||
: this._i18n.localize("ui.dialogs.shortcuts.keys.ctrl")
|
||||
: typeof shortcutKey === "string"
|
||||
? shortcutKey
|
||||
: this.localize(shortcutKey.shortcutTranslationKey)}</span
|
||||
: this._i18n.localize(
|
||||
shortcutKey.shortcutTranslationKey
|
||||
)}</span
|
||||
>`
|
||||
)}
|
||||
${this.localize(descriptionKey)}
|
||||
${this._i18n.localize(descriptionKey)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -198,12 +200,12 @@ class DialogShortcuts extends DialogMixin(LitElement) {
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
.headerTitle=${this.localize("ui.dialogs.shortcuts.title")}
|
||||
.headerTitle=${this._i18n.localize("ui.dialogs.shortcuts.title")}
|
||||
>
|
||||
<div class="content">
|
||||
${_SHORTCUTS.map(
|
||||
(section) => html`
|
||||
<h3>${this.localize(section.titleTranslationKey)}</h3>
|
||||
<h3>${this._i18n.localize(section.titleTranslationKey)}</h3>
|
||||
<div class="items">
|
||||
${section.items.map((item) => {
|
||||
if ("shortcut" in item) {
|
||||
@@ -213,7 +215,7 @@ class DialogShortcuts extends DialogMixin(LitElement) {
|
||||
);
|
||||
}
|
||||
return html`<p>
|
||||
${this.localize((item as Text).textTranslationKey)}
|
||||
${this._i18n.localize((item as Text).textTranslationKey)}
|
||||
</p>`;
|
||||
})}
|
||||
</div>
|
||||
@@ -222,9 +224,9 @@ class DialogShortcuts extends DialogMixin(LitElement) {
|
||||
</div>
|
||||
|
||||
<ha-alert slot="footer">
|
||||
${this.localize("ui.dialogs.shortcuts.enable_shortcuts_hint", {
|
||||
${this._i18n.localize("ui.dialogs.shortcuts.enable_shortcuts_hint", {
|
||||
user_profile: html`<a href="/profile/general#shortcuts"
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.dialogs.shortcuts.enable_shortcuts_hint_user_profile"
|
||||
)}</a
|
||||
>`,
|
||||
|
||||
@@ -303,7 +303,6 @@ export const provideHass = (
|
||||
debugConnection: false,
|
||||
kioskMode: false,
|
||||
suspendWhenHidden: false,
|
||||
moreInfoEntityId: null as any,
|
||||
// @ts-ignore
|
||||
async callService(domain, service, data) {
|
||||
if (data && "entity_id" in data) {
|
||||
|
||||
@@ -31,6 +31,8 @@ import { storage } from "../../../../common/decorators/storage";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { preventDefaultStopPropagation } from "../../../../common/dom/prevent_default_stop_propagation";
|
||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||
import { computeObjectId } from "../../../../common/entity/compute_object_id";
|
||||
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
|
||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
||||
@@ -95,8 +97,6 @@ import "./types/ha-automation-action-set_conversation_response";
|
||||
import "./types/ha-automation-action-stop";
|
||||
import "./types/ha-automation-action-wait_for_trigger";
|
||||
import "./types/ha-automation-action-wait_template";
|
||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||
import { computeObjectId } from "../../../../common/entity/compute_object_id";
|
||||
|
||||
export const getAutomationActionType = memoizeOne(
|
||||
(action: Action | undefined) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import "../../../../../components/ha-formfield";
|
||||
import "../../../../../components/ha-switch";
|
||||
import "../../../../../components/input/ha-input";
|
||||
import type { HaInput } from "../../../../../components/input/ha-input";
|
||||
import { localizeContext } from "../../../../../data/context";
|
||||
import { internationalizationContext } from "../../../../../data/context";
|
||||
import type { StopAction } from "../../../../../data/script";
|
||||
import type { ActionElement } from "../ha-automation-action-row";
|
||||
|
||||
@@ -17,8 +17,8 @@ export class HaStopAction extends LitElement implements ActionElement {
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
public static get defaultConfig(): StopAction {
|
||||
return { stop: "" };
|
||||
@@ -29,7 +29,7 @@ export class HaStopAction extends LitElement implements ActionElement {
|
||||
|
||||
return html`
|
||||
<ha-input
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.actions.type.stop.stop"
|
||||
)}
|
||||
.value=${stop}
|
||||
@@ -37,7 +37,7 @@ export class HaStopAction extends LitElement implements ActionElement {
|
||||
@change=${this._stopChanged}
|
||||
></ha-input>
|
||||
<ha-input
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.actions.type.stop.response_variable"
|
||||
)}
|
||||
.value=${response_variable || ""}
|
||||
@@ -46,7 +46,7 @@ export class HaStopAction extends LitElement implements ActionElement {
|
||||
></ha-input>
|
||||
<ha-formfield
|
||||
.disabled=${this.disabled}
|
||||
.label=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.actions.type.stop.error"
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -99,9 +99,9 @@ import {
|
||||
domainToName,
|
||||
fetchIntegrationManifests,
|
||||
} from "../../../data/integration";
|
||||
import { filterSelectorEntities } from "../../../data/selector";
|
||||
import type { LabelRegistryEntry } from "../../../data/label/label_registry";
|
||||
import { subscribeLabFeature } from "../../../data/labs";
|
||||
import { filterSelectorEntities } from "../../../data/selector";
|
||||
import {
|
||||
TARGET_SEPARATOR,
|
||||
getConditionsForTarget,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "@home-assistant/webawesome/dist/components/tree-item/tree-item";
|
||||
import "@home-assistant/webawesome/dist/components/tree/tree";
|
||||
import type { WaSelectionChangeEvent } from "@home-assistant/webawesome/dist/events/selection-change";
|
||||
import { consume } from "@lit/context";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiTextureBox } from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
@@ -44,12 +44,9 @@ import {
|
||||
type ConfigEntry,
|
||||
} from "../../../../data/config_entries";
|
||||
import {
|
||||
areasContext,
|
||||
devicesContext,
|
||||
entitiesContext,
|
||||
floorsContext,
|
||||
internationalizationContext,
|
||||
labelsContext,
|
||||
localizeContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../../../data/context";
|
||||
import { getDeviceEntityLookup } from "../../../../data/device/device_registry";
|
||||
@@ -99,28 +96,14 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
// #region context
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: HomeAssistant["localize"];
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private states!: HomeAssistant["states"];
|
||||
private states!: ContextType<typeof statesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: floorsContext, subscribe: true })
|
||||
private floors!: HomeAssistant["floors"];
|
||||
|
||||
@state()
|
||||
@consume({ context: areasContext, subscribe: true })
|
||||
private areas!: HomeAssistant["areas"];
|
||||
|
||||
@state()
|
||||
@consume({ context: devicesContext, subscribe: true })
|
||||
private devices!: HomeAssistant["devices"];
|
||||
|
||||
@state()
|
||||
@consume({ context: entitiesContext, subscribe: true })
|
||||
private entities!: HomeAssistant["entities"];
|
||||
@consume({ context: registriesContext, subscribe: true })
|
||||
private _registries!: ContextType<typeof registriesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: labelsContext, subscribe: true })
|
||||
@@ -205,7 +188,9 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
? html`
|
||||
<div class="targets-show-more">
|
||||
<ha-button appearance="filled" @click=${this._expandHeight}>
|
||||
${this.localize("ui.panel.config.automation.editor.show_more")}
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.show_more"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
`
|
||||
@@ -235,7 +220,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
if (valueType === "area" && valueId) {
|
||||
const floor =
|
||||
entries[
|
||||
`floor${TARGET_SEPARATOR}${this.areas[valueId]?.floor_id || ""}`
|
||||
`floor${TARGET_SEPARATOR}${this._registries.areas[valueId]?.floor_id || ""}`
|
||||
];
|
||||
const { devices, entities } =
|
||||
floor.areas![`area${TARGET_SEPARATOR}${valueId}`];
|
||||
@@ -255,9 +240,9 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (valueId && valueType === "device") {
|
||||
const areaId = this.devices[valueId]?.area_id;
|
||||
const areaId = this._registries.devices[valueId]?.area_id;
|
||||
if (areaId) {
|
||||
const floorId = this.areas[areaId]?.floor_id || "";
|
||||
const floorId = this._registries.areas[areaId]?.floor_id || "";
|
||||
const { entities } =
|
||||
entries[`floor${TARGET_SEPARATOR}${floorId}`].areas![
|
||||
`area${TARGET_SEPARATOR}${areaId}`
|
||||
@@ -266,7 +251,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
return entities.length ? this._renderEntities(entities) : nothing;
|
||||
}
|
||||
|
||||
const device = this.devices[valueId];
|
||||
const device = this._registries.devices[valueId];
|
||||
const isService = device.entry_type === "service";
|
||||
const { entities } =
|
||||
entries[`${isService ? "service" : "area"}${TARGET_SEPARATOR}`]
|
||||
@@ -316,7 +301,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
)
|
||||
: this._renderItem(
|
||||
!floor.id
|
||||
? this.localize(
|
||||
? this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.other_areas"
|
||||
)
|
||||
: floor.primary,
|
||||
@@ -337,7 +322,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
)
|
||||
);
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.home"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -345,7 +330,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
? html`<ha-md-list>
|
||||
<ha-md-list-item type="text">
|
||||
<div slot="headline">
|
||||
${this.localize("ui.components.area-picker.no_areas")}
|
||||
${this._i18n.localize("ui.components.area-picker.no_areas")}
|
||||
</div>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>`
|
||||
@@ -362,9 +347,9 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
(narrow: boolean, value?: SingleHassServiceTarget) => {
|
||||
const labels = this._getLabelsMemoized(
|
||||
this.states,
|
||||
this.areas,
|
||||
this.devices,
|
||||
this.entities,
|
||||
this._registries.areas,
|
||||
this._registries.devices,
|
||||
this._registries.entities,
|
||||
this._labelRegistry,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -380,7 +365,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.components.label-picker.labels"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -447,7 +432,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const open = entries[`device${TARGET_SEPARATOR}`].open;
|
||||
items.push(
|
||||
this._renderItem(
|
||||
this.localize("ui.components.target-picker.type.entities"),
|
||||
this._i18n.localize("ui.components.target-picker.type.entities"),
|
||||
`device${TARGET_SEPARATOR}`,
|
||||
true,
|
||||
false,
|
||||
@@ -468,7 +453,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const open = entries[`helper${TARGET_SEPARATOR}`].open;
|
||||
items.push(
|
||||
this._renderItem(
|
||||
this.localize("ui.panel.config.automation.editor.helpers"),
|
||||
this._i18n.localize("ui.panel.config.automation.editor.helpers"),
|
||||
`helper${TARGET_SEPARATOR}`,
|
||||
true,
|
||||
false,
|
||||
@@ -489,7 +474,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const open = entries[`area${TARGET_SEPARATOR}`].open;
|
||||
items.push(
|
||||
this._renderItem(
|
||||
this.localize("ui.components.target-picker.type.devices"),
|
||||
this._i18n.localize("ui.components.target-picker.type.devices"),
|
||||
`area${TARGET_SEPARATOR}`,
|
||||
true,
|
||||
false,
|
||||
@@ -507,7 +492,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const open = entries[`service${TARGET_SEPARATOR}`].open;
|
||||
items.push(
|
||||
this._renderItem(
|
||||
this.localize("ui.panel.config.automation.editor.services"),
|
||||
this._i18n.localize("ui.panel.config.automation.editor.services"),
|
||||
`service${TARGET_SEPARATOR}`,
|
||||
true,
|
||||
false,
|
||||
@@ -524,7 +509,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.unassigned"
|
||||
)}</ha-section-title
|
||||
>${narrow
|
||||
@@ -539,11 +524,11 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const renderedAreas = Object.keys(areas)
|
||||
.filter((areaTargetId) => {
|
||||
const [, areaId] = areaTargetId.split(TARGET_SEPARATOR, 2);
|
||||
return this.areas[areaId];
|
||||
return this._registries.areas[areaId];
|
||||
})
|
||||
.map((areaTargetId) => {
|
||||
const [, areaId] = areaTargetId.split(TARGET_SEPARATOR, 2);
|
||||
const area = this.areas[areaId];
|
||||
const area = this._registries.areas[areaId];
|
||||
return [
|
||||
areaTargetId,
|
||||
computeAreaName(area) || area.area_id,
|
||||
@@ -578,7 +563,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
if (this.narrow) {
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.components.target-picker.type.areas"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -590,9 +575,9 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
private _renderDevices(devices: Record<string, Level3Entries>) {
|
||||
const renderedDevices = Object.keys(devices)
|
||||
.filter((deviceId) => this.devices[deviceId])
|
||||
.filter((deviceId) => this._registries.devices[deviceId])
|
||||
.map((deviceId) => {
|
||||
const device = this.devices[deviceId];
|
||||
const device = this._registries.devices[deviceId];
|
||||
const configEntry = device.primary_config_entry
|
||||
? this._configEntryLookup?.[device.primary_config_entry]
|
||||
: undefined;
|
||||
@@ -627,7 +612,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
if (this.narrow) {
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.components.target-picker.type.devices"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -648,7 +633,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
domainTargetId.length - TARGET_SEPARATOR.length
|
||||
);
|
||||
const label = domainToName(
|
||||
this.localize,
|
||||
this._i18n.localize,
|
||||
domain,
|
||||
this.manifests![domain]
|
||||
);
|
||||
@@ -674,7 +659,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
if (this.narrow) {
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.components.target-picker.type.devices"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -697,16 +682,16 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const [entityName, deviceName] = computeEntityNameList(
|
||||
stateObj,
|
||||
[{ type: "entity" }, { type: "device" }, { type: "area" }],
|
||||
this.entities,
|
||||
this.devices,
|
||||
this.areas,
|
||||
this.floors
|
||||
this._registries.entities,
|
||||
this._registries.devices,
|
||||
this._registries.areas,
|
||||
this._registries.floors
|
||||
);
|
||||
|
||||
let label = entityName || deviceName || entityId;
|
||||
|
||||
if (this.entities[entityId]?.hidden) {
|
||||
label += ` (${this.localize("ui.panel.config.automation.editor.entity_hidden")})`;
|
||||
if (this._registries.entities[entityId]?.hidden) {
|
||||
label += ` (${this._i18n.localize("ui.panel.config.automation.editor.entity_hidden")})`;
|
||||
}
|
||||
|
||||
return [entityId, label, stateObj] as [string, string, HassEntity];
|
||||
@@ -729,7 +714,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
|
||||
if (this.narrow) {
|
||||
return html`<ha-section-title
|
||||
>${this.localize(
|
||||
>${this._i18n.localize(
|
||||
"ui.components.target-picker.type.entities"
|
||||
)}</ha-section-title
|
||||
>
|
||||
@@ -867,10 +852,10 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
private _getTreeData() {
|
||||
this._floorAreas = getAreasNestedInFloors(
|
||||
this.states,
|
||||
this.floors,
|
||||
this.areas,
|
||||
this.devices,
|
||||
this.entities,
|
||||
this._registries.floors,
|
||||
this._registries.areas,
|
||||
this._registries.devices,
|
||||
this._registries.entities,
|
||||
this._formatId,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -903,7 +888,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
private _loadUnassignedDevices() {
|
||||
const unassignedDevices = Object.values(this.devices).filter(
|
||||
const unassignedDevices = Object.values(this._registries.devices).filter(
|
||||
(device) => !device.area_id
|
||||
);
|
||||
|
||||
@@ -912,16 +897,16 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
const services: Record<string, Level3Entries> = {};
|
||||
|
||||
unassignedDevices.forEach(({ id: deviceId, entry_type }) => {
|
||||
const device = this.devices[deviceId];
|
||||
const device = this._registries.devices[deviceId];
|
||||
if (!device || device.disabled_by) {
|
||||
return;
|
||||
}
|
||||
const deviceEntry = {
|
||||
open: false,
|
||||
entities:
|
||||
this._getDeviceEntityLookupMemoized(this.entities)[deviceId]?.map(
|
||||
(entity) => entity.entity_id
|
||||
) || [],
|
||||
this._getDeviceEntityLookupMemoized(this._registries.entities)[
|
||||
deviceId
|
||||
]?.map((entity) => entity.entity_id) || [],
|
||||
};
|
||||
if (entry_type === "service") {
|
||||
services[deviceId] = deviceEntry;
|
||||
@@ -953,7 +938,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
private _loadUnassignedEntities() {
|
||||
Object.values(this.entities)
|
||||
Object.values(this._registries.entities)
|
||||
.filter((entity) => !entity.area_id && !entity.device_id)
|
||||
.forEach(({ entity_id }) => {
|
||||
const domain = entity_id.split(".", 2)[0];
|
||||
@@ -1010,23 +995,23 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
private _loadArea(area: FloorComboBoxItem) {
|
||||
const [, id] = area.id.split(TARGET_SEPARATOR, 2);
|
||||
const referenced_devices =
|
||||
this._getAreaDeviceLookupMemoized(this.devices)[id] || [];
|
||||
this._getAreaDeviceLookupMemoized(this._registries.devices)[id] || [];
|
||||
const referenced_entities =
|
||||
this._getAreaEntityLookupMemoized(this.entities)[id] || [];
|
||||
this._getAreaEntityLookupMemoized(this._registries.entities)[id] || [];
|
||||
|
||||
const devices: Record<string, Level3Entries> = {};
|
||||
|
||||
referenced_devices.forEach(({ id: deviceId }) => {
|
||||
const device = this.devices[deviceId];
|
||||
const device = this._registries.devices[deviceId];
|
||||
if (!device || device.disabled_by) {
|
||||
return;
|
||||
}
|
||||
devices[deviceId] = {
|
||||
open: false,
|
||||
entities:
|
||||
this._getDeviceEntityLookupMemoized(this.entities)[deviceId]?.map(
|
||||
(entity) => entity.entity_id
|
||||
) || [],
|
||||
this._getDeviceEntityLookupMemoized(this._registries.entities)[
|
||||
deviceId
|
||||
]?.map((entity) => entity.entity_id) || [],
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1051,17 +1036,17 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (type === "entity") {
|
||||
const deviceId = this.entities[id]?.device_id;
|
||||
const device = deviceId ? this.devices[deviceId] : undefined;
|
||||
const deviceId = this._registries.entities[id]?.device_id;
|
||||
const device = deviceId ? this._registries.devices[deviceId] : undefined;
|
||||
const deviceAreaId = (deviceId && device?.area_id) || undefined;
|
||||
|
||||
if (!deviceAreaId) {
|
||||
let floor: string;
|
||||
let area: string;
|
||||
const entity = this.entities[id];
|
||||
const entity = this._registries.entities[id];
|
||||
|
||||
if (!deviceId && entity.area_id) {
|
||||
floor = `floor${TARGET_SEPARATOR}${this.areas[entity.area_id]?.floor_id || ""}`;
|
||||
floor = `floor${TARGET_SEPARATOR}${this._registries.areas[entity.area_id]?.floor_id || ""}`;
|
||||
area = `area${TARGET_SEPARATOR}${entity.area_id}`;
|
||||
} else if (!deviceId) {
|
||||
const domain = id.split(".", 1)[0];
|
||||
@@ -1093,7 +1078,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const floor = `floor${TARGET_SEPARATOR}${this.areas[deviceAreaId]?.floor_id || ""}`;
|
||||
const floor = `floor${TARGET_SEPARATOR}${this._registries.areas[deviceAreaId]?.floor_id || ""}`;
|
||||
const area = `area${TARGET_SEPARATOR}${deviceAreaId}`;
|
||||
|
||||
this._entries = {
|
||||
@@ -1121,10 +1106,10 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (type === "device") {
|
||||
const deviceAreaId = this.devices[id]?.area_id;
|
||||
const deviceAreaId = this._registries.devices[id]?.area_id;
|
||||
|
||||
if (!deviceAreaId) {
|
||||
const device = this.devices[id];
|
||||
const device = this._registries.devices[id];
|
||||
const floor = `${device.entry_type === "service" ? "service" : "area"}${TARGET_SEPARATOR}`;
|
||||
this._entries = {
|
||||
...this._entries,
|
||||
@@ -1136,7 +1121,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const floor = `floor${TARGET_SEPARATOR}${this.areas[deviceAreaId]?.floor_id || ""}`;
|
||||
const floor = `floor${TARGET_SEPARATOR}${this._registries.areas[deviceAreaId]?.floor_id || ""}`;
|
||||
const area = `area${TARGET_SEPARATOR}${deviceAreaId}`;
|
||||
|
||||
this._entries = {
|
||||
@@ -1157,7 +1142,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (type === "area") {
|
||||
const floor = `floor${TARGET_SEPARATOR}${this.areas[id]?.floor_id || ""}`;
|
||||
const floor = `floor${TARGET_SEPARATOR}${this._registries.areas[id]?.floor_id || ""}`;
|
||||
this._entries = {
|
||||
...this._entries,
|
||||
[floor]: {
|
||||
@@ -1231,7 +1216,7 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (type === "area" && id) {
|
||||
const floorId = `floor${TARGET_SEPARATOR}${this.areas[id]?.floor_id || ""}`;
|
||||
const floorId = `floor${TARGET_SEPARATOR}${this._registries.areas[id]?.floor_id || ""}`;
|
||||
|
||||
this._entries = {
|
||||
...this._entries,
|
||||
@@ -1272,10 +1257,10 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
if (type === "device" && id) {
|
||||
const areaId = this.devices[id]?.area_id;
|
||||
const areaId = this._registries.devices[id]?.area_id;
|
||||
if (areaId) {
|
||||
const areaTargetId = `area${TARGET_SEPARATOR}${this.devices[id]?.area_id ?? ""}`;
|
||||
const floorId = `floor${TARGET_SEPARATOR}${(areaId && this.areas[areaId]?.floor_id) || ""}`;
|
||||
const areaTargetId = `area${TARGET_SEPARATOR}${this._registries.devices[id]?.area_id ?? ""}`;
|
||||
const floorId = `floor${TARGET_SEPARATOR}${(areaId && this._registries.areas[areaId]?.floor_id) || ""}`;
|
||||
|
||||
this._entries = {
|
||||
...this._entries,
|
||||
@@ -1300,7 +1285,9 @@ export default class HaAutomationAddFromTarget extends LitElement {
|
||||
}
|
||||
|
||||
const deviceType =
|
||||
this.devices[id]?.entry_type === "service" ? "service" : "area";
|
||||
this._registries.devices[id]?.entry_type === "service"
|
||||
? "service"
|
||||
: "area";
|
||||
const floorId = `${deviceType}${TARGET_SEPARATOR}`;
|
||||
this._entries = {
|
||||
...this._entries,
|
||||
|
||||
@@ -36,6 +36,7 @@ import type { HaAutomationRow } from "../../../../components/ha-automation-row";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-condition-icon";
|
||||
import "../../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-icon-button";
|
||||
@@ -76,7 +77,6 @@ import "./types/ha-automation-condition-template";
|
||||
import "./types/ha-automation-condition-time";
|
||||
import "./types/ha-automation-condition-trigger";
|
||||
import "./types/ha-automation-condition-zone";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
|
||||
export interface ConditionElement extends LitElement {
|
||||
condition: Condition;
|
||||
|
||||
@@ -45,13 +45,13 @@ import type {
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/entity/ha-entity-toggle";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type {
|
||||
HaDropdown,
|
||||
HaDropdownSelectEvent,
|
||||
} from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-filter-blueprints";
|
||||
import "../../../components/ha-filter-categories";
|
||||
import "../../../components/ha-filter-devices";
|
||||
|
||||
@@ -21,6 +21,7 @@ import "../../../../components/ha-automation-row";
|
||||
import type { HaAutomationRow } from "../../../../components/ha-automation-row";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-icon-button";
|
||||
@@ -47,7 +48,6 @@ import {
|
||||
overflowStyles,
|
||||
rowStyles,
|
||||
} from "../styles";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
|
||||
@customElement("ha-automation-option-row")
|
||||
export default class HaAutomationOptionRow extends LitElement {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import {
|
||||
mdiAlert,
|
||||
mdiAlertOctagon,
|
||||
@@ -16,12 +16,10 @@ import { isTemplate } from "../../../../common/string/has-template";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import type { ConfigEntry } from "../../../../data/config_entries";
|
||||
import {
|
||||
areasContext,
|
||||
configEntriesContext,
|
||||
devicesContext,
|
||||
floorsContext,
|
||||
internationalizationContext,
|
||||
labelsContext,
|
||||
localizeContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../../../data/context";
|
||||
import type { LabelRegistryEntry } from "../../../../data/label/label_registry";
|
||||
@@ -41,29 +39,20 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
public targetRequired = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: HomeAssistant["localize"];
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: floorsContext, subscribe: true })
|
||||
private floors!: HomeAssistant["floors"];
|
||||
|
||||
@state()
|
||||
@consume({ context: areasContext, subscribe: true })
|
||||
private areas!: HomeAssistant["areas"];
|
||||
|
||||
@state()
|
||||
@consume({ context: devicesContext, subscribe: true })
|
||||
private devices!: HomeAssistant["devices"];
|
||||
|
||||
@state()
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private states!: HomeAssistant["states"];
|
||||
@consume({ context: registriesContext, subscribe: true })
|
||||
private _registries!: ContextType<typeof registriesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: labelsContext, subscribe: true })
|
||||
private _labelRegistry!: LabelRegistryEntry[];
|
||||
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private _states!: ContextType<typeof statesContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: configEntriesContext, subscribe: true })
|
||||
@transform<ConfigEntry[], Record<string, ConfigEntry>>({
|
||||
@@ -82,7 +71,7 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
this.targetRequired
|
||||
? html`<ha-svg-icon .path=${mdiAlertOctagon}></ha-svg-icon>`
|
||||
: nothing,
|
||||
this.localize(
|
||||
this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.no_target"
|
||||
),
|
||||
false,
|
||||
@@ -124,7 +113,7 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
return html`<span class="target">
|
||||
<ha-svg-icon .path=${mdiFormatListBulleted}></ha-svg-icon>
|
||||
<div class="label">
|
||||
${this.localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.targets",
|
||||
{
|
||||
count: totalLength,
|
||||
@@ -142,16 +131,16 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
targetId: string
|
||||
): boolean {
|
||||
if (targetType === "floor") {
|
||||
return !!this.floors[targetId];
|
||||
return !!this._registries.floors[targetId];
|
||||
}
|
||||
if (targetType === "area") {
|
||||
return !!this.areas[targetId];
|
||||
return !!this._registries.areas[targetId];
|
||||
}
|
||||
if (targetType === "device") {
|
||||
return !!this.devices[targetId];
|
||||
return !!this._registries.devices[targetId];
|
||||
}
|
||||
if (targetType === "entity") {
|
||||
return !!this.states[targetId];
|
||||
return !!this._states[targetId];
|
||||
}
|
||||
if (targetType === "label") {
|
||||
return !!this._getLabel(targetId);
|
||||
@@ -178,7 +167,7 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
if (targetType === "entity" && ["all", "none"].includes(targetId)) {
|
||||
return this._renderTargetBadge(
|
||||
html`<ha-svg-icon .path=${mdiShape}></ha-svg-icon>`,
|
||||
this.localize(
|
||||
this._i18n.localize(
|
||||
`ui.panel.config.automation.editor.target_summary.${targetId as "all" | "none"}_entities`
|
||||
)
|
||||
);
|
||||
@@ -188,7 +177,7 @@ export class HaAutomationRowTargets extends LitElement {
|
||||
if (isTemplate(targetId)) {
|
||||
return this._renderTargetBadge(
|
||||
html`<ha-svg-icon .path=${mdiCodeBraces}></ha-svg-icon>`,
|
||||
this.localize(
|
||||
this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.target_summary.template"
|
||||
)
|
||||
);
|
||||
|
||||
@@ -39,6 +39,7 @@ import "../../../../components/ha-automation-row";
|
||||
import type { HaAutomationRow } from "../../../../components/ha-automation-row";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-icon-button";
|
||||
@@ -89,7 +90,6 @@ import "./types/ha-automation-trigger-time";
|
||||
import "./types/ha-automation-trigger-time_pattern";
|
||||
import "./types/ha-automation-trigger-webhook";
|
||||
import "./types/ha-automation-trigger-zone";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
|
||||
export interface TriggerElement extends LitElement {
|
||||
trigger: Trigger;
|
||||
|
||||
@@ -30,6 +30,7 @@ import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { showAlertDialog } from "../../lovelace/custom-card-helpers";
|
||||
import "./components/overview/ha-backup-overview-backups";
|
||||
import "./components/overview/ha-backup-overview-onboarding";
|
||||
import "./components/overview/ha-backup-overview-progress";
|
||||
@@ -87,7 +88,17 @@ class HaConfigBackupOverview extends LitElement {
|
||||
}
|
||||
|
||||
fireEvent(this, "ha-refresh-backup-config");
|
||||
await generateBackupWithAutomaticSettings(this.hass);
|
||||
try {
|
||||
await generateBackupWithAutomaticSettings(this.hass);
|
||||
} catch (err: any) {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.backup.overview.create_backup_failed"
|
||||
),
|
||||
text: err.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
fireEvent(this, "ha-refresh-backup-info");
|
||||
}
|
||||
|
||||
@@ -109,23 +120,30 @@ class HaConfigBackupOverview extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "manual") {
|
||||
const params = await showGenerateBackupDialog(this, {
|
||||
cloudStatus: this.cloudStatus,
|
||||
});
|
||||
try {
|
||||
if (type === "manual") {
|
||||
const params = await showGenerateBackupDialog(this, {
|
||||
cloudStatus: this.cloudStatus,
|
||||
});
|
||||
|
||||
if (!params) {
|
||||
return;
|
||||
if (!params) {
|
||||
return;
|
||||
}
|
||||
|
||||
await generateBackup(this.hass, params);
|
||||
} else if (type === "automatic") {
|
||||
await generateBackupWithAutomaticSettings(this.hass);
|
||||
}
|
||||
|
||||
await generateBackup(this.hass, params);
|
||||
fireEvent(this, "ha-refresh-backup-info");
|
||||
} catch (err: any) {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.backup.overview.create_backup_failed"
|
||||
),
|
||||
text: err.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (type === "automatic") {
|
||||
await generateBackupWithAutomaticSettings(this.hass);
|
||||
fireEvent(this, "ha-refresh-backup-info");
|
||||
}
|
||||
fireEvent(this, "ha-refresh-backup-info");
|
||||
}
|
||||
|
||||
private get _needsOnboarding() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
CategoryRegistryEntry,
|
||||
CategoryRegistryEntryMutableParams,
|
||||
} from "../../../data/category_registry";
|
||||
import { localizeContext } from "../../../data/context";
|
||||
import { internationalizationContext } from "../../../data/context";
|
||||
import { DialogMixin } from "../../../dialogs/dialog-mixin";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
import type { ValueChangedEvent } from "../../../types";
|
||||
@@ -24,8 +24,8 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
LitElement
|
||||
) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state() private _name!: string;
|
||||
|
||||
@@ -56,8 +56,8 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
<ha-dialog
|
||||
open
|
||||
header-title=${entry
|
||||
? this.localize("ui.panel.config.category.editor.edit")
|
||||
: this.localize("ui.panel.config.category.editor.create")}
|
||||
? this._i18n.localize("ui.panel.config.category.editor.edit")
|
||||
: this._i18n.localize("ui.panel.config.category.editor.create")}
|
||||
prevent-scrim-close
|
||||
>
|
||||
${this._error
|
||||
@@ -67,8 +67,10 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
<ha-input
|
||||
.value=${this._name}
|
||||
@input=${this._nameChanged}
|
||||
.label=${this.localize("ui.panel.config.category.editor.name")}
|
||||
.validationMessage=${this.localize(
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.category.editor.name"
|
||||
)}
|
||||
.validationMessage=${this._i18n.localize(
|
||||
"ui.panel.config.category.editor.required_error_msg"
|
||||
)}
|
||||
required
|
||||
@@ -78,7 +80,9 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
<ha-icon-picker
|
||||
.value=${this._icon ?? undefined}
|
||||
@value-changed=${this._iconChanged}
|
||||
.label=${this.localize("ui.panel.config.category.editor.icon")}
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.category.editor.icon"
|
||||
)}
|
||||
></ha-icon-picker>
|
||||
</div>
|
||||
<ha-dialog-footer slot="footer">
|
||||
@@ -87,7 +91,7 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
appearance="plain"
|
||||
@click=${this.closeDialog}
|
||||
>
|
||||
${this.localize("ui.common.cancel")}
|
||||
${this._i18n.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
@@ -95,8 +99,8 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
.disabled=${nameInvalid || !!this._submitting}
|
||||
>
|
||||
${entry
|
||||
? this.localize("ui.common.save")
|
||||
: this.localize("ui.common.add")}
|
||||
? this._i18n.localize("ui.common.save")
|
||||
: this._i18n.localize("ui.common.add")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-dialog>
|
||||
@@ -135,7 +139,7 @@ class DialogCategoryDetail extends DialogMixin<CategoryRegistryDetailDialogParam
|
||||
} catch (err: any) {
|
||||
this._error =
|
||||
err.message ||
|
||||
this.localize("ui.panel.config.category.editor.unknown_error");
|
||||
this._i18n.localize("ui.panel.config.category.editor.unknown_error");
|
||||
} finally {
|
||||
this._submitting = false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import { consume } from "@lit/context";
|
||||
import {
|
||||
mdiCancel,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
@@ -37,10 +37,11 @@ import type {
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/entity/ha-battery-icon";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-integrations";
|
||||
@@ -83,18 +84,17 @@ import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
import { showAreaRegistryDetailDialog } from "../areas/show-dialog-area-registry-detail";
|
||||
import {
|
||||
getAreaTableColumn,
|
||||
getCreatedAtTableColumn,
|
||||
getFloorTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getModifiedAtTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import "../integrations/ha-integration-overflow-menu";
|
||||
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||
import {
|
||||
getAreaTableColumn,
|
||||
getFloorTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getCreatedAtTableColumn,
|
||||
getModifiedAtTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
interface DeviceRowData extends DeviceRegistryEntry {
|
||||
device?: DeviceRowData;
|
||||
|
||||
@@ -55,9 +55,10 @@ import type {
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-button";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-domains";
|
||||
@@ -109,26 +110,25 @@ import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import {
|
||||
getAreaTableColumn,
|
||||
getCreatedAtTableColumn,
|
||||
getDomainTableColumn,
|
||||
getEntityIdTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getModifiedAtTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import type { Helper } from "../helpers/const";
|
||||
import { isHelperDomain } from "../helpers/const";
|
||||
import "../integrations/ha-integration-overflow-menu";
|
||||
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||
import {
|
||||
getEntityIdTableColumn,
|
||||
getDomainTableColumn,
|
||||
getAreaTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getCreatedAtTableColumn,
|
||||
getModifiedAtTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import {
|
||||
getAssistantsSortableKey,
|
||||
getAssistantsTableColumn,
|
||||
} from "../voice-assistants/expose/assistants-table-column";
|
||||
import { getAvailableAssistants } from "../voice-assistants/expose/available-assistants";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
export interface StateEntity extends Omit<
|
||||
EntityRegistryEntry,
|
||||
|
||||
@@ -42,9 +42,10 @@ import type {
|
||||
SortingChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-filter-categories";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-entities";
|
||||
@@ -112,15 +113,15 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { fileDownload } from "../../../util/file_download";
|
||||
import {
|
||||
getEntityIdTableColumn,
|
||||
getAreaTableColumn,
|
||||
getCategoryTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getEditableTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
||||
import {
|
||||
getAreaTableColumn,
|
||||
getCategoryTableColumn,
|
||||
getEditableTableColumn,
|
||||
getEntityIdTableColumn,
|
||||
getLabelsTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { renderConfigEntryError } from "../integrations/ha-config-integration-page";
|
||||
import "../integrations/ha-integration-overflow-menu";
|
||||
@@ -132,7 +133,6 @@ import {
|
||||
import { getAvailableAssistants } from "../voice-assistants/expose/available-assistants";
|
||||
import { isHelperDomain, type HelperDomain } from "./const";
|
||||
import { showHelperDetailDialog } from "./show-dialog-helper-detail";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
interface HelperItem {
|
||||
id: string;
|
||||
|
||||
@@ -17,12 +17,10 @@ import "../../../../../../components/ha-md-list";
|
||||
import "../../../../../../components/ha-md-list-item";
|
||||
import "../../../../../../components/ha-spinner";
|
||||
import {
|
||||
areasContext,
|
||||
configEntriesContext,
|
||||
devicesContext,
|
||||
entitiesContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
internationalizationContext,
|
||||
registriesContext,
|
||||
statesContext,
|
||||
} from "../../../../../../data/context";
|
||||
import {
|
||||
@@ -38,8 +36,8 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
LitElement
|
||||
) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private _localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: configEntriesContext, subscribe: true })
|
||||
@@ -84,14 +82,8 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
@consume({ context: statesContext, subscribe: true })
|
||||
private _states!: ContextType<typeof statesContext>;
|
||||
|
||||
@consume({ context: entitiesContext, subscribe: true })
|
||||
private _entities!: ContextType<typeof entitiesContext>;
|
||||
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
private _locale!: ContextType<typeof localeContext>;
|
||||
|
||||
@consume({ context: areasContext, subscribe: true })
|
||||
private _areas!: ContextType<typeof areasContext>;
|
||||
@consume({ context: registriesContext, subscribe: true })
|
||||
private _registries!: ContextType<typeof registriesContext>;
|
||||
|
||||
protected render() {
|
||||
if (!this.params) {
|
||||
@@ -102,7 +94,7 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
<ha-dialog
|
||||
open
|
||||
width="small"
|
||||
.headerTitle=${this._localize(
|
||||
.headerTitle=${this._i18n.localize(
|
||||
`ui.panel.config.zwave_js.rebuild_network_routes.details.${this.params.type}`,
|
||||
{
|
||||
count: this._progress ? this._progress.length : 0,
|
||||
@@ -117,7 +109,7 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
`
|
||||
: !this._progress || this._progress.length === 0
|
||||
? html`<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.details.no_devices"
|
||||
)}
|
||||
</p>`
|
||||
@@ -165,7 +157,7 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
});
|
||||
|
||||
const deviceEntityLookup = getDeviceEntityDisplayLookup(
|
||||
Object.values(this._entities)
|
||||
Object.values(this._registries.entities)
|
||||
);
|
||||
|
||||
const configEntryLookup = Object.fromEntries(
|
||||
@@ -177,12 +169,13 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
const name =
|
||||
computeDeviceNameDisplay(
|
||||
device,
|
||||
this._localize,
|
||||
this._i18n.localize,
|
||||
this._states,
|
||||
deviceEntityLookup[device.id]
|
||||
) || this._localize("ui.components.device-picker.unnamed_device");
|
||||
) ||
|
||||
this._i18n.localize("ui.components.device-picker.unnamed_device");
|
||||
|
||||
const area = getDeviceArea(device, this._areas);
|
||||
const area = getDeviceArea(device, this._registries.areas);
|
||||
|
||||
const areaName = area ? computeAreaName(area) : undefined;
|
||||
|
||||
@@ -200,7 +193,7 @@ class DialogZWaveJSRebuildNetworkRoutesDetail extends DialogMixin<ZWaveJSRebuild
|
||||
caseInsensitiveStringCompare(
|
||||
[entry1.name, entry1.areaName].filter(Boolean).join(" "),
|
||||
[entry2.name, entry2.areaName].filter(Boolean).join(" "),
|
||||
this._locale.language
|
||||
this._i18n.locale.language
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import "../../../../../../components/ha-spinner";
|
||||
import "../../../../../../components/progress/ha-progress-bar";
|
||||
import {
|
||||
connectionContext,
|
||||
localizeContext,
|
||||
internationalizationContext,
|
||||
} from "../../../../../../data/context";
|
||||
import type {
|
||||
ZWaveJSNetwork,
|
||||
@@ -46,8 +46,8 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
LitElement
|
||||
) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private _localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state()
|
||||
@consume({ context: connectionContext, subscribe: true })
|
||||
@@ -81,7 +81,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
header-title=${this._localize(
|
||||
header-title=${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.title"
|
||||
)}
|
||||
>
|
||||
@@ -100,7 +100,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.introduction"
|
||||
)}
|
||||
</p>
|
||||
@@ -108,7 +108,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
</div>
|
||||
<p>
|
||||
<em>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.traffic_warning"
|
||||
)}
|
||||
</em>
|
||||
@@ -119,13 +119,13 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
<div class="status">
|
||||
<p>
|
||||
<b>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.in_progress"
|
||||
)}
|
||||
</b>
|
||||
</p>
|
||||
<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.run_in_background"
|
||||
)}
|
||||
</p>
|
||||
@@ -146,7 +146,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
appearance="outlined"
|
||||
variant="warning"
|
||||
size="small"
|
||||
.title=${this._localize(
|
||||
.title=${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.progress.in_progress",
|
||||
{ count: this._progress.pending.length }
|
||||
)}
|
||||
@@ -163,7 +163,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
appearance="outlined"
|
||||
variant="success"
|
||||
size="small"
|
||||
.title=${this._localize(
|
||||
.title=${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.progress.completed",
|
||||
{ count: this._progress.done.length }
|
||||
)}
|
||||
@@ -182,7 +182,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
appearance="outlined"
|
||||
variant="danger"
|
||||
size="small"
|
||||
.title=${this._localize(
|
||||
.title=${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.progress.failed",
|
||||
{ count: this._progress.failed.length }
|
||||
)}
|
||||
@@ -201,7 +201,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
appearance="outlined"
|
||||
variant="neutral"
|
||||
size="small"
|
||||
.title=${this._localize(
|
||||
.title=${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.progress.skipped",
|
||||
{ count: this._progress.skipped.length }
|
||||
)}
|
||||
@@ -225,7 +225,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.rebuilding_routes_failed"
|
||||
)}
|
||||
</p>
|
||||
@@ -241,7 +241,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.rebuilding_routes_complete"
|
||||
)}
|
||||
</p>
|
||||
@@ -257,7 +257,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
></ha-svg-icon>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.rebuilding_routes_cancelled"
|
||||
)}
|
||||
</p>
|
||||
@@ -272,7 +272,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
slot="primaryAction"
|
||||
@click=${this._startRebuildingRoutes}
|
||||
>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.start_rebuilding_routes"
|
||||
)}
|
||||
</ha-button>
|
||||
@@ -285,17 +285,17 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
@click=${this._stopRebuildingRoutes}
|
||||
variant="danger"
|
||||
>
|
||||
${this._localize(
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_network_routes.stop_rebuilding_routes"
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this._localize("ui.common.close")}
|
||||
${this._i18n.localize("ui.common.close")}
|
||||
</ha-button>
|
||||
`
|
||||
: html`
|
||||
<ha-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
${this._localize("ui.common.close")}
|
||||
${this._i18n.localize("ui.common.close")}
|
||||
</ha-button>
|
||||
`}
|
||||
</ha-dialog-footer>
|
||||
@@ -305,7 +305,7 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
|
||||
private async _fetchData(): Promise<void> {
|
||||
const network: ZWaveJSNetwork = await fetchZwaveNetworkStatus(
|
||||
this._connection,
|
||||
this._connection.connection,
|
||||
{
|
||||
entry_id: this.params!.entry_id,
|
||||
}
|
||||
@@ -319,21 +319,27 @@ class DialogZWaveJSRebuildNetworkRoutes extends DialogMixin<ZWaveJSRebuildNetwor
|
||||
}
|
||||
|
||||
private _startRebuildingRoutes(): void {
|
||||
rebuildZwaveNetworkRoutes(this._connection, this.params!.entry_id);
|
||||
rebuildZwaveNetworkRoutes(
|
||||
this._connection.connection,
|
||||
this.params!.entry_id
|
||||
);
|
||||
this._status = "started";
|
||||
this._startSubscribingToProgress();
|
||||
}
|
||||
|
||||
private async _startSubscribingToProgress() {
|
||||
this._subscribed = subscribeRebuildZwaveNetworkRoutesProgress(
|
||||
this._connection,
|
||||
this._connection.connection,
|
||||
this.params!.entry_id,
|
||||
this._handleMessage
|
||||
);
|
||||
}
|
||||
|
||||
private _stopRebuildingRoutes(): void {
|
||||
stopRebuildingZwaveNetworkRoutes(this._connection, this.params!.entry_id);
|
||||
stopRebuildingZwaveNetworkRoutes(
|
||||
this._connection.connection,
|
||||
this.params!.entry_id
|
||||
);
|
||||
this._unsubscribe();
|
||||
this._status = "cancelled";
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import "../../../components/ha-icon-picker";
|
||||
import "../../../components/ha-switch";
|
||||
import "../../../components/ha-textarea";
|
||||
import "../../../components/input/ha-input";
|
||||
import { localizeContext } from "../../../data/context";
|
||||
import { internationalizationContext } from "../../../data/context";
|
||||
import type { LabelRegistryEntryMutableParams } from "../../../data/label/label_registry";
|
||||
import { DialogMixin } from "../../../dialogs/dialog-mixin";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
@@ -22,8 +22,8 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
LitElement
|
||||
) {
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize!: ContextType<typeof localizeContext>;
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state() private _name!: string;
|
||||
|
||||
@@ -62,7 +62,7 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
open
|
||||
header-title=${this.params.entry
|
||||
? this.params.entry.name || this.params.entry.label_id
|
||||
: this.localize("ui.dialogs.label-detail.new_label")}
|
||||
: this._i18n.localize("ui.dialogs.label-detail.new_label")}
|
||||
prevent-scrim-close
|
||||
>
|
||||
<div>
|
||||
@@ -75,8 +75,8 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
.value=${this._name}
|
||||
.configValue=${"name"}
|
||||
@input=${this._input}
|
||||
.label=${this.localize("ui.dialogs.label-detail.name")}
|
||||
.validationMessage=${this.localize(
|
||||
.label=${this._i18n.localize("ui.dialogs.label-detail.name")}
|
||||
.validationMessage=${this._i18n.localize(
|
||||
"ui.dialogs.label-detail.required_error_msg"
|
||||
)}
|
||||
required
|
||||
@@ -85,19 +85,21 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
.value=${this._icon}
|
||||
.configValue=${"icon"}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.localize("ui.dialogs.label-detail.icon")}
|
||||
.label=${this._i18n.localize("ui.dialogs.label-detail.icon")}
|
||||
></ha-icon-picker>
|
||||
<ha-color-picker
|
||||
.value=${this._color}
|
||||
.configValue=${"color"}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.localize("ui.dialogs.label-detail.color")}
|
||||
.label=${this._i18n.localize("ui.dialogs.label-detail.color")}
|
||||
></ha-color-picker>
|
||||
<ha-textarea
|
||||
.value=${this._description}
|
||||
.configValue=${"description"}
|
||||
@input=${this._input}
|
||||
.label=${this.localize("ui.dialogs.label-detail.description")}
|
||||
.label=${this._i18n.localize(
|
||||
"ui.dialogs.label-detail.description"
|
||||
)}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -112,7 +114,7 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
@click=${this._deleteEntry}
|
||||
.disabled=${this._submitting}
|
||||
>
|
||||
${this.localize("ui.common.delete")}
|
||||
${this._i18n.localize("ui.common.delete")}
|
||||
</ha-button>
|
||||
`
|
||||
: html`
|
||||
@@ -121,7 +123,7 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
slot="secondaryAction"
|
||||
@click=${this.closeDialog}
|
||||
>
|
||||
${this.localize("ui.common.cancel")}
|
||||
${this._i18n.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
`}
|
||||
<ha-button
|
||||
@@ -130,8 +132,8 @@ class DialogLabelDetail extends DialogMixin<LabelDetailDialogParams>(
|
||||
.disabled=${this._submitting || !this._name}
|
||||
>
|
||||
${this.params.entry
|
||||
? this.localize("ui.common.update")
|
||||
: this.localize("ui.common.create")}
|
||||
? this._i18n.localize("ui.common.update")
|
||||
: this._i18n.localize("ui.common.create")}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
</ha-dialog>
|
||||
|
||||
@@ -41,9 +41,10 @@ import type {
|
||||
SortingChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/data-table/ha-data-table-labels";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-filter-blueprints";
|
||||
import "../../../components/ha-filter-categories";
|
||||
import "../../../components/ha-filter-devices";
|
||||
@@ -106,9 +107,9 @@ import { showNewAutomationDialog } from "../automation/show-dialog-new-automatio
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
||||
import {
|
||||
getEntityIdHiddenTableColumn,
|
||||
getAreaTableColumn,
|
||||
getCategoryTableColumn,
|
||||
getEntityIdHiddenTableColumn,
|
||||
getLabelsTableColumn,
|
||||
getTriggeredAtTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
@@ -119,7 +120,6 @@ import {
|
||||
getAssistantsTableColumn,
|
||||
} from "../voice-assistants/expose/assistants-table-column";
|
||||
import { getAvailableAssistants } from "../voice-assistants/expose/available-assistants";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
type ScriptItem = ScriptEntity & {
|
||||
name: string;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { consume } from "@lit/context";
|
||||
import {
|
||||
mdiDotsVertical,
|
||||
mdiDownload,
|
||||
@@ -13,13 +14,13 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { consume } from "@lit/context";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { formatDateTimeWithSeconds } from "../../../common/datetime/format_date_time";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/trace/ha-trace-blueprint-config";
|
||||
@@ -33,6 +34,7 @@ import type {
|
||||
NodeInfo,
|
||||
} from "../../../components/trace/hat-script-graph";
|
||||
import { traceTabStyles } from "../../../components/trace/trace-tab-styles";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity/entity_registry";
|
||||
import type { LogbookEntry } from "../../../data/logbook";
|
||||
import { getLogbookDataForContext } from "../../../data/logbook";
|
||||
@@ -44,8 +46,6 @@ import "../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { fileDownload } from "../../../util/file_download";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
|
||||
@customElement("ha-script-trace")
|
||||
export class HaScriptTrace extends LitElement {
|
||||
|
||||
@@ -49,19 +49,19 @@ import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import {
|
||||
getEntityIdTableColumn,
|
||||
getDomainTableColumn,
|
||||
getAreaTableColumn,
|
||||
getDomainTableColumn,
|
||||
getEntityIdTableColumn,
|
||||
} from "../common/data-table-columns";
|
||||
import "./expose/expose-assistant-icon";
|
||||
import {
|
||||
getAssistantsTableColumn,
|
||||
getAssistantsSortableKey,
|
||||
getAssistantsTableColumn,
|
||||
} from "./expose/assistants-table-column";
|
||||
import { getAvailableAssistants } from "./expose/available-assistants";
|
||||
import "./expose/expose-assistant-icon";
|
||||
import { voiceAssistantTabs } from "./ha-config-voice-assistants";
|
||||
import { showExposeEntityDialog } from "./show-dialog-expose-entity";
|
||||
import { showVoiceSettingsDialog } from "./show-dialog-voice-settings";
|
||||
import { getAvailableAssistants } from "./expose/available-assistants";
|
||||
|
||||
@customElement("ha-config-voice-assistants-expose")
|
||||
export class VoiceAssistantsExpose extends LitElement {
|
||||
|
||||
@@ -95,13 +95,12 @@ export class DialogEditHome
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
.headerTitle=${this.hass.localize("ui.panel.home.editor.title")}
|
||||
.headerSubtitle=${this.hass.localize(
|
||||
"ui.panel.home.editor.description"
|
||||
)}
|
||||
prevent-scrim-close
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<p class="description">
|
||||
${this.hass.localize("ui.panel.home.editor.description")}
|
||||
</p>
|
||||
|
||||
<ha-entities-picker
|
||||
autofocus
|
||||
.hass=${this.hass}
|
||||
@@ -264,11 +263,6 @@ export class DialogEditHome
|
||||
--dialog-content-padding: var(--ha-space-6);
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0 0 var(--ha-space-4) 0;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { consume } from "@lit/context";
|
||||
import type {
|
||||
HassConfig,
|
||||
HassEntities,
|
||||
HassEntity,
|
||||
} from "home-assistant-js-websocket";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import type { HassEntities, HassEntity } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
@@ -23,23 +19,18 @@ import {
|
||||
} from "../../../common/entity/state_color";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-ripple";
|
||||
import { CLIMATE_HVAC_ACTION_TO_MODE } from "../../../data/climate";
|
||||
import {
|
||||
configContext,
|
||||
entitiesContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
statesContext,
|
||||
themesContext,
|
||||
uiContext,
|
||||
} from "../../../data/context";
|
||||
import type { EntityRegistryDisplayEntry } from "../../../data/entity/entity_registry";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { FrontendLocaleData } from "../../../data/translation";
|
||||
import type { Themes } from "../../../data/ws-themes";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { HomeAssistant, HomeAssistantUI } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -113,24 +104,15 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
private _stateObj?: HassEntity;
|
||||
|
||||
@state()
|
||||
@consume({ context: themesContext, subscribe: true })
|
||||
_themes!: Themes;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
_localize!: LocalizeFunc;
|
||||
|
||||
@state()
|
||||
@consume({ context: localeContext, subscribe: true })
|
||||
_locale!: FrontendLocaleData;
|
||||
|
||||
@state()
|
||||
@consume({ context: configContext, subscribe: true })
|
||||
_hassConfig!: HassConfig;
|
||||
@consume({ context: uiContext, subscribe: true })
|
||||
@transform<HomeAssistantUI, Themes>({
|
||||
transformer: ({ themes }) => themes,
|
||||
})
|
||||
private _themes!: Themes;
|
||||
|
||||
@state()
|
||||
@consume<any>({ context: entitiesContext, subscribe: true })
|
||||
@transform<HomeAssistant["entities"], EntityRegistryDisplayEntry>({
|
||||
@transform<ContextType<typeof entitiesContext>, EntityRegistryDisplayEntry>({
|
||||
transformer: function (this: HuiButtonCard, value) {
|
||||
return this._config?.entity ? value?.[this._config?.entity] : undefined;
|
||||
},
|
||||
@@ -184,7 +166,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._config || !this._localize || !this._locale) {
|
||||
if (!this._config) {
|
||||
return nothing;
|
||||
}
|
||||
const stateObj = this._stateObj;
|
||||
|
||||
@@ -89,7 +89,6 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
debugConnection: __DEV__,
|
||||
suspendWhenHidden: true,
|
||||
enableShortcuts: true,
|
||||
moreInfoEntityId: null,
|
||||
hassUrl: (path = "") =>
|
||||
addBrandsAuth(
|
||||
new URL(path, auth.data.hassUrl).toString(),
|
||||
|
||||
@@ -4,25 +4,33 @@ import {
|
||||
type ConfigEntryUpdate,
|
||||
} from "../data/config_entries";
|
||||
import {
|
||||
apiContext,
|
||||
areasContext,
|
||||
authContext,
|
||||
configContext,
|
||||
configEntriesContext,
|
||||
configSingleContext,
|
||||
connectionContext,
|
||||
connectionSingleContext,
|
||||
devicesContext,
|
||||
entitiesContext,
|
||||
floorsContext,
|
||||
fullEntitiesContext,
|
||||
internationalizationContext,
|
||||
labelsContext,
|
||||
localeContext,
|
||||
localizeContext,
|
||||
panelsContext,
|
||||
registriesContext,
|
||||
selectedThemeContext,
|
||||
servicesContext,
|
||||
statesContext,
|
||||
themesContext,
|
||||
uiContext,
|
||||
userContext,
|
||||
userDataContext,
|
||||
} from "../data/context";
|
||||
import { updateHassGroups } from "../data/context/updateContext";
|
||||
import { subscribeEntityRegistry } from "../data/entity/entity_registry";
|
||||
import { subscribeLabelRegistry } from "../data/label/label_registry";
|
||||
import type { Constructor, HomeAssistant } from "../types";
|
||||
@@ -33,20 +41,60 @@ export const contextMixin = <T extends Constructor<HassBaseEl>>(
|
||||
superClass: T
|
||||
) =>
|
||||
class extends superClass {
|
||||
private __hassContextProviderGroups: Record<string, ContextProvider<any>> =
|
||||
{
|
||||
registries: new ContextProvider(this, {
|
||||
context: registriesContext,
|
||||
initialValue: updateHassGroups.registries(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
internationalization: new ContextProvider(this, {
|
||||
context: internationalizationContext,
|
||||
initialValue: updateHassGroups.internationalization(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
api: new ContextProvider(this, {
|
||||
context: apiContext,
|
||||
initialValue: updateHassGroups.api(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
connection: new ContextProvider(this, {
|
||||
context: connectionContext,
|
||||
initialValue: updateHassGroups.connection(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
ui: new ContextProvider(this, {
|
||||
context: uiContext,
|
||||
initialValue: updateHassGroups.ui(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
config: new ContextProvider(this, {
|
||||
context: configContext,
|
||||
initialValue: updateHassGroups.config(
|
||||
this.hass || (this._pendingHass as HomeAssistant)
|
||||
),
|
||||
}),
|
||||
};
|
||||
|
||||
private __contextProviders: Record<
|
||||
string,
|
||||
ContextProvider<any> | undefined
|
||||
> = {
|
||||
connection: new ContextProvider(this, {
|
||||
context: connectionContext,
|
||||
initialValue: this.hass
|
||||
? this.hass.connection
|
||||
: this._pendingHass.connection,
|
||||
}),
|
||||
states: new ContextProvider(this, {
|
||||
context: statesContext,
|
||||
initialValue: this.hass ? this.hass.states : this._pendingHass.states,
|
||||
}),
|
||||
services: new ContextProvider(this, {
|
||||
context: servicesContext,
|
||||
initialValue: this.hass
|
||||
? this.hass.services
|
||||
: this._pendingHass.services,
|
||||
}),
|
||||
entities: new ContextProvider(this, {
|
||||
context: entitiesContext,
|
||||
initialValue: this.hass
|
||||
@@ -61,6 +109,16 @@ export const contextMixin = <T extends Constructor<HassBaseEl>>(
|
||||
context: areasContext,
|
||||
initialValue: this.hass ? this.hass.areas : this._pendingHass.areas,
|
||||
}),
|
||||
floors: new ContextProvider(this, {
|
||||
context: floorsContext,
|
||||
initialValue: this.hass ? this.hass.floors : this._pendingHass.floors,
|
||||
}),
|
||||
connection: new ContextProvider(this, {
|
||||
context: connectionSingleContext,
|
||||
initialValue: this.hass
|
||||
? this.hass.connection
|
||||
: this._pendingHass.connection,
|
||||
}),
|
||||
localize: new ContextProvider(this, {
|
||||
context: localizeContext,
|
||||
initialValue: this.hass
|
||||
@@ -72,7 +130,7 @@ export const contextMixin = <T extends Constructor<HassBaseEl>>(
|
||||
initialValue: this.hass ? this.hass.locale : this._pendingHass.locale,
|
||||
}),
|
||||
config: new ContextProvider(this, {
|
||||
context: configContext,
|
||||
context: configSingleContext,
|
||||
initialValue: this.hass ? this.hass.config : this._pendingHass.config,
|
||||
}),
|
||||
themes: new ContextProvider(this, {
|
||||
@@ -99,10 +157,6 @@ export const contextMixin = <T extends Constructor<HassBaseEl>>(
|
||||
context: panelsContext,
|
||||
initialValue: this.hass ? this.hass.panels : this._pendingHass.panels,
|
||||
}),
|
||||
floors: new ContextProvider(this, {
|
||||
context: floorsContext,
|
||||
initialValue: this.hass ? this.hass.floors : this._pendingHass.floors,
|
||||
}),
|
||||
auth: new ContextProvider(this, {
|
||||
context: authContext,
|
||||
initialValue: this.hass?.auth,
|
||||
@@ -151,6 +205,20 @@ export const contextMixin = <T extends Constructor<HassBaseEl>>(
|
||||
|
||||
protected _updateHass(obj: Partial<HomeAssistant>) {
|
||||
super._updateHass(obj);
|
||||
|
||||
for (const groupProvider of Object.keys(
|
||||
this.__hassContextProviderGroups
|
||||
)) {
|
||||
if (groupProvider in updateHassGroups) {
|
||||
this.__hassContextProviderGroups[groupProvider]!.setValue(
|
||||
updateHassGroups[groupProvider]!(
|
||||
this.hass!,
|
||||
this.__hassContextProviderGroups[groupProvider]!.value
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (key in this.__contextProviders) {
|
||||
this.__contextProviders[key]!.setValue(value);
|
||||
|
||||
@@ -3386,6 +3386,7 @@
|
||||
"upload_backup": "Upload backup"
|
||||
},
|
||||
"agent_error": "Error in location {name}",
|
||||
"create_backup_failed": "Failed to create backup",
|
||||
"new_backup": "Backup now",
|
||||
"onboarding": {
|
||||
"title": "Set up backups",
|
||||
|
||||
86
src/types.ts
86
src/types.ts
@@ -225,21 +225,14 @@ export interface ServiceCallRequest {
|
||||
target?: HassServiceTarget;
|
||||
}
|
||||
|
||||
export interface HomeAssistant {
|
||||
auth: Auth & { external?: ExternalMessaging };
|
||||
connection: Connection;
|
||||
connected: boolean;
|
||||
states: HassEntities;
|
||||
export interface HomeAssistantRegistries {
|
||||
entities: Record<string, EntityRegistryDisplayEntry>;
|
||||
devices: Record<string, DeviceRegistryEntry>;
|
||||
areas: Record<string, AreaRegistryEntry>;
|
||||
floors: Record<string, FloorRegistryEntry>;
|
||||
services: HassServices;
|
||||
config: HassConfig;
|
||||
themes: Themes;
|
||||
selectedTheme: ThemeSettings | null;
|
||||
panels: Panels;
|
||||
panelUrl: string;
|
||||
}
|
||||
|
||||
export interface HomeAssistantInternationalization {
|
||||
// i18n
|
||||
// current effective language in that order:
|
||||
// - backend saved user selected language
|
||||
@@ -250,20 +243,17 @@ export interface HomeAssistant {
|
||||
// local stored language, keep that name for backward compatibility
|
||||
selectedLanguage: string | null;
|
||||
locale: FrontendLocaleData;
|
||||
resources: Resources;
|
||||
localize: LocalizeFunc;
|
||||
translationMetadata: TranslationMetadata;
|
||||
suspendWhenHidden: boolean;
|
||||
enableShortcuts: boolean;
|
||||
vibrate: boolean;
|
||||
debugConnection: boolean;
|
||||
kioskMode: boolean;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
moreInfoEntityId: string | null;
|
||||
user?: CurrentUser;
|
||||
userData?: CoreFrontendUserData;
|
||||
systemData?: CoreFrontendSystemData;
|
||||
hassUrl(path?): string;
|
||||
loadBackendTranslation(
|
||||
category: Parameters<typeof getHassTranslations>[2],
|
||||
integrations?: Parameters<typeof getHassTranslations>[3],
|
||||
configFlow?: Parameters<typeof getHassTranslations>[4]
|
||||
): Promise<LocalizeFunc>;
|
||||
loadFragmentTranslation(fragment: string): Promise<LocalizeFunc | undefined>;
|
||||
}
|
||||
|
||||
export interface HomeAssistantApi {
|
||||
callService<T = any>(
|
||||
domain: ServiceCallRequest["domain"],
|
||||
service: ServiceCallRequest["service"],
|
||||
@@ -288,12 +278,9 @@ export interface HomeAssistant {
|
||||
fetchWithAuth(path: string, init?: Record<string, any>): Promise<Response>;
|
||||
sendWS(msg: MessageBase): void;
|
||||
callWS<T>(msg: MessageBase): Promise<T>;
|
||||
loadBackendTranslation(
|
||||
category: Parameters<typeof getHassTranslations>[2],
|
||||
integrations?: Parameters<typeof getHassTranslations>[3],
|
||||
configFlow?: Parameters<typeof getHassTranslations>[4]
|
||||
): Promise<LocalizeFunc>;
|
||||
loadFragmentTranslation(fragment: string): Promise<LocalizeFunc | undefined>;
|
||||
}
|
||||
|
||||
export interface HomeAssistantFormatters {
|
||||
formatEntityState(stateObj: HassEntity, state?: string): string;
|
||||
formatEntityStateToParts(stateObj: HassEntity, state?: string): ValuePart[];
|
||||
formatEntityAttributeValue(
|
||||
@@ -314,6 +301,47 @@ export interface HomeAssistant {
|
||||
): string;
|
||||
}
|
||||
|
||||
export interface HomeAssistantConnection {
|
||||
connection: Connection;
|
||||
connected: boolean;
|
||||
debugConnection: boolean;
|
||||
hassUrl(path?): string;
|
||||
}
|
||||
|
||||
export interface HomeAssistantUI {
|
||||
themes: Themes;
|
||||
selectedTheme: ThemeSettings | null;
|
||||
panels: Panels;
|
||||
panelUrl: string;
|
||||
dockedSidebar: "docked" | "always_hidden" | "auto";
|
||||
kioskMode: boolean;
|
||||
enableShortcuts: boolean;
|
||||
vibrate: boolean;
|
||||
suspendWhenHidden: boolean;
|
||||
}
|
||||
|
||||
export interface HomeAssistantConfig {
|
||||
auth: Auth & { external?: ExternalMessaging };
|
||||
config: HassConfig;
|
||||
user?: CurrentUser;
|
||||
userData?: CoreFrontendUserData;
|
||||
systemData?: CoreFrontendSystemData;
|
||||
}
|
||||
|
||||
export interface HomeAssistant
|
||||
extends
|
||||
HomeAssistantRegistries,
|
||||
HomeAssistantInternationalization,
|
||||
HomeAssistantApi,
|
||||
HomeAssistantFormatters,
|
||||
HomeAssistantConnection,
|
||||
HomeAssistantUI,
|
||||
HomeAssistantConfig {
|
||||
states: HassEntities;
|
||||
services: HassServices;
|
||||
resources: Resources;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
prefix: string;
|
||||
path: string;
|
||||
|
||||
331
yarn.lock
331
yarn.lock
@@ -3935,22 +3935,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sinonjs/fake-timers@npm:^15.1.1":
|
||||
version: 15.1.1
|
||||
resolution: "@sinonjs/fake-timers@npm:15.1.1"
|
||||
"@sinonjs/fake-timers@npm:^15.3.0":
|
||||
version: 15.3.0
|
||||
resolution: "@sinonjs/fake-timers@npm:15.3.0"
|
||||
dependencies:
|
||||
"@sinonjs/commons": "npm:^3.0.1"
|
||||
checksum: 10/f262d613ea7f7cdb1b5d90c0cae01b7c6b797d6d0f1ca0fe30b7b69012e3076bb8a0f69d735bc69d2824b9bb1efb8554ca9765b4a6bb22defdec9ce79e7cd8a4
|
||||
checksum: 10/657766c969f61af47d480e63112c126bb3088d3b0cfd6a609c90979971c5e98f388c189b7c46c05525edaa543f91d627d01b0007705eac679f7cdf4f66b1959e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sinonjs/samsam@npm:^9.0.3":
|
||||
version: 9.0.3
|
||||
resolution: "@sinonjs/samsam@npm:9.0.3"
|
||||
"@sinonjs/samsam@npm:^10.0.0":
|
||||
version: 10.0.1
|
||||
resolution: "@sinonjs/samsam@npm:10.0.1"
|
||||
dependencies:
|
||||
"@sinonjs/commons": "npm:^3.0.1"
|
||||
type-detect: "npm:^4.1.0"
|
||||
checksum: 10/bbb94c9d5e4a64dccf7de7679d17434aae1c16f209b25534a75eea2b0fb37b4d55829116c51fb24aa83f180a2c698fcdf9444747bd436726068cbc419c89aa2a
|
||||
checksum: 10/b5eac2408a30aba64d0d5bfbde0bc422354793e4ac19be46cb1b01f754f56e7dd69766739b62a849d93f03eeb14cc93f180e2a79a05f6ec05789e2b95bb89421
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -4688,105 +4688,105 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.58.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.58.1"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.12.2"
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.58.0"
|
||||
"@typescript-eslint/utils": "npm:8.58.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.1"
|
||||
"@typescript-eslint/type-utils": "npm:8.58.1"
|
||||
"@typescript-eslint/utils": "npm:8.58.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.1"
|
||||
ignore: "npm:^7.0.5"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
"@typescript-eslint/parser": ^8.58.0
|
||||
"@typescript-eslint/parser": ^8.58.1
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/0b1f4d4e62279fc5925c0a89d94816db0e236648eb4aec522cf22071877c6ecc63146b6830a1075049f402b842f45d7332ce6ae67883639754dcbb1881d07c34
|
||||
checksum: 10/0fcbe6faadb77313aa91c895c977a24fc72a79eed62f46f7b2d5804db52a9af99351b33b9c4d73fdabb0f69772d5d4a9acdef249a0d1526a44d3817fb51419b5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.58.0"
|
||||
"@typescript-eslint/parser@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/parser@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.0"
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.1"
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/0498e593b14841023b7495544637acaca84807de1ac17174fa9331af61ba35791da919e16680c6897002b4a843d5f0fe812c460a28a65fca7e3ae8e5971baf7a
|
||||
checksum: 10/062584d26609e82169459ebf0c59f4925ba6596f4ea1637a320c34a25c34117585c458b9c6c268f5eeaee1988f4c7257d34d4bd05a214a88de12110e71b48493
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/project-service@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/project-service@npm:8.58.0"
|
||||
"@typescript-eslint/project-service@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/project-service@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.58.0"
|
||||
"@typescript-eslint/types": "npm:^8.58.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.58.1"
|
||||
"@typescript-eslint/types": "npm:^8.58.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/fab2601f76b2df61b09e3b7ff364d0e17e6d80e65e84e8a8d11f6a0813748bed3912da098659d00f46b1f277d462bd7529157182b72b5e2e0b41ee6176a0edd7
|
||||
checksum: 10/2f3136268fc262e77e8c8c14291e60c54e0228b63ccb022826b6def6d80b83ce9c3a92fef11c888889fb204343c845556868c49495c3aa0a115e9a861dd5fe99
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.58.0"
|
||||
"@typescript-eslint/scope-manager@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.0"
|
||||
checksum: 10/97293f1215faa785a3c1ee8d630591db9dcd5fb6bdcdd0b2e818c80478d41e59a05003fb33000530780dc466fb8cf662352932080ee7406c4aaac72af4000541
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.1"
|
||||
checksum: 10/dc070fd73847807e32cb7dfc37512abd0b1a485b0037d8cfb6c593555a5b673d3ee9d19c61504ea71d067ad610c66f64d70d56f3a5db51895c0a25e45621cd08
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.58.0, @typescript-eslint/tsconfig-utils@npm:^8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.58.0"
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.58.1, @typescript-eslint/tsconfig-utils@npm:^8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.58.1"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/4f47212c0e26e6b06e97044ec5e483007d5145ef6b205393a0b43cbc0b385c75c14ba5749d01cf7d1ff100332c2cf1d336f060f7d2191bb67fb892bb4446afaa
|
||||
checksum: 10/4a5cf9a5eb834d05f2d37f7d80319575cf4a75aa52807b96edc0db24349ba417b41cb6f5257ffb07b8b9b4c59c7438637e8c75ed7c2b513bcb07e259b49e058e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.58.0"
|
||||
"@typescript-eslint/type-utils@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.0"
|
||||
"@typescript-eslint/utils": "npm:8.58.0"
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.1"
|
||||
"@typescript-eslint/utils": "npm:8.58.1"
|
||||
debug: "npm:^4.4.3"
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/da09868cd0b2cebb8cc4494e73aeed3997a7a4ff899fef496c54731610af1f92f8e3169f9b7f23060105db892f3bc880aacc0bdc7c1734ea5829252230c13aea
|
||||
checksum: 10/39d62d6711590e817cf9a36257c19ea18e201ceca42b900350e121ea8986c167fbdd9da385ced29c61e38a1b5c76b6c320d59e21d4dd7f32767520e31aef4654
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:8.58.0, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/types@npm:8.58.0"
|
||||
checksum: 10/c68eac0bc25812fdbb2ed4a121e42bfca9f24f3c6be95f6a9c4e7b9af767f1bcfacd6d496e358166143e0a1801dc7d042ce1b5e69946ac2768d9114ff6b8d375
|
||||
"@typescript-eslint/types@npm:8.58.1, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/types@npm:8.58.1"
|
||||
checksum: 10/447e1351af8a47297096f063b327c69b1c986af89e39cb39e142bb35d7bec2ce8f34f31edcf62d1beb2e09a38e2029b12b50b335dae4e7c9ff49bd82f9127523
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.58.0"
|
||||
"@typescript-eslint/typescript-estree@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/project-service": "npm:8.58.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.58.0"
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.0"
|
||||
"@typescript-eslint/project-service": "npm:8.58.1"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.58.1"
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.58.1"
|
||||
debug: "npm:^4.4.3"
|
||||
minimatch: "npm:^10.2.2"
|
||||
semver: "npm:^7.7.3"
|
||||
@@ -4794,32 +4794,32 @@ __metadata:
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/4d6c4175e8a4d5c097393d161016836cc322f090c3f69fd751f5bbc25afce64df9ea0c97cee8b36ac060e06dc2cca2a4de7a0c7e04e19727cc4bd98ab3291fed
|
||||
checksum: 10/107510b484148a8a9a5874f5451b9a6649609607ee5e67de36cded786157987a5262b145398b1bd1935afab66134532369a4d6abb53c6f5b7744e3ace0b13f07
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.58.0"
|
||||
"@typescript-eslint/utils@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/utils@npm:8.58.1"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.9.1"
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.0"
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.58.1"
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/936433b761a990147612d78bb4afc79244239541b4a4061fbbc2de1810b40ec7f78eb4e9181e5d9c5ab7acbd9bf49fc6195dbb1d823370f717f07ad492ad6c7e
|
||||
checksum: 10/c51a5e116d1a09d0eb701c5884d5b9b8c22f79c427cb4c46357e4bcb7dfdfd9beba92e5d518572f42111b7335541a4ccefe3c05595fc3d666c1b62ddd1522e54
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.58.0"
|
||||
"@typescript-eslint/visitor-keys@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.58.0"
|
||||
"@typescript-eslint/types": "npm:8.58.1"
|
||||
eslint-visitor-keys: "npm:^5.0.0"
|
||||
checksum: 10/50b0779e19079dedf3723323a4dfa398c639b3da48f2fcf071c22ca69342e03592f1726d68ea59b9b5a51f14ab112eabc5c93fd2579c84b02a3320042ae20066
|
||||
checksum: 10/e9f34741da6fc0cb8e9eb67828ea4427ac2004a33ce8d1e1e9ba038471f9ed68405eca871651bb2efa793a467bc5233a4310c5571ad1497cb2a84a600e1733a8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5066,12 +5066,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/coverage-v8@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/coverage-v8@npm:4.1.2"
|
||||
"@vitest/coverage-v8@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/coverage-v8@npm:4.1.4"
|
||||
dependencies:
|
||||
"@bcoe/v8-coverage": "npm:^1.0.2"
|
||||
"@vitest/utils": "npm:4.1.2"
|
||||
"@vitest/utils": "npm:4.1.4"
|
||||
ast-v8-to-istanbul: "npm:^1.0.0"
|
||||
istanbul-lib-coverage: "npm:^3.2.2"
|
||||
istanbul-lib-report: "npm:^3.0.1"
|
||||
@@ -5081,34 +5081,34 @@ __metadata:
|
||||
std-env: "npm:^4.0.0-rc.1"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
peerDependencies:
|
||||
"@vitest/browser": 4.1.2
|
||||
vitest: 4.1.2
|
||||
"@vitest/browser": 4.1.4
|
||||
vitest: 4.1.4
|
||||
peerDependenciesMeta:
|
||||
"@vitest/browser":
|
||||
optional: true
|
||||
checksum: 10/2a38252da937894dfd47a20839714cd49deb8ea0b8289fe25ba17b6677b99dc9b695e4c689b1d6532f19e0d1b81dbac2cf555f82a0ae75abf490dd4107407206
|
||||
checksum: 10/75c7bfa08d4a410dce09688a7bb1c06b782f90b785a51aea424806621dc90ce21663cf2e8f6f28e3c3c1be708932c5274408cd7cfda51e39dd3e0ae523cca133
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/expect@npm:4.1.2"
|
||||
"@vitest/expect@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/expect@npm:4.1.4"
|
||||
dependencies:
|
||||
"@standard-schema/spec": "npm:^1.1.0"
|
||||
"@types/chai": "npm:^5.2.2"
|
||||
"@vitest/spy": "npm:4.1.2"
|
||||
"@vitest/utils": "npm:4.1.2"
|
||||
"@vitest/spy": "npm:4.1.4"
|
||||
"@vitest/utils": "npm:4.1.4"
|
||||
chai: "npm:^6.2.2"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/536c5a8903927e324bbb66967be4e0ec2ec4ff6234f0b8fe20987841b0705c931c7e3ce2e61c7665f4ded65ba736de6cda8d2d37ee114efeedb187ca5d597ea1
|
||||
checksum: 10/3317bc42e4ee39cfa2102a9f08f0c7975817a74d9503a14e0b1715e5b8c4ab31c5646c07ef8d2d3f71bdf6f1b3053949b175df9c8457e0c0bb3f38b9e031f259
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/mocker@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/mocker@npm:4.1.2"
|
||||
"@vitest/mocker@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/mocker@npm:4.1.4"
|
||||
dependencies:
|
||||
"@vitest/spy": "npm:4.1.2"
|
||||
"@vitest/spy": "npm:4.1.4"
|
||||
estree-walker: "npm:^3.0.3"
|
||||
magic-string: "npm:^0.30.21"
|
||||
peerDependencies:
|
||||
@@ -5119,56 +5119,56 @@ __metadata:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
checksum: 10/1d7976e19ef168357aba2ca41cd8db86236a98dfb2209bd3152a3a20e9a5b8cbfd8f73356c43a934b384d3b4c7a63835fb1037d3f56a7824faa838331eaa214e
|
||||
checksum: 10/f07f8877635eb03f63981d0d3348bb82fabe7607bbb6b259045bf0b64fae79150b1f399aa7ce42926e4769dc8cde9b7d79d1f665eae2d17b22ecc9ec54663698
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/pretty-format@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/pretty-format@npm:4.1.2"
|
||||
"@vitest/pretty-format@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/pretty-format@npm:4.1.4"
|
||||
dependencies:
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/a07a6023c52b25be5c75fc05bb3317629390cc1b50eae6cbea91ba4c13193ec88e54abaa56b46b40ddb8a6a4558d667f2ba0e1cf2ee2d0e32b463244f3002aa7
|
||||
checksum: 10/e06d63ce4f797ad578ee19aeec996f72835a7274ee2eb75dce12d7b45debcda72d054f58b6f4e5dac4424681dc13dbad7ac023c6017fc60406cabea5a352e4c3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/runner@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/runner@npm:4.1.2"
|
||||
"@vitest/runner@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/runner@npm:4.1.4"
|
||||
dependencies:
|
||||
"@vitest/utils": "npm:4.1.2"
|
||||
"@vitest/utils": "npm:4.1.4"
|
||||
pathe: "npm:^2.0.3"
|
||||
checksum: 10/13fd019a63ee3225420474cbd1ca0ae7c5c2dcdd241f2a958ca45731c10de36131f15303ae8ab1196133ec4e955b7c6de658c7b5e19736d550f310c8195fa9b2
|
||||
checksum: 10/a852477adc6254e1d304bcba9b137f98f09a7001a557e8e4f4404518e3ade58a16ab459e83cf223e38cc37dc4b04d1248a14df56b056a0ae68fc54b19a1226fb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/snapshot@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/snapshot@npm:4.1.2"
|
||||
"@vitest/snapshot@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/snapshot@npm:4.1.4"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:4.1.2"
|
||||
"@vitest/utils": "npm:4.1.2"
|
||||
"@vitest/pretty-format": "npm:4.1.4"
|
||||
"@vitest/utils": "npm:4.1.4"
|
||||
magic-string: "npm:^0.30.21"
|
||||
pathe: "npm:^2.0.3"
|
||||
checksum: 10/9d124412dbe44db43ca5277180bf5fe5dad7373218a177830bba631b53d225f7d4de368a20d6f5740ec07402e9e4dd179609db2b2f691d2d8b02f1bdbfd8c1a3
|
||||
checksum: 10/e957cc95274a9663cd59e5b34c99b6e4e5cd989f04dadf9e3cec6c7bc64b4d167229644f31fd44c19c7acbbcb7cbbbb50e8084dbf1e0322ee411a697d80d490a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/spy@npm:4.1.2"
|
||||
checksum: 10/e20e417ac430fee34e4be58802b2eb31e1c1163296a8921c0878be14e1ae77c7a7cae1b9b515d56fe623e05ee21b092aff7eb5e0d412f656650b72ecd02bb30a
|
||||
"@vitest/spy@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/spy@npm:4.1.4"
|
||||
checksum: 10/516e465413fc6a22e0c7e99871f3b9703277c309e94e7247bbdb83a8e807e2da968cf7a30c61503afd6b565787e822786b8aad443210eba5488192a36730f3ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@vitest/utils@npm:4.1.2"
|
||||
"@vitest/utils@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "@vitest/utils@npm:4.1.4"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:4.1.2"
|
||||
"@vitest/pretty-format": "npm:4.1.4"
|
||||
convert-source-map: "npm:^2.0.0"
|
||||
tinyrainbow: "npm:^3.1.0"
|
||||
checksum: 10/854decf0eb639758d012c9aa53c3d7aed547e37c05ece6704d5f53035be77f704a24973ed95089926e1768c0b55902d42c4438660788e7a0f0e80d0fda1c713b
|
||||
checksum: 10/f599ae744f0ff45edda90d0c52eea9809b7367adca39fc985f85880322236d089dfdf6625f04913f03a25a160eccbbc0b16dd3201ccc0ae48087992b1ea755d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6990,10 +6990,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"diff@npm:^8.0.3":
|
||||
version: 8.0.3
|
||||
resolution: "diff@npm:8.0.3"
|
||||
checksum: 10/52f957e1fa53db4616ff5f4811b92b22b97a160c12a2f86f22debd4181227b0f6751aa8fd711d6a8fcf4618acb13b86bc702e6d9d6d6ed82acfd00c9cb26ace2
|
||||
"diff@npm:^8.0.4":
|
||||
version: 8.0.4
|
||||
resolution: "diff@npm:8.0.4"
|
||||
checksum: 10/b4036ceda0d1e10683a2313079ed52c5e6b09553ae29da87bce81d98714d9725dbf3c0f6f7c3b1f16eec049fe17087e38ee329e732580fa62f6ec1c2487b2435
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8936,7 +8936,7 @@ __metadata:
|
||||
"@types/tar": "npm:7.0.87"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@vibrant/color": "npm:4.0.4"
|
||||
"@vitest/coverage-v8": "npm:4.1.2"
|
||||
"@vitest/coverage-v8": "npm:4.1.4"
|
||||
"@webcomponents/scoped-custom-element-registry": "npm:0.0.10"
|
||||
"@webcomponents/webcomponentsjs": "npm:2.8.0"
|
||||
babel-loader: "npm:10.1.1"
|
||||
@@ -9002,7 +9002,7 @@ __metadata:
|
||||
node-vibrant: "npm:4.0.4"
|
||||
object-hash: "npm:3.0.0"
|
||||
pinst: "npm:3.0.0"
|
||||
prettier: "npm:3.8.1"
|
||||
prettier: "npm:3.8.2"
|
||||
punycode: "npm:2.3.1"
|
||||
qr-scanner: "npm:1.4.2"
|
||||
qrcode: "npm:1.5.4"
|
||||
@@ -9010,7 +9010,7 @@ __metadata:
|
||||
rrule: "npm:2.8.1"
|
||||
rspack-manifest-plugin: "npm:5.2.1"
|
||||
serve: "npm:14.2.6"
|
||||
sinon: "npm:21.0.3"
|
||||
sinon: "npm:21.1.0"
|
||||
sortablejs: "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch"
|
||||
stacktrace-js: "npm:2.0.2"
|
||||
superstruct: "npm:2.0.2"
|
||||
@@ -9019,9 +9019,9 @@ __metadata:
|
||||
tinykeys: "npm:3.0.0"
|
||||
ts-lit-plugin: "npm:2.0.2"
|
||||
typescript: "npm:6.0.2"
|
||||
typescript-eslint: "npm:8.58.0"
|
||||
typescript-eslint: "npm:8.58.1"
|
||||
vite-tsconfig-paths: "npm:6.1.1"
|
||||
vitest: "npm:4.1.2"
|
||||
vitest: "npm:4.1.4"
|
||||
webpack-stats-plugin: "npm:1.1.3"
|
||||
webpackbar: "npm:7.0.0"
|
||||
weekstart: "npm:2.0.0"
|
||||
@@ -11794,12 +11794,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:3.8.1":
|
||||
version: 3.8.1
|
||||
resolution: "prettier@npm:3.8.1"
|
||||
"prettier@npm:3.8.2":
|
||||
version: 3.8.2
|
||||
resolution: "prettier@npm:3.8.2"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10/3da1cf8c1ef9bea828aa618553696c312e951f810bee368f6887109b203f18ee869fe88f66e65f9cf60b7cb1f2eae859892c860a300c062ff8ec69c381fc8dbd
|
||||
checksum: 10/fd784175bc600c07eb2c44d7ec4ee7133f95f26492adad61b6a15c06f438b858181faf096ab74163d7f49500ad80cff4479c6abb084e161a2e85a9df5974ecd1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -12834,16 +12834,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sinon@npm:21.0.3":
|
||||
version: 21.0.3
|
||||
resolution: "sinon@npm:21.0.3"
|
||||
"sinon@npm:21.1.0":
|
||||
version: 21.1.0
|
||||
resolution: "sinon@npm:21.1.0"
|
||||
dependencies:
|
||||
"@sinonjs/commons": "npm:^3.0.1"
|
||||
"@sinonjs/fake-timers": "npm:^15.1.1"
|
||||
"@sinonjs/samsam": "npm:^9.0.3"
|
||||
diff: "npm:^8.0.3"
|
||||
supports-color: "npm:^7.2.0"
|
||||
checksum: 10/af1018ce4ae854ef30435fd6dd130c1fbb067561fba6fbc3930fd5da807267851f2a7e7abb2902b0882b878f50d281f2a88f88f559a49d7c4190712a2da536c5
|
||||
"@sinonjs/fake-timers": "npm:^15.3.0"
|
||||
"@sinonjs/samsam": "npm:^10.0.0"
|
||||
diff: "npm:^8.0.4"
|
||||
supports-color: "npm:^10.2.2"
|
||||
checksum: 10/cb9b174fbb0f5efb8004d93fc0e0a6152118cbbfe66ef45446ec40924483fa899e5b2196b3eed0da140549cc630ab29955d4935605fe1a79f150b8aa2c30723b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13396,6 +13396,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"supports-color@npm:^10.2.2":
|
||||
version: 10.2.2
|
||||
resolution: "supports-color@npm:10.2.2"
|
||||
checksum: 10/bd132705fc07213a4024131fb061f0a46a48b49ecaf434bb029c0a5aa0339b969236d496d63969e3c248a90fdcac16d4f9c5bf187e7be0bfb5e804ed13bef6b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"supports-color@npm:^5.3.0":
|
||||
version: 5.5.0
|
||||
resolution: "supports-color@npm:5.5.0"
|
||||
@@ -13405,7 +13412,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"supports-color@npm:^7.1.0, supports-color@npm:^7.2.0":
|
||||
"supports-color@npm:^7.1.0":
|
||||
version: 7.2.0
|
||||
resolution: "supports-color@npm:7.2.0"
|
||||
dependencies:
|
||||
@@ -13936,18 +13943,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript-eslint@npm:8.58.0":
|
||||
version: 8.58.0
|
||||
resolution: "typescript-eslint@npm:8.58.0"
|
||||
"typescript-eslint@npm:8.58.1":
|
||||
version: 8.58.1
|
||||
resolution: "typescript-eslint@npm:8.58.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.58.0"
|
||||
"@typescript-eslint/parser": "npm:8.58.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.0"
|
||||
"@typescript-eslint/utils": "npm:8.58.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.58.1"
|
||||
"@typescript-eslint/parser": "npm:8.58.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.58.1"
|
||||
"@typescript-eslint/utils": "npm:8.58.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/e30c9a094c9cf49265db626c0570a1af21b117fe9ce695cd7f0e7962bd8ac1a4e5b5fb1a1e0cb5413f237cd32804be56b11fb72ee2cfede775768c28617b1a0b
|
||||
checksum: 10/b65fba0a594870fe5c456e6650a9050adf83b72c3d57983e3924778e217399e057c4c185abbe21396f288113d85c475377ee0d7ed6ac24538ef4ea0a7332c0df
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14445,17 +14452,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vitest@npm:4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "vitest@npm:4.1.2"
|
||||
"vitest@npm:4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "vitest@npm:4.1.4"
|
||||
dependencies:
|
||||
"@vitest/expect": "npm:4.1.2"
|
||||
"@vitest/mocker": "npm:4.1.2"
|
||||
"@vitest/pretty-format": "npm:4.1.2"
|
||||
"@vitest/runner": "npm:4.1.2"
|
||||
"@vitest/snapshot": "npm:4.1.2"
|
||||
"@vitest/spy": "npm:4.1.2"
|
||||
"@vitest/utils": "npm:4.1.2"
|
||||
"@vitest/expect": "npm:4.1.4"
|
||||
"@vitest/mocker": "npm:4.1.4"
|
||||
"@vitest/pretty-format": "npm:4.1.4"
|
||||
"@vitest/runner": "npm:4.1.4"
|
||||
"@vitest/snapshot": "npm:4.1.4"
|
||||
"@vitest/spy": "npm:4.1.4"
|
||||
"@vitest/utils": "npm:4.1.4"
|
||||
es-module-lexer: "npm:^2.0.0"
|
||||
expect-type: "npm:^1.3.0"
|
||||
magic-string: "npm:^0.30.21"
|
||||
@@ -14473,10 +14480,12 @@ __metadata:
|
||||
"@edge-runtime/vm": "*"
|
||||
"@opentelemetry/api": ^1.9.0
|
||||
"@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0
|
||||
"@vitest/browser-playwright": 4.1.2
|
||||
"@vitest/browser-preview": 4.1.2
|
||||
"@vitest/browser-webdriverio": 4.1.2
|
||||
"@vitest/ui": 4.1.2
|
||||
"@vitest/browser-playwright": 4.1.4
|
||||
"@vitest/browser-preview": 4.1.4
|
||||
"@vitest/browser-webdriverio": 4.1.4
|
||||
"@vitest/coverage-istanbul": 4.1.4
|
||||
"@vitest/coverage-v8": 4.1.4
|
||||
"@vitest/ui": 4.1.4
|
||||
happy-dom: "*"
|
||||
jsdom: "*"
|
||||
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
@@ -14493,6 +14502,10 @@ __metadata:
|
||||
optional: true
|
||||
"@vitest/browser-webdriverio":
|
||||
optional: true
|
||||
"@vitest/coverage-istanbul":
|
||||
optional: true
|
||||
"@vitest/coverage-v8":
|
||||
optional: true
|
||||
"@vitest/ui":
|
||||
optional: true
|
||||
happy-dom:
|
||||
@@ -14503,7 +14516,7 @@ __metadata:
|
||||
optional: false
|
||||
bin:
|
||||
vitest: vitest.mjs
|
||||
checksum: 10/6b037387e59d403f6570f887f6ac96b81ff6e768dbd02d32a812ddff5bdebef022dd6d9f20b84fb9535866e0c5dbdf80e6705cc428b6a8f8a8e67e1335235848
|
||||
checksum: 10/c5608c506ae9ab3d0baa7445290c240941ad54a93eb853a005b2fe518efb1b28282945e0565ca16a624cca5b23af0c33ee34fbc2c38e6664ea54b08b9a22a653
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user