import { mdiPlay, mdiStop } from "@mdi/js"; import type { HassEntity } from "home-assistant-js-websocket"; import type { PropertyValues } from "lit"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { listenMediaQuery } from "../../../common/dom/media_query"; import { computeObjectId } from "../../../common/entity/compute_object_id"; import "../../../components/entity/state-info"; import "../../../components/ha-control-button"; import "../../../components/ha-control-button-group"; import "../../../components/ha-markdown"; import "../../../components/ha-relative-time"; import "../../../components/ha-service-control"; import { isUnavailableState } from "../../../data/entity/entity"; import type { ExtEntityRegistryEntry } from "../../../data/entity/entity_registry"; import type { ScriptEntity } from "../../../data/script"; import { canRun, hasRequiredScriptFields, requiredScriptFieldsFilled, } from "../../../data/script"; import type { HomeAssistant } from "../../../types"; import "../components/ha-more-info-state-header"; @customElement("more-info-script") class MoreInfoScript extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public stateObj?: ScriptEntity; @property({ attribute: false }) public entry?: ExtEntityRegistryEntry; @property({ attribute: false }) public data?: Record; @state() private _scriptData: Record = {}; @state() private narrow = false; private _unsubMediaQuery?: () => void; public connectedCallback(): void { super.connectedCallback(); this._unsubMediaQuery = listenMediaQuery( "(max-width: 870px)", (matches) => { this.narrow = matches; } ); } public disconnectedCallback(): void { super.disconnectedCallback(); if (this._unsubMediaQuery) { this._unsubMediaQuery(); this._unsubMediaQuery = undefined; } } protected render() { if (!this.hass || !this.stateObj) { return nothing; } const stateObj = this.stateObj; const script = this.hass.services.script[ this.entry?.unique_id || computeObjectId(this.stateObj.entity_id) ]; const fields = script?.fields; const hasFields = fields && Object.keys(fields).length > 0; const current = stateObj.attributes.current || 0; const isQueued = stateObj.attributes.mode === "queued"; const isParallel = stateObj.attributes.mode === "parallel"; const hasQueue = isQueued && current > 1; return html` 0 ? isParallel && current > 1 ? this.hass.localize("ui.card.script.running_parallel", { active: current, }) : this.hass.localize("ui.card.script.running_single") : this.hass.localize("ui.card.script.idle")} .changedOverride=${this.stateObj.attributes.last_triggered || 0} > ${script?.description ? html`` : nothing}
${hasQueue ? html` ${this.hass.localize("ui.card.script.running_queued", { queued: current - 1, })} ` : ""}
${hasFields ? html`
${this.hass.localize("ui.card.script.run_script")}
` : nothing} ${(isQueued || isParallel) && current > 1 ? this.hass.localize("ui.card.script.cancel_all") : this.hass.localize("ui.card.script.cancel")} ${this.hass!.localize("ui.card.script.run")} `; } protected override willUpdate(changedProperties: PropertyValues): void { super.willUpdate(changedProperties); if (changedProperties.has("stateObj")) { const oldState = changedProperties.get("stateObj") as | HassEntity | undefined; const newState = this.stateObj; if ( newState && (!oldState || oldState.entity_id !== newState.entity_id) ) { this._scriptData = { action: this.entry?.entity_id === newState.entity_id ? `script.${this.entry.unique_id}` : newState.entity_id, }; } } if (this.entry?.unique_id && changedProperties.has("entry")) { const action = `script.${this.entry?.unique_id}`; if (this._scriptData?.action !== action) { this._scriptData = { ...this._scriptData, action }; } } } private _cancelScript(ev: Event) { ev.stopPropagation(); this._callService("turn_off"); } private async _runScript(ev: Event) { ev.stopPropagation(); this.hass.callService( "script", this.entry?.unique_id || computeObjectId(this.stateObj!.entity_id), this._scriptData.data ); } private _callService(service: string): void { this.hass.callService("script", service, { entity_id: this.stateObj!.entity_id, }); } private _scriptDataChanged(ev: CustomEvent): void { this._scriptData = { ...this._scriptData, ...ev.detail.value }; } private _canRun() { if ( !hasRequiredScriptFields(this.hass, this.stateObj!.entity_id) || (requiredScriptFieldsFilled( this.hass, this.stateObj!.entity_id, this._scriptData.data ) && canRun(this.stateObj!)) || // Restart can also always runs. Just cancels other run. this.stateObj!.attributes.mode === "restart" ) { return true; } return false; } static styles = css` .queue { visibility: hidden; color: var(--secondary-text-color); text-align: center; margin-bottom: var(--ha-space-4); height: 21px; } .queue.has-queue { visibility: visible; } .fields { padding: var(--ha-space-4); border: 1px solid var(--divider-color); border-radius: var(--ha-border-radius-md); margin-bottom: var(--ha-space-4); } .fields .title { font-weight: var(--ha-font-weight-bold); } ha-control-button ha-svg-icon { z-index: -1; margin-right: var(--ha-space-1); } ha-service-control { --service-control-padding: 0; --service-control-items-border-top: none; } ha-markdown { text-align: center; padding: 0 var(--ha-space-4); } `; } declare global { interface HTMLElementTagNameMap { "more-info-script": MoreInfoScript; } }