mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 16:26:43 +00:00
Add preview for template (#17699)
This commit is contained in:
parent
034ce56da5
commit
d350c35c4e
@ -1,4 +1,5 @@
|
||||
import { Connection, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
export interface RenderTemplateResult {
|
||||
result: string;
|
||||
@ -12,6 +13,17 @@ interface TemplateListeners {
|
||||
time: boolean;
|
||||
}
|
||||
|
||||
export type TemplatePreview = TemplatePreviewState | TemplatePreviewError;
|
||||
|
||||
interface TemplatePreviewState {
|
||||
state: string;
|
||||
attributes: Record<string, any>;
|
||||
}
|
||||
|
||||
interface TemplatePreviewError {
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const subscribeRenderTemplate = (
|
||||
conn: Connection,
|
||||
onChange: (result: RenderTemplateResult) => void,
|
||||
@ -27,3 +39,17 @@ export const subscribeRenderTemplate = (
|
||||
type: "render_template",
|
||||
...params,
|
||||
});
|
||||
|
||||
export const subscribePreviewTemplate = (
|
||||
hass: HomeAssistant,
|
||||
flow_id: string,
|
||||
flow_type: "config_flow" | "options_flow",
|
||||
user_input: Record<string, any>,
|
||||
callback: (preview: TemplatePreview) => void
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
hass.connection.subscribeMessage(callback, {
|
||||
type: "template/start_preview",
|
||||
flow_id,
|
||||
flow_type,
|
||||
user_input,
|
||||
});
|
||||
|
114
src/dialogs/config-flow/previews/flow-preview-template.ts
Normal file
114
src/dialogs/config-flow/previews/flow-preview-template.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import { FlowType } from "../../../data/data_entry_flow";
|
||||
import {
|
||||
TemplatePreview,
|
||||
subscribePreviewTemplate,
|
||||
} from "../../../data/ws-templates";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import "./entity-preview-row";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
|
||||
@customElement("flow-preview-template")
|
||||
class FlowPreviewTemplate extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public flowType!: FlowType;
|
||||
|
||||
public handler!: string;
|
||||
|
||||
@property() public stepId!: string;
|
||||
|
||||
@property() public flowId!: string;
|
||||
|
||||
@property() public stepData!: Record<string, any>;
|
||||
|
||||
@state() private _preview?: HassEntity;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
private _unsub?: Promise<UnsubscribeFunc>;
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
if (this._unsub) {
|
||||
this._unsub.then((unsub) => unsub());
|
||||
this._unsub = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
willUpdate(changedProps) {
|
||||
if (changedProps.has("stepData")) {
|
||||
this._debouncedSubscribePreview();
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (this._error) {
|
||||
return html`<ha-alert alert-type="error">${this._error}</ha-alert>`;
|
||||
}
|
||||
return html`<entity-preview-row
|
||||
.hass=${this.hass}
|
||||
.stateObj=${this._preview}
|
||||
></entity-preview-row>`;
|
||||
}
|
||||
|
||||
private _setPreview = (preview: TemplatePreview) => {
|
||||
if ("error" in preview) {
|
||||
this._error = preview.error;
|
||||
this._preview = undefined;
|
||||
return;
|
||||
}
|
||||
this._error = undefined;
|
||||
const now = new Date().toISOString();
|
||||
this._preview = {
|
||||
entity_id: `${this.stepId}.flow_preview`,
|
||||
last_changed: now,
|
||||
last_updated: now,
|
||||
context: { id: "", parent_id: null, user_id: null },
|
||||
...preview,
|
||||
};
|
||||
};
|
||||
|
||||
private _debouncedSubscribePreview = debounce(() => {
|
||||
this._subscribePreview();
|
||||
}, 250);
|
||||
|
||||
private async _subscribePreview() {
|
||||
if (this._unsub) {
|
||||
(await this._unsub)();
|
||||
this._unsub = undefined;
|
||||
}
|
||||
if (this.flowType === "repair_flow") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this._unsub = subscribePreviewTemplate(
|
||||
this.hass,
|
||||
this.flowId,
|
||||
this.flowType,
|
||||
this.stepData,
|
||||
this._setPreview
|
||||
);
|
||||
await this._unsub;
|
||||
fireEvent(this, "set-flow-errors", { errors: {} });
|
||||
} catch (err: any) {
|
||||
if (typeof err.message === "string") {
|
||||
this._error = err.message;
|
||||
} else {
|
||||
this._error = undefined;
|
||||
fireEvent(this, "set-flow-errors", err.message);
|
||||
}
|
||||
this._unsub = undefined;
|
||||
this._preview = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"flow-preview-template": FlowPreviewTemplate;
|
||||
}
|
||||
}
|
@ -70,7 +70,7 @@ class StepFlowForm extends LitElement {
|
||||
></ha-form>
|
||||
</div>
|
||||
${step.preview
|
||||
? html`<div class="preview">
|
||||
? html`<div class="preview" @set-flow-errors=${this._setError}>
|
||||
<h3>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.preview"
|
||||
@ -107,6 +107,10 @@ class StepFlowForm extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _setError(ev: CustomEvent) {
|
||||
this.step = { ...this.step, errors: ev.detail };
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
setTimeout(() => this.shadowRoot!.querySelector("ha-form")!.focus(), 0);
|
||||
@ -253,6 +257,9 @@ class StepFlowForm extends LitElement {
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"set-flow-errors": { errors: DataEntryFlowStepForm["errors"] };
|
||||
}
|
||||
interface HTMLElementTagNameMap {
|
||||
"step-flow-form": StepFlowForm;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user