mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-30 21:27:21 +00:00
Compare commits
23 Commits
dev
...
20251127.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38b7bd18bb | ||
|
|
a00e944a35 | ||
|
|
481569804e | ||
|
|
a1d7e270ff | ||
|
|
225ccf1d2f | ||
|
|
4a5e1f9f3f | ||
|
|
b27b7210fd | ||
|
|
acd5181449 | ||
|
|
b6b2d03a80 | ||
|
|
7aee2b7cb7 | ||
|
|
df1914cb7a | ||
|
|
6706d5904d | ||
|
|
221aefd764 | ||
|
|
670057e8e6 | ||
|
|
427e46201c | ||
|
|
fd1240f335 | ||
|
|
aa7670cb59 | ||
|
|
468139229c | ||
|
|
39752f0e3f | ||
|
|
4d850d067f | ||
|
|
bcae64df88 | ||
|
|
690fd5a061 | ||
|
|
ac56c6df9a |
@@ -305,8 +305,9 @@ export class HcMain extends HassElement {
|
||||
await llColl.refresh();
|
||||
this._unsubLovelace = llColl.subscribe(async (rawConfig) => {
|
||||
if (isStrategyDashboard(rawConfig)) {
|
||||
const { generateLovelaceDashboardStrategy } =
|
||||
await import("../../../../src/panels/lovelace/strategies/get-strategy");
|
||||
const { generateLovelaceDashboardStrategy } = await import(
|
||||
"../../../../src/panels/lovelace/strategies/get-strategy"
|
||||
);
|
||||
const config = await generateLovelaceDashboardStrategy(
|
||||
rawConfig,
|
||||
this.hass!
|
||||
@@ -346,8 +347,9 @@ export class HcMain extends HassElement {
|
||||
}
|
||||
|
||||
private async _generateDefaultLovelaceConfig() {
|
||||
const { generateLovelaceDashboardStrategy } =
|
||||
await import("../../../../src/panels/lovelace/strategies/get-strategy");
|
||||
const { generateLovelaceDashboardStrategy } = await import(
|
||||
"../../../../src/panels/lovelace/strategies/get-strategy"
|
||||
);
|
||||
this._handleNewLovelaceConfig(
|
||||
await generateLovelaceDashboardStrategy(DEFAULT_CONFIG, this.hass!)
|
||||
);
|
||||
|
||||
18
package.json
18
package.json
@@ -89,8 +89,8 @@
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@tsparticles/engine": "3.9.1",
|
||||
"@tsparticles/preset-links": "3.2.0",
|
||||
"@vaadin/combo-box": "24.9.6",
|
||||
"@vaadin/vaadin-themable-mixin": "24.9.6",
|
||||
"@vaadin/combo-box": "24.9.5",
|
||||
"@vaadin/vaadin-themable-mixin": "24.9.5",
|
||||
"@vibrant/color": "4.0.0",
|
||||
"@vue/web-component-wrapper": "1.3.0",
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||
@@ -152,13 +152,13 @@
|
||||
"@babel/helper-define-polyfill-provider": "0.6.5",
|
||||
"@babel/plugin-transform-runtime": "7.28.5",
|
||||
"@babel/preset-env": "7.28.5",
|
||||
"@bundle-stats/plugin-webpack-filter": "4.21.7",
|
||||
"@bundle-stats/plugin-webpack-filter": "4.21.6",
|
||||
"@lokalise/node-api": "15.4.0",
|
||||
"@octokit/auth-oauth-device": "8.0.3",
|
||||
"@octokit/plugin-retry": "8.0.3",
|
||||
"@octokit/rest": "22.0.1",
|
||||
"@rsdoctor/rspack-plugin": "1.3.11",
|
||||
"@rspack/core": "1.6.5",
|
||||
"@rspack/core": "1.6.4",
|
||||
"@rspack/dev-server": "1.1.4",
|
||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||
"@types/chromecast-caf-receiver": "6.0.22",
|
||||
@@ -178,7 +178,7 @@
|
||||
"@types/tar": "6.1.13",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@vitest/coverage-v8": "4.0.14",
|
||||
"@vitest/coverage-v8": "4.0.13",
|
||||
"babel-loader": "10.0.0",
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"browserslist-useragent-regexp": "4.1.3",
|
||||
@@ -194,7 +194,7 @@
|
||||
"eslint-plugin-wc": "3.0.2",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.2",
|
||||
"glob": "13.0.0",
|
||||
"glob": "12.0.0",
|
||||
"gulp": "5.0.1",
|
||||
"gulp-brotli": "3.0.0",
|
||||
"gulp-json-transform": "0.5.0",
|
||||
@@ -209,7 +209,7 @@
|
||||
"lodash.template": "4.5.0",
|
||||
"map-stream": "0.0.7",
|
||||
"pinst": "3.0.0",
|
||||
"prettier": "3.7.1",
|
||||
"prettier": "3.6.2",
|
||||
"rspack-manifest-plugin": "5.2.0",
|
||||
"serve": "14.2.5",
|
||||
"sinon": "21.0.0",
|
||||
@@ -217,9 +217,9 @@
|
||||
"terser-webpack-plugin": "5.3.14",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.48.0",
|
||||
"typescript-eslint": "8.47.0",
|
||||
"vite-tsconfig-paths": "5.1.4",
|
||||
"vitest": "4.0.14",
|
||||
"vitest": "4.0.13",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20251029.0"
|
||||
version = "20251127.0"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*"]
|
||||
description = "The Home Assistant frontend"
|
||||
|
||||
@@ -45,8 +45,9 @@ export const computeFormatFunctions = async (
|
||||
formatEntityAttributeName: FormatEntityAttributeNameFunc;
|
||||
formatEntityName: FormatEntityNameFunc;
|
||||
}> => {
|
||||
const { computeStateDisplay } =
|
||||
await import("../entity/compute_state_display");
|
||||
const { computeStateDisplay } = await import(
|
||||
"../entity/compute_state_display"
|
||||
);
|
||||
const { computeAttributeValueDisplay, computeAttributeNameDisplay } =
|
||||
await import("../entity/compute_attribute_display");
|
||||
|
||||
|
||||
@@ -838,10 +838,10 @@ export class HaDataTable extends LitElement {
|
||||
} else if (this.sortDirection === "asc") {
|
||||
this.sortDirection = "desc";
|
||||
} else {
|
||||
this.sortDirection = "asc";
|
||||
this.sortDirection = null;
|
||||
}
|
||||
|
||||
this.sortColumn = columnId;
|
||||
this.sortColumn = this.sortDirection === null ? undefined : columnId;
|
||||
|
||||
fireEvent(this, "sorting-changed", {
|
||||
column: columnId,
|
||||
|
||||
@@ -186,6 +186,7 @@ export class HaIcon extends LitElement {
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
fill: currentcolor;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -73,8 +73,6 @@ export class HaLanguagePicker extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public required = false;
|
||||
|
||||
@property() public helper?: string;
|
||||
|
||||
@property({ attribute: "native-name", type: Boolean })
|
||||
public nativeName = false;
|
||||
|
||||
@@ -137,7 +135,6 @@ export class HaLanguagePicker extends LitElement {
|
||||
.value=${value}
|
||||
.valueRenderer=${this._valueRenderer}
|
||||
.disabled=${this.disabled}
|
||||
.helper=${this.helper}
|
||||
.getItems=${this._getItems}
|
||||
@value-changed=${this._changed}
|
||||
hide-clear-icon
|
||||
|
||||
@@ -71,7 +71,7 @@ class HaMarkdownElement extends ReactiveElement {
|
||||
if (!this.innerHTML && this.cache) {
|
||||
const key = this._computeCacheKey();
|
||||
if (markdownCache.has(key)) {
|
||||
render(h(unsafeHTML(markdownCache.get(key))), this.renderRoot);
|
||||
render(markdownCache.get(key)!, this.renderRoot);
|
||||
this._resize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ export class HaMarkdown extends LitElement {
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
padding-inline-start: 1rem;
|
||||
list-style-position: inside;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
li {
|
||||
&:has(input[type="checkbox"]) {
|
||||
@@ -139,19 +140,16 @@ export class HaMarkdown extends LitElement {
|
||||
margin: var(--ha-space-4) 0;
|
||||
}
|
||||
table {
|
||||
border-collapse: var(--markdown-table-border-collapse, collapse);
|
||||
}
|
||||
div:has(> table) {
|
||||
overflow: auto;
|
||||
border-collapse: collapse;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
}
|
||||
th {
|
||||
text-align: start;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
border-width: var(--markdown-table-border-width, 1px);
|
||||
border-style: var(--markdown-table-border-style, solid);
|
||||
border-color: var(--markdown-table-border-color, var(--divider-color));
|
||||
border: 1px solid var(--markdown-table-border-color, transparent);
|
||||
padding: 0.25em 0.5em;
|
||||
}
|
||||
blockquote {
|
||||
|
||||
@@ -103,8 +103,8 @@ export class HaPickerField extends LitElement {
|
||||
--md-list-item-two-line-container-height: 56px;
|
||||
--md-list-item-top-space: 0px;
|
||||
--md-list-item-bottom-space: 0px;
|
||||
--md-list-item-leading-space: var(--ha-space-4);
|
||||
--md-list-item-trailing-space: var(--ha-space-2);
|
||||
--md-list-item-leading-space: 8px;
|
||||
--md-list-item-trailing-space: 8px;
|
||||
--ha-md-list-item-gap: var(--ha-space-2);
|
||||
/* Remove the default focus ring */
|
||||
--md-focus-ring-width: 0px;
|
||||
|
||||
@@ -53,7 +53,6 @@ export type DialogWidth = "small" | "medium" | "large" | "full";
|
||||
* @cssprop --dialog-surface-margin-top - Top margin for the dialog surface.
|
||||
*
|
||||
* @attr {boolean} open - Controls the dialog open state.
|
||||
* @attr {("alert"|"standard")} type - Dialog type. Defaults to "standard".
|
||||
* @attr {("small"|"medium"|"large"|"full")} width - Preferred dialog width preset. Defaults to "medium".
|
||||
* @attr {boolean} prevent-scrim-close - Prevents closing the dialog by clicking the scrim/overlay. Defaults to false.
|
||||
* @attr {string} header-title - Header title text. If not set, the headerTitle slot is used.
|
||||
@@ -85,9 +84,6 @@ export class HaWaDialog extends LitElement {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
public open = false;
|
||||
|
||||
@property({ reflect: true })
|
||||
public type: "alert" | "standard" = "standard";
|
||||
|
||||
@property({ type: String, reflect: true, attribute: "width" })
|
||||
public width: DialogWidth = "medium";
|
||||
|
||||
@@ -204,7 +200,18 @@ export class HaWaDialog extends LitElement {
|
||||
haStyleScrollbar,
|
||||
css`
|
||||
wa-dialog {
|
||||
--full-width: var(--ha-dialog-width-full, min(95vw, var(--safe-width)));
|
||||
--full-width: var(
|
||||
--ha-dialog-width-full,
|
||||
min(
|
||||
95vw,
|
||||
calc(
|
||||
100vw - var(--safe-area-inset-left, var(--ha-space-0)) - var(
|
||||
--safe-area-inset-right,
|
||||
var(--ha-space-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
--width: min(var(--ha-dialog-width-md, 580px), var(--full-width));
|
||||
--spacing: var(--dialog-content-padding, var(--ha-space-6));
|
||||
--show-duration: var(--ha-dialog-show-duration, 200ms);
|
||||
@@ -221,7 +228,8 @@ export class HaWaDialog extends LitElement {
|
||||
--ha-dialog-border-radius,
|
||||
var(--ha-border-radius-3xl)
|
||||
);
|
||||
max-width: var(--ha-dialog-max-width, var(--safe-width));
|
||||
max-width: var(--ha-dialog-max-width, 100vw);
|
||||
max-width: var(--ha-dialog-max-width, 100svw);
|
||||
}
|
||||
|
||||
:host([width="small"]) wa-dialog {
|
||||
@@ -241,57 +249,34 @@ export class HaWaDialog extends LitElement {
|
||||
max-width: var(--width, var(--full-width));
|
||||
max-height: var(
|
||||
--ha-dialog-max-height,
|
||||
calc(var(--safe-height) - var(--ha-space-20))
|
||||
calc(100% - var(--ha-space-20))
|
||||
);
|
||||
min-height: var(--ha-dialog-min-height);
|
||||
position: var(--dialog-surface-position, relative);
|
||||
margin-top: var(--dialog-surface-margin-top, auto);
|
||||
/* Used to offset the dialog from the safe areas when space is limited */
|
||||
transform: translate(
|
||||
calc(
|
||||
var(--safe-area-offset-left, var(--ha-space-0)) - var(
|
||||
--safe-area-offset-right,
|
||||
var(--ha-space-0)
|
||||
)
|
||||
),
|
||||
calc(
|
||||
var(--safe-area-offset-top, var(--ha-space-0)) - var(
|
||||
--safe-area-offset-bottom,
|
||||
var(--ha-space-0)
|
||||
)
|
||||
)
|
||||
);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
:host([type="standard"]) {
|
||||
:host {
|
||||
--ha-dialog-border-radius: var(--ha-space-0);
|
||||
}
|
||||
|
||||
wa-dialog {
|
||||
/* Make the container fill the whole screen width and not the safe width */
|
||||
--full-width: var(--ha-dialog-width-full, 100vw);
|
||||
--width: var(--full-width);
|
||||
}
|
||||
|
||||
wa-dialog::part(dialog) {
|
||||
/* Make the dialog fill the whole screen height and not the safe height */
|
||||
min-height: var(--ha-dialog-min-height, 100vh);
|
||||
min-height: var(--ha-dialog-min-height, 100dvh);
|
||||
min-height: var(--ha-dialog-min-height, 100svh);
|
||||
max-height: var(--ha-dialog-max-height, 100vh);
|
||||
max-height: var(--ha-dialog-max-height, 100dvh);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
/* Use safe area as padding instead of the container size */
|
||||
padding-top: var(--safe-area-inset-top);
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-left: var(--safe-area-inset-left);
|
||||
padding-right: var(--safe-area-inset-right);
|
||||
/* Reset the transform to center the dialog */
|
||||
transform: none;
|
||||
}
|
||||
max-height: var(--ha-dialog-max-height, 100svh);
|
||||
padding-top: var(--safe-area-inset-top, var(--ha-space-0));
|
||||
padding-bottom: var(--safe-area-inset-bottom, var(--ha-space-0));
|
||||
padding-left: var(--safe-area-inset-left, var(--ha-space-0));
|
||||
padding-right: var(--safe-area-inset-right, var(--ha-space-0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ export interface HassioFullBackupCreateParams {
|
||||
confirm_password?: string;
|
||||
background?: boolean;
|
||||
}
|
||||
export interface HassioPartialBackupCreateParams extends HassioFullBackupCreateParams {
|
||||
export interface HassioPartialBackupCreateParams
|
||||
extends HassioFullBackupCreateParams {
|
||||
folders?: string[];
|
||||
addons?: string[];
|
||||
homeassistant?: boolean;
|
||||
|
||||
@@ -18,7 +18,8 @@ export const enum LawnMowerEntityFeature {
|
||||
}
|
||||
|
||||
interface LawnMowerEntityAttributes
|
||||
extends HassEntityAttributeBase, Record<string, any> {}
|
||||
extends HassEntityAttributeBase,
|
||||
Record<string, any> {}
|
||||
|
||||
export interface LawnMowerEntity extends HassEntityBase {
|
||||
attributes: LawnMowerEntityAttributes;
|
||||
|
||||
@@ -18,7 +18,8 @@ export interface LovelaceSectionConfig extends LovelaceBaseSectionConfig {
|
||||
cards?: LovelaceCardConfig[];
|
||||
}
|
||||
|
||||
export interface LovelaceStrategySectionConfig extends LovelaceBaseSectionConfig {
|
||||
export interface LovelaceStrategySectionConfig
|
||||
extends LovelaceBaseSectionConfig {
|
||||
strategy: LovelaceStrategyConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ export interface LovelaceConfig extends LovelaceDashboardBaseConfig {
|
||||
views: LovelaceViewRawConfig[];
|
||||
}
|
||||
|
||||
export interface LovelaceDashboardStrategyConfig extends LovelaceDashboardBaseConfig {
|
||||
export interface LovelaceDashboardStrategyConfig
|
||||
extends LovelaceDashboardBaseConfig {
|
||||
strategy: LovelaceStrategyConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ export interface LovelaceDashboardMutableParams {
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface LovelaceDashboardCreateParams extends LovelaceDashboardMutableParams {
|
||||
export interface LovelaceDashboardCreateParams
|
||||
extends LovelaceDashboardMutableParams {
|
||||
url_path: string;
|
||||
mode: "storage";
|
||||
}
|
||||
|
||||
@@ -106,7 +106,8 @@ export interface AutomationTrace extends BaseTrace {
|
||||
}
|
||||
|
||||
export interface AutomationTraceExtended
|
||||
extends AutomationTrace, BaseTraceExtended {
|
||||
extends AutomationTrace,
|
||||
BaseTraceExtended {
|
||||
config: ManualAutomationConfig;
|
||||
blueprint_inputs?: BlueprintAutomationConfig;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { mdiAlertOutline, mdiClose } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../components/ha-button";
|
||||
@@ -65,7 +64,6 @@ class DialogBox extends LitElement {
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
type=${confirmPrompt ? "alert" : "standard"}
|
||||
?prevent-scrim-close=${confirmPrompt}
|
||||
@closed=${this._dialogClosed}
|
||||
aria-labelledby="dialog-box-title"
|
||||
@@ -81,11 +79,7 @@ class DialogBox extends LitElement {
|
||||
></ha-icon-button
|
||||
></slot>`
|
||||
: nothing}
|
||||
<span
|
||||
class=${classMap({ title: true, alert: confirmPrompt })}
|
||||
slot="title"
|
||||
id="dialog-box-title"
|
||||
>
|
||||
<span slot="title" id="dialog-box-title">
|
||||
${this._params.warning
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAlertOutline}
|
||||
@@ -205,14 +199,6 @@ class DialogBox extends LitElement {
|
||||
ha-textfield {
|
||||
width: 100%;
|
||||
}
|
||||
.title.alert {
|
||||
padding: 0 var(--ha-space-2);
|
||||
}
|
||||
@media all and (min-width: 450px) and (min-height: 500px) {
|
||||
.title.alert {
|
||||
padding: 0 var(--ha-space-1);
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ export interface PromptDialogParams extends BaseDialogBoxParams {
|
||||
}
|
||||
|
||||
export interface DialogBoxParams
|
||||
extends ConfirmationDialogParams, PromptDialogParams {
|
||||
extends ConfirmationDialogParams,
|
||||
PromptDialogParams {
|
||||
confirm?: (out?: string) => void;
|
||||
confirmation?: boolean;
|
||||
prompt?: boolean;
|
||||
|
||||
@@ -19,9 +19,8 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export interface HassDialog<
|
||||
T = HASSDomEvents[ValidHassDomEvent],
|
||||
> extends HTMLElement {
|
||||
export interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]>
|
||||
extends HTMLElement {
|
||||
showDialog(params: T);
|
||||
closeDialog?: () => boolean;
|
||||
}
|
||||
|
||||
@@ -621,9 +621,9 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
|
||||
} else if (this._sortDirection === "asc") {
|
||||
this._sortDirection = "desc";
|
||||
} else {
|
||||
this._sortDirection = "asc";
|
||||
this._sortDirection = null;
|
||||
}
|
||||
this._sortColumn = columnId;
|
||||
this._sortColumn = this._sortDirection === null ? undefined : columnId;
|
||||
|
||||
fireEvent(this, "sorting-changed", {
|
||||
column: columnId,
|
||||
|
||||
@@ -90,7 +90,9 @@ class OnboardingRestoreBackupCloudLogin extends LitElement {
|
||||
this._email = this._cloudLoginElement.emailField.value;
|
||||
}
|
||||
|
||||
await import("../../panels/config/cloud/forgot-password/cloud-forgot-password-card");
|
||||
await import(
|
||||
"../../panels/config/cloud/forgot-password/cloud-forgot-password-card"
|
||||
);
|
||||
this._view = "forgot-password";
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { slugify } from "../../../common/string/slugify";
|
||||
import "../../../components/ha-tooltip";
|
||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import {
|
||||
hasRejectedItems,
|
||||
@@ -329,19 +327,14 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
||||
const date = new Date(automation.last_triggered);
|
||||
const now = new Date();
|
||||
const dayDifference = differenceInDays(now, date);
|
||||
const formattedTime = formatShortDateTimeWithConditionalYear(
|
||||
return html`
|
||||
${dayDifference > 3
|
||||
? formatShortDateTimeWithConditionalYear(
|
||||
date,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
);
|
||||
const elementId = "last-triggered-" + slugify(automation.entity_id);
|
||||
return html`
|
||||
${dayDifference > 3
|
||||
? formattedTime
|
||||
: html`
|
||||
<ha-tooltip for=${elementId}>${formattedTime}</ha-tooltip>
|
||||
<span id=${elementId}>${relativeTime(date, locale)}</span>
|
||||
`}
|
||||
)
|
||||
: relativeTime(date, locale)}
|
||||
`;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1138,20 +1138,23 @@ export class HaConfigDevicePage extends LitElement {
|
||||
}
|
||||
|
||||
if (domains.includes("mqtt")) {
|
||||
const mqtt =
|
||||
await import("./device-detail/integration-elements/mqtt/device-actions");
|
||||
const mqtt = await import(
|
||||
"./device-detail/integration-elements/mqtt/device-actions"
|
||||
);
|
||||
const actions = mqtt.getMQTTDeviceActions(this, device);
|
||||
deviceActions.push(...actions);
|
||||
}
|
||||
if (domains.includes("zha")) {
|
||||
const zha =
|
||||
await import("./device-detail/integration-elements/zha/device-actions");
|
||||
const zha = await import(
|
||||
"./device-detail/integration-elements/zha/device-actions"
|
||||
);
|
||||
const actions = await zha.getZHADeviceActions(this, this.hass, device);
|
||||
deviceActions.push(...actions);
|
||||
}
|
||||
if (domains.includes("zwave_js")) {
|
||||
const zwave =
|
||||
await import("./device-detail/integration-elements/zwave_js/device-actions");
|
||||
const zwave = await import(
|
||||
"./device-detail/integration-elements/zwave_js/device-actions"
|
||||
);
|
||||
const actions = await zwave.getZwaveDeviceActions(
|
||||
this,
|
||||
this.hass,
|
||||
@@ -1160,8 +1163,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
deviceActions.push(...actions);
|
||||
}
|
||||
if (domains.includes("esphome")) {
|
||||
const esphome =
|
||||
await import("./device-detail/integration-elements/esphome/device-actions");
|
||||
const esphome = await import(
|
||||
"./device-detail/integration-elements/esphome/device-actions"
|
||||
);
|
||||
const actions = await esphome.getESPHomeDeviceActions(
|
||||
this,
|
||||
this.hass,
|
||||
@@ -1170,8 +1174,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
deviceActions.push(...actions);
|
||||
}
|
||||
if (domains.includes("matter")) {
|
||||
const matter =
|
||||
await import("./device-detail/integration-elements/matter/device-actions");
|
||||
const matter = await import(
|
||||
"./device-detail/integration-elements/matter/device-actions"
|
||||
);
|
||||
const defaultActions = matter.getMatterDeviceDefaultActions(
|
||||
this,
|
||||
this.hass,
|
||||
@@ -1215,8 +1220,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
).map((int) => int.domain);
|
||||
|
||||
if (domains.includes("zwave_js")) {
|
||||
const zwave =
|
||||
await import("./device-detail/integration-elements/zwave_js/device-alerts");
|
||||
const zwave = await import(
|
||||
"./device-detail/integration-elements/zwave_js/device-alerts"
|
||||
);
|
||||
|
||||
const alerts = await zwave.getZwaveDeviceAlerts(this.hass, device);
|
||||
deviceAlerts.push(...alerts);
|
||||
@@ -1298,7 +1304,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
`);
|
||||
}
|
||||
if (domains.includes("zwave_js")) {
|
||||
import("./device-detail/integration-elements/zwave_js/ha-device-info-zwave_js");
|
||||
import(
|
||||
"./device-detail/integration-elements/zwave_js/ha-device-info-zwave_js"
|
||||
);
|
||||
deviceInfo.push(html`
|
||||
<ha-device-info-zwave_js
|
||||
.hass=${this.hass}
|
||||
@@ -1307,7 +1315,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
`);
|
||||
}
|
||||
if (domains.includes("matter")) {
|
||||
import("./device-detail/integration-elements/matter/ha-device-info-matter");
|
||||
import(
|
||||
"./device-detail/integration-elements/matter/ha-device-info-matter"
|
||||
);
|
||||
deviceInfo.push(html`
|
||||
<ha-device-info-matter
|
||||
.hass=${this.hass}
|
||||
|
||||
@@ -116,10 +116,8 @@ import { showAddIntegrationDialog } from "../integrations/show-add-integration-d
|
||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||
import { slugify } from "../../../common/string/slugify";
|
||||
|
||||
export interface StateEntity extends Omit<
|
||||
EntityRegistryEntry,
|
||||
"id" | "unique_id"
|
||||
> {
|
||||
export interface StateEntity
|
||||
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
||||
readonly?: boolean;
|
||||
selectable?: boolean;
|
||||
id?: string;
|
||||
|
||||
@@ -530,7 +530,9 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
||||
zha: {
|
||||
tag: "zha-config-dashboard-router",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/zha/zha-config-dashboard-router"),
|
||||
import(
|
||||
"./integrations/integration-panels/zha/zha-config-dashboard-router"
|
||||
),
|
||||
},
|
||||
mqtt: {
|
||||
tag: "mqtt-config-panel",
|
||||
@@ -540,22 +542,30 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
||||
zwave_js: {
|
||||
tag: "zwave_js-config-router",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/zwave_js/zwave_js-config-router"),
|
||||
import(
|
||||
"./integrations/integration-panels/zwave_js/zwave_js-config-router"
|
||||
),
|
||||
},
|
||||
matter: {
|
||||
tag: "matter-config-panel",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/matter/matter-config-panel"),
|
||||
import(
|
||||
"./integrations/integration-panels/matter/matter-config-panel"
|
||||
),
|
||||
},
|
||||
thread: {
|
||||
tag: "thread-config-panel",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/thread/thread-config-panel"),
|
||||
import(
|
||||
"./integrations/integration-panels/thread/thread-config-panel"
|
||||
),
|
||||
},
|
||||
bluetooth: {
|
||||
tag: "bluetooth-config-dashboard-router",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/bluetooth/bluetooth-config-dashboard-router"),
|
||||
import(
|
||||
"./integrations/integration-panels/bluetooth/bluetooth-config-dashboard-router"
|
||||
),
|
||||
},
|
||||
dhcp: {
|
||||
tag: "dhcp-config-panel",
|
||||
@@ -570,7 +580,9 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
||||
zeroconf: {
|
||||
tag: "zeroconf-config-panel",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/zeroconf/zeroconf-config-panel"),
|
||||
import(
|
||||
"./integrations/integration-panels/zeroconf/zeroconf-config-panel"
|
||||
),
|
||||
},
|
||||
application_credentials: {
|
||||
tag: "ha-config-application-credentials",
|
||||
|
||||
@@ -24,7 +24,7 @@ import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeCssColor } from "../../../common/color/compute-color";
|
||||
import { formatShortDateTimeWithConditionalYear } from "../../../common/datetime/format_date_time";
|
||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
@@ -301,21 +301,10 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
||||
const date = new Date(scene.state);
|
||||
const now = new Date();
|
||||
const dayDifference = differenceInDays(now, date);
|
||||
const formattedTime = formatShortDateTimeWithConditionalYear(
|
||||
date,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
);
|
||||
const elementId = "last-activated-" + slugify(scene.entity_id);
|
||||
return html`
|
||||
${dayDifference > 3
|
||||
? formattedTime
|
||||
: html`
|
||||
<ha-tooltip for=${elementId}>${formattedTime}</ha-tooltip>
|
||||
<span id=${elementId}
|
||||
>${relativeTime(date, this.hass.locale)}</span
|
||||
>
|
||||
`}
|
||||
? formatShortDateTime(date, this.hass.locale, this.hass.config)
|
||||
: relativeTime(date, this.hass.locale)}
|
||||
`;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -33,8 +33,6 @@ import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { slugify } from "../../../common/string/slugify";
|
||||
import "../../../components/ha-tooltip";
|
||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import {
|
||||
hasRejectedItems,
|
||||
@@ -304,27 +302,19 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
||||
sortable: true,
|
||||
title: localize("ui.card.automation.last_triggered"),
|
||||
template: (script) => {
|
||||
if (!script.last_triggered) {
|
||||
return this.hass.localize("ui.components.relative_time.never");
|
||||
}
|
||||
const date = new Date(script.last_triggered);
|
||||
const now = new Date();
|
||||
const dayDifference = differenceInDays(now, date);
|
||||
const formattedTime = formatShortDateTimeWithConditionalYear(
|
||||
return html`
|
||||
${script.last_triggered
|
||||
? dayDifference > 3
|
||||
? formatShortDateTimeWithConditionalYear(
|
||||
date,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
);
|
||||
const elementId = "last-triggered-" + slugify(script.entity_id);
|
||||
return html`
|
||||
${dayDifference > 3
|
||||
? formattedTime
|
||||
: html`
|
||||
<ha-tooltip for=${elementId}>${formattedTime}</ha-tooltip>
|
||||
<span id=${elementId}
|
||||
>${relativeTime(date, this.hass.locale)}</span
|
||||
>
|
||||
`}
|
||||
)
|
||||
: relativeTime(date, this.hass.locale)
|
||||
: this.hass.localize("ui.components.relative_time.never")}
|
||||
`;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -547,9 +547,9 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
} else if (this._sortDirection === "asc") {
|
||||
this._sortDirection = "desc";
|
||||
} else {
|
||||
this._sortDirection = "asc";
|
||||
this._sortDirection = null;
|
||||
}
|
||||
this._sortColumn = columnId;
|
||||
this._sortColumn = this._sortDirection === null ? undefined : columnId;
|
||||
}
|
||||
|
||||
private _handleGroupBy(ev) {
|
||||
|
||||
@@ -324,7 +324,6 @@ class PanelEnergy extends LitElement {
|
||||
|
||||
const energy_sources = energyData.prefs.energy_sources;
|
||||
const device_consumption = energyData.prefs.device_consumption;
|
||||
const device_consumption_water = energyData.prefs.device_consumption_water;
|
||||
const stats = energyData.state.stats;
|
||||
|
||||
const timeSet = new Set<number>();
|
||||
@@ -510,20 +509,6 @@ class PanelEnergy extends LitElement {
|
||||
|
||||
printCategory("device_consumption", devices, electricUnit);
|
||||
|
||||
if (device_consumption_water) {
|
||||
const waterDevices: string[] = [];
|
||||
device_consumption_water.forEach((source) => {
|
||||
source = source as DeviceConsumptionEnergyPreference;
|
||||
waterDevices.push(source.stat_consumption);
|
||||
});
|
||||
|
||||
printCategory(
|
||||
"device_consumption_water",
|
||||
waterDevices,
|
||||
energyData.state.waterUnit
|
||||
);
|
||||
}
|
||||
|
||||
const { summedData, compareSummedData: _ } = getSummedData(
|
||||
energyData.state
|
||||
);
|
||||
|
||||
@@ -62,7 +62,9 @@ class HuiAlarmModeCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-alarm-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-alarm-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-alarm-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,9 @@ class HuiAreaControlsCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-area-controls-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-area-controls-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-area-controls-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,9 @@ class HuiClimateFanModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-climate-fan-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-climate-fan-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-climate-fan-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,9 @@ class HuiClimateHvacModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-climate-hvac-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-climate-hvac-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-climate-hvac-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,9 @@ class HuiClimatePresetModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-climate-preset-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-climate-preset-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-climate-preset-modes-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -71,7 +71,9 @@ class HuiClimateSwingHorizontalModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-climate-swing-horizontal-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-climate-swing-horizontal-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-climate-swing-horizontal-modes-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -71,7 +71,9 @@ class HuiClimateSwingModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-climate-swing-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-climate-swing-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-climate-swing-modes-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -79,7 +79,9 @@ class HuiCounterActionsCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-counter-actions-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-counter-actions-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-counter-actions-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ class HuiFanPresetModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-fan-preset-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-fan-preset-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-fan-preset-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,9 @@ class HuiHumidifierModesCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-humidifier-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-humidifier-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-humidifier-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,9 @@ class HuiLawnMowerCommandCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-lawn-mower-commands-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-lawn-mower-commands-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-lawn-mower-commands-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -60,7 +60,9 @@ class HuiMediaPlayerVolumeButtonsCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-media-player-volume-buttons-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-media-player-volume-buttons-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-media-player-volume-buttons-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -57,7 +57,9 @@ class HuiNumericInputCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-numeric-input-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-numeric-input-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-numeric-input-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,9 @@ class HuiSelectOptionsCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-select-options-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-select-options-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-select-options-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,9 @@ class HuiHistoryChartCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-trend-graph-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-trend-graph-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-trend-graph-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ class HuiUpdateActionsCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-update-actions-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-update-actions-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-update-actions-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,9 @@ class HuiVacuumCommandCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-vacuum-commands-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-vacuum-commands-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-vacuum-commands-card-feature-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,9 @@ class HuiWaterHeaterOperationModeCardFeature
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import("../editor/config-elements/hui-water-heater-operation-modes-card-feature-editor");
|
||||
await import(
|
||||
"../editor/config-elements/hui-water-heater-operation-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-water-heater-operation-modes-card-feature-editor"
|
||||
);
|
||||
|
||||
@@ -183,7 +183,8 @@ export interface EnergyDevicesGraphCardConfig extends EnergyCardBaseConfig {
|
||||
modes?: ("bar" | "pie")[];
|
||||
}
|
||||
|
||||
export interface EnergyDevicesDetailGraphCardConfig extends EnergyCardBaseConfig {
|
||||
export interface EnergyDevicesDetailGraphCardConfig
|
||||
extends EnergyCardBaseConfig {
|
||||
type: "energy-devices-detail-graph";
|
||||
title?: string;
|
||||
max_devices?: number;
|
||||
@@ -201,12 +202,14 @@ export interface EnergySolarGaugeCardConfig extends EnergyCardBaseConfig {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface EnergySelfSufficiencyGaugeCardConfig extends EnergyCardBaseConfig {
|
||||
export interface EnergySelfSufficiencyGaugeCardConfig
|
||||
extends EnergyCardBaseConfig {
|
||||
type: "energy-self-sufficiency-gauge";
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface EnergyGridNeutralityGaugeCardConfig extends EnergyCardBaseConfig {
|
||||
export interface EnergyGridNeutralityGaugeCardConfig
|
||||
extends EnergyCardBaseConfig {
|
||||
type: "energy-grid-neutrality-gauge";
|
||||
title?: string;
|
||||
}
|
||||
|
||||
@@ -43,9 +43,8 @@ export interface ConfigError {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface EntitiesEditorEvent<
|
||||
T extends EntityConfig = EntityConfig,
|
||||
> extends CustomEvent {
|
||||
export interface EntitiesEditorEvent<T extends EntityConfig = EntityConfig>
|
||||
extends CustomEvent {
|
||||
detail: {
|
||||
entities?: T[];
|
||||
item?: any;
|
||||
|
||||
@@ -13,7 +13,9 @@ import type {
|
||||
|
||||
class HuiConditionalElement extends HTMLElement implements LovelaceElement {
|
||||
public static async getConfigElement(): Promise<LovelacePictureElementEditor> {
|
||||
await import("../editor/config-elements/elements/hui-conditional-element-editor");
|
||||
await import(
|
||||
"../editor/config-elements/elements/hui-conditional-element-editor"
|
||||
);
|
||||
return document.createElement("hui-conditional-element-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ export class HuiServiceButtonElement
|
||||
implements LovelaceElement
|
||||
{
|
||||
public static async getConfigElement(): Promise<LovelacePictureElementEditor> {
|
||||
await import("../editor/config-elements/elements/hui-service-button-element-editor");
|
||||
await import(
|
||||
"../editor/config-elements/elements/hui-service-button-element-editor"
|
||||
);
|
||||
return document.createElement("hui-service-button-element-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ export class HuiStateBadgeElement
|
||||
implements LovelaceElement
|
||||
{
|
||||
public static async getConfigElement(): Promise<LovelacePictureElementEditor> {
|
||||
await import("../editor/config-elements/elements/hui-state-badge-element-editor");
|
||||
await import(
|
||||
"../editor/config-elements/elements/hui-state-badge-element-editor"
|
||||
);
|
||||
return document.createElement("hui-state-badge-element-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ import type { LovelaceElement, StateIconElementConfig } from "./types";
|
||||
@customElement("hui-state-icon-element")
|
||||
export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
||||
public static async getConfigElement(): Promise<LovelacePictureElementEditor> {
|
||||
await import("../editor/config-elements/elements/hui-state-icon-element-editor");
|
||||
await import(
|
||||
"../editor/config-elements/elements/hui-state-icon-element-editor"
|
||||
);
|
||||
return document.createElement("hui-state-icon-element-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ import type { LovelaceElement, StateLabelElementConfig } from "./types";
|
||||
@customElement("hui-state-label-element")
|
||||
class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
||||
public static async getConfigElement(): Promise<LovelacePictureElementEditor> {
|
||||
await import("../editor/config-elements/elements/hui-state-label-element-editor");
|
||||
await import(
|
||||
"../editor/config-elements/elements/hui-state-label-element-editor"
|
||||
);
|
||||
return document.createElement("hui-state-label-element-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@ export class HuiEntityHeadingBadge
|
||||
implements LovelaceHeadingBadge
|
||||
{
|
||||
public static async getConfigElement(): Promise<LovelaceHeadingBadgeEditor> {
|
||||
await import("../editor/heading-badge-editor/hui-entity-heading-badge-editor");
|
||||
await import(
|
||||
"../editor/heading-badge-editor/hui-entity-heading-badge-editor"
|
||||
);
|
||||
return document.createElement("hui-heading-entity-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ export class IframeDashboardStrategy extends ReactiveElement {
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceStrategyEditor> {
|
||||
await import("../../editor/dashboard-strategy-editor/hui-iframe-dashboard-strategy-editor");
|
||||
await import(
|
||||
"../../editor/dashboard-strategy-editor/hui-iframe-dashboard-strategy-editor"
|
||||
);
|
||||
return document.createElement("hui-iframe-dashboard-strategy-editor");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ export class OriginalStatesDashboardStrategy extends ReactiveElement {
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceStrategyEditor> {
|
||||
await import("../../editor/dashboard-strategy-editor/hui-original-states-dashboard-strategy-editor");
|
||||
await import(
|
||||
"../../editor/dashboard-strategy-editor/hui-original-states-dashboard-strategy-editor"
|
||||
);
|
||||
return document.createElement(
|
||||
"hui-original-states-dashboard-strategy-editor"
|
||||
);
|
||||
|
||||
@@ -12,11 +12,14 @@ export interface LovelaceStrategy<T = any> {
|
||||
configRequired?: boolean;
|
||||
}
|
||||
|
||||
export interface LovelaceDashboardStrategy extends LovelaceStrategy<LovelaceConfig> {}
|
||||
export interface LovelaceDashboardStrategy
|
||||
extends LovelaceStrategy<LovelaceConfig> {}
|
||||
|
||||
export interface LovelaceViewStrategy extends LovelaceStrategy<LovelaceViewConfig> {}
|
||||
export interface LovelaceViewStrategy
|
||||
extends LovelaceStrategy<LovelaceViewConfig> {}
|
||||
|
||||
export interface LovelaceSectionStrategy extends LovelaceStrategy<LovelaceSectionConfig> {}
|
||||
export interface LovelaceSectionStrategy
|
||||
extends LovelaceStrategy<LovelaceSectionConfig> {}
|
||||
|
||||
export interface LovelaceStrategyEditor extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceStrategyConfig): void;
|
||||
|
||||
@@ -112,7 +112,8 @@ export interface LovelaceBadgeConstructor extends Constructor<LovelaceBadge> {
|
||||
getConfigForm?: () => LovelaceConfigForm;
|
||||
}
|
||||
|
||||
export interface LovelaceHeaderFooterConstructor extends Constructor<LovelaceHeaderFooter> {
|
||||
export interface LovelaceHeaderFooterConstructor
|
||||
extends Constructor<LovelaceHeaderFooter> {
|
||||
getStubConfig?: (
|
||||
hass: HomeAssistant,
|
||||
entities: string[],
|
||||
@@ -125,7 +126,8 @@ export interface LovelaceRowConstructor extends Constructor<LovelaceRow> {
|
||||
getConfigElement?: () => LovelaceRowEditor;
|
||||
}
|
||||
|
||||
export interface LovelaceElementConstructor extends Constructor<LovelaceElement> {
|
||||
export interface LovelaceElementConstructor
|
||||
extends Constructor<LovelaceElement> {
|
||||
getConfigElement?: () => LovelacePictureElementEditor;
|
||||
getStubConfig?: (
|
||||
hass: HomeAssistant,
|
||||
@@ -149,7 +151,8 @@ export interface LovelaceBadgeEditor extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceBadgeConfig): void;
|
||||
}
|
||||
|
||||
export interface LovelaceHeaderFooterEditor extends LovelaceGenericElementEditor {
|
||||
export interface LovelaceHeaderFooterEditor
|
||||
extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceHeaderFooterConfig): void;
|
||||
}
|
||||
|
||||
@@ -157,7 +160,8 @@ export interface LovelaceRowEditor extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceRowConfig): void;
|
||||
}
|
||||
|
||||
export interface LovelacePictureElementEditor extends LovelaceGenericElementEditor {
|
||||
export interface LovelacePictureElementEditor
|
||||
extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceElementConfig): void;
|
||||
}
|
||||
|
||||
@@ -180,7 +184,8 @@ export interface LovelaceCardFeature extends HTMLElement {
|
||||
position?: LovelaceCardFeaturePosition;
|
||||
}
|
||||
|
||||
export interface LovelaceCardFeatureConstructor extends Constructor<LovelaceCardFeature> {
|
||||
export interface LovelaceCardFeatureConstructor
|
||||
extends Constructor<LovelaceCardFeature> {
|
||||
getStubConfig?: (
|
||||
hass: HomeAssistant,
|
||||
context?: LovelaceCardFeatureContext
|
||||
@@ -193,7 +198,8 @@ export interface LovelaceCardFeatureConstructor extends Constructor<LovelaceCard
|
||||
isSupported?: (stateObj?: HassEntity) => boolean;
|
||||
}
|
||||
|
||||
export interface LovelaceCardFeatureEditor extends LovelaceGenericElementEditor {
|
||||
export interface LovelaceCardFeatureEditor
|
||||
extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceCardFeatureConfig): void;
|
||||
}
|
||||
|
||||
@@ -203,7 +209,8 @@ export interface LovelaceHeadingBadge extends HTMLElement {
|
||||
setConfig(config: LovelaceHeadingBadgeConfig);
|
||||
}
|
||||
|
||||
export interface LovelaceHeadingBadgeConstructor extends Constructor<LovelaceHeadingBadge> {
|
||||
export interface LovelaceHeadingBadgeConstructor
|
||||
extends Constructor<LovelaceHeadingBadge> {
|
||||
getStubConfig?: (
|
||||
hass: HomeAssistant,
|
||||
stateObj?: HassEntity
|
||||
@@ -215,6 +222,7 @@ export interface LovelaceHeadingBadgeConstructor extends Constructor<LovelaceHea
|
||||
};
|
||||
}
|
||||
|
||||
export interface LovelaceHeadingBadgeEditor extends LovelaceGenericElementEditor {
|
||||
export interface LovelaceHeadingBadgeEditor
|
||||
extends LovelaceGenericElementEditor {
|
||||
setConfig(config: LovelaceHeadingBadgeConfig): void;
|
||||
}
|
||||
|
||||
@@ -514,7 +514,8 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
.wrapper.narrow hui-view-sidebar {
|
||||
grid-column: 1 / -1;
|
||||
padding-bottom: calc(
|
||||
var(--ha-space-14) + var(--ha-space-3) + var(--safe-area-inset-bottom)
|
||||
var(--ha-space-4) + 56px + var(--ha-space-4) +
|
||||
env(safe-area-inset-bottom)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -524,7 +525,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
.mobile-tabs {
|
||||
position: fixed;
|
||||
bottom: calc(var(--ha-space-3) + var(--safe-area-inset-bottom));
|
||||
bottom: calc(var(--ha-space-3) + env(safe-area-inset-bottom));
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 0;
|
||||
@@ -565,7 +566,8 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
.wrapper.narrow.has-sidebar .content {
|
||||
padding-bottom: calc(
|
||||
var(--ha-space-14) + var(--ha-space-3) + var(--safe-area-inset-bottom)
|
||||
var(--ha-space-4) + 56px + var(--ha-space-4) +
|
||||
env(safe-area-inset-bottom)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,18 +55,6 @@ const renderMarkdown = async (
|
||||
|
||||
marked.setOptions(markedOptions);
|
||||
|
||||
marked.use({
|
||||
renderer: {
|
||||
table(...args) {
|
||||
const defaultRenderer = new marked.Renderer();
|
||||
// Wrap the table with block element because the property 'overflow'
|
||||
// cannot be applied to elements of display type 'table'.
|
||||
// https://www.w3.org/TR/css-overflow-3/#overflow-control
|
||||
return `<div>${defaultRenderer.table.apply(this, args)}</div>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const tokens = marked.lexer(content);
|
||||
return tokens.map((token) =>
|
||||
filterXSS(marked.parser([token]), {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
if (typeof window.ResizeObserver !== "function") {
|
||||
window.ResizeObserver = (
|
||||
await import("@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver")
|
||||
await import(
|
||||
"@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver"
|
||||
)
|
||||
).default;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,27 +27,14 @@ export const mainStyles = css`
|
||||
--margin-title-ltr: 0 0 0 24px;
|
||||
--margin-title-rtl: 0 24px 0 0;
|
||||
|
||||
/* Safe area insets */
|
||||
--safe-area-inset-top: var(--app-safe-area-inset-top, env(safe-area-inset-top, 0px));
|
||||
--safe-area-inset-bottom: var(--app-safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
|
||||
--safe-area-inset-left: var(--app-safe-area-inset-left, env(safe-area-inset-left, 0px));
|
||||
--safe-area-inset-right: var(--app-safe-area-inset-right, env(safe-area-inset-right, 0px));
|
||||
/* safe-area-insets */
|
||||
--safe-area-inset-top: var(--app-safe-area-inset-top, env(safe-area-inset-top, 0));
|
||||
--safe-area-inset-bottom: var(--app-safe-area-inset-bottom, env(safe-area-inset-bottom, 0));
|
||||
--safe-area-inset-left: var(--app-safe-area-inset-left, env(safe-area-inset-left, 0));
|
||||
--safe-area-inset-right: var(--app-safe-area-inset-right, env(safe-area-inset-right, 0));
|
||||
|
||||
/* Safe area inset x and y */
|
||||
--safe-area-inset-x: calc(var(--safe-area-inset-left, 0px) + var(--safe-area-inset-right, 0px));
|
||||
--safe-area-inset-y: calc(var(--safe-area-inset-top, 0px) + var(--safe-area-inset-bottom, 0px));
|
||||
|
||||
/* Offsets for centering elements within asymmetric safe areas */
|
||||
--safe-area-offset-left: calc(max(var(--safe-area-inset-left, 0px) - var(--safe-area-inset-right, 0px), 0px) / 2);
|
||||
--safe-area-offset-right: calc(max(var(--safe-area-inset-right, 0px) - var(--safe-area-inset-left, 0px), 0px) / 2);
|
||||
--safe-area-offset-top: calc(max(var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px), 0px) / 2);
|
||||
--safe-area-offset-bottom: calc(max(var(--safe-area-inset-bottom, 0px) - var(--safe-area-inset-top, 0px), 0px) / 2);
|
||||
|
||||
/* Safe width and height for use instead of 100vw and 100vh
|
||||
* when working with areas like dialogs which need to fill the entire safe area.
|
||||
*/
|
||||
--safe-width: calc(100vw - var(--safe-area-inset-left) - var(--safe-area-inset-right));
|
||||
--safe-height: calc(100vh - var(--safe-area-inset-top) - var(--safe-area-inset-bottom));
|
||||
--safe-area-inset-x: calc(var(--safe-area-inset-left, 0px) + var(--safe-area-inset-right, 0px));
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -150,8 +150,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
let redirects: Redirects;
|
||||
|
||||
if (targetPath.startsWith("/hassio")) {
|
||||
const myPanelSupervisor =
|
||||
await import("../../hassio/src/hassio-my-redirect");
|
||||
const myPanelSupervisor = await import(
|
||||
"../../hassio/src/hassio-my-redirect"
|
||||
);
|
||||
redirects = myPanelSupervisor.REDIRECTS;
|
||||
} else {
|
||||
const myPanel = await import("../panels/my/ha-panel-my");
|
||||
|
||||
@@ -35,8 +35,9 @@ describe("token_storage.saveTokens", () => {
|
||||
})
|
||||
);
|
||||
|
||||
({ saveTokens } =
|
||||
await import("../../../../src/common/auth/token_storage"));
|
||||
({ saveTokens } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
));
|
||||
saveTokens(tokens);
|
||||
expect(window.__tokenCache.tokens).toEqual(tokens);
|
||||
});
|
||||
@@ -67,8 +68,9 @@ describe("token_storage.saveTokens", () => {
|
||||
const setItemSpy = vi.fn();
|
||||
window.localStorage.setItem = setItemSpy;
|
||||
|
||||
({ saveTokens } =
|
||||
await import("../../../../src/common/auth/token_storage"));
|
||||
({ saveTokens } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
));
|
||||
saveTokens(tokens);
|
||||
expect(window.__tokenCache.tokens).toEqual(tokens);
|
||||
expect(window.__tokenCache.writeEnabled).toBe(true);
|
||||
@@ -117,8 +119,9 @@ describe("token_storage.saveTokens", () => {
|
||||
error: vi.fn(),
|
||||
} as unknown as Console;
|
||||
|
||||
({ saveTokens } =
|
||||
await import("../../../../src/common/auth/token_storage"));
|
||||
({ saveTokens } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
));
|
||||
saveTokens(tokens);
|
||||
expect(window.__tokenCache.tokens).toEqual(tokens);
|
||||
expect(window.__tokenCache.writeEnabled).toBe(true);
|
||||
|
||||
@@ -49,8 +49,9 @@ describe("token_storage", () => {
|
||||
const getItemSpy = vi.fn(() => JSON.stringify(tokens));
|
||||
window.localStorage.getItem = getItemSpy;
|
||||
|
||||
const { loadTokens } =
|
||||
await import("../../../../src/common/auth/token_storage");
|
||||
const { loadTokens } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
);
|
||||
|
||||
const loadedTokens = loadTokens();
|
||||
expect(loadedTokens).toEqual(tokens);
|
||||
@@ -65,8 +66,9 @@ describe("token_storage", () => {
|
||||
const getItemSpy = vi.fn(() => "hello");
|
||||
window.localStorage.getItem = getItemSpy;
|
||||
|
||||
const { loadTokens } =
|
||||
await import("../../../../src/common/auth/token_storage");
|
||||
const { loadTokens } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
);
|
||||
|
||||
const loadedTokens = loadTokens();
|
||||
expect(loadedTokens).toEqual(null);
|
||||
@@ -78,8 +80,9 @@ describe("token_storage", () => {
|
||||
});
|
||||
|
||||
it("should enable write", async () => {
|
||||
const { enableWrite } =
|
||||
await import("../../../../src/common/auth/token_storage");
|
||||
const { enableWrite } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
);
|
||||
enableWrite();
|
||||
expect(window.__tokenCache.writeEnabled).toBe(true);
|
||||
});
|
||||
@@ -95,8 +98,9 @@ describe("token_storage", () => {
|
||||
const setItemSpy = vi.fn();
|
||||
window.localStorage.setItem = setItemSpy;
|
||||
|
||||
const { enableWrite } =
|
||||
await import("../../../../src/common/auth/token_storage");
|
||||
const { enableWrite } = await import(
|
||||
"../../../../src/common/auth/token_storage"
|
||||
);
|
||||
|
||||
enableWrite();
|
||||
expect(window.__tokenCache.writeEnabled).toBe(true);
|
||||
|
||||
Reference in New Issue
Block a user