diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index f57806f896..2ff983d4c0 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -1,56 +1,23 @@ import "@material/mwc-button/mwc-button"; import { HassEntity } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, LitElement } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { nestedArrayMove } from "../../../common/util/array-move"; +import { html } from "lit"; +import { customElement, property } from "lit/decorators"; import "../../../components/ha-alert"; -import "../../../components/ha-blueprint-picker"; -import "../../../components/ha-card"; -import "../../../components/ha-circular-progress"; -import "../../../components/ha-markdown"; -import "../../../components/ha-selector/ha-selector"; -import "../../../components/ha-settings-row"; import { BlueprintAutomationConfig } from "../../../data/automation"; -import { - BlueprintOrError, - Blueprints, - fetchBlueprints, -} from "../../../data/blueprint"; -import { haStyle } from "../../../resources/styles"; -import { HomeAssistant } from "../../../types"; -import "../ha-config-section"; +import { fetchBlueprints } from "../../../data/blueprint"; +import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; @customElement("blueprint-automation-editor") -export class HaBlueprintAutomationEditor extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property({ type: Boolean }) public isWide = false; - - @property({ type: Boolean }) public disabled = false; - - @property({ type: Boolean, reflect: true }) public narrow = false; - +export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { @property({ attribute: false }) public config!: BlueprintAutomationConfig; @property({ attribute: false }) public stateObj?: HassEntity; - @state() private _blueprints?: Blueprints; - - protected firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this._getBlueprints(); - } - - private get _blueprint(): BlueprintOrError | undefined { - if (!this._blueprints) { - return undefined; - } - return this._blueprints[this.config.use_blueprint.path]; + protected get _config(): BlueprintAutomationConfig { + return this.config; } protected render() { - const blueprint = this._blueprint; return html` ${this.disabled ? html` @@ -77,167 +44,14 @@ export class HaBlueprintAutomationEditor extends LitElement { ${this.config.description ? html`

${this.config.description}

` : ""} - -
- ${this._blueprints - ? Object.keys(this._blueprints).length - ? html` - - ` - : this.hass.localize( - "ui.panel.config.automation.editor.blueprint.no_blueprints" - ) - : html``} -
- - ${this.config.use_blueprint.path - ? blueprint && "error" in blueprint - ? html`

- There is an error in this Blueprint: ${blueprint.error} -

` - : html`${blueprint?.metadata.description - ? html`` - : ""} - ${blueprint?.metadata?.input && - Object.keys(blueprint.metadata.input).length - ? Object.entries(blueprint.metadata.input).map( - ([key, value]) => { - const selector = value?.selector ?? { text: undefined }; - const type = Object.keys(selector)[0]; - const enhancedSelector = [ - "action", - "condition", - "trigger", - ].includes(type) - ? { - [type]: { - ...selector[type], - path: [key], - }, - } - : selector; - - return html` - ${value?.name || key} - - ${html``} - `; - } - ) - : html`

- ${this.hass.localize( - "ui.panel.config.automation.editor.blueprint.no_inputs" - )} -

`}` - : ""} -
+ ${this.renderCard()} `; } - private async _getBlueprints() { + protected async _getBlueprints() { this._blueprints = await fetchBlueprints(this.hass, "automation"); } - private _blueprintChanged(ev) { - ev.stopPropagation(); - if (this.config.use_blueprint.path === ev.detail.value) { - return; - } - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - path: ev.detail.value, - }, - }, - }); - } - - private _inputChanged(ev) { - ev.stopPropagation(); - const target = ev.target as any; - const key = target.key; - const value = ev.detail ? ev.detail.value : target.value; - if ( - (this.config.use_blueprint.input && - this.config.use_blueprint.input[key] === value) || - (!this.config.use_blueprint.input && value === "") - ) { - return; - } - const input = { ...this.config.use_blueprint.input, [key]: value }; - - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - ...this.config.use_blueprint, - input, - }, - }, - }); - } - - private _itemMoved(ev) { - ev.stopPropagation(); - const { oldIndex, newIndex, oldPath, newPath } = ev.detail; - - const input = nestedArrayMove( - this.config.use_blueprint.input, - oldIndex, - newIndex, - oldPath, - newPath - ); - - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - ...this.config.use_blueprint, - input, - }, - }, - }); - } - private async _enable(): Promise { if (!this.hass || !this.stateObj) { return; @@ -246,69 +60,7 @@ export class HaBlueprintAutomationEditor extends LitElement { entity_id: this.stateObj.entity_id, }); } - - private _duplicate() { - fireEvent(this, "duplicate"); - } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - :host { - display: block; - } - ha-card.blueprint { - margin: 0 auto; - } - .padding { - padding: 16px; - } - .link-button-row { - padding: 14px; - } - .blueprint-picker-container { - padding: 0 16px 16px; - } - ha-textfield, - ha-blueprint-picker { - display: block; - } - h3 { - margin: 16px; - } - .introduction { - margin-top: 0; - margin-bottom: 12px; - } - .introduction a { - color: var(--primary-color); - } - p { - margin-bottom: 0; - } - .description { - margin-bottom: 16px; - } - ha-settings-row { - --paper-time-input-justify-content: flex-end; - --settings-row-content-width: 100%; - --settings-row-prefix-display: contents; - border-top: 1px solid var(--divider-color); - } - ha-alert { - margin-bottom: 16px; - display: block; - } - ha-alert.re-order { - border-radius: var(--ha-card-border-radius, 12px); - overflow: hidden; - } - `, - ]; - } } - declare global { interface HTMLElementTagNameMap { "blueprint-automation-editor": HaBlueprintAutomationEditor; diff --git a/src/panels/config/blueprint/blueprint-generic-editor.ts b/src/panels/config/blueprint/blueprint-generic-editor.ts new file mode 100644 index 0000000000..188ef35e25 --- /dev/null +++ b/src/panels/config/blueprint/blueprint-generic-editor.ts @@ -0,0 +1,275 @@ +import "@material/mwc-button/mwc-button"; +import { css, CSSResultGroup, html, LitElement } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { nestedArrayMove } from "../../../common/util/array-move"; +import "../../../components/ha-alert"; +import "../../../components/ha-blueprint-picker"; +import "../../../components/ha-card"; +import "../../../components/ha-circular-progress"; +import "../../../components/ha-markdown"; +import "../../../components/ha-selector/ha-selector"; +import "../../../components/ha-settings-row"; +import { BlueprintAutomationConfig } from "../../../data/automation"; +import { BlueprintOrError, Blueprints } from "../../../data/blueprint"; +import { BlueprintScriptConfig } from "../../../data/script"; +import { haStyle } from "../../../resources/styles"; +import { HomeAssistant } from "../../../types"; + +@customElement("blueprint-generic-editor") +export abstract class HaBlueprintGenericEditor extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public isWide = false; + + @property({ type: Boolean }) public disabled = false; + + @property({ type: Boolean, reflect: true }) public narrow = false; + + @state() protected _blueprints?: Blueprints; + + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this._getBlueprints(); + } + + protected get _blueprint(): BlueprintOrError | undefined { + if (!this._blueprints) { + return undefined; + } + return this._blueprints[this._config.use_blueprint.path]; + } + + protected abstract get _config(): + | BlueprintAutomationConfig + | BlueprintScriptConfig; + + protected renderCard() { + const blueprint = this._blueprint; + return html` + +
+ ${this._blueprints + ? Object.keys(this._blueprints).length + ? html` + + ` + : this.hass.localize( + "ui.panel.config.automation.editor.blueprint.no_blueprints" + ) + : html``} +
+ + ${this._config.use_blueprint.path + ? blueprint && "error" in blueprint + ? html`

+ There is an error in this Blueprint: ${blueprint.error} +

` + : html`${blueprint?.metadata.description + ? html`` + : ""} + ${blueprint?.metadata?.input && + Object.keys(blueprint.metadata.input).length + ? Object.entries(blueprint.metadata.input).map( + ([key, value]) => { + const selector = value?.selector ?? { text: undefined }; + const type = Object.keys(selector)[0]; + const enhancedSelector = [ + "action", + "condition", + "trigger", + ].includes(type) + ? { + [type]: { + ...selector[type], + path: [key], + }, + } + : selector; + + return html` + ${value?.name || key} + + ${html``} + `; + } + ) + : html`

+ ${this.hass.localize( + "ui.panel.config.automation.editor.blueprint.no_inputs" + )} +

`}` + : ""} +
+ `; + } + + protected abstract _getBlueprints(); + + private _blueprintChanged(ev) { + ev.stopPropagation(); + if (this._config.use_blueprint.path === ev.detail.value) { + return; + } + fireEvent(this, "value-changed", { + value: { + ...this._config, + use_blueprint: { + path: ev.detail.value, + }, + }, + }); + } + + private _inputChanged(ev) { + ev.stopPropagation(); + const target = ev.target as any; + const key = target.key; + const value = ev.detail ? ev.detail.value : target.value; + if ( + (this._config.use_blueprint.input && + this._config.use_blueprint.input[key] === value) || + (!this._config.use_blueprint.input && value === "") + ) { + return; + } + const input = { ...this._config.use_blueprint.input, [key]: value }; + + fireEvent(this, "value-changed", { + value: { + ...this._config, + use_blueprint: { + ...this._config.use_blueprint, + input, + }, + }, + }); + } + + private _itemMoved(ev) { + ev.stopPropagation(); + const { oldIndex, newIndex, oldPath, newPath } = ev.detail; + + const input = nestedArrayMove( + this._config.use_blueprint.input, + oldIndex, + newIndex, + oldPath, + newPath + ); + + fireEvent(this, "value-changed", { + value: { + ...this._config, + use_blueprint: { + ...this._config.use_blueprint, + input, + }, + }, + }); + } + + protected _duplicate() { + fireEvent(this, "duplicate"); + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + :host { + display: block; + } + ha-card.blueprint { + margin: 0 auto; + } + .padding { + padding: 16px; + } + .link-button-row { + padding: 14px; + } + .blueprint-picker-container { + padding: 0 16px 16px; + } + ha-textfield, + ha-blueprint-picker { + display: block; + } + h3 { + margin: 16px; + } + .introduction { + margin-top: 0; + margin-bottom: 12px; + } + .introduction a { + color: var(--primary-color); + } + p { + margin-bottom: 0; + } + .description { + margin-bottom: 16px; + } + ha-settings-row { + --paper-time-input-justify-content: flex-end; + --settings-row-content-width: 100%; + --settings-row-prefix-display: contents; + border-top: 1px solid var(--divider-color); + } + ha-alert { + margin-bottom: 16px; + display: block; + } + ha-alert.re-order { + border-radius: var(--ha-card-border-radius, 12px); + overflow: hidden; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "blueprint-generic-editor": HaBlueprintGenericEditor; + } +} diff --git a/src/panels/config/script/blueprint-script-editor.ts b/src/panels/config/script/blueprint-script-editor.ts index be455965f4..c233eae662 100644 --- a/src/panels/config/script/blueprint-script-editor.ts +++ b/src/panels/config/script/blueprint-script-editor.ts @@ -1,52 +1,19 @@ -import { css, CSSResultGroup, html, LitElement } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { nestedArrayMove } from "../../../common/util/array-move"; +import { html } from "lit"; +import { customElement, property } from "lit/decorators"; import "../../../components/ha-alert"; -import "../../../components/ha-blueprint-picker"; -import "../../../components/ha-card"; -import "../../../components/ha-circular-progress"; -import "../../../components/ha-markdown"; -import "../../../components/ha-selector/ha-selector"; -import "../../../components/ha-settings-row"; -import { - BlueprintOrError, - Blueprints, - fetchBlueprints, -} from "../../../data/blueprint"; import { BlueprintScriptConfig } from "../../../data/script"; -import { haStyle } from "../../../resources/styles"; -import { HomeAssistant } from "../../../types"; -import "../ha-config-section"; +import { fetchBlueprints } from "../../../data/blueprint"; +import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor"; @customElement("blueprint-script-editor") -export class HaBlueprintScriptEditor extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property({ type: Boolean }) public isWide = false; - - @property({ reflect: true, type: Boolean }) public narrow = false; - - @property({ type: Boolean }) public disabled = false; - +export class HaBlueprintScriptEditor extends HaBlueprintGenericEditor { @property({ attribute: false }) public config!: BlueprintScriptConfig; - @state() private _blueprints?: Blueprints; - - protected firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this._getBlueprints(); - } - - private get _blueprint(): BlueprintOrError | undefined { - if (!this._blueprints) { - return undefined; - } - return this._blueprints[this.config.use_blueprint.path]; + protected get _config(): BlueprintScriptConfig { + return this.config; } protected render() { - const blueprint = this._blueprint; return html` ${this.disabled ? html` @@ -56,228 +23,14 @@ export class HaBlueprintScriptEditor extends LitElement { ` : ""} - -
- ${this._blueprints - ? Object.keys(this._blueprints).length - ? html` - - ` - : this.hass.localize( - "ui.panel.config.automation.editor.blueprint.no_blueprints" - ) - : html``} -
- ${this.config.use_blueprint.path - ? blueprint && "error" in blueprint - ? html`

- There is an error in this Blueprint: ${blueprint.error} -

` - : html`${blueprint?.metadata.description - ? html`` - : ""} - ${blueprint?.metadata?.input && - Object.keys(blueprint.metadata.input).length - ? Object.entries(blueprint.metadata.input).map( - ([key, value]) => { - const selector = value?.selector ?? { text: undefined }; - const type = Object.keys(selector)[0]; - const enhancedSelector = [ - "action", - "condition", - "trigger", - ].includes(type) - ? { - [type]: { - ...selector[type], - path: [key], - }, - } - : selector; - - return html` - ${value?.name || key} - - ${html``} - `; - } - ) - : html`

- ${this.hass.localize( - "ui.panel.config.automation.editor.blueprint.no_inputs" - )} -

`}` - : ""} -
+ ${this.renderCard()} `; } - private async _getBlueprints() { + protected async _getBlueprints() { this._blueprints = await fetchBlueprints(this.hass, "script"); } - - private _blueprintChanged(ev) { - ev.stopPropagation(); - if (this.config.use_blueprint.path === ev.detail.value) { - return; - } - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - path: ev.detail.value, - }, - }, - }); - } - - private _inputChanged(ev) { - ev.stopPropagation(); - const target = ev.target as any; - const key = target.key; - const value = ev.detail ? ev.detail.value : target.value; - if ( - (this.config.use_blueprint.input && - this.config.use_blueprint.input[key] === value) || - (!this.config.use_blueprint.input && value === "") - ) { - return; - } - const input = { ...this.config.use_blueprint.input, [key]: value }; - - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - ...this.config.use_blueprint, - input, - }, - }, - }); - } - - private _itemMoved(ev) { - ev.stopPropagation(); - const { oldIndex, newIndex, oldPath, newPath } = ev.detail; - - const input = nestedArrayMove( - this.config.use_blueprint.input, - oldIndex, - newIndex, - oldPath, - newPath - ); - - fireEvent(this, "value-changed", { - value: { - ...this.config, - use_blueprint: { - ...this.config.use_blueprint, - input, - }, - }, - }); - } - - private _duplicate() { - fireEvent(this, "duplicate"); - } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - :host { - display: block; - } - ha-card.blueprint { - margin: 0 auto; - } - .padding { - padding: 16px; - } - .link-button-row { - padding: 14px; - } - .blueprint-picker-container { - padding: 0 16px 16px; - } - ha-textfield, - ha-blueprint-picker { - display: block; - } - h3 { - margin: 16px; - } - .introduction { - margin-top: 0; - margin-bottom: 12px; - } - .introduction a { - color: var(--primary-color); - } - p { - margin-bottom: 0; - } - .description { - margin-bottom: 16px; - } - ha-settings-row { - --paper-time-input-justify-content: flex-end; - --settings-row-content-width: 100%; - --settings-row-prefix-display: contents; - border-top: 1px solid var(--divider-color); - } - ha-alert { - margin-bottom: 16px; - display: block; - } - ha-alert.re-order { - border-radius: var(--ha-card-border-radius, 12px); - overflow: hidden; - } - `, - ]; - } } - declare global { interface HTMLElementTagNameMap { "blueprint-script-editor": HaBlueprintScriptEditor;