1+ import { mdiContentCopy , mdiDevices , mdiTextureBox } from "@mdi/js" ;
12import { consume } from "@lit/context" ;
23import type { HassEntity } from "home-assistant-js-websocket" ;
3- import type { CSSResultGroup , PropertyValues } from "lit" ;
4+ import type { CSSResultGroup , PropertyValues , TemplateResult } from "lit" ;
45import { css , html , LitElement , nothing } from "lit" ;
56import { customElement , property , state } from "lit/decorators" ;
67import memoizeOne from "memoize-one" ;
@@ -11,8 +12,14 @@ import { getEntityContext } from "../../common/entity/context/get_entity_context
1112import checkValidDate from "../../common/datetime/check_valid_date" ;
1213import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time" ;
1314import "../../components/ha-attribute-value" ;
15+ import "../../components/ha-floor-icon" ;
16+ import "../../components/ha-icon" ;
17+ import "../../components/ha-icon-next" ;
18+ import "../../components/ha-svg-icon" ;
19+ import "../../components/item/ha-list-item-button" ;
1420import "../../components/item/ha-list-item-value" ;
1521import "../../components/list/ha-grouped-list" ;
22+ import { copyToClipboard } from "../../common/util/copy-clipboard" ;
1623import type { LocalizeKeys } from "../../common/translations/localize" ;
1724import { labelsContext } from "../../data/context" ;
1825import type { ExtEntityRegistryEntry } from "../../data/entity/entity_registry" ;
@@ -25,6 +32,8 @@ import { getFeatures } from "../../common/entity/get_domain_features";
2532import { supportsFeature } from "../../common/entity/supports-feature" ;
2633import { titleCase } from "../../common/string/title-case" ;
2734import { stringCompare } from "../../common/string/compare" ;
35+ import { brandsUrl } from "../../util/brands-url" ;
36+ import { showToast } from "../../util/toast" ;
2837
2938interface DetailsViewParams {
3039 entityId : string ;
@@ -34,6 +43,8 @@ interface DetailEntry {
3443 translationKey : LocalizeKeys ;
3544 value : string ;
3645 href ?: string ;
46+ icon ?: TemplateResult ;
47+ copyable ?: boolean ;
3748}
3849
3950@customElement ( "ha-more-info-details" )
@@ -106,20 +117,25 @@ class HaMoreInfoDetails extends LitElement {
106117 translationKey : "ui.dialogs.more_info_control.floor" ,
107118 value : floorName ,
108119 href : "/config/areas/dashboard" ,
120+ icon : html `<ha- floor - icon slot= "end" .floor = ${ floor } > </ ha- floor - icon> ` ,
109121 } ) ;
110122 }
111123 if ( area && areaName ) {
112124 contextEntries . push ( {
113125 translationKey : "ui.components.related-items.area" ,
114126 value : areaName ,
115127 href : `/config/areas/area/${ area . area_id } ` ,
128+ icon : area . icon
129+ ? html `<ha- icon slot= "end" .icon = ${ area . icon } > </ ha- icon> `
130+ : html `<ha- svg- icon slot= "end" .path = ${ mdiTextureBox } > </ ha- svg- icon> ` ,
116131 } ) ;
117132 }
118133 if ( device && deviceName ) {
119134 contextEntries . push ( {
120135 translationKey : "ui.components.related-items.device" ,
121136 value : deviceName ,
122137 href : `/config/devices/device/${ device . id } ` ,
138+ icon : html `<ha- svg- icon slot= "end" .path = ${ mdiDevices } > </ ha- svg- icon> ` ,
123139 } ) ;
124140 }
125141 if ( this . entry ?. platform && integrationName ) {
@@ -129,31 +145,40 @@ class HaMoreInfoDetails extends LitElement {
129145 href : this . entry . config_entry_id
130146 ? `/config/integrations/integration/${ this . entry . platform } #config_entry=${ this . entry . config_entry_id } `
131147 : undefined ,
148+ icon : html `<img
149+ slot= "end"
150+ alt = ""
151+ crossor igin= "anonymous"
152+ referrerpolicy= "no- referrer"
153+ src= ${ brandsUrl (
154+ {
155+ domain : this . entry . platform ,
156+ type : "icon" ,
157+ darkOptimized : this . hass . themes ?. darkMode ,
158+ } ,
159+ this . hass . auth . data . hassUrl
160+ ) }
161+ / > ` ,
132162 } ) ;
133163 }
134164
135- const entityEntries : DetailEntry [ ] = [
165+ contextEntries . push (
136166 {
137167 translationKey : "ui.dialogs.more_info_control.entity_id" ,
138168 value : this . params . entityId ,
169+ copyable : true ,
139170 } ,
140171 {
141172 translationKey : "ui.dialogs.more_info_control.labels" ,
142173 value : labelNames . join ( ", " ) || this . hass . localize ( "ui.common.none" ) ,
143- } ,
144- ] ;
174+ }
175+ ) ;
145176 const yamlData = {
146- ...( contextEntries . length
147- ? {
148- context : {
149- ...( floorName ? { floor : floorName } : { } ) ,
150- ...( areaName ? { area : areaName } : { } ) ,
151- ...( deviceName ? { device : deviceName } : { } ) ,
152- ...( integrationName ? { integration : integrationName } : { } ) ,
153- } ,
154- }
155- : { } ) ,
156- entity : {
177+ context : {
178+ ...( floorName ? { floor : floorName } : { } ) ,
179+ ...( areaName ? { area : areaName } : { } ) ,
180+ ...( deviceName ? { device : deviceName } : { } ) ,
181+ ...( integrationName ? { integration : integrationName } : { } ) ,
157182 entity_id : this . params . entityId ,
158183 labels : labelNames ,
159184 } ,
@@ -171,17 +196,9 @@ class HaMoreInfoDetails extends LitElement {
171196 in- dialog
172197 > </ ha- yaml- edito r> `
173198 : html `
174- ${
175- contextEntries . length
176- ? html `<ha- grouped- lis t
177- .header = ${ this . hass . localize (
178- "ui.dialogs.more_info_control.context"
179- ) }
180- >
181- ${ this . _renderEntries ( contextEntries ) }
182- </ ha- grouped- lis t> `
183- : nothing
184- }
199+ <ha- grouped- lis t>
200+ ${ this . _renderEntries ( contextEntries ) }
201+ </ ha- grouped- lis t>
185202
186203 <ha- grouped- lis t
187204 .header = ${ this . hass . localize (
@@ -191,14 +208,6 @@ class HaMoreInfoDetails extends LitElement {
191208 ${ this . _renderEntries ( stateEntries ) }
192209 </ ha- grouped- lis t>
193210
194- <ha- grouped- lis t
195- .header = ${ this . hass . localize (
196- "ui.dialogs.more_info_control.entity"
197- ) }
198- >
199- ${ this . _renderEntries ( entityEntries ) }
200- </ ha- grouped- lis t>
201-
202211 <ha- grouped- lis t
203212 .header = ${ this . hass . localize (
204213 "ui.dialogs.more_info_control.attributes"
@@ -284,17 +293,54 @@ class HaMoreInfoDetails extends LitElement {
284293 }
285294
286295 private _renderEntries ( entries : DetailEntry [ ] ) {
287- return entries . map (
288- ( entry ) => html `
289- <ha- lis t- item- value .label = ${ this . hass . localize ( entry . translationKey ) } >
290- ${
291- entry . href
292- ? html `<a href= ${ entry . href } > ${ entry . value } </ a> `
293- : entry . value
294- }
295- </ ha- lis t- item- value>
296- `
297- ) ;
296+ return entries . map ( ( entry ) => {
297+ const label = this . hass . localize ( entry . translationKey ) ;
298+
299+ if ( ! entry . href && ! entry . copyable ) {
300+ return html `
301+ <ha- lis t- item- value .label = ${ label }
302+ > ${ entry . value } </ ha- lis t- item- value
303+ >
304+ ` ;
305+ }
306+
307+ if ( entry . copyable ) {
308+ return html `
309+ <ha- lis t- item- butto n
310+ data- value= ${ entry . value }
311+ @click = ${ this . _copyValue }
312+ >
313+ <div class= "link-row" slot = "content">
314+ <div class= "label" > ${ label } </ div>
315+ <div class= "value" > ${ entry . value } </ div>
316+ </ div>
317+ <ha- svg- icon slot= "end" .path = ${ mdiContentCopy } > </ ha- svg- icon>
318+ </ ha- lis t- item- butto n>
319+ ` ;
320+ }
321+
322+ return html `
323+ <ha- lis t- item- butto n .href = ${ entry . href } >
324+ <div class= "link-row" slot = "content">
325+ <div class= "label" > ${ label } </ div>
326+ <div class= "value" > ${ entry . value } </ div>
327+ </ div>
328+ ${ entry . icon ?? nothing }
329+ <ha- icon- next slot= "end" > </ ha- icon- next>
330+ </ ha- lis t- item- butto n>
331+ ` ;
332+ } ) ;
333+ }
334+
335+ private async _copyValue ( ev : Event ) {
336+ const value = ( ev . currentTarget as HTMLElement ) . dataset . value ;
337+ if ( value === undefined ) {
338+ return ;
339+ }
340+ await copyToClipboard ( value ) ;
341+ showToast ( this , {
342+ message : this . hass . localize ( "ui.common.copied_clipboard" ) ,
343+ } ) ;
298344 }
299345
300346 private _renderAttributes ( attributes : { name : string ; label : string } [ ] ) {
@@ -358,11 +404,47 @@ class HaMoreInfoDetails extends LitElement {
358404 }
359405
360406 ha-grouped-list + ha-grouped-list {
361- margin-top : var (--ha-space-4 );
407+ margin-top : var (--ha-space-6 );
408+ }
409+
410+ ha-list-item-button {
411+ --ha-row-item-padding-block : var (--ha-space-2 );
412+ --ha-row-item-min-height : 40px ;
413+ --ha-row-item-gap : var (--ha-space-3 );
414+ --mdc-icon-size : 20px ;
415+ }
416+
417+ ha-list-item-button ::part (end ) {
418+ gap : var (--ha-space-2 );
419+ }
420+
421+ ha-list-item-button img {
422+ width : 20px ;
423+ height : 20px ;
424+ object-fit : contain;
362425 }
363426
364- a {
365- color : var (--primary-color );
427+ .link-row {
428+ display : flex;
429+ flex-direction : row;
430+ align-items : center;
431+ gap : var (--ha-space-3 );
432+ }
433+
434+ .link-row .label {
435+ flex : 1 ;
436+ color : var (--secondary-text-color );
437+ }
438+
439+ .link-row .value {
440+ max-width : 60% ;
441+ min-width : 0 ;
442+ text-align : end;
443+ overflow-wrap : anywhere;
444+ }
445+
446+ ha-icon-next {
447+ color : var (--secondary-text-color );
366448 }
367449
368450 .empty {
0 commit comments