Skip to content

Commit d6ab8ff

Browse files
committed
Resolve service name and icon for shortcut card and badge (#51850)
1 parent 2dc4b16 commit d6ab8ff

14 files changed

Lines changed: 301 additions & 50 deletions

src/components/ha-condition-icon.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ export class HaConditionIcon extends LitElement {
5555
return this._renderFallback();
5656
}
5757

58-
const icon = conditionIcon(this.hass, this.condition).then((icn) => {
58+
const icon = conditionIcon(
59+
this.hass.connection,
60+
this.hass.config,
61+
this.condition
62+
).then((icn) => {
5963
if (icn) {
6064
return html`<ha-icon .icon=${icn}></ha-icon>`;
6165
}

src/components/ha-service-icon.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ export class HaServiceIcon extends LitElement {
3232
return this._renderFallback();
3333
}
3434

35-
const icon = serviceIcon(this.hass, this.service).then((icn) => {
35+
const icon = serviceIcon(
36+
this.hass.connection,
37+
this.hass.config,
38+
this.service
39+
).then((icn) => {
3640
if (icn) {
3741
return html`<ha-icon .icon=${icn}></ha-icon>`;
3842
}

src/components/ha-service-picker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class HaServicePicker extends LitElement {
5454
protected firstUpdated(props: PropertyValues<this>) {
5555
super.firstUpdated(props);
5656
this.hass.loadBackendTranslation("services");
57-
getServiceIcons(this.hass);
57+
getServiceIcons(this.hass.connection, this.hass.config);
5858
}
5959

6060
private _rowRenderer: RenderItemFunction<ServiceComboBoxItem> = (

src/components/ha-service-section-icon.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,17 @@ export class HaServiceSectionIcon extends LitElement {
2929
return this._renderFallback();
3030
}
3131

32-
const icon = serviceSectionIcon(this.hass, this.service, this.section).then(
33-
(icn) => {
34-
if (icn) {
35-
return html`<ha-icon .icon=${icn}></ha-icon>`;
36-
}
37-
return this._renderFallback();
32+
const icon = serviceSectionIcon(
33+
this.hass.connection,
34+
this.hass.config,
35+
this.service,
36+
this.section
37+
).then((icn) => {
38+
if (icn) {
39+
return html`<ha-icon .icon=${icn}></ha-icon>`;
3840
}
39-
);
41+
return this._renderFallback();
42+
});
4043

4144
return html`${until(icon)}`;
4245
}

src/components/ha-trigger-icon.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ export class HaTriggerIcon extends LitElement {
6969
return this._renderFallback();
7070
}
7171

72-
const icon = triggerIcon(this.hass, this.trigger).then((icn) => {
72+
const icon = triggerIcon(
73+
this.hass.connection,
74+
this.hass.config,
75+
this.trigger
76+
).then((icn) => {
7377
if (icn) {
7478
return html`<ha-icon .icon=${icn}></ha-icon>`;
7579
}

src/data/compute-service-info.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { computeDomain } from "../common/entity/compute_domain";
2+
import { computeObjectId } from "../common/entity/compute_object_id";
3+
import type { LocalizeFunc } from "../common/translations/localize";
4+
import { DEFAULT_SERVICE_ICON } from "./icons";
5+
import type { HomeAssistant } from "../types";
6+
7+
export interface ServiceInfo {
8+
label: string;
9+
icon?: string;
10+
iconPath: string;
11+
}
12+
13+
export const DEFAULT_SERVICE_INFO: ServiceInfo = {
14+
label: "",
15+
iconPath: DEFAULT_SERVICE_ICON,
16+
};
17+
18+
export const computeServiceLabel = (
19+
localize: LocalizeFunc,
20+
services: HomeAssistant["services"],
21+
service: string
22+
): string => {
23+
const domain = computeDomain(service);
24+
const serviceName = computeObjectId(service);
25+
const serviceDef = services[domain]?.[serviceName];
26+
return (
27+
localize(
28+
`component.${domain}.services.${serviceName}.name`,
29+
serviceDef?.description_placeholders
30+
) ||
31+
serviceDef?.name ||
32+
service
33+
);
34+
};

src/data/icons.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ export const getComponentIcons = async (
323323
export const getCategoryIcons = async <
324324
T extends Exclude<IconCategory, "entity" | "entity_component">,
325325
>(
326-
hass: HomeAssistant,
326+
connection: Connection,
327+
hassConfig: HomeAssistant["config"],
327328
category: T,
328329
domain?: string,
329330
force = false
@@ -334,12 +335,10 @@ export const getCategoryIcons = async <
334335
Record<string, CategoryType[T]>
335336
>;
336337
}
337-
resources[category].all = getHassIcons(hass.connection, category).then(
338-
(res) => {
339-
resources[category].domains = res.resources as any;
340-
return res?.resources as Record<string, CategoryType[T]>;
341-
}
342-
) as any;
338+
resources[category].all = getHassIcons(connection, category).then((res) => {
339+
resources[category].domains = res.resources as any;
340+
return res?.resources as Record<string, CategoryType[T]>;
341+
}) as any;
343342
return resources[category].all as Promise<Record<string, CategoryType[T]>>;
344343
}
345344
if (!force && domain in resources[category].domains) {
@@ -351,36 +350,39 @@ export const getCategoryIcons = async <
351350
return resources[category].domains[domain] as Promise<CategoryType[T]>;
352351
}
353352
}
354-
if (!isComponentLoaded(hass.config, domain)) {
353+
if (!isComponentLoaded(hassConfig, domain)) {
355354
return undefined;
356355
}
357-
const result = getHassIcons(hass.connection, category, domain);
356+
const result = getHassIcons(connection, category, domain);
358357
resources[category].domains[domain] = result.then(
359358
(res) => res?.resources[domain]
360359
) as any;
361360
return resources[category].domains[domain] as Promise<CategoryType[T]>;
362361
};
363362

364363
export const getServiceIcons = async (
365-
hass: HomeAssistant,
364+
connection: Connection,
365+
hassConfig: HomeAssistant["config"],
366366
domain?: string,
367367
force = false
368368
): Promise<ServiceIcons | Record<string, ServiceIcons> | undefined> =>
369-
getCategoryIcons(hass, "services", domain, force);
369+
getCategoryIcons(connection, hassConfig, "services", domain, force);
370370

371371
export const getTriggerIcons = async (
372-
hass: HomeAssistant,
372+
connection: Connection,
373+
hassConfig: HomeAssistant["config"],
373374
domain?: string,
374375
force = false
375376
): Promise<TriggerIcons | Record<string, TriggerIcons> | undefined> =>
376-
getCategoryIcons(hass, "triggers", domain, force);
377+
getCategoryIcons(connection, hassConfig, "triggers", domain, force);
377378

378379
export const getConditionIcons = async (
379-
hass: HomeAssistant,
380+
connection: Connection,
381+
hassConfig: HomeAssistant["config"],
380382
domain?: string,
381383
force = false
382384
): Promise<ConditionIcons | Record<string, ConditionIcons> | undefined> =>
383-
getCategoryIcons(hass, "conditions", domain, force);
385+
getCategoryIcons(connection, hassConfig, "conditions", domain, force);
384386

385387
// Cache for sorted range keys
386388
const sortedRangeCache = new WeakMap<Record<string, string>, number[]>();
@@ -578,70 +580,78 @@ export const attributeIcon = async (
578580
};
579581

580582
export const triggerIcon = async (
581-
hass: HomeAssistant,
583+
connection: Connection,
584+
hassConfig: HomeAssistant["config"],
582585
trigger: string
583586
): Promise<string | undefined> => {
584587
let icon: string | undefined;
585588

586589
const domain = getTriggerDomain(trigger);
587590
const triggerName = getTriggerObjectId(trigger);
588591

589-
const triggerIcons = await getTriggerIcons(hass, domain);
592+
const triggerIcons = await getTriggerIcons(connection, hassConfig, domain);
590593
if (triggerIcons) {
591594
const trgrIcon = triggerIcons[triggerName] as TriggerIcons[string];
592595
icon = trgrIcon?.trigger;
593596
}
594597
if (!icon) {
595-
icon = await domainIcon(hass.connection, hass.config, domain);
598+
icon = await domainIcon(connection, hassConfig, domain);
596599
}
597600
return icon;
598601
};
599602

600603
export const conditionIcon = async (
601-
hass: HomeAssistant,
604+
connection: Connection,
605+
hassConfig: HomeAssistant["config"],
602606
condition: string
603607
): Promise<string | undefined> => {
604608
let icon: string | undefined;
605609

606610
const domain = getConditionDomain(condition);
607-
const conditionIcons = await getConditionIcons(hass, domain);
611+
const conditionIcons = await getConditionIcons(
612+
connection,
613+
hassConfig,
614+
domain
615+
);
608616
if (conditionIcons) {
609617
const conditionName = getConditionObjectId(condition);
610618
const condIcon = conditionIcons[conditionName] as ConditionIcons[string];
611619
icon = condIcon?.condition;
612620
}
613621
if (!icon) {
614-
icon = await domainIcon(hass.connection, hass.config, domain);
622+
icon = await domainIcon(connection, hassConfig, domain);
615623
}
616624
return icon;
617625
};
618626

619627
export const serviceIcon = async (
620-
hass: HomeAssistant,
628+
connection: Connection,
629+
hassConfig: HomeAssistant["config"],
621630
service: string
622631
): Promise<string | undefined> => {
623632
let icon: string | undefined;
624633
const domain = computeDomain(service);
625634
const serviceName = computeObjectId(service);
626-
const serviceIcons = await getServiceIcons(hass, domain);
635+
const serviceIcons = await getServiceIcons(connection, hassConfig, domain);
627636
if (serviceIcons) {
628637
const srvceIcon = serviceIcons[serviceName] as ServiceIcons[string];
629638
icon = srvceIcon?.service;
630639
}
631640
if (!icon) {
632-
icon = await domainIcon(hass.connection, hass.config, domain);
641+
icon = await domainIcon(connection, hassConfig, domain);
633642
}
634643
return icon;
635644
};
636645

637646
export const serviceSectionIcon = async (
638-
hass: HomeAssistant,
647+
connection: Connection,
648+
hassConfig: HomeAssistant["config"],
639649
service: string,
640650
section: string
641651
): Promise<string | undefined> => {
642652
const domain = computeDomain(service);
643653
const serviceName = computeObjectId(service);
644-
const serviceIcons = await getServiceIcons(hass, domain);
654+
const serviceIcons = await getServiceIcons(connection, hassConfig, domain);
645655
if (serviceIcons) {
646656
const srvceIcon = serviceIcons[serviceName] as ServiceIcons[string];
647657
return srvceIcon?.sections?.[section];

0 commit comments

Comments
 (0)