mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-23 16:38:17 +00:00
Compare commits
3 Commits
quick-bar-
...
integratio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c16c78984 | ||
|
|
767d43021f | ||
|
|
fbeab4e151 |
@@ -6,6 +6,7 @@ import {
|
||||
mdiEarth,
|
||||
mdiKeyboard,
|
||||
mdiMagnify,
|
||||
mdiPuzzle,
|
||||
mdiReload,
|
||||
mdiServerNetwork,
|
||||
} from "@mdi/js";
|
||||
@@ -94,12 +95,22 @@ interface DeviceItem extends QuickBarItem {
|
||||
area?: string;
|
||||
}
|
||||
|
||||
interface IntegrationItem extends QuickBarItem {
|
||||
domain: string;
|
||||
translatedDomain: string;
|
||||
}
|
||||
|
||||
const isCommandItem = (item: QuickBarItem): item is CommandItem =>
|
||||
(item as CommandItem).categoryKey !== undefined;
|
||||
|
||||
const isDeviceItem = (item: QuickBarItem): item is DeviceItem =>
|
||||
(item as DeviceItem).deviceId !== undefined;
|
||||
|
||||
const isIntegrationItem = (item: QuickBarItem): item is IntegrationItem =>
|
||||
(item as DeviceItem).deviceId === undefined &&
|
||||
(item as IntegrationItem).domain !== undefined &&
|
||||
(item as IntegrationItem).translatedDomain !== undefined;
|
||||
|
||||
interface QuickBarNavigationItem extends CommandItem {
|
||||
path: string;
|
||||
}
|
||||
@@ -121,6 +132,8 @@ export class QuickBar extends LitElement {
|
||||
|
||||
@state() private _deviceItems?: DeviceItem[];
|
||||
|
||||
@state() private _integrationItems?: IntegrationItem[];
|
||||
|
||||
@state() private _filter = "";
|
||||
|
||||
@state() private _search = "";
|
||||
@@ -159,6 +172,8 @@ export class QuickBar extends LitElement {
|
||||
this._search = "";
|
||||
this._entityItems = undefined;
|
||||
this._commandItems = undefined;
|
||||
this._deviceItems = undefined;
|
||||
this._integrationItems = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
@@ -174,6 +189,7 @@ export class QuickBar extends LitElement {
|
||||
commandItems,
|
||||
entityItems,
|
||||
deviceItems,
|
||||
integrationItems,
|
||||
filter: string
|
||||
) => {
|
||||
let items = entityItems;
|
||||
@@ -182,6 +198,8 @@ export class QuickBar extends LitElement {
|
||||
items = commandItems;
|
||||
} else if (mode === QuickBarMode.Device) {
|
||||
items = deviceItems;
|
||||
} else if (mode === QuickBarMode.Integration) {
|
||||
items = integrationItems;
|
||||
}
|
||||
|
||||
if (items && filter && filter !== " ") {
|
||||
@@ -201,25 +219,37 @@ export class QuickBar extends LitElement {
|
||||
this._commandItems,
|
||||
this._entityItems,
|
||||
this._deviceItems,
|
||||
this._integrationItems,
|
||||
this._filter
|
||||
);
|
||||
|
||||
const translationKey =
|
||||
this._mode === QuickBarMode.Device
|
||||
? "filter_placeholder_devices"
|
||||
: "filter_placeholder";
|
||||
: this._mode === QuickBarMode.Integration
|
||||
? "filter_placeholder_integrations"
|
||||
: "filter_placeholder";
|
||||
const placeholder = this.hass.localize(
|
||||
`ui.dialogs.quick-bar.${translationKey}`
|
||||
);
|
||||
|
||||
const commandMode = this._mode === QuickBarMode.Command;
|
||||
const deviceMode = this._mode === QuickBarMode.Device;
|
||||
const integrationMode = this._mode === QuickBarMode.Integration;
|
||||
const icon = commandMode
|
||||
? mdiConsoleLine
|
||||
: deviceMode
|
||||
? mdiDevices
|
||||
: mdiMagnify;
|
||||
const searchPrefix = commandMode ? ">" : deviceMode ? "#" : "";
|
||||
: integrationMode
|
||||
? mdiPuzzle
|
||||
: mdiMagnify;
|
||||
const searchPrefix = commandMode
|
||||
? ">"
|
||||
: deviceMode
|
||||
? "#"
|
||||
: integrationMode
|
||||
? "@"
|
||||
: "";
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
@@ -318,6 +348,9 @@ export class QuickBar extends LitElement {
|
||||
} else if (this._mode === QuickBarMode.Device) {
|
||||
this._deviceItems =
|
||||
this._deviceItems || (await this._generateDeviceItems());
|
||||
} else if (this._mode === QuickBarMode.Integration) {
|
||||
this._integrationItems =
|
||||
this._integrationItems || (await this._generateIntegrationItems());
|
||||
} else {
|
||||
this._entityItems =
|
||||
this._entityItems || (await this._generateEntityItems());
|
||||
@@ -352,6 +385,10 @@ export class QuickBar extends LitElement {
|
||||
return this._renderCommandItem(item, index);
|
||||
}
|
||||
|
||||
if (isIntegrationItem(item)) {
|
||||
return this._renderIntegrationItem(item, index);
|
||||
}
|
||||
|
||||
return this._renderEntityItem(item as EntityItem, index);
|
||||
};
|
||||
|
||||
@@ -459,6 +496,35 @@ export class QuickBar extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderIntegrationItem(item: IntegrationItem, index?: number) {
|
||||
return html`
|
||||
<ha-md-list-item
|
||||
class="two-line"
|
||||
.item=${item}
|
||||
index=${ifDefined(index)}
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
slot="start"
|
||||
alt=""
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
src=${brandsUrl({
|
||||
domain: item.domain,
|
||||
type: "icon",
|
||||
useFallback: true,
|
||||
darkOptimized: this.hass.themes?.darkMode,
|
||||
})}
|
||||
/>
|
||||
<span slot="headline">${item.primaryText}</span>
|
||||
<div slot="trailing-supporting-text" class="domain">
|
||||
${item.translatedDomain}
|
||||
</div>
|
||||
</ha-md-list-item>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _processItemAndCloseDialog(item: QuickBarItem, index: number) {
|
||||
this._addSpinnerToCommandItem(index);
|
||||
|
||||
@@ -507,6 +573,9 @@ export class QuickBar extends LitElement {
|
||||
} else if (newFilter.startsWith("#")) {
|
||||
newMode = QuickBarMode.Device;
|
||||
newSearch = newFilter.substring(1);
|
||||
} else if (newFilter.startsWith("@")) {
|
||||
newMode = QuickBarMode.Integration;
|
||||
newSearch = newFilter.substring(1);
|
||||
} else {
|
||||
newMode = QuickBarMode.Entity;
|
||||
newSearch = newFilter;
|
||||
@@ -706,6 +775,43 @@ export class QuickBar extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private async _generateIntegrationItems(): Promise<IntegrationItem[]> {
|
||||
const configEntries = await getConfigEntries(this.hass);
|
||||
|
||||
// Get unique domains from enabled entries
|
||||
const domains = new Set<string>();
|
||||
for (const entry of configEntries) {
|
||||
if (entry.disabled_by || entry.source === "ignore") {
|
||||
continue;
|
||||
}
|
||||
domains.add(entry.domain);
|
||||
}
|
||||
|
||||
const integrationItems: IntegrationItem[] = [];
|
||||
|
||||
for (const domain of domains) {
|
||||
const translatedDomain = domainToName(this.hass.localize, domain);
|
||||
const primaryText = translatedDomain;
|
||||
|
||||
integrationItems.push({
|
||||
id: `integration-${domain}`,
|
||||
primaryText,
|
||||
domain,
|
||||
translatedDomain,
|
||||
action: () => navigate(`/config/integrations/integration/${domain}`),
|
||||
strings: [primaryText, domain, translatedDomain],
|
||||
});
|
||||
}
|
||||
|
||||
return integrationItems.sort((a, b) =>
|
||||
caseInsensitiveStringCompare(
|
||||
a.primaryText,
|
||||
b.primaryText,
|
||||
this.hass.locale.language
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private async _generateCommandItems(): Promise<CommandItem[]> {
|
||||
return [
|
||||
...(await this._generateReloadCommands()),
|
||||
|
||||
@@ -4,6 +4,7 @@ export const enum QuickBarMode {
|
||||
Command = "command",
|
||||
Device = "device",
|
||||
Entity = "entity",
|
||||
Integration = "integration",
|
||||
}
|
||||
|
||||
export interface QuickBarParams {
|
||||
|
||||
@@ -47,6 +47,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
case "d":
|
||||
this._showQuickBar(ev.detail, QuickBarMode.Device);
|
||||
break;
|
||||
case "i":
|
||||
this._showQuickBar(ev.detail, QuickBarMode.Integration);
|
||||
break;
|
||||
case "m":
|
||||
this._createMyLink(ev.detail);
|
||||
break;
|
||||
@@ -70,6 +73,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
m: { handler: (ev) => this._createMyLink(ev) },
|
||||
a: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||
d: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
||||
i: {
|
||||
handler: (ev) => this._showQuickBar(ev, QuickBarMode.Integration),
|
||||
},
|
||||
// Workaround see https://github.com/jamiebuilds/tinykeys/issues/130
|
||||
"Shift+?": { handler: (ev) => this._showShortcutDialog(ev) },
|
||||
// Those are fallbacks for non-latin keyboards that don't have e, c, m keys (qwerty-based shortcuts)
|
||||
@@ -78,6 +84,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
KeyM: { handler: (ev) => this._createMyLink(ev) },
|
||||
KeyA: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||
KeyD: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
||||
KeyI: {
|
||||
handler: (ev) => this._showQuickBar(ev, QuickBarMode.Integration),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1407,6 +1407,7 @@
|
||||
},
|
||||
"filter_placeholder": "Search entities",
|
||||
"filter_placeholder_devices": "Search devices",
|
||||
"filter_placeholder_integrations": "Search integrations",
|
||||
"title": "Quick search",
|
||||
"key_c_tip": "[%key:ui::tips::key_c_tip%]",
|
||||
"nothing_found": "Nothing found!"
|
||||
|
||||
Reference in New Issue
Block a user