Compare commits

...

3 Commits

Author SHA1 Message Date
Donnie
72bf0c918a Update src/dialogs/template-editor/ha-template-editor.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2020-11-17 16:07:54 -08:00
Donnie
419f5d13bf Update src/dialogs/template-editor/ha-template-editor.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2020-11-17 16:07:48 -08:00
Donnie
16549b3404 Add ability to launch small version of template editor in a dialog using shortcut 2020-11-17 11:41:29 -08:00
4 changed files with 277 additions and 137 deletions

View 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;
}
}

View 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,
});
};

View File

@@ -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 {

View File

@@ -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 &&