mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 00:36:34 +00:00
Merge dialog with more info
This commit is contained in:
parent
3269fd3c5b
commit
9e4835107d
@ -0,0 +1,225 @@
|
|||||||
|
import { mdiLightbulb, mdiLightbulbOff } from "@mdi/js";
|
||||||
|
import type { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||||
|
import { computeStateDomain } from "../../../../common/entity/compute_state_domain";
|
||||||
|
import { computeGroupEntitiesState } from "../../../../common/entity/group_entities";
|
||||||
|
import "../../../../components/ha-control-button";
|
||||||
|
import "../../../../components/ha-control-button-group";
|
||||||
|
import "../../../../components/ha-domain-icon";
|
||||||
|
import { isFullyClosed, isFullyOpen } from "../../../../data/cover";
|
||||||
|
import { UNAVAILABLE } from "../../../../data/entity";
|
||||||
|
import { forwardHaptic } from "../../../../data/haptics";
|
||||||
|
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||||
|
import type { TileCardConfig } from "../../../../panels/lovelace/cards/types";
|
||||||
|
import "../../../../panels/lovelace/sections/hui-section";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
|
export interface GroupToggleDialogParams {
|
||||||
|
entityIds: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement("ha-more-info-view-toggle-group")
|
||||||
|
class HaMoreInfoViewToggleGroup extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public params?: GroupToggleDialogParams;
|
||||||
|
|
||||||
|
private _sectionConfig = memoizeOne(
|
||||||
|
(entities: string[]): LovelaceSectionConfig => ({
|
||||||
|
type: "grid",
|
||||||
|
cards: entities.map<TileCardConfig>((entity) => ({
|
||||||
|
type: "tile",
|
||||||
|
entity: entity,
|
||||||
|
icon_tap_action: {
|
||||||
|
action: "toggle",
|
||||||
|
},
|
||||||
|
tap_action: {
|
||||||
|
action: "more-info",
|
||||||
|
},
|
||||||
|
grid_options: {
|
||||||
|
columns: 12,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.params) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sectionConfig = this._sectionConfig(this.params.entityIds);
|
||||||
|
|
||||||
|
const entities = this.params.entityIds
|
||||||
|
.map((entityId) => this.hass!.states[entityId] as HassEntity | undefined)
|
||||||
|
.filter((v): v is HassEntity => Boolean(v));
|
||||||
|
|
||||||
|
const mainStateObj = entities[0];
|
||||||
|
|
||||||
|
const groupState = computeGroupEntitiesState(entities);
|
||||||
|
const formattedGroupState = this.hass.formatEntityState(
|
||||||
|
mainStateObj,
|
||||||
|
groupState
|
||||||
|
);
|
||||||
|
|
||||||
|
const domain = computeStateDomain(mainStateObj);
|
||||||
|
|
||||||
|
const deviceClass = mainStateObj.attributes.device_class;
|
||||||
|
|
||||||
|
const isGroup = this.params.entityIds.length > 1;
|
||||||
|
|
||||||
|
const isAllOn = entities.every((entity) =>
|
||||||
|
entity.state === UNAVAILABLE ||
|
||||||
|
computeDomain(entity.entity_id) === "cover"
|
||||||
|
? isFullyOpen(entity)
|
||||||
|
: entity.state === "on"
|
||||||
|
);
|
||||||
|
const isAllOff = entities.every((entity) =>
|
||||||
|
entity.state === UNAVAILABLE ||
|
||||||
|
computeDomain(entity.entity_id) === "cover"
|
||||||
|
? isFullyClosed(entity)
|
||||||
|
: entity.state === "off"
|
||||||
|
);
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="content">
|
||||||
|
<ha-more-info-state-header
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${mainStateObj}
|
||||||
|
.stateOverride=${formattedGroupState}
|
||||||
|
></ha-more-info-state-header>
|
||||||
|
<ha-control-button-group vertical>
|
||||||
|
<ha-control-button
|
||||||
|
vertical
|
||||||
|
@click=${this._turnAllOn}
|
||||||
|
.disabled=${isAllOn}
|
||||||
|
>
|
||||||
|
${domain !== "light"
|
||||||
|
? html`<ha-domain-icon
|
||||||
|
.hass=${this.hass}
|
||||||
|
.domain=${domain}
|
||||||
|
.state=${domain === "cover" ? "open" : "on"}
|
||||||
|
.deviceClass=${deviceClass}
|
||||||
|
></ha-domain-icon>`
|
||||||
|
: html` <ha-svg-icon .path=${mdiLightbulb}></ha-svg-icon> `}
|
||||||
|
<p>
|
||||||
|
${domain === "cover"
|
||||||
|
? isGroup
|
||||||
|
? "Open all"
|
||||||
|
: "Open"
|
||||||
|
: isGroup
|
||||||
|
? "Turn all on"
|
||||||
|
: "Turn on"}
|
||||||
|
</p>
|
||||||
|
</ha-control-button>
|
||||||
|
<ha-control-button
|
||||||
|
vertical
|
||||||
|
@click=${this._turnAllOff}
|
||||||
|
.disabled=${isAllOff}
|
||||||
|
>
|
||||||
|
${domain !== "light"
|
||||||
|
? html`
|
||||||
|
<ha-domain-icon
|
||||||
|
.hass=${this.hass}
|
||||||
|
.domain=${domain}
|
||||||
|
.state=${domain === "cover" ? "closed" : "off"}
|
||||||
|
.deviceClass=${deviceClass}
|
||||||
|
></ha-domain-icon>
|
||||||
|
`
|
||||||
|
: html` <ha-svg-icon .path=${mdiLightbulbOff}></ha-svg-icon>`}
|
||||||
|
<p>
|
||||||
|
${domain === "cover"
|
||||||
|
? isGroup
|
||||||
|
? "Close all"
|
||||||
|
: "Close"
|
||||||
|
: isGroup
|
||||||
|
? "Turn all off"
|
||||||
|
: "Turn off"}
|
||||||
|
</p>
|
||||||
|
</ha-control-button>
|
||||||
|
</ha-control-button-group>
|
||||||
|
<hui-section .config=${sectionConfig} .hass=${this.hass}></hui-section>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _turnAllOff() {
|
||||||
|
if (!this.params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
forwardHaptic("light");
|
||||||
|
const domain = computeDomain(this.params.entityIds[0]);
|
||||||
|
if (domain === "cover") {
|
||||||
|
this.hass.callService("cover", "close_cover", {
|
||||||
|
entity_id: this.params.entityIds,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hass.callService("homeassistant", "turn_off", {
|
||||||
|
entity_id: this.params.entityIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _turnAllOn() {
|
||||||
|
if (!this.params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
forwardHaptic("light");
|
||||||
|
const domain = computeDomain(this.params.entityIds[0]);
|
||||||
|
if (domain === "cover") {
|
||||||
|
this.hass.callService("cover", "open_cover", {
|
||||||
|
entity_id: this.params.entityIds,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hass.callService("homeassistant", "turn_on", {
|
||||||
|
entity_id: this.params.entityIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = [
|
||||||
|
css`
|
||||||
|
.content {
|
||||||
|
padding: 24px;
|
||||||
|
padding-bottom: max(var(--safe-area-inset-bottom), 24px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
ha-control-button-group {
|
||||||
|
--control-button-group-spacing: 12px;
|
||||||
|
--control-button-group-thickness: 130px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
ha-control-button {
|
||||||
|
--control-button-border-radius: 16px;
|
||||||
|
--mdc-icon-size: 24px;
|
||||||
|
color: #006787;
|
||||||
|
--control-button-padding: 16px 8px;
|
||||||
|
--control-button-icon-color: #006787;
|
||||||
|
--control-button-background-color: #eff9fe;
|
||||||
|
--control-button-background-opacity: 1;
|
||||||
|
--control-button-focus-color: #006787;
|
||||||
|
--ha-ripple-color: #006787;
|
||||||
|
}
|
||||||
|
ha-control-button p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
hui-section {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-more-info-view-toggle-group": HaMoreInfoViewToggleGroup;
|
||||||
|
}
|
||||||
|
}
|
@ -8,9 +8,9 @@ export const showVoiceAssistantsView = (
|
|||||||
title: string
|
title: string
|
||||||
): void => {
|
): void => {
|
||||||
fireEvent(element, "show-child-view", {
|
fireEvent(element, "show-child-view", {
|
||||||
viewTag: "ha-more-info-view-voice-assistants",
|
tag: "ha-more-info-view-voice-assistants",
|
||||||
viewImport: loadVoiceAssistantsView,
|
import: loadVoiceAssistantsView,
|
||||||
viewTitle: title,
|
title: title,
|
||||||
viewParams: {},
|
params: {},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
mdiPencilOutline,
|
mdiPencilOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { HassEntity } from "home-assistant-js-websocket";
|
import type { HassEntity } from "home-assistant-js-websocket";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues, TemplateResult } from "lit";
|
||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { cache } from "lit/directives/cache";
|
import { cache } from "lit/directives/cache";
|
||||||
@ -68,15 +68,24 @@ export interface MoreInfoDialogParams {
|
|||||||
view?: View;
|
view?: View;
|
||||||
/** @deprecated Use `view` instead */
|
/** @deprecated Use `view` instead */
|
||||||
tab?: View;
|
tab?: View;
|
||||||
|
parentView?: ParentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
type View = "info" | "history" | "settings" | "related";
|
type View = "info" | "history" | "settings" | "related" | "parent";
|
||||||
|
|
||||||
|
interface ParentView {
|
||||||
|
tag: string;
|
||||||
|
title?: string;
|
||||||
|
subtitle?: string;
|
||||||
|
import?: () => Promise<unknown>;
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
|
|
||||||
interface ChildView {
|
interface ChildView {
|
||||||
viewTag: string;
|
tag: string;
|
||||||
viewTitle?: string;
|
title?: string;
|
||||||
viewImport?: () => Promise<unknown>;
|
import?: () => Promise<unknown>;
|
||||||
viewParams?: any;
|
params?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@ -88,7 +97,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_VIEW: View = "info";
|
const INFO_VIEW: View = "info";
|
||||||
|
const PARENT_VIEW: View = "parent";
|
||||||
|
|
||||||
@customElement("ha-more-info-dialog")
|
@customElement("ha-more-info-dialog")
|
||||||
export class MoreInfoDialog extends LitElement {
|
export class MoreInfoDialog extends LitElement {
|
||||||
@ -98,9 +108,11 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
|
|
||||||
@state() private _entityId?: string | null;
|
@state() private _entityId?: string | null;
|
||||||
|
|
||||||
@state() private _currView: View = DEFAULT_VIEW;
|
@state() private _currView: View = INFO_VIEW;
|
||||||
|
|
||||||
@state() private _initialView: View = DEFAULT_VIEW;
|
@state() private _initialView: View = INFO_VIEW;
|
||||||
|
|
||||||
|
@state() private _parentView?: ParentView;
|
||||||
|
|
||||||
@state() private _childView?: ChildView;
|
@state() private _childView?: ChildView;
|
||||||
|
|
||||||
@ -114,17 +126,29 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
|
|
||||||
public showDialog(params: MoreInfoDialogParams) {
|
public showDialog(params: MoreInfoDialogParams) {
|
||||||
this._entityId = params.entityId;
|
this._entityId = params.entityId;
|
||||||
if (!this._entityId) {
|
if (!this._entityId && !params.parentView) {
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._currView = params.view || DEFAULT_VIEW;
|
this._parentView = params.parentView;
|
||||||
this._initialView = params.view || DEFAULT_VIEW;
|
if (this._parentView?.import) {
|
||||||
|
this._parentView.import();
|
||||||
|
this._currView = PARENT_VIEW;
|
||||||
|
} else {
|
||||||
|
this._currView = params.view || INFO_VIEW;
|
||||||
|
}
|
||||||
|
this._initialView = params.view || INFO_VIEW;
|
||||||
this._childView = undefined;
|
this._childView = undefined;
|
||||||
this.large = false;
|
this.large = false;
|
||||||
this._loadEntityRegistryEntry();
|
this._loadEntityRegistryEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public willUpdate(changedProps: PropertyValues): void {
|
||||||
|
if (changedProps.has("_entityId")) {
|
||||||
|
this._loadEntityRegistryEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _loadEntityRegistryEntry() {
|
private async _loadEntityRegistryEntry() {
|
||||||
if (!this._entityId) {
|
if (!this._entityId) {
|
||||||
return;
|
return;
|
||||||
@ -143,19 +167,18 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
this._entityId = undefined;
|
this._entityId = undefined;
|
||||||
this._entry = undefined;
|
this._entry = undefined;
|
||||||
this._childView = undefined;
|
this._childView = undefined;
|
||||||
|
this._parentView = undefined;
|
||||||
|
this._currView = INFO_VIEW;
|
||||||
this._infoEditMode = false;
|
this._infoEditMode = false;
|
||||||
this._initialView = DEFAULT_VIEW;
|
this._initialView = INFO_VIEW;
|
||||||
this._isEscapeEnabled = true;
|
this._isEscapeEnabled = true;
|
||||||
window.removeEventListener("dialog-closed", this._enableEscapeKeyClose);
|
window.removeEventListener("dialog-closed", this._enableEscapeKeyClose);
|
||||||
window.removeEventListener("show-dialog", this._disableEscapeKeyClose);
|
window.removeEventListener("show-dialog", this._disableEscapeKeyClose);
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldShowEditIcon(
|
private _shouldShowEditIcon(domain?: string, stateObj?: HassEntity): boolean {
|
||||||
domain: string,
|
if (__DEMO__ || !stateObj || !domain) {
|
||||||
stateObj: HassEntity | undefined
|
|
||||||
): boolean {
|
|
||||||
if (__DEMO__ || !stateObj) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (EDITABLE_DOMAINS_WITH_ID.includes(domain) && stateObj.attributes.id) {
|
if (EDITABLE_DOMAINS_WITH_ID.includes(domain) && stateObj.attributes.id) {
|
||||||
@ -171,8 +194,9 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldShowHistory(domain: string): boolean {
|
private _shouldShowHistory(domain?: string): boolean {
|
||||||
return (
|
return (
|
||||||
|
domain !== undefined &&
|
||||||
DOMAINS_WITH_MORE_INFO.includes(domain) &&
|
DOMAINS_WITH_MORE_INFO.includes(domain) &&
|
||||||
(computeShowHistoryComponent(this.hass, this._entityId!) ||
|
(computeShowHistoryComponent(this.hass, this._entityId!) ||
|
||||||
computeShowLogBookComponent(
|
computeShowLogBookComponent(
|
||||||
@ -207,14 +231,30 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
private _goBack() {
|
private _goBack() {
|
||||||
if (this._childView) {
|
if (this._childView) {
|
||||||
this._childView = undefined;
|
this._childView = undefined;
|
||||||
} else {
|
return;
|
||||||
this._setView(this._initialView);
|
}
|
||||||
|
const previousView = this._previousView();
|
||||||
|
if (previousView) {
|
||||||
|
this._setView(previousView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _previousView(): View | undefined {
|
||||||
|
if (this._currView === PARENT_VIEW) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (this._currView !== this._initialView) {
|
||||||
|
return this._initialView;
|
||||||
|
}
|
||||||
|
if (this._parentView) {
|
||||||
|
return PARENT_VIEW;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private _resetInitialView() {
|
private _resetInitialView() {
|
||||||
this._initialView = DEFAULT_VIEW;
|
this._initialView = INFO_VIEW;
|
||||||
this._setView(DEFAULT_VIEW);
|
this._setView(INFO_VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _goToHistory() {
|
private _goToHistory() {
|
||||||
@ -227,8 +267,8 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
|
|
||||||
private _showChildView(ev: CustomEvent): void {
|
private _showChildView(ev: CustomEvent): void {
|
||||||
const view = ev.detail as ChildView;
|
const view = ev.detail as ChildView;
|
||||||
if (view.viewImport) {
|
if (view.import) {
|
||||||
view.viewImport();
|
view.import();
|
||||||
}
|
}
|
||||||
this._childView = view;
|
this._childView = view;
|
||||||
}
|
}
|
||||||
@ -286,45 +326,99 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
this._sensorNumericDeviceClasses = deviceClasses.numeric_device_classes;
|
this._sensorNumericDeviceClasses = deviceClasses.numeric_device_classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleMoreInfoEvent(ev: CustomEvent) {
|
||||||
|
// If the parent view has a `show-dialog` event to open more info, we handle it here to set the entity ID and view.
|
||||||
|
const detail = ev.detail as MoreInfoDialogParams;
|
||||||
|
if (detail.entityId) {
|
||||||
|
this._entityId = detail.entityId;
|
||||||
|
this._setView(detail.view || INFO_VIEW);
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderHeader = (): TemplateResult | typeof nothing => {
|
||||||
|
if (this._parentView && this._currView === PARENT_VIEW) {
|
||||||
|
return html`
|
||||||
|
${this._parentView
|
||||||
|
? html`<p class="breadcrumb">${this._parentView.subtitle}</p>`
|
||||||
|
: nothing}
|
||||||
|
<p class="main">${this._parentView.title}</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entityId = this._entityId;
|
||||||
|
|
||||||
|
if (entityId) {
|
||||||
|
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
|
||||||
|
const context = stateObj
|
||||||
|
? getEntityContext(stateObj, this.hass)
|
||||||
|
: this._entry
|
||||||
|
? getEntityEntryContext(this._entry, this.hass)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const entityName = stateObj
|
||||||
|
? computeEntityName(stateObj, this.hass)
|
||||||
|
: this._entry
|
||||||
|
? computeEntityEntryName(this._entry, this.hass)
|
||||||
|
: entityId;
|
||||||
|
|
||||||
|
const deviceName = context?.device
|
||||||
|
? computeDeviceName(context.device)
|
||||||
|
: undefined;
|
||||||
|
const areaName = context?.area
|
||||||
|
? computeAreaName(context.area)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const breadcrumb = [areaName, deviceName, entityName].filter(
|
||||||
|
(v): v is string => Boolean(v)
|
||||||
|
);
|
||||||
|
const title = this._childView?.title || breadcrumb.pop() || entityId;
|
||||||
|
const isAdmin = this.hass.user!.is_admin;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
${breadcrumb.length > 0
|
||||||
|
? !__DEMO__ && isAdmin
|
||||||
|
? html`
|
||||||
|
<button
|
||||||
|
class="breadcrumb"
|
||||||
|
@click=${this._breadcrumbClick}
|
||||||
|
aria-label=${breadcrumb.join(" > ")}
|
||||||
|
>
|
||||||
|
${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<p class="breadcrumb">
|
||||||
|
${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
|
||||||
|
</p>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
<p class="main">${title}</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nothing;
|
||||||
|
};
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this._entityId) {
|
if (!this._entityId && !this._parentView) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
const entityId = this._entityId;
|
const entityId = this._entityId;
|
||||||
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
|
const stateObj = entityId ? this.hass.states[entityId] : undefined;
|
||||||
|
|
||||||
const domain = computeDomain(entityId);
|
const domain = entityId ? computeDomain(entityId) : undefined;
|
||||||
|
|
||||||
const isAdmin = this.hass.user!.is_admin;
|
const isAdmin = this.hass.user!.is_admin;
|
||||||
|
|
||||||
const deviceId = this._getDeviceId();
|
const deviceId = this._getDeviceId();
|
||||||
|
|
||||||
const isDefaultView = this._currView === DEFAULT_VIEW && !this._childView;
|
const previousView = this._previousView();
|
||||||
|
const isDefaultView = this._currView === INFO_VIEW && !this._childView;
|
||||||
const isSpecificInitialView =
|
const isSpecificInitialView =
|
||||||
this._initialView !== DEFAULT_VIEW && !this._childView;
|
this._initialView !== INFO_VIEW && !this._childView;
|
||||||
const showCloseIcon = isDefaultView || isSpecificInitialView;
|
const showCloseIcon = !previousView && !this._childView;
|
||||||
|
|
||||||
const context = stateObj
|
|
||||||
? getEntityContext(stateObj, this.hass)
|
|
||||||
: this._entry
|
|
||||||
? getEntityEntryContext(this._entry, this.hass)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const entityName = stateObj
|
|
||||||
? computeEntityName(stateObj, this.hass)
|
|
||||||
: this._entry
|
|
||||||
? computeEntityEntryName(this._entry, this.hass)
|
|
||||||
: entityId;
|
|
||||||
|
|
||||||
const deviceName = context?.device
|
|
||||||
? computeDeviceName(context.device)
|
|
||||||
: undefined;
|
|
||||||
const areaName = context?.area ? computeAreaName(context.area) : undefined;
|
|
||||||
|
|
||||||
const breadcrumb = [areaName, deviceName, entityName].filter(
|
|
||||||
(v): v is string => Boolean(v)
|
|
||||||
);
|
|
||||||
const title = this._childView?.viewTitle || breadcrumb.pop() || entityId;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
@ -332,7 +426,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
@closed=${this.closeDialog}
|
@closed=${this.closeDialog}
|
||||||
@opened=${this._handleOpened}
|
@opened=${this._handleOpened}
|
||||||
.escapeKeyAction=${this._isEscapeEnabled ? undefined : ""}
|
.escapeKeyAction=${this._isEscapeEnabled ? undefined : ""}
|
||||||
.heading=${title}
|
.heading=${" "}
|
||||||
hideActions
|
hideActions
|
||||||
flexContent
|
flexContent
|
||||||
>
|
>
|
||||||
@ -356,24 +450,7 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
></ha-icon-button-prev>
|
></ha-icon-button-prev>
|
||||||
`}
|
`}
|
||||||
<span slot="title" @click=${this._enlarge} class="title">
|
<span slot="title" @click=${this._enlarge} class="title">
|
||||||
${breadcrumb.length > 0
|
${this._renderHeader()}
|
||||||
? !__DEMO__ && isAdmin
|
|
||||||
? html`
|
|
||||||
<button
|
|
||||||
class="breadcrumb"
|
|
||||||
@click=${this._breadcrumbClick}
|
|
||||||
aria-label=${breadcrumb.join(" > ")}
|
|
||||||
>
|
|
||||||
${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
: html`
|
|
||||||
<p class="breadcrumb">
|
|
||||||
${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
|
|
||||||
</p>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
<p class="main">${title}</p>
|
|
||||||
</span>
|
</span>
|
||||||
${isDefaultView
|
${isDefaultView
|
||||||
? html`
|
? html`
|
||||||
@ -521,54 +598,62 @@ export class MoreInfoDialog extends LitElement {
|
|||||||
@show-child-view=${this._showChildView}
|
@show-child-view=${this._showChildView}
|
||||||
@entity-entry-updated=${this._entryUpdated}
|
@entity-entry-updated=${this._entryUpdated}
|
||||||
@toggle-edit-mode=${this._handleToggleInfoEditModeEvent}
|
@toggle-edit-mode=${this._handleToggleInfoEditModeEvent}
|
||||||
|
@hass-more-info=${this._handleMoreInfoEvent}
|
||||||
>
|
>
|
||||||
${cache(
|
${cache(
|
||||||
this._childView
|
this._childView
|
||||||
? html`
|
? html`
|
||||||
<div class="child-view">
|
<div class="child-view">
|
||||||
${dynamicElement(this._childView.viewTag, {
|
${dynamicElement(this._childView.tag, {
|
||||||
hass: this.hass,
|
hass: this.hass,
|
||||||
entry: this._entry,
|
entry: this._entry,
|
||||||
params: this._childView.viewParams,
|
params: this._childView.params,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: this._currView === "info"
|
: this._currView === "parent"
|
||||||
? html`
|
? dynamicElement(this._parentView!.tag, {
|
||||||
<ha-more-info-info
|
hass: this.hass,
|
||||||
dialogInitialFocus
|
entry: this._entry,
|
||||||
.hass=${this.hass}
|
params: this._parentView!.params,
|
||||||
.entityId=${this._entityId}
|
})
|
||||||
.entry=${this._entry}
|
: this._currView === "info"
|
||||||
.editMode=${this._infoEditMode}
|
|
||||||
></ha-more-info-info>
|
|
||||||
`
|
|
||||||
: this._currView === "history"
|
|
||||||
? html`
|
? html`
|
||||||
<ha-more-info-history-and-logbook
|
<ha-more-info-info
|
||||||
|
dialogInitialFocus
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.entityId=${this._entityId}
|
.entityId=${this._entityId}
|
||||||
></ha-more-info-history-and-logbook>
|
.entry=${this._entry}
|
||||||
|
.editMode=${this._infoEditMode}
|
||||||
|
></ha-more-info-info>
|
||||||
`
|
`
|
||||||
: this._currView === "settings"
|
: this._currView === "history"
|
||||||
? html`
|
? html`
|
||||||
<ha-more-info-settings
|
<ha-more-info-history-and-logbook
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.entityId=${this._entityId}
|
.entityId=${this._entityId}
|
||||||
.entry=${this._entry}
|
></ha-more-info-history-and-logbook>
|
||||||
></ha-more-info-settings>
|
|
||||||
`
|
`
|
||||||
: this._currView === "related"
|
: this._currView === "settings"
|
||||||
? html`
|
? html`
|
||||||
<ha-related-items
|
<ha-more-info-settings
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.itemId=${entityId}
|
.entityId=${this._entityId}
|
||||||
.itemType=${SearchableDomains.has(domain)
|
.entry=${this._entry}
|
||||||
? (domain as ItemType)
|
></ha-more-info-settings>
|
||||||
: "entity"}
|
|
||||||
></ha-related-items>
|
|
||||||
`
|
`
|
||||||
: nothing
|
: this._currView === "related"
|
||||||
|
? html`
|
||||||
|
<ha-related-items
|
||||||
|
.hass=${this.hass}
|
||||||
|
.itemId=${entityId}
|
||||||
|
.itemType=${domain &&
|
||||||
|
SearchableDomains.has(domain)
|
||||||
|
? (domain as ItemType)
|
||||||
|
: "entity"}
|
||||||
|
></ha-related-items>
|
||||||
|
`
|
||||||
|
: nothing
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
|
@ -15,10 +15,11 @@ import "../../../components/ha-control-button-group";
|
|||||||
import "../../../components/ha-domain-icon";
|
import "../../../components/ha-domain-icon";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import type { AreaRegistryEntry } from "../../../data/area_registry";
|
import type { AreaRegistryEntry } from "../../../data/area_registry";
|
||||||
|
import type { GroupToggleDialogParams } from "../../../dialogs/more-info/components/voice/ha-more-info-view-toggle-group";
|
||||||
|
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||||
import { computeCssVariable } from "../../../resources/css-variables";
|
import { computeCssVariable } from "../../../resources/css-variables";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import type { AreaCardFeatureContext } from "../cards/hui-area-card";
|
import type { AreaCardFeatureContext } from "../cards/hui-area-card";
|
||||||
import { showGroupControlDialog } from "../dialogs/show-group-toggle-dialog";
|
|
||||||
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||||
import { cardFeatureStyles } from "./common/card-feature-styles";
|
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||||
import type {
|
import type {
|
||||||
@ -176,10 +177,20 @@ class HuiAreaControlsCardFeature
|
|||||||
|
|
||||||
const domain = AREA_CONTROLS_BUTTONS[control].filter.domain;
|
const domain = AREA_CONTROLS_BUTTONS[control].filter.domain;
|
||||||
|
|
||||||
showGroupControlDialog(this, {
|
showMoreInfoDialog(this, {
|
||||||
title: computeAreaName(this._area!) || "",
|
entityId: null,
|
||||||
subtitle: domain,
|
parentView: {
|
||||||
entityIds: entitiesIds,
|
title: computeAreaName(this._area!) || "",
|
||||||
|
subtitle: domain,
|
||||||
|
tag: "ha-more-info-view-toggle-group",
|
||||||
|
import: () =>
|
||||||
|
import(
|
||||||
|
"../../../dialogs/more-info/components/voice/ha-more-info-view-toggle-group"
|
||||||
|
),
|
||||||
|
params: {
|
||||||
|
entityIds: entitiesIds,
|
||||||
|
} as GroupToggleDialogParams,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
import { mdiClose, mdiLightbulb, mdiLightbulbOff } from "@mdi/js";
|
|
||||||
import type { HassEntity } from "home-assistant-js-websocket";
|
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import memoizeOne from "memoize-one";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
|
||||||
import { computeGroupEntitiesState } from "../../../common/entity/group_entities";
|
|
||||||
import "../../../components/ha-control-button";
|
|
||||||
import "../../../components/ha-control-button-group";
|
|
||||||
import "../../../components/ha-dialog";
|
|
||||||
import "../../../components/ha-dialog-header";
|
|
||||||
import "../../../components/ha-domain-icon";
|
|
||||||
import "../../../components/ha-header-bar";
|
|
||||||
import { forwardHaptic } from "../../../data/haptics";
|
|
||||||
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
|
||||||
import "../../../dialogs/more-info/components/ha-more-info-state-header";
|
|
||||||
import { haStyleDialog } from "../../../resources/styles";
|
|
||||||
import type { HomeAssistant } from "../../../types";
|
|
||||||
import type { TileCardConfig } from "../cards/types";
|
|
||||||
import "../sections/hui-section";
|
|
||||||
import type { GroupToggleDialogParams } from "./show-group-toggle-dialog";
|
|
||||||
import { isFullyClosed, isFullyOpen } from "../../../data/cover";
|
|
||||||
import { UNAVAILABLE } from "../../../data/entity";
|
|
||||||
|
|
||||||
@customElement("hui-dialog-group-toggle")
|
|
||||||
class HuiGroupToggleDialog extends LitElement {
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
||||||
|
|
||||||
@state() private _params?: GroupToggleDialogParams;
|
|
||||||
|
|
||||||
public async showDialog(params: GroupToggleDialogParams): Promise<void> {
|
|
||||||
this._params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async closeDialog(): Promise<void> {
|
|
||||||
this._params = undefined;
|
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _sectionConfig = memoizeOne(
|
|
||||||
(entities: string[]): LovelaceSectionConfig => ({
|
|
||||||
type: "grid",
|
|
||||||
cards: entities.map<TileCardConfig>((entity) => ({
|
|
||||||
type: "tile",
|
|
||||||
entity: entity,
|
|
||||||
icon_tap_action: {
|
|
||||||
action: "toggle",
|
|
||||||
},
|
|
||||||
tap_action: {
|
|
||||||
action: "more-info",
|
|
||||||
},
|
|
||||||
grid_options: {
|
|
||||||
columns: 12,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (!this._params) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sectionConfig = this._sectionConfig(this._params.entityIds);
|
|
||||||
|
|
||||||
const entities = this._params.entityIds
|
|
||||||
.map((entityId) => this.hass!.states[entityId] as HassEntity | undefined)
|
|
||||||
.filter((v): v is HassEntity => Boolean(v));
|
|
||||||
|
|
||||||
const mainStateObj = entities[0];
|
|
||||||
|
|
||||||
const groupState = computeGroupEntitiesState(entities);
|
|
||||||
const formattedGroupState = this.hass.formatEntityState(
|
|
||||||
mainStateObj,
|
|
||||||
groupState
|
|
||||||
);
|
|
||||||
|
|
||||||
const domain = computeStateDomain(mainStateObj);
|
|
||||||
|
|
||||||
const deviceClass = mainStateObj.attributes.device_class;
|
|
||||||
|
|
||||||
const isGroup = this._params.entityIds.length > 1;
|
|
||||||
|
|
||||||
const isAllOn = entities.every((entity) =>
|
|
||||||
entity.state === UNAVAILABLE ||
|
|
||||||
computeDomain(entity.entity_id) === "cover"
|
|
||||||
? isFullyOpen(entity)
|
|
||||||
: entity.state === "on"
|
|
||||||
);
|
|
||||||
const isAllOff = entities.every((entity) =>
|
|
||||||
entity.state === UNAVAILABLE ||
|
|
||||||
computeDomain(entity.entity_id) === "cover"
|
|
||||||
? isFullyClosed(entity)
|
|
||||||
: entity.state === "off"
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-dialog
|
|
||||||
open
|
|
||||||
@closed=${this.closeDialog}
|
|
||||||
.heading=${this._params.title}
|
|
||||||
hideActions
|
|
||||||
flexContent
|
|
||||||
>
|
|
||||||
<ha-dialog-header slot="heading">
|
|
||||||
<ha-icon-button
|
|
||||||
slot="navigationIcon"
|
|
||||||
dialogAction="cancel"
|
|
||||||
.label=${this.hass.localize("ui.common.close")}
|
|
||||||
.path=${mdiClose}
|
|
||||||
></ha-icon-button>
|
|
||||||
<span slot="title" class="title">
|
|
||||||
${this._params.subtitle
|
|
||||||
? html`<span class="subtitle">${this._params.subtitle}</span>`
|
|
||||||
: nothing}
|
|
||||||
<p class="main">${this._params.title}</p>
|
|
||||||
</span>
|
|
||||||
</ha-dialog-header>
|
|
||||||
<div class="content">
|
|
||||||
<ha-more-info-state-header
|
|
||||||
.hass=${this.hass}
|
|
||||||
.stateObj=${mainStateObj}
|
|
||||||
.stateOverride=${formattedGroupState}
|
|
||||||
></ha-more-info-state-header>
|
|
||||||
<ha-control-button-group vertical>
|
|
||||||
<ha-control-button
|
|
||||||
vertical
|
|
||||||
@click=${this._turnAllOn}
|
|
||||||
.disabled=${isAllOn}
|
|
||||||
>
|
|
||||||
${domain !== "light"
|
|
||||||
? html`<ha-domain-icon
|
|
||||||
.hass=${this.hass}
|
|
||||||
.domain=${domain}
|
|
||||||
.state=${domain === "cover" ? "open" : "on"}
|
|
||||||
.deviceClass=${deviceClass}
|
|
||||||
></ha-domain-icon>`
|
|
||||||
: html` <ha-svg-icon .path=${mdiLightbulb}></ha-svg-icon> `}
|
|
||||||
<p>
|
|
||||||
${domain === "cover"
|
|
||||||
? isGroup
|
|
||||||
? "Open all"
|
|
||||||
: "Open"
|
|
||||||
: isGroup
|
|
||||||
? "Turn all on"
|
|
||||||
: "Turn on"}
|
|
||||||
</p>
|
|
||||||
</ha-control-button>
|
|
||||||
<ha-control-button
|
|
||||||
vertical
|
|
||||||
@click=${this._turnAllOff}
|
|
||||||
.disabled=${isAllOff}
|
|
||||||
>
|
|
||||||
${domain !== "light"
|
|
||||||
? html`
|
|
||||||
<ha-domain-icon
|
|
||||||
.hass=${this.hass}
|
|
||||||
.domain=${domain}
|
|
||||||
.state=${domain === "cover" ? "closed" : "off"}
|
|
||||||
.deviceClass=${deviceClass}
|
|
||||||
></ha-domain-icon>
|
|
||||||
`
|
|
||||||
: html` <ha-svg-icon .path=${mdiLightbulbOff}></ha-svg-icon>`}
|
|
||||||
<p>
|
|
||||||
${domain === "cover"
|
|
||||||
? isGroup
|
|
||||||
? "Close all"
|
|
||||||
: "Close"
|
|
||||||
: isGroup
|
|
||||||
? "Turn all off"
|
|
||||||
: "Turn off"}
|
|
||||||
</p>
|
|
||||||
</ha-control-button>
|
|
||||||
</ha-control-button-group>
|
|
||||||
<hui-section
|
|
||||||
.config=${sectionConfig}
|
|
||||||
.hass=${this.hass}
|
|
||||||
></hui-section>
|
|
||||||
</div>
|
|
||||||
</ha-dialog>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _turnAllOff() {
|
|
||||||
if (!this._params) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
forwardHaptic("light");
|
|
||||||
const domain = computeDomain(this._params.entityIds[0]);
|
|
||||||
if (domain === "cover") {
|
|
||||||
this.hass.callService("cover", "close_cover", {
|
|
||||||
entity_id: this._params.entityIds,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.hass.callService("homeassistant", "turn_off", {
|
|
||||||
entity_id: this._params.entityIds,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _turnAllOn() {
|
|
||||||
if (!this._params) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
forwardHaptic("light");
|
|
||||||
const domain = computeDomain(this._params.entityIds[0]);
|
|
||||||
if (domain === "cover") {
|
|
||||||
this.hass.callService("cover", "open_cover", {
|
|
||||||
entity_id: this._params.entityIds,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.hass.callService("homeassistant", "turn_on", {
|
|
||||||
entity_id: this._params.entityIds,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = [
|
|
||||||
haStyleDialog,
|
|
||||||
css`
|
|
||||||
ha-dialog {
|
|
||||||
/* Set the top top of the dialog to a fixed position, so it doesnt jump when the content changes size */
|
|
||||||
--vertical-align-dialog: flex-start;
|
|
||||||
--dialog-surface-margin-top: 40px;
|
|
||||||
--dialog-content-padding: 0;
|
|
||||||
}
|
|
||||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
|
||||||
/* When in fullscreen dialog should be attached to top */
|
|
||||||
ha-dialog {
|
|
||||||
--dialog-surface-margin-top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media all and (min-width: 600px) and (min-height: 501px) {
|
|
||||||
ha-dialog {
|
|
||||||
--mdc-dialog-min-width: 580px;
|
|
||||||
--mdc-dialog-max-width: 580px;
|
|
||||||
--mdc-dialog-max-height: calc(100% - 72px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-title {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([large]) ha-dialog {
|
|
||||||
--mdc-dialog-min-width: 90vw;
|
|
||||||
--mdc-dialog-max-width: 90vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title p {
|
|
||||||
margin: 0;
|
|
||||||
min-width: 0;
|
|
||||||
width: 100%;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title .main {
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
font-size: var(--ha-font-size-xl);
|
|
||||||
line-height: var(--ha-line-height-condensed);
|
|
||||||
}
|
|
||||||
|
|
||||||
.title .subtitle {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: var(--ha-font-size-m);
|
|
||||||
line-height: 16px;
|
|
||||||
--mdc-icon-size: 16px;
|
|
||||||
padding: 4px;
|
|
||||||
margin: -4px;
|
|
||||||
margin-top: -10px;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
display: inline;
|
|
||||||
border-radius: 6px;
|
|
||||||
transition: background-color 180ms ease-in-out;
|
|
||||||
min-width: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 0 16px 16px 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 24px;
|
|
||||||
}
|
|
||||||
ha-control-button-group {
|
|
||||||
--control-button-group-spacing: 12px;
|
|
||||||
--control-button-group-thickness: 130px;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
ha-control-button {
|
|
||||||
--control-button-border-radius: 16px;
|
|
||||||
--mdc-icon-size: 24px;
|
|
||||||
color: #006787;
|
|
||||||
--control-button-padding: 16px 8px;
|
|
||||||
--control-button-icon-color: #006787;
|
|
||||||
--control-button-background-color: #eff9fe;
|
|
||||||
--control-button-background-opacity: 1;
|
|
||||||
--control-button-focus-color: #006787;
|
|
||||||
--ha-ripple-color: #006787;
|
|
||||||
}
|
|
||||||
ha-control-button p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
hui-section {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hui-dialog-group-toggle": HuiGroupToggleDialog;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
|
|
||||||
export interface GroupToggleDialogParams {
|
|
||||||
title: string;
|
|
||||||
subtitle?: string;
|
|
||||||
entityIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const showGroupControlDialog = (
|
|
||||||
element: HTMLElement,
|
|
||||||
dialogParams: GroupToggleDialogParams
|
|
||||||
) => {
|
|
||||||
fireEvent(element, "show-dialog", {
|
|
||||||
dialogTag: "hui-dialog-group-toggle",
|
|
||||||
dialogImport: () => import("./hui-dialog-group-toggle"),
|
|
||||||
dialogParams: dialogParams,
|
|
||||||
});
|
|
||||||
};
|
|
@ -30,6 +30,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||||||
{
|
{
|
||||||
entityId: ev.detail.entityId,
|
entityId: ev.detail.entityId,
|
||||||
view: ev.detail.view || ev.detail.tab,
|
view: ev.detail.view || ev.detail.tab,
|
||||||
|
parentView: ev.detail.parentView,
|
||||||
},
|
},
|
||||||
() => import("../dialogs/more-info/ha-more-info-dialog")
|
() => import("../dialogs/more-info/ha-more-info-dialog")
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user