mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-10-31 14:39:38 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			config-das
			...
			copilot/al
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ![copilot-swe-agent[bot]](/assets/img/avatar_default.png)  | 84c8420286 | 
| @@ -16,9 +16,9 @@ import { | ||||
| } from "../../../../src/common/auth/token_storage"; | ||||
| import { atLeastVersion } from "../../../../src/common/config/version"; | ||||
| import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute"; | ||||
| import "../../../../src/components/ha-button"; | ||||
| import "../../../../src/components/ha-icon"; | ||||
| import "../../../../src/components/ha-list"; | ||||
| import "../../../../src/components/ha-button"; | ||||
| import "../../../../src/components/ha-list-item"; | ||||
| import "../../../../src/components/ha-svg-icon"; | ||||
| import { | ||||
| @@ -28,6 +28,7 @@ import { | ||||
| import { isStrategyDashboard } from "../../../../src/data/lovelace/config/types"; | ||||
| import type { LovelaceViewConfig } from "../../../../src/data/lovelace/config/view"; | ||||
| import "../../../../src/layouts/hass-loading-screen"; | ||||
| import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config"; | ||||
| import "./hc-layout"; | ||||
|  | ||||
| @customElement("hc-cast") | ||||
| @@ -95,9 +96,7 @@ class HcCast extends LitElement { | ||||
|                 <ha-list @action=${this._handlePickView} activatable> | ||||
|                   ${( | ||||
|                     this.lovelaceViews ?? [ | ||||
|                       { | ||||
|                         title: "Home", | ||||
|                       }, | ||||
|                       generateDefaultViewConfig({}, {}, {}, {}, () => ""), | ||||
|                     ] | ||||
|                   ).map( | ||||
|                     (view, idx) => html` | ||||
|   | ||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							| @@ -157,7 +157,7 @@ | ||||
|     "@octokit/auth-oauth-device": "8.0.2", | ||||
|     "@octokit/plugin-retry": "8.0.2", | ||||
|     "@octokit/rest": "22.0.0", | ||||
|     "@rsdoctor/rspack-plugin": "1.3.6", | ||||
|     "@rsdoctor/rspack-plugin": "1.3.4", | ||||
|     "@rspack/core": "1.5.8", | ||||
|     "@rspack/dev-server": "1.1.4", | ||||
|     "@types/babel__plugin-transform-runtime": "7.9.5", | ||||
| @@ -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.4", | ||||
|     "@vitest/coverage-v8": "4.0.3", | ||||
|     "babel-loader": "10.0.0", | ||||
|     "babel-plugin-template-html-minifier": "4.1.0", | ||||
|     "browserslist-useragent-regexp": "4.1.3", | ||||
| @@ -219,7 +219,7 @@ | ||||
|     "typescript": "5.9.3", | ||||
|     "typescript-eslint": "8.46.2", | ||||
|     "vite-tsconfig-paths": "5.1.4", | ||||
|     "vitest": "4.0.4", | ||||
|     "vitest": "4.0.3", | ||||
|     "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" | ||||
| @@ -235,8 +235,5 @@ | ||||
|     "tslib": "2.8.1", | ||||
|     "@material/mwc-list@^0.27.0": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch" | ||||
|   }, | ||||
|   "packageManager": "yarn@4.10.3", | ||||
|   "volta": { | ||||
|     "node": "22.21.1" | ||||
|   } | ||||
|   "packageManager": "yarn@4.10.3" | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" | ||||
|  | ||||
| [project] | ||||
| name         = "home-assistant-frontend" | ||||
| version      = "20251029.0" | ||||
| version      = "20250924.0" | ||||
| license      = "Apache-2.0" | ||||
| license-files = ["LICENSE*"] | ||||
| description  = "The Home Assistant frontend" | ||||
|   | ||||
| @@ -35,7 +35,6 @@ export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000; | ||||
| const LEGEND_OVERFLOW_LIMIT = 10; | ||||
| const LEGEND_OVERFLOW_LIMIT_MOBILE = 6; | ||||
| const DOUBLE_TAP_TIME = 300; | ||||
| const RESIZE_ANIMATION_DURATION = 250; | ||||
|  | ||||
| export type CustomLegendOption = ECOption["legend"] & { | ||||
|   type: "custom"; | ||||
| @@ -206,15 +205,6 @@ export class HaChartBase extends LitElement { | ||||
|     } | ||||
|     if (changedProps.has("options")) { | ||||
|       chartOptions = { ...chartOptions, ...this._createOptions() }; | ||||
|       if ( | ||||
|         this._compareCustomLegendOptions( | ||||
|           changedProps.get("options"), | ||||
|           this.options | ||||
|         ) | ||||
|       ) { | ||||
|         // custom legend changes may require a resize to layout properly | ||||
|         this._shouldResizeChart = true; | ||||
|       } | ||||
|     } else if (this._isTouchDevice && changedProps.has("_isZoomed")) { | ||||
|       chartOptions.dataZoom = this._getDataZoomConfig(); | ||||
|     } | ||||
| @@ -306,7 +296,7 @@ export class HaChartBase extends LitElement { | ||||
|           itemStyle = { | ||||
|             color: dataset?.color as string, | ||||
|             ...(dataset?.itemStyle as { borderColor?: string }), | ||||
|             ...itemStyle, | ||||
|             itemStyle, | ||||
|           }; | ||||
|           const color = itemStyle?.color as string; | ||||
|           const borderColor = itemStyle?.borderColor as string; | ||||
| @@ -518,7 +508,6 @@ export class HaChartBase extends LitElement { | ||||
|         ); | ||||
|       } | ||||
|     }); | ||||
|     this.requestUpdate("_hiddenDatasets"); | ||||
|   } | ||||
|  | ||||
|   private _getDataZoomConfig(): DataZoomComponentOption | undefined { | ||||
| @@ -969,31 +958,11 @@ export class HaChartBase extends LitElement { | ||||
|  | ||||
|   private _handleChartRenderFinished = () => { | ||||
|     if (this._shouldResizeChart) { | ||||
|       this.chart?.resize({ | ||||
|         animation: this._reducedMotion | ||||
|           ? undefined | ||||
|           : { duration: RESIZE_ANIMATION_DURATION }, | ||||
|       }); | ||||
|       this.chart?.resize(); | ||||
|       this._shouldResizeChart = false; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   private _compareCustomLegendOptions( | ||||
|     oldOptions: ECOption | undefined, | ||||
|     newOptions: ECOption | undefined | ||||
|   ): boolean { | ||||
|     const oldLegends = ensureArray( | ||||
|       oldOptions?.legend || [] | ||||
|     ) as LegendComponentOption[]; | ||||
|     const newLegends = ensureArray( | ||||
|       newOptions?.legend || [] | ||||
|     ) as LegendComponentOption[]; | ||||
|     return ( | ||||
|       oldLegends.some((l) => l.show && l.type === "custom") !== | ||||
|       newLegends.some((l) => l.show && l.type === "custom") | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   static styles = css` | ||||
|     :host { | ||||
|       display: block; | ||||
|   | ||||
| @@ -147,7 +147,7 @@ class HaEntitiesPicker extends LitElement { | ||||
|           .createDomains=${this.createDomains} | ||||
|           .required=${this.required && !currentEntities.length} | ||||
|           @value-changed=${this._addEntity} | ||||
|           .addButton=${currentEntities.length > 0} | ||||
|           add-button | ||||
|         ></ha-entity-picker> | ||||
|       </div> | ||||
|     `; | ||||
|   | ||||
| @@ -312,7 +312,7 @@ export class HaEntityNamePicker extends LitElement { | ||||
|   private _toValue = memoizeOne( | ||||
|     (items: EntityNameItem[]): typeof this.value => { | ||||
|       if (items.length === 0) { | ||||
|         return undefined; | ||||
|         return ""; | ||||
|       } | ||||
|       if (items.length === 1) { | ||||
|         const item = items[0]; | ||||
|   | ||||
| @@ -148,7 +148,7 @@ export class HaForm extends LitElement implements HaFormElement { | ||||
|                   .value=${getValue(this.data, item)} | ||||
|                   .label=${this._computeLabel(item, this.data)} | ||||
|                   .disabled=${item.disabled || this.disabled || false} | ||||
|                   .placeholder=${item.required ? undefined : item.default} | ||||
|                   .placeholder=${item.required ? "" : item.default} | ||||
|                   .helper=${this._computeHelper(item)} | ||||
|                   .localizeValue=${this.localizeValue} | ||||
|                   .required=${item.required || false} | ||||
|   | ||||
| @@ -16,10 +16,14 @@ import memoizeOne from "memoize-one"; | ||||
| import { computeCssColor } from "../../common/color/compute-color"; | ||||
| import { hex2rgb } from "../../common/color/convert-color"; | ||||
| import { fireEvent } from "../../common/dom/fire_event"; | ||||
| import { computeDeviceNameDisplay } from "../../common/entity/compute_device_name"; | ||||
| import { computeDomain } from "../../common/entity/compute_domain"; | ||||
| import { computeStateName } from "../../common/entity/compute_state_name"; | ||||
| import { slugify } from "../../common/string/slugify"; | ||||
| import { | ||||
|   computeDeviceName, | ||||
|   computeDeviceNameDisplay, | ||||
| } from "../../common/entity/compute_device_name"; | ||||
| import { computeDomain } from "../../common/entity/compute_domain"; | ||||
| import { computeEntityName } from "../../common/entity/compute_entity_name"; | ||||
| import { getEntityContext } from "../../common/entity/context/get_entity_context"; | ||||
| import { getConfigEntry } from "../../data/config_entries"; | ||||
| import { labelsContext } from "../../data/context"; | ||||
| import { domainToName } from "../../data/integration"; | ||||
| @@ -168,10 +172,23 @@ export class HaTargetPickerValueChip extends LitElement { | ||||
|     if (type === "entity") { | ||||
|       this._setDomainName(computeDomain(itemId)); | ||||
|  | ||||
|       const stateObj = this.hass.states[itemId]; | ||||
|       const stateObject = this.hass.states[itemId]; | ||||
|       const entityName = computeEntityName( | ||||
|         stateObject, | ||||
|         this.hass.entities, | ||||
|         this.hass.devices | ||||
|       ); | ||||
|       const { device } = getEntityContext( | ||||
|         stateObject, | ||||
|         this.hass.entities, | ||||
|         this.hass.devices, | ||||
|         this.hass.areas, | ||||
|         this.hass.floors | ||||
|       ); | ||||
|       const deviceName = device ? computeDeviceName(device) : undefined; | ||||
|       return { | ||||
|         name: computeStateName(stateObj) || itemId, | ||||
|         stateObject: stateObj, | ||||
|         name: entityName || deviceName || itemId, | ||||
|         stateObject, | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,6 @@ import { | ||||
|   getFloors, | ||||
| } from "../../lovelace/strategies/areas/helpers/areas-strategy-helper"; | ||||
| import { getHomeStructure } from "../../lovelace/strategies/home/helpers/home-structure"; | ||||
| import { floorDefaultIcon } from "../../../components/ha-floor-icon"; | ||||
|  | ||||
| export interface ClimateViewStrategyConfig { | ||||
|   type: "climate"; | ||||
| @@ -153,7 +152,6 @@ export class ClimateViewStrategy extends ReactiveElement { | ||||
|               floorCount > 1 | ||||
|                 ? floor.name | ||||
|                 : hass.localize("ui.panel.lovelace.strategy.home.areas"), | ||||
|             icon: floor.icon || floorDefaultIcon(floor), | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|   | ||||
| @@ -3,7 +3,6 @@ import { | ||||
|   mdiContentCopy, | ||||
|   mdiContentCut, | ||||
|   mdiDelete, | ||||
|   mdiIdentifier, | ||||
|   mdiPlayCircleOutline, | ||||
|   mdiPlaylistEdit, | ||||
|   mdiPlusCircleMultipleOutline, | ||||
| @@ -41,8 +40,6 @@ export default class HaAutomationSidebarTrigger extends LitElement { | ||||
|   @property({ type: Number, attribute: "sidebar-key" }) | ||||
|   public sidebarKey?: number; | ||||
|  | ||||
|   @state() private _requestShowId = false; | ||||
|  | ||||
|   @state() private _warnings?: string[]; | ||||
|  | ||||
|   @query(".sidebar-editor") | ||||
| @@ -50,7 +47,6 @@ export default class HaAutomationSidebarTrigger extends LitElement { | ||||
|  | ||||
|   protected willUpdate(changedProperties) { | ||||
|     if (changedProperties.has("config")) { | ||||
|       this._requestShowId = false; | ||||
|       this._warnings = undefined; | ||||
|       if (this.config) { | ||||
|         this.yamlMode = this.config.yamlMode; | ||||
| @@ -105,24 +101,6 @@ export default class HaAutomationSidebarTrigger extends LitElement { | ||||
|           </div> | ||||
|         </ha-md-menu-item> | ||||
|  | ||||
|         ${!this.yamlMode && | ||||
|         !("id" in this.config.config) && | ||||
|         !this._requestShowId | ||||
|           ? html`<ha-md-menu-item | ||||
|               slot="menu-items" | ||||
|               .clickAction=${this._showTriggerId} | ||||
|               .disabled=${this.disabled || type === "list"} | ||||
|             > | ||||
|               <ha-svg-icon slot="start" .path=${mdiIdentifier}></ha-svg-icon> | ||||
|               <div class="overflow-label"> | ||||
|                 ${this.hass.localize( | ||||
|                   "ui.panel.config.automation.editor.triggers.edit_id" | ||||
|                 )} | ||||
|                 <span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span> | ||||
|               </div> | ||||
|             </ha-md-menu-item>` | ||||
|           : nothing} | ||||
|  | ||||
|         <ha-md-divider | ||||
|           slot="menu-items" | ||||
|           role="separator" | ||||
| @@ -272,7 +250,6 @@ export default class HaAutomationSidebarTrigger extends LitElement { | ||||
|             @value-changed=${this._valueChangedSidebar} | ||||
|             @yaml-changed=${this._yamlChangedSidebar} | ||||
|             .uiSupported=${this.config.uiSupported} | ||||
|             .showId=${this._requestShowId} | ||||
|             .yamlMode=${this.yamlMode} | ||||
|             .disabled=${this.disabled} | ||||
|             @ui-mode-not-available=${this._handleUiModeNotAvailable} | ||||
| @@ -315,10 +292,6 @@ export default class HaAutomationSidebarTrigger extends LitElement { | ||||
|     fireEvent(this, "toggle-yaml-mode"); | ||||
|   }; | ||||
|  | ||||
|   private _showTriggerId = () => { | ||||
|     this._requestShowId = true; | ||||
|   }; | ||||
|  | ||||
|   static styles = [sidebarEditorStyles, overflowStyles]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -29,8 +29,6 @@ export default class HaAutomationTriggerEditor extends LitElement { | ||||
|  | ||||
|   @property({ type: Boolean, attribute: "sidebar" }) public inSidebar = false; | ||||
|  | ||||
|   @property({ type: Boolean, attribute: "show-id" }) public showId = false; | ||||
|  | ||||
|   @query("ha-yaml-editor") public yamlEditor?: HaYamlEditor; | ||||
|  | ||||
|   protected render() { | ||||
| @@ -38,8 +36,6 @@ export default class HaAutomationTriggerEditor extends LitElement { | ||||
|  | ||||
|     const yamlMode = this.yamlMode || !this.uiSupported; | ||||
|  | ||||
|     const showId = "id" in this.trigger || this.showId; | ||||
|  | ||||
|     return html` | ||||
|       <div | ||||
|         class=${classMap({ | ||||
| @@ -74,15 +70,20 @@ export default class HaAutomationTriggerEditor extends LitElement { | ||||
|               ></ha-yaml-editor> | ||||
|             ` | ||||
|           : html` | ||||
|               ${showId && !isTriggerList(this.trigger) | ||||
|               ${!isTriggerList(this.trigger) | ||||
|                 ? html` | ||||
|                     <ha-textfield | ||||
|                       .label=${this.hass.localize( | ||||
|                       .label=${`${this.hass.localize( | ||||
|                         "ui.panel.config.automation.editor.triggers.id" | ||||
|                       )} | ||||
|                       )} (${this.hass.localize( | ||||
|                         "ui.panel.config.automation.editor.triggers.optional" | ||||
|                       )})`} | ||||
|                       .value=${this.trigger.id || ""} | ||||
|                       .disabled=${this.disabled} | ||||
|                       @change=${this._idChanged} | ||||
|                       .helper=${this.hass.localize( | ||||
|                         "ui.panel.config.automation.editor.triggers.id_helper" | ||||
|                       )} | ||||
|                     ></ha-textfield> | ||||
|                   ` | ||||
|                 : nothing} | ||||
|   | ||||
| @@ -245,20 +245,18 @@ export class HaStateTrigger extends LitElement implements TriggerElement { | ||||
|       newTrigger.to, | ||||
|       newTrigger.attribute | ||||
|     ); | ||||
|     if (Array.isArray(newTrigger.to) && newTrigger.to.length === 0) { | ||||
|       delete newTrigger.to; | ||||
|     } | ||||
|     newTrigger.from = this._applyAnyStateExclusive( | ||||
|       newTrigger.from, | ||||
|       newTrigger.attribute | ||||
|     ); | ||||
|     if (Array.isArray(newTrigger.from) && newTrigger.from.length === 0) { | ||||
|       delete newTrigger.from; | ||||
|     } | ||||
|  | ||||
|     Object.keys(newTrigger).forEach((key) => { | ||||
|       const val = newTrigger[key]; | ||||
|       if (val === undefined || val === "") { | ||||
|       if ( | ||||
|         val === undefined || | ||||
|         val === "" || | ||||
|         (Array.isArray(val) && val.length === 0) | ||||
|       ) { | ||||
|         delete newTrigger[key]; | ||||
|       } | ||||
|     }); | ||||
|   | ||||
| @@ -20,7 +20,6 @@ import { subscribeEntityRegistry } from "../../../data/entity_registry"; | ||||
| import type { UpdateEntity } from "../../../data/update"; | ||||
| import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import "../../../components/ha-progress-ring"; | ||||
|  | ||||
| @customElement("ha-config-updates") | ||||
| class HaConfigUpdates extends SubscribeMixin(LitElement) { | ||||
| @@ -57,26 +56,6 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) { | ||||
|       this._entities?.find((entity) => entity.entity_id === entityId) | ||||
|   ); | ||||
|  | ||||
|   private _renderUpdateProgress(entity: UpdateEntity) { | ||||
|     if (entity.attributes.update_percentage !== null) { | ||||
|       return html`<ha-progress-ring | ||||
|         size="small" | ||||
|         .value=${entity.attributes.update_percentage} | ||||
|       ></ha-progress-ring>`; | ||||
|     } | ||||
|  | ||||
|     if (entity.attributes.in_progress) { | ||||
|       return html`<ha-spinner | ||||
|         size="small" | ||||
|         .ariaLabel=${this.hass.localize( | ||||
|           "ui.panel.config.updates.update_in_progress" | ||||
|         )} | ||||
|       ></ha-spinner>`; | ||||
|     } | ||||
|  | ||||
|     return html`<ha-icon-next></ha-icon-next>`; | ||||
|   } | ||||
|  | ||||
|   protected render() { | ||||
|     if (!this.updateEntities?.length) { | ||||
|       return nothing; | ||||
| @@ -127,9 +106,13 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) { | ||||
|                   )} | ||||
|                 ></state-badge> | ||||
|                 ${this.narrow && entity.attributes.in_progress | ||||
|                   ? html`<div class="absolute"> | ||||
|                       ${this._renderUpdateProgress(entity)} | ||||
|                     </div>` | ||||
|                   ? html`<ha-spinner | ||||
|                       class="absolute" | ||||
|                       size="small" | ||||
|                       .ariaLabel=${this.hass.localize( | ||||
|                         "ui.panel.config.updates.update_in_progress" | ||||
|                       )} | ||||
|                     ></ha-spinner>` | ||||
|                   : nothing} | ||||
|               </div> | ||||
|               <span slot="headline" | ||||
| @@ -145,9 +128,16 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) { | ||||
|                   : nothing} | ||||
|               </span> | ||||
|               ${!this.narrow | ||||
|                 ? html`<div slot="end"> | ||||
|                     ${this._renderUpdateProgress(entity)} | ||||
|                   </div>` | ||||
|                 ? entity.attributes.in_progress | ||||
|                   ? html`<div slot="end"> | ||||
|                       <ha-spinner | ||||
|                         size="small" | ||||
|                         .ariaLabel=${this.hass.localize( | ||||
|                           "ui.panel.config.updates.update_in_progress" | ||||
|                         )} | ||||
|                       ></ha-spinner> | ||||
|                     </div>` | ||||
|                   : html`<ha-icon-next slot="end"></ha-icon-next>` | ||||
|                 : nothing} | ||||
|             </ha-md-list-item> | ||||
|           `; | ||||
| @@ -203,13 +193,13 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) { | ||||
|         div[slot="start"] { | ||||
|           position: relative; | ||||
|         } | ||||
|         div.absolute { | ||||
|         ha-spinner.absolute { | ||||
|           position: absolute; | ||||
|           left: 6px; | ||||
|           top: 6px; | ||||
|         } | ||||
|         state-badge.updating { | ||||
|           opacity: 0.2; | ||||
|           opacity: 0.5; | ||||
|         } | ||||
|       `, | ||||
|     ]; | ||||
|   | ||||
| @@ -228,7 +228,7 @@ export class HaDeviceEntitiesCard extends LitElement { | ||||
|     addEntitiesToLovelaceView( | ||||
|       this, | ||||
|       this.hass, | ||||
|       computeCards(this.hass, entities, { | ||||
|       computeCards(this.hass.states, entities, { | ||||
|         title: this.deviceName, | ||||
|       }), | ||||
|       computeSection(entities, { | ||||
|   | ||||
| @@ -5,7 +5,8 @@ import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name"; | ||||
| import "../../../../components/ha-alert"; | ||||
| import "../../../../components/ha-area-picker"; | ||||
| import "../../../../components/ha-dialog"; | ||||
| import "../../../../components/ha-wa-dialog"; | ||||
| import "../../../../components/ha-dialog-footer"; | ||||
| import "../../../../components/ha-button"; | ||||
| import "../../../../components/ha-labels-picker"; | ||||
| import type { HaSwitch } from "../../../../components/ha-switch"; | ||||
| @@ -19,6 +20,8 @@ import type { DeviceRegistryDetailDialogParams } from "./show-dialog-device-regi | ||||
| class DialogDeviceRegistryDetail extends LitElement { | ||||
|   @property({ attribute: false }) public hass!: HomeAssistant; | ||||
|  | ||||
|   @state() private _open = false; | ||||
|  | ||||
|   @state() private _nameByUser!: string; | ||||
|  | ||||
|   @state() private _error?: string; | ||||
| @@ -42,10 +45,15 @@ class DialogDeviceRegistryDetail extends LitElement { | ||||
|     this._areaId = this._params.device.area_id || ""; | ||||
|     this._labels = this._params.device.labels || []; | ||||
|     this._disabledBy = this._params.device.disabled_by; | ||||
|     this._open = true; | ||||
|     await this.updateComplete; | ||||
|   } | ||||
|  | ||||
|   public closeDialog(): void { | ||||
|     this._open = false; | ||||
|   } | ||||
|  | ||||
|   private _dialogClosed(): void { | ||||
|     this._error = ""; | ||||
|     this._params = undefined; | ||||
|     fireEvent(this, "dialog-closed", { dialog: this.localName }); | ||||
| @@ -57,10 +65,12 @@ class DialogDeviceRegistryDetail extends LitElement { | ||||
|     } | ||||
|     const device = this._params.device; | ||||
|     return html` | ||||
|       <ha-dialog | ||||
|         open | ||||
|         @closed=${this.closeDialog} | ||||
|         .heading=${computeDeviceNameDisplay(device, this.hass)} | ||||
|       <ha-wa-dialog | ||||
|         .hass=${this.hass} | ||||
|         .open=${this._open} | ||||
|         header-title=${computeDeviceNameDisplay(device, this.hass)} | ||||
|         prevent-scrim-close | ||||
|         @closed=${this._dialogClosed} | ||||
|       > | ||||
|         <div> | ||||
|           ${this._error | ||||
| @@ -68,6 +78,7 @@ class DialogDeviceRegistryDetail extends LitElement { | ||||
|             : ""} | ||||
|           <div class="form"> | ||||
|             <ha-textfield | ||||
|               autofocus | ||||
|               .value=${this._nameByUser} | ||||
|               @input=${this._nameChanged} | ||||
|               .label=${this.hass.localize( | ||||
| @@ -75,7 +86,6 @@ class DialogDeviceRegistryDetail extends LitElement { | ||||
|               )} | ||||
|               .placeholder=${device.name || ""} | ||||
|               .disabled=${this._submitting} | ||||
|               dialogInitialFocus | ||||
|             ></ha-textfield> | ||||
|             <ha-area-picker | ||||
|               .hass=${this.hass} | ||||
| @@ -131,22 +141,25 @@ class DialogDeviceRegistryDetail extends LitElement { | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <ha-button | ||||
|           slot="secondaryAction" | ||||
|           @click=${this.closeDialog} | ||||
|           .disabled=${this._submitting} | ||||
|           appearance="plain" | ||||
|         > | ||||
|           ${this.hass.localize("ui.common.cancel")} | ||||
|         </ha-button> | ||||
|         <ha-button | ||||
|           slot="primaryAction" | ||||
|           @click=${this._updateEntry} | ||||
|           .disabled=${this._submitting} | ||||
|         > | ||||
|           ${this.hass.localize("ui.dialogs.device-registry-detail.update")} | ||||
|         </ha-button> | ||||
|       </ha-dialog> | ||||
|  | ||||
|         <ha-dialog-footer slot="footer"> | ||||
|           <ha-button | ||||
|             slot="secondaryAction" | ||||
|             @click=${this.closeDialog} | ||||
|             .disabled=${this._submitting} | ||||
|             appearance="plain" | ||||
|           > | ||||
|             ${this.hass.localize("ui.common.cancel")} | ||||
|           </ha-button> | ||||
|           <ha-button | ||||
|             slot="primaryAction" | ||||
|             @click=${this._updateEntry} | ||||
|             .disabled=${this._submitting} | ||||
|           > | ||||
|             ${this.hass.localize("ui.dialogs.device-registry-detail.update")} | ||||
|           </ha-button> | ||||
|         </ha-dialog-footer> | ||||
|       </ha-wa-dialog> | ||||
|     `; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -139,12 +139,6 @@ export class AssistPipelineDebug extends LitElement { | ||||
|  | ||||
|   @property({ attribute: false }) public pipelineRun!: PipelineRun; | ||||
|  | ||||
|   private _audioElement?: HTMLAudioElement; | ||||
|  | ||||
|   private get _isPlaying(): boolean { | ||||
|     return this._audioElement != null && !this._audioElement.paused; | ||||
|   } | ||||
|  | ||||
|   protected render(): TemplateResult { | ||||
|     const lastRunStage: string = this.pipelineRun | ||||
|       ? ["tts", "intent", "stt", "wake_word"].find( | ||||
| @@ -355,13 +349,8 @@ export class AssistPipelineDebug extends LitElement { | ||||
|               ${this.pipelineRun?.tts?.tts_output | ||||
|                 ? html` | ||||
|                     <div class="card-actions"> | ||||
|                       <ha-button | ||||
|                         .variant=${this._isPlaying ? "danger" : "brand"} | ||||
|                         @click=${this._isPlaying | ||||
|                           ? this._stopTTS | ||||
|                           : this._playTTS} | ||||
|                       > | ||||
|                         ${this._isPlaying ? "Stop audio" : "Play audio"} | ||||
|                       <ha-button @click=${this._playTTS}> | ||||
|                         Play Audio | ||||
|                       </ha-button> | ||||
|                     </div> | ||||
|                   ` | ||||
| @@ -384,41 +373,14 @@ export class AssistPipelineDebug extends LitElement { | ||||
|   } | ||||
|  | ||||
|   private _playTTS(): void { | ||||
|     // Stop any existing audio first | ||||
|     this._stopTTS(); | ||||
|  | ||||
|     const url = this.pipelineRun!.tts!.tts_output!.url; | ||||
|     this._audioElement = new Audio(url); | ||||
|  | ||||
|     this._audioElement.addEventListener("error", () => { | ||||
|     const audio = new Audio(url); | ||||
|     audio.addEventListener("error", () => { | ||||
|       showAlertDialog(this, { title: "Error", text: "Error playing audio" }); | ||||
|     }); | ||||
|  | ||||
|     this._audioElement.addEventListener("play", () => { | ||||
|       this.requestUpdate(); | ||||
|     audio.addEventListener("canplaythrough", () => { | ||||
|       audio.play(); | ||||
|     }); | ||||
|  | ||||
|     this._audioElement.addEventListener("ended", () => { | ||||
|       this.requestUpdate(); | ||||
|     }); | ||||
|  | ||||
|     this._audioElement.addEventListener("canplaythrough", () => { | ||||
|       this._audioElement!.play(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   private _stopTTS(): void { | ||||
|     if (this._audioElement) { | ||||
|       this._audioElement.pause(); | ||||
|       this._audioElement.currentTime = 0; | ||||
|       this._audioElement = undefined; | ||||
|       this.requestUpdate(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public disconnectedCallback(): void { | ||||
|     super.disconnectedCallback(); | ||||
|     this._stopTTS(); | ||||
|   } | ||||
|  | ||||
|   static styles = css` | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import { | ||||
|   generateEntityFilter, | ||||
|   type EntityFilter, | ||||
| } from "../../../common/entity/entity_filter"; | ||||
| import { floorDefaultIcon } from "../../../components/ha-floor-icon"; | ||||
| import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; | ||||
| import type { LovelaceSectionRawConfig } from "../../../data/lovelace/config/section"; | ||||
| import type { LovelaceViewConfig } from "../../../data/lovelace/config/view"; | ||||
| @@ -99,7 +98,6 @@ export class LightViewStrategy extends ReactiveElement { | ||||
|               floorCount > 1 | ||||
|                 ? floor.name | ||||
|                 : hass.localize("ui.panel.lovelace.strategy.home.areas"), | ||||
|             icon: floor.icon || floorDefaultIcon(floor), | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|   | ||||
| @@ -52,8 +52,6 @@ export class HaLogbook extends LitElement { | ||||
|  | ||||
|   @property({ attribute: false }) public deviceIds?: string[]; | ||||
|  | ||||
|   @property({ attribute: false }) public stateFilter?: string[]; | ||||
|  | ||||
|   @property({ type: Boolean }) public narrow = false; | ||||
|  | ||||
|   @property({ type: Boolean, reflect: true }) public virtualize = false; | ||||
| @@ -167,7 +165,7 @@ export class HaLogbook extends LitElement { | ||||
|   protected willUpdate(changedProps: PropertyValues): void { | ||||
|     let changed = changedProps.has("time"); | ||||
|  | ||||
|     for (const key of ["entityIds", "deviceIds", "stateFilter"]) { | ||||
|     for (const key of ["entityIds", "deviceIds"]) { | ||||
|       if (!changedProps.has(key)) { | ||||
|         continue; | ||||
|       } | ||||
| @@ -354,19 +352,9 @@ export class HaLogbook extends LitElement { | ||||
|       "recent" in this.time | ||||
|         ? findStartOfRecentTime(new Date(), this.time.recent) | ||||
|         : undefined; | ||||
|  | ||||
|     let eventsFiltered: LogbookEntry[] | undefined; | ||||
|     if (this.stateFilter && this.stateFilter.length > 0) { | ||||
|       eventsFiltered = streamMessage.events.filter( | ||||
|         (e) => e.state && this.stateFilter?.includes(e.state) | ||||
|       ); | ||||
|     } else { | ||||
|       eventsFiltered = [...streamMessage.events]; | ||||
|     } | ||||
|  | ||||
|     // Put newest ones on top. Reverse works in-place so | ||||
|     // make a copy first. | ||||
|     const newEntries = eventsFiltered.reverse(); | ||||
|     const newEntries = [...streamMessage.events].reverse(); | ||||
|     if (!this._logbookEntries || !this._logbookEntries.length) { | ||||
|       this._logbookEntries = newEntries; | ||||
|       return; | ||||
|   | ||||
| @@ -94,7 +94,7 @@ class HuiHistoryChartCardFeature | ||||
|     } | ||||
|     if (!this._coordinates) { | ||||
|       return html` | ||||
|         <div class="container loading"> | ||||
|         <div class="container"> | ||||
|           <ha-spinner size="small"></ha-spinner> | ||||
|         </div> | ||||
|       `; | ||||
| @@ -153,14 +153,6 @@ class HuiHistoryChartCardFeature | ||||
|       align-items: flex-end; | ||||
|       pointer-events: none !important; | ||||
|     } | ||||
|  | ||||
|     .container.loading { | ||||
|       width: 100%; | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|     } | ||||
|  | ||||
|     hui-graph-base { | ||||
|       width: 100%; | ||||
|       --accent-color: var(--feature-color); | ||||
|   | ||||
| @@ -35,8 +35,6 @@ import { measureTextWidth } from "../../../../util/text"; | ||||
| import "../../../../components/ha-icon-button"; | ||||
| import { storage } from "../../../../common/decorators/storage"; | ||||
| import { listenMediaQuery } from "../../../../common/dom/media_query"; | ||||
| import { getEnergyColor } from "./common/color"; | ||||
| import type { CustomLegendOption } from "../../../../components/chart/ha-chart-base"; | ||||
|  | ||||
| @customElement("hui-energy-devices-graph-card") | ||||
| export class HuiEnergyDevicesGraphCard | ||||
| @@ -51,8 +49,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|  | ||||
|   @state() private _data?: EnergyData; | ||||
|  | ||||
|   @state() private _legendData: NonNullable<CustomLegendOption["data"]> = []; | ||||
|  | ||||
|   @state() | ||||
|   @storage({ | ||||
|     key: "energy-devices-graph-chart-type", | ||||
| @@ -61,14 +57,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|   }) | ||||
|   private _chartType: "bar" | "pie" = "bar"; | ||||
|  | ||||
|   @state() | ||||
|   @storage({ | ||||
|     key: "energy-devices-pie-hidden-stats", | ||||
|     state: true, | ||||
|     subscribe: false, | ||||
|   }) | ||||
|   private _hiddenStats: string[] = []; | ||||
|  | ||||
|   @state() private _isMobile = false; | ||||
|  | ||||
|   private _compoundStats: string[] = []; | ||||
| @@ -133,16 +121,10 @@ export class HuiEnergyDevicesGraphCard | ||||
|           <ha-chart-base | ||||
|             .hass=${this.hass} | ||||
|             .data=${this._chartData} | ||||
|             .options=${this._createOptions( | ||||
|               this._chartData, | ||||
|               this._chartType, | ||||
|               this._legendData | ||||
|             )} | ||||
|             .height=${`${Math.max(300, (this._legendData?.length || 0) * 28 + 50)}px`} | ||||
|             .extraComponents=${[PieChart]} | ||||
|             .options=${this._createOptions(this._chartData, this._chartType)} | ||||
|             .height=${`${Math.max(300, (this._chartData[0]?.data?.length || 0) * 28 + 50)}px`} | ||||
|             @chart-click=${this._handleChartClick} | ||||
|             @dataset-hidden=${this._datasetHidden} | ||||
|             @dataset-unhidden=${this._datasetUnhidden} | ||||
|             .extraComponents=${[PieChart]} | ||||
|           ></ha-chart-base> | ||||
|         </div> | ||||
|       </ha-card> | ||||
| @@ -163,8 +145,7 @@ export class HuiEnergyDevicesGraphCard | ||||
|   private _createOptions = memoizeOne( | ||||
|     ( | ||||
|       data: (BarSeriesOption | PieSeriesOption)[], | ||||
|       chartType: "bar" | "pie", | ||||
|       legendData: typeof this._legendData | ||||
|       chartType: "bar" | "pie" | ||||
|     ): ECOption => { | ||||
|       const options: ECOption = { | ||||
|         grid: { | ||||
| @@ -180,7 +161,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|         }, | ||||
|         xAxis: { show: false }, | ||||
|         yAxis: { show: false }, | ||||
|         legend: { type: "custom", show: false }, | ||||
|       }; | ||||
|       if (chartType === "bar") { | ||||
|         options.xAxis = { | ||||
| @@ -211,18 +191,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|             ), | ||||
|           }, | ||||
|         }; | ||||
|       } else { | ||||
|         options.legend = { | ||||
|           type: "custom", | ||||
|           show: true, | ||||
|           data: legendData, | ||||
|           selected: legendData | ||||
|             .filter((d) => d.id && this._hiddenStats.includes(d.id)) | ||||
|             .reduce((acc, d) => { | ||||
|               acc[d.id!] = false; | ||||
|               return acc; | ||||
|             }, {}), | ||||
|         }; | ||||
|       } | ||||
|       return options; | ||||
|     } | ||||
| @@ -386,12 +354,23 @@ export class HuiEnergyDevicesGraphCard | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     if (this._chartType === "pie") { | ||||
|       const { summedData, compareSummedData } = getSummedData(energyData); | ||||
|       const { consumption, compareConsumption } = computeConsumptionData( | ||||
|         summedData, | ||||
|         compareSummedData | ||||
|     chartData.sort((a: any, b: any) => b.value[0] - a.value[0]); | ||||
|     if (compareData) { | ||||
|       datasets[1].data = chartData.map((d) => | ||||
|         chartDataCompare.find((d2) => (d2 as any).id === d.id) | ||||
|       ) as typeof chartDataCompare; | ||||
|     } | ||||
|  | ||||
|     datasets.forEach((dataset) => { | ||||
|       dataset.data!.length = Math.min( | ||||
|         this._config?.max_devices || Infinity, | ||||
|         dataset.data!.length | ||||
|       ); | ||||
|     }); | ||||
|  | ||||
|     if (this._chartType === "pie") { | ||||
|       const { summedData } = getSummedData(energyData); | ||||
|       const { consumption } = computeConsumptionData(summedData); | ||||
|       const totalUsed = consumption.total.used_total; | ||||
|       const showUntracked = | ||||
|         "from_grid" in summedData || | ||||
| @@ -401,47 +380,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|         ? totalUsed - | ||||
|           chartData.reduce((acc: number, d: any) => acc + d.value[0], 0) | ||||
|         : 0; | ||||
|       if (untracked > 0) { | ||||
|         const color = getEnergyColor( | ||||
|           computedStyle, | ||||
|           this.hass.themes.darkMode, | ||||
|           false, | ||||
|           false, | ||||
|           "--history-unknown-color" | ||||
|         ); | ||||
|         chartData.push({ | ||||
|           id: "untracked", | ||||
|           value: [untracked, "untracked"] as any, | ||||
|           name: this.hass.localize( | ||||
|             "ui.panel.lovelace.cards.energy.energy_devices_graph.untracked_consumption" | ||||
|           ), | ||||
|           itemStyle: { | ||||
|             color: color + "7F", | ||||
|             borderColor: color, | ||||
|           }, | ||||
|         }); | ||||
|         if (compareData) { | ||||
|           const compareUntracked = | ||||
|             compareConsumption!.total.used_total - | ||||
|             chartDataCompare.reduce( | ||||
|               (acc: number, d: any) => acc + d.value[0], | ||||
|               0 | ||||
|             ); | ||||
|           if (compareUntracked > 0) { | ||||
|             chartDataCompare.push({ | ||||
|               id: "untracked", | ||||
|               value: [compareUntracked, "untracked"] as any, | ||||
|               name: this.hass.localize( | ||||
|                 "ui.panel.lovelace.cards.energy.energy_devices_graph.untracked_consumption" | ||||
|               ), | ||||
|               itemStyle: { | ||||
|                 color: color + "32", | ||||
|                 borderColor: color + "7F", | ||||
|               }, | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       datasets.push({ | ||||
|         type: "pie", | ||||
|         radius: ["0%", compareData ? "30%" : "40%"], | ||||
| @@ -463,36 +401,17 @@ export class HuiEnergyDevicesGraphCard | ||||
|           color: "rgba(0, 0, 0, 0)", | ||||
|         }, | ||||
|         tooltip: { | ||||
|           show: false, | ||||
|           formatter: () => | ||||
|             untracked > 0 | ||||
|               ? this.hass.localize( | ||||
|                   "ui.panel.lovelace.cards.energy.energy_devices_graph.includes_untracked", | ||||
|                   { num: formatNumber(untracked, this.hass.locale) } | ||||
|                 ) | ||||
|               : "", | ||||
|         }, | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     chartData.sort((a: any, b: any) => b.value[0] - a.value[0]); | ||||
|     if ( | ||||
|       this._config?.max_devices && | ||||
|       chartData.length > this._config.max_devices | ||||
|     ) { | ||||
|       chartData.splice(this._config.max_devices); | ||||
|     } | ||||
|  | ||||
|     this._legendData = chartData.map((d) => ({ | ||||
|       ...d, | ||||
|       name: this._getDeviceName(d.name), | ||||
|     })); | ||||
|     // filter out hidden stats in place | ||||
|     for (let i = chartData.length - 1; i >= 0; i--) { | ||||
|       if (this._hiddenStats.includes((chartData[i] as any).id)) { | ||||
|         chartData.splice(i, 1); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (compareData) { | ||||
|       datasets[1].data = chartData.map((d) => | ||||
|         chartDataCompare.find((d2) => (d2 as any).id === d.id) | ||||
|       ) as typeof chartDataCompare; | ||||
|     } | ||||
|  | ||||
|     this._chartData = datasets; | ||||
|     await this.updateComplete; | ||||
|   } | ||||
| @@ -521,18 +440,6 @@ export class HuiEnergyDevicesGraphCard | ||||
|     this._getStatistics(this._data!); | ||||
|   } | ||||
|  | ||||
|   private _datasetHidden(ev: CustomEvent<{ id: string }>) { | ||||
|     this._hiddenStats = [...this._hiddenStats, ev.detail.id]; | ||||
|     this._getStatistics(this._data!); | ||||
|   } | ||||
|  | ||||
|   private _datasetUnhidden(ev: CustomEvent<{ id: string }>) { | ||||
|     this._hiddenStats = this._hiddenStats.filter( | ||||
|       (stat) => stat !== ev.detail.id | ||||
|     ); | ||||
|     this._getStatistics(this._data!); | ||||
|   } | ||||
|  | ||||
|   static styles = css` | ||||
|     .card-header { | ||||
|       display: flex; | ||||
|   | ||||
| @@ -137,7 +137,6 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { | ||||
|           class=${classMap({ | ||||
|             "is-grid": this.layout === "grid", | ||||
|             "is-panel": this.layout === "panel", | ||||
|             "has-title": !!this._config.title, | ||||
|           })} | ||||
|           .narrow=${this._narrow} | ||||
|           .events=${this._events} | ||||
| @@ -230,7 +229,6 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { | ||||
|       padding: 0 8px 8px; | ||||
|       box-sizing: border-box; | ||||
|       height: 100%; | ||||
|       overflow: hidden; | ||||
|     } | ||||
|  | ||||
|     .header { | ||||
| @@ -241,25 +239,15 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { | ||||
|       padding-left: 8px; | ||||
|       padding-inline-start: 8px; | ||||
|       direction: var(--direction); | ||||
|       white-space: nowrap; | ||||
|       text-overflow: ellipsis; | ||||
|     } | ||||
|  | ||||
|     ha-full-calendar { | ||||
|       --calendar-height: 400px; | ||||
|       height: var(--calendar-height); | ||||
|     } | ||||
|  | ||||
|     ha-full-calendar.is-grid, | ||||
|     ha-full-calendar.is-panel { | ||||
|       --calendar-height: calc(100% - 16px); | ||||
|     } | ||||
|  | ||||
|     ha-full-calendar.is-grid.has-title, | ||||
|     ha-full-calendar.is-panel.has-title { | ||||
|       --calendar-height: calc( | ||||
|         100% - var(--ha-card-header-font-size, var(--ha-font-size-2xl)) - 22px | ||||
|       ); | ||||
|       height: calc(100% - 16px); | ||||
|     } | ||||
|   `; | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import type { PropertyValues, TemplateResult } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, state } from "lit/decorators"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { DOMAINS_TOGGLE } from "../../../common/const"; | ||||
| import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; | ||||
| import { computeDomain } from "../../../common/entity/compute_domain"; | ||||
| @@ -20,9 +20,11 @@ import type { | ||||
| import type { | ||||
|   LovelaceCard, | ||||
|   LovelaceCardEditor, | ||||
|   LovelaceGridOptions, | ||||
|   LovelaceHeaderFooter, | ||||
| } from "../types"; | ||||
| import type { EntitiesCardConfig } from "./types"; | ||||
| import { haStyleScrollbar } from "../../../resources/styles"; | ||||
|  | ||||
| export const computeShowHeaderToggle = < | ||||
|   T extends EntityConfig | LovelaceRowConfig, | ||||
| @@ -75,6 +77,8 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { | ||||
|  | ||||
|   private _hass?: HomeAssistant; | ||||
|  | ||||
|   @property({ attribute: false }) public layout?: string; | ||||
|  | ||||
|   private _configEntities?: LovelaceRowConfig[]; | ||||
|  | ||||
|   private _showHeaderToggle?: boolean; | ||||
| @@ -139,6 +143,14 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { | ||||
|     return size; | ||||
|   } | ||||
|  | ||||
|   public getGridOptions(): LovelaceGridOptions { | ||||
|     return { | ||||
|       columns: 12, | ||||
|       min_columns: 6, | ||||
|       min_rows: this._config?.title || this._showHeaderToggle ? 3 : 2, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   public setConfig(config: EntitiesCardConfig): void { | ||||
|     if (!config.entities || !Array.isArray(config.entities)) { | ||||
|       throw new Error("Entities must be specified"); | ||||
| @@ -233,7 +245,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { | ||||
|                     `} | ||||
|               </h1> | ||||
|             `} | ||||
|         <div id="states" class="card-content"> | ||||
|         <div id="states" class="card-content ha-scrollbar"> | ||||
|           ${this._configEntities!.map((entityConf) => | ||||
|             this._renderEntity(entityConf) | ||||
|           )} | ||||
| @@ -246,69 +258,73 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { | ||||
|     `; | ||||
|   } | ||||
|  | ||||
|   static styles = css` | ||||
|     ha-card { | ||||
|       height: 100%; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: space-between; | ||||
|     } | ||||
|     .card-header { | ||||
|       display: flex; | ||||
|       justify-content: space-between; | ||||
|     } | ||||
|   static styles = [ | ||||
|     haStyleScrollbar, | ||||
|     css` | ||||
|       ha-card { | ||||
|         height: 100%; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: space-between; | ||||
|       } | ||||
|       .card-header { | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|       } | ||||
|  | ||||
|     .card-header .name { | ||||
|       white-space: nowrap; | ||||
|       overflow: hidden; | ||||
|       text-overflow: ellipsis; | ||||
|     } | ||||
|       .card-header .name { | ||||
|         white-space: nowrap; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|       } | ||||
|  | ||||
|     #states { | ||||
|       flex: 1; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: var(--entities-card-row-gap, var(--card-row-gap, 8px)); | ||||
|     } | ||||
|       #states { | ||||
|         flex: 1; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         gap: var(--entities-card-row-gap, var(--card-row-gap, 8px)); | ||||
|         overflow-y: auto; | ||||
|       } | ||||
|  | ||||
|     #states > div > * { | ||||
|       overflow: clip visible; | ||||
|     } | ||||
|       #states > div > * { | ||||
|         overflow: clip visible; | ||||
|       } | ||||
|  | ||||
|     #states > div { | ||||
|       position: relative; | ||||
|     } | ||||
|       #states > div { | ||||
|         position: relative; | ||||
|       } | ||||
|  | ||||
|     .icon { | ||||
|       padding: 0px 18px 0px 8px; | ||||
|     } | ||||
|       .icon { | ||||
|         padding: 0px 18px 0px 8px; | ||||
|       } | ||||
|  | ||||
|     .header { | ||||
|       border-top-left-radius: var( | ||||
|         --ha-card-border-radius, | ||||
|         var(--ha-border-radius-lg) | ||||
|       ); | ||||
|       border-top-right-radius: var( | ||||
|         --ha-card-border-radius, | ||||
|         var(--ha-border-radius-lg) | ||||
|       ); | ||||
|       margin-bottom: 16px; | ||||
|       overflow: hidden; | ||||
|     } | ||||
|       .header { | ||||
|         border-top-left-radius: var( | ||||
|           --ha-card-border-radius, | ||||
|           var(--ha-border-radius-lg) | ||||
|         ); | ||||
|         border-top-right-radius: var( | ||||
|           --ha-card-border-radius, | ||||
|           var(--ha-border-radius-lg) | ||||
|         ); | ||||
|         margin-bottom: 16px; | ||||
|         overflow: hidden; | ||||
|       } | ||||
|  | ||||
|     .footer { | ||||
|       border-bottom-left-radius: var( | ||||
|         --ha-card-border-radius, | ||||
|         var(--ha-border-radius-lg) | ||||
|       ); | ||||
|       border-bottom-right-radius: var( | ||||
|         --ha-card-border-radius, | ||||
|         var(--ha-border-radius-lg) | ||||
|       ); | ||||
|       margin-top: -16px; | ||||
|       overflow: hidden; | ||||
|     } | ||||
|   `; | ||||
|       .footer { | ||||
|         border-bottom-left-radius: var( | ||||
|           --ha-card-border-radius, | ||||
|           var(--ha-border-radius-lg) | ||||
|         ); | ||||
|         border-bottom-right-radius: var( | ||||
|           --ha-card-border-radius, | ||||
|           var(--ha-border-radius-lg) | ||||
|         ); | ||||
|         margin-top: -16px; | ||||
|         overflow: hidden; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   private _renderEntity(entityConf: LovelaceRowConfig): TemplateResult { | ||||
|     const element = createRowElement( | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import { classMap } from "lit/directives/class-map"; | ||||
| import { ifDefined } from "lit/directives/if-defined"; | ||||
| import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; | ||||
| import { computeDomain } from "../../../common/entity/compute_domain"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/entity/state-badge"; | ||||
| import "../../../components/ha-card"; | ||||
| import "../../../components/ha-icon"; | ||||
| @@ -18,7 +19,6 @@ import type { | ||||
| import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { actionHandler } from "../common/directives/action-handler-directive"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { findEntities } from "../common/find-entities"; | ||||
| import { handleAction } from "../common/handle-action"; | ||||
| import { hasAction, hasAnyAction } from "../common/has-action"; | ||||
| @@ -252,11 +252,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { | ||||
|       </div>`; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       entityConf.name | ||||
|     ); | ||||
|     const name = entityConf.name ?? computeStateName(stateObj); | ||||
|  | ||||
|     return html` | ||||
|       <div | ||||
|   | ||||
| @@ -3,27 +3,25 @@ import { LitElement, css, html, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { classMap } from "lit/directives/class-map"; | ||||
| import { isComponentLoaded } from "../../../common/config/is_component_loaded"; | ||||
| import { createSearchParam } from "../../../common/url/search-params"; | ||||
| import "../../../components/chart/state-history-charts"; | ||||
| import "../../../components/ha-alert"; | ||||
| import "../../../components/ha-card"; | ||||
| import "../../../components/ha-icon-next"; | ||||
| import { | ||||
|   computeHistory, | ||||
|   convertStatisticsToHistory, | ||||
|   mergeHistoryResults, | ||||
|   subscribeHistoryStatesTimeWindow, | ||||
|   type HistoryResult, | ||||
|   convertStatisticsToHistory, | ||||
|   mergeHistoryResults, | ||||
| } from "../../../data/history"; | ||||
| import { fetchStatistics } from "../../../data/recorder"; | ||||
| import { getSensorNumericDeviceClasses } from "../../../data/sensor"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { hasConfigOrEntitiesChanged } from "../common/has-changed"; | ||||
| import { processConfigEntities } from "../common/process-config-entities"; | ||||
| import type { EntityConfig } from "../entity-rows/types"; | ||||
| import type { LovelaceCard, LovelaceGridOptions } from "../types"; | ||||
| import type { HistoryGraphCardConfig } from "./types"; | ||||
| import { createSearchParam } from "../../../common/url/search-params"; | ||||
| import { fetchStatistics } from "../../../data/recorder"; | ||||
|  | ||||
| export const DEFAULT_HOURS_TO_SHOW = 24; | ||||
|  | ||||
| @@ -53,8 +51,6 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard { | ||||
|  | ||||
|   private _entityIds: string[] = []; | ||||
|  | ||||
|   private _entities: EntityConfig[] = []; | ||||
|  | ||||
|   private _hoursToShow = DEFAULT_HOURS_TO_SHOW; | ||||
|  | ||||
|   private _interval?: number; | ||||
| @@ -84,35 +80,21 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard { | ||||
|       throw new Error("You must include at least one entity"); | ||||
|     } | ||||
|  | ||||
|     this._entities = config.entities | ||||
|     const configEntities = config.entities | ||||
|       ? processConfigEntities(config.entities) | ||||
|       : []; | ||||
|     this._entityIds = this._entities.map((entity) => entity.entity); | ||||
|  | ||||
|     this._entityIds = []; | ||||
|     configEntities.forEach((entity) => { | ||||
|       this._entityIds.push(entity.entity); | ||||
|       if (entity.name) { | ||||
|         this._names[entity.entity] = entity.name; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     this._hoursToShow = config.hours_to_show || DEFAULT_HOURS_TO_SHOW; | ||||
|  | ||||
|     this._config = config; | ||||
|     this._computeNames(); | ||||
|   } | ||||
|  | ||||
|   private _computeNames() { | ||||
|     if (!this.hass || !this._config) { | ||||
|       return; | ||||
|     } | ||||
|     this._names = {}; | ||||
|     this._entities.forEach((entity) => { | ||||
|       const stateObj = this.hass!.states[entity.entity]; | ||||
|       this._names[entity.entity] = stateObj | ||||
|         ? computeLovelaceEntityName(this.hass!, stateObj, entity.name) | ||||
|         : entity.entity; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   public willUpdate(changedProps: PropertyValues) { | ||||
|     super.willUpdate(changedProps); | ||||
|     if (changedProps.has("hass")) { | ||||
|       this._computeNames(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public connectedCallback() { | ||||
|   | ||||
| @@ -64,8 +64,6 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { | ||||
|  | ||||
|   @state() private _targetPickerValue: HassServiceTarget = {}; | ||||
|  | ||||
|   @state() private _stateFilter?: string[]; | ||||
|  | ||||
|   public getCardSize(): number { | ||||
|     return 9 + (this._config?.title ? 1 : 0); | ||||
|   } | ||||
| @@ -131,8 +129,6 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { | ||||
|     }; | ||||
|  | ||||
|     this._targetPickerValue = target; | ||||
|  | ||||
|     this._stateFilter = ensureArray(config.state_filter); | ||||
|   } | ||||
|  | ||||
|   private _getEntityIds(): string[] | undefined { | ||||
| @@ -213,7 +209,6 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { | ||||
|             .hass=${this.hass} | ||||
|             .time=${this._time} | ||||
|             .entityIds=${this._getEntityIds()} | ||||
|             .stateFilter=${this._stateFilter} | ||||
|             narrow | ||||
|             relative-time | ||||
|             virtualize | ||||
|   | ||||
| @@ -35,12 +35,20 @@ import { | ||||
|   hasConfigOrEntitiesChanged, | ||||
| } from "../common/has-changed"; | ||||
| import { processConfigEntities } from "../common/process-config-entities"; | ||||
| import type { EntityConfig } from "../entity-rows/types"; | ||||
| import type { LovelaceCard, LovelaceGridOptions } from "../types"; | ||||
| import type { MapCardConfig, MapEntityConfig } from "./types"; | ||||
| import type { MapCardConfig } from "./types"; | ||||
|  | ||||
| export const DEFAULT_HOURS_TO_SHOW = 0; | ||||
| export const DEFAULT_ZOOM = 14; | ||||
|  | ||||
| interface MapEntityConfig extends EntityConfig { | ||||
|   label_mode?: "state" | "attribute" | "name"; | ||||
|   attribute?: string; | ||||
|   unit?: string; | ||||
|   focus?: boolean; | ||||
| } | ||||
|  | ||||
| interface GeoEntity { | ||||
|   entity_id: string; | ||||
|   label_mode?: "state" | "attribute" | "name" | "icon"; | ||||
|   | ||||
| @@ -20,15 +20,14 @@ import { | ||||
| } from "../../../data/recorder"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { computeCardSize } from "../common/compute-card-size"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { findEntities } from "../common/find-entities"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import { createHeaderFooterElement } from "../create-element/create-header-footer-element"; | ||||
| import type { | ||||
|   LovelaceCard, | ||||
|   LovelaceCardEditor, | ||||
|   LovelaceGridOptions, | ||||
|   LovelaceHeaderFooter, | ||||
|   LovelaceGridOptions, | ||||
| } from "../types"; | ||||
| import type { HuiErrorCard } from "./hui-error-card"; | ||||
| import type { EntityCardConfig, StatisticCardConfig } from "./types"; | ||||
| @@ -181,9 +180,7 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard { | ||||
|  | ||||
|     const stateObj = this.hass.states[this._config.entity]; | ||||
|     const name = | ||||
|       (this._config.name | ||||
|         ? computeLovelaceEntityName(this.hass, stateObj, this._config.name) | ||||
|         : "") || | ||||
|       this._config.name || | ||||
|       getStatisticLabel(this.hass, this._config.entity, this._metadata); | ||||
|  | ||||
|     return html` | ||||
|   | ||||
| @@ -1,11 +1,15 @@ | ||||
| import { differenceInDays, subHours } from "date-fns"; | ||||
| import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; | ||||
| import { subHours, differenceInDays } from "date-fns"; | ||||
| import type { PropertyValues } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { classMap } from "lit/directives/class-map"; | ||||
| import "../../../components/ha-card"; | ||||
| import { getEnergyDataCollection } from "../../../data/energy"; | ||||
| import { | ||||
|   getSuggestedMax, | ||||
|   getSuggestedPeriod, | ||||
| } from "./energy/common/energy-chart-options"; | ||||
| import type { | ||||
|   Statistics, | ||||
|   StatisticsMetaData, | ||||
| @@ -17,16 +21,10 @@ import { | ||||
|   getStatisticMetadata, | ||||
| } from "../../../data/recorder"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { findEntities } from "../common/find-entities"; | ||||
| import { hasConfigOrEntitiesChanged } from "../common/has-changed"; | ||||
| import { processConfigEntities } from "../common/process-config-entities"; | ||||
| import type { EntityConfig } from "../entity-rows/types"; | ||||
| import type { LovelaceCard, LovelaceGridOptions } from "../types"; | ||||
| import { | ||||
|   getSuggestedMax, | ||||
|   getSuggestedPeriod, | ||||
| } from "./energy/common/energy-chart-options"; | ||||
| import type { StatisticsGraphCardConfig } from "./types"; | ||||
|  | ||||
| export const DEFAULT_DAYS_TO_SHOW = 30; | ||||
| @@ -69,9 +67,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|  | ||||
|   @state() private _unit?: string; | ||||
|  | ||||
|   private _entities: EntityConfig[] = []; | ||||
|  | ||||
|   private _entityIds: string[] = []; | ||||
|   private _entities: string[] = []; | ||||
|  | ||||
|   private _names: Record<string, string> = {}; | ||||
|  | ||||
| @@ -152,10 +148,17 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|       throw new Error("You must include at least one entity"); | ||||
|     } | ||||
|  | ||||
|     this._entities = config.entities | ||||
|     const configEntities = config.entities | ||||
|       ? processConfigEntities(config.entities, false) | ||||
|       : []; | ||||
|     this._entityIds = this._entities.map((ent) => ent.entity); | ||||
|  | ||||
|     this._entities = []; | ||||
|     configEntities.forEach((entity) => { | ||||
|       this._entities.push(entity.entity); | ||||
|       if (entity.name) { | ||||
|         this._names[entity.entity] = entity.name; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     if (typeof config.stat_types === "string") { | ||||
|       this._statTypes = [config.stat_types]; | ||||
| @@ -165,20 +168,6 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|       this._statTypes = config.stat_types; | ||||
|     } | ||||
|     this._config = config; | ||||
|     this._computeNames(); | ||||
|   } | ||||
|  | ||||
|   private _computeNames() { | ||||
|     if (!this.hass || !this._config) { | ||||
|       return; | ||||
|     } | ||||
|     this._names = {}; | ||||
|     this._entities.forEach((config) => { | ||||
|       const stateObj = this.hass!.states[config.entity]; | ||||
|       this._names[config.entity] = stateObj | ||||
|         ? computeLovelaceEntityName(this.hass!, stateObj, config.name) | ||||
|         : config.entity; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   protected shouldUpdate(changedProps: PropertyValues): boolean { | ||||
| @@ -220,10 +209,6 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (changedProps.has("hass")) { | ||||
|       this._computeNames(); | ||||
|     } | ||||
|  | ||||
|     if ( | ||||
|       changedProps.has("_config") && | ||||
|       oldConfig?.entities !== this._config.entities | ||||
| @@ -247,7 +232,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|     clearInterval(this._interval); | ||||
|     this._interval = 0; // block concurrent calls | ||||
|     if (fetchMetadata) { | ||||
|       await this._getStatisticsMetaData(this._entityIds); | ||||
|       await this._getStatisticsMetaData(this._entities); | ||||
|     } | ||||
|     await this._getStatistics(); | ||||
|     // statistics are created every hour | ||||
| @@ -359,7 +344,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|         } | ||||
|       } | ||||
|       if (!unitClass && this._metadata) { | ||||
|         const metadata = this._metadata[this._entityIds[0]]; | ||||
|         const metadata = this._metadata[this._entities[0]]; | ||||
|         unitClass = metadata?.unit_class; | ||||
|         this._unit = unitClass | ||||
|           ? getDisplayUnit(this.hass!, metadata.statistic_id, metadata) || | ||||
| @@ -371,15 +356,14 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { | ||||
|         this.hass!, | ||||
|         startDate, | ||||
|         endDate, | ||||
|         this._entityIds, | ||||
|         this._entities, | ||||
|         this._period, | ||||
|         unitconfig, | ||||
|         this._statTypes | ||||
|       ); | ||||
|  | ||||
|       this._statistics = {}; | ||||
|       this._entities.forEach((entity) => { | ||||
|         const id = entity.entity; | ||||
|       this._entities.forEach((id) => { | ||||
|         if (id in statistics) { | ||||
|           this._statistics![id] = statistics[id]; | ||||
|         } | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import type { EnergySourceByType } from "../../../data/energy"; | ||||
| import type { ActionConfig } from "../../../data/lovelace/config/action"; | ||||
| import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; | ||||
| import type { Statistic, StatisticType } from "../../../data/recorder"; | ||||
| import type { MediaSelectorValue } from "../../../data/selector"; | ||||
| import type { TimeFormat } from "../../../data/translation"; | ||||
| import type { ForecastType } from "../../../data/weather"; | ||||
| import type { | ||||
| @@ -30,6 +29,7 @@ import type { | ||||
| import type { LovelaceHeaderFooterConfig } from "../header-footer/types"; | ||||
| import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types"; | ||||
| import type { HomeSummary } from "../strategies/home/helpers/home-summaries"; | ||||
| import type { MediaSelectorValue } from "../../../data/selector"; | ||||
|  | ||||
| export type AlarmPanelCardConfigState = | ||||
|   | "arm_away" | ||||
| @@ -345,18 +345,9 @@ export interface LogbookCardConfig extends LovelaceCardConfig { | ||||
|   title?: string; | ||||
|   hours_to_show?: number; | ||||
|   theme?: string; | ||||
|   state_filter?: string[]; | ||||
| } | ||||
|  | ||||
| export interface MapEntityConfig extends EntityConfig { | ||||
|   label_mode?: "state" | "attribute" | "name"; | ||||
|   attribute?: string; | ||||
|   unit?: string; | ||||
|   focus?: boolean; | ||||
|   name?: string; | ||||
| } | ||||
|  | ||||
| export interface GeoLocationSourceConfig { | ||||
| interface GeoLocationSourceConfig { | ||||
|   source: string; | ||||
|   label_mode?: "name" | "state" | "attribute" | "icon"; | ||||
|   attribute?: string; | ||||
| @@ -371,7 +362,7 @@ export interface MapCardConfig extends LovelaceCardConfig { | ||||
|   auto_fit?: boolean; | ||||
|   fit_zones?: boolean; | ||||
|   default_zoom?: number; | ||||
|   entities?: (MapEntityConfig | string)[]; | ||||
|   entities?: (EntityConfig | string)[]; | ||||
|   hours_to_show?: number; | ||||
|   geo_location_sources?: (GeoLocationSourceConfig | string)[]; | ||||
|   dark_mode?: boolean; | ||||
| @@ -443,7 +434,7 @@ export interface StatisticsGraphCardConfig extends EnergyCardBaseConfig { | ||||
| } | ||||
|  | ||||
| export interface StatisticCardConfig extends LovelaceCardConfig { | ||||
|   name?: string | EntityNameItem | EntityNameItem[]; | ||||
|   name?: string; | ||||
|   entities: (EntityConfig | string)[]; | ||||
|   period: | ||||
|     | { | ||||
|   | ||||
| @@ -1,29 +1,28 @@ | ||||
| import type { HassEntity } from "home-assistant-js-websocket"; | ||||
| import { ensureArray } from "../../../../common/array/ensure-array"; | ||||
| import type { EntityNameItem } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import { computeStateName } from "../../../../common/entity/compute_state_name"; | ||||
| import { | ||||
|   DEFAULT_ENTITY_NAME, | ||||
|   type EntityNameItem, | ||||
| } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { HomeAssistant } from "../../../../types"; | ||||
| import { ensureArray } from "../../../../common/array/ensure-array"; | ||||
|  | ||||
| /** | ||||
|  * Computes the display name for an entity in Lovelace (cards and badges). | ||||
|  * | ||||
|  * @param hass - The Home Assistant instance | ||||
|  * @param stateObj - The entity state object | ||||
|  * @param config - The name configuration (string for override, or EntityNameItem[] for structured naming) | ||||
|  * @param nameConfig - The name configuration (string for override, or EntityNameItem[] for structured naming) | ||||
|  * @returns The computed entity name | ||||
|  */ | ||||
| export const computeLovelaceEntityName = ( | ||||
|   hass: HomeAssistant, | ||||
|   stateObj: HassEntity | undefined, | ||||
|   config: string | EntityNameItem | EntityNameItem[] | undefined | ||||
|   nameConfig: string | EntityNameItem | EntityNameItem[] | undefined | ||||
| ): string => { | ||||
|   // If no config is provided, fall back to the default state name | ||||
|   if (!config) { | ||||
|     return stateObj ? computeStateName(stateObj) : ""; | ||||
|   } | ||||
|   if (typeof config === "string") { | ||||
|     return config; | ||||
|   if (typeof nameConfig === "string") { | ||||
|     return nameConfig; | ||||
|   } | ||||
|   const config = nameConfig || DEFAULT_ENTITY_NAME; | ||||
|   if (stateObj) { | ||||
|     return hass.formatEntityName(stateObj, config); | ||||
|   } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import type { HassEntities, HassEntity } from "home-assistant-js-websocket"; | ||||
| import { ASSIST_ENTITIES, SENSOR_ENTITIES } from "../../../common/const"; | ||||
| import { SENSOR_ENTITIES, ASSIST_ENTITIES } from "../../../common/const"; | ||||
| import { computeDomain } from "../../../common/entity/compute_domain"; | ||||
| import { computeStateDomain } from "../../../common/entity/compute_state_domain"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| @@ -14,14 +14,12 @@ import type { | ||||
|   GridSourceTypeEnergyPreference, | ||||
| } from "../../../data/energy"; | ||||
| import { domainToName } from "../../../data/integration"; | ||||
| import type { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge"; | ||||
| import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; | ||||
| import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section"; | ||||
| import type { LovelaceViewConfig } from "../../../data/lovelace/config/view"; | ||||
| import { computeUserInitials } from "../../../data/user"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { HELPER_DOMAINS } from "../../config/helpers/const"; | ||||
| import type { EntityBadgeConfig } from "../badges/types"; | ||||
| import type { | ||||
|   AlarmPanelCardConfig, | ||||
|   EntitiesCardConfig, | ||||
| @@ -33,7 +31,8 @@ import type { | ||||
| } from "../cards/types"; | ||||
| import type { EntityConfig } from "../entity-rows/types"; | ||||
| import type { ButtonsHeaderFooterConfig } from "../header-footer/types"; | ||||
| import { computeLovelaceEntityName } from "./entity/compute-lovelace-entity-name"; | ||||
| import type { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge"; | ||||
| import type { EntityBadgeConfig } from "../badges/types"; | ||||
|  | ||||
| const HIDE_DOMAIN = new Set([ | ||||
|   "ai_task", | ||||
| @@ -126,13 +125,13 @@ export const computeSection = ( | ||||
| }); | ||||
|  | ||||
| export const computeCards = ( | ||||
|   hass: HomeAssistant, | ||||
|   states: HassEntities, | ||||
|   entityIds: string[], | ||||
|   entityCardOptions: Partial<EntitiesCardConfig>, | ||||
|   renderFooterEntities = true | ||||
| ): LovelaceCardConfig[] => { | ||||
|   const cards: LovelaceCardConfig[] = []; | ||||
|   const states = hass.states; | ||||
|  | ||||
|   // For entity card | ||||
|   const entitiesConf: (string | EntityConfig)[] = []; | ||||
|  | ||||
| @@ -271,23 +270,19 @@ export const computeCards = ( | ||||
|         ? states[a] | ||||
|           ? computeStateName(states[a]) | ||||
|           : "" | ||||
|         : states[a.entity] | ||||
|           ? computeLovelaceEntityName(hass, states[a.entity], a.name) | ||||
|           : "", | ||||
|         : a.name || "", | ||||
|       typeof b === "string" | ||||
|         ? states[b] | ||||
|           ? computeStateName(states[b]) | ||||
|           : "" | ||||
|         : states[b.entity] | ||||
|           ? computeLovelaceEntityName(hass, states[b.entity], b.name) | ||||
|           : "" | ||||
|         : b.name || "" | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   // If we ended up with footer entities but no normal entities, | ||||
|   // render the footer entities as normal entities. | ||||
|   if (entitiesConf.length === 0 && footerEntities.length > 0) { | ||||
|     return computeCards(hass, entityIds, entityCardOptions, false); | ||||
|     return computeCards(states, entityIds, entityCardOptions, false); | ||||
|   } | ||||
|  | ||||
|   if (entitiesConf.length > 0 || footerEntities.length > 0) { | ||||
| @@ -365,14 +360,14 @@ const computeDefaultViewStates = ( | ||||
| }; | ||||
|  | ||||
| export const generateViewConfig = ( | ||||
|   hass: HomeAssistant, | ||||
|   localize: LocalizeFunc, | ||||
|   path: string, | ||||
|   title: string | undefined, | ||||
|   icon: string | undefined, | ||||
|   entities: HassEntities | ||||
| ): LovelaceViewConfig => { | ||||
|   const ungroupedEntitites: Record<string, string[]> = {}; | ||||
|   const { localize } = hass; | ||||
|  | ||||
|   // Organize ungrouped entities in ungrouped things | ||||
|   for (const entityId of Object.keys(entities)) { | ||||
|     const state = entities[entityId]; | ||||
| @@ -475,7 +470,7 @@ export const generateViewConfig = ( | ||||
|     .forEach((domain) => { | ||||
|       cards.push( | ||||
|         ...computeCards( | ||||
|           hass, | ||||
|           entities, | ||||
|           ungroupedEntitites[domain].sort((a, b) => | ||||
|             stringCompare( | ||||
|               computeStateName(entities[a]), | ||||
| @@ -503,17 +498,16 @@ export const generateViewConfig = ( | ||||
| }; | ||||
|  | ||||
| export const generateDefaultViewConfig = ( | ||||
|   hass: HomeAssistant, | ||||
|   areaEntries: HomeAssistant["areas"], | ||||
|   deviceEntries: HomeAssistant["devices"], | ||||
|   entityEntries: HomeAssistant["entities"], | ||||
|   entities: HassEntities, | ||||
|   localize: LocalizeFunc, | ||||
|   energyPrefs?: EnergyPreferences, | ||||
|   areasPrefs?: AreasDisplayValue, | ||||
|   hideEntitiesWithoutAreas?: boolean, | ||||
|   hideEnergy?: boolean | ||||
| ): LovelaceViewConfig => { | ||||
|   const entities = hass.states; | ||||
|   const areaEntries = hass.areas; | ||||
|   const deviceEntries = hass.devices; | ||||
|   const entityEntries = hass.entities; | ||||
|   const states = computeDefaultViewStates(entities, entityEntries); | ||||
|   const path = "default_view"; | ||||
|   const title = "Home"; | ||||
| @@ -555,7 +549,7 @@ export const generateDefaultViewConfig = ( | ||||
|  | ||||
|   for (const groupEntity of splittedByGroups.groups) { | ||||
|     groupCards.push( | ||||
|       ...computeCards(hass, groupEntity.attributes.entity_id, { | ||||
|       ...computeCards(entities, groupEntity.attributes.entity_id, { | ||||
|         title: computeStateName(groupEntity), | ||||
|         show_header_toggle: groupEntity.attributes.control !== "hidden", | ||||
|       }) | ||||
| @@ -563,7 +557,7 @@ export const generateDefaultViewConfig = ( | ||||
|   } | ||||
|  | ||||
|   const config = generateViewConfig( | ||||
|     hass, | ||||
|     localize, | ||||
|     path, | ||||
|     title, | ||||
|     icon, | ||||
| @@ -581,7 +575,7 @@ export const generateDefaultViewConfig = ( | ||||
|     const area = areaEntries[areaId]; | ||||
|     areaCards.push( | ||||
|       ...computeCards( | ||||
|         hass, | ||||
|         entities, | ||||
|         areaEntities.map((entity) => entity.entity_id), | ||||
|         { | ||||
|           title: area.name, | ||||
| @@ -607,7 +601,7 @@ export const generateDefaultViewConfig = ( | ||||
|     const device = deviceEntries[deviceId]; | ||||
|     deviceCards.push( | ||||
|       ...computeCards( | ||||
|         hass, | ||||
|         entities, | ||||
|         deviceEntities.map((entity) => entity.entity_id), | ||||
|         { | ||||
|           title: | ||||
|   | ||||
| @@ -2,12 +2,8 @@ | ||||
| import { isValidEntityId } from "../../../common/entity/valid_entity_id"; | ||||
| import type { EntityConfig, LovelaceRowConfig } from "../entity-rows/types"; | ||||
|  | ||||
| interface BaseEntityConfig { | ||||
|   type: string; | ||||
|   entity: string; | ||||
| } | ||||
| export const processConfigEntities = < | ||||
|   T extends BaseEntityConfig | LovelaceRowConfig, | ||||
|   T extends EntityConfig | LovelaceRowConfig, | ||||
| >( | ||||
|   entities: (T | string)[], | ||||
|   checkEntityId = true | ||||
|   | ||||
| @@ -45,13 +45,14 @@ export class HuiEntityEditor extends LitElement { | ||||
|       this.hass.devices | ||||
|     ); | ||||
|  | ||||
|     const name = this.hass.formatEntityName( | ||||
|       stateObj, | ||||
|       useDeviceName ? { type: "device" } : { type: "entity" } | ||||
|     ); | ||||
|  | ||||
|     const isRTL = computeRTL(this.hass); | ||||
|  | ||||
|     const primary = | ||||
|       this.hass.formatEntityName( | ||||
|         stateObj, | ||||
|         useDeviceName ? { type: "device" } : { type: "entity" } | ||||
|       ) || item.entity; | ||||
|     const primary = item.name || name || item.entity; | ||||
|  | ||||
|     const secondary = this.hass.formatEntityName( | ||||
|       stateObj, | ||||
|   | ||||
| @@ -4,19 +4,19 @@ import { customElement, property } from "lit/decorators"; | ||||
| import { classMap } from "lit/directives/class-map"; | ||||
| import { ifDefined } from "lit/directives/if-defined"; | ||||
| import { DOMAINS_INPUT_ROW } from "../../../common/const"; | ||||
| import { stopPropagation } from "../../../common/dom/stop_propagation"; | ||||
| import { toggleAttribute } from "../../../common/dom/toggle_attribute"; | ||||
| import { computeDomain } from "../../../common/entity/compute_domain"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/entity/state-badge"; | ||||
| import "../../../components/ha-relative-time"; | ||||
| import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import type { EntitiesCardEntityConfig } from "../cards/types"; | ||||
| import { actionHandler } from "../common/directives/action-handler-directive"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { handleAction } from "../common/handle-action"; | ||||
| import { hasAction, hasAnyAction } from "../common/has-action"; | ||||
| import { createEntityNotFoundWarning } from "./hui-warning"; | ||||
| import { stopPropagation } from "../../../common/dom/stop_propagation"; | ||||
|  | ||||
| @customElement("hui-generic-entity-row") | ||||
| export class HuiGenericEntityRow extends LitElement { | ||||
| @@ -59,11 +59,7 @@ export class HuiGenericEntityRow extends LitElement { | ||||
|     const pointer = hasAnyAction(this.config); | ||||
|  | ||||
|     const hasSecondary = this.secondaryText || this.config.secondary_info; | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass, | ||||
|       stateObj, | ||||
|       this.config.name | ||||
|     ); | ||||
|     const name = this.config.name ?? computeStateName(stateObj); | ||||
|  | ||||
|     return html` | ||||
|       <div | ||||
| @@ -91,7 +87,7 @@ export class HuiGenericEntityRow extends LitElement { | ||||
|               class="info ${classMap({ "text-content": !hasSecondary })}" | ||||
|               .title=${name} | ||||
|             > | ||||
|               ${name} | ||||
|               ${this.config.name || computeStateName(stateObj)} | ||||
|               ${hasSecondary | ||||
|                 ? html` | ||||
|                     <div class="secondary"> | ||||
|   | ||||
| @@ -296,7 +296,11 @@ export class HuiCreateDialogCard | ||||
|   } | ||||
|  | ||||
|   private _suggestCards(): void { | ||||
|     const cardConfig = computeCards(this.hass, this._selectedEntities, {}); | ||||
|     const cardConfig = computeCards( | ||||
|       this.hass.states, | ||||
|       this._selectedEntities, | ||||
|       {} | ||||
|     ); | ||||
|  | ||||
|     let sectionOptions: Partial<LovelaceSectionConfig> = {}; | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { array, assert, assign, object, optional, string } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import { supportsFeature } from "../../../../common/entity/supports-feature"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| @@ -64,7 +65,9 @@ export class HuiAlarmPanelCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import { customElement, property, state } from "lit/decorators"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { assert, assign, boolean, object, optional, string } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { | ||||
|   HaFormSchema, | ||||
| @@ -72,7 +73,7 @@ export class HuiButtonCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { default_name: DEFAULT_ENTITY_NAME }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import { | ||||
|   string, | ||||
|   union, | ||||
| } from "superstruct"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| @@ -85,7 +86,9 @@ export class HuiEntityBadgeEditor | ||||
|             { | ||||
|               name: "name", | ||||
|               selector: { | ||||
|                 entity_name: {}, | ||||
|                 entity_name: { | ||||
|                   default_name: DEFAULT_ENTITY_NAME, | ||||
|                 }, | ||||
|               }, | ||||
|               context: { entity: "entity" }, | ||||
|             }, | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { assert, assign, boolean, object, optional, string } from "superstruct"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import type { HaFormSchema } from "../../../../components/ha-form/types"; | ||||
| import { headerFooterConfigStructs } from "../../header-footer/structs"; | ||||
| @@ -25,7 +26,9 @@ const SCHEMA = [ | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { | ||||
|       entity_name: {}, | ||||
|       entity_name: { | ||||
|         default_name: DEFAULT_ENTITY_NAME, | ||||
|       }, | ||||
|     }, | ||||
|     context: { entity: "entity" }, | ||||
|   }, | ||||
|   | ||||
| @@ -14,6 +14,7 @@ import { | ||||
|   string, | ||||
| } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import { NON_NUMERIC_ATTRIBUTES } from "../../../../data/entity_attributes"; | ||||
| @@ -101,7 +102,9 @@ export class HuiGaugeCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -46,18 +46,20 @@ export class HuiGenericEntityRowEditor | ||||
|     return [ | ||||
|       { name: "entity", required: true, selector: { entity: {} } }, | ||||
|       { | ||||
|         name: "name", | ||||
|         selector: { entity_name: {} }, | ||||
|         context: { entity: "entity" }, | ||||
|       }, | ||||
|       { | ||||
|         name: "icon", | ||||
|         selector: { | ||||
|           icon: {}, | ||||
|         }, | ||||
|         context: { | ||||
|           icon_entity: "entity", | ||||
|         }, | ||||
|         type: "grid", | ||||
|         name: "", | ||||
|         schema: [ | ||||
|           { name: "name", selector: { text: {} } }, | ||||
|           { | ||||
|             name: "icon", | ||||
|             selector: { | ||||
|               icon: {}, | ||||
|             }, | ||||
|             context: { | ||||
|               icon_entity: "entity", | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|       { | ||||
|         name: "secondary_info", | ||||
|   | ||||
| @@ -11,20 +11,20 @@ import { | ||||
|   string, | ||||
|   union, | ||||
| } from "superstruct"; | ||||
| import type { HASSDomEvent } from "../../../../common/dom/fire_event"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import "../hui-sub-element-editor"; | ||||
| import type { EditDetailElementEvent, SubElementEditorConfig } from "../types"; | ||||
| import type { HASSDomEvent } from "../../../../common/dom/fire_event"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import type { HomeAssistant } from "../../../../types"; | ||||
| import type { ConfigEntity, GlanceCardConfig } from "../../cards/types"; | ||||
| import "../../components/hui-entity-editor"; | ||||
| import type { EntityConfig } from "../../entity-rows/types"; | ||||
| import type { LovelaceCardEditor } from "../../types"; | ||||
| import "../hui-sub-element-editor"; | ||||
| import { processEditorEntities } from "../process-editor-entities"; | ||||
| import { baseLovelaceCardConfig } from "../structs/base-card-struct"; | ||||
| import { entitiesConfigStruct } from "../structs/entities-struct"; | ||||
| import type { EditDetailElementEvent, SubElementEditorConfig } from "../types"; | ||||
| import type { EntityConfig } from "../../entity-rows/types"; | ||||
|  | ||||
| const cardConfigStruct = assign( | ||||
|   baseLovelaceCardConfig, | ||||
| @@ -42,17 +42,11 @@ const cardConfigStruct = assign( | ||||
|  | ||||
| const SUB_SCHEMA = [ | ||||
|   { name: "entity", selector: { entity: {} }, required: true }, | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { entity_name: {} }, | ||||
|     context: { | ||||
|       entity: "entity", | ||||
|     }, | ||||
|   }, | ||||
|   { | ||||
|     type: "grid", | ||||
|     name: "", | ||||
|     schema: [ | ||||
|       { name: "name", selector: { text: {} } }, | ||||
|       { | ||||
|         name: "icon", | ||||
|         selector: { | ||||
|   | ||||
| @@ -45,13 +45,7 @@ const cardConfigStruct = assign( | ||||
|  | ||||
| const SUB_SCHEMA = [ | ||||
|   { name: "entity", selector: { entity: {} }, required: true }, | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { entity_name: {} }, | ||||
|     context: { | ||||
|       entity: "entity", | ||||
|     }, | ||||
|   }, | ||||
|   { name: "name", selector: { text: {} } }, | ||||
| ] as const; | ||||
|  | ||||
| @customElement("hui-history-graph-card-editor") | ||||
|   | ||||
| @@ -14,6 +14,7 @@ import { | ||||
| } from "superstruct"; | ||||
| import type { HASSDomEvent } from "../../../../common/dom/fire_event"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-expansion-panel"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { | ||||
| @@ -60,7 +61,9 @@ const SCHEMA = [ | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { | ||||
|       entity_name: {}, | ||||
|       entity_name: { | ||||
|         default_name: DEFAULT_ENTITY_NAME, | ||||
|       }, | ||||
|     }, | ||||
|     context: { entity: "entity" }, | ||||
|   }, | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| import { mdiGestureTap } from "@mdi/js"; | ||||
| import type { CSSResultGroup } from "lit"; | ||||
| import { html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { assert, assign, object, optional, string } from "superstruct"; | ||||
| import { mdiGestureTap } from "@mdi/js"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import type { HomeAssistant } from "../../../../types"; | ||||
| @@ -36,7 +37,9 @@ const SCHEMA = [ | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { | ||||
|       entity_name: {}, | ||||
|       entity_name: { | ||||
|         default_name: DEFAULT_ENTITY_NAME, | ||||
|       }, | ||||
|     }, | ||||
|     context: { entity: "entity" }, | ||||
|   }, | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import { | ||||
|   string, | ||||
| } from "superstruct"; | ||||
| import type { HassServiceTarget } from "home-assistant-js-websocket"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import "../../../../components/entity/ha-entities-picker"; | ||||
| import "../../../../components/ha-target-picker"; | ||||
| @@ -25,7 +24,6 @@ import { DEFAULT_HOURS_TO_SHOW } from "../../cards/hui-logbook-card"; | ||||
| import { targetStruct } from "../../../../data/script"; | ||||
| import { getSensorNumericDeviceClasses } from "../../../../data/sensor"; | ||||
| import type { HaEntityPickerEntityFilterFunc } from "../../../../data/entity"; | ||||
| import { resolveEntityIDs } from "../../../../data/selector"; | ||||
|  | ||||
| const cardConfigStruct = assign( | ||||
|   baseLovelaceCardConfig, | ||||
| @@ -35,7 +33,6 @@ const cardConfigStruct = assign( | ||||
|     hours_to_show: optional(number()), | ||||
|     theme: optional(string()), | ||||
|     target: optional(targetStruct), | ||||
|     state_filter: optional(array(string())), | ||||
|   }) | ||||
| ); | ||||
|  | ||||
| @@ -53,13 +50,6 @@ const SCHEMA = [ | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     name: "state_filter", | ||||
|     context: { | ||||
|       filter_entity: "context_entities", | ||||
|     }, | ||||
|     selector: { state: { multiple: true } }, | ||||
|   }, | ||||
| ] as const; | ||||
|  | ||||
| @customElement("hui-logbook-card-editor") | ||||
| @@ -116,13 +106,7 @@ export class HuiLogbookCardEditor | ||||
|     return html` | ||||
|       <ha-form | ||||
|         .hass=${this.hass} | ||||
|         .data=${this._data( | ||||
|           this._config, | ||||
|           this._targetPicker, | ||||
|           this.hass.entities, | ||||
|           this.hass.devices, | ||||
|           this.hass.areas | ||||
|         )} | ||||
|         .data=${this._config} | ||||
|         .schema=${SCHEMA} | ||||
|         .computeLabel=${this._computeLabelCallback} | ||||
|         @value-changed=${this._valueChanged} | ||||
| @@ -138,25 +122,6 @@ export class HuiLogbookCardEditor | ||||
|     `; | ||||
|   } | ||||
|  | ||||
|   private _data = memoizeOne( | ||||
|     ( | ||||
|       config: LogbookCardConfig, | ||||
|       target: HassServiceTarget, | ||||
|       entities: HomeAssistant["entities"], | ||||
|       devices: HomeAssistant["devices"], | ||||
|       areas: HomeAssistant["areas"] | ||||
|     ) => ({ | ||||
|       ...config, | ||||
|       context_entities: resolveEntityIDs( | ||||
|         this.hass!, | ||||
|         target, | ||||
|         entities, | ||||
|         devices, | ||||
|         areas | ||||
|       ), | ||||
|     }) | ||||
|   ); | ||||
|  | ||||
|   private _filterFunc: HaEntityPickerEntityFilterFunc = (entity) => | ||||
|     filterLogbookCompatibleEntities(entity, this._sensorNumericDeviceClasses); | ||||
|  | ||||
| @@ -166,9 +131,7 @@ export class HuiLogbookCardEditor | ||||
|   } | ||||
|  | ||||
|   private _valueChanged(ev: CustomEvent): void { | ||||
|     const newConfig = { ...ev.detail.value }; | ||||
|     delete newConfig.context_entities; | ||||
|     fireEvent(this, "config-changed", { config: newConfig }); | ||||
|     fireEvent(this, "config-changed", { config: ev.detail.value }); | ||||
|   } | ||||
|  | ||||
|   private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => { | ||||
| @@ -179,10 +142,6 @@ export class HuiLogbookCardEditor | ||||
|         )} (${this.hass!.localize( | ||||
|           "ui.panel.lovelace.editor.card.config.optional" | ||||
|         )})`; | ||||
|       case "state_filter": | ||||
|         return this.hass!.localize( | ||||
|           "ui.panel.lovelace.editor.card.logbook.state_filter" | ||||
|         ); | ||||
|       default: | ||||
|         return this.hass!.localize( | ||||
|           `ui.panel.lovelace.editor.card.generic.${schema.name}` | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import { mdiPalette } from "@mdi/js"; | ||||
| import type { CSSResultGroup } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { | ||||
|   array, | ||||
|   assert, | ||||
| @@ -14,19 +13,19 @@ import { | ||||
|   string, | ||||
|   union, | ||||
| } from "superstruct"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { computeDomain } from "../../../../common/entity/compute_domain"; | ||||
| import { hasLocation } from "../../../../common/entity/has_location"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import { computeDomain } from "../../../../common/entity/compute_domain"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import "../../../../components/ha-formfield"; | ||||
| import "../../../../components/ha-selector/ha-selector-select"; | ||||
| import "../../../../components/ha-switch"; | ||||
| import type { SelectSelector } from "../../../../data/selector"; | ||||
| import "../../../../components/ha-formfield"; | ||||
| import "../../../../components/ha-switch"; | ||||
| import "../../../../components/ha-selector/ha-selector-select"; | ||||
| import type { HomeAssistant, ValueChangedEvent } from "../../../../types"; | ||||
| import { DEFAULT_HOURS_TO_SHOW, DEFAULT_ZOOM } from "../../cards/hui-map-card"; | ||||
| import type { MapCardConfig, MapEntityConfig } from "../../cards/types"; | ||||
| import type { MapCardConfig } from "../../cards/types"; | ||||
| import "../../components/hui-entity-editor"; | ||||
| import type { EntityConfig } from "../../entity-rows/types"; | ||||
| import type { LovelaceCardEditor } from "../../types"; | ||||
| @@ -34,6 +33,7 @@ import { processEditorEntities } from "../process-editor-entities"; | ||||
| import { baseLovelaceCardConfig } from "../structs/base-card-struct"; | ||||
| import type { EntitiesEditorEvent } from "../types"; | ||||
| import { configElementStyle } from "./config-elements-style"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
|  | ||||
| export const mapEntitiesConfigStruct = union([ | ||||
|   object({ | ||||
| @@ -223,9 +223,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor { | ||||
|     }) | ||||
|   ); | ||||
|  | ||||
|   private _entitiesValueChanged( | ||||
|     ev: EntitiesEditorEvent<MapEntityConfig> | ||||
|   ): void { | ||||
|   private _entitiesValueChanged(ev: EntitiesEditorEvent): void { | ||||
|     if (ev.detail && ev.detail.entities) { | ||||
|       this._config = { ...this._config!, entities: ev.detail.entities }; | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import { html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { assert, assign, object, optional, string } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { | ||||
|   HaFormSchema, | ||||
| @@ -32,7 +33,9 @@ const SCHEMA = [ | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { | ||||
|       entity_name: {}, | ||||
|       entity_name: { | ||||
|         default_name: DEFAULT_ENTITY_NAME, | ||||
|       }, | ||||
|     }, | ||||
|     context: { entity: "entity" }, | ||||
|   }, | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { mdiGestureTap } from "@mdi/js"; | ||||
| import type { CSSResultGroup } from "lit"; | ||||
| import { html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { | ||||
|   assert, | ||||
|   assign, | ||||
| @@ -15,6 +15,7 @@ import { | ||||
| } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { computeDomain } from "../../../../common/entity/compute_domain"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { | ||||
| @@ -70,7 +71,9 @@ export class HuiPictureEntityCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import { html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { assert, assign, object, optional, string } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import type { HomeAssistant } from "../../../../types"; | ||||
| @@ -24,7 +25,9 @@ const SCHEMA = [ | ||||
|   { | ||||
|     name: "name", | ||||
|     selector: { | ||||
|       entity_name: {}, | ||||
|       entity_name: { | ||||
|         default_name: DEFAULT_ENTITY_NAME, | ||||
|       }, | ||||
|     }, | ||||
|     context: { entity: "entity" }, | ||||
|   }, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import memoizeOne from "memoize-one"; | ||||
| import type { CSSResultGroup } from "lit"; | ||||
| import { html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import memoizeOne from "memoize-one"; | ||||
| import { | ||||
|   assert, | ||||
|   assign, | ||||
| @@ -12,17 +12,18 @@ import { | ||||
|   string, | ||||
|   union, | ||||
| } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { SchemaUnion } from "../../../../components/ha-form/types"; | ||||
| import type { HomeAssistant } from "../../../../types"; | ||||
| import { DEFAULT_HOURS_TO_SHOW } from "../../cards/hui-sensor-card"; | ||||
| import type { SensorCardConfig } from "../../cards/types"; | ||||
| import type { LovelaceCardEditor } from "../../types"; | ||||
| import { baseLovelaceCardConfig } from "../structs/base-card-struct"; | ||||
| import { entityNameStruct } from "../structs/entity-name-struct"; | ||||
| import { configElementStyle } from "./config-elements-style"; | ||||
| import { DEFAULT_HOURS_TO_SHOW } from "../../cards/hui-sensor-card"; | ||||
|  | ||||
| const cardConfigStruct = assign( | ||||
|   baseLovelaceCardConfig, | ||||
| @@ -70,7 +71,9 @@ export class HuiSensorCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -21,13 +21,12 @@ import type { StatisticCardConfig } from "../../cards/types"; | ||||
| import { headerFooterConfigStructs } from "../../header-footer/structs"; | ||||
| import type { LovelaceCardEditor } from "../../types"; | ||||
| import { baseLovelaceCardConfig } from "../structs/base-card-struct"; | ||||
| import { entityNameStruct } from "../structs/entity-name-struct"; | ||||
|  | ||||
| const cardConfigStruct = assign( | ||||
|   baseLovelaceCardConfig, | ||||
|   object({ | ||||
|     entity: optional(string()), | ||||
|     name: optional(entityNameStruct), | ||||
|     name: optional(string()), | ||||
|     icon: optional(string()), | ||||
|     unit: optional(string()), | ||||
|     stat_type: optional(string()), | ||||
| @@ -145,15 +144,11 @@ export class HuiStatisticCardEditor | ||||
|                 } | ||||
|               : { object: {} }, | ||||
|         }, | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { entity_name: {} }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|         { | ||||
|           type: "grid", | ||||
|           name: "", | ||||
|           schema: [ | ||||
|             { name: "name", selector: { text: {} } }, | ||||
|             { | ||||
|               name: "icon", | ||||
|               selector: { | ||||
|   | ||||
| @@ -14,7 +14,7 @@ import { | ||||
| } from "superstruct"; | ||||
| import type { HASSDomEvent } from "../../../../common/dom/fire_event"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { computeDomain } from "../../../../common/entity/compute_domain"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import "../../../../components/ha-expansion-panel"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| import type { | ||||
| @@ -35,6 +35,7 @@ import type { EditDetailElementEvent, EditSubElementEvent } from "../types"; | ||||
| import { configElementStyle } from "./config-elements-style"; | ||||
| import "./hui-card-features-editor"; | ||||
| import type { FeatureType } from "./hui-card-features-editor"; | ||||
| import { computeDomain } from "../../../../common/entity/compute_domain"; | ||||
|  | ||||
| const COMPATIBLE_FEATURES_TYPES: Record<string, FeatureType[]> = { | ||||
|   climate: [ | ||||
| @@ -88,7 +89,9 @@ export class HuiThermostatCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -16,6 +16,7 @@ import { | ||||
| } from "superstruct"; | ||||
| import type { HASSDomEvent } from "../../../../common/dom/fire_event"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import { orderProperties } from "../../../../common/util/order-properties"; | ||||
| import "../../../../components/ha-expansion-panel"; | ||||
| @@ -101,7 +102,9 @@ export class HuiTileCardEditor | ||||
|             { | ||||
|               name: "name", | ||||
|               selector: { | ||||
|                 entity_name: {}, | ||||
|                 entity_name: { | ||||
|                   default_name: DEFAULT_ENTITY_NAME, | ||||
|                 }, | ||||
|               }, | ||||
|               context: { entity: "entity" }, | ||||
|             }, | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import { | ||||
|   string, | ||||
| } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import { supportsFeature } from "../../../../common/entity/supports-feature"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| @@ -152,7 +153,9 @@ export class HuiWeatherForecastCardEditor | ||||
|         { | ||||
|           name: "name", | ||||
|           selector: { | ||||
|             entity_name: {}, | ||||
|             entity_name: { | ||||
|               default_name: DEFAULT_ENTITY_NAME, | ||||
|             }, | ||||
|           }, | ||||
|           context: { entity: "entity" }, | ||||
|         }, | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import { | ||||
|   union, | ||||
| } from "superstruct"; | ||||
| import { fireEvent } from "../../../../common/dom/fire_event"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; | ||||
| import type { LocalizeFunc } from "../../../../common/translations/localize"; | ||||
| import "../../../../components/ha-expansion-panel"; | ||||
| import "../../../../components/ha-form/ha-form"; | ||||
| @@ -93,7 +94,9 @@ export class HuiHeadingEntityEditor | ||||
|                 { | ||||
|                   name: "name", | ||||
|                   selector: { | ||||
|                     entity_name: {}, | ||||
|                     entity_name: { | ||||
|                       default_name: DEFAULT_ENTITY_NAME, | ||||
|                     }, | ||||
|                   }, | ||||
|                   context: { entity: "entity" }, | ||||
|                 }, | ||||
|   | ||||
| @@ -4,12 +4,11 @@ import { | ||||
|   actionConfigStruct, | ||||
|   actionConfigStructConfirmation, | ||||
| } from "./action-struct"; | ||||
| import { entityNameStruct } from "./entity-name-struct"; | ||||
|  | ||||
| export const entitiesConfigStruct = union([ | ||||
|   object({ | ||||
|     entity: string(), | ||||
|     name: optional(entityNameStruct), | ||||
|     name: optional(string()), | ||||
|     icon: optional(string()), | ||||
|     image: optional(string()), | ||||
|     secondary_info: optional(string()), | ||||
|   | ||||
| @@ -43,10 +43,9 @@ export interface ConfigError { | ||||
|   message: string; | ||||
| } | ||||
|  | ||||
| export interface EntitiesEditorEvent<T extends EntityConfig = EntityConfig> | ||||
|   extends CustomEvent { | ||||
| export interface EntitiesEditorEvent extends CustomEvent { | ||||
|   detail: { | ||||
|     entities?: T[]; | ||||
|     entities?: EntityConfig[]; | ||||
|     item?: any; | ||||
|   }; | ||||
|   target: EventTarget | null; | ||||
|   | ||||
| @@ -111,7 +111,11 @@ export class HuiUnusedEntities extends LitElement { | ||||
|   } | ||||
|  | ||||
|   private _addToLovelaceView(): void { | ||||
|     const cardConfig = computeCards(this.hass, this._selectedEntities, {}); | ||||
|     const cardConfig = computeCards( | ||||
|       this.hass.states, | ||||
|       this._selectedEntities, | ||||
|       {} | ||||
|     ); | ||||
|     const sectionConfig = computeSection(this._selectedEntities, {}); | ||||
|  | ||||
|     if (this.lovelace.config.views.length === 1) { | ||||
|   | ||||
| @@ -1,17 +1,17 @@ | ||||
| import { format } from "date-fns"; | ||||
| import type { PropertyValues, TemplateResult } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import "../../../components/ha-date-input"; | ||||
| import "../../../components/ha-time-input"; | ||||
| import { setDateTimeValue } from "../../../data/datetime"; | ||||
| import { format } from "date-fns"; | ||||
| import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; | ||||
| import { setDateTimeValue } from "../../../data/datetime"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| import type { EntityConfig, LovelaceRow } from "./types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import "../../../components/ha-time-input"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
|  | ||||
| @customElement("hui-datetime-entity-row") | ||||
| class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { | ||||
| @@ -53,12 +53,6 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { | ||||
|     const time = dateObj ? format(dateObj, "HH:mm:ss") : undefined; | ||||
|     const date = dateObj ? format(dateObj, "yyyy-MM-dd") : undefined; | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|         .hass=${this.hass} | ||||
| @@ -67,7 +61,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { | ||||
|       > | ||||
|         <div> | ||||
|           <ha-date-input | ||||
|             .label=${name} | ||||
|             .label=${this._config.name || computeStateName(stateObj)} | ||||
|             .locale=${this.hass.locale} | ||||
|             .value=${date} | ||||
|             .disabled=${unavailable} | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import type { PropertyValues } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-date-input"; | ||||
| import "../../../components/ha-time-input"; | ||||
| import { isUnavailableState, UNKNOWN } from "../../../data/entity"; | ||||
| @@ -9,7 +10,6 @@ import { | ||||
|   stateToIsoDateString, | ||||
| } from "../../../data/input_datetime"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| @@ -47,11 +47,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { | ||||
|       `; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|     const name = this._config.name || computeStateName(stateObj); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import type { PropertyValues } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { stopPropagation } from "../../../common/dom/stop_propagation"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-list-item"; | ||||
| import "../../../components/ha-select"; | ||||
| import { UNAVAILABLE } from "../../../data/entity"; | ||||
| @@ -10,7 +11,6 @@ import type { InputSelectEntity } from "../../../data/input_select"; | ||||
| import { setInputSelectOption } from "../../../data/input_select"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import type { EntitiesCardEntityConfig } from "../cards/types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| @@ -51,12 +51,6 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { | ||||
|       `; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|         .hass=${this.hass} | ||||
| @@ -64,7 +58,7 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow { | ||||
|         hide-name | ||||
|       > | ||||
|         <ha-select | ||||
|           .label=${name} | ||||
|           .label=${this._config.name || computeStateName(stateObj)} | ||||
|           .value=${stateObj.state} | ||||
|           .options=${stateObj.attributes.options} | ||||
|           .disabled=${ | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| import type { PropertyValues } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-textfield"; | ||||
| import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; | ||||
| import { setValue } from "../../../data/input_text"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| @@ -43,12 +43,6 @@ class HuiInputTextEntityRow extends LitElement implements LovelaceRow { | ||||
|       `; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|         .hass=${this.hass} | ||||
| @@ -56,7 +50,7 @@ class HuiInputTextEntityRow extends LitElement implements LovelaceRow { | ||||
|         hide-name | ||||
|       > | ||||
|         <ha-textfield | ||||
|           .label=${name} | ||||
|           .label=${this._config.name || computeStateName(stateObj)} | ||||
|           .disabled=${stateObj.state === UNAVAILABLE} | ||||
|           .value=${stateObj.state} | ||||
|           .minlength=${stateObj.attributes.min} | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import type { PropertyValues } from "lit"; | ||||
| import { LitElement, css, html, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { stopPropagation } from "../../../common/dom/stop_propagation"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-list-item"; | ||||
| import "../../../components/ha-select"; | ||||
| import { UNAVAILABLE } from "../../../data/entity"; | ||||
| @@ -10,7 +11,6 @@ import type { SelectEntity } from "../../../data/select"; | ||||
| import { setSelectOption } from "../../../data/select"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import type { EntitiesCardEntityConfig } from "../cards/types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| @@ -51,12 +51,6 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow { | ||||
|       `; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|         .hass=${this.hass} | ||||
| @@ -64,7 +58,7 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow { | ||||
|         hide-name | ||||
|       > | ||||
|         <ha-select | ||||
|           .label=${name} | ||||
|           .label=${this._config.name || computeStateName(stateObj)} | ||||
|           .value=${stateObj.state} | ||||
|           .options=${stateObj.attributes.options} | ||||
|           .disabled=${stateObj.state === UNAVAILABLE} | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import type { PropertyValues } from "lit"; | ||||
| import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-textfield"; | ||||
| import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; | ||||
| import type { TextEntity } from "../../../data/text"; | ||||
| @@ -10,7 +11,6 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| import type { EntityConfig, LovelaceRow } from "./types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
|  | ||||
| @customElement("hui-text-entity-row") | ||||
| class HuiTextEntityRow extends LitElement implements LovelaceRow { | ||||
| @@ -46,12 +46,6 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow { | ||||
|       `; | ||||
|     } | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <hui-generic-entity-row | ||||
|         .hass=${this.hass} | ||||
| @@ -59,7 +53,7 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow { | ||||
|         hide-name | ||||
|       > | ||||
|         <ha-textfield | ||||
|           .label=${name} | ||||
|           .label=${this._config.name || computeStateName(stateObj)} | ||||
|           .disabled=${stateObj.state === UNAVAILABLE} | ||||
|           .value=${stateObj.state} | ||||
|           .minlength=${stateObj.attributes.min} | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import { LitElement, css, html, nothing } from "lit"; | ||||
| import { customElement, property, state } from "lit/decorators"; | ||||
| import { classMap } from "lit/directives/class-map"; | ||||
| import { ifDefined } from "lit/directives/if-defined"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import { isUnavailableState } from "../../../data/entity"; | ||||
| import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler"; | ||||
| import type { ForecastEvent, WeatherEntity } from "../../../data/weather"; | ||||
| @@ -23,7 +24,6 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; | ||||
| import "../components/hui-generic-entity-row"; | ||||
| import { createEntityNotFoundWarning } from "../components/hui-warning"; | ||||
| import type { LovelaceRow } from "./types"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
|  | ||||
| @customElement("hui-weather-entity-row") | ||||
| class HuiWeatherEntityRow extends LitElement implements LovelaceRow { | ||||
| @@ -119,12 +119,6 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow { | ||||
|     const forecastData = getForecast(stateObj.attributes, this._forecastEvent); | ||||
|     const forecast = forecastData?.forecast; | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|  | ||||
|     return html` | ||||
|       <div | ||||
|         class="icon-image ${classMap({ | ||||
| @@ -161,7 +155,7 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow { | ||||
|           hasDoubleClick: hasAction(this._config!.double_tap_action), | ||||
|         })} | ||||
|       > | ||||
|         ${name} | ||||
|         ${this._config.name || computeStateName(stateObj)} | ||||
|         ${hasSecondary | ||||
|           ? html` | ||||
|               <div class="secondary"> | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import type { EntityNameItem } from "../../../common/entity/compute_entity_name_display"; | ||||
| import type { | ||||
|   ActionConfig, | ||||
|   ConfirmationRestrictionConfig, | ||||
| @@ -11,7 +10,7 @@ import type { TimestampRenderingFormat } from "../components/types"; | ||||
| export interface EntityConfig { | ||||
|   entity: string; | ||||
|   type?: string; | ||||
|   name?: string | EntityNameItem | EntityNameItem[]; | ||||
|   name?: string; | ||||
|   icon?: string; | ||||
|   image?: string; | ||||
| } | ||||
|   | ||||
| @@ -321,8 +321,6 @@ class HUIRoot extends LitElement { | ||||
|                 .id="button-${index}" | ||||
|                 .path=${item.icon} | ||||
|                 slot="trigger" | ||||
|                 .label=${label} | ||||
|                 hide-title | ||||
|               ></ha-icon-button> | ||||
|               ${item.subItems | ||||
|                 .filter((subItem) => subItem.visible) | ||||
| @@ -342,6 +340,9 @@ class HUIRoot extends LitElement { | ||||
|                   ` | ||||
|                 )} | ||||
|             </ha-button-menu> | ||||
|             <ha-tooltip placement="bottom" .for="button-${index}"> | ||||
|               ${label} | ||||
|             </ha-tooltip> | ||||
|           ` | ||||
|         : html` | ||||
|             <ha-icon-button | ||||
|   | ||||
| @@ -2,15 +2,15 @@ import { css, html, LitElement, nothing } from "lit"; | ||||
| import { customElement, state } from "lit/decorators"; | ||||
| import { DOMAINS_TOGGLE } from "../../../common/const"; | ||||
| import { computeDomain } from "../../../common/entity/compute_domain"; | ||||
| import "../../../components/ha-button"; | ||||
| import { computeStateName } from "../../../common/entity/compute_state_name"; | ||||
| import "../../../components/ha-state-icon"; | ||||
| import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler"; | ||||
| import "../../../components/ha-button"; | ||||
| import type { HomeAssistant } from "../../../types"; | ||||
| import { actionHandler } from "../common/directives/action-handler-directive"; | ||||
| import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name"; | ||||
| import { handleAction } from "../common/handle-action"; | ||||
| import { hasAction } from "../common/has-action"; | ||||
| import type { ButtonRowConfig, LovelaceRow } from "../entity-rows/types"; | ||||
| import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler"; | ||||
|  | ||||
| @customElement("hui-button-row") | ||||
| export class HuiButtonRow extends LitElement implements LovelaceRow { | ||||
| @@ -49,11 +49,8 @@ export class HuiButtonRow extends LitElement implements LovelaceRow { | ||||
|         ? this.hass.states[this._config.entity] | ||||
|         : undefined; | ||||
|  | ||||
|     const name = computeLovelaceEntityName( | ||||
|       this.hass!, | ||||
|       stateObj, | ||||
|       this._config.name | ||||
|     ); | ||||
|     const name = | ||||
|       this._config.name ?? (stateObj ? computeStateName(stateObj) : ""); | ||||
|  | ||||
|     return html` | ||||
|       <ha-state-icon | ||||
|   | ||||
| @@ -168,17 +168,9 @@ export class HomeAreaViewStrategy extends ReactiveElement { | ||||
|  | ||||
|     const summaryEntities = Object.values(entitiesBySummary).flat(); | ||||
|  | ||||
|     // Automations section | ||||
|     const automationFilter = generateEntityFilter(hass, { | ||||
|       domain: "automation", | ||||
|       entity_category: "none", | ||||
|     }); | ||||
|     const automations = areaEntities.filter(automationFilter); | ||||
|  | ||||
|     // Rest of entities grouped by device | ||||
|     const otherEntities = areaEntities.filter( | ||||
|       (entityId) => | ||||
|         !summaryEntities.includes(entityId) && !automations.includes(entityId) | ||||
|       (entityId) => !summaryEntities.includes(entityId) | ||||
|     ); | ||||
|  | ||||
|     const entitiesByDevice: Record<string, string[]> = {}; | ||||
| @@ -303,21 +295,6 @@ export class HomeAreaViewStrategy extends ReactiveElement { | ||||
|       sections.push(...deviceSections); | ||||
|     } | ||||
|  | ||||
|     // Show automations last, if they exist | ||||
|     if (automations.length > 0) { | ||||
|       sections.push({ | ||||
|         type: "grid", | ||||
|         cards: [ | ||||
|           computeHeadingCard( | ||||
|             hass.localize("ui.panel.lovelace.strategy.home.automations"), | ||||
|             "mdi:robot", | ||||
|             "/config/automation/dashboard" | ||||
|           ), | ||||
|           ...automations.map(computeTileCard), | ||||
|         ], | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     // Allow between 2 and 3 columns (the max should be set to define the width of the header) | ||||
|     const maxColumns = clamp(sections.length, 2, 3); | ||||
|  | ||||
|   | ||||
| @@ -21,7 +21,6 @@ import type { | ||||
| import { getAreas, getFloors } from "../areas/helpers/areas-strategy-helper"; | ||||
| import type { CommonControlSectionStrategyConfig } from "../usage_prediction/common-controls-section-strategy"; | ||||
| import { getHomeStructure } from "./helpers/home-structure"; | ||||
| import { floorDefaultIcon } from "../../../../components/ha-floor-icon"; | ||||
|  | ||||
| export interface HomeMainViewStrategyConfig { | ||||
|   type: "home-main"; | ||||
| @@ -93,7 +92,7 @@ export class HomeMainViewStrategy extends ReactiveElement { | ||||
|                   ? floor.name | ||||
|                   : hass.localize("ui.panel.lovelace.strategy.home.areas"), | ||||
|               heading_style: "title", | ||||
|               icon: floor.icon || floorDefaultIcon(floor), | ||||
|               icon: floor.icon, | ||||
|             }, | ||||
|             ...cards, | ||||
|           ], | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import { | ||||
|   findEntities, | ||||
|   generateEntityFilter, | ||||
| } from "../../../../common/entity/entity_filter"; | ||||
| import { floorDefaultIcon } from "../../../../components/ha-floor-icon"; | ||||
| import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card"; | ||||
| import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section"; | ||||
| import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; | ||||
| @@ -97,7 +96,6 @@ export class HomeMMediaPlayersViewStrategy extends ReactiveElement { | ||||
|               floorCount > 1 | ||||
|                 ? floor.name | ||||
|                 : hass.localize("ui.panel.lovelace.strategy.home.areas"), | ||||
|             icon: floor.icon || floorDefaultIcon(floor), | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|   | ||||
| @@ -44,7 +44,10 @@ export class OriginalStatesViewStrategy extends ReactiveElement { | ||||
|     // User can override default view. If they didn't, we will add one | ||||
|     // that contains all entities. | ||||
|     const view = generateDefaultViewConfig( | ||||
|       hass, | ||||
|       hass.areas, | ||||
|       hass.devices, | ||||
|       hass.entities, | ||||
|       hass.states, | ||||
|       localize, | ||||
|       energyPrefs, | ||||
|       config.areas, | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import { | ||||
|   generateEntityFilter, | ||||
|   type EntityFilter, | ||||
| } from "../../../common/entity/entity_filter"; | ||||
| import { floorDefaultIcon } from "../../../components/ha-floor-icon"; | ||||
| import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; | ||||
| import type { LovelaceSectionRawConfig } from "../../../data/lovelace/config/section"; | ||||
| import type { LovelaceViewConfig } from "../../../data/lovelace/config/view"; | ||||
| @@ -141,7 +140,6 @@ export class SafetyViewStrategy extends ReactiveElement { | ||||
|               floorCount > 1 | ||||
|                 ? floor.name | ||||
|                 : hass.localize("ui.panel.lovelace.strategy.home.areas"), | ||||
|             icon: floor.icon || floorDefaultIcon(floor), | ||||
|           }, | ||||
|         ], | ||||
|       }; | ||||
|   | ||||
| @@ -255,10 +255,6 @@ class DialogTodoItemEditor extends LitElement { | ||||
|  | ||||
|   // Parse a date in the browser timezone | ||||
|   private _parseDate(dateStr: string): Date { | ||||
|     // If it's a date-only string (no 'T'), parse as midnight in browser time to avoid offset issues | ||||
|     if (!dateStr.includes("T")) { | ||||
|       return new Date(dateStr + "T00:00:00"); | ||||
|     } | ||||
|     const tzDate = new TZDate(dateStr, this._timeZone!); | ||||
|     return new Date(tzDate.getTime()); | ||||
|   } | ||||
|   | ||||
| @@ -3945,6 +3945,7 @@ | ||||
|               "add": "Add trigger", | ||||
|               "empty_search": "No triggers found for {term}", | ||||
|               "id": "Trigger ID", | ||||
|               "id_helper": "Helps identify each run based on which trigger fired.", | ||||
|               "optional": "Optional", | ||||
|               "edit_id": "Edit ID", | ||||
|               "duplicate": "[%key:ui::common::duplicate%]", | ||||
| @@ -6942,8 +6943,7 @@ | ||||
|             "areas": "Areas", | ||||
|             "other_areas": "Other areas", | ||||
|             "unamed_device": "Unnamed device", | ||||
|             "others": "Others", | ||||
|             "automations": "Automations" | ||||
|             "others": "Others" | ||||
|           }, | ||||
|           "common_controls": { | ||||
|             "not_loaded": "Usage Prediction integration is not loaded.", | ||||
| @@ -7075,10 +7075,10 @@ | ||||
|             "energy_devices_graph": { | ||||
|               "energy_usage": "Energy usage", | ||||
|               "previous_energy_usage": "Previous energy usage", | ||||
|               "total_energy_usage": "Total", | ||||
|               "total_energy_usage": "Total energy usage", | ||||
|               "change_chart_type": "Change chart type", | ||||
|               "untracked_consumption": "Untracked consumption", | ||||
|               "untracked": "untracked" | ||||
|               "untracked": "untracked", | ||||
|               "includes_untracked": "Includes {num} kWh of untracked energy" | ||||
|             }, | ||||
|             "energy_devices_detail_graph": { | ||||
|               "untracked_consumption": "Untracked consumption", | ||||
| @@ -7651,8 +7651,7 @@ | ||||
|             }, | ||||
|             "logbook": { | ||||
|               "name": "Activity", | ||||
|               "description": "The Activity card shows a list of events for entities.", | ||||
|               "state_filter": "State filter" | ||||
|               "description": "The Activity card shows a list of events for entities." | ||||
|             }, | ||||
|             "history-graph": { | ||||
|               "name": "History graph", | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { describe, expect, it, vi } from "vitest"; | ||||
| import { DEFAULT_ENTITY_NAME } from "../../../../../src/common/entity/compute_entity_name_display"; | ||||
| import { computeLovelaceEntityName } from "../../../../../src/panels/lovelace/common/entity/compute-lovelace-entity-name"; | ||||
| import type { HomeAssistant } from "../../../../../src/types"; | ||||
| import { mockStateObj } from "../../../../common/entity/context/context-mock"; | ||||
| @@ -22,32 +23,30 @@ describe("computeLovelaceEntityName", () => { | ||||
|     expect(mockFormatEntityName).not.toHaveBeenCalled(); | ||||
|   }); | ||||
|  | ||||
|   it("return state name when nameConfig is empty string", () => { | ||||
|   it("returns empty string when nameConfig is empty string", () => { | ||||
|     const mockFormatEntityName = vi.fn(); | ||||
|     const hass = createMockHass(mockFormatEntityName); | ||||
|     const stateObj = mockStateObj({ | ||||
|       entity_id: "light.kitchen", | ||||
|       attributes: { friendly_name: "Kitchen Light" }, | ||||
|     }); | ||||
|     const stateObj = mockStateObj({ entity_id: "light.kitchen" }); | ||||
|  | ||||
|     const result = computeLovelaceEntityName(hass, stateObj, ""); | ||||
|  | ||||
|     expect(result).toBe("Kitchen Light"); | ||||
|     expect(result).toBe(""); | ||||
|     expect(mockFormatEntityName).not.toHaveBeenCalled(); | ||||
|   }); | ||||
|  | ||||
|   it("return state name when nameConfig is undefined", () => { | ||||
|   it("calls formatEntityName with DEFAULT_ENTITY_NAME when nameConfig is undefined", () => { | ||||
|     const mockFormatEntityName = vi.fn(() => "Formatted Name"); | ||||
|     const hass = createMockHass(mockFormatEntityName); | ||||
|     const stateObj = mockStateObj({ | ||||
|       entity_id: "light.kitchen", | ||||
|       attributes: { friendly_name: "Kitchen Light" }, | ||||
|     }); | ||||
|     const stateObj = mockStateObj({ entity_id: "light.kitchen" }); | ||||
|  | ||||
|     const result = computeLovelaceEntityName(hass, stateObj, undefined); | ||||
|  | ||||
|     expect(result).toBe("Kitchen Light"); | ||||
|     expect(mockFormatEntityName).not.toHaveBeenCalled(); | ||||
|     expect(result).toBe("Formatted Name"); | ||||
|     expect(mockFormatEntityName).toHaveBeenCalledTimes(1); | ||||
|     expect(mockFormatEntityName).toHaveBeenCalledWith( | ||||
|       stateObj, | ||||
|       DEFAULT_ENTITY_NAME | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it("calls formatEntityName with EntityNameItem config", () => { | ||||
|   | ||||
							
								
								
									
										291
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										291
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -3884,12 +3884,12 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsbuild/plugin-check-syntax@npm:1.5.0": | ||||
|   version: 1.5.0 | ||||
|   resolution: "@rsbuild/plugin-check-syntax@npm:1.5.0" | ||||
| "@rsbuild/plugin-check-syntax@npm:1.4.0": | ||||
|   version: 1.4.0 | ||||
|   resolution: "@rsbuild/plugin-check-syntax@npm:1.4.0" | ||||
|   dependencies: | ||||
|     acorn: "npm:^8.15.0" | ||||
|     browserslist-to-es-version: "npm:^1.1.1" | ||||
|     browserslist-to-es-version: "npm:^1.1.0" | ||||
|     htmlparser2: "npm:10.0.0" | ||||
|     picocolors: "npm:^1.1.1" | ||||
|     source-map: "npm:^0.7.6" | ||||
| @@ -3898,86 +3898,85 @@ __metadata: | ||||
|   peerDependenciesMeta: | ||||
|     "@rsbuild/core": | ||||
|       optional: true | ||||
|   checksum: 10/69f537d24aa298b9913c1e21378eded13a6deff21e597257bdfeb1ddbe42c711d21d068543190cdd2f6537531fea24feb84cf1637e2492c9fc5d2fcc1f9a53d6 | ||||
|   checksum: 10/1e6ee37cc072bbf459ecd493a78cab2798e08c2e046828e0d93f618581738a4b7a6b6f3bf8b890a58b67b5a879d0a778810b33b834f75dadd89817cf16c73a38 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/client@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/client@npm:1.3.6" | ||||
|   checksum: 10/9c1207c7bbc0f7ba3ca100074703db07625997e9ed9649c4115ebbb7f3deb44605d0d0a508f20586a10a22ba006d022046cf55a82c19f2f9c599f5f8cd963379 | ||||
| "@rsdoctor/client@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/client@npm:1.3.4" | ||||
|   checksum: 10/0f3d35ce16264c20294f317efc063153cc62b0d7d5f5f11aa444ace2cbf9617f1ea26828e1d8e5f7fe4ce6f6e276ea6cd8312fd4e4f3214a8a3c8d3728f0fc1f | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/core@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/core@npm:1.3.6" | ||||
| "@rsdoctor/core@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/core@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@rsbuild/plugin-check-syntax": "npm:1.5.0" | ||||
|     "@rsdoctor/graph": "npm:1.3.6" | ||||
|     "@rsdoctor/sdk": "npm:1.3.6" | ||||
|     "@rsdoctor/types": "npm:1.3.6" | ||||
|     "@rsdoctor/utils": "npm:1.3.6" | ||||
|     "@rsbuild/plugin-check-syntax": "npm:1.4.0" | ||||
|     "@rsdoctor/graph": "npm:1.3.4" | ||||
|     "@rsdoctor/sdk": "npm:1.3.4" | ||||
|     "@rsdoctor/types": "npm:1.3.4" | ||||
|     "@rsdoctor/utils": "npm:1.3.4" | ||||
|     browserslist-load-config: "npm:^1.0.1" | ||||
|     enhanced-resolve: "npm:5.12.0" | ||||
|     es-toolkit: "npm:^1.41.0" | ||||
|     filesize: "npm:^10.1.6" | ||||
|     fs-extra: "npm:^11.1.1" | ||||
|     semver: "npm:^7.7.3" | ||||
|     source-map: "npm:^0.7.6" | ||||
|   checksum: 10/e4501b8621b687a55e2cb8002286f3f84d950f2399721ecfc906be789d1554f946818d5c3ab6900a7d37725874f43632181cd6dd0ccd7d0e5f318ff30ad98055 | ||||
|   checksum: 10/852f79ea59b6e2d6bcf0301136e3a9dd6f8acc2c011277128b791f8378a5d291e91c385ab691440bdba454f2130bde1097c3a3ba7eedf35e0a48cf1462d4d7c8 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/graph@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/graph@npm:1.3.6" | ||||
| "@rsdoctor/graph@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/graph@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@rsdoctor/types": "npm:1.3.6" | ||||
|     "@rsdoctor/utils": "npm:1.3.6" | ||||
|     es-toolkit: "npm:^1.41.0" | ||||
|     "@rsdoctor/types": "npm:1.3.4" | ||||
|     "@rsdoctor/utils": "npm:1.3.4" | ||||
|     es-toolkit: "npm:^1.40.0" | ||||
|     path-browserify: "npm:1.0.1" | ||||
|     source-map: "npm:^0.7.6" | ||||
|   checksum: 10/64373a0cae33687a65db1ed093a7e0713aec8f749131367474668d32e3e84dd3b9e14e5cf7b8268cc7bff31ba8f6288515cc63ecb1804b25816e7b8483134df3 | ||||
|   checksum: 10/77b50fa73e97c1bd01ef14134d5c81ba63dacba6c4119f712fff139c39adc787a71f4cca793565a7d4faa4d2dbdd869fa72e955632671121ece92ff945adfa83 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/rspack-plugin@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/rspack-plugin@npm:1.3.6" | ||||
| "@rsdoctor/rspack-plugin@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/rspack-plugin@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@rsdoctor/core": "npm:1.3.6" | ||||
|     "@rsdoctor/graph": "npm:1.3.6" | ||||
|     "@rsdoctor/sdk": "npm:1.3.6" | ||||
|     "@rsdoctor/types": "npm:1.3.6" | ||||
|     "@rsdoctor/utils": "npm:1.3.6" | ||||
|     "@rsdoctor/core": "npm:1.3.4" | ||||
|     "@rsdoctor/graph": "npm:1.3.4" | ||||
|     "@rsdoctor/sdk": "npm:1.3.4" | ||||
|     "@rsdoctor/types": "npm:1.3.4" | ||||
|     "@rsdoctor/utils": "npm:1.3.4" | ||||
|   peerDependencies: | ||||
|     "@rspack/core": "*" | ||||
|   peerDependenciesMeta: | ||||
|     "@rspack/core": | ||||
|       optional: true | ||||
|   checksum: 10/7498e070668e57f747c786730618431732e4e74c4ba033cbe8b11f6b65974f41d426a31c0ceb847eb7ea886385004fa7a6e9e63ea30138dd2ff4c182cbf900c3 | ||||
|   checksum: 10/bc09ae1f19c624011961f65e1185889420d60d8aea8ca404766368f60c9d4381bbff146d17e166db66d88080246a7a3029714285bac8f2a2d797130822e787d5 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/sdk@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/sdk@npm:1.3.6" | ||||
| "@rsdoctor/sdk@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/sdk@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@rsdoctor/client": "npm:1.3.6" | ||||
|     "@rsdoctor/graph": "npm:1.3.6" | ||||
|     "@rsdoctor/types": "npm:1.3.6" | ||||
|     "@rsdoctor/utils": "npm:1.3.6" | ||||
|     "@rsdoctor/client": "npm:1.3.4" | ||||
|     "@rsdoctor/graph": "npm:1.3.4" | ||||
|     "@rsdoctor/types": "npm:1.3.4" | ||||
|     "@rsdoctor/utils": "npm:1.3.4" | ||||
|     safer-buffer: "npm:2.1.2" | ||||
|     socket.io: "npm:4.8.1" | ||||
|     tapable: "npm:2.2.3" | ||||
|   checksum: 10/b1a78b36843fdb9596d42a67e12d25fcf2ba03e26793483d6bd50de18ed9a20df5891b5772b456cdf8d73c920b1f42d5e8c90c03def813ae8d8b0ca0e7ba1113 | ||||
|   checksum: 10/9e57d1c9f51c4404a6c262c2f4602c19c6d3a9e467ca63456a81d8f614690d85a2574d5e936f03ca5672813a61544f02ca3c4e5f10eb5833f0116f8d2214572b | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/types@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/types@npm:1.3.6" | ||||
| "@rsdoctor/types@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/types@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@types/connect": "npm:3.4.38" | ||||
|     "@types/estree": "npm:1.0.5" | ||||
| @@ -3991,16 +3990,16 @@ __metadata: | ||||
|       optional: true | ||||
|     webpack: | ||||
|       optional: true | ||||
|   checksum: 10/090c5872cb7c04c83ed134ec47fdf673777056e80041860f21e36c4f7c506f019136a834d59ed3b84db8d8df615300e331060234dc48b71af5acab287352adc3 | ||||
|   checksum: 10/56ce0af51c6d78eaac6fa6236dba1c5753b52dd021f8ffc4d3fe40d7f52f079ecec7e2c247ac3ca6e44d8a6f274bb20b9c7310baa9ce7bf7e60d8ee16ec8c0c4 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@rsdoctor/utils@npm:1.3.6": | ||||
|   version: 1.3.6 | ||||
|   resolution: "@rsdoctor/utils@npm:1.3.6" | ||||
| "@rsdoctor/utils@npm:1.3.4": | ||||
|   version: 1.3.4 | ||||
|   resolution: "@rsdoctor/utils@npm:1.3.4" | ||||
|   dependencies: | ||||
|     "@babel/code-frame": "npm:7.26.2" | ||||
|     "@rsdoctor/types": "npm:1.3.6" | ||||
|     "@rsdoctor/types": "npm:1.3.4" | ||||
|     "@types/estree": "npm:1.0.5" | ||||
|     acorn: "npm:^8.10.0" | ||||
|     acorn-import-attributes: "npm:^1.9.5" | ||||
| @@ -4014,7 +4013,7 @@ __metadata: | ||||
|     picocolors: "npm:^1.1.1" | ||||
|     rslog: "npm:^1.2.11" | ||||
|     strip-ansi: "npm:^6.0.1" | ||||
|   checksum: 10/cb3b6e0c6ea64d6d7657a6682c1c295a4d0a787af7292fe4e7da46ef064d8ca843c7a65b9e0014a9d77053aeaf3481f16776acec3963ac6a8dcc4ba1c4bf5a17 | ||||
|   checksum: 10/04b72e7ab1b63cad77ef83a468cb5c5b1468662dd29d03fbae7ef16aa81d3d91b54958d8630ee53655b794c32b12effb5ff3162cc309174c5ec784373d3f0560 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -5377,12 +5376,12 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/coverage-v8@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/coverage-v8@npm:4.0.4" | ||||
| "@vitest/coverage-v8@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/coverage-v8@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@bcoe/v8-coverage": "npm:^1.0.2" | ||||
|     "@vitest/utils": "npm:4.0.4" | ||||
|     "@vitest/utils": "npm:4.0.3" | ||||
|     ast-v8-to-istanbul: "npm:^0.3.5" | ||||
|     debug: "npm:^4.4.3" | ||||
|     istanbul-lib-coverage: "npm:^3.2.2" | ||||
| @@ -5393,34 +5392,34 @@ __metadata: | ||||
|     std-env: "npm:^3.9.0" | ||||
|     tinyrainbow: "npm:^3.0.3" | ||||
|   peerDependencies: | ||||
|     "@vitest/browser": 4.0.4 | ||||
|     vitest: 4.0.4 | ||||
|     "@vitest/browser": 4.0.3 | ||||
|     vitest: 4.0.3 | ||||
|   peerDependenciesMeta: | ||||
|     "@vitest/browser": | ||||
|       optional: true | ||||
|   checksum: 10/9aaab295ae81da2be090973173922e3db2822725d0fbe27e8084908018e95cc6666259c8cc4b6bab14bd40bb9365072e41c7ae64c4d2a28672ad23f7743cec29 | ||||
|   checksum: 10/8051dc457f74f9dbd912be9805fc3c6c1a965e3c86d88a6f4b2d4b7e38511dcce689447adb92235c33bec8fddcd0ede8e81f6bdf33eedc9ff00070b28a474093 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/expect@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/expect@npm:4.0.4" | ||||
| "@vitest/expect@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/expect@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@standard-schema/spec": "npm:^1.0.0" | ||||
|     "@types/chai": "npm:^5.2.2" | ||||
|     "@vitest/spy": "npm:4.0.4" | ||||
|     "@vitest/utils": "npm:4.0.4" | ||||
|     "@vitest/spy": "npm:4.0.3" | ||||
|     "@vitest/utils": "npm:4.0.3" | ||||
|     chai: "npm:^6.0.1" | ||||
|     tinyrainbow: "npm:^3.0.3" | ||||
|   checksum: 10/7d6f4e501c5b84c63fd99259a2b0000b81b075fd62c1a4ff479c50136d46d6cf90bcdd514f6304bf972fbba148949fda23ebd2926fa26f0fd428f1010f1cff63 | ||||
|   checksum: 10/663936d8f3abd91cb9725196ec542d109d7c64ddcdb6a483d89c9d67aa78a8ddd4468348c54b69f9c801fc3add9a8ae35dd0491c9f2bd19ec17b9b7a9ebf0d82 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/mocker@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/mocker@npm:4.0.4" | ||||
| "@vitest/mocker@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/mocker@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@vitest/spy": "npm:4.0.4" | ||||
|     "@vitest/spy": "npm:4.0.3" | ||||
|     estree-walker: "npm:^3.0.3" | ||||
|     magic-string: "npm:^0.30.19" | ||||
|   peerDependencies: | ||||
| @@ -5431,54 +5430,54 @@ __metadata: | ||||
|       optional: true | ||||
|     vite: | ||||
|       optional: true | ||||
|   checksum: 10/070ddbd7f9907482aa1812e01d13ff66cea540479435a857072fc7528f4b583d62f0600eed112b5780e9698812c944b679fc959e764670de23621eba9be9e177 | ||||
|   checksum: 10/933cab25563f68335a9871a6deba8f886f6be155c4a2146ee2b3b625578a0b4e068a4a26cf1a8d4ba3b5eb34771276f0365e51320fd06ad3f3f19163c5521d77 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/pretty-format@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/pretty-format@npm:4.0.4" | ||||
| "@vitest/pretty-format@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/pretty-format@npm:4.0.3" | ||||
|   dependencies: | ||||
|     tinyrainbow: "npm:^3.0.3" | ||||
|   checksum: 10/64b0430012f8c34748a39dd1ea061f51d17053086d961830e93a4083b7cda50d822d6db8154398d7f800e15e1efc45c6460d7c1c5f06e21f09a282663824b9c9 | ||||
|   checksum: 10/1b1197e53e5bcf9f77c842005ff11068f754b87286c6a7669b78c08a05bdbaa5cf4c7326c3b13347b02341b084bf97992c3fe89ea98fb77019e28fd96bc4c5b4 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/runner@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/runner@npm:4.0.4" | ||||
| "@vitest/runner@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/runner@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@vitest/utils": "npm:4.0.4" | ||||
|     "@vitest/utils": "npm:4.0.3" | ||||
|     pathe: "npm:^2.0.3" | ||||
|   checksum: 10/3bd7e8944d8770ae7dd7457fb83751def5cb4834766cb86b7231cc0fd77d4e889b5ec6da70ae82e06902b19c216f114a5a670e4422ba2db8384dee09dc24b832 | ||||
|   checksum: 10/a028898045cedac1939cc1adeff8fe36cbba2714d08e8524c8028b6fef7d617440bf0dfd72f1e264e8bff876979c49923bf268cb5920305a0ca9562a8318a80c | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/snapshot@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/snapshot@npm:4.0.4" | ||||
| "@vitest/snapshot@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/snapshot@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@vitest/pretty-format": "npm:4.0.4" | ||||
|     "@vitest/pretty-format": "npm:4.0.3" | ||||
|     magic-string: "npm:^0.30.19" | ||||
|     pathe: "npm:^2.0.3" | ||||
|   checksum: 10/dba29abb40e8a4e8931a9522076f0884a579280c440d1e7591c32c4f8d75366b18e3f78920eed13337909384767d0403d15f384275f22d7c0bc5c36a0c4f5482 | ||||
|   checksum: 10/38d0707ad66b33987c4066ee713f22d4535712ca016cece007c84736fa543d3ad3a314e759632b63e369e6a5454b03b142f66f5d661ac81ce7c4f1d6f6d325f4 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/spy@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/spy@npm:4.0.4" | ||||
|   checksum: 10/f3bca9c53840c6f271d676a5b7a06535eb4a80e4b2e52e179ff56cb53f7f725ba1c683cb13d2ef1283057c09bf260634b9b9b318bd2a1755853c067bc9a0dd6a | ||||
| "@vitest/spy@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/spy@npm:4.0.3" | ||||
|   checksum: 10/4fc8e3aae425fdbbe96126291079f67f1e6be9545ffbaab7a31de8d6e6825b115eb3fafbf24167eab91dbbb4ed6fcd120c387116f181de1e3369e8d5fdd75f17 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "@vitest/utils@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "@vitest/utils@npm:4.0.4" | ||||
| "@vitest/utils@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "@vitest/utils@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@vitest/pretty-format": "npm:4.0.4" | ||||
|     "@vitest/pretty-format": "npm:4.0.3" | ||||
|     tinyrainbow: "npm:^3.0.3" | ||||
|   checksum: 10/032aa6fad679efe270015bd0ceec55915b3ff4597f5e0b4ee9ae2ac54d5e8a2f903ef64533cc73f05264d8959c01104a32283c2b0298f4e903a003c9bf427514 | ||||
|   checksum: 10/d4ddb293e908d43b954c5e41f351a61f719e30e9ea058e47af5b18389d74cb073ea1638ab28dbbd5b365ed31a21577bb090b8a3594292c59df18798fd292f002 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -6147,12 +6146,12 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "baseline-browser-mapping@npm:^2.8.19": | ||||
|   version: 2.8.21 | ||||
|   resolution: "baseline-browser-mapping@npm:2.8.21" | ||||
| "baseline-browser-mapping@npm:^2.8.9": | ||||
|   version: 2.8.16 | ||||
|   resolution: "baseline-browser-mapping@npm:2.8.16" | ||||
|   bin: | ||||
|     baseline-browser-mapping: dist/cli.js | ||||
|   checksum: 10/4154199589f9d5ca0cf80962494f34967e5bcbe2a3df234f4eb4b7a1766b263062ed47640686ab1d949f1156f5153bdc382ff7815368e365bc86916dc099d61b | ||||
|   checksum: 10/52a5807591daeffc810b783b1afa20c4017dd94e5bb74934bcde4dd408758e492610e330cfe6e609a0f0bde5ce210dd934271540fb931389d6838db17ec8cfef | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -6299,12 +6298,12 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "browserslist-to-es-version@npm:^1.1.1": | ||||
|   version: 1.2.0 | ||||
|   resolution: "browserslist-to-es-version@npm:1.2.0" | ||||
| "browserslist-to-es-version@npm:^1.1.0": | ||||
|   version: 1.1.1 | ||||
|   resolution: "browserslist-to-es-version@npm:1.1.1" | ||||
|   dependencies: | ||||
|     browserslist: "npm:^4.26.2" | ||||
|   checksum: 10/a9af676f4b736fc17cd42cbc98edc735e7f1e775ccb71443afc5ec7184203669f4c6c37ec2d73964c598d7f8fa42ae6ce2ec0e9a9c64fcb1bc297110dbfbd0c9 | ||||
|     browserslist: "npm:^4.25.1" | ||||
|   checksum: 10/efce2f27e67bda030ee3957f6df5aaa8594ee5cf017d3567f1226f6abcea7c3840c1ba73105b6bd661c5f57339e44c6819804609e1f064cfdfb8d53894a9f777 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -6326,18 +6325,18 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "browserslist@npm:^4.24.0, browserslist@npm:^4.25.3, browserslist@npm:^4.26.2": | ||||
|   version: 4.27.0 | ||||
|   resolution: "browserslist@npm:4.27.0" | ||||
| "browserslist@npm:^4.24.0, browserslist@npm:^4.25.1, browserslist@npm:^4.25.3": | ||||
|   version: 4.26.3 | ||||
|   resolution: "browserslist@npm:4.26.3" | ||||
|   dependencies: | ||||
|     baseline-browser-mapping: "npm:^2.8.19" | ||||
|     caniuse-lite: "npm:^1.0.30001751" | ||||
|     electron-to-chromium: "npm:^1.5.238" | ||||
|     node-releases: "npm:^2.0.26" | ||||
|     update-browserslist-db: "npm:^1.1.4" | ||||
|     baseline-browser-mapping: "npm:^2.8.9" | ||||
|     caniuse-lite: "npm:^1.0.30001746" | ||||
|     electron-to-chromium: "npm:^1.5.227" | ||||
|     node-releases: "npm:^2.0.21" | ||||
|     update-browserslist-db: "npm:^1.1.3" | ||||
|   bin: | ||||
|     browserslist: cli.js | ||||
|   checksum: 10/56db4cdb98b5c93797a47e5a60decb144f73a2ae41c60a16c41b75516fabcb0db0116b8cfcf3a26c960cc6c9ab1c4f4801d8d3a743ec72f27acfe5380153ba2f | ||||
|   checksum: 10/49add06fd753a2514d84c75a7de8d9fb3d70be675e53b72981d87f0c0ff40d8a8cd0bd92f77400381704be0bf1c9c5c65aef95d03843d69475ff55188aa12124 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -6481,10 +6480,10 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "caniuse-lite@npm:^1.0.30001751": | ||||
|   version: 1.0.30001751 | ||||
|   resolution: "caniuse-lite@npm:1.0.30001751" | ||||
|   checksum: 10/608f7e1248b7023020382c7dbb0ef389693b3fc98193c3ccea2d44126306d6ac905a5061cf9e62bf640535a86e7a98e563b34c02f909296cfe228f41627a4dc7 | ||||
| "caniuse-lite@npm:^1.0.30001746": | ||||
|   version: 1.0.30001750 | ||||
|   resolution: "caniuse-lite@npm:1.0.30001750" | ||||
|   checksum: 10/2b912758d817cd2c2c179246e282f8b598695ec733bc446183e1d381eada60889c4770a1dfd86075e046a43d55f9922e2eaed1501347fcb12a38716cc14be297 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -7456,10 +7455,10 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "electron-to-chromium@npm:^1.5.238": | ||||
|   version: 1.5.243 | ||||
|   resolution: "electron-to-chromium@npm:1.5.243" | ||||
|   checksum: 10/cc1d566936aa05edcdef45c837bd3bf3c640b297f16d961d6b2b8536efb82bf1938a3dbc6d930e7561ffe4545c3d683dd6ffe57da37c1f6230defd32818785ab | ||||
| "electron-to-chromium@npm:^1.5.227": | ||||
|   version: 1.5.235 | ||||
|   resolution: "electron-to-chromium@npm:1.5.235" | ||||
|   checksum: 10/fbc227d58a07dbb1b01e4a0f624a2fae03881f160a7c2e4416a68f30c83c1ca29b8f0e04056cb2851a6f493ebaf0d3b24bc2c7721d9e779cccbc9faeffef1c0e | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -7745,7 +7744,7 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "es-toolkit@npm:^1.41.0": | ||||
| "es-toolkit@npm:^1.40.0": | ||||
|   version: 1.41.0 | ||||
|   resolution: "es-toolkit@npm:1.41.0" | ||||
|   dependenciesMeta: | ||||
| @@ -9272,7 +9271,7 @@ __metadata: | ||||
|     "@octokit/plugin-retry": "npm:8.0.2" | ||||
|     "@octokit/rest": "npm:22.0.0" | ||||
|     "@replit/codemirror-indentation-markers": "npm:6.5.3" | ||||
|     "@rsdoctor/rspack-plugin": "npm:1.3.6" | ||||
|     "@rsdoctor/rspack-plugin": "npm:1.3.4" | ||||
|     "@rspack/core": "npm:1.5.8" | ||||
|     "@rspack/dev-server": "npm:1.1.4" | ||||
|     "@swc/helpers": "npm:0.5.17" | ||||
| @@ -9300,7 +9299,7 @@ __metadata: | ||||
|     "@vaadin/combo-box": "npm:24.9.2" | ||||
|     "@vaadin/vaadin-themable-mixin": "npm:24.9.2" | ||||
|     "@vibrant/color": "npm:4.0.0" | ||||
|     "@vitest/coverage-v8": "npm:4.0.4" | ||||
|     "@vitest/coverage-v8": "npm:4.0.3" | ||||
|     "@vue/web-component-wrapper": "npm:1.3.0" | ||||
|     "@webcomponents/scoped-custom-element-registry": "npm:0.0.10" | ||||
|     "@webcomponents/webcomponentsjs": "npm:2.8.0" | ||||
| @@ -9385,7 +9384,7 @@ __metadata: | ||||
|     typescript-eslint: "npm:8.46.2" | ||||
|     ua-parser-js: "npm:2.0.6" | ||||
|     vite-tsconfig-paths: "npm:5.1.4" | ||||
|     vitest: "npm:4.0.4" | ||||
|     vitest: "npm:4.0.3" | ||||
|     vue: "npm:2.7.16" | ||||
|     vue2-daterange-picker: "npm:0.6.8" | ||||
|     webpack-stats-plugin: "npm:1.1.3" | ||||
| @@ -11430,10 +11429,10 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "node-releases@npm:^2.0.26": | ||||
|   version: 2.0.27 | ||||
|   resolution: "node-releases@npm:2.0.27" | ||||
|   checksum: 10/f6c78ddb392ae500719644afcbe68a9ea533242c02312eb6a34e8478506eb7482a3fb709c70235b01c32fe65625b68dfa9665113f816d87f163bc3819b62b106 | ||||
| "node-releases@npm:^2.0.21": | ||||
|   version: 2.0.21 | ||||
|   resolution: "node-releases@npm:2.0.21" | ||||
|   checksum: 10/5344d634b39d20f47c0d85a1c64567fdb9cf46f7b27ed3d141f752642faab47dae326835c2109636f823758afb16ffbed7b0c0fe6f800ef91cec9f2beb4f2b4a | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -14538,9 +14537,9 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "update-browserslist-db@npm:^1.1.4": | ||||
|   version: 1.1.4 | ||||
|   resolution: "update-browserslist-db@npm:1.1.4" | ||||
| "update-browserslist-db@npm:^1.1.3": | ||||
|   version: 1.1.3 | ||||
|   resolution: "update-browserslist-db@npm:1.1.3" | ||||
|   dependencies: | ||||
|     escalade: "npm:^3.2.0" | ||||
|     picocolors: "npm:^1.1.1" | ||||
| @@ -14548,7 +14547,7 @@ __metadata: | ||||
|     browserslist: ">= 4.21.0" | ||||
|   bin: | ||||
|     update-browserslist-db: cli.js | ||||
|   checksum: 10/79b2c0a31e9b837b49dc55d5cb7b77f44a69502847c7be352a44b1d35ac2032bf0e1bb7543f992809ed427bf9d32aa3f7ad41cef96198fa959c1666870174c06 | ||||
|   checksum: 10/87af2776054ffb9194cf95e0201547d041f72ee44ce54b144da110e65ea7ca01379367407ba21de5c9edd52c74d95395366790de67f3eb4cc4afa0fe4424e76f | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| @@ -14767,17 +14766,17 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
| "vitest@npm:4.0.4": | ||||
|   version: 4.0.4 | ||||
|   resolution: "vitest@npm:4.0.4" | ||||
| "vitest@npm:4.0.3": | ||||
|   version: 4.0.3 | ||||
|   resolution: "vitest@npm:4.0.3" | ||||
|   dependencies: | ||||
|     "@vitest/expect": "npm:4.0.4" | ||||
|     "@vitest/mocker": "npm:4.0.4" | ||||
|     "@vitest/pretty-format": "npm:4.0.4" | ||||
|     "@vitest/runner": "npm:4.0.4" | ||||
|     "@vitest/snapshot": "npm:4.0.4" | ||||
|     "@vitest/spy": "npm:4.0.4" | ||||
|     "@vitest/utils": "npm:4.0.4" | ||||
|     "@vitest/expect": "npm:4.0.3" | ||||
|     "@vitest/mocker": "npm:4.0.3" | ||||
|     "@vitest/pretty-format": "npm:4.0.3" | ||||
|     "@vitest/runner": "npm:4.0.3" | ||||
|     "@vitest/snapshot": "npm:4.0.3" | ||||
|     "@vitest/spy": "npm:4.0.3" | ||||
|     "@vitest/utils": "npm:4.0.3" | ||||
|     debug: "npm:^4.4.3" | ||||
|     es-module-lexer: "npm:^1.7.0" | ||||
|     expect-type: "npm:^1.2.2" | ||||
| @@ -14795,10 +14794,10 @@ __metadata: | ||||
|     "@edge-runtime/vm": "*" | ||||
|     "@types/debug": ^4.1.12 | ||||
|     "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 | ||||
|     "@vitest/browser-playwright": 4.0.4 | ||||
|     "@vitest/browser-preview": 4.0.4 | ||||
|     "@vitest/browser-webdriverio": 4.0.4 | ||||
|     "@vitest/ui": 4.0.4 | ||||
|     "@vitest/browser-playwright": 4.0.3 | ||||
|     "@vitest/browser-preview": 4.0.3 | ||||
|     "@vitest/browser-webdriverio": 4.0.3 | ||||
|     "@vitest/ui": 4.0.3 | ||||
|     happy-dom: "*" | ||||
|     jsdom: "*" | ||||
|   peerDependenciesMeta: | ||||
| @@ -14822,7 +14821,7 @@ __metadata: | ||||
|       optional: true | ||||
|   bin: | ||||
|     vitest: vitest.mjs | ||||
|   checksum: 10/5a7cd573e1a1daeaa7d874d9a676945aab67c1b5167119e903d50be33f3490f919ea575119efdc473a42d8c42b176bbbc31c12f3c7f1fdd2eb817cc8e162c10a | ||||
|   checksum: 10/535ef75a39d5d3233eeb1050a09cd9b3c9353daad610a442aec16ef657887c16d4a6264d37a4181d487cd07cbb4b2e763ce74b1df037b2850a184983545f3db6 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user