mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Allow an external sidebar (#11347)
This commit is contained in:
parent
bbcec38450
commit
6c12a5a4b1
@ -9,7 +9,6 @@ import {
|
|||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { nextRender } from "../common/util/render-status";
|
import { nextRender } from "../common/util/render-status";
|
||||||
import { getExternalConfig } from "../external_app/external_config";
|
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import "./ha-alert";
|
import "./ha-alert";
|
||||||
|
|
||||||
@ -91,18 +90,9 @@ class HaHLSPlayer extends LitElement {
|
|||||||
this._startHls();
|
this._startHls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _getUseExoPlayer(): Promise<boolean> {
|
|
||||||
if (!this.hass!.auth.external || !this.allowExoPlayer) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const externalConfig = await getExternalConfig(this.hass!.auth.external);
|
|
||||||
return externalConfig && externalConfig.hasExoPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _startHls(): Promise<void> {
|
private async _startHls(): Promise<void> {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
|
||||||
const useExoPlayerPromise = this._getUseExoPlayer();
|
|
||||||
const masterPlaylistPromise = fetch(this.url);
|
const masterPlaylistPromise = fetch(this.url);
|
||||||
|
|
||||||
const Hls: typeof HlsType = (await import("hls.js/dist/hls.light.min"))
|
const Hls: typeof HlsType = (await import("hls.js/dist/hls.light.min"))
|
||||||
@ -126,7 +116,8 @@ class HaHLSPlayer extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useExoPlayer = await useExoPlayerPromise;
|
const useExoPlayer =
|
||||||
|
this.allowExoPlayer && this.hass.auth.external?.config.hasExoPlayer;
|
||||||
const masterPlaylist = await (await masterPlaylistPromise).text();
|
const masterPlaylist = await (await masterPlaylistPromise).text();
|
||||||
|
|
||||||
if (!this.isConnected) {
|
if (!this.isConnected) {
|
||||||
|
@ -44,10 +44,6 @@ import {
|
|||||||
PersistentNotification,
|
PersistentNotification,
|
||||||
subscribeNotifications,
|
subscribeNotifications,
|
||||||
} from "../data/persistent_notification";
|
} from "../data/persistent_notification";
|
||||||
import {
|
|
||||||
ExternalConfig,
|
|
||||||
getExternalConfig,
|
|
||||||
} from "../external_app/external_config";
|
|
||||||
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
||||||
import { haStyleScrollbar } from "../resources/styles";
|
import { haStyleScrollbar } from "../resources/styles";
|
||||||
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
||||||
@ -192,8 +188,6 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public editMode = false;
|
@property({ type: Boolean }) public editMode = false;
|
||||||
|
|
||||||
@state() private _externalConfig?: ExternalConfig;
|
|
||||||
|
|
||||||
@state() private _notifications?: PersistentNotification[];
|
@state() private _notifications?: PersistentNotification[];
|
||||||
|
|
||||||
@state() private _renderEmptySortable = false;
|
@state() private _renderEmptySortable = false;
|
||||||
@ -270,13 +264,6 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
if (this.hass && this.hass.auth.external) {
|
|
||||||
getExternalConfig(this.hass.auth.external).then((conf) => {
|
|
||||||
this._externalConfig = conf;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||||
this._notifications = notifications;
|
this._notifications = notifications;
|
||||||
});
|
});
|
||||||
@ -559,8 +546,7 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
private _renderExternalConfiguration() {
|
private _renderExternalConfiguration() {
|
||||||
return html`${!this.hass.user?.is_admin &&
|
return html`${!this.hass.user?.is_admin &&
|
||||||
this._externalConfig &&
|
this.hass.auth.external?.config.hasSettingsScreen
|
||||||
this._externalConfig.hasSettingsScreen
|
|
||||||
? html`
|
? html`
|
||||||
<a
|
<a
|
||||||
role="option"
|
role="option"
|
||||||
|
52
src/external_app/external_app_entrypoint.ts
Normal file
52
src/external_app/external_app_entrypoint.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
All commands that do UI stuff need to be loaded from the app bundle as UI stuff
|
||||||
|
in core bundle slows things down and causes duplicate registration.
|
||||||
|
|
||||||
|
This is the entry point for providing external app stuff from app entrypoint.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { HomeAssistantMain } from "../layouts/home-assistant-main";
|
||||||
|
import type { EMExternalMessageCommands } from "./external_messaging";
|
||||||
|
|
||||||
|
export const attachExternalToApp = (hassMainEl: HomeAssistantMain) => {
|
||||||
|
window.addEventListener("haptic", (ev) =>
|
||||||
|
hassMainEl.hass.auth.external!.fireMessage({
|
||||||
|
type: "haptic",
|
||||||
|
payload: { hapticType: ev.detail },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
hassMainEl.hass.auth.external!.addCommandHandler((msg) =>
|
||||||
|
handleExternalMessage(hassMainEl, msg)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleExternalMessage = (
|
||||||
|
hassMainEl: HomeAssistantMain,
|
||||||
|
msg: EMExternalMessageCommands
|
||||||
|
): boolean => {
|
||||||
|
const bus = hassMainEl.hass.auth.external!;
|
||||||
|
|
||||||
|
if (msg.command === "restart") {
|
||||||
|
hassMainEl.hass.connection.reconnect(true);
|
||||||
|
bus.fireMessage({
|
||||||
|
id: msg.id,
|
||||||
|
type: "result",
|
||||||
|
success: true,
|
||||||
|
result: null,
|
||||||
|
});
|
||||||
|
} else if (msg.command === "notifications/show") {
|
||||||
|
fireEvent(hassMainEl, "hass-show-notifications");
|
||||||
|
bus.fireMessage({
|
||||||
|
id: msg.id,
|
||||||
|
type: "result",
|
||||||
|
success: true,
|
||||||
|
result: null,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
@ -128,14 +128,14 @@ export class ExternalAuth extends Auth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createExternalAuth = (hassUrl: string) => {
|
export const createExternalAuth = async (hassUrl: string) => {
|
||||||
const auth = new ExternalAuth(hassUrl);
|
const auth = new ExternalAuth(hassUrl);
|
||||||
if (
|
if (
|
||||||
(window.externalApp && window.externalApp.externalBus) ||
|
(window.externalApp && window.externalApp.externalBus) ||
|
||||||
(window.webkit && window.webkit.messageHandlers.externalBus)
|
(window.webkit && window.webkit.messageHandlers.externalBus)
|
||||||
) {
|
) {
|
||||||
auth.external = new ExternalMessaging();
|
auth.external = new ExternalMessaging();
|
||||||
auth.external.attach();
|
await auth.external.attach();
|
||||||
}
|
}
|
||||||
return auth;
|
return auth;
|
||||||
};
|
};
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import { ExternalMessaging } from "./external_messaging";
|
|
||||||
|
|
||||||
export interface ExternalConfig {
|
|
||||||
hasSettingsScreen: boolean;
|
|
||||||
canWriteTag: boolean;
|
|
||||||
hasExoPlayer: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getExternalConfig = (
|
|
||||||
bus: ExternalMessaging
|
|
||||||
): Promise<ExternalConfig> => {
|
|
||||||
if (!bus.cache.cfg) {
|
|
||||||
bus.cache.cfg = bus.sendMessage<ExternalConfig>({
|
|
||||||
type: "config/get",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return bus.cache.cfg;
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
import { ExternalMessaging } from "./external_messaging";
|
|
||||||
|
|
||||||
export const externalForwardConnectionEvents = (bus: ExternalMessaging) => {
|
|
||||||
window.addEventListener("connection-status", (ev) =>
|
|
||||||
bus.fireMessage({
|
|
||||||
type: "connection-status",
|
|
||||||
payload: { event: ev.detail },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const externalForwardHaptics = (bus: ExternalMessaging) =>
|
|
||||||
window.addEventListener("haptic", (ev) =>
|
|
||||||
bus.fireMessage({ type: "haptic", payload: { hapticType: ev.detail } })
|
|
||||||
);
|
|
@ -1,9 +1,3 @@
|
|||||||
import { Connection } from "home-assistant-js-websocket";
|
|
||||||
import {
|
|
||||||
externalForwardConnectionEvents,
|
|
||||||
externalForwardHaptics,
|
|
||||||
} from "./external_events_forwarder";
|
|
||||||
|
|
||||||
const CALLBACK_EXTERNAL_BUS = "externalBus";
|
const CALLBACK_EXTERNAL_BUS = "externalBus";
|
||||||
|
|
||||||
interface CommandInFlight {
|
interface CommandInFlight {
|
||||||
@ -42,24 +36,54 @@ interface EMExternalMessageRestart {
|
|||||||
command: "restart";
|
command: "restart";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EMExternMessageShowNotifications {
|
||||||
|
id: number;
|
||||||
|
type: "command";
|
||||||
|
command: "notifications/show";
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EMExternalMessageCommands =
|
||||||
|
| EMExternalMessageRestart
|
||||||
|
| EMExternMessageShowNotifications;
|
||||||
|
|
||||||
type ExternalMessage =
|
type ExternalMessage =
|
||||||
| EMMessageResultSuccess
|
| EMMessageResultSuccess
|
||||||
| EMMessageResultError
|
| EMMessageResultError
|
||||||
| EMExternalMessageRestart;
|
| EMExternalMessageCommands;
|
||||||
|
|
||||||
|
type ExternalMessageHandler = (msg: EMExternalMessageCommands) => boolean;
|
||||||
|
|
||||||
|
export interface ExternalConfig {
|
||||||
|
hasSettingsScreen: boolean;
|
||||||
|
hasSidebar: boolean;
|
||||||
|
canWriteTag: boolean;
|
||||||
|
hasExoPlayer: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class ExternalMessaging {
|
export class ExternalMessaging {
|
||||||
|
public config!: ExternalConfig;
|
||||||
|
|
||||||
public commands: { [msgId: number]: CommandInFlight } = {};
|
public commands: { [msgId: number]: CommandInFlight } = {};
|
||||||
|
|
||||||
public connection?: Connection;
|
|
||||||
|
|
||||||
public cache: Record<string, any> = {};
|
|
||||||
|
|
||||||
public msgId = 0;
|
public msgId = 0;
|
||||||
|
|
||||||
public attach() {
|
private _commandHandler?: ExternalMessageHandler;
|
||||||
externalForwardConnectionEvents(this);
|
|
||||||
externalForwardHaptics(this);
|
public async attach() {
|
||||||
window[CALLBACK_EXTERNAL_BUS] = (msg) => this.receiveMessage(msg);
|
window[CALLBACK_EXTERNAL_BUS] = (msg) => this.receiveMessage(msg);
|
||||||
|
window.addEventListener("connection-status", (ev) =>
|
||||||
|
this.fireMessage({
|
||||||
|
type: "connection-status",
|
||||||
|
payload: { event: ev.detail },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.config = await this.sendMessage<ExternalConfig>({
|
||||||
|
type: "config/get",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public addCommandHandler(handler: ExternalMessageHandler) {
|
||||||
|
this._commandHandler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,36 +121,25 @@ export class ExternalMessaging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type === "command") {
|
if (msg.type === "command") {
|
||||||
if (!this.connection) {
|
if (!this._commandHandler || !this._commandHandler(msg)) {
|
||||||
|
let code: string;
|
||||||
|
let message: string;
|
||||||
|
if (this._commandHandler) {
|
||||||
|
code = "not_ready";
|
||||||
|
message = "Command handler not ready";
|
||||||
|
} else {
|
||||||
|
code = "unknown_command";
|
||||||
|
message = `Unknown command ${msg.command}`;
|
||||||
|
}
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn("Received command without having connection set", msg);
|
console.warn(message, msg);
|
||||||
this.fireMessage({
|
this.fireMessage({
|
||||||
id: msg.id,
|
id: msg.id,
|
||||||
type: "result",
|
type: "result",
|
||||||
success: false,
|
success: false,
|
||||||
error: {
|
error: {
|
||||||
code: "commands_not_init",
|
code,
|
||||||
message: `Commands connection not set`,
|
message,
|
||||||
},
|
|
||||||
});
|
|
||||||
} else if (msg.command === "restart") {
|
|
||||||
this.connection.reconnect(true);
|
|
||||||
this.fireMessage({
|
|
||||||
id: msg.id,
|
|
||||||
type: "result",
|
|
||||||
success: true,
|
|
||||||
result: null,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn("Received unknown command", msg.command, msg);
|
|
||||||
this.fireMessage({
|
|
||||||
id: msg.id,
|
|
||||||
type: "result",
|
|
||||||
success: false,
|
|
||||||
error: {
|
|
||||||
code: "unknown_command",
|
|
||||||
message: `Unknown command ${msg.command}`,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ interface EditSideBarEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("home-assistant-main")
|
@customElement("home-assistant-main")
|
||||||
class HomeAssistantMain extends LitElement {
|
export class HomeAssistantMain extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public route?: Route;
|
@property() public route?: Route;
|
||||||
@ -47,6 +47,8 @@ class HomeAssistantMain extends LitElement {
|
|||||||
|
|
||||||
@state() private _sidebarEditMode = false;
|
@state() private _sidebarEditMode = false;
|
||||||
|
|
||||||
|
@state() private _externalSidebar = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
listenMediaQuery("(max-width: 870px)", (matches) => {
|
listenMediaQuery("(max-width: 870px)", (matches) => {
|
||||||
@ -56,11 +58,12 @@ class HomeAssistantMain extends LitElement {
|
|||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const hass = this.hass;
|
const hass = this.hass;
|
||||||
const sidebarNarrow = this._sidebarNarrow;
|
const sidebarNarrow = this._sidebarNarrow || this._externalSidebar;
|
||||||
const disableSwipe =
|
const disableSwipe =
|
||||||
this._sidebarEditMode ||
|
this._sidebarEditMode ||
|
||||||
!sidebarNarrow ||
|
!sidebarNarrow ||
|
||||||
NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
|
NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1 ||
|
||||||
|
this._externalSidebar;
|
||||||
|
|
||||||
// Style block in render because of the mixin that is not supported
|
// Style block in render because of the mixin that is not supported
|
||||||
return html`
|
return html`
|
||||||
@ -107,6 +110,14 @@ class HomeAssistantMain extends LitElement {
|
|||||||
protected firstUpdated() {
|
protected firstUpdated() {
|
||||||
import(/* webpackPreload: true */ "../components/ha-sidebar");
|
import(/* webpackPreload: true */ "../components/ha-sidebar");
|
||||||
|
|
||||||
|
if (this.hass.auth.external) {
|
||||||
|
this._externalSidebar =
|
||||||
|
this.hass.auth.external.config.hasSidebar === true;
|
||||||
|
import("../external_app/external_app_entrypoint").then((mod) =>
|
||||||
|
mod.attachExternalToApp(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.addEventListener(
|
this.addEventListener(
|
||||||
"hass-edit-sidebar",
|
"hass-edit-sidebar",
|
||||||
(ev: HASSDomEvent<EditSideBarEvent>) => {
|
(ev: HASSDomEvent<EditSideBarEvent>) => {
|
||||||
@ -129,6 +140,12 @@ class HomeAssistantMain extends LitElement {
|
|||||||
if (this._sidebarEditMode) {
|
if (this._sidebarEditMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this._externalSidebar) {
|
||||||
|
this.hass.auth.external!.fireMessage({
|
||||||
|
type: "sidebar/show",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this._sidebarNarrow) {
|
if (this._sidebarNarrow) {
|
||||||
if (this.drawer.opened) {
|
if (this.drawer.opened) {
|
||||||
this.drawer.close();
|
this.drawer.close();
|
||||||
|
@ -3,15 +3,8 @@ import "@material/mwc-list/mwc-list-item";
|
|||||||
import type { ActionDetail } from "@material/mwc-list";
|
import type { ActionDetail } from "@material/mwc-list";
|
||||||
import "@polymer/app-layout/app-header/app-header";
|
import "@polymer/app-layout/app-header/app-header";
|
||||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
import { customElement, property } from "lit/decorators";
|
||||||
CSSResultGroup,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
@ -24,10 +17,6 @@ import {
|
|||||||
SupervisorAvailableUpdates,
|
SupervisorAvailableUpdates,
|
||||||
} from "../../../data/supervisor/root";
|
} from "../../../data/supervisor/root";
|
||||||
import { showQuickBar } from "../../../dialogs/quick-bar/show-dialog-quick-bar";
|
import { showQuickBar } from "../../../dialogs/quick-bar/show-dialog-quick-bar";
|
||||||
import {
|
|
||||||
ExternalConfig,
|
|
||||||
getExternalConfig,
|
|
||||||
} from "../../../external_app/external_config";
|
|
||||||
import "../../../layouts/ha-app-layout";
|
import "../../../layouts/ha-app-layout";
|
||||||
import { haStyle } from "../../../resources/styles";
|
import { haStyle } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
@ -54,18 +43,6 @@ class HaConfigDashboard extends LitElement {
|
|||||||
|
|
||||||
@property() public showAdvanced!: boolean;
|
@property() public showAdvanced!: boolean;
|
||||||
|
|
||||||
@state() private _externalConfig?: ExternalConfig;
|
|
||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
|
||||||
super.firstUpdated(changedProps);
|
|
||||||
|
|
||||||
if (this.hass && this.hass.auth.external) {
|
|
||||||
getExternalConfig(this.hass.auth.external).then((conf) => {
|
|
||||||
this._externalConfig = conf;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<ha-app-layout>
|
<ha-app-layout>
|
||||||
@ -143,7 +120,6 @@ class HaConfigDashboard extends LitElement {
|
|||||||
<ha-config-navigation
|
<ha-config-navigation
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.externalConfig=${this._externalConfig}
|
|
||||||
.showAdvanced=${this.showAdvanced}
|
.showAdvanced=${this.showAdvanced}
|
||||||
.pages=${configSections.dashboard}
|
.pages=${configSections.dashboard}
|
||||||
></ha-config-navigation>
|
></ha-config-navigation>
|
||||||
|
@ -6,7 +6,6 @@ import { canShowPage } from "../../../common/config/can_show_page";
|
|||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
import { CloudStatus, CloudStatusLoggedIn } from "../../../data/cloud";
|
import { CloudStatus, CloudStatusLoggedIn } from "../../../data/cloud";
|
||||||
import { ExternalConfig } from "../../../external_app/external_config";
|
|
||||||
import { PageNavigation } from "../../../layouts/hass-tabs-subpage";
|
import { PageNavigation } from "../../../layouts/hass-tabs-subpage";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
|
||||||
@ -20,14 +19,12 @@ class HaConfigNavigation extends LitElement {
|
|||||||
|
|
||||||
@property() public pages!: PageNavigation[];
|
@property() public pages!: PageNavigation[];
|
||||||
|
|
||||||
@property() public externalConfig?: ExternalConfig;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
${this.pages.map((page) =>
|
${this.pages.map((page) =>
|
||||||
(
|
(
|
||||||
page.path === "#external-app-configuration"
|
page.path === "#external-app-configuration"
|
||||||
? this.externalConfig?.hasSettingsScreen
|
? this.hass.auth.external?.config.hasSettingsScreen
|
||||||
: canShowPage(this.hass, page)
|
: canShowPage(this.hass, page)
|
||||||
)
|
)
|
||||||
? html`
|
? html`
|
||||||
|
@ -28,7 +28,6 @@ import {
|
|||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
} from "../../../dialogs/generic/show-dialog-box";
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import { getExternalConfig } from "../../../external_app/external_config";
|
|
||||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||||
import { HomeAssistant, Route } from "../../../types";
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
@ -53,14 +52,12 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _tags: Tag[] = [];
|
@state() private _tags: Tag[] = [];
|
||||||
|
|
||||||
@state() private _canWriteTags = false;
|
private get _canWriteTags() {
|
||||||
|
return this.hass.auth.external?.config.canWriteTag;
|
||||||
|
}
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(
|
(narrow: boolean, _language): DataTableColumnContainer => {
|
||||||
narrow: boolean,
|
|
||||||
canWriteTags: boolean,
|
|
||||||
_language
|
|
||||||
): DataTableColumnContainer => {
|
|
||||||
const columns: DataTableColumnContainer = {
|
const columns: DataTableColumnContainer = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
@ -103,7 +100,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (canWriteTags) {
|
if (this._canWriteTags) {
|
||||||
columns.write = {
|
columns.write = {
|
||||||
title: "",
|
title: "",
|
||||||
type: "icon-button",
|
type: "icon-button",
|
||||||
@ -152,11 +149,6 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
protected firstUpdated(changedProperties: PropertyValues) {
|
protected firstUpdated(changedProperties: PropertyValues) {
|
||||||
super.firstUpdated(changedProperties);
|
super.firstUpdated(changedProperties);
|
||||||
this._fetchTags();
|
this._fetchTags();
|
||||||
if (this.hass && this.hass.auth.external) {
|
|
||||||
getExternalConfig(this.hass.auth.external).then((conf) => {
|
|
||||||
this._canWriteTags = conf.canWriteTag;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected hassSubscribe() {
|
protected hassSubscribe() {
|
||||||
@ -181,11 +173,7 @@ export class HaConfigTags extends SubscribeMixin(LitElement) {
|
|||||||
back-path="/config"
|
back-path="/config"
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
.tabs=${configSections.tags}
|
.tabs=${configSections.tags}
|
||||||
.columns=${this._columns(
|
.columns=${this._columns(this.narrow, this.hass.language)}
|
||||||
this.narrow,
|
|
||||||
this._canWriteTags,
|
|
||||||
this.hass.language
|
|
||||||
)}
|
|
||||||
.data=${this._data(this._tags)}
|
.data=${this._data(this._tags)}
|
||||||
.noDataText=${this.hass.localize("ui.panel.config.tag.no_tags")}
|
.noDataText=${this.hass.localize("ui.panel.config.tag.no_tags")}
|
||||||
hasFab
|
hasFab
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import { Constructor } from "../types";
|
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
|
||||||
|
|
||||||
export const ExternalMixin = <T extends Constructor<HassBaseEl>>(
|
|
||||||
superClass: T
|
|
||||||
) =>
|
|
||||||
class extends superClass {
|
|
||||||
protected hassConnected() {
|
|
||||||
super.hassConnected();
|
|
||||||
|
|
||||||
if (this.hass!.auth.external) {
|
|
||||||
this.hass!.auth.external.connection = this.hass!.connection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -6,7 +6,6 @@ import DisconnectToastMixin from "./disconnect-toast-mixin";
|
|||||||
import { hapticMixin } from "./haptic-mixin";
|
import { hapticMixin } from "./haptic-mixin";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
import { loggingMixin } from "./logging-mixin";
|
import { loggingMixin } from "./logging-mixin";
|
||||||
import { ExternalMixin } from "./external-mixin";
|
|
||||||
import MoreInfoMixin from "./more-info-mixin";
|
import MoreInfoMixin from "./more-info-mixin";
|
||||||
import NotificationMixin from "./notification-mixin";
|
import NotificationMixin from "./notification-mixin";
|
||||||
import { panelTitleMixin } from "./panel-title-mixin";
|
import { panelTitleMixin } from "./panel-title-mixin";
|
||||||
@ -32,5 +31,4 @@ export class HassElement extends ext(HassBaseEl, [
|
|||||||
hapticMixin,
|
hapticMixin,
|
||||||
panelTitleMixin,
|
panelTitleMixin,
|
||||||
loggingMixin,
|
loggingMixin,
|
||||||
ExternalMixin,
|
|
||||||
]) {}
|
]) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user