mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Add category and labels to automation/script save and rename dialog (#23240)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
523c38a83e
commit
5cd6f22e99
@ -3,7 +3,7 @@
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
// leading edge, instead of the trailing.
|
||||
// leading edge and on the trailing.
|
||||
|
||||
export const debounce = <T extends any[]>(
|
||||
func: (...args: T) => void,
|
||||
@ -14,9 +14,7 @@ export const debounce = <T extends any[]>(
|
||||
const debouncedFunc = (...args: T): void => {
|
||||
const later = () => {
|
||||
timeout = undefined;
|
||||
if (!immediate) {
|
||||
func(...args);
|
||||
}
|
||||
func(...args);
|
||||
};
|
||||
const callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
|
@ -19,6 +19,9 @@ export class HaFab extends FabBase {
|
||||
margin-inline-end: 12px;
|
||||
direction: var(--direction);
|
||||
}
|
||||
:disabled {
|
||||
opacity: var(--light-disabled-opacity);
|
||||
}
|
||||
`,
|
||||
// safari workaround - must be explicit
|
||||
mainWindow.document.dir === "rtl"
|
||||
|
@ -30,7 +30,7 @@ export const PreventUnsavedMixin = <T extends Constructor<LitElement>>(
|
||||
window.removeEventListener("beforeunload", this._handleUnload);
|
||||
}
|
||||
|
||||
public willUpdate(changedProperties: PropertyValues): void {
|
||||
protected willUpdate(changedProperties: PropertyValues): void {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
if (this.isDirty) {
|
||||
|
@ -2,19 +2,25 @@ import "@material/mwc-button";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { mdiClose, mdiPlus } from "@mdi/js";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import { createCloseHeading } from "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-domain-icon";
|
||||
import "../../../../components/ha-icon-picker";
|
||||
import "../../../../components/ha-textarea";
|
||||
import "../../../../components/ha-textfield";
|
||||
import "../../../../components/ha-labels-picker";
|
||||
import "../../category/ha-category-picker";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/chips/ha-chip-set";
|
||||
import "../../../../components/chips/ha-assist-chip";
|
||||
|
||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type {
|
||||
AutomationRenameDialogParams,
|
||||
EntityRegistryUpdate,
|
||||
ScriptRenameDialogParams,
|
||||
} from "./show-dialog-automation-rename";
|
||||
|
||||
@ -26,6 +32,10 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
@state() private _visibleOptionals: string[] = [];
|
||||
|
||||
@state() private _entryUpdates!: EntityRegistryUpdate;
|
||||
|
||||
private _params!: AutomationRenameDialogParams | ScriptRenameDialogParams;
|
||||
|
||||
private _newName?: string;
|
||||
@ -46,6 +56,17 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
`ui.panel.config.${this._params.domain}.editor.default_name`
|
||||
);
|
||||
this._newDescription = params.config.description || "";
|
||||
this._entryUpdates = params.entityRegistryUpdate || {
|
||||
labels: params.entityRegistryEntry?.labels || [],
|
||||
category: params.entityRegistryEntry?.categories[params.domain] || "",
|
||||
};
|
||||
|
||||
this._visibleOptionals = [
|
||||
this._newDescription ? "description" : "",
|
||||
this._newIcon ? "icon" : "",
|
||||
this._entryUpdates.category ? "category" : "",
|
||||
this._entryUpdates.labels.length > 0 ? "labels" : "",
|
||||
];
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
@ -55,6 +76,19 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
this._opened = false;
|
||||
this._visibleOptionals = [];
|
||||
}
|
||||
|
||||
protected _renderOptionalChip(id: string, label: string) {
|
||||
if (this._visibleOptionals.includes(id)) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-assist-chip id=${id} @click=${this._addOptional} label=${label}>
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
@ -66,15 +100,27 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
open
|
||||
scrimClickAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this.hass.localize(
|
||||
this._params.config.alias
|
||||
? "ui.panel.config.automation.editor.rename"
|
||||
: "ui.panel.config.automation.editor.save"
|
||||
)
|
||||
.heading=${this.hass.localize(
|
||||
this._params.config.alias
|
||||
? "ui.panel.config.automation.editor.rename"
|
||||
: "ui.panel.config.automation.editor.save"
|
||||
)}
|
||||
>
|
||||
<ha-dialog-header slot="heading">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
dialogAction="cancel"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title"
|
||||
>${this.hass.localize(
|
||||
this._params.config.alias
|
||||
? "ui.panel.config.automation.editor.rename"
|
||||
: "ui.panel.config.automation.editor.save"
|
||||
)}</span
|
||||
>
|
||||
</ha-dialog-header>
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error"
|
||||
>${this.hass.localize(
|
||||
@ -96,7 +142,8 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
@input=${this._valueChanged}
|
||||
></ha-textfield>
|
||||
|
||||
${this._params.domain === "script"
|
||||
${this._params.domain === "script" &&
|
||||
this._visibleOptionals.includes("icon")
|
||||
? html`
|
||||
<ha-icon-picker
|
||||
.hass=${this.hass}
|
||||
@ -115,33 +162,97 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
</ha-icon-picker>
|
||||
`
|
||||
: nothing}
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
autogrow
|
||||
.value=${this._newDescription}
|
||||
@input=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
${this._visibleOptionals.includes("description")
|
||||
? html` <ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
autogrow
|
||||
.value=${this._newDescription}
|
||||
@input=${this._valueChanged}
|
||||
></ha-textarea>`
|
||||
: nothing}
|
||||
${this._visibleOptionals.includes("category")
|
||||
? html` <ha-category-picker
|
||||
id="category"
|
||||
.hass=${this.hass}
|
||||
.scope=${this._params.domain}
|
||||
.value=${this._entryUpdates.category}
|
||||
@value-changed=${this._registryEntryChanged}
|
||||
></ha-category-picker>`
|
||||
: nothing}
|
||||
${this._visibleOptionals.includes("labels")
|
||||
? html` <ha-labels-picker
|
||||
id="labels"
|
||||
.hass=${this.hass}
|
||||
.value=${this._entryUpdates.labels}
|
||||
@value-changed=${this._registryEntryChanged}
|
||||
></ha-labels-picker>`
|
||||
: nothing}
|
||||
|
||||
<mwc-button @click=${this.closeDialog} slot="secondaryAction">
|
||||
${this.hass.localize("ui.dialogs.generic.cancel")}
|
||||
</mwc-button>
|
||||
<mwc-button @click=${this._save} slot="primaryAction">
|
||||
${this.hass.localize(
|
||||
this._params.config.alias
|
||||
? "ui.panel.config.automation.editor.rename"
|
||||
: "ui.panel.config.automation.editor.save"
|
||||
<ha-chip-set>
|
||||
${this._renderOptionalChip(
|
||||
"description",
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.dialog.add_description"
|
||||
)
|
||||
)}
|
||||
</mwc-button>
|
||||
${this._params.domain === "script"
|
||||
? this._renderOptionalChip(
|
||||
"icon",
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.dialog.add_icon"
|
||||
)
|
||||
)
|
||||
: nothing}
|
||||
${this._renderOptionalChip(
|
||||
"category",
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.dialog.add_category"
|
||||
)
|
||||
)}
|
||||
${this._renderOptionalChip(
|
||||
"labels",
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.dialog.add_labels"
|
||||
)
|
||||
)}
|
||||
</ha-chip-set>
|
||||
|
||||
<div slot="primaryAction">
|
||||
<mwc-button @click=${this.closeDialog}>
|
||||
${this.hass.localize("ui.dialogs.generic.cancel")}
|
||||
</mwc-button>
|
||||
<mwc-button @click=${this._save}>
|
||||
${this.hass.localize(
|
||||
this._params.config.alias
|
||||
? "ui.panel.config.automation.editor.rename"
|
||||
: "ui.panel.config.automation.editor.save"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _addOptional(ev) {
|
||||
ev.stopPropagation();
|
||||
const option: string = ev.target.id;
|
||||
this._visibleOptionals = [...this._visibleOptionals, option];
|
||||
}
|
||||
|
||||
private _registryEntryChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
const id: string = ev.target.id;
|
||||
const value = ev.detail.value;
|
||||
|
||||
this._entryUpdates = { ...this._entryUpdates, [id]: value };
|
||||
}
|
||||
|
||||
private _iconChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this._newIcon = ev.detail.value || undefined;
|
||||
@ -162,19 +273,26 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
this._error = "Name is required";
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._params.domain === "script") {
|
||||
this._params.updateConfig({
|
||||
...this._params.config,
|
||||
alias: this._newName,
|
||||
description: this._newDescription,
|
||||
icon: this._newIcon,
|
||||
});
|
||||
this._params.updateConfig(
|
||||
{
|
||||
...this._params.config,
|
||||
alias: this._newName,
|
||||
description: this._newDescription,
|
||||
icon: this._newIcon,
|
||||
},
|
||||
this._entryUpdates
|
||||
);
|
||||
} else {
|
||||
this._params.updateConfig({
|
||||
...this._params.config,
|
||||
alias: this._newName,
|
||||
description: this._newDescription,
|
||||
});
|
||||
this._params.updateConfig(
|
||||
{
|
||||
...this._params.config,
|
||||
alias: this._newName,
|
||||
description: this._newDescription,
|
||||
},
|
||||
this._entryUpdates
|
||||
);
|
||||
}
|
||||
|
||||
this.closeDialog();
|
||||
@ -185,12 +303,21 @@ class DialogAutomationRename extends LitElement implements HassDialog {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-dialog {
|
||||
--dialog-content-padding: 0 24px 24px 24px;
|
||||
}
|
||||
ha-textfield,
|
||||
ha-textarea,
|
||||
ha-icon-picker {
|
||||
ha-icon-picker,
|
||||
ha-category-picker,
|
||||
ha-labels-picker,
|
||||
ha-chip-set {
|
||||
display: block;
|
||||
}
|
||||
ha-icon-picker {
|
||||
ha-icon-picker,
|
||||
ha-category-picker,
|
||||
ha-labels-picker,
|
||||
ha-chip-set {
|
||||
margin-top: 16px;
|
||||
}
|
||||
ha-alert {
|
||||
|
@ -1,22 +1,38 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { AutomationConfig } from "../../../../data/automation";
|
||||
import type { ScriptConfig } from "../../../../data/script";
|
||||
import type { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||
|
||||
export const loadAutomationRenameDialog = () =>
|
||||
import("./dialog-automation-rename");
|
||||
|
||||
export interface AutomationRenameDialogParams {
|
||||
config: AutomationConfig;
|
||||
domain: "automation";
|
||||
updateConfig: (config: AutomationConfig) => void;
|
||||
interface BaseRenameDialogParams {
|
||||
entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
entityRegistryEntry?: EntityRegistryEntry;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export interface ScriptRenameDialogParams {
|
||||
export interface EntityRegistryUpdate {
|
||||
labels: string[];
|
||||
category: string;
|
||||
}
|
||||
|
||||
export interface AutomationRenameDialogParams extends BaseRenameDialogParams {
|
||||
config: AutomationConfig;
|
||||
domain: "automation";
|
||||
updateConfig: (
|
||||
config: AutomationConfig,
|
||||
entityRegistryUpdate: EntityRegistryUpdate
|
||||
) => void;
|
||||
}
|
||||
|
||||
export interface ScriptRenameDialogParams extends BaseRenameDialogParams {
|
||||
config: ScriptConfig;
|
||||
domain: "script";
|
||||
updateConfig: (config: ScriptConfig) => void;
|
||||
onClose: () => void;
|
||||
updateConfig: (
|
||||
config: ScriptConfig,
|
||||
entityRegistryUpdate: EntityRegistryUpdate
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const showAutomationRenameDialog = (
|
||||
|
@ -53,8 +53,8 @@ import { substituteBlueprint } from "../../../data/blueprint";
|
||||
import { validateConfig } from "../../../data/config";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import {
|
||||
fetchEntityRegistry,
|
||||
type EntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import {
|
||||
showAlertDialog,
|
||||
@ -67,7 +67,10 @@ import type { Entries, HomeAssistant, Route } from "../../../types";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import "../ha-config-section";
|
||||
import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-automation-mode";
|
||||
import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename";
|
||||
import {
|
||||
type EntityRegistryUpdate,
|
||||
showAutomationRenameDialog,
|
||||
} from "./automation-rename-dialog/show-dialog-automation-rename";
|
||||
import "./blueprint-automation-editor";
|
||||
import "./manual-automation-editor";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
@ -137,6 +140,12 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
})
|
||||
private _registryEntry?: EntityRegistryEntry;
|
||||
|
||||
@state() private _saving = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
_entityRegistry!: EntityRegistryEntry[];
|
||||
|
||||
private _configSubscriptions: Record<
|
||||
string,
|
||||
(config?: AutomationConfig) => void
|
||||
@ -144,6 +153,33 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
private _configSubscriptionsId = 1;
|
||||
|
||||
private _entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
|
||||
private _newAutomationId?: string;
|
||||
|
||||
private _entityRegCreated?: (
|
||||
value: PromiseLike<EntityRegistryEntry> | EntityRegistryEntry
|
||||
) => void;
|
||||
|
||||
protected willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (
|
||||
this._entityRegCreated &&
|
||||
this._newAutomationId &&
|
||||
changedProps.has("entityRegistry")
|
||||
) {
|
||||
const automation = this._entityRegistry.find(
|
||||
(entity: EntityRegistryEntry) =>
|
||||
entity.unique_id === this._newAutomationId
|
||||
);
|
||||
if (automation) {
|
||||
this._entityRegCreated(automation);
|
||||
this._entityRegCreated = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | typeof nothing {
|
||||
if (!this._config) {
|
||||
return nothing;
|
||||
@ -456,8 +492,11 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
</div>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
class=${classMap({ dirty: !this._readOnly && this._dirty })}
|
||||
class=${classMap({
|
||||
dirty: !this._readOnly && this._dirty,
|
||||
})}
|
||||
.label=${this.hass.localize("ui.panel.config.automation.editor.save")}
|
||||
.disabled=${this._saving}
|
||||
extended
|
||||
@click=${this._saveAutomation}
|
||||
>
|
||||
@ -577,8 +616,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
this._config = normalizeAutomationConfig(config);
|
||||
this._checkValidation();
|
||||
} catch (err: any) {
|
||||
const entityRegistry = await fetchEntityRegistry(this.hass.connection);
|
||||
const entity = entityRegistry.find(
|
||||
const entity = this._entityRegistry.find(
|
||||
(ent) =>
|
||||
ent.platform === "automation" && ent.unique_id === this.automationId
|
||||
);
|
||||
@ -841,13 +879,16 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
showAutomationRenameDialog(this, {
|
||||
config: this._config!,
|
||||
domain: "automation",
|
||||
updateConfig: (config) => {
|
||||
updateConfig: (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryEntry: this._registryEntry,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -883,21 +924,49 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
}
|
||||
|
||||
this._saving = true;
|
||||
this._validationErrors = undefined;
|
||||
|
||||
try {
|
||||
await saveAutomationConfig(this.hass, id, this._config!);
|
||||
|
||||
if (this._entityRegistryUpdate !== undefined) {
|
||||
let entityId = this._entityId;
|
||||
|
||||
// wait for automation to appear in entity registry when creating a new automation
|
||||
if (!entityId) {
|
||||
this._newAutomationId = id;
|
||||
const automation = await new Promise<EntityRegistryEntry>(
|
||||
(resolve) => {
|
||||
this._entityRegCreated = resolve;
|
||||
}
|
||||
);
|
||||
entityId = automation.entity_id;
|
||||
}
|
||||
|
||||
if (entityId) {
|
||||
await updateEntityRegistryEntry(this.hass, entityId, {
|
||||
categories: {
|
||||
automation: this._entityRegistryUpdate.category || null,
|
||||
},
|
||||
labels: this._entityRegistryUpdate.labels || [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
|
||||
if (!this.automationId) {
|
||||
navigate(`/config/automation/edit/${id}`, { replace: true });
|
||||
}
|
||||
} catch (errors: any) {
|
||||
this._errors = errors.body.message || errors.error || errors.body;
|
||||
showToast(this, {
|
||||
message: errors.body.message || errors.error || errors.body,
|
||||
});
|
||||
throw errors;
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
|
||||
if (!this.automationId) {
|
||||
navigate(`/config/automation/edit/${id}`, { replace: true });
|
||||
} finally {
|
||||
this._saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,10 @@ import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import { validateConfig } from "../../../data/config";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import {
|
||||
type EntityRegistryEntry,
|
||||
updateEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import type { BlueprintScriptConfig, ScriptConfig } from "../../../data/script";
|
||||
import {
|
||||
deleteScript,
|
||||
@ -58,6 +61,7 @@ import { haStyle } from "../../../resources/styles";
|
||||
import type { Entries, HomeAssistant, Route } from "../../../types";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAutomationModeDialog } from "../automation/automation-mode-dialog/show-dialog-automation-mode";
|
||||
import type { EntityRegistryUpdate } from "../automation/automation-rename-dialog/show-dialog-automation-rename";
|
||||
import { showAutomationRenameDialog } from "../automation/automation-rename-dialog/show-dialog-automation-rename";
|
||||
import "./blueprint-script-editor";
|
||||
import "./manual-script-editor";
|
||||
@ -116,6 +120,34 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
@state() private _blueprintConfig?: BlueprintScriptConfig;
|
||||
|
||||
@state() private _saving = false;
|
||||
|
||||
private _entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
|
||||
private _newScriptId?: string;
|
||||
|
||||
private _entityRegCreated?: (
|
||||
value: PromiseLike<EntityRegistryEntry> | EntityRegistryEntry
|
||||
) => void;
|
||||
|
||||
protected willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (
|
||||
this._entityRegCreated &&
|
||||
this._newScriptId &&
|
||||
changedProps.has("entityRegistry")
|
||||
) {
|
||||
const script = this.entityRegistry.find(
|
||||
(entity: EntityRegistryEntry) => entity.unique_id === this._newScriptId
|
||||
);
|
||||
if (script) {
|
||||
this._entityRegCreated(script);
|
||||
this._entityRegCreated = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | typeof nothing {
|
||||
if (!this._config) {
|
||||
return nothing;
|
||||
@ -410,11 +442,12 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
class=${classMap({
|
||||
dirty: this._dirty,
|
||||
dirty: !this._readOnly && this._dirty,
|
||||
})}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.script.editor.save_script"
|
||||
)}
|
||||
.disabled=${this._saving}
|
||||
extended
|
||||
@click=${this._saveScript}
|
||||
>
|
||||
@ -812,13 +845,18 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
showAutomationRenameDialog(this, {
|
||||
config: this._config!,
|
||||
domain: "script",
|
||||
updateConfig: (config) => {
|
||||
updateConfig: (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryEntry: this.entityRegistry.find(
|
||||
(entry) => entry.unique_id === this.scriptId
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -855,24 +893,48 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
const id = this.scriptId || this._entityId || Date.now();
|
||||
|
||||
this._saving = true;
|
||||
try {
|
||||
await this.hass!.callApi(
|
||||
"POST",
|
||||
"config/script/config/" + id,
|
||||
this._config
|
||||
);
|
||||
|
||||
if (this._entityRegistryUpdate !== undefined) {
|
||||
let entityId = id.toString().startsWith("script.")
|
||||
? id.toString()
|
||||
: `script.${id}`;
|
||||
|
||||
// wait for new script to appear in entity registry
|
||||
if (!this.scriptId) {
|
||||
const script = await new Promise<EntityRegistryEntry>((resolve) => {
|
||||
this._entityRegCreated = resolve;
|
||||
});
|
||||
entityId = script.entity_id;
|
||||
}
|
||||
|
||||
await updateEntityRegistryEntry(this.hass, entityId, {
|
||||
categories: {
|
||||
script: this._entityRegistryUpdate.category || null,
|
||||
},
|
||||
labels: this._entityRegistryUpdate.labels || [],
|
||||
});
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
|
||||
if (!this.scriptId) {
|
||||
navigate(`/config/script/edit/${id}`, { replace: true });
|
||||
}
|
||||
} catch (errors: any) {
|
||||
this._errors = errors.body.message || errors.error || errors.body;
|
||||
showToast(this, {
|
||||
message: errors.body.message || errors.error || errors.body,
|
||||
});
|
||||
throw errors;
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
|
||||
if (!this.scriptId) {
|
||||
navigate(`/config/script/edit/${id}`, { replace: true });
|
||||
} finally {
|
||||
this._saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3708,6 +3708,12 @@
|
||||
"label": "Unknown"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"add_description": "Add description",
|
||||
"add_icon": "Add icon",
|
||||
"add_category": "Add category",
|
||||
"add_labels": "Add labels"
|
||||
}
|
||||
},
|
||||
"trace": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user