mirror of
https://github.com/home-assistant/frontend.git
synced 2026-07-15 16:54:03 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c16c78984 | |||
| 767d43021f | |||
| fbeab4e151 |
@@ -6,6 +6,7 @@ import {
|
|||||||
mdiEarth,
|
mdiEarth,
|
||||||
mdiKeyboard,
|
mdiKeyboard,
|
||||||
mdiMagnify,
|
mdiMagnify,
|
||||||
|
mdiPuzzle,
|
||||||
mdiReload,
|
mdiReload,
|
||||||
mdiServerNetwork,
|
mdiServerNetwork,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
@@ -94,12 +95,22 @@ interface DeviceItem extends QuickBarItem {
|
|||||||
area?: string;
|
area?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IntegrationItem extends QuickBarItem {
|
||||||
|
domain: string;
|
||||||
|
translatedDomain: string;
|
||||||
|
}
|
||||||
|
|
||||||
const isCommandItem = (item: QuickBarItem): item is CommandItem =>
|
const isCommandItem = (item: QuickBarItem): item is CommandItem =>
|
||||||
(item as CommandItem).categoryKey !== undefined;
|
(item as CommandItem).categoryKey !== undefined;
|
||||||
|
|
||||||
const isDeviceItem = (item: QuickBarItem): item is DeviceItem =>
|
const isDeviceItem = (item: QuickBarItem): item is DeviceItem =>
|
||||||
(item as DeviceItem).deviceId !== undefined;
|
(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 {
|
interface QuickBarNavigationItem extends CommandItem {
|
||||||
path: string;
|
path: string;
|
||||||
}
|
}
|
||||||
@@ -121,6 +132,8 @@ export class QuickBar extends LitElement {
|
|||||||
|
|
||||||
@state() private _deviceItems?: DeviceItem[];
|
@state() private _deviceItems?: DeviceItem[];
|
||||||
|
|
||||||
|
@state() private _integrationItems?: IntegrationItem[];
|
||||||
|
|
||||||
@state() private _filter = "";
|
@state() private _filter = "";
|
||||||
|
|
||||||
@state() private _search = "";
|
@state() private _search = "";
|
||||||
@@ -159,6 +172,8 @@ export class QuickBar extends LitElement {
|
|||||||
this._search = "";
|
this._search = "";
|
||||||
this._entityItems = undefined;
|
this._entityItems = undefined;
|
||||||
this._commandItems = undefined;
|
this._commandItems = undefined;
|
||||||
|
this._deviceItems = undefined;
|
||||||
|
this._integrationItems = undefined;
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +189,7 @@ export class QuickBar extends LitElement {
|
|||||||
commandItems,
|
commandItems,
|
||||||
entityItems,
|
entityItems,
|
||||||
deviceItems,
|
deviceItems,
|
||||||
|
integrationItems,
|
||||||
filter: string
|
filter: string
|
||||||
) => {
|
) => {
|
||||||
let items = entityItems;
|
let items = entityItems;
|
||||||
@@ -182,6 +198,8 @@ export class QuickBar extends LitElement {
|
|||||||
items = commandItems;
|
items = commandItems;
|
||||||
} else if (mode === QuickBarMode.Device) {
|
} else if (mode === QuickBarMode.Device) {
|
||||||
items = deviceItems;
|
items = deviceItems;
|
||||||
|
} else if (mode === QuickBarMode.Integration) {
|
||||||
|
items = integrationItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items && filter && filter !== " ") {
|
if (items && filter && filter !== " ") {
|
||||||
@@ -201,25 +219,37 @@ export class QuickBar extends LitElement {
|
|||||||
this._commandItems,
|
this._commandItems,
|
||||||
this._entityItems,
|
this._entityItems,
|
||||||
this._deviceItems,
|
this._deviceItems,
|
||||||
|
this._integrationItems,
|
||||||
this._filter
|
this._filter
|
||||||
);
|
);
|
||||||
|
|
||||||
const translationKey =
|
const translationKey =
|
||||||
this._mode === QuickBarMode.Device
|
this._mode === QuickBarMode.Device
|
||||||
? "filter_placeholder_devices"
|
? "filter_placeholder_devices"
|
||||||
: "filter_placeholder";
|
: this._mode === QuickBarMode.Integration
|
||||||
|
? "filter_placeholder_integrations"
|
||||||
|
: "filter_placeholder";
|
||||||
const placeholder = this.hass.localize(
|
const placeholder = this.hass.localize(
|
||||||
`ui.dialogs.quick-bar.${translationKey}`
|
`ui.dialogs.quick-bar.${translationKey}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const commandMode = this._mode === QuickBarMode.Command;
|
const commandMode = this._mode === QuickBarMode.Command;
|
||||||
const deviceMode = this._mode === QuickBarMode.Device;
|
const deviceMode = this._mode === QuickBarMode.Device;
|
||||||
|
const integrationMode = this._mode === QuickBarMode.Integration;
|
||||||
const icon = commandMode
|
const icon = commandMode
|
||||||
? mdiConsoleLine
|
? mdiConsoleLine
|
||||||
: deviceMode
|
: deviceMode
|
||||||
? mdiDevices
|
? mdiDevices
|
||||||
: mdiMagnify;
|
: integrationMode
|
||||||
const searchPrefix = commandMode ? ">" : deviceMode ? "#" : "";
|
? mdiPuzzle
|
||||||
|
: mdiMagnify;
|
||||||
|
const searchPrefix = commandMode
|
||||||
|
? ">"
|
||||||
|
: deviceMode
|
||||||
|
? "#"
|
||||||
|
: integrationMode
|
||||||
|
? "@"
|
||||||
|
: "";
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
@@ -318,6 +348,9 @@ export class QuickBar extends LitElement {
|
|||||||
} else if (this._mode === QuickBarMode.Device) {
|
} else if (this._mode === QuickBarMode.Device) {
|
||||||
this._deviceItems =
|
this._deviceItems =
|
||||||
this._deviceItems || (await this._generateDeviceItems());
|
this._deviceItems || (await this._generateDeviceItems());
|
||||||
|
} else if (this._mode === QuickBarMode.Integration) {
|
||||||
|
this._integrationItems =
|
||||||
|
this._integrationItems || (await this._generateIntegrationItems());
|
||||||
} else {
|
} else {
|
||||||
this._entityItems =
|
this._entityItems =
|
||||||
this._entityItems || (await this._generateEntityItems());
|
this._entityItems || (await this._generateEntityItems());
|
||||||
@@ -352,6 +385,10 @@ export class QuickBar extends LitElement {
|
|||||||
return this._renderCommandItem(item, index);
|
return this._renderCommandItem(item, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isIntegrationItem(item)) {
|
||||||
|
return this._renderIntegrationItem(item, index);
|
||||||
|
}
|
||||||
|
|
||||||
return this._renderEntityItem(item as EntityItem, 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) {
|
private async _processItemAndCloseDialog(item: QuickBarItem, index: number) {
|
||||||
this._addSpinnerToCommandItem(index);
|
this._addSpinnerToCommandItem(index);
|
||||||
|
|
||||||
@@ -507,6 +573,9 @@ export class QuickBar extends LitElement {
|
|||||||
} else if (newFilter.startsWith("#")) {
|
} else if (newFilter.startsWith("#")) {
|
||||||
newMode = QuickBarMode.Device;
|
newMode = QuickBarMode.Device;
|
||||||
newSearch = newFilter.substring(1);
|
newSearch = newFilter.substring(1);
|
||||||
|
} else if (newFilter.startsWith("@")) {
|
||||||
|
newMode = QuickBarMode.Integration;
|
||||||
|
newSearch = newFilter.substring(1);
|
||||||
} else {
|
} else {
|
||||||
newMode = QuickBarMode.Entity;
|
newMode = QuickBarMode.Entity;
|
||||||
newSearch = newFilter;
|
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[]> {
|
private async _generateCommandItems(): Promise<CommandItem[]> {
|
||||||
return [
|
return [
|
||||||
...(await this._generateReloadCommands()),
|
...(await this._generateReloadCommands()),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export const enum QuickBarMode {
|
|||||||
Command = "command",
|
Command = "command",
|
||||||
Device = "device",
|
Device = "device",
|
||||||
Entity = "entity",
|
Entity = "entity",
|
||||||
|
Integration = "integration",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuickBarParams {
|
export interface QuickBarParams {
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
|||||||
case "d":
|
case "d":
|
||||||
this._showQuickBar(ev.detail, QuickBarMode.Device);
|
this._showQuickBar(ev.detail, QuickBarMode.Device);
|
||||||
break;
|
break;
|
||||||
|
case "i":
|
||||||
|
this._showQuickBar(ev.detail, QuickBarMode.Integration);
|
||||||
|
break;
|
||||||
case "m":
|
case "m":
|
||||||
this._createMyLink(ev.detail);
|
this._createMyLink(ev.detail);
|
||||||
break;
|
break;
|
||||||
@@ -70,6 +73,9 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
|||||||
m: { handler: (ev) => this._createMyLink(ev) },
|
m: { handler: (ev) => this._createMyLink(ev) },
|
||||||
a: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
a: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||||
d: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
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
|
// Workaround see https://github.com/jamiebuilds/tinykeys/issues/130
|
||||||
"Shift+?": { handler: (ev) => this._showShortcutDialog(ev) },
|
"Shift+?": { handler: (ev) => this._showShortcutDialog(ev) },
|
||||||
// Those are fallbacks for non-latin keyboards that don't have e, c, m keys (qwerty-based shortcuts)
|
// 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) },
|
KeyM: { handler: (ev) => this._createMyLink(ev) },
|
||||||
KeyA: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
KeyA: { handler: (ev) => this._showVoiceCommandDialog(ev) },
|
||||||
KeyD: { handler: (ev) => this._showQuickBar(ev, QuickBarMode.Device) },
|
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": "Search entities",
|
||||||
"filter_placeholder_devices": "Search devices",
|
"filter_placeholder_devices": "Search devices",
|
||||||
|
"filter_placeholder_integrations": "Search integrations",
|
||||||
"title": "Quick search",
|
"title": "Quick search",
|
||||||
"key_c_tip": "[%key:ui::tips::key_c_tip%]",
|
"key_c_tip": "[%key:ui::tips::key_c_tip%]",
|
||||||
"nothing_found": "Nothing found!"
|
"nothing_found": "Nothing found!"
|
||||||
|
|||||||
Reference in New Issue
Block a user