mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Template markdown card (#3451)
* Render templates in markdown card * Add manual entity_id option * Linting * Address review comments * Address review comments * Address review comments * Address review comments * Tweak disconnect function * Remove cardSize instance variable * Fix demo
This commit is contained in:
parent
c15629b81b
commit
1f3a5b1396
20
src/data/ws-templates.ts
Normal file
20
src/data/ws-templates.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Connection, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
|
interface RenderTemplateResult {
|
||||||
|
result: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const subscribeRenderTemplate = (
|
||||||
|
conn: Connection,
|
||||||
|
onChange: (result: string) => void,
|
||||||
|
params: {
|
||||||
|
template: string;
|
||||||
|
entity_ids?: string | string[];
|
||||||
|
variables?: object;
|
||||||
|
}
|
||||||
|
): Promise<UnsubscribeFunc> => {
|
||||||
|
return conn.subscribeMessage(
|
||||||
|
(msg: RenderTemplateResult) => onChange(msg.result),
|
||||||
|
{ type: "render_template", ...params }
|
||||||
|
);
|
||||||
|
};
|
@ -24,7 +24,10 @@ export interface MockHomeAssistant extends HomeAssistant {
|
|||||||
updateHass(obj: Partial<MockHomeAssistant>);
|
updateHass(obj: Partial<MockHomeAssistant>);
|
||||||
updateStates(newStates: HassEntities);
|
updateStates(newStates: HassEntities);
|
||||||
addEntities(entites: Entity | Entity[], replace?: boolean);
|
addEntities(entites: Entity | Entity[], replace?: boolean);
|
||||||
mockWS(type: string, callback: (msg: any) => any);
|
mockWS(
|
||||||
|
type: string,
|
||||||
|
callback: (msg: any, onChange?: (response: any) => void) => any
|
||||||
|
);
|
||||||
mockAPI(path: string | RegExp, callback: MockRestCallback);
|
mockAPI(path: string | RegExp, callback: MockRestCallback);
|
||||||
mockEvent(event);
|
mockEvent(event);
|
||||||
mockTheme(theme: { [key: string]: string } | null);
|
mockTheme(theme: { [key: string]: string } | null);
|
||||||
@ -108,7 +111,7 @@ export const provideHass = (
|
|||||||
console.error(`Unknown WS command: ${msg.type}`);
|
console.error(`Unknown WS command: ${msg.type}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendMessagePromise: (msg) => {
|
sendMessagePromise: async (msg) => {
|
||||||
const callback = wsCommands[msg.type];
|
const callback = wsCommands[msg.type];
|
||||||
return callback
|
return callback
|
||||||
? callback(msg)
|
? callback(msg)
|
||||||
@ -119,6 +122,17 @@ export const provideHass = (
|
|||||||
} is not implemented in provide_hass.`,
|
} is not implemented in provide_hass.`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
subscribeMessage: async (onChange, msg) => {
|
||||||
|
const callback = wsCommands[msg.type];
|
||||||
|
return callback
|
||||||
|
? callback(msg, onChange)
|
||||||
|
: Promise.reject({
|
||||||
|
code: "command_not_mocked",
|
||||||
|
message: `WS Command ${
|
||||||
|
msg.type
|
||||||
|
} is not implemented in provide_hass.`,
|
||||||
|
});
|
||||||
|
},
|
||||||
subscribeEvents: async (
|
subscribeEvents: async (
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
callback,
|
callback,
|
||||||
|
@ -8,12 +8,15 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-markdown";
|
import "../../../components/ha-markdown";
|
||||||
|
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { MarkdownCardConfig } from "./types";
|
import { MarkdownCardConfig } from "./types";
|
||||||
|
import { subscribeRenderTemplate } from "../../../data/ws-templates";
|
||||||
|
|
||||||
@customElement("hui-markdown-card")
|
@customElement("hui-markdown-card")
|
||||||
export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
||||||
@ -27,11 +30,16 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@property() private _config?: MarkdownCardConfig;
|
@property() private _config?: MarkdownCardConfig;
|
||||||
|
@property() private _content?: string = "";
|
||||||
|
@property() private _unsubRenderTemplate?: Promise<UnsubscribeFunc>;
|
||||||
|
@property() private _hass?: HomeAssistant;
|
||||||
|
|
||||||
public getCardSize(): number {
|
public getCardSize(): number {
|
||||||
return (
|
return this._config === undefined
|
||||||
this._config!.content.split("\n").length + (this._config!.title ? 1 : 0)
|
? 3
|
||||||
);
|
: this._config.card_size === undefined
|
||||||
|
? this._config.content.split("\n").length + (this._config.title ? 1 : 0)
|
||||||
|
: this._config.card_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setConfig(config: MarkdownCardConfig): void {
|
public setConfig(config: MarkdownCardConfig): void {
|
||||||
@ -40,6 +48,20 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._config = config;
|
this._config = config;
|
||||||
|
|
||||||
|
this._disconnect();
|
||||||
|
if (this._hass) {
|
||||||
|
this._connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
this._disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public set hass(hass) {
|
||||||
|
this._hass = hass;
|
||||||
|
this._connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult | void {
|
protected render(): TemplateResult | void {
|
||||||
@ -53,12 +75,47 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard {
|
|||||||
class="markdown ${classMap({
|
class="markdown ${classMap({
|
||||||
"no-header": !this._config.title,
|
"no-header": !this._config.title,
|
||||||
})}"
|
})}"
|
||||||
.content="${this._config.content}"
|
.content="${this._content}"
|
||||||
></ha-markdown>
|
></ha-markdown>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _connect() {
|
||||||
|
if (!this._unsubRenderTemplate && this._hass && this._config) {
|
||||||
|
this._unsubRenderTemplate = subscribeRenderTemplate(
|
||||||
|
this._hass.connection,
|
||||||
|
(result) => {
|
||||||
|
this._content = result;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: this._config.content,
|
||||||
|
entity_ids: this._config.entity_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this._unsubRenderTemplate.catch(() => {
|
||||||
|
this._content = this._config!.content;
|
||||||
|
this._unsubRenderTemplate = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _disconnect() {
|
||||||
|
if (this._unsubRenderTemplate) {
|
||||||
|
try {
|
||||||
|
const unsub = await this._unsubRenderTemplate;
|
||||||
|
this._unsubRenderTemplate = undefined;
|
||||||
|
await unsub();
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === "not_found") {
|
||||||
|
// If we get here, the connection was probably already closed. Ignore.
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
ha-markdown {
|
ha-markdown {
|
||||||
|
@ -118,6 +118,8 @@ export interface MarkdownCardConfig extends LovelaceCardConfig {
|
|||||||
type: "markdown";
|
type: "markdown";
|
||||||
content: string;
|
content: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
card_size?: number;
|
||||||
|
entity_ids?: string | string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MediaControlCardConfig extends LovelaceCardConfig {
|
export interface MediaControlCardConfig extends LovelaceCardConfig {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user