mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-12 18:59:26 +00:00
Compare commits
3 Commits
20220322.0
...
template-e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
72bf0c918a | ||
![]() |
419f5d13bf | ||
![]() |
16549b3404 |
88
src/dialogs/template-editor/ha-template-editor.ts
Normal file
88
src/dialogs/template-editor/ha-template-editor.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import "../../panels/developer-tools/template/developer-tools-template";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "../../components/ha-code-editor";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import {
|
||||
css,
|
||||
CSSResultArray,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../components/ha-circular-progress";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-header-bar";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { TemplateEditorParams } from "./show-dialog-template-editor";
|
||||
|
||||
@customElement("ha-template-editor")
|
||||
export class TemplateEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
|
||||
@internalProperty() private _startingTemplate?: string;
|
||||
|
||||
public showDialog(params: TemplateEditorParams) {
|
||||
this._startingTemplate = `${params.startingTemplate}\n\n\n\n`;
|
||||
this._opened = true;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._opened = false;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._opened) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`<ha-dialog
|
||||
.heading=${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.editor"
|
||||
)}
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
hideActions
|
||||
>
|
||||
<div class="content">
|
||||
<developer-tools-template
|
||||
.narrow=${true}
|
||||
.hass=${this.hass}
|
||||
.simple=${true}
|
||||
.startingTemplate=${this._startingTemplate}
|
||||
></developer-tools-template>
|
||||
</div>
|
||||
</ha-dialog>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
:host {
|
||||
width: 100%;
|
||||
--mdc-dialog-max-width: 700px;
|
||||
--mdc-dialog-min-width: 700px;
|
||||
--mdc-dialog-max-height: calc(100% - 72px);
|
||||
--mdc-dialog-min-height: 400px;
|
||||
--dialog-content-padding: 0px;
|
||||
--template-results-width: 100%;
|
||||
--mdc-dialog-content-ink-color: var(--primary-text-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-template-editor": TemplateEditor;
|
||||
}
|
||||
}
|
21
src/dialogs/template-editor/show-dialog-template-editor.ts
Normal file
21
src/dialogs/template-editor/show-dialog-template-editor.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
|
||||
export interface TemplateEditorParams {
|
||||
startingTemplate?: string;
|
||||
}
|
||||
|
||||
export const loadTemplateEditor = () =>
|
||||
import(
|
||||
/* webpackChunkName: "template-editor-dialog" */ "./ha-template-editor"
|
||||
);
|
||||
|
||||
export const showTemplateEditor = (
|
||||
element: HTMLElement,
|
||||
dialogParams: TemplateEditorParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "ha-template-editor",
|
||||
dialogImport: loadTemplateEditor,
|
||||
dialogParams,
|
||||
});
|
||||
};
|
@@ -48,6 +48,10 @@ class HaPanelDevTemplate extends LitElement {
|
||||
|
||||
@property() public narrow!: boolean;
|
||||
|
||||
@property() public simple = false;
|
||||
|
||||
@property() public startingTemplate?: string;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
|
||||
@internalProperty() private _rendering = false;
|
||||
@@ -72,7 +76,9 @@ class HaPanelDevTemplate extends LitElement {
|
||||
}
|
||||
|
||||
protected firstUpdated() {
|
||||
if (localStorage && localStorage["panel-dev-template-template"]) {
|
||||
if (this.startingTemplate) {
|
||||
this._template = this.startingTemplate;
|
||||
} else if (localStorage && localStorage["panel-dev-template-template"]) {
|
||||
this._template = localStorage["panel-dev-template-template"];
|
||||
} else {
|
||||
this._template = DEMO_TEMPLATE;
|
||||
@@ -82,13 +88,6 @@ class HaPanelDevTemplate extends LitElement {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const type = typeof this._templateResult?.result;
|
||||
const resultType =
|
||||
type === "object"
|
||||
? Array.isArray(this._templateResult?.result)
|
||||
? "list"
|
||||
: "dict"
|
||||
: type;
|
||||
return html`
|
||||
<div
|
||||
class="content ${classMap({
|
||||
@@ -97,42 +96,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
})}"
|
||||
>
|
||||
<div class="edit-pane">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.description"
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="http://jinja.pocoo.org/docs/dev/templates/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.jinja_documentation"
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="${documentationUrl(
|
||||
this.hass,
|
||||
"/docs/configuration/templating/"
|
||||
)}"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.template_extensions"
|
||||
)}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.editor"
|
||||
)}
|
||||
</p>
|
||||
${this.simple ? "" : this._renderDescription()}
|
||||
<ha-code-editor
|
||||
mode="jinja2"
|
||||
.value=${this._template}
|
||||
@@ -147,103 +111,156 @@ class HaPanelDevTemplate extends LitElement {
|
||||
</mwc-button>
|
||||
</div>
|
||||
|
||||
<div class="render-pane">
|
||||
${this._rendering
|
||||
? html`<ha-circular-progress
|
||||
class="render-spinner"
|
||||
active
|
||||
size="small"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this._templateResult
|
||||
? html`${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.result_type"
|
||||
)}:
|
||||
${resultType}`
|
||||
: ""}
|
||||
<!-- prettier-ignore -->
|
||||
<pre
|
||||
class="rendered ${classMap({
|
||||
error: Boolean(this._error),
|
||||
[resultType]: resultType,
|
||||
})}"
|
||||
>${this._error}${type === "object"
|
||||
? JSON.stringify(this._templateResult!.result, null, 2)
|
||||
: this._templateResult?.result}</pre>
|
||||
${this._templateResult?.listeners.time
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.time"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
: ""}
|
||||
${!this._templateResult?.listeners
|
||||
? ""
|
||||
: this._templateResult.listeners.all
|
||||
? html`
|
||||
<p class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.all_listeners"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
: this._templateResult.listeners.domains.length ||
|
||||
this._templateResult.listeners.entities.length
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.listeners"
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
${this._templateResult.listeners.domains
|
||||
.sort()
|
||||
.map(
|
||||
(domain) =>
|
||||
html`
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.domain"
|
||||
)}</b
|
||||
>: ${domain}
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
${this._templateResult.listeners.entities
|
||||
.sort()
|
||||
.map(
|
||||
(entity_id) =>
|
||||
html`
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.entity"
|
||||
)}</b
|
||||
>: ${entity_id}
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
</ul>
|
||||
`
|
||||
: !this._templateResult?.listeners.time
|
||||
? html` <span class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.no_listeners"
|
||||
)}
|
||||
</span>`
|
||||
: html``}
|
||||
</div>
|
||||
${this._renderResult()}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderResult() {
|
||||
const type = typeof this._templateResult?.result;
|
||||
const resultType =
|
||||
type === "object"
|
||||
? Array.isArray(this._templateResult?.result)
|
||||
? "list"
|
||||
: "dict"
|
||||
: type;
|
||||
|
||||
return html`<div class="render-pane">
|
||||
${this._rendering
|
||||
? html`<ha-circular-progress
|
||||
class="render-spinner"
|
||||
active
|
||||
size="small"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this._templateResult
|
||||
? html`${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.result_type"
|
||||
)}:
|
||||
${resultType}`
|
||||
: ""}
|
||||
<!-- prettier-ignore -->
|
||||
<pre
|
||||
class="rendered ${classMap({
|
||||
error: Boolean(this._error),
|
||||
[resultType]: resultType,
|
||||
})}"
|
||||
>${this._error}${type === "object"
|
||||
? JSON.stringify(this._templateResult!.result, null, 2)
|
||||
: this._templateResult?.result}</pre>
|
||||
${this._templateResult?.listeners.time
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.time"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
: ""}
|
||||
${!this._templateResult?.listeners
|
||||
? ""
|
||||
: this._templateResult.listeners.all
|
||||
? html`
|
||||
<p class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.all_listeners"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
: this._templateResult.listeners.domains.length ||
|
||||
this._templateResult.listeners.entities.length
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.listeners"
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
${this._templateResult.listeners.domains
|
||||
.sort()
|
||||
.map(
|
||||
(domain) =>
|
||||
html`
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.domain"
|
||||
)}</b
|
||||
>: ${domain}
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
${this._templateResult.listeners.entities
|
||||
.sort()
|
||||
.map(
|
||||
(entity_id) =>
|
||||
html`
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.entity"
|
||||
)}</b
|
||||
>: ${entity_id}
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
</ul>
|
||||
`
|
||||
: !this._templateResult?.listeners.time
|
||||
? html` <span class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.no_listeners"
|
||||
)}
|
||||
</span>`
|
||||
: html``}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private _renderDescription() {
|
||||
return html`<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.description"
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="http://jinja.pocoo.org/docs/dev/templates/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.jinja_documentation"
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="${documentationUrl(
|
||||
this.hass,
|
||||
"/docs/configuration/templating/"
|
||||
)}"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.template_extensions"
|
||||
)}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.templates.editor")}
|
||||
</p>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
:root {
|
||||
--template-results-width: 50%;
|
||||
}
|
||||
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
-webkit-user-select: initial;
|
||||
@@ -264,12 +281,12 @@ class HaPanelDevTemplate extends LitElement {
|
||||
}
|
||||
|
||||
.horizontal .edit-pane {
|
||||
max-width: 50%;
|
||||
max-width: var(--template-results-width, 50%);
|
||||
}
|
||||
|
||||
.render-pane {
|
||||
position: relative;
|
||||
max-width: 50%;
|
||||
max-width: var(--template-results-width, 50%);
|
||||
}
|
||||
|
||||
.render-spinner {
|
||||
|
@@ -7,10 +7,15 @@ import {
|
||||
} from "../dialogs/quick-bar/show-dialog-quick-bar";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { storeState } from "../util/ha-pref-storage";
|
||||
import {
|
||||
showTemplateEditor,
|
||||
TemplateEditorParams,
|
||||
} from "../dialogs/template-editor/show-dialog-template-editor";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"hass-quick-bar": QuickBarParams;
|
||||
"hass-template-editor": TemplateEditorParams;
|
||||
"hass-enable-shortcuts": HomeAssistant["enableShortcuts"];
|
||||
}
|
||||
}
|
||||
@@ -32,18 +37,27 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
tinykeys(window, {
|
||||
e: (ev) => this._showQuickBar(ev),
|
||||
c: (ev) => this._showQuickBar(ev, true),
|
||||
t: (ev) => this._showTemplateEditor(ev),
|
||||
});
|
||||
}
|
||||
|
||||
private _showQuickBar(e: KeyboardEvent, commandMode = false) {
|
||||
if (!this._canShowQuickBar(e)) {
|
||||
if (!this._canShowDialogWithShortcut(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
showQuickBar(this, { commandMode });
|
||||
}
|
||||
|
||||
private _canShowQuickBar(e: KeyboardEvent) {
|
||||
private _showTemplateEditor(e: KeyboardEvent) {
|
||||
if (!this._canShowDialogWithShortcut(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
showTemplateEditor(this, { startingTemplate: "{{ states.sun.sun }}" });
|
||||
}
|
||||
|
||||
private _canShowDialogWithShortcut(e: KeyboardEvent) {
|
||||
return (
|
||||
this.hass?.user?.is_admin &&
|
||||
this.hass.enableShortcuts &&
|
||||
|
Reference in New Issue
Block a user