mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Allow to set an id and icon when creating new script (#6373)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
e70a3e09bf
commit
d1dd8231cd
@ -1,19 +1,19 @@
|
|||||||
// https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
|
// https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
|
||||||
export const slugify = (value: string) => {
|
export const slugify = (value: string, delimiter = "-") => {
|
||||||
const a =
|
const a =
|
||||||
"àáäâãåăæąçćčđďèéěėëêęğǵḧìíïîįłḿǹńňñòóöôœøṕŕřßşśšșťțùúüûǘůűūųẃẍÿýźžż·/_,:;";
|
"àáäâãåăæąçćčđďèéěėëêęğǵḧìíïîįłḿǹńňñòóöôœøṕŕřßşśšșťțùúüûǘůűūųẃẍÿýźžż·/_,:;";
|
||||||
const b =
|
const b = `aaaaaaaaacccddeeeeeeegghiiiiilmnnnnooooooprrsssssttuuuuuuuuuwxyyzzz${delimiter}${delimiter}${delimiter}${delimiter}${delimiter}${delimiter}`;
|
||||||
"aaaaaaaaacccddeeeeeeegghiiiiilmnnnnooooooprrsssssttuuuuuuuuuwxyyzzz------";
|
|
||||||
const p = new RegExp(a.split("").join("|"), "g");
|
const p = new RegExp(a.split("").join("|"), "g");
|
||||||
|
|
||||||
return value
|
return value
|
||||||
.toString()
|
.toString()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(/\s+/g, "-") // Replace spaces with -
|
.replace(/\s+/g, delimiter) // Replace spaces with delimiter
|
||||||
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
|
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
|
||||||
.replace(/&/g, "-and-") // Replace & with 'and'
|
.replace(/&/g, `${delimiter}and${delimiter}`) // Replace & with 'and'
|
||||||
.replace(/[^\w-]+/g, "") // Remove all non-word characters
|
.replace(/[^\w-]+/g, "") // Remove all non-word characters
|
||||||
.replace(/--+/g, "-") // Replace multiple - with single -
|
.replace(/-/, delimiter) // Replace - with delimiter
|
||||||
.replace(/^-+/, "") // Trim - from start of text
|
.replace(new RegExp(`/${delimiter}${delimiter}+/`, "g"), delimiter) // Replace multiple delimiters with single delimiter
|
||||||
.replace(/-+$/, ""); // Trim - from end of text
|
.replace(new RegExp(`/^${delimiter}+/`), "") // Trim delimiter from start of text
|
||||||
|
.replace(new RegExp(`/-+$/`), ""); // Trim delimiter from end of text
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ export interface ScriptEntity extends HassEntityBase {
|
|||||||
export interface ScriptConfig {
|
export interface ScriptConfig {
|
||||||
alias: string;
|
alias: string;
|
||||||
sequence: Action[];
|
sequence: Action[];
|
||||||
|
icon?: string;
|
||||||
mode?: "single" | "restart" | "queued" | "parallel";
|
mode?: "single" | "restart" | "queued" | "parallel";
|
||||||
max?: number;
|
max?: number;
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,14 @@ import {
|
|||||||
property,
|
property,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
|
internalProperty,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { computeObjectId } from "../../../common/entity/compute_object_id";
|
import { computeObjectId } from "../../../common/entity/compute_object_id";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-icon-input";
|
||||||
import "@material/mwc-fab";
|
import "@material/mwc-fab";
|
||||||
import {
|
import {
|
||||||
Action,
|
Action,
|
||||||
@ -36,6 +38,7 @@ import { configSections } from "../ha-panel-config";
|
|||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { mdiContentSave } from "@mdi/js";
|
import { mdiContentSave } from "@mdi/js";
|
||||||
import { PaperListboxElement } from "@polymer/paper-listbox";
|
import { PaperListboxElement } from "@polymer/paper-listbox";
|
||||||
|
import { slugify } from "../../../common/string/slugify";
|
||||||
|
|
||||||
export class HaScriptEditor extends LitElement {
|
export class HaScriptEditor extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -48,11 +51,15 @@ export class HaScriptEditor extends LitElement {
|
|||||||
|
|
||||||
@property() public narrow!: boolean;
|
@property() public narrow!: boolean;
|
||||||
|
|
||||||
@property() private _config?: ScriptConfig;
|
@internalProperty() private _config?: ScriptConfig;
|
||||||
|
|
||||||
@property() private _dirty?: boolean;
|
@internalProperty() private _entityId?: string;
|
||||||
|
|
||||||
@property() private _errors?: string;
|
@internalProperty() private _idError = false;
|
||||||
|
|
||||||
|
@internalProperty() private _dirty?: boolean;
|
||||||
|
|
||||||
|
@internalProperty() private _errors?: string;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
@ -107,9 +114,32 @@ export class HaScriptEditor extends LitElement {
|
|||||||
name="alias"
|
name="alias"
|
||||||
.value=${this._config.alias}
|
.value=${this._config.alias}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
|
@change=${this._aliasChanged}
|
||||||
>
|
>
|
||||||
</paper-input>
|
</paper-input>
|
||||||
|
<ha-icon-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.script.editor.icon"
|
||||||
|
)}
|
||||||
|
.name=${"icon"}
|
||||||
|
.value=${this._config.icon}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
>
|
||||||
|
</ha-icon-input>
|
||||||
|
${!this.scriptEntityId
|
||||||
|
? html` <paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.script.editor.id"
|
||||||
|
)}
|
||||||
|
.errorMessage=${this.hass.localize(
|
||||||
|
"ui.panel.config.script.editor.id_already_exists"
|
||||||
|
)}
|
||||||
|
.invalid=${this._idError}
|
||||||
|
.value=${this._entityId}
|
||||||
|
@value-changed=${this._idChanged}
|
||||||
|
>
|
||||||
|
</paper-input>`
|
||||||
|
: ""}
|
||||||
<p>
|
<p>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.script.editor.modes.description",
|
"ui.panel.config.script.editor.modes.description",
|
||||||
@ -283,6 +313,30 @@ export class HaScriptEditor extends LitElement {
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _aliasChanged(ev: CustomEvent) {
|
||||||
|
if (this.scriptEntityId || this._entityId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const aliasSlugify = slugify((ev.target as any).value, "_");
|
||||||
|
let id = aliasSlugify;
|
||||||
|
let i = 2;
|
||||||
|
while (this.hass.states[`script.${id}`]) {
|
||||||
|
id = `${aliasSlugify}_${i}`;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
this._entityId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _idChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this._entityId = (ev.target as any).value;
|
||||||
|
if (this.hass.states[`script.${this._entityId}`]) {
|
||||||
|
this._idError = true;
|
||||||
|
} else {
|
||||||
|
this._idError = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent) {
|
private _valueChanged(ev: CustomEvent) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const target = ev.target as any;
|
const target = ev.target as any;
|
||||||
@ -337,9 +391,15 @@ export class HaScriptEditor extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _saveScript(): void {
|
private _saveScript(): void {
|
||||||
|
if (this._idError) {
|
||||||
|
this._errors = this.hass.localize(
|
||||||
|
"ui.panel.config.script.editor.id_already_exists_save_error"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const id = this.scriptEntityId
|
const id = this.scriptEntityId
|
||||||
? computeObjectId(this.scriptEntityId)
|
? computeObjectId(this.scriptEntityId)
|
||||||
: Date.now();
|
: this._entityId || Date.now();
|
||||||
this.hass!.callApi("POST", "config/script/config/" + id, this._config).then(
|
this.hass!.callApi("POST", "config/script/config/" + id, this._config).then(
|
||||||
() => {
|
() => {
|
||||||
this._dirty = false;
|
this._dirty = false;
|
||||||
|
@ -25,6 +25,7 @@ import { showToast } from "../../../util/toast";
|
|||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { mdiPlus } from "@mdi/js";
|
import { mdiPlus } from "@mdi/js";
|
||||||
|
import { stateIcon } from "../../../common/entity/state_icon";
|
||||||
|
|
||||||
@customElement("ha-script-picker")
|
@customElement("ha-script-picker")
|
||||||
class HaScriptPicker extends LitElement {
|
class HaScriptPicker extends LitElement {
|
||||||
@ -43,6 +44,7 @@ class HaScriptPicker extends LitElement {
|
|||||||
return {
|
return {
|
||||||
...script,
|
...script,
|
||||||
name: computeStateName(script),
|
name: computeStateName(script),
|
||||||
|
icon: stateIcon(script),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -65,6 +67,11 @@ class HaScriptPicker extends LitElement {
|
|||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
title: "",
|
||||||
|
type: "icon",
|
||||||
|
template: (icon) => html` <ha-icon .icon=${icon}></ha-icon> `,
|
||||||
|
},
|
||||||
name: {
|
name: {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
"ui.panel.config.script.picker.headers.name"
|
"ui.panel.config.script.picker.headers.name"
|
||||||
|
@ -1080,6 +1080,10 @@
|
|||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"alias": "Name",
|
"alias": "Name",
|
||||||
|
"icon": "Icon",
|
||||||
|
"id": "Entity ID",
|
||||||
|
"id_already_exists_save_error": "You can't save this script because the ID is not unique, pick another ID or leave it blank to automatically generate one.",
|
||||||
|
"id_already_exists": "This ID already exists",
|
||||||
"introduction": "Use scripts to execute a sequence of actions.",
|
"introduction": "Use scripts to execute a sequence of actions.",
|
||||||
"header": "Script: {name}",
|
"header": "Script: {name}",
|
||||||
"default_name": "New Script",
|
"default_name": "New Script",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user