mirror of
https://github.com/home-assistant/frontend.git
synced 2026-03-03 05:47:54 +00:00
Compare commits
57 Commits
20260302.0
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b82882e15 | ||
|
|
2701015eda | ||
|
|
1991a9e493 | ||
|
|
2b72c54194 | ||
|
|
a7cb2fe7a7 | ||
|
|
51ea0c8201 | ||
|
|
ead7081bc6 | ||
|
|
ee982b1899 | ||
|
|
e8b100a39e | ||
|
|
50c361db62 | ||
|
|
e7a8d15a13 | ||
|
|
fbd0409837 | ||
|
|
a0d100611f | ||
|
|
a969bf1065 | ||
|
|
a153330610 | ||
|
|
bd2f1ca3a8 | ||
|
|
3263034416 | ||
|
|
82b28b547a | ||
|
|
61c2c750b4 | ||
|
|
117690ee70 | ||
|
|
e753de85eb | ||
|
|
a240019968 | ||
|
|
0bdf4b8777 | ||
|
|
6337828ed8 | ||
|
|
b8e5af652b | ||
|
|
e4ae29e8b5 | ||
|
|
08231dbbb0 | ||
|
|
0ca656933d | ||
|
|
b23cf8eba4 | ||
|
|
61b546415d | ||
|
|
4e1b709303 | ||
|
|
34e65b302d | ||
|
|
336d0e1b9d | ||
|
|
58d4cf8d84 | ||
|
|
d3453aff37 | ||
|
|
64ff2e414c | ||
|
|
2ca25c980f | ||
|
|
73d93bc601 | ||
|
|
5ca6a8aced | ||
|
|
7ff4993e0b | ||
|
|
4e6fbacccc | ||
|
|
2958d49e36 | ||
|
|
92289dc7ea | ||
|
|
f6c1a890e4 | ||
|
|
d06321ed43 | ||
|
|
3c3d8d9974 | ||
|
|
4f39fa482d | ||
|
|
5d0fe3236c | ||
|
|
b86142ae50 | ||
|
|
5d2f3ee5e8 | ||
|
|
e3f7c631a7 | ||
|
|
49f9d95853 | ||
|
|
db3d7701b5 | ||
|
|
3e55acf531 | ||
|
|
f102618d9d | ||
|
|
a3c02b511d | ||
|
|
74111d248e |
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
@@ -89,13 +89,13 @@ jobs:
|
||||
env:
|
||||
IS_TEST: "true"
|
||||
- name: Upload bundle stats
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: frontend-bundle-stats
|
||||
path: build/stats/*.json
|
||||
if-no-files-found: error
|
||||
- name: Upload frontend build
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: frontend-build
|
||||
path: hass_frontend/
|
||||
|
||||
4
.github/workflows/nightly.yaml
vendored
4
.github/workflows/nightly.yaml
vendored
@@ -57,14 +57,14 @@ jobs:
|
||||
run: tar -czvf translations.tar.gz translations
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: wheels
|
||||
path: dist/home_assistant_frontend*.whl
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload translations
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: translations
|
||||
path: translations.tar.gz
|
||||
|
||||
26
package.json
26
package.json
@@ -30,7 +30,7 @@
|
||||
"@braintree/sanitize-url": "7.1.2",
|
||||
"@codemirror/autocomplete": "6.20.0",
|
||||
"@codemirror/commands": "6.10.2",
|
||||
"@codemirror/language": "6.12.1",
|
||||
"@codemirror/language": "6.12.2",
|
||||
"@codemirror/legacy-modes": "6.5.2",
|
||||
"@codemirror/search": "6.6.0",
|
||||
"@codemirror/state": "6.5.4",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@fullcalendar/list": "6.1.20",
|
||||
"@fullcalendar/luxon3": "6.1.20",
|
||||
"@fullcalendar/timegrid": "6.1.20",
|
||||
"@home-assistant/webawesome": "3.2.1-ha.2",
|
||||
"@home-assistant/webawesome": "3.2.1-ha.3",
|
||||
"@lezer/highlight": "1.2.3",
|
||||
"@lit-labs/motion": "1.1.0",
|
||||
"@lit-labs/observers": "2.1.0",
|
||||
@@ -83,7 +83,7 @@
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/svg": "7.4.47",
|
||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||
"@swc/helpers": "0.5.18",
|
||||
"@swc/helpers": "0.5.19",
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@tsparticles/engine": "3.9.1",
|
||||
"@tsparticles/preset-links": "3.2.0",
|
||||
@@ -92,7 +92,7 @@
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||
"@webcomponents/webcomponentsjs": "2.8.0",
|
||||
"app-datepicker": "5.1.1",
|
||||
"barcode-detector": "3.0.8",
|
||||
"barcode-detector": "3.1.0",
|
||||
"color-name": "2.1.0",
|
||||
"comlink": "4.4.2",
|
||||
"core-js": "3.48.0",
|
||||
@@ -106,7 +106,7 @@
|
||||
"element-internals-polyfill": "3.0.2",
|
||||
"fuse.js": "7.1.0",
|
||||
"google-timezones-json": "1.2.0",
|
||||
"gulp-zopfli-green": "6.0.2",
|
||||
"gulp-zopfli-green": "7.0.0",
|
||||
"hls.js": "1.6.15",
|
||||
"home-assistant-js-websocket": "9.6.0",
|
||||
"idb-keyval": "6.2.2",
|
||||
@@ -149,7 +149,7 @@
|
||||
"@babel/plugin-transform-runtime": "7.29.0",
|
||||
"@babel/preset-env": "7.29.0",
|
||||
"@bundle-stats/plugin-webpack-filter": "4.21.10",
|
||||
"@html-eslint/eslint-plugin": "0.56.0",
|
||||
"@html-eslint/eslint-plugin": "0.57.1",
|
||||
"@lokalise/node-api": "15.6.1",
|
||||
"@octokit/auth-oauth-device": "8.0.3",
|
||||
"@octokit/plugin-retry": "8.1.0",
|
||||
@@ -172,7 +172,7 @@
|
||||
"@types/mocha": "10.0.10",
|
||||
"@types/qrcode": "1.5.6",
|
||||
"@types/sortablejs": "1.15.9",
|
||||
"@types/tar": "6.1.13",
|
||||
"@types/tar": "7.0.87",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@vitest/coverage-v8": "4.0.18",
|
||||
@@ -188,7 +188,7 @@
|
||||
"eslint-plugin-lit": "2.2.1",
|
||||
"eslint-plugin-lit-a11y": "5.1.1",
|
||||
"eslint-plugin-unused-imports": "4.4.1",
|
||||
"eslint-plugin-wc": "3.0.2",
|
||||
"eslint-plugin-wc": "3.1.0",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.3",
|
||||
"glob": "13.0.6",
|
||||
@@ -198,7 +198,7 @@
|
||||
"gulp-rename": "2.1.0",
|
||||
"html-minifier-terser": "7.2.0",
|
||||
"husky": "9.1.7",
|
||||
"jsdom": "28.0.0",
|
||||
"jsdom": "28.1.0",
|
||||
"jszip": "3.10.1",
|
||||
"lint-staged": "16.2.7",
|
||||
"lit-analyzer": "2.0.3",
|
||||
@@ -210,12 +210,12 @@
|
||||
"rspack-manifest-plugin": "5.2.1",
|
||||
"serve": "14.2.5",
|
||||
"sinon": "21.0.1",
|
||||
"tar": "7.5.8",
|
||||
"tar": "7.5.9",
|
||||
"terser-webpack-plugin": "5.3.16",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.54.0",
|
||||
"vite-tsconfig-paths": "6.0.5",
|
||||
"typescript-eslint": "8.56.1",
|
||||
"vite-tsconfig-paths": "6.1.1",
|
||||
"vitest": "4.0.18",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
@@ -235,6 +235,6 @@
|
||||
},
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"volta": {
|
||||
"node": "24.13.1"
|
||||
"node": "24.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20260302.0"
|
||||
version = "20260128.0"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*"]
|
||||
description = "The Home Assistant frontend"
|
||||
|
||||
@@ -672,11 +672,11 @@ export class HaAssistChat extends LitElement {
|
||||
--markdown-code-background-color: var(--primary-background-color);
|
||||
--markdown-code-text-color: var(--primary-text-color);
|
||||
--markdown-list-indent: 1.15em;
|
||||
&:not(:has(ha-markdown-element)) {
|
||||
min-height: 1lh;
|
||||
min-width: 1lh;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
ha-markdown:not(:has(ha-markdown-element)) {
|
||||
min-height: 1lh;
|
||||
min-width: 1lh;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.bouncer {
|
||||
width: 48px;
|
||||
|
||||
@@ -410,29 +410,29 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
:host([type="standard"]) {
|
||||
--ha-dialog-border-radius: 0;
|
||||
}
|
||||
|
||||
wa-dialog {
|
||||
/* Make the container fill the whole screen width and not the safe width */
|
||||
--full-width: var(--ha-dialog-width-full, 100vw);
|
||||
--width: var(--full-width);
|
||||
}
|
||||
:host([type="standard"]) wa-dialog {
|
||||
/* Make the container fill the whole screen width and not the safe width */
|
||||
--full-width: var(--ha-dialog-width-full, 100vw);
|
||||
--width: var(--full-width);
|
||||
}
|
||||
|
||||
wa-dialog::part(dialog) {
|
||||
/* Make the dialog fill the whole screen height and not the safe height */
|
||||
min-height: var(--ha-dialog-min-height, 100vh);
|
||||
min-height: var(--ha-dialog-min-height, 100dvh);
|
||||
max-height: var(--ha-dialog-max-height, 100vh);
|
||||
max-height: var(--ha-dialog-max-height, 100dvh);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
/* Use safe area as padding instead of the container size */
|
||||
padding-top: var(--safe-area-inset-top);
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-left: var(--safe-area-inset-left);
|
||||
padding-right: var(--safe-area-inset-right);
|
||||
/* Reset the transform to center the dialog */
|
||||
transform: none;
|
||||
}
|
||||
:host([type="standard"]) wa-dialog::part(dialog) {
|
||||
/* Make the dialog fill the whole screen height and not the safe height */
|
||||
min-height: var(--ha-dialog-min-height, 100vh);
|
||||
min-height: var(--ha-dialog-min-height, 100dvh);
|
||||
max-height: var(--ha-dialog-max-height, 100vh);
|
||||
max-height: var(--ha-dialog-max-height, 100dvh);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
/* Use safe area as padding instead of the container size */
|
||||
padding-top: var(--safe-area-inset-top);
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-left: var(--safe-area-inset-left);
|
||||
padding-right: var(--safe-area-inset-right);
|
||||
/* Reset the transform to center the dialog */
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ const LOAD_ELEMENTS = {
|
||||
};
|
||||
|
||||
const getValue = (obj, item) =>
|
||||
obj ? (!item.name || item.flatten ? obj : obj[item.name]) : null;
|
||||
obj ? (!item.name || item.flatten ? obj : obj[item.name]) : undefined;
|
||||
|
||||
const getError = (obj, item) => (obj && item.name ? obj[item.name] : null);
|
||||
|
||||
|
||||
@@ -84,13 +84,11 @@ export class HaMarkdown extends LitElement {
|
||||
ha-markdown-element > :is(ol, ul) {
|
||||
padding-inline-start: var(--markdown-list-indent, revert);
|
||||
}
|
||||
li {
|
||||
&:has(input[type="checkbox"]) {
|
||||
list-style: none;
|
||||
& > input[type="checkbox"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
li:has(input[type="checkbox"]) {
|
||||
list-style: none;
|
||||
}
|
||||
li:has(input[type="checkbox"]) > input[type="checkbox"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
svg {
|
||||
background-color: var(--markdown-svg-background-color, none);
|
||||
@@ -137,10 +135,10 @@ export class HaMarkdown extends LitElement {
|
||||
--markdown-table-border-width: 0;
|
||||
--markdown-table-padding-inline: 0;
|
||||
--markdown-table-padding-block: 0;
|
||||
th,
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
table[role="presentation"] th,
|
||||
table[role="presentation"] td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
table[role="presentation"] td[valign="top"],
|
||||
table[role="presentation"] th[valign="top"] {
|
||||
|
||||
@@ -2,10 +2,10 @@ import type { LitElement, PropertyValues } from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import type { LocalizeFunc } from "../common/translations/localize";
|
||||
import { computeLocalize } from "../common/translations/localize";
|
||||
import { computeDirectionStyles } from "../common/util/compute_rtl";
|
||||
import { translationMetadata } from "../resources/translations-metadata";
|
||||
import type { Constructor, Resources } from "../types";
|
||||
import { getLocalLanguage, getTranslation } from "../util/common-translation";
|
||||
import { translationMetadata } from "../resources/translations-metadata";
|
||||
import { computeDirectionStyles } from "../common/util/compute_rtl";
|
||||
|
||||
const empty = () => "";
|
||||
|
||||
@@ -28,16 +28,16 @@ export const litLocalizeLiteMixin = <T extends Constructor<LitElement>>(
|
||||
this._initializeLocalizeLite();
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
computeDirectionStyles(
|
||||
translationMetadata.translations[this.language!].isRTL,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues) {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
if (!this.updated || changedProperties.has("language")) {
|
||||
computeDirectionStyles(
|
||||
translationMetadata.translations[this.language!].isRTL,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
if (changedProperties.get("language")) {
|
||||
this._resources = undefined;
|
||||
this._initializeLocalizeLite();
|
||||
|
||||
@@ -1,30 +1,17 @@
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { isTemplate } from "../../../../../common/string/has-template";
|
||||
import type { WaitAction } from "../../../../../data/script";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import type { ActionElement } from "../ha-automation-action-row";
|
||||
import "../../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../../components/ha-form/types";
|
||||
|
||||
const SCHEMA = [
|
||||
{
|
||||
name: "wait_template",
|
||||
selector: {
|
||||
template: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "timeout",
|
||||
required: false,
|
||||
selector: {
|
||||
text: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "continue_on_timeout",
|
||||
selector: { boolean: {} },
|
||||
},
|
||||
] as const;
|
||||
type TimeoutType = "string_template" | "object_template" | "duration";
|
||||
|
||||
@customElement("ha-automation-action-wait_template")
|
||||
export class HaWaitAction extends LitElement implements ActionElement {
|
||||
@@ -38,12 +25,47 @@ export class HaWaitAction extends LitElement implements ActionElement {
|
||||
return { wait_template: "", continue_on_timeout: true };
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(timeoutType: TimeoutType) =>
|
||||
[
|
||||
{
|
||||
name: "wait_template",
|
||||
selector: { template: {} },
|
||||
},
|
||||
{
|
||||
name: "timeout",
|
||||
required: false,
|
||||
selector:
|
||||
timeoutType === "string_template"
|
||||
? { template: {} }
|
||||
: timeoutType === "object_template"
|
||||
? { object: {} }
|
||||
: { duration: { enable_millisecond: true } },
|
||||
},
|
||||
{
|
||||
name: "continue_on_timeout",
|
||||
selector: { boolean: {} },
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
protected render() {
|
||||
const timeout = this.action.timeout;
|
||||
const timeoutType: TimeoutType =
|
||||
typeof timeout === "string" && isTemplate(timeout)
|
||||
? "string_template"
|
||||
: typeof timeout === "object" &&
|
||||
timeout !== null &&
|
||||
Object.values(timeout).some(
|
||||
(v) => typeof v === "string" && isTemplate(v)
|
||||
)
|
||||
? "object_template"
|
||||
: "duration";
|
||||
return html`
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this.action}
|
||||
.schema=${SCHEMA}
|
||||
.schema=${this._schema(timeoutType)}
|
||||
.disabled=${this.disabled}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
></ha-form>
|
||||
@@ -51,7 +73,7 @@ export class HaWaitAction extends LitElement implements ActionElement {
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
schema: SchemaUnion<typeof SCHEMA>
|
||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
||||
): string =>
|
||||
this.hass.localize(
|
||||
`ui.panel.config.automation.editor.actions.type.wait_template.${
|
||||
|
||||
@@ -27,19 +27,15 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { UndoRedoController } from "../../../common/controllers/undo-redo-controller";
|
||||
import { transform } from "../../../common/decorators/transform";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { goBack, navigate } from "../../../common/navigate";
|
||||
import { promiseTimeout } from "../../../common/util/promise-timeout";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-fade-in";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import type {
|
||||
@@ -72,27 +68,22 @@ import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type {
|
||||
Entries,
|
||||
HomeAssistant,
|
||||
Route,
|
||||
ValueChangedEvent,
|
||||
} from "../../../types";
|
||||
import type { Entries, ValueChangedEvent } from "../../../types";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-automation-mode";
|
||||
import {
|
||||
type EntityRegistryUpdate,
|
||||
showAutomationSaveDialog,
|
||||
} from "./automation-save-dialog/show-dialog-automation-save";
|
||||
import { showAutomationSaveDialog } from "./automation-save-dialog/show-dialog-automation-save";
|
||||
import { showAutomationSaveTimeoutDialog } from "./automation-save-timeout-dialog/show-dialog-automation-save-timeout";
|
||||
import "./blueprint-automation-editor";
|
||||
import {
|
||||
AutomationScriptEditorMixin,
|
||||
automationScriptEditorStyles,
|
||||
} from "./ha-automation-script-editor-mixin";
|
||||
import "./manual-automation-editor";
|
||||
import type { HaManualAutomationEditor } from "./manual-automation-editor";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
@@ -119,53 +110,13 @@ declare global {
|
||||
}
|
||||
|
||||
@customElement("ha-automation-editor")
|
||||
export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
KeyboardShortcutMixin(LitElement)
|
||||
export class HaAutomationEditor extends AutomationScriptEditorMixin<AutomationConfig>(
|
||||
PreventUnsavedMixin(KeyboardShortcutMixin(LitElement))
|
||||
) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public automationId: string | null = null;
|
||||
|
||||
@property({ attribute: false }) public entityId: string | null = null;
|
||||
|
||||
@property({ attribute: false }) public automations!: AutomationEntity[];
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@state() private _config?: AutomationConfig;
|
||||
|
||||
@state() private _dirty = false;
|
||||
|
||||
@state() private _errors?: string;
|
||||
|
||||
@state() private _yamlErrors?: string;
|
||||
|
||||
@state() private _entityId?: string;
|
||||
|
||||
@state() private _mode: "gui" | "yaml" = "gui";
|
||||
|
||||
@state() private _readOnly = false;
|
||||
|
||||
@state() private _validationErrors?: (string | TemplateResult)[];
|
||||
|
||||
@state() private _blueprintConfig?: BlueprintAutomationConfig;
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
@transform<EntityRegistryEntry[], EntityRegistryEntry>({
|
||||
transformer: function (this: HaAutomationEditor, value) {
|
||||
return value.find(({ entity_id }) => entity_id === this._entityId);
|
||||
},
|
||||
watch: ["_entityId"],
|
||||
})
|
||||
private _registryEntry?: EntityRegistryEntry;
|
||||
|
||||
@state() private _saving = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
_entityRegistry!: EntityRegistryEntry[];
|
||||
@@ -180,24 +131,18 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
private _configSubscriptionsId = 1;
|
||||
|
||||
private _entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
|
||||
private _newAutomationId?: string;
|
||||
|
||||
private _entityRegCreated?: (
|
||||
value: PromiseLike<EntityRegistryEntry> | EntityRegistryEntry
|
||||
) => void;
|
||||
|
||||
private _undoRedoController = new UndoRedoController<AutomationConfig>(this, {
|
||||
apply: (config) => this._applyUndoRedo(config),
|
||||
currentConfig: () => this._config!,
|
||||
currentConfig: () => this.config!,
|
||||
});
|
||||
|
||||
protected willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (
|
||||
this._entityRegCreated &&
|
||||
this.entityRegCreated &&
|
||||
this._newAutomationId &&
|
||||
changedProps.has("_entityRegistry")
|
||||
) {
|
||||
@@ -207,26 +152,22 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
entity.unique_id === this._newAutomationId
|
||||
);
|
||||
if (automation) {
|
||||
this._entityRegCreated(automation);
|
||||
this._entityRegCreated = undefined;
|
||||
this.entityRegCreated(automation);
|
||||
this.entityRegCreated = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | typeof nothing {
|
||||
if (!this._config) {
|
||||
return html`
|
||||
<ha-fade-in .delay=${500}>
|
||||
<ha-spinner size="large"></ha-spinner>
|
||||
</ha-fade-in>
|
||||
`;
|
||||
if (!this.config) {
|
||||
return this.renderLoading();
|
||||
}
|
||||
|
||||
const stateObj = this._entityId
|
||||
? this.hass.states[this._entityId]
|
||||
const stateObj = this.currentEntityId
|
||||
? this.hass.states[this.currentEntityId]
|
||||
: undefined;
|
||||
|
||||
const useBlueprint = "use_blueprint" in this._config;
|
||||
const useBlueprint = "use_blueprint" in this.config;
|
||||
const shortcutIcon = isMac
|
||||
? html`<ha-svg-icon .path=${mdiAppleKeyboardCommand}></ha-svg-icon>`
|
||||
: this.hass.localize("ui.panel.config.automation.editor.ctrl");
|
||||
@@ -236,11 +177,11 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${this._backTapped}
|
||||
.header=${this._config.alias ||
|
||||
.backCallback=${this.backTapped}
|
||||
.header=${this.config.alias ||
|
||||
this.hass.localize("ui.panel.config.automation.editor.default_name")}
|
||||
>
|
||||
${this._mode === "gui" && !this.narrow
|
||||
${this.mode === "gui" && !this.narrow
|
||||
? html`<ha-icon-button
|
||||
slot="toolbar-icon"
|
||||
.label=${this.hass.localize("ui.common.undo")}
|
||||
@@ -284,7 +225,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
</span>
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
${this._config?.id && !this.narrow
|
||||
${this.config?.id && !this.narrow
|
||||
? html`
|
||||
<ha-button
|
||||
appearance="plain"
|
||||
@@ -308,7 +249,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
|
||||
${this._mode === "gui" && this.narrow
|
||||
${this.mode === "gui" && this.narrow
|
||||
? html`<ha-dropdown-item
|
||||
value="undo"
|
||||
.disabled=${!this._undoRedoController.canUndo}
|
||||
@@ -342,7 +283,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
<ha-dropdown-item .disabled=${!stateObj} value="category">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.scene.picker.${this._registryEntry?.categories?.automation ? "edit_category" : "assign_category"}`
|
||||
`ui.panel.config.scene.picker.${this.registryEntry?.categories?.automation ? "edit_category" : "assign_category"}`
|
||||
)}
|
||||
<ha-svg-icon slot="icon" .path=${mdiTag}></ha-svg-icon>
|
||||
</ha-dropdown-item>
|
||||
@@ -366,9 +307,9 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
<ha-dropdown-item
|
||||
value="rename"
|
||||
.disabled=${this._readOnly ||
|
||||
.disabled=${this.readOnly ||
|
||||
!this.automationId ||
|
||||
this._mode === "yaml"}
|
||||
this.mode === "yaml"}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.automation.editor.rename")}
|
||||
<ha-svg-icon slot="icon" .path=${mdiRenameBox}></ha-svg-icon>
|
||||
@@ -377,7 +318,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
@click=${this._promptAutomationMode}
|
||||
.disabled=${this._readOnly || this._mode === "yaml"}
|
||||
.disabled=${this.readOnly || this.mode === "yaml"}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.change_mode"
|
||||
@@ -391,12 +332,12 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
: nothing}
|
||||
|
||||
<ha-dropdown-item
|
||||
.disabled=${!!this._blueprintConfig ||
|
||||
(!this._readOnly && !this.automationId)}
|
||||
.disabled=${!!this.blueprintConfig ||
|
||||
(!this.readOnly && !this.automationId)}
|
||||
value="duplicate"
|
||||
>
|
||||
${this.hass.localize(
|
||||
this._readOnly
|
||||
this.readOnly
|
||||
? "ui.panel.config.automation.editor.migrate"
|
||||
: "ui.panel.config.automation.editor.duplicate"
|
||||
)}
|
||||
@@ -410,7 +351,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
value="take_control"
|
||||
.disabled=${this._readOnly}
|
||||
.disabled=${this.readOnly}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.take_control"
|
||||
@@ -422,7 +363,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
<ha-dropdown-item value="toggle_yaml_mode">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.edit_${this._mode === "gui" ? "yaml" : "ui"}`
|
||||
`ui.panel.config.automation.editor.edit_${this.mode === "gui" ? "yaml" : "ui"}`
|
||||
)}
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
|
||||
</ha-dropdown-item>
|
||||
@@ -456,10 +397,10 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
<div
|
||||
class=${this._mode === "yaml" ? "yaml-mode" : ""}
|
||||
class=${this.mode === "yaml" ? "yaml-mode" : ""}
|
||||
@subscribe-automation-config=${this._subscribeAutomationConfig}
|
||||
>
|
||||
${this._mode === "gui"
|
||||
${this.mode === "gui"
|
||||
? html`
|
||||
<div>
|
||||
${useBlueprint
|
||||
@@ -469,10 +410,10 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
.narrow=${this.narrow}
|
||||
.isWide=${this.isWide}
|
||||
.stateObj=${stateObj}
|
||||
.config=${this._config}
|
||||
.disabled=${this._readOnly}
|
||||
.saving=${this._saving}
|
||||
.dirty=${this._dirty}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.saving=${this.saving}
|
||||
.dirty=${this.dirty}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-automation=${this._handleSaveAutomation}
|
||||
></blueprint-automation-editor>
|
||||
@@ -483,16 +424,16 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
.narrow=${this.narrow}
|
||||
.isWide=${this.isWide}
|
||||
.stateObj=${stateObj}
|
||||
.config=${this._config}
|
||||
.disabled=${this._readOnly}
|
||||
.dirty=${this._dirty}
|
||||
.saving=${this._saving}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.dirty=${this.dirty}
|
||||
.saving=${this.saving}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-automation=${this._handleSaveAutomation}
|
||||
@editor-save=${this._handleSaveAutomation}
|
||||
>
|
||||
<div class="alert-wrapper" slot="alerts">
|
||||
${this._errors || stateObj?.state === UNAVAILABLE
|
||||
${this.errors || stateObj?.state === UNAVAILABLE
|
||||
? html`<ha-alert
|
||||
alert-type="error"
|
||||
.title=${stateObj?.state === UNAVAILABLE
|
||||
@@ -501,7 +442,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
)
|
||||
: undefined}
|
||||
>
|
||||
${this._errors || this._validationErrors}
|
||||
${this.errors || this.validationErrors}
|
||||
${stateObj?.state === UNAVAILABLE
|
||||
? html`<ha-svg-icon
|
||||
slot="icon"
|
||||
@@ -510,7 +451,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
: nothing}
|
||||
</ha-alert>`
|
||||
: nothing}
|
||||
${this._blueprintConfig
|
||||
${this.blueprintConfig
|
||||
? html`<ha-alert alert-type="info">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.confirm_take_control"
|
||||
@@ -518,21 +459,21 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
<div slot="action" style="display: flex;">
|
||||
<ha-button
|
||||
appearance="plain"
|
||||
@click=${this._takeControlSave}
|
||||
@click=${this.takeControlSave}
|
||||
>${this.hass.localize(
|
||||
"ui.common.yes"
|
||||
)}</ha-button
|
||||
>
|
||||
<ha-button
|
||||
appearance="plain"
|
||||
@click=${this._revertBlueprint}
|
||||
@click=${this.revertBlueprint}
|
||||
>${this.hass.localize(
|
||||
"ui.common.no"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>
|
||||
</ha-alert>`
|
||||
: this._readOnly
|
||||
: this.readOnly
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
dismissable
|
||||
@@ -575,7 +516,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
`}
|
||||
</div>
|
||||
`
|
||||
: this._mode === "yaml"
|
||||
: this.mode === "yaml"
|
||||
? html`${stateObj?.state === "off"
|
||||
? html`
|
||||
<ha-alert alert-type="info">
|
||||
@@ -598,7 +539,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
<ha-yaml-editor
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
.readOnly=${this.readOnly}
|
||||
@value-changed=${this._yamlChanged}
|
||||
@editor-save=${this._handleSaveAutomation}
|
||||
.showErrors=${false}
|
||||
@@ -606,9 +547,9 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
></ha-yaml-editor>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
class=${this._dirty ? "dirty" : ""}
|
||||
class=${this.dirty ? "dirty" : ""}
|
||||
.label=${this.hass.localize("ui.common.save")}
|
||||
.disabled=${this._saving}
|
||||
.disabled=${this.saving}
|
||||
extended
|
||||
@click=${this._handleSaveAutomation}
|
||||
>
|
||||
@@ -645,7 +586,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
this.hass
|
||||
) {
|
||||
const initData = getAutomationEditorInitData();
|
||||
this._dirty = !!initData;
|
||||
this.dirty = !!initData;
|
||||
let baseConfig: Partial<AutomationConfig> = { description: "" };
|
||||
if (!initData || !("use_blueprint" in initData)) {
|
||||
baseConfig = {
|
||||
@@ -656,35 +597,35 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
actions: [],
|
||||
};
|
||||
}
|
||||
this._config = {
|
||||
this.config = {
|
||||
...baseConfig,
|
||||
...(initData ? normalizeAutomationConfig(initData) : initData),
|
||||
} as AutomationConfig;
|
||||
this._entityId = undefined;
|
||||
this._readOnly = false;
|
||||
this.currentEntityId = undefined;
|
||||
this.readOnly = false;
|
||||
}
|
||||
|
||||
if (changedProps.has("entityId") && this.entityId) {
|
||||
getAutomationStateConfig(this.hass, this.entityId).then((c) => {
|
||||
this._config = normalizeAutomationConfig(c.config);
|
||||
this.config = normalizeAutomationConfig(c.config);
|
||||
this._checkValidation();
|
||||
});
|
||||
this._entityId = this.entityId;
|
||||
this._dirty = false;
|
||||
this._readOnly = true;
|
||||
this.currentEntityId = this.entityId;
|
||||
this.dirty = false;
|
||||
this.readOnly = true;
|
||||
}
|
||||
|
||||
if (
|
||||
changedProps.has("automations") &&
|
||||
this.automationId &&
|
||||
!this._entityId
|
||||
!this.currentEntityId
|
||||
) {
|
||||
this._setEntityId();
|
||||
}
|
||||
|
||||
if (changedProps.has("_config")) {
|
||||
if (changedProps.has("config")) {
|
||||
Object.values(this._configSubscriptions).forEach((sub) =>
|
||||
sub(this._config)
|
||||
sub(this.config)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -693,24 +634,24 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
const automation = this.automations.find(
|
||||
(entity: AutomationEntity) => entity.attributes.id === this.automationId
|
||||
);
|
||||
this._entityId = automation?.entity_id;
|
||||
this.currentEntityId = automation?.entity_id;
|
||||
}
|
||||
|
||||
private async _checkValidation() {
|
||||
this._validationErrors = undefined;
|
||||
if (!this._entityId || !this._config) {
|
||||
this.validationErrors = undefined;
|
||||
if (!this.currentEntityId || !this.config) {
|
||||
return;
|
||||
}
|
||||
const stateObj = this.hass.states[this._entityId];
|
||||
const stateObj = this.hass.states[this.currentEntityId];
|
||||
if (stateObj?.state !== UNAVAILABLE) {
|
||||
return;
|
||||
}
|
||||
const validation = await validateConfig(this.hass, {
|
||||
triggers: this._config.triggers,
|
||||
conditions: this._config.conditions,
|
||||
actions: this._config.actions,
|
||||
triggers: this.config.triggers,
|
||||
conditions: this.config.conditions,
|
||||
actions: this.config.actions,
|
||||
});
|
||||
this._validationErrors = (
|
||||
this.validationErrors = (
|
||||
Object.entries(validation) as Entries<typeof validation>
|
||||
).map(([key, value]) =>
|
||||
value.valid
|
||||
@@ -728,9 +669,9 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
this.hass,
|
||||
this.automationId as string
|
||||
);
|
||||
this._dirty = false;
|
||||
this._readOnly = false;
|
||||
this._config = normalizeAutomationConfig(config);
|
||||
this.dirty = false;
|
||||
this.readOnly = false;
|
||||
this.config = normalizeAutomationConfig(config);
|
||||
this._checkValidation();
|
||||
} catch (err: any) {
|
||||
const entity = this._entityRegistry.find(
|
||||
@@ -761,34 +702,27 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
private _valueChanged(ev: ValueChangedEvent<AutomationConfig>) {
|
||||
ev.stopPropagation();
|
||||
|
||||
if (this._config) {
|
||||
this._undoRedoController.commit(this._config);
|
||||
if (this.config) {
|
||||
this._undoRedoController.commit(this.config);
|
||||
}
|
||||
|
||||
this._config = ev.detail.value;
|
||||
if (this._readOnly) {
|
||||
this.config = ev.detail.value;
|
||||
if (this.readOnly) {
|
||||
return;
|
||||
}
|
||||
this._dirty = true;
|
||||
this._errors = undefined;
|
||||
this.dirty = true;
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
private _showInfo() {
|
||||
if (!this.hass || !this._entityId) {
|
||||
if (!this.hass || !this.currentEntityId) {
|
||||
return;
|
||||
}
|
||||
fireEvent(this, "hass-more-info", { entityId: this._entityId });
|
||||
}
|
||||
|
||||
private _showSettings() {
|
||||
showMoreInfoDialog(this, {
|
||||
entityId: this._entityId!,
|
||||
view: "settings",
|
||||
});
|
||||
fireEvent(this, "hass-more-info", { entityId: this.currentEntityId });
|
||||
}
|
||||
|
||||
private _editCategory() {
|
||||
if (!this._registryEntry) {
|
||||
if (!this.registryEntry) {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.scene.picker.no_category_support"
|
||||
@@ -801,36 +735,36 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
showAssignCategoryDialog(this, {
|
||||
scope: "automation",
|
||||
entityReg: this._registryEntry,
|
||||
entityReg: this.registryEntry,
|
||||
});
|
||||
}
|
||||
|
||||
private async _showTrace() {
|
||||
if (this._config?.id) {
|
||||
const result = await this._confirmUnsavedChanged();
|
||||
if (this.config?.id) {
|
||||
const result = await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
navigate(
|
||||
`/config/automation/trace/${encodeURIComponent(this._config.id)}`
|
||||
`/config/automation/trace/${encodeURIComponent(this.config.id)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _runActions() {
|
||||
if (!this.hass || !this._entityId) {
|
||||
if (!this.hass || !this.currentEntityId) {
|
||||
return;
|
||||
}
|
||||
triggerAutomationActions(
|
||||
this.hass,
|
||||
this.hass.states[this._entityId].entity_id
|
||||
this.hass.states[this.currentEntityId].entity_id
|
||||
);
|
||||
}
|
||||
|
||||
private async _toggle(): Promise<void> {
|
||||
if (!this.hass || !this._entityId) {
|
||||
if (!this.hass || !this.currentEntityId) {
|
||||
return;
|
||||
}
|
||||
const stateObj = this.hass.states[this._entityId];
|
||||
const stateObj = this.hass.states[this.currentEntityId];
|
||||
const service = stateObj.state === "off" ? "turn_on" : "turn_off";
|
||||
await this.hass.callService("automation", service, {
|
||||
entity_id: stateObj.entity_id,
|
||||
@@ -838,42 +772,42 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
private _preprocessYaml() {
|
||||
if (!this._config) {
|
||||
if (!this.config) {
|
||||
return {};
|
||||
}
|
||||
const cleanConfig: AutomationConfig = { ...this._config };
|
||||
const cleanConfig: AutomationConfig = { ...this.config };
|
||||
delete cleanConfig.id;
|
||||
return cleanConfig;
|
||||
}
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this._dirty = true;
|
||||
this.dirty = true;
|
||||
if (!ev.detail.isValid) {
|
||||
this._yamlErrors = ev.detail.errorMsg;
|
||||
this.yamlErrors = ev.detail.errorMsg;
|
||||
return;
|
||||
}
|
||||
this._yamlErrors = undefined;
|
||||
this._config = {
|
||||
id: this._config?.id,
|
||||
this.yamlErrors = undefined;
|
||||
this.config = {
|
||||
id: this.config?.id,
|
||||
...normalizeAutomationConfig(ev.detail.value),
|
||||
};
|
||||
this._errors = undefined;
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
private async _confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this._dirty) {
|
||||
protected async confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this.dirty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
showAutomationSaveDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
domain: "automation",
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
|
||||
const id = this.automationId || String(Date.now());
|
||||
@@ -889,8 +823,8 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
onDiscard: () => resolve(true),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryEntry: this._registryEntry,
|
||||
entityRegistryUpdate: this.entityRegistryUpdate,
|
||||
entityRegistryEntry: this.registryEntry,
|
||||
title: this.hass.localize(
|
||||
this.automationId
|
||||
? "ui.panel.config.automation.editor.leave.unsaved_confirm_title"
|
||||
@@ -906,15 +840,8 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
});
|
||||
}
|
||||
|
||||
private _backTapped = async () => {
|
||||
const result = await this._confirmUnsavedChanged();
|
||||
if (result) {
|
||||
afterNextRender(() => goBack("/config"));
|
||||
}
|
||||
};
|
||||
|
||||
private async _takeControl() {
|
||||
const config = this._config as BlueprintAutomationConfig;
|
||||
const config = this.config as BlueprintAutomationConfig;
|
||||
|
||||
try {
|
||||
const result = await substituteBlueprint(
|
||||
@@ -931,35 +858,20 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
description: config.description,
|
||||
};
|
||||
|
||||
this._blueprintConfig = config;
|
||||
this._config = newConfig;
|
||||
if (this._mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this._config);
|
||||
this.blueprintConfig = config;
|
||||
this.config = newConfig;
|
||||
if (this.mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this.config);
|
||||
}
|
||||
this._readOnly = true;
|
||||
this._errors = undefined;
|
||||
this.readOnly = true;
|
||||
this.errors = undefined;
|
||||
} catch (err: any) {
|
||||
this._errors = err.message;
|
||||
this.errors = err.message;
|
||||
}
|
||||
}
|
||||
|
||||
private _revertBlueprint() {
|
||||
this._config = this._blueprintConfig;
|
||||
if (this._mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this._config);
|
||||
}
|
||||
this._blueprintConfig = undefined;
|
||||
this._readOnly = false;
|
||||
}
|
||||
|
||||
private _takeControlSave() {
|
||||
this._readOnly = false;
|
||||
this._dirty = true;
|
||||
this._blueprintConfig = undefined;
|
||||
}
|
||||
|
||||
private async _duplicate() {
|
||||
const result = this._readOnly
|
||||
const result = this.readOnly
|
||||
? await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.automation.picker.migrate_automation"
|
||||
@@ -968,12 +880,12 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
"ui.panel.config.automation.picker.migrate_automation_description"
|
||||
),
|
||||
})
|
||||
: await this._confirmUnsavedChanged();
|
||||
: await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
showAutomationEditor({
|
||||
...this._config,
|
||||
...this.config,
|
||||
id: undefined,
|
||||
alias: this._readOnly ? this._config?.alias : undefined,
|
||||
alias: this.readOnly ? this.config?.alias : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -985,7 +897,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.automation.picker.delete_confirm_text",
|
||||
{ name: this._config?.alias }
|
||||
{ name: this.config?.alias }
|
||||
),
|
||||
confirmText: this.hass!.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
@@ -1001,43 +913,21 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
}
|
||||
|
||||
private async _switchUiMode() {
|
||||
if (this._yamlErrors) {
|
||||
const result = await showConfirmationDialog(this, {
|
||||
text: html`${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.switch_ui_yaml_error"
|
||||
)}<br /><br />${this._yamlErrors}`,
|
||||
confirmText: this.hass!.localize("ui.common.continue"),
|
||||
destructive: true,
|
||||
dismissText: this.hass!.localize("ui.common.cancel"),
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._yamlErrors = undefined;
|
||||
this._mode = "gui";
|
||||
}
|
||||
|
||||
private _switchYamlMode() {
|
||||
this._mode = "yaml";
|
||||
}
|
||||
|
||||
private async _promptAutomationAlias(): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
showAutomationSaveDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
domain: "automation",
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryEntry: this._registryEntry,
|
||||
entityRegistryUpdate: this.entityRegistryUpdate,
|
||||
entityRegistryEntry: this.registryEntry,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1045,10 +935,10 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
private async _promptAutomationMode(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
showAutomationModeDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
updateConfig: (config) => {
|
||||
this._config = config;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve();
|
||||
},
|
||||
@@ -1058,9 +948,9 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
private async _handleSaveAutomation(): Promise<void> {
|
||||
if (this._yamlErrors) {
|
||||
if (this.yamlErrors) {
|
||||
showToast(this, {
|
||||
message: this._yamlErrors,
|
||||
message: this.yamlErrors,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -1082,22 +972,22 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
}
|
||||
|
||||
private async _saveAutomation(id): Promise<void> {
|
||||
this._saving = true;
|
||||
this._validationErrors = undefined;
|
||||
this.saving = true;
|
||||
this.validationErrors = undefined;
|
||||
|
||||
let entityRegPromise: Promise<EntityRegistryEntry> | undefined;
|
||||
if (this._entityRegistryUpdate !== undefined && !this._entityId) {
|
||||
if (this.entityRegistryUpdate !== undefined && !this.currentEntityId) {
|
||||
this._newAutomationId = id;
|
||||
entityRegPromise = new Promise<EntityRegistryEntry>((resolve) => {
|
||||
this._entityRegCreated = resolve;
|
||||
this.entityRegCreated = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await saveAutomationConfig(this.hass, id, this._config!);
|
||||
await saveAutomationConfig(this.hass, id, this.config!);
|
||||
|
||||
if (this._entityRegistryUpdate !== undefined) {
|
||||
let entityId = this._entityId;
|
||||
if (this.entityRegistryUpdate !== undefined) {
|
||||
let entityId = this.currentEntityId;
|
||||
|
||||
// wait for automation to appear in entity registry when creating a new automation
|
||||
if (entityRegPromise) {
|
||||
@@ -1131,23 +1021,23 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
if (entityId) {
|
||||
await updateEntityRegistryEntry(this.hass, entityId, {
|
||||
categories: {
|
||||
automation: this._entityRegistryUpdate.category || null,
|
||||
automation: this.entityRegistryUpdate.category || null,
|
||||
},
|
||||
labels: this._entityRegistryUpdate.labels || [],
|
||||
area_id: this._entityRegistryUpdate.area || null,
|
||||
labels: this.entityRegistryUpdate.labels || [],
|
||||
area_id: this.entityRegistryUpdate.area || null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
this.dirty = false;
|
||||
} catch (errors: any) {
|
||||
this._errors = errors.body?.message || errors.error || errors.body;
|
||||
this.errors = errors.body?.message || errors.error || errors.body;
|
||||
showToast(this, {
|
||||
message: errors.body?.message || errors.error || errors.body,
|
||||
});
|
||||
throw errors;
|
||||
} finally {
|
||||
this._saving = false;
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1157,7 +1047,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
ev.detail.unsub = () => {
|
||||
delete this._configSubscriptions[id];
|
||||
};
|
||||
ev.detail.callback(this._config);
|
||||
ev.detail.callback(this.config);
|
||||
}
|
||||
|
||||
protected supportedShortcuts(): SupportedShortcuts {
|
||||
@@ -1173,14 +1063,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
};
|
||||
}
|
||||
|
||||
protected get isDirty() {
|
||||
return this._dirty;
|
||||
}
|
||||
|
||||
protected async promptDiscardChanges() {
|
||||
return this._confirmUnsavedChanged();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
private _collapseAll() {
|
||||
this._manualEditor?.collapseAll();
|
||||
@@ -1205,8 +1087,8 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
|
||||
private _applyUndoRedo(config: AutomationConfig) {
|
||||
this._manualEditor?.triggerCloseSidebar();
|
||||
this._config = config;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
private _undo() {
|
||||
@@ -1235,7 +1117,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
this._showInfo();
|
||||
break;
|
||||
case "settings":
|
||||
this._showSettings();
|
||||
this.showSettings();
|
||||
break;
|
||||
case "category":
|
||||
this._editCategory();
|
||||
@@ -1256,11 +1138,11 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
this._takeControl();
|
||||
break;
|
||||
case "toggle_yaml_mode":
|
||||
if (this._mode === "gui") {
|
||||
this._switchYamlMode();
|
||||
if (this.mode === "gui") {
|
||||
this.switchYamlMode();
|
||||
break;
|
||||
}
|
||||
this._switchUiMode();
|
||||
this.switchUiMode();
|
||||
break;
|
||||
case "disable":
|
||||
this._toggle();
|
||||
@@ -1277,25 +1159,8 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
automationScriptEditorStyles,
|
||||
css`
|
||||
:host {
|
||||
--ha-automation-editor-max-width: var(
|
||||
--ha-automation-editor-width,
|
||||
1540px
|
||||
);
|
||||
}
|
||||
ha-fade-in {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
.yaml-mode {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
manual-automation-editor,
|
||||
blueprint-automation-editor {
|
||||
margin: 0 auto;
|
||||
@@ -1309,17 +1174,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
ha-yaml-editor {
|
||||
flex-grow: 1;
|
||||
--actions-border-radius: var(--ha-border-radius-square);
|
||||
--code-mirror-height: 100%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
ha-entity-toggle {
|
||||
margin-right: 8px;
|
||||
margin-inline-end: 8px;
|
||||
@@ -1335,24 +1189,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
||||
max-width: 1040px;
|
||||
padding: 28px 20px 0;
|
||||
}
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
right: calc(16px + var(--safe-area-inset-right, 0px));
|
||||
bottom: calc(-80px - var(--safe-area-inset-bottom));
|
||||
transition: bottom 0.3s;
|
||||
}
|
||||
ha-fab.dirty {
|
||||
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
|
||||
}
|
||||
ha-tooltip ha-svg-icon {
|
||||
width: 12px;
|
||||
}
|
||||
ha-tooltip .shortcut {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
import { consume } from "@lit/context";
|
||||
import type { CSSResult, TemplateResult, LitElement } from "lit";
|
||||
import { css, html } from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import { transform } from "../../../common/decorators/transform";
|
||||
import { goBack } from "../../../common/navigate";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity/entity_registry";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import type { Constructor, HomeAssistant, Route } from "../../../types";
|
||||
import type { EntityRegistryUpdate } from "./automation-save-dialog/show-dialog-automation-save";
|
||||
import "../../../components/ha-fade-in";
|
||||
import "../../../components/ha-spinner"; // used by renderLoading() provided to both editors
|
||||
|
||||
/** Minimum config shape shared by both AutomationConfig and ScriptConfig. */
|
||||
interface BaseEditorConfig {
|
||||
alias?: string;
|
||||
}
|
||||
|
||||
/** Shared CSS styles for both automation and script editors. */
|
||||
export const automationScriptEditorStyles: CSSResult = css`
|
||||
:host {
|
||||
--ha-automation-editor-max-width: var(--ha-automation-editor-width, 1540px);
|
||||
}
|
||||
ha-fade-in {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
.yaml-mode {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
ha-yaml-editor {
|
||||
flex-grow: 1;
|
||||
--actions-border-radius: var(--ha-border-radius-square);
|
||||
--code-mirror-height: 100%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
right: calc(16px + var(--safe-area-inset-right, 0px));
|
||||
bottom: calc(-80px - var(--safe-area-inset-bottom));
|
||||
transition: bottom 0.3s;
|
||||
}
|
||||
ha-fab.dirty {
|
||||
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
|
||||
}
|
||||
ha-tooltip ha-svg-icon {
|
||||
width: 12px;
|
||||
}
|
||||
ha-tooltip .shortcut {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const AutomationScriptEditorMixin = <TConfig extends BaseEditorConfig>(
|
||||
superClass: Constructor<LitElement>
|
||||
) => {
|
||||
class AutomationScriptEditorClass extends superClass {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@property({ attribute: false }) public entityId: string | null = null;
|
||||
|
||||
@state() protected dirty = false;
|
||||
|
||||
@state() protected errors?: string;
|
||||
|
||||
@state() protected yamlErrors?: string;
|
||||
|
||||
@state() protected currentEntityId?: string;
|
||||
|
||||
@state() protected mode: "gui" | "yaml" = "gui";
|
||||
|
||||
@state() protected readOnly = false;
|
||||
|
||||
@state() protected saving = false;
|
||||
|
||||
@state() protected validationErrors?: (string | TemplateResult)[];
|
||||
|
||||
@state() protected config?: TConfig;
|
||||
|
||||
@state() protected blueprintConfig?: TConfig;
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
@transform<EntityRegistryEntry[], EntityRegistryEntry>({
|
||||
transformer: function (this: { currentEntityId?: string }, value) {
|
||||
return value.find(
|
||||
({ entity_id }) => entity_id === this.currentEntityId
|
||||
);
|
||||
},
|
||||
watch: ["currentEntityId"],
|
||||
})
|
||||
protected registryEntry?: EntityRegistryEntry;
|
||||
|
||||
protected entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
|
||||
protected entityRegCreated?: (
|
||||
value: PromiseLike<EntityRegistryEntry> | EntityRegistryEntry
|
||||
) => void;
|
||||
|
||||
protected renderLoading(): TemplateResult {
|
||||
return html`
|
||||
<ha-fade-in .delay=${500}>
|
||||
<ha-spinner size="large"></ha-spinner>
|
||||
</ha-fade-in>
|
||||
`;
|
||||
}
|
||||
|
||||
protected showSettings() {
|
||||
showMoreInfoDialog(this, {
|
||||
entityId: this.currentEntityId!,
|
||||
view: "settings",
|
||||
});
|
||||
}
|
||||
|
||||
protected async switchUiMode() {
|
||||
if (this.yamlErrors) {
|
||||
const result = await showConfirmationDialog(this, {
|
||||
text: html`${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.switch_ui_yaml_error"
|
||||
)}<br /><br />${this.yamlErrors}`,
|
||||
confirmText: this.hass!.localize("ui.common.continue"),
|
||||
destructive: true,
|
||||
dismissText: this.hass!.localize("ui.common.cancel"),
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.yamlErrors = undefined;
|
||||
this.mode = "gui";
|
||||
}
|
||||
|
||||
protected switchYamlMode() {
|
||||
this.mode = "yaml";
|
||||
}
|
||||
|
||||
protected takeControlSave() {
|
||||
this.readOnly = false;
|
||||
this.dirty = true;
|
||||
this.blueprintConfig = undefined;
|
||||
}
|
||||
|
||||
protected revertBlueprint() {
|
||||
this.config = this.blueprintConfig;
|
||||
if (this.mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this.config);
|
||||
}
|
||||
this.blueprintConfig = undefined;
|
||||
this.readOnly = false;
|
||||
}
|
||||
|
||||
protected backTapped = async () => {
|
||||
const result = await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
afterNextRender(() => goBack("/config"));
|
||||
}
|
||||
};
|
||||
|
||||
protected get isDirty() {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
protected async promptDiscardChanges() {
|
||||
return this.confirmUnsavedChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks whether unsaved changes should be discarded.
|
||||
* Subclasses must override this to show a confirmation dialog.
|
||||
* @returns true to proceed (discard/save changes), false to cancel.
|
||||
*/
|
||||
protected confirmUnsavedChanged(): Promise<boolean> {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
return AutomationScriptEditorClass;
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { consume } from "@lit/context";
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCog,
|
||||
@@ -22,15 +21,13 @@ import {
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { UndoRedoController } from "../../../common/controllers/undo-redo-controller";
|
||||
import { transform } from "../../../common/decorators/transform";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { goBack, navigate } from "../../../common/navigate";
|
||||
import { slugify } from "../../../common/string/slugify";
|
||||
import { promiseTimeout } from "../../../common/util/promise-timeout";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
@@ -40,7 +37,6 @@ import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import { substituteBlueprint } from "../../../data/blueprint";
|
||||
import { validateConfig } from "../../../data/config";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import { UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import {
|
||||
type EntityRegistryEntry,
|
||||
@@ -67,88 +63,47 @@ import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { Entries, HomeAssistant, Route } from "../../../types";
|
||||
import type { Entries } from "../../../types";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAutomationModeDialog } from "../automation/automation-mode-dialog/show-dialog-automation-mode";
|
||||
import type { EntityRegistryUpdate } from "../automation/automation-save-dialog/show-dialog-automation-save";
|
||||
import { showAutomationSaveDialog } from "../automation/automation-save-dialog/show-dialog-automation-save";
|
||||
import { showAutomationSaveTimeoutDialog } from "../automation/automation-save-timeout-dialog/show-dialog-automation-save-timeout";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import "./blueprint-script-editor";
|
||||
import {
|
||||
AutomationScriptEditorMixin,
|
||||
automationScriptEditorStyles,
|
||||
} from "../automation/ha-automation-script-editor-mixin";
|
||||
import "./manual-script-editor";
|
||||
import type { HaManualScriptEditor } from "./manual-script-editor";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
@customElement("ha-script-editor")
|
||||
export class HaScriptEditor extends SubscribeMixin(
|
||||
PreventUnsavedMixin(KeyboardShortcutMixin(LitElement))
|
||||
AutomationScriptEditorMixin<ScriptConfig>(
|
||||
PreventUnsavedMixin(KeyboardShortcutMixin(LitElement))
|
||||
)
|
||||
) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public scriptId: string | null = null;
|
||||
|
||||
@property({ attribute: false }) public entityId: string | null = null;
|
||||
|
||||
@property({ attribute: false }) public entityRegistry!: EntityRegistryEntry[];
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@state() private _config?: ScriptConfig;
|
||||
|
||||
@state() private _dirty = false;
|
||||
|
||||
@state() private _errors?: string;
|
||||
|
||||
@state() private _yamlErrors?: string;
|
||||
|
||||
@state() private _entityId?: string;
|
||||
|
||||
@state() private _mode: "gui" | "yaml" = "gui";
|
||||
|
||||
@state() private _readOnly = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||
@transform<EntityRegistryEntry[], EntityRegistryEntry>({
|
||||
transformer: function (this: HaScriptEditor, value) {
|
||||
return value.find(({ entity_id }) => entity_id === this._entityId);
|
||||
},
|
||||
watch: ["_entityId"],
|
||||
})
|
||||
private _registryEntry?: EntityRegistryEntry;
|
||||
|
||||
@query("manual-script-editor")
|
||||
private _manualEditor?: HaManualScriptEditor;
|
||||
|
||||
@state() private _validationErrors?: (string | TemplateResult)[];
|
||||
|
||||
@state() private _blueprintConfig?: BlueprintScriptConfig;
|
||||
|
||||
@state() private _saving = false;
|
||||
|
||||
private _entityRegistryUpdate?: EntityRegistryUpdate;
|
||||
|
||||
private _newScriptId?: string;
|
||||
|
||||
private _entityRegCreated?: (
|
||||
value: PromiseLike<EntityRegistryEntry> | EntityRegistryEntry
|
||||
) => void;
|
||||
|
||||
private _undoRedoController = new UndoRedoController<ScriptConfig>(this, {
|
||||
apply: (config) => this._applyUndoRedo(config),
|
||||
currentConfig: () => this._config!,
|
||||
currentConfig: () => this.config!,
|
||||
});
|
||||
|
||||
protected willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (
|
||||
this._entityRegCreated &&
|
||||
this.entityRegCreated &&
|
||||
this._newScriptId &&
|
||||
changedProps.has("entityRegistry")
|
||||
) {
|
||||
@@ -157,22 +112,22 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
entity.platform === "script" && entity.unique_id === this._newScriptId
|
||||
);
|
||||
if (script) {
|
||||
this._entityRegCreated(script);
|
||||
this._entityRegCreated = undefined;
|
||||
this.entityRegCreated(script);
|
||||
this.entityRegCreated = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | typeof nothing {
|
||||
if (!this._config) {
|
||||
return nothing;
|
||||
if (!this.config) {
|
||||
return this.renderLoading();
|
||||
}
|
||||
|
||||
const stateObj = this._entityId
|
||||
? this.hass.states[this._entityId]
|
||||
const stateObj = this.currentEntityId
|
||||
? this.hass.states[this.currentEntityId]
|
||||
: undefined;
|
||||
|
||||
const useBlueprint = "use_blueprint" in this._config;
|
||||
const useBlueprint = "use_blueprint" in this.config;
|
||||
const shortcutIcon = isMac
|
||||
? html`<ha-svg-icon .path=${mdiAppleKeyboardCommand}></ha-svg-icon>`
|
||||
: this.hass.localize("ui.panel.config.automation.editor.ctrl");
|
||||
@@ -182,11 +137,11 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.backCallback=${this._backTapped}
|
||||
.header=${this._config.alias ||
|
||||
.backCallback=${this.backTapped}
|
||||
.header=${this.config.alias ||
|
||||
this.hass.localize("ui.panel.config.script.editor.default_name")}
|
||||
>
|
||||
${this._mode === "gui" && !this.narrow
|
||||
${this.mode === "gui" && !this.narrow
|
||||
? html`<ha-icon-button
|
||||
slot="toolbar-icon"
|
||||
.label=${this.hass.localize("ui.common.undo")}
|
||||
@@ -252,7 +207,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
|
||||
${this._mode === "gui" && this.narrow
|
||||
${this.mode === "gui" && this.narrow
|
||||
? html`<ha-dropdown-item
|
||||
value="undo"
|
||||
.disabled=${!this._undoRedoController.canUndo}
|
||||
@@ -286,7 +241,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
<ha-dropdown-item .disabled=${!stateObj} value="category">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.scene.picker.${this._registryEntry?.categories?.script ? "edit_category" : "assign_category"}`
|
||||
`ui.panel.config.scene.picker.${this.registryEntry?.categories?.script ? "edit_category" : "assign_category"}`
|
||||
)}
|
||||
<ha-svg-icon slot="icon" .path=${mdiTag}></ha-svg-icon>
|
||||
</ha-dropdown-item>
|
||||
@@ -307,10 +262,10 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
></ha-svg-icon>
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
${!useBlueprint && !("fields" in this._config)
|
||||
${!useBlueprint && !("fields" in this.config)
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
.disabled=${this._readOnly || this._mode === "yaml"}
|
||||
.disabled=${this.readOnly || this.mode === "yaml"}
|
||||
value="add_fields"
|
||||
>
|
||||
${this.hass.localize(
|
||||
@@ -326,9 +281,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
<ha-dropdown-item
|
||||
value="rename"
|
||||
.disabled=${!this.scriptId ||
|
||||
this._readOnly ||
|
||||
this._mode === "yaml"}
|
||||
.disabled=${!this.scriptId || this.readOnly || this.mode === "yaml"}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.script.editor.rename")}
|
||||
<ha-svg-icon slot="icon" .path=${mdiRenameBox}></ha-svg-icon>
|
||||
@@ -337,7 +290,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
value="change_mode"
|
||||
.disabled=${this._readOnly || this._mode === "yaml"}
|
||||
.disabled=${this.readOnly || this.mode === "yaml"}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.script.editor.change_mode"
|
||||
@@ -351,12 +304,12 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
: nothing}
|
||||
|
||||
<ha-dropdown-item
|
||||
.disabled=${!!this._blueprintConfig ||
|
||||
(!this._readOnly && !this.scriptId)}
|
||||
.disabled=${!!this.blueprintConfig ||
|
||||
(!this.readOnly && !this.scriptId)}
|
||||
value="duplicate"
|
||||
>
|
||||
${this.hass.localize(
|
||||
this._readOnly
|
||||
this.readOnly
|
||||
? "ui.panel.config.script.editor.migrate"
|
||||
: "ui.panel.config.script.editor.duplicate"
|
||||
)}
|
||||
@@ -370,7 +323,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
value="take_control"
|
||||
.disabled=${this._readOnly}
|
||||
.disabled=${this.readOnly}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.script.editor.take_control"
|
||||
@@ -382,7 +335,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
<ha-dropdown-item value="toggle_yaml_mode">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.edit_${this._mode === "gui" ? "yaml" : "ui"}`
|
||||
`ui.panel.config.automation.editor.edit_${this.mode === "gui" ? "yaml" : "ui"}`
|
||||
)}
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
|
||||
</ha-dropdown-item>
|
||||
@@ -390,7 +343,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<ha-dropdown-item
|
||||
.disabled=${this._readOnly || !this.scriptId}
|
||||
.disabled=${this.readOnly || !this.scriptId}
|
||||
value="delete"
|
||||
.variant=${this.scriptId ? "danger" : "default"}
|
||||
>
|
||||
@@ -403,8 +356,8 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
</ha-svg-icon>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
<div class=${this._mode === "yaml" ? "yaml-mode" : ""}>
|
||||
${this._mode === "gui"
|
||||
<div class=${this.mode === "yaml" ? "yaml-mode" : ""}>
|
||||
${this.mode === "gui"
|
||||
? html`
|
||||
<div>
|
||||
${useBlueprint
|
||||
@@ -413,10 +366,10 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.isWide=${this.isWide}
|
||||
.config=${this._config}
|
||||
.disabled=${this._readOnly}
|
||||
.saving=${this._saving}
|
||||
.dirty=${this._dirty}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.saving=${this.saving}
|
||||
.dirty=${this.dirty}
|
||||
@value-changed=${this._valueChanged}
|
||||
@save-script=${this._handleSaveScript}
|
||||
></blueprint-script-editor>
|
||||
@@ -426,16 +379,16 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.isWide=${this.isWide}
|
||||
.config=${this._config}
|
||||
.disabled=${this._readOnly}
|
||||
.dirty=${this._dirty}
|
||||
.saving=${this._saving}
|
||||
.config=${this.config}
|
||||
.disabled=${this.readOnly}
|
||||
.dirty=${this.dirty}
|
||||
.saving=${this.saving}
|
||||
@value-changed=${this._valueChanged}
|
||||
@editor-save=${this._handleSaveScript}
|
||||
@save-script=${this._handleSaveScript}
|
||||
>
|
||||
<div class="alert-wrapper" slot="alerts">
|
||||
${this._errors || stateObj?.state === UNAVAILABLE
|
||||
${this.errors || stateObj?.state === UNAVAILABLE
|
||||
? html`<ha-alert
|
||||
alert-type="error"
|
||||
.title=${stateObj?.state === UNAVAILABLE
|
||||
@@ -444,7 +397,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
)
|
||||
: undefined}
|
||||
>
|
||||
${this._errors || this._validationErrors}
|
||||
${this.errors || this.validationErrors}
|
||||
${stateObj?.state === UNAVAILABLE
|
||||
? html`<ha-svg-icon
|
||||
slot="icon"
|
||||
@@ -453,7 +406,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
: nothing}
|
||||
</ha-alert>`
|
||||
: nothing}
|
||||
${this._blueprintConfig
|
||||
${this.blueprintConfig
|
||||
? html`<ha-alert alert-type="info">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.script.editor.confirm_take_control"
|
||||
@@ -461,21 +414,21 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
<div slot="action" style="display: flex;">
|
||||
<ha-button
|
||||
appearance="plain"
|
||||
@click=${this._takeControlSave}
|
||||
@click=${this.takeControlSave}
|
||||
>${this.hass.localize(
|
||||
"ui.common.yes"
|
||||
)}</ha-button
|
||||
>
|
||||
<ha-button
|
||||
appearance="plain"
|
||||
@click=${this._revertBlueprint}
|
||||
@click=${this.revertBlueprint}
|
||||
>${this.hass.localize(
|
||||
"ui.common.no"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>
|
||||
</ha-alert>`
|
||||
: this._readOnly
|
||||
: this.readOnly
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
dismissable
|
||||
@@ -498,11 +451,11 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
`}
|
||||
</div>
|
||||
`
|
||||
: this._mode === "yaml"
|
||||
: this.mode === "yaml"
|
||||
? html`<ha-yaml-editor
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
.readOnly=${this.readOnly}
|
||||
disable-fullscreen
|
||||
@value-changed=${this._yamlChanged}
|
||||
@editor-save=${this._handleSaveScript}
|
||||
@@ -510,9 +463,9 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
></ha-yaml-editor>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
class=${!this._readOnly && this._dirty ? "dirty" : ""}
|
||||
class=${!this.readOnly && this.dirty ? "dirty" : ""}
|
||||
.label=${this.hass.localize("ui.common.save")}
|
||||
.disabled=${this._saving}
|
||||
.disabled=${this.saving}
|
||||
extended
|
||||
@click=${this._handleSaveScript}
|
||||
>
|
||||
@@ -551,26 +504,26 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
const entity = this.entityRegistry.find(
|
||||
(ent) => ent.platform === "script" && ent.unique_id === this.scriptId
|
||||
);
|
||||
this._entityId = entity?.entity_id;
|
||||
this.currentEntityId = entity?.entity_id;
|
||||
}
|
||||
|
||||
if (changedProps.has("scriptId") && !this.scriptId && this.hass) {
|
||||
const initData = getScriptEditorInitData();
|
||||
this._dirty = !!initData;
|
||||
this.dirty = !!initData;
|
||||
const baseConfig: Partial<ScriptConfig> = {};
|
||||
if (!initData || !("use_blueprint" in initData)) {
|
||||
baseConfig.sequence = [];
|
||||
}
|
||||
this._config = {
|
||||
this.config = {
|
||||
...baseConfig,
|
||||
...initData,
|
||||
} as ScriptConfig;
|
||||
this._readOnly = false;
|
||||
this.readOnly = false;
|
||||
}
|
||||
|
||||
if (changedProps.has("entityId") && this.entityId) {
|
||||
getScriptStateConfig(this.hass, this.entityId).then((c) => {
|
||||
this._config = normalizeScriptConfig(c.config);
|
||||
this.config = normalizeScriptConfig(c.config);
|
||||
this._checkValidation();
|
||||
});
|
||||
const regEntry = this.entityRegistry.find(
|
||||
@@ -579,25 +532,25 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
if (regEntry?.unique_id) {
|
||||
this.scriptId = regEntry.unique_id;
|
||||
}
|
||||
this._entityId = this.entityId;
|
||||
this._dirty = false;
|
||||
this._readOnly = true;
|
||||
this.currentEntityId = this.entityId;
|
||||
this.dirty = false;
|
||||
this.readOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async _checkValidation() {
|
||||
this._validationErrors = undefined;
|
||||
if (!this._entityId || !this._config) {
|
||||
this.validationErrors = undefined;
|
||||
if (!this.currentEntityId || !this.config) {
|
||||
return;
|
||||
}
|
||||
const stateObj = this.hass.states[this._entityId];
|
||||
const stateObj = this.hass.states[this.currentEntityId];
|
||||
if (stateObj?.state !== UNAVAILABLE) {
|
||||
return;
|
||||
}
|
||||
const validation = await validateConfig(this.hass, {
|
||||
actions: this._config.sequence,
|
||||
actions: this.config.sequence,
|
||||
});
|
||||
this._validationErrors = (
|
||||
this.validationErrors = (
|
||||
Object.entries(validation) as Entries<typeof validation>
|
||||
).map(([key, value]) =>
|
||||
value.valid
|
||||
@@ -612,13 +565,13 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
private async _loadConfig() {
|
||||
fetchScriptFileConfig(this.hass, this.scriptId!).then(
|
||||
(config) => {
|
||||
this._dirty = false;
|
||||
this._readOnly = false;
|
||||
this._config = normalizeScriptConfig(config);
|
||||
this.dirty = false;
|
||||
this.readOnly = false;
|
||||
this.config = normalizeScriptConfig(config);
|
||||
const entity = this.entityRegistry.find(
|
||||
(ent) => ent.platform === "script" && ent.unique_id === this.scriptId
|
||||
);
|
||||
this._entityId = entity?.entity_id;
|
||||
this.currentEntityId = entity?.entity_id;
|
||||
this._checkValidation();
|
||||
},
|
||||
(resp) => {
|
||||
@@ -647,19 +600,19 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
|
||||
private _valueChanged(ev) {
|
||||
if (this._config) {
|
||||
this._undoRedoController.commit(this._config);
|
||||
if (this.config) {
|
||||
this._undoRedoController.commit(this.config);
|
||||
}
|
||||
|
||||
this._config = ev.detail.value;
|
||||
this._errors = undefined;
|
||||
this._dirty = true;
|
||||
this.config = ev.detail.value;
|
||||
this.errors = undefined;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
private async _runScript() {
|
||||
if (hasScriptFields(this.hass, this._entityId!)) {
|
||||
if (hasScriptFields(this.hass, this.currentEntityId!)) {
|
||||
showMoreInfoDialog(this, {
|
||||
entityId: this._entityId!,
|
||||
entityId: this.currentEntityId!,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -667,20 +620,13 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
await triggerScript(this.hass, this.scriptId!);
|
||||
showToast(this, {
|
||||
message: this.hass.localize("ui.notification_toast.triggered", {
|
||||
name: this._config!.alias,
|
||||
name: this.config!.alias,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
private _showSettings() {
|
||||
showMoreInfoDialog(this, {
|
||||
entityId: this._entityId!,
|
||||
view: "settings",
|
||||
});
|
||||
}
|
||||
|
||||
private _editCategory() {
|
||||
if (!this._registryEntry) {
|
||||
if (!this.registryEntry) {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.scene.picker.no_category_support"
|
||||
@@ -693,7 +639,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
showAssignCategoryDialog(this, {
|
||||
scope: "script",
|
||||
entityReg: this._registryEntry,
|
||||
entityReg: this.registryEntry,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -730,7 +676,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
private async _showTrace() {
|
||||
if (this.scriptId) {
|
||||
const result = await this._confirmUnsavedChanged();
|
||||
const result = await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
navigate(`/config/script/trace/${this.scriptId}`);
|
||||
}
|
||||
@@ -738,47 +684,47 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
|
||||
private _addFields() {
|
||||
if ("fields" in this._config!) {
|
||||
if ("fields" in this.config!) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._config) {
|
||||
this._undoRedoController.commit(this._config);
|
||||
if (this.config) {
|
||||
this._undoRedoController.commit(this.config);
|
||||
}
|
||||
|
||||
this._manualEditor?.addFields();
|
||||
this._dirty = true;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
private _preprocessYaml() {
|
||||
return this._config;
|
||||
return this.config;
|
||||
}
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this._dirty = true;
|
||||
this.dirty = true;
|
||||
if (!ev.detail.isValid) {
|
||||
this._yamlErrors = ev.detail.errorMsg;
|
||||
this.yamlErrors = ev.detail.errorMsg;
|
||||
return;
|
||||
}
|
||||
this._yamlErrors = undefined;
|
||||
this._config = ev.detail.value;
|
||||
this._errors = undefined;
|
||||
this.yamlErrors = undefined;
|
||||
this.config = ev.detail.value;
|
||||
this.errors = undefined;
|
||||
}
|
||||
|
||||
private async _confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this._dirty) {
|
||||
protected async confirmUnsavedChanged(): Promise<boolean> {
|
||||
if (!this.dirty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
showAutomationSaveDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
domain: "script",
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
|
||||
const id = this.scriptId || String(Date.now());
|
||||
@@ -794,8 +740,8 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
onDiscard: () => resolve(true),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryEntry: this._registryEntry,
|
||||
entityRegistryUpdate: this.entityRegistryUpdate,
|
||||
entityRegistryEntry: this.registryEntry,
|
||||
title: this.hass.localize(
|
||||
this.scriptId
|
||||
? "ui.panel.config.script.editor.leave.unsaved_confirm_title"
|
||||
@@ -811,15 +757,8 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
});
|
||||
}
|
||||
|
||||
private _backTapped = async () => {
|
||||
const result = await this._confirmUnsavedChanged();
|
||||
if (result) {
|
||||
afterNextRender(() => goBack("/config"));
|
||||
}
|
||||
};
|
||||
|
||||
private async _takeControl() {
|
||||
const config = this._config as BlueprintScriptConfig;
|
||||
const config = this.config as BlueprintScriptConfig;
|
||||
|
||||
try {
|
||||
const result = await substituteBlueprint(
|
||||
@@ -835,35 +774,20 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
description: config.description,
|
||||
};
|
||||
|
||||
this._blueprintConfig = config;
|
||||
this._config = newConfig;
|
||||
if (this._mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this._config);
|
||||
this.blueprintConfig = config;
|
||||
this.config = newConfig;
|
||||
if (this.mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this.config);
|
||||
}
|
||||
this._readOnly = true;
|
||||
this._errors = undefined;
|
||||
this.readOnly = true;
|
||||
this.errors = undefined;
|
||||
} catch (err: any) {
|
||||
this._errors = err.message;
|
||||
this.errors = err.message;
|
||||
}
|
||||
}
|
||||
|
||||
private _revertBlueprint() {
|
||||
this._config = this._blueprintConfig;
|
||||
if (this._mode === "yaml") {
|
||||
this.renderRoot.querySelector("ha-yaml-editor")?.setValue(this._config);
|
||||
}
|
||||
this._blueprintConfig = undefined;
|
||||
this._readOnly = false;
|
||||
}
|
||||
|
||||
private _takeControlSave() {
|
||||
this._readOnly = false;
|
||||
this._dirty = true;
|
||||
this._blueprintConfig = undefined;
|
||||
}
|
||||
|
||||
private async _duplicate() {
|
||||
const result = this._readOnly
|
||||
const result = this.readOnly
|
||||
? await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.script.picker.migrate_script"
|
||||
@@ -872,14 +796,14 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
"ui.panel.config.script.picker.migrate_script_description"
|
||||
),
|
||||
})
|
||||
: await this._confirmUnsavedChanged();
|
||||
: await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
this._entityId = undefined;
|
||||
this.currentEntityId = undefined;
|
||||
showScriptEditor({
|
||||
...this._config,
|
||||
alias: this._readOnly
|
||||
? this._config?.alias
|
||||
: `${this._config?.alias} (${this.hass.localize(
|
||||
...this.config,
|
||||
alias: this.readOnly
|
||||
? this.config?.alias
|
||||
: `${this.config?.alias} (${this.hass.localize(
|
||||
"ui.panel.config.script.picker.duplicate"
|
||||
)})`,
|
||||
});
|
||||
@@ -893,7 +817,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.script.editor.delete_confirm_text",
|
||||
{ name: this._config?.alias }
|
||||
{ name: this.config?.alias }
|
||||
),
|
||||
confirmText: this.hass!.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
@@ -907,42 +831,20 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
goBack("/config");
|
||||
}
|
||||
|
||||
private async _switchUiMode() {
|
||||
if (this._yamlErrors) {
|
||||
const result = await showConfirmationDialog(this, {
|
||||
text: html`${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.switch_ui_yaml_error"
|
||||
)}<br /><br />${this._yamlErrors}`,
|
||||
confirmText: this.hass!.localize("ui.common.continue"),
|
||||
destructive: true,
|
||||
dismissText: this.hass!.localize("ui.common.cancel"),
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._yamlErrors = undefined;
|
||||
this._mode = "gui";
|
||||
}
|
||||
|
||||
private _switchYamlMode() {
|
||||
this._mode = "yaml";
|
||||
}
|
||||
|
||||
private async _promptScriptAlias(): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
showAutomationSaveDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
domain: "script",
|
||||
updateConfig: async (config, entityRegistryUpdate) => {
|
||||
this._config = config;
|
||||
this._entityRegistryUpdate = entityRegistryUpdate;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.entityRegistryUpdate = entityRegistryUpdate;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => resolve(false),
|
||||
entityRegistryUpdate: this._entityRegistryUpdate,
|
||||
entityRegistryUpdate: this.entityRegistryUpdate,
|
||||
entityRegistryEntry: this.entityRegistry.find(
|
||||
(entry) => entry.unique_id === this.scriptId
|
||||
),
|
||||
@@ -953,10 +855,10 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
private async _promptScriptMode(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
showAutomationModeDialog(this, {
|
||||
config: this._config!,
|
||||
config: this.config!,
|
||||
updateConfig: (config) => {
|
||||
this._config = config;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
this.requestUpdate();
|
||||
resolve();
|
||||
},
|
||||
@@ -966,9 +868,9 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
|
||||
private async _handleSaveScript() {
|
||||
if (this._yamlErrors) {
|
||||
if (this.yamlErrors) {
|
||||
showToast(this, {
|
||||
message: this._yamlErrors,
|
||||
message: this.yamlErrors,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -980,9 +882,9 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
if (!saved) {
|
||||
return;
|
||||
}
|
||||
this._entityId = this._computeEntityIdFromAlias(this._config!.alias);
|
||||
this.currentEntityId = this._computeEntityIdFromAlias(this.config!.alias);
|
||||
}
|
||||
const id = this.scriptId || this._entityId || Date.now();
|
||||
const id = this.scriptId || this.currentEntityId || Date.now();
|
||||
|
||||
await this._saveScript(id);
|
||||
if (!this.scriptId) {
|
||||
@@ -991,13 +893,13 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
}
|
||||
|
||||
private async _saveScript(id): Promise<void> {
|
||||
this._saving = true;
|
||||
this.saving = true;
|
||||
|
||||
let entityRegPromise: Promise<EntityRegistryEntry> | undefined;
|
||||
if (this._entityRegistryUpdate !== undefined && !this.scriptId) {
|
||||
if (this.entityRegistryUpdate !== undefined && !this.scriptId) {
|
||||
this._newScriptId = id.toString();
|
||||
entityRegPromise = new Promise<EntityRegistryEntry>((resolve) => {
|
||||
this._entityRegCreated = resolve;
|
||||
this.entityRegCreated = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1005,11 +907,11 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
await this.hass!.callApi(
|
||||
"POST",
|
||||
"config/script/config/" + id,
|
||||
this._config
|
||||
this.config
|
||||
);
|
||||
|
||||
if (this._entityRegistryUpdate !== undefined) {
|
||||
let entityId = this._entityId;
|
||||
if (this.entityRegistryUpdate !== undefined) {
|
||||
let entityId = this.currentEntityId;
|
||||
|
||||
// wait for new script to appear in entity registry
|
||||
if (entityRegPromise) {
|
||||
@@ -1044,23 +946,23 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
if (entityId) {
|
||||
await updateEntityRegistryEntry(this.hass, entityId, {
|
||||
categories: {
|
||||
script: this._entityRegistryUpdate.category || null,
|
||||
script: this.entityRegistryUpdate.category || null,
|
||||
},
|
||||
labels: this._entityRegistryUpdate.labels || [],
|
||||
area_id: this._entityRegistryUpdate.area || null,
|
||||
labels: this.entityRegistryUpdate.labels || [],
|
||||
area_id: this.entityRegistryUpdate.area || null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._dirty = false;
|
||||
this.dirty = false;
|
||||
} catch (errors: any) {
|
||||
this._errors = errors.body?.message || errors.error || errors.body;
|
||||
this.errors = errors.body?.message || errors.error || errors.body;
|
||||
showToast(this, {
|
||||
message: errors.body?.message || errors.error || errors.body,
|
||||
});
|
||||
throw errors;
|
||||
} finally {
|
||||
this._saving = false;
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1077,14 +979,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
};
|
||||
}
|
||||
|
||||
protected get isDirty() {
|
||||
return this._dirty;
|
||||
}
|
||||
|
||||
protected async promptDiscardChanges() {
|
||||
return this._confirmUnsavedChanged();
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
private _collapseAll() {
|
||||
this._manualEditor?.collapseAll();
|
||||
@@ -1109,8 +1003,8 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
|
||||
private _applyUndoRedo(config: ScriptConfig) {
|
||||
this._manualEditor?.triggerCloseSidebar();
|
||||
this._config = config;
|
||||
this._dirty = true;
|
||||
this.config = config;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
private _undo() {
|
||||
@@ -1139,7 +1033,7 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
this._showInfo();
|
||||
break;
|
||||
case "settings":
|
||||
this._showSettings();
|
||||
this.showSettings();
|
||||
break;
|
||||
case "category":
|
||||
this._editCategory();
|
||||
@@ -1163,11 +1057,11 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
this._takeControl();
|
||||
break;
|
||||
case "toggle_yaml_mode":
|
||||
if (this._mode === "gui") {
|
||||
this._switchYamlMode();
|
||||
if (this.mode === "gui") {
|
||||
this.switchYamlMode();
|
||||
break;
|
||||
}
|
||||
this._switchUiMode();
|
||||
this.switchUiMode();
|
||||
break;
|
||||
case "delete":
|
||||
this._deleteConfirm();
|
||||
@@ -1181,19 +1075,8 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
automationScriptEditorStyles,
|
||||
css`
|
||||
:host {
|
||||
--ha-automation-editor-max-width: var(
|
||||
--ha-automation-editor-width,
|
||||
1540px
|
||||
);
|
||||
}
|
||||
.yaml-mode {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
manual-script-editor,
|
||||
blueprint-script-editor {
|
||||
margin: 0 auto;
|
||||
@@ -1244,29 +1127,9 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
ha-yaml-editor {
|
||||
flex-grow: 1;
|
||||
--actions-border-radius: var(--ha-border-radius-square);
|
||||
--code-mirror-height: 100%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
span[slot="introduction"] a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: calc(-80px - var(--safe-area-inset-bottom));
|
||||
transition: bottom 0.3s;
|
||||
}
|
||||
ha-fab.dirty {
|
||||
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
margin: 16px 0;
|
||||
@@ -1280,15 +1143,6 @@ export class HaScriptEditor extends SubscribeMixin(
|
||||
.header a {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-tooltip ha-svg-icon {
|
||||
width: 12px;
|
||||
}
|
||||
ha-tooltip .shortcut {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -239,28 +239,15 @@ export class LovelacePanel extends LitElement {
|
||||
|
||||
const newConfig = checkLovelaceConfig(generatedConfig) as LovelaceConfig;
|
||||
|
||||
// Ask to regenerate if the config changed
|
||||
// Regenerate if the config changed
|
||||
if (!deepEqual(newConfig, oldConfig)) {
|
||||
this._askRegenerateStrategyConfig();
|
||||
this._regenerateStrategyConfig();
|
||||
}
|
||||
};
|
||||
|
||||
private _strategyConfigChanged = (ev: CustomEvent) => {
|
||||
ev.stopPropagation();
|
||||
this._askRegenerateStrategyConfig();
|
||||
};
|
||||
|
||||
private _askRegenerateStrategyConfig = () => {
|
||||
showToast(this, {
|
||||
message: this.hass!.localize("ui.panel.lovelace.changed_toast.message"),
|
||||
action: {
|
||||
action: () => this._regenerateStrategyConfig(),
|
||||
text: this.hass!.localize("ui.common.refresh"),
|
||||
},
|
||||
duration: -1,
|
||||
id: "regenerate-strategy-config",
|
||||
dismissable: false,
|
||||
});
|
||||
this._regenerateStrategyConfig();
|
||||
};
|
||||
|
||||
private async _regenerateStrategyConfig() {
|
||||
@@ -313,8 +300,14 @@ export class LovelacePanel extends LitElement {
|
||||
this._fetchConfigOnConnect = true;
|
||||
return;
|
||||
}
|
||||
if (!this.lovelace?.editMode && this._panelState !== "yaml-editor") {
|
||||
this._fetchConfig(false);
|
||||
return;
|
||||
}
|
||||
showToast(this, {
|
||||
message: this.hass!.localize("ui.panel.lovelace.changed_toast.message"),
|
||||
message: this.hass!.localize(
|
||||
"ui.panel.lovelace.externally_updated_toast.message"
|
||||
),
|
||||
action: {
|
||||
action: () => this._fetchConfig(false),
|
||||
text: this.hass!.localize("ui.common.refresh"),
|
||||
|
||||
@@ -7,21 +7,20 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { array, assert, object, optional, string, type } from "superstruct";
|
||||
import { deepEqual } from "../../common/util/deep-equal";
|
||||
import "../../components/ha-button";
|
||||
import "../../components/ha-code-editor";
|
||||
import type { HaCodeEditor } from "../../components/ha-code-editor";
|
||||
import "../../components/ha-icon-button";
|
||||
import "../../components/ha-button";
|
||||
import "../../components/ha-top-app-bar-fixed";
|
||||
import type { LovelaceRawConfig } from "../../data/lovelace/config/types";
|
||||
import { isStrategyDashboard } from "../../data/lovelace/config/types";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../dialogs/generic/show-dialog-box";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { showToast } from "../../util/toast";
|
||||
import type { Lovelace } from "./types";
|
||||
import "../../components/ha-top-app-bar-fixed";
|
||||
import type { LovelaceRawConfig } from "../../data/lovelace/config/types";
|
||||
import { isStrategyDashboard } from "../../data/lovelace/config/types";
|
||||
|
||||
const lovelaceStruct = type({
|
||||
title: optional(string()),
|
||||
@@ -113,21 +112,7 @@ class LovelaceFullConfigEditor extends LitElement {
|
||||
oldLovelace.rawConfig !== this.lovelace.rawConfig &&
|
||||
!deepEqual(oldLovelace.rawConfig, this.lovelace.rawConfig)
|
||||
) {
|
||||
showToast(this, {
|
||||
message: this.hass!.localize(
|
||||
"ui.panel.lovelace.editor.raw_editor.lovelace_changed"
|
||||
),
|
||||
action: {
|
||||
action: () => {
|
||||
this.yamlEditor.value = dump(this.lovelace!.rawConfig);
|
||||
},
|
||||
text: this.hass!.localize(
|
||||
"ui.panel.lovelace.editor.raw_editor.reload"
|
||||
),
|
||||
},
|
||||
duration: -1,
|
||||
dismissable: false,
|
||||
});
|
||||
this.yamlEditor.value = dump(this.lovelace!.rawConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,24 +186,10 @@ export const haStyleDialog = css`
|
||||
var(--safe-area-inset-right, 0) var(--safe-area-inset-bottom, 0)
|
||||
var(--safe-area-inset-left, 0);
|
||||
--vertical-align-dialog: flex-end;
|
||||
}
|
||||
ha-dialog {
|
||||
--ha-dialog-border-radius: var(--ha-border-radius-square);
|
||||
ha-dialog,
|
||||
ha-adaptive-dialog {
|
||||
--mdc-dialog-min-width: 100vw;
|
||||
--mdc-dialog-max-width: 100vw;
|
||||
--mdc-dialog-min-height: 100vh;
|
||||
--mdc-dialog-min-height: 100svh;
|
||||
--mdc-dialog-max-height: 100vh;
|
||||
--mdc-dialog-max-height: 100svh;
|
||||
--dialog-container-padding: 0px;
|
||||
--dialog-surface-padding: var(--safe-area-inset-top, 0)
|
||||
var(--safe-area-inset-right, 0) var(--safe-area-inset-bottom, 0)
|
||||
var(--safe-area-inset-left, 0);
|
||||
--vertical-align-dialog: flex-end;
|
||||
}
|
||||
ha-dialog {
|
||||
--ha-dialog-border-radius: var(--ha-border-radius-square);
|
||||
}
|
||||
}
|
||||
}
|
||||
.error {
|
||||
color: var(--error-color);
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
},
|
||||
"template": {
|
||||
"yaml_warning": "It appears you may be writing YAML into this template field (saw ''{string}''), which is likely incorrect. This field is intended for templates only (e.g. '{{ states(sensor.test) > 0 }}' ).",
|
||||
"learn_more": "Learn more about templating."
|
||||
"learn_more": "Learn more about templating"
|
||||
},
|
||||
"text": {
|
||||
"show_password": "Show password",
|
||||
@@ -679,9 +679,9 @@
|
||||
"no_entities": "You don't have any entities",
|
||||
"no_match": "No entities found for {term}",
|
||||
"show_entities": "Show entities",
|
||||
"new_entity": "Create a new entity",
|
||||
"new_entity": "Creates a new entity",
|
||||
"placeholder": "Select an entity",
|
||||
"create_helper": "Create a new {domain, select, \n undefined {} \n other {{domain} }\n } helper.",
|
||||
"create_helper": "Create a new {domain, select, \n undefined {} \n other {{domain} }\n }helper",
|
||||
"unknown": "Unknown entity selected"
|
||||
},
|
||||
"entity-name-picker": {
|
||||
@@ -3812,7 +3812,7 @@
|
||||
"grid": {
|
||||
"title": "Electricity grid",
|
||||
"sub": "Configure the amount of energy that you consume from the grid and, if you produce energy, give back to the grid. This allows Home Assistant to track your whole home energy usage.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"grid_connections": "Grid connections",
|
||||
"add_connection": "Add grid connection",
|
||||
"edit_connection": "Edit grid connection",
|
||||
@@ -3873,7 +3873,7 @@
|
||||
"solar": {
|
||||
"title": "Solar panels",
|
||||
"sub": "Let Home Assistant monitor your solar panels and give you insight on their performance.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"solar_production": "Solar production",
|
||||
"edit_solar_production": "Edit solar production",
|
||||
"delete_solar_production": "Remove solar production",
|
||||
@@ -3896,7 +3896,7 @@
|
||||
"battery": {
|
||||
"title": "Home battery storage",
|
||||
"sub": "If you have a battery system, you can configure it to monitor how much energy was stored and used from your battery.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"battery_systems": "Battery systems",
|
||||
"edit_battery_system": "Edit battery system",
|
||||
"delete_battery_system": "Remove battery system",
|
||||
@@ -3923,7 +3923,7 @@
|
||||
"gas": {
|
||||
"title": "Gas consumption",
|
||||
"sub": "Let Home Assistant monitor your gas usage.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"gas_consumption": "Gas consumption",
|
||||
"edit_gas_source": "Edit gas source",
|
||||
"delete_gas_source": "Remove gas source",
|
||||
@@ -3952,7 +3952,7 @@
|
||||
"water": {
|
||||
"title": "Water consumption",
|
||||
"sub": "Let Home Assistant monitor your water usage.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"water_consumption": "Water consumption",
|
||||
"edit_water_source": "Edit water source",
|
||||
"delete_water_source": "Remove water source",
|
||||
@@ -3978,7 +3978,7 @@
|
||||
"device_consumption": {
|
||||
"title": "Individual electrical devices",
|
||||
"sub": "Tracking the energy usage of individual devices allows Home Assistant to break down your energy usage by device.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"add_stat": "Pick entity to track energy of",
|
||||
"selected_stat": "Tracking energy for",
|
||||
"devices": "Devices",
|
||||
@@ -3997,7 +3997,7 @@
|
||||
"device_consumption_water": {
|
||||
"title": "Individual water devices",
|
||||
"sub": "Tracking the water usage of individual devices allows Home Assistant to break down your water usage by device.",
|
||||
"learn_more": "More information on how to get started.",
|
||||
"learn_more": "More information on how to get started",
|
||||
"devices": "Devices",
|
||||
"add_device": "Add device",
|
||||
"dialog": {
|
||||
@@ -5749,7 +5749,7 @@
|
||||
"key_not_null": "The field key must not be empty.",
|
||||
"key_not_unique": "The field key must not be the same value as another field.",
|
||||
"fields": "Fields",
|
||||
"link_help_fields": "Learn more about fields.",
|
||||
"link_help_fields": "Learn more about fields",
|
||||
"add_fields": "Add fields",
|
||||
"add_field": "Add field",
|
||||
"field": "field",
|
||||
@@ -5777,7 +5777,7 @@
|
||||
"delete_confirm_text": "{name} will be permanently deleted.",
|
||||
"sequence": "Sequence",
|
||||
"sequence_sentence": "The sequence of actions of this script.",
|
||||
"link_available_actions": "Learn more about available actions.",
|
||||
"link_available_actions": "Learn more about available actions",
|
||||
"leave": {
|
||||
"unsaved_new_title": "Save new script?",
|
||||
"unsaved_new_text": "You can save your changes, or delete this script. You can't undo this action.",
|
||||
@@ -6050,7 +6050,7 @@
|
||||
"no_hooks_yet_link_integration": "webhook-based integration",
|
||||
"no_hooks_yet2": " or by creating a ",
|
||||
"no_hooks_yet_link_automation": "webhook automation",
|
||||
"link_learn_more": "Learn more about creating webhook-powered automations.",
|
||||
"link_learn_more": "Learn more about creating webhook-powered automations",
|
||||
"loading": "Loading…",
|
||||
"manage": "Manage",
|
||||
"disable_hook_error_msg": "Failed to disable webhook:"
|
||||
@@ -7042,7 +7042,7 @@
|
||||
"remove_node": "Remove foreign device",
|
||||
"remove_a_node": "Remove a device",
|
||||
"rebuild_network_routes": "Discover and assign new routes",
|
||||
"in_progress_inclusion_exclusion": "Z-Wave JS is searching for devices",
|
||||
"in_progress_inclusion_exclusion": "Z-Wave is searching for devices",
|
||||
"cancel_inclusion_exclusion": "Stop searching"
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -7517,7 +7517,7 @@
|
||||
"caption": "Logs",
|
||||
"title": "Z-Wave logs",
|
||||
"log_level": "Log level",
|
||||
"subscribed_to_logs": "Subscribed to Z-Wave JS log messages…",
|
||||
"subscribed_to_logs": "Subscribed to Z-Wave log messages…",
|
||||
"log_level_changed": "Log level changed to: {level}",
|
||||
"download_logs": "Download logs"
|
||||
},
|
||||
@@ -7629,7 +7629,7 @@
|
||||
},
|
||||
"picker": {
|
||||
"title": "Select Z-Wave network",
|
||||
"no_entries": "No Z-Wave networks configured. Set up the Z-Wave JS integration first."
|
||||
"no_entries": "No Z-Wave networks configured. Set up the Z-Wave integration first."
|
||||
}
|
||||
},
|
||||
"matter": {
|
||||
@@ -8353,7 +8353,6 @@
|
||||
"unsaved_changes": "Unsaved changes",
|
||||
"saved": "Saved",
|
||||
"reload": "Reload",
|
||||
"lovelace_changed": "Your dashboard was updated, do you want to load the updated config in the editor and lose your current changes?",
|
||||
"confirm_reset_config_title": "Reset dashboard configuration?",
|
||||
"confirm_reset_config_text": "Your dashboard will be reset to an empty state. You can start fresh and build your dashboard from scratch.",
|
||||
"confirm_unsaved_changes": "You have unsaved changes, are you sure you want to exit?",
|
||||
@@ -9676,8 +9675,8 @@
|
||||
"entity_unavailable": "Entity is currently unavailable: {entity}",
|
||||
"starting": "Home Assistant is starting. Not everything may be available yet."
|
||||
},
|
||||
"changed_toast": {
|
||||
"message": "Your dashboard was updated. Refresh to see changes?"
|
||||
"externally_updated_toast": {
|
||||
"message": "Dashboard updated in another session. Refreshing will discard your unsaved changes."
|
||||
},
|
||||
"components": {
|
||||
"timestamp-display": {
|
||||
|
||||
537
yarn.lock
537
yarn.lock
@@ -25,29 +25,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@asamuzakjp/css-color@npm:^4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "@asamuzakjp/css-color@npm:4.1.1"
|
||||
"@asamuzakjp/css-color@npm:^4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "@asamuzakjp/css-color@npm:4.1.2"
|
||||
dependencies:
|
||||
"@csstools/css-calc": "npm:^2.1.4"
|
||||
"@csstools/css-color-parser": "npm:^3.1.0"
|
||||
"@csstools/css-parser-algorithms": "npm:^3.0.5"
|
||||
"@csstools/css-tokenizer": "npm:^3.0.4"
|
||||
lru-cache: "npm:^11.2.4"
|
||||
checksum: 10/4b7e900d9d18a86e01a42d6140936a0373801e44854bcdd70fc7c06022b7e6a793d1960fbe9f6a65bdad1874798a30c0cd91e52bfd5eae909b3347c98cc1c4f5
|
||||
"@csstools/css-calc": "npm:^3.0.0"
|
||||
"@csstools/css-color-parser": "npm:^4.0.1"
|
||||
"@csstools/css-parser-algorithms": "npm:^4.0.0"
|
||||
"@csstools/css-tokenizer": "npm:^4.0.0"
|
||||
lru-cache: "npm:^11.2.5"
|
||||
checksum: 10/0938a4598a1d06d4db53b8aff406815f77047419eccb78f484dd26d13bd6cafaff247bc42f5493f2cb585477f461a38fba0db3c7a407ba9f281d27bc0d8f1983
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@asamuzakjp/dom-selector@npm:^6.7.6":
|
||||
version: 6.7.6
|
||||
resolution: "@asamuzakjp/dom-selector@npm:6.7.6"
|
||||
"@asamuzakjp/dom-selector@npm:^6.8.1":
|
||||
version: 6.8.1
|
||||
resolution: "@asamuzakjp/dom-selector@npm:6.8.1"
|
||||
dependencies:
|
||||
"@asamuzakjp/nwsapi": "npm:^2.3.9"
|
||||
bidi-js: "npm:^1.0.3"
|
||||
css-tree: "npm:^3.1.0"
|
||||
is-potential-custom-element-name: "npm:^1.0.1"
|
||||
lru-cache: "npm:^11.2.4"
|
||||
checksum: 10/91a479f5f59a3b1b23f46407d874882c05b50e72316e57af105c88603fb1008120c46c7fe7504c5be556ea4c9a68ee10aee43433bd8d34f000b9aaf6dcae4d5c
|
||||
lru-cache: "npm:^11.2.6"
|
||||
checksum: 10/4d1c63bf094aa35c9c60ad8d2faf45ee4f5f8d1520fbb158e2552c456f8264029932ff4464ea18ea760a89b3075b4bf70e43b2086191d256f35eff46fde3eb24
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1204,6 +1204,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@bramus/specificity@npm:^2.4.2":
|
||||
version: 2.4.2
|
||||
resolution: "@bramus/specificity@npm:2.4.2"
|
||||
dependencies:
|
||||
css-tree: "npm:^3.0.0"
|
||||
bin:
|
||||
specificity: bin/cli.js
|
||||
checksum: 10/4255ed6ff12f7db9ec3c21acfd0da2327d30ec29deb199345810cdcad992618f40039c5483eefeb665913bffbc80b690e9f1b954fbbbfa93480c6a22f9c3a69c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@bundle-stats/plugin-webpack-filter@npm:4.21.10":
|
||||
version: 4.21.10
|
||||
resolution: "@bundle-stats/plugin-webpack-filter@npm:4.21.10"
|
||||
@@ -1239,9 +1250,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/language@npm:6.12.1, @codemirror/language@npm:^6.0.0":
|
||||
version: 6.12.1
|
||||
resolution: "@codemirror/language@npm:6.12.1"
|
||||
"@codemirror/language@npm:6.12.2, @codemirror/language@npm:^6.0.0":
|
||||
version: 6.12.2
|
||||
resolution: "@codemirror/language@npm:6.12.2"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.23.0"
|
||||
@@ -1249,7 +1260,7 @@ __metadata:
|
||||
"@lezer/highlight": "npm:^1.0.0"
|
||||
"@lezer/lr": "npm:^1.0.0"
|
||||
style-mod: "npm:^4.0.0"
|
||||
checksum: 10/a24c3512d38cbb2a20cc3128da0eea074b4a6102b6a5a041b3dfd5e67638fb61dcdf4743ed87708db882df5d72a84d9f891aac6fa68447830989c8e2d9ffa2ba
|
||||
checksum: 10/9afc704e17cad4782b68ad02869503a27103c4c3ac6927d2ffa3c6decfad627ade40b0ed78d1d6e941b2e879a7a79bda0d573e58604f3923f9e1f3311108ec36
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1294,56 +1305,56 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/color-helpers@npm:^5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "@csstools/color-helpers@npm:5.1.0"
|
||||
checksum: 10/0138b3d5ccbe77aeccf6721fd008a53523c70e932f0c82dca24a1277ca780447e1d8357da47512ebf96358476f8764de57002f3e491920d67e69202f5a74c383
|
||||
"@csstools/color-helpers@npm:^6.0.2":
|
||||
version: 6.0.2
|
||||
resolution: "@csstools/color-helpers@npm:6.0.2"
|
||||
checksum: 10/c47a943e947d76980d0e1071027cb70481ac481968e744a05a7aea7ede9886f10d062b2e3691e03c115d97b053d4140c1ca28e24c1ffe2d21693e126de6522e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-calc@npm:^2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@csstools/css-calc@npm:2.1.4"
|
||||
"@csstools/css-calc@npm:^3.0.0, @csstools/css-calc@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "@csstools/css-calc@npm:3.1.1"
|
||||
peerDependencies:
|
||||
"@csstools/css-parser-algorithms": ^3.0.5
|
||||
"@csstools/css-tokenizer": ^3.0.4
|
||||
checksum: 10/06975b650c0f44c60eeb7afdb3fd236f2dd607b2c622e0bc908d3f54de39eb84e0692833320d03dac04bd6c1ab0154aa3fa0dd442bd9e5f917cf14d8e2ba8d74
|
||||
"@csstools/css-parser-algorithms": ^4.0.0
|
||||
"@csstools/css-tokenizer": ^4.0.0
|
||||
checksum: 10/faa3aa2736b20757ceafd76e3d2841e8726ec9e7ae78e387684eb462aba73d533ba384039338685c3a52196196300ccdfecb051e59864b1d3b457fe927b7f53b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-color-parser@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "@csstools/css-color-parser@npm:3.1.0"
|
||||
"@csstools/css-color-parser@npm:^4.0.1":
|
||||
version: 4.0.2
|
||||
resolution: "@csstools/css-color-parser@npm:4.0.2"
|
||||
dependencies:
|
||||
"@csstools/color-helpers": "npm:^5.1.0"
|
||||
"@csstools/css-calc": "npm:^2.1.4"
|
||||
"@csstools/color-helpers": "npm:^6.0.2"
|
||||
"@csstools/css-calc": "npm:^3.1.1"
|
||||
peerDependencies:
|
||||
"@csstools/css-parser-algorithms": ^3.0.5
|
||||
"@csstools/css-tokenizer": ^3.0.4
|
||||
checksum: 10/4741095fdc4501e8e7ada4ed14fbf9dbbe6fea9b989818790ebca15657c29c62defbebacf18592cde2aa638a1d098bbe86d742d2c84ba932fbc00fac51cb8805
|
||||
"@csstools/css-parser-algorithms": ^4.0.0
|
||||
"@csstools/css-tokenizer": ^4.0.0
|
||||
checksum: 10/6418bfadc8c15d3a65c1e80278df383b542f0437446c0ba21d591dd564bcc19ab0b11243edf62672f4c62cc778f9b386fa4349e9a8d1de2b414148ea8a1ac775
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-parser-algorithms@npm:^3.0.5":
|
||||
version: 3.0.5
|
||||
resolution: "@csstools/css-parser-algorithms@npm:3.0.5"
|
||||
"@csstools/css-parser-algorithms@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@csstools/css-parser-algorithms@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@csstools/css-tokenizer": ^3.0.4
|
||||
checksum: 10/e93083b5cb36a3c1e7a47ce10cf62961d05bd1e4c608bb3ee50186ff740157ab0ec16a3956f7b86251efd10703034d849693201eea858ae904848c68d2d46ada
|
||||
"@csstools/css-tokenizer": ^4.0.0
|
||||
checksum: 10/000f3ba55f440d9fbece50714e88f9d4479e2bde9e0568333492663f2c6034dc31d0b9ef5d66d196c76be58eea145ca6920aa8bdfdcc6361894806c21b5402d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-syntax-patches-for-csstree@npm:^1.0.21":
|
||||
version: 1.0.25
|
||||
resolution: "@csstools/css-syntax-patches-for-csstree@npm:1.0.25"
|
||||
checksum: 10/42dfcd164ed6a66eee8dd3fcdbdaa58d032ab8c3bb5ead2453915429367766879b25332e09379a67357fd33742b856160e7c0182c7d90be00f57571b916c18e7
|
||||
"@csstools/css-syntax-patches-for-csstree@npm:^1.0.26":
|
||||
version: 1.0.28
|
||||
resolution: "@csstools/css-syntax-patches-for-csstree@npm:1.0.28"
|
||||
checksum: 10/b7b393a4285b2d91aec71ef714ebe356f6607d6358e025306eaf567bd7bbd201e3a5d1f0a8d3cd9063b3dd40bbdbfd6664b4c658c2bca45c4c1b122a54a0804e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/css-tokenizer@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "@csstools/css-tokenizer@npm:3.0.4"
|
||||
checksum: 10/eb6c84c086312f6bb8758dfe2c85addd7475b0927333c5e39a4d59fb210b9810f8c346972046f95e60a721329cffe98895abe451e51de753ad1ca7a8c24ec65f
|
||||
"@csstools/css-tokenizer@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@csstools/css-tokenizer@npm:4.0.0"
|
||||
checksum: 10/074ade1a7fc3410b813c8982cf07a56814a55af509c533c2dc80d5689f34d2ba38219f8fa78fa36ea2adc6c5db506ea3c3a667388dda1b59b1281fdd2a2d1e28
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1962,9 +1973,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@home-assistant/webawesome@npm:3.2.1-ha.2":
|
||||
version: 3.2.1-ha.2
|
||||
resolution: "@home-assistant/webawesome@npm:3.2.1-ha.2"
|
||||
"@home-assistant/webawesome@npm:3.2.1-ha.3":
|
||||
version: 3.2.1-ha.3
|
||||
resolution: "@home-assistant/webawesome@npm:3.2.1-ha.3"
|
||||
dependencies:
|
||||
"@ctrl/tinycolor": "npm:4.1.0"
|
||||
"@floating-ui/dom": "npm:^1.6.13"
|
||||
@@ -1975,78 +1986,80 @@ __metadata:
|
||||
lit: "npm:^3.2.1"
|
||||
nanoid: "npm:^5.1.5"
|
||||
qr-creator: "npm:^1.0.0"
|
||||
checksum: 10/36f15a10760fe4c13c9551e4440d9ad395c894d6f3735494da2032948fae052056ea6e762fbfa3b2e7e0cb94a8d1e214bb73478e682813cb3ed9c44b2daec98d
|
||||
checksum: 10/e5182d4ce11ed6a0b17e6da7783f0dea20dc743593b9873cbfcaf26425a78383e9f90dbb152618b96422ea37be6fb8ff09aa9903b012d5fe0ab5ebc0570154a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/core@npm:^0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/core@npm:0.56.0"
|
||||
"@html-eslint/core@npm:^0.57.0":
|
||||
version: 0.57.0
|
||||
resolution: "@html-eslint/core@npm:0.57.0"
|
||||
dependencies:
|
||||
"@html-eslint/types": "npm:^0.56.0"
|
||||
"@html-eslint/types": "npm:^0.57.0"
|
||||
eslint: "npm:^9.39.1"
|
||||
html-standard: "npm:^0.0.13"
|
||||
checksum: 10/0722e7405e56b256c471229dbd0ccb49cf0edd3e5224a087240f1954c74af0a6f289e5be0b83957480f1fa5abf6f7cbad7212134a6872a3fd66e1dc1ad879d66
|
||||
checksum: 10/18b7aaf455969008dc5b79f6fd4b38792d893053e77c098c56a9238fe9b3ac3fa36441a88b908ade71de2f5179d5b4c45f552d7da5beff1d5c8df9cb3fd14e63
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/eslint-plugin@npm:0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/eslint-plugin@npm:0.56.0"
|
||||
"@html-eslint/eslint-plugin@npm:0.57.1":
|
||||
version: 0.57.1
|
||||
resolution: "@html-eslint/eslint-plugin@npm:0.57.1"
|
||||
dependencies:
|
||||
"@eslint/plugin-kit": "npm:^0.4.1"
|
||||
"@html-eslint/core": "npm:^0.56.0"
|
||||
"@html-eslint/parser": "npm:^0.56.0"
|
||||
"@html-eslint/template-parser": "npm:^0.56.0"
|
||||
"@html-eslint/template-syntax-parser": "npm:^0.56.0"
|
||||
"@html-eslint/types": "npm:^0.56.0"
|
||||
"@html-eslint/core": "npm:^0.57.0"
|
||||
"@html-eslint/parser": "npm:^0.57.1"
|
||||
"@html-eslint/template-parser": "npm:^0.57.0"
|
||||
"@html-eslint/template-syntax-parser": "npm:^0.57.0"
|
||||
"@html-eslint/types": "npm:^0.57.0"
|
||||
"@rviscomi/capo.js": "npm:^2.1.0"
|
||||
html-standard: "npm:^0.0.13"
|
||||
peerDependencies:
|
||||
eslint: ">=8.0.0 || ^10.0.0-0"
|
||||
checksum: 10/16c5d638045266ca201b5dc154b3706262801668b2edde4f0905bdba9ba2e14b7175eacf9ca7d2ad5a5a03e3369843822d34ee607b6b7fbbeb020ac7f87629fb
|
||||
checksum: 10/21a923a1ee8efb02f01c015345a23b38cd0a9e98c4f3fa07d79afe1f8e9f26651e0a9d6983b2f9cfae76be71c14f3224fd64433612535c1e04e3c9b440e46245
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/parser@npm:^0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/parser@npm:0.56.0"
|
||||
"@html-eslint/parser@npm:^0.57.1":
|
||||
version: 0.57.1
|
||||
resolution: "@html-eslint/parser@npm:0.57.1"
|
||||
dependencies:
|
||||
"@eslint/css-tree": "npm:^3.6.9"
|
||||
"@html-eslint/template-syntax-parser": "npm:^0.56.0"
|
||||
"@html-eslint/types": "npm:^0.56.0"
|
||||
"@html-eslint/template-syntax-parser": "npm:^0.57.0"
|
||||
"@html-eslint/types": "npm:^0.57.0"
|
||||
css-tree: "npm:^3.1.0"
|
||||
es-html-parser: "npm:0.3.1"
|
||||
checksum: 10/1fead2be97481f461ee7030f4ea9274e5f969540118b4429e3eea361f62138660c1b7538668c7f8d55a8ae6985deff3056968d71bae62b91fb001d4209a24b50
|
||||
checksum: 10/3e148f0bf83600e5b931938dc02d01e805c275b0534fad0adc8ac68ceb37220896c007b1d33ebc4347cb59ab35d1cc3c57207ff798f08d2327d92abf1c88e72b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/template-parser@npm:^0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/template-parser@npm:0.56.0"
|
||||
"@html-eslint/template-parser@npm:^0.57.0":
|
||||
version: 0.57.0
|
||||
resolution: "@html-eslint/template-parser@npm:0.57.0"
|
||||
dependencies:
|
||||
"@html-eslint/types": "npm:^0.56.0"
|
||||
"@html-eslint/types": "npm:^0.57.0"
|
||||
es-html-parser: "npm:0.3.1"
|
||||
checksum: 10/45e41dc8fb46336f40d1b78ef55ee3150d7a1034d393529eb40ce37a7d0a8fa04f6ed8f9a63478ff884d9588b1359b97a799681a37cd485d237dce867b7f9d20
|
||||
checksum: 10/160d7f6156f242ed7bd4e7f13d79c350bf5db7fef089ba7b404ef770d80547620e9ee860ead8892a4079668db1cdccf6a6c6b91183a8c478a634314b39efea32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/template-syntax-parser@npm:^0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/template-syntax-parser@npm:0.56.0"
|
||||
"@html-eslint/template-syntax-parser@npm:^0.57.0":
|
||||
version: 0.57.0
|
||||
resolution: "@html-eslint/template-syntax-parser@npm:0.57.0"
|
||||
dependencies:
|
||||
"@html-eslint/types": "npm:^0.56.0"
|
||||
checksum: 10/2cc4f2cbfa58c6381b2542ca86e424a97429326aa0b8b6b09e0a51d27b0e26fd723a4550e4c17536e00cfd506cbd0c61d8fd3dff1c829714c4432406096b4a01
|
||||
"@html-eslint/types": "npm:^0.57.0"
|
||||
checksum: 10/147d8d15ebc5ea9b75eea04463b9f29cfc476be2e98c5a2129442be6f66d32a9e8bb11a1be13cc3778df25e14d7ed1cd345342951ecec05292545f64bb3d92c6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@html-eslint/types@npm:^0.56.0":
|
||||
version: 0.56.0
|
||||
resolution: "@html-eslint/types@npm:0.56.0"
|
||||
"@html-eslint/types@npm:^0.57.0":
|
||||
version: 0.57.0
|
||||
resolution: "@html-eslint/types@npm:0.57.0"
|
||||
dependencies:
|
||||
"@types/css-tree": "npm:^2.3.11"
|
||||
"@types/estree": "npm:^1.0.6"
|
||||
es-html-parser: "npm:0.3.1"
|
||||
eslint: "npm:^9.39.1"
|
||||
checksum: 10/5359ccfb8f431ccedfe7d9c0b20d883d19bbb6a24eee925c036c7774d6f2177eda021826abbc6f947b59c2364d7cf25a596591e852c1141000a3fab6ea70acc9
|
||||
checksum: 10/44d0bde592786a2da966beab13c3d543e6669b1e38b6e5feea0f01121eec928be0081969df3ada1f27c9bd43d6286596afa56a2e075da843251079a940cf0825
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -4246,6 +4259,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rviscomi/capo.js@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "@rviscomi/capo.js@npm:2.1.0"
|
||||
checksum: 10/83ce30106ec6bd4b4791af12556119c568cb9d0ec7550b7b015a8c2c1c49687d8c6605564415d9d85e991581958212109ee5caa0db4166c1d3628033175e80b8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@shoelace-style/animations@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "@shoelace-style/animations@npm:1.2.0"
|
||||
@@ -4321,12 +4341,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/helpers@npm:0.5.18":
|
||||
version: 0.5.18
|
||||
resolution: "@swc/helpers@npm:0.5.18"
|
||||
"@swc/helpers@npm:0.5.19":
|
||||
version: 0.5.19
|
||||
resolution: "@swc/helpers@npm:0.5.19"
|
||||
dependencies:
|
||||
tslib: "npm:^2.8.0"
|
||||
checksum: 10/03c7efa3e62d965fddd0baea98ee7a4c3ba7fa58187f07f26ec8d86740572f5ffd6f7517578a1d3201f64c85399be1538eba4dd30cef79d073060ecb101d753c
|
||||
checksum: 10/3fd365fb3265f97e1241bcbcea9bfa5e15e03c630424e1b54597e00d30be2c271cb0c74f45e1739c6bc5ae892647302fab412de5138941aa96e66aebf4586700
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5013,13 +5033,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/tar@npm:6.1.13":
|
||||
version: 6.1.13
|
||||
resolution: "@types/tar@npm:6.1.13"
|
||||
"@types/tar@npm:7.0.87":
|
||||
version: 7.0.87
|
||||
resolution: "@types/tar@npm:7.0.87"
|
||||
dependencies:
|
||||
"@types/node": "npm:*"
|
||||
minipass: "npm:^4.0.0"
|
||||
checksum: 10/d325223cf90399fd03f366d0eabe2383e75e550b3e40a006d5f062d006b894a475cd7c0968d258a8eb8eae5df30b6e7f4607d493a474f89134bbff65362b77ed
|
||||
tar: "npm:*"
|
||||
checksum: 10/f53a63d49d1775928a60afee5524c8d58052cf0896c0e051461f4faf4131caa0cec1d2e3d711374d91d55a59de3e898c43243e5026e5faca9436b69cb5e414b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5053,138 +5072,138 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.54.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.56.1"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.12.2"
|
||||
"@typescript-eslint/scope-manager": "npm:8.54.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.54.0"
|
||||
"@typescript-eslint/utils": "npm:8.54.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.54.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.56.1"
|
||||
"@typescript-eslint/type-utils": "npm:8.56.1"
|
||||
"@typescript-eslint/utils": "npm:8.56.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.56.1"
|
||||
ignore: "npm:^7.0.5"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
ts-api-utils: "npm:^2.4.0"
|
||||
peerDependencies:
|
||||
"@typescript-eslint/parser": ^8.54.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
"@typescript-eslint/parser": ^8.56.1
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/8f1c74ac77d7a84ae3f201bb09cb67271662befed036266af1eaa0653d09b545353441640516c1c86e0a94939887d32f0473c61a642488b14d46533742bfbd1b
|
||||
checksum: 10/669d19cff91fcad5fe34dba97cc8c0c2df3160ae14646759fb23dfd6ffbb861d00d8d081e74d1060d544bfba0ea4d05588c5b73ae104907af26cc18189c0d139
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.54.0"
|
||||
"@typescript-eslint/parser@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/parser@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:8.54.0"
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.54.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.54.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.56.1"
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.56.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.56.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/d2e09462c9966ef3deeba71d9e41d1d4876c61eea65888c93a3db6fba48b89a2165459c6519741d40e969da05ed98d3f4c87a7f56c5521ab5699743cc315f6cb
|
||||
checksum: 10/280b041a69153caf9e721b307781830483dd39d881b02d993156635bd8600e30e6a816aaead8bdd662ae5149b8870aef7b3823d3b98ec974d924c23a786fb6d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/project-service@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/project-service@npm:8.54.0"
|
||||
"@typescript-eslint/project-service@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/project-service@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.54.0"
|
||||
"@typescript-eslint/types": "npm:^8.54.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.56.1"
|
||||
"@typescript-eslint/types": "npm:^8.56.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/93f0483f6bbcf7cf776a53a130f7606f597fba67cf111e1897873bf1531efaa96e4851cfd461da0f0cc93afbdb51e47bcce11cf7dd4fb68b7030c7f9f240b92f
|
||||
checksum: 10/5e7fdc95aebcefc72fec77806bb0821a9a59e5e88f86d72b15ad011eb6110da05419b803875f021716a219fc7fb8517331a6736364344c8613a90209539a6d32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.54.0"
|
||||
"@typescript-eslint/scope-manager@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.54.0"
|
||||
checksum: 10/3474f3197e8647754393dee62b3145c9de71eaa66c8a68f61c8283aa332141803885db9c96caa6a51f78128ad9ef92f774a90361655e57bd951d5b57eb76f914
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.56.1"
|
||||
checksum: 10/f358cf8bd32952eed005d4f34c1e95805baefe35abee96d866222b0eff8027cc02f831cee04b308707d74db2b415437a134191207b4213ee8acbc6d67a435616
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.54.0, @typescript-eslint/tsconfig-utils@npm:^8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.54.0"
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.56.1, @typescript-eslint/tsconfig-utils@npm:^8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.56.1"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/e9d6b29538716f007919bfcee94f09b7f8e7d2b684ad43d1a3c8d43afb9f0539c7707f84a34f42054e31c8c056b0ccf06575d89e860b4d34632ffefaefafe1fc
|
||||
checksum: 10/d509f1ae4b14969173e498db6d15c833b6407db456c7fca9e25396798a35014229a73754691f353c4a99f5f0bbb4535b4144f42f84e596645a16d88a2022135f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.54.0"
|
||||
"@typescript-eslint/type-utils@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.54.0"
|
||||
"@typescript-eslint/utils": "npm:8.54.0"
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.56.1"
|
||||
"@typescript-eslint/utils": "npm:8.56.1"
|
||||
debug: "npm:^4.4.3"
|
||||
ts-api-utils: "npm:^2.4.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/60e92fb32274abd70165ce6f4187e4cffa55416374c63731d7de8fdcfb7a558b4dd48909ff1ad38ac39d2ea1248ec54d6ce38dbc065fd34529a217fc2450d5b1
|
||||
checksum: 10/2b07c674c26d797d05c05779ac5c89761b6b96680ecaf01440957727d12c6d06a2e48f0b139e45752eb4b53bf13c03940628656c519d362082b716d6a0ece6d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:8.54.0, @typescript-eslint/types@npm:^8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/types@npm:8.54.0"
|
||||
checksum: 10/c25cc0bdf90fb150cf6ce498897f43fe3adf9e872562159118f34bd91a9bfab5f720cb1a41f3cdf253b2e840145d7d372089b7cef5156624ef31e98d34f91b31
|
||||
"@typescript-eslint/types@npm:8.56.1, @typescript-eslint/types@npm:^8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/types@npm:8.56.1"
|
||||
checksum: 10/4bcffab5b0fd48adb731fcade86a776ca4a66e229defa5a282b58ba9c95af16ffc459a7d188e27c988a35be1f6fb5b812f9cf0952692eac38d5b3e87daafb20a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.54.0"
|
||||
"@typescript-eslint/typescript-estree@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/project-service": "npm:8.54.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.54.0"
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.54.0"
|
||||
"@typescript-eslint/project-service": "npm:8.56.1"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.56.1"
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.56.1"
|
||||
debug: "npm:^4.4.3"
|
||||
minimatch: "npm:^9.0.5"
|
||||
minimatch: "npm:^10.2.2"
|
||||
semver: "npm:^7.7.3"
|
||||
tinyglobby: "npm:^0.2.15"
|
||||
ts-api-utils: "npm:^2.4.0"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/3a545037c6f9319251d3ba44cf7a3216b1372422469e27f7ed3415244ebf42553da1ab4644da42d3f0ae2706a8cad12529ffebcb2e75406f74e3b30b812d010d
|
||||
checksum: 10/af39dae0a8fada72295a11f0efb49f311241134b0a3d819100eeda6a2f92368844645873ba785de5513ad541cd9c2ba17b9bfed2679daac4682fa2a3b627f087
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.54.0"
|
||||
"@typescript-eslint/utils@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/utils@npm:8.56.1"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.9.1"
|
||||
"@typescript-eslint/scope-manager": "npm:8.54.0"
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.54.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.56.1"
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.56.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/9f88a2a7ab3e11aa0ff7f99c0e66a0cf2cba10b640def4c64a4f4ef427fecfb22f28dbe5697535915eb01f6507515ac43e45e0ff384bf82856e3420194d9ffdd
|
||||
checksum: 10/528cbd187d8288a8cfce24a043f993b93711087f53d2b6f95cdd615a1a4087af1dab083a747761af97474a621c7b14f11c84ee50c250f31566ebc64cf73867fe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.54.0"
|
||||
"@typescript-eslint/visitor-keys@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.54.0"
|
||||
eslint-visitor-keys: "npm:^4.2.1"
|
||||
checksum: 10/cca5380ee30250302ee1459e5a0a38de8c16213026dbbff3d167fa7d71d012f31d60ac4483ad45ebd13f2ac963d1ca52dd5f22759a68d4ee57626e421769187a
|
||||
"@typescript-eslint/types": "npm:8.56.1"
|
||||
eslint-visitor-keys: "npm:^5.0.0"
|
||||
checksum: 10/efed6a9867e7be203eec543e5a65da5aaec96aae55fba6fe74a305bf600e57c707764835e82bb8eb541f49a9b70442ff1e1a0ecf3543c78c91b84dda43b95c53
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6068,12 +6087,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"barcode-detector@npm:3.0.8":
|
||||
version: 3.0.8
|
||||
resolution: "barcode-detector@npm:3.0.8"
|
||||
"barcode-detector@npm:3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "barcode-detector@npm:3.1.0"
|
||||
dependencies:
|
||||
zxing-wasm: "npm:2.2.4"
|
||||
checksum: 10/7de6225f659c69a0f4101d080a9e0812f2404c485fa2406424b8b13eaff274f6e7405c94de24827a09def52c32a63b19b9c9fba61c5274b074d558f696ec1684
|
||||
zxing-wasm: "npm:3.0.0"
|
||||
checksum: 10/60767161081b827e290b60bb3416999dee616bab39291ee55565df9b72d59f0bbbf511fd3bb85db18eee7c0ad9acf1ff90359cdb21e10f80793acd0105c86a1d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6924,7 +6943,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-tree@npm:^3.1.0":
|
||||
"css-tree@npm:^3.0.0, css-tree@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "css-tree@npm:3.1.0"
|
||||
dependencies:
|
||||
@@ -6941,15 +6960,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cssstyle@npm:^5.3.7":
|
||||
version: 5.3.7
|
||||
resolution: "cssstyle@npm:5.3.7"
|
||||
"cssstyle@npm:^6.0.1":
|
||||
version: 6.0.2
|
||||
resolution: "cssstyle@npm:6.0.2"
|
||||
dependencies:
|
||||
"@asamuzakjp/css-color": "npm:^4.1.1"
|
||||
"@csstools/css-syntax-patches-for-csstree": "npm:^1.0.21"
|
||||
"@asamuzakjp/css-color": "npm:^4.1.2"
|
||||
"@csstools/css-syntax-patches-for-csstree": "npm:^1.0.26"
|
||||
css-tree: "npm:^3.1.0"
|
||||
lru-cache: "npm:^11.2.4"
|
||||
checksum: 10/bd4469af81f068537dbbce53c4247f192e91202c19abc066b77b4ee7bbf256526bc82471198bec762ac70ea53ce17b8044aec69fd7982d2d0fd9fd7780329e2d
|
||||
lru-cache: "npm:^11.2.5"
|
||||
checksum: 10/88f102b618d1b86fba9fe967f5252fde090f8eea45f5f46bfbedd61a4839bc1dab85287ffc14e912af0f9a80a86c904654b9f6c04c09521aa147d70b1b9b5917
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7134,7 +7153,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"defaults@npm:^1.0.3, defaults@npm:^1.0.4":
|
||||
"defaults@npm:^1.0.3":
|
||||
version: 1.0.4
|
||||
resolution: "defaults@npm:1.0.4"
|
||||
dependencies:
|
||||
@@ -7976,15 +7995,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-wc@npm:3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "eslint-plugin-wc@npm:3.0.2"
|
||||
"eslint-plugin-wc@npm:3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "eslint-plugin-wc@npm:3.1.0"
|
||||
dependencies:
|
||||
is-valid-element-name: "npm:^1.0.0"
|
||||
js-levenshtein-esm: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
eslint: ">=8.40.0"
|
||||
checksum: 10/488d8cbfb57c8845ff82358a7b5c1b2b6a670f2638ad577cdfb4ebf4270783624b6754c75223f0cec5fe1bf3273b62b1837e1bef1435c4376b14f1ec709b838e
|
||||
checksum: 10/00797dcbf3f50d88ce1036555bc8940d7796015a77c2a5e9953638ae9d847f8a81027342232909924f46a1b834be957ed5e08168932482b9c21e6a0ef02f7543
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8019,6 +8038,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-visitor-keys@npm:^5.0.0":
|
||||
version: 5.0.1
|
||||
resolution: "eslint-visitor-keys@npm:5.0.1"
|
||||
checksum: 10/f9cc1a57b75e0ef949545cac33d01e8367e302de4c1483266ed4d8646ee5c306376660196bbb38b004e767b7043d1e661cb4336b49eff634a1bbe75c1db709ec
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint@npm:9.39.3, eslint@npm:^9.39.1":
|
||||
version: 9.39.3
|
||||
resolution: "eslint@npm:9.39.3"
|
||||
@@ -8281,7 +8307,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fancy-log@npm:2.0.0, fancy-log@npm:^2.0.0":
|
||||
"fancy-log@npm:2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "fancy-log@npm:2.0.0"
|
||||
dependencies:
|
||||
@@ -9014,18 +9040,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"gulp-zopfli-green@npm:6.0.2":
|
||||
version: 6.0.2
|
||||
resolution: "gulp-zopfli-green@npm:6.0.2"
|
||||
"gulp-zopfli-green@npm:7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "gulp-zopfli-green@npm:7.0.0"
|
||||
dependencies:
|
||||
"@gfx/zopfli": "npm:^1.0.15"
|
||||
bytes: "npm:^3.1.2"
|
||||
defaults: "npm:^1.0.4"
|
||||
fancy-log: "npm:^2.0.0"
|
||||
plugin-error: "npm:^2.0.1"
|
||||
stream-to-array: "npm:^2.3.0"
|
||||
through2: "npm:^4.0.2"
|
||||
checksum: 10/52e899dfb86777ff8f97a23af99c59e203ea485fbf04d0a8f4f1cfbd4d4c496808a3593ae8dac16584fc4b4d81cf127b2eda5355a61bcc213875c95cc86d41da
|
||||
checksum: 10/25db42b9a8f6395847e3cc06c548c3f3d51c84606166f18de71d91d505e7293176b45b4b78b7e0b1566c26263fe0dc212e56d2b367461c3d712bee9d22d5224f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9152,7 +9176,7 @@ __metadata:
|
||||
"@bundle-stats/plugin-webpack-filter": "npm:4.21.10"
|
||||
"@codemirror/autocomplete": "npm:6.20.0"
|
||||
"@codemirror/commands": "npm:6.10.2"
|
||||
"@codemirror/language": "npm:6.12.1"
|
||||
"@codemirror/language": "npm:6.12.2"
|
||||
"@codemirror/legacy-modes": "npm:6.5.2"
|
||||
"@codemirror/search": "npm:6.6.0"
|
||||
"@codemirror/state": "npm:6.5.4"
|
||||
@@ -9174,8 +9198,8 @@ __metadata:
|
||||
"@fullcalendar/list": "npm:6.1.20"
|
||||
"@fullcalendar/luxon3": "npm:6.1.20"
|
||||
"@fullcalendar/timegrid": "npm:6.1.20"
|
||||
"@home-assistant/webawesome": "npm:3.2.1-ha.2"
|
||||
"@html-eslint/eslint-plugin": "npm:0.56.0"
|
||||
"@home-assistant/webawesome": "npm:3.2.1-ha.3"
|
||||
"@html-eslint/eslint-plugin": "npm:0.57.1"
|
||||
"@lezer/highlight": "npm:1.2.3"
|
||||
"@lit-labs/motion": "npm:1.1.0"
|
||||
"@lit-labs/observers": "npm:2.1.0"
|
||||
@@ -9213,7 +9237,7 @@ __metadata:
|
||||
"@rsdoctor/rspack-plugin": "npm:1.5.2"
|
||||
"@rspack/core": "npm:1.7.6"
|
||||
"@rspack/dev-server": "npm:1.2.1"
|
||||
"@swc/helpers": "npm:0.5.18"
|
||||
"@swc/helpers": "npm:0.5.19"
|
||||
"@thomasloven/round-slider": "npm:0.6.0"
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
"@tsparticles/preset-links": "npm:3.2.0"
|
||||
@@ -9232,7 +9256,7 @@ __metadata:
|
||||
"@types/mocha": "npm:10.0.10"
|
||||
"@types/qrcode": "npm:1.5.6"
|
||||
"@types/sortablejs": "npm:1.15.9"
|
||||
"@types/tar": "npm:6.1.13"
|
||||
"@types/tar": "npm:7.0.87"
|
||||
"@types/ua-parser-js": "npm:0.7.39"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@vibrant/color": "npm:4.0.4"
|
||||
@@ -9243,7 +9267,7 @@ __metadata:
|
||||
app-datepicker: "npm:5.1.1"
|
||||
babel-loader: "npm:10.0.0"
|
||||
babel-plugin-template-html-minifier: "npm:4.1.0"
|
||||
barcode-detector: "npm:3.0.8"
|
||||
barcode-detector: "npm:3.1.0"
|
||||
browserslist-useragent-regexp: "npm:4.1.3"
|
||||
color-name: "npm:2.1.0"
|
||||
comlink: "npm:4.4.2"
|
||||
@@ -9265,7 +9289,7 @@ __metadata:
|
||||
eslint-plugin-lit: "npm:2.2.1"
|
||||
eslint-plugin-lit-a11y: "npm:5.1.1"
|
||||
eslint-plugin-unused-imports: "npm:4.4.1"
|
||||
eslint-plugin-wc: "npm:3.0.2"
|
||||
eslint-plugin-wc: "npm:3.1.0"
|
||||
fancy-log: "npm:2.0.0"
|
||||
fs-extra: "npm:11.3.3"
|
||||
fuse.js: "npm:7.1.0"
|
||||
@@ -9275,7 +9299,7 @@ __metadata:
|
||||
gulp-brotli: "npm:3.0.0"
|
||||
gulp-json-transform: "npm:0.5.0"
|
||||
gulp-rename: "npm:2.1.0"
|
||||
gulp-zopfli-green: "npm:6.0.2"
|
||||
gulp-zopfli-green: "npm:7.0.0"
|
||||
hls.js: "npm:1.6.15"
|
||||
home-assistant-js-websocket: "npm:9.6.0"
|
||||
html-minifier-terser: "npm:7.2.0"
|
||||
@@ -9283,7 +9307,7 @@ __metadata:
|
||||
idb-keyval: "npm:6.2.2"
|
||||
intl-messageformat: "npm:11.1.2"
|
||||
js-yaml: "npm:4.1.1"
|
||||
jsdom: "npm:28.0.0"
|
||||
jsdom: "npm:28.1.0"
|
||||
jszip: "npm:3.10.1"
|
||||
leaflet: "npm:1.9.4"
|
||||
leaflet-draw: "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch"
|
||||
@@ -9313,14 +9337,14 @@ __metadata:
|
||||
sortablejs: "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch"
|
||||
stacktrace-js: "npm:2.0.2"
|
||||
superstruct: "npm:2.0.2"
|
||||
tar: "npm:7.5.8"
|
||||
tar: "npm:7.5.9"
|
||||
terser-webpack-plugin: "npm:5.3.16"
|
||||
tinykeys: "npm:3.0.0"
|
||||
ts-lit-plugin: "npm:2.0.2"
|
||||
typescript: "npm:5.9.3"
|
||||
typescript-eslint: "npm:8.54.0"
|
||||
typescript-eslint: "npm:8.56.1"
|
||||
ua-parser-js: "npm:2.0.9"
|
||||
vite-tsconfig-paths: "npm:6.0.5"
|
||||
vite-tsconfig-paths: "npm:6.1.1"
|
||||
vitest: "npm:4.0.18"
|
||||
vue: "npm:2.7.16"
|
||||
vue2-daterange-picker: "npm:0.6.8"
|
||||
@@ -10341,14 +10365,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsdom@npm:28.0.0":
|
||||
version: 28.0.0
|
||||
resolution: "jsdom@npm:28.0.0"
|
||||
"jsdom@npm:28.1.0":
|
||||
version: 28.1.0
|
||||
resolution: "jsdom@npm:28.1.0"
|
||||
dependencies:
|
||||
"@acemir/cssom": "npm:^0.9.31"
|
||||
"@asamuzakjp/dom-selector": "npm:^6.7.6"
|
||||
"@asamuzakjp/dom-selector": "npm:^6.8.1"
|
||||
"@bramus/specificity": "npm:^2.4.2"
|
||||
"@exodus/bytes": "npm:^1.11.0"
|
||||
cssstyle: "npm:^5.3.7"
|
||||
cssstyle: "npm:^6.0.1"
|
||||
data-urls: "npm:^7.0.0"
|
||||
decimal.js: "npm:^10.6.0"
|
||||
html-encoding-sniffer: "npm:^6.0.0"
|
||||
@@ -10359,7 +10384,7 @@ __metadata:
|
||||
saxes: "npm:^6.0.0"
|
||||
symbol-tree: "npm:^3.2.4"
|
||||
tough-cookie: "npm:^6.0.0"
|
||||
undici: "npm:^7.20.0"
|
||||
undici: "npm:^7.21.0"
|
||||
w3c-xmlserializer: "npm:^5.0.0"
|
||||
webidl-conversions: "npm:^8.0.1"
|
||||
whatwg-mimetype: "npm:^5.0.0"
|
||||
@@ -10370,7 +10395,7 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
canvas:
|
||||
optional: true
|
||||
checksum: 10/c50461190982834446308bbfdfbbb829c6447b1693b1f0dd90fd717960a1d02c326cc90c9a378831d9bf8166702e57dcbf12691ddd7406c13d0a522c7b8971d9
|
||||
checksum: 10/700ef06cf3a72998173205e49c7565926c22f51f562400ec033d426fe0a419f4209c3527735b8dd22eddef9798c905810600b89c84c3474447819fa8b37848ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10797,10 +10822,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1, lru-cache@npm:^11.2.4":
|
||||
version: 11.2.4
|
||||
resolution: "lru-cache@npm:11.2.4"
|
||||
checksum: 10/3b2da74c0b6653767f8164c38c4c4f4d7f0cc10c62bfa512663d94a830191ae6a5af742a8d88a8b30d5f9974652d3adae53931f32069139ad24fa2a18a199aca
|
||||
"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1, lru-cache@npm:^11.2.5, lru-cache@npm:^11.2.6":
|
||||
version: 11.2.6
|
||||
resolution: "lru-cache@npm:11.2.6"
|
||||
checksum: 10/91222bbd59f793a0a0ad57789388f06b34ac9bb1613433c1d1810457d09db5cd3ec8943227ce2e1f5d6a0a15d6f1a9f129cb2c49ae9b6b10e82d4965fddecbef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11099,15 +11124,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^9.0.5":
|
||||
version: 9.0.5
|
||||
resolution: "minimatch@npm:9.0.5"
|
||||
dependencies:
|
||||
brace-expansion: "npm:^2.0.1"
|
||||
checksum: 10/dd6a8927b063aca6d910b119e1f2df6d2ce7d36eab91de83167dd136bb85e1ebff97b0d3de1cb08bd1f7e018ca170b4962479fefab5b2a69e2ae12cb2edc8348
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimist@npm:^1.2.0, minimist@npm:^1.2.6":
|
||||
version: 1.2.8
|
||||
resolution: "minimist@npm:1.2.8"
|
||||
@@ -11175,13 +11191,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minipass@npm:^4.0.0":
|
||||
version: 4.2.8
|
||||
resolution: "minipass@npm:4.2.8"
|
||||
checksum: 10/e148eb6dcb85c980234cad889139ef8ddf9d5bdac534f4f0268446c8792dd4c74f4502479be48de3c1cce2f6450f6da4d0d4a86405a8a12be04c1c36b339569a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3":
|
||||
version: 7.1.3
|
||||
resolution: "minipass@npm:7.1.3"
|
||||
@@ -12577,8 +12586,8 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"rollup@npm:^2.43.1":
|
||||
version: 2.79.2
|
||||
resolution: "rollup@npm:2.79.2"
|
||||
version: 2.80.0
|
||||
resolution: "rollup@npm:2.80.0"
|
||||
dependencies:
|
||||
fsevents: "npm:~2.3.2"
|
||||
dependenciesMeta:
|
||||
@@ -12586,7 +12595,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
rollup: dist/bin/rollup
|
||||
checksum: 10/095ba0a82811b1866a76d826987743278db0a87c45092656986bfff490326b66187d5f9ff0c24cf8d5682bc470aa00c36654e0044d6b6335ac0c1201b8280880
|
||||
checksum: 10/1150ab0f71d59e25a0fe6c0d07e49615ada1e9deba1754073be527c48c558a019fcd31d4d927a9c172593b7dc9c7c3c6871ef07fe1e575371ee24400a7c58213
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13734,16 +13743,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar@npm:7.5.8, tar@npm:^7.5.2":
|
||||
version: 7.5.8
|
||||
resolution: "tar@npm:7.5.8"
|
||||
"tar@npm:*, tar@npm:7.5.9, tar@npm:^7.5.2":
|
||||
version: 7.5.9
|
||||
resolution: "tar@npm:7.5.9"
|
||||
dependencies:
|
||||
"@isaacs/fs-minipass": "npm:^4.0.0"
|
||||
chownr: "npm:^3.0.0"
|
||||
minipass: "npm:^7.1.2"
|
||||
minizlib: "npm:^3.1.0"
|
||||
yallist: "npm:^5.0.0"
|
||||
checksum: 10/5fddc22e0fd03e73d5e9e922e71d8681f85443dee4f21403059a757e186ae4004abc9a709cdc7f4143d7d75758a2935f7306b3cc193123d46b6f786dd2b99c2a
|
||||
checksum: 10/1213cdde9c22d6acf8809ba5d2a025212ce3517bc99c4a4c6981b7dc0489bf3b164db9c826c9517680889194c9ba57448c8ff0da35eca9a60bb7689bf0b3897d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14129,12 +14138,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-fest@npm:^5.2.0":
|
||||
version: 5.4.1
|
||||
resolution: "type-fest@npm:5.4.1"
|
||||
"type-fest@npm:^5.4.4":
|
||||
version: 5.4.4
|
||||
resolution: "type-fest@npm:5.4.4"
|
||||
dependencies:
|
||||
tagged-tag: "npm:^1.0.0"
|
||||
checksum: 10/be7d4749e1e5cf2e2c9904fa1aaf9da5eef6c47c130881bf93bfd5a670b2ab59c5502466768e42c521281056a2375b1617176a75cf6c52b575f4bbabbd450b21
|
||||
checksum: 10/0bbdca645f95740587f389a2d712fe8d5e9ab7d13e74aac97cf396112510abcaab6b75fd90d65172bc13b02fdfc827e6a871322cc9c1c1a5a2754d9ab264c6f5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14201,18 +14210,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript-eslint@npm:8.54.0":
|
||||
version: 8.54.0
|
||||
resolution: "typescript-eslint@npm:8.54.0"
|
||||
"typescript-eslint@npm:8.56.1":
|
||||
version: 8.56.1
|
||||
resolution: "typescript-eslint@npm:8.56.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.54.0"
|
||||
"@typescript-eslint/parser": "npm:8.54.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.54.0"
|
||||
"@typescript-eslint/utils": "npm:8.54.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.56.1"
|
||||
"@typescript-eslint/parser": "npm:8.56.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.56.1"
|
||||
"@typescript-eslint/utils": "npm:8.56.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.0.0"
|
||||
checksum: 10/21b1a27fd44716df8d2c7bac4ebd0caef196a04375fff7919dc817066017b6b8700f1e242bd065a26ac7ce0505b7a588626099e04a28142504ed4f0aae8bffb1
|
||||
checksum: 10/e18cd347ddce0f0e5b28121346f27736a418adf68e73d613690ea3a1d0adfe03bc393f77a8872c2cef77ca74bcc0974212d1775c360de33a9987a94cda11a05b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14335,10 +14344,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici@npm:^7.20.0":
|
||||
version: 7.20.0
|
||||
resolution: "undici@npm:7.20.0"
|
||||
checksum: 10/09ca3e1255cf05f3c76e6dff2ae760131ea5bba57290b9b184bd94f5167939548e7ea73292c524c25eb91f5a2152623394d4c6124e222d34fcd53ef733c6b156
|
||||
"undici@npm:^7.21.0":
|
||||
version: 7.22.0
|
||||
resolution: "undici@npm:7.22.0"
|
||||
checksum: 10/a7a1813ba4b74c0d46cc8dd160386202c05699ffc487c5d882cf40e6d2435c8d6faff3b8f8675d09bd1ef0386e370675c26b59b9a8c8b3f17b9f82a42236a927
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14593,16 +14602,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-tsconfig-paths@npm:6.0.5":
|
||||
version: 6.0.5
|
||||
resolution: "vite-tsconfig-paths@npm:6.0.5"
|
||||
"vite-tsconfig-paths@npm:6.1.1":
|
||||
version: 6.1.1
|
||||
resolution: "vite-tsconfig-paths@npm:6.1.1"
|
||||
dependencies:
|
||||
debug: "npm:^4.1.1"
|
||||
globrex: "npm:^0.1.2"
|
||||
tsconfck: "npm:^3.0.3"
|
||||
peerDependencies:
|
||||
vite: "*"
|
||||
checksum: 10/1c3d38102ed34d057fc602c332bfd059bfedd0b378ee87b1a73eac89e20f6d81ee4bd9639557287e275cae2230f1d9225d2d7d83a2fa355a380cf77568f2cd31
|
||||
checksum: 10/f752bce4f3c5707f0df7af8a20294b1f325e26f50578b82c8262d851028616ebb1a3e73ab0789c55cf3c8da8d985e843193c0bec2cb31662c567ccdf137f1fd0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -15693,14 +15702,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zxing-wasm@npm:2.2.4":
|
||||
version: 2.2.4
|
||||
resolution: "zxing-wasm@npm:2.2.4"
|
||||
"zxing-wasm@npm:3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "zxing-wasm@npm:3.0.0"
|
||||
dependencies:
|
||||
"@types/emscripten": "npm:^1.41.5"
|
||||
type-fest: "npm:^5.2.0"
|
||||
type-fest: "npm:^5.4.4"
|
||||
peerDependencies:
|
||||
"@types/emscripten": ">=1.39.6"
|
||||
checksum: 10/e5928cbb066c854c970cbf724e978e502c3469d69de2469bd37d1f6ab8f5d2a2acdbaa9dea32d35cfc058e2b482e29a9c4f12161d9df3e1e952c30dda3a96d8c
|
||||
checksum: 10/0acf04829acf8f3987173af011784642792fc877c7765f79222fe33efff8af09fbf95bf5d590d2490ae39ec411e6c4de06ea24e96d4eb48189b9d06f7502eaa2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
Reference in New Issue
Block a user