Skip to content

Commit

Permalink
Restore Bluetooth configuration panel (#23877)
Browse files Browse the repository at this point in the history
* Restore Bluetooth configuration panel

* cleanup copypasta

* Apply suggestions from code review

* Update src/panels/config/integrations/integration-panels/bluetooth/bluetooth-config-dashboard-router.ts

* preen

* trim down updatePageEl
  • Loading branch information
bdraco authored Jan 26, 2025
1 parent 240e48f commit 99d832a
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/data/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { HomeAssistant } from "../types";
import { debounce } from "../common/util/debounce";

export const integrationsWithPanel = {
bluetooth: "config/bluetooth",
matter: "config/matter",
mqtt: "config/mqtt",
thread: "config/thread",
Expand Down
4 changes: 2 additions & 2 deletions src/panels/config/ha-panel-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,10 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
),
},
bluetooth: {
tag: "bluetooth-config-panel",
tag: "bluetooth-config-dashboard-router",
load: () =>
import(
"./integrations/integration-panels/bluetooth/bluetooth-config-panel"
"./integrations/integration-panels/bluetooth/bluetooth-config-dashboard-router"
),
},
application_credentials: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import type { BluetoothDeviceData } from "../../../../../data/bluetooth";
import { subscribeBluetoothAdvertisements } from "../../../../../data/bluetooth";
import { showBluetoothDeviceInfoDialog } from "./show-dialog-bluetooth-device-info";

@customElement("bluetooth-config-panel")
export class BluetoothConfigPanel extends LitElement {
@customElement("bluetooth-advertisement-monitor")
export class BluetoothAdvertisementMonitorPanel extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public route!: Route;
Expand Down Expand Up @@ -121,6 +121,6 @@ export class BluetoothConfigPanel extends LitElement {

declare global {
interface HTMLElementTagNameMap {
"bluetooth-config-panel": BluetoothConfigPanel;
"bluetooth-advertisement-monitor": BluetoothAdvertisementMonitorPanel;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { customElement, property } from "lit/decorators";
import type { RouterOptions } from "../../../../../layouts/hass-router-page";
import { HassRouterPage } from "../../../../../layouts/hass-router-page";
import type { HomeAssistant } from "../../../../../types";

@customElement("bluetooth-config-dashboard-router")
class BluetoothConfigDashboardRouter extends HassRouterPage {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: "is-wide", type: Boolean }) public isWide = false;

@property({ type: Boolean }) public narrow = false;

private _configEntry = new URLSearchParams(window.location.search).get(
"config_entry"
);

protected routerOptions: RouterOptions = {
defaultPage: "dashboard",
showLoading: true,
routes: {
dashboard: {
tag: "bluetooth-config-dashboard",
load: () => import("./bluetooth-config-dashboard"),
},
"advertisement-monitor": {
tag: "bluetooth-advertisement-monitor",
load: () => import("./bluetooth-advertisement-monitor"),
},
},
};

protected updatePageEl(el): void {
el.route = this.routeTail;
el.hass = this.hass;
el.isWide = this.isWide;
el.narrow = this.narrow;
el.configEntryId = this._configEntry;
}
}

declare global {
interface HTMLElementTagNameMap {
"bluetooth-config-dashboard-router": BluetoothConfigDashboardRouter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import "@material/mwc-button";
import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../../../components/ha-card";
import "../../../../../components/ha-code-editor";
import "../../../../../components/ha-formfield";
import "../../../../../components/ha-switch";
import { getConfigEntries } from "../../../../../data/config_entries";
import { showOptionsFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-options-flow";
import "../../../../../layouts/hass-subpage";
import { haStyle } from "../../../../../resources/styles";
import type { HomeAssistant } from "../../../../../types";

@customElement("bluetooth-config-dashboard")
export class BluetoothConfigDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ type: Boolean }) public narrow = false;

protected render(): TemplateResult {
return html`
<hass-subpage .narrow=${this.narrow} .hass=${this.hass}>
<div class="content">
<ha-card
.header=${this.hass.localize(
"ui.panel.config.bluetooth.settings_title"
)}
>
<div class="card-actions">
<mwc-button @click=${this._openOptionFlow}
>${this.hass.localize(
"ui.panel.config.bluetooth.option_flow"
)}</mwc-button
>
</div>
</ha-card>
<ha-card
.header=${this.hass.localize(
"ui.panel.config.bluetooth.advertisement_monitor"
)}
>
<div class="card-content">
<p>
${this.hass.localize(
"ui.panel.config.bluetooth.advertisement_monitor_details"
)}
</p>
</div>
<div class="card-actions">
<a href="/config/bluetooth/advertisement-monitor"
><mwc-button>
${this.hass.localize(
"ui.panel.config.bluetooth.advertisement_monitor"
)}
</mwc-button></a
>
</div>
</ha-card>
</div>
</hass-subpage>
`;
}

private async _openOptionFlow() {
const searchParams = new URLSearchParams(window.location.search);
if (!searchParams.has("config_entry")) {
return;
}
const configEntryId = searchParams.get("config_entry") as string;
const configEntries = await getConfigEntries(this.hass, {
domain: "bluetooth",
});
const configEntry = configEntries.find(
(entry) => entry.entry_id === configEntryId
);
showOptionsFlowDialog(this, configEntry!);
}

static get styles(): CSSResultGroup {
return [
haStyle,
css`
:host {
-ms-user-select: initial;
-webkit-user-select: initial;
-moz-user-select: initial;
}
.content {
padding: 24px 0 32px;
max-width: 600px;
margin: 0 auto;
direction: ltr;
}
ha-card:first-child {
margin-bottom: 16px;
}
`,
];
}
}

declare global {
interface HTMLElementTagNameMap {
"bluetooth-config-dashboard": BluetoothConfigDashboard;
}
}
4 changes: 4 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5281,6 +5281,10 @@
},
"bluetooth": {
"title": "Bluetooth",
"settings_title": "Bluetooth settings",
"option_flow": "Configure Bluetooth options",
"advertisement_monitor": "Advertisement Monitor",
"advertisement_monitor_details": "The advertisement monitor listens for Bluetooth advertisements and displays the data in a structured format.",
"address": "Address",
"name": "Name",
"source": "Source",
Expand Down

0 comments on commit 99d832a

Please sign in to comment.