mirror of
https://github.com/home-assistant/frontend.git
synced 2026-05-19 07:37:08 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 854e56947f | |||
| 4728eb7231 | |||
| d02b92bd32 | |||
| 98525d23e6 | |||
| ec98b21276 | |||
| defad3beca |
+2
-2
@@ -75,8 +75,8 @@
|
||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||
"@swc/helpers": "0.5.21",
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@tsparticles/engine": "3.9.1",
|
||||
"@tsparticles/preset-links": "3.2.0",
|
||||
"@tsparticles/engine": "4.0.0",
|
||||
"@tsparticles/preset-links": "4.0.0",
|
||||
"@vibrant/color": "4.0.4",
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||
"@webcomponents/webcomponentsjs": "2.8.0",
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import type {
|
||||
ReactiveController,
|
||||
ReactiveControllerHost,
|
||||
} from "@lit/reactive-element/reactive-controller";
|
||||
import type {
|
||||
Condition,
|
||||
ConditionContext,
|
||||
} from "../../panels/lovelace/common/validate-condition";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { setupConditionListeners } from "../condition/listeners";
|
||||
|
||||
/**
|
||||
* Reactive controller that manages the media-query and time-based listeners
|
||||
* needed to keep a set of lovelace visibility conditions evaluated live.
|
||||
*
|
||||
* The host is responsible for the actual evaluation (e.g. computing visible /
|
||||
* hidden / invalid state); the controller only triggers it via the supplied
|
||||
* `onUpdate` callback when something the conditions depend on changes. Call
|
||||
* `setup()` whenever the conditions change; the controller clears previous
|
||||
* listeners and re-subscribes. Listeners are automatically released when the
|
||||
* host disconnects.
|
||||
*/
|
||||
export class ConditionListenersController implements ReactiveController {
|
||||
private _unsubs: (() => void)[] = [];
|
||||
|
||||
constructor(host: ReactiveControllerHost) {
|
||||
host.addController(this);
|
||||
}
|
||||
|
||||
public hostDisconnected(): void {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
public setup(
|
||||
conditions: Condition[],
|
||||
hass: HomeAssistant,
|
||||
onUpdate: () => void,
|
||||
getContext?: () => ConditionContext
|
||||
): void {
|
||||
this.clear();
|
||||
if (!conditions.length) {
|
||||
return;
|
||||
}
|
||||
setupConditionListeners(
|
||||
conditions,
|
||||
hass,
|
||||
(unsub) => this._unsubs.push(unsub),
|
||||
() => onUpdate(),
|
||||
getContext
|
||||
);
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
for (const unsub of this._unsubs) {
|
||||
unsub();
|
||||
}
|
||||
this._unsubs = [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../ha-tooltip";
|
||||
|
||||
export type LiveTestState = "pass" | "fail" | "invalid" | "unknown";
|
||||
|
||||
/**
|
||||
* @element ha-automation-row-live-test
|
||||
*
|
||||
* @summary
|
||||
* Small status indicator dot used in automation/condition rows to surface the
|
||||
* live evaluation result. Renders an optional tooltip with details on hover.
|
||||
*
|
||||
* @attr {"pass"|"fail"|"invalid"|"unknown"} state - The current live-test state. Defaults to `unknown`.
|
||||
* @attr {string} label - Accessible label announced by assistive technology.
|
||||
* @attr {string} message - Optional tooltip body shown on hover/focus.
|
||||
*/
|
||||
@customElement("ha-automation-row-live-test")
|
||||
export class HaAutomationRowLiveTest extends LitElement {
|
||||
@property({ reflect: true }) public state: LiveTestState = "unknown";
|
||||
|
||||
@property() public label = "";
|
||||
|
||||
@property() public message?: string;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<div
|
||||
id="indicator"
|
||||
role="status"
|
||||
tabindex="0"
|
||||
aria-label=${this.label}
|
||||
></div>
|
||||
${this.message
|
||||
? html`<ha-tooltip for="indicator">${this.message}</ha-tooltip>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
position: absolute;
|
||||
inset-inline-end: -6px;
|
||||
display: inline-block;
|
||||
}
|
||||
#indicator {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: var(--ha-border-radius-circle);
|
||||
border: 3px solid;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--card-background-color);
|
||||
transition: all var(--ha-animation-duration-normal) ease-in-out;
|
||||
}
|
||||
:host([state="pass"]) #indicator {
|
||||
background-color: var(--ha-color-fill-success-loud-resting);
|
||||
border-color: var(--ha-color-fill-success-loud-resting);
|
||||
}
|
||||
:host([state="pass"]) #indicator:hover {
|
||||
background-color: var(--ha-color-fill-success-loud-hover);
|
||||
border-color: var(--ha-color-fill-success-loud-hover);
|
||||
}
|
||||
:host([state="fail"]) #indicator {
|
||||
border-color: var(--ha-color-fill-warning-loud-resting);
|
||||
}
|
||||
:host([state="fail"]) #indicator:hover {
|
||||
background-color: var(--ha-color-fill-warning-loud-hover);
|
||||
border-color: var(--ha-color-fill-warning-loud-hover);
|
||||
}
|
||||
:host([state="invalid"]) #indicator {
|
||||
border-color: var(--ha-color-fill-danger-loud-resting);
|
||||
}
|
||||
:host([state="invalid"]) #indicator:hover {
|
||||
background-color: var(--ha-color-fill-danger-loud-hover);
|
||||
border-color: var(--ha-color-fill-danger-loud-hover);
|
||||
}
|
||||
:host([state="unknown"]) #indicator {
|
||||
border-color: var(--ha-color-fill-neutral-loud-resting);
|
||||
}
|
||||
:host([state="unknown"]) #indicator:hover {
|
||||
background-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
border-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-automation-row-live-test": HaAutomationRowLiveTest;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ export class HaSettingsRow extends LitElement {
|
||||
<slot name="prefix"></slot>
|
||||
<div
|
||||
class="body"
|
||||
part="heading"
|
||||
?two-line=${!this.threeLine && hasDescription}
|
||||
?three-line=${this.threeLine}
|
||||
>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import "@home-assistant/webawesome/dist/components/textarea/textarea";
|
||||
import type WaTextarea from "@home-assistant/webawesome/dist/components/textarea/textarea";
|
||||
import { HasSlotController } from "@home-assistant/webawesome/dist/internal/slot";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
import { WaInputMixin, waInputStyles } from "./input/wa-input-mixin";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
|
||||
/**
|
||||
* Home Assistant textarea component
|
||||
@@ -85,20 +84,6 @@ export class HaTextArea extends WaInputMixin(LitElement) {
|
||||
this.removeEventListener("keydown", stopPropagation);
|
||||
}
|
||||
|
||||
protected override async firstUpdated(
|
||||
changedProperties: PropertyValues<this>
|
||||
): Promise<void> {
|
||||
super.firstUpdated(changedProperties);
|
||||
if (this.autofocus) {
|
||||
await this._textarea?.updateComplete;
|
||||
this._textarea?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
public override focus(options?: FocusOptions): void {
|
||||
this._textarea?.focus(options);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const hasLabelSlot = this.label
|
||||
? false
|
||||
|
||||
@@ -95,7 +95,6 @@ export interface TriggerList {
|
||||
|
||||
export interface BaseTrigger {
|
||||
alias?: string;
|
||||
comment?: string;
|
||||
/** @deprecated Use `trigger` instead */
|
||||
platform?: string;
|
||||
trigger: string;
|
||||
@@ -241,7 +240,6 @@ export type Trigger = LegacyTrigger | TriggerList | PlatformTrigger;
|
||||
interface BaseCondition {
|
||||
condition: string;
|
||||
alias?: string;
|
||||
comment?: string;
|
||||
enabled?: boolean;
|
||||
options?: Record<string, unknown>;
|
||||
}
|
||||
@@ -609,7 +607,6 @@ export interface AutomationClipboard {
|
||||
export interface BaseSidebarConfig {
|
||||
delete: () => void;
|
||||
close: (focus?: boolean) => void;
|
||||
editComment: () => void;
|
||||
}
|
||||
|
||||
export interface TriggerSidebarConfig extends BaseSidebarConfig {
|
||||
@@ -671,7 +668,6 @@ export interface OptionSidebarConfig extends BaseSidebarConfig {
|
||||
rename: () => void;
|
||||
duplicate: () => void;
|
||||
defaultOption?: boolean;
|
||||
comment?: string;
|
||||
}
|
||||
|
||||
export interface ScriptFieldSidebarConfig extends BaseSidebarConfig {
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
|
||||
export interface DeviceAutomation {
|
||||
alias?: string;
|
||||
comment?: string;
|
||||
device_id: string;
|
||||
domain: string;
|
||||
entity_id?: string;
|
||||
|
||||
@@ -38,7 +38,7 @@ import { stateActive } from "../common/entity/state_active";
|
||||
import { supportsFeature } from "../common/entity/supports-feature";
|
||||
import type { MediaPlayerItemId } from "../components/media-player/ha-media-player-browse";
|
||||
import type { HomeAssistant, TranslationDict } from "../types";
|
||||
import { isUnavailableState } from "./entity/entity";
|
||||
import { UNAVAILABLE } from "./entity/entity";
|
||||
import { isTTSMediaSource } from "./tts";
|
||||
|
||||
interface MediaPlayerEntityAttributes extends HassEntityAttributeBase {
|
||||
@@ -284,7 +284,8 @@ export const computeMediaControls = (
|
||||
|
||||
const state = stateObj.state;
|
||||
|
||||
if (isUnavailableState(state)) {
|
||||
// We only filter out `unavailable`, not `unknown`
|
||||
if (state === UNAVAILABLE) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ export const isMaxMode = arrayLiteralIncludes(MODES_MAX);
|
||||
|
||||
export const baseActionStruct = object({
|
||||
alias: optional(string()),
|
||||
comment: optional(string()),
|
||||
continue_on_error: optional(boolean()),
|
||||
enabled: optional(boolean()),
|
||||
});
|
||||
@@ -106,7 +105,6 @@ export interface Field {
|
||||
|
||||
interface BaseAction {
|
||||
alias?: string;
|
||||
comment?: string;
|
||||
continue_on_error?: boolean;
|
||||
enabled?: boolean;
|
||||
}
|
||||
@@ -197,7 +195,6 @@ export interface ForEachRepeat extends BaseRepeat {
|
||||
|
||||
export interface Option {
|
||||
alias?: string;
|
||||
comment?: string;
|
||||
conditions: string | Condition[];
|
||||
sequence: Action | Action[];
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import "../../components/ha-dialog";
|
||||
import "../../components/ha-dialog-footer";
|
||||
import "../../components/ha-dialog-header";
|
||||
import "../../components/ha-svg-icon";
|
||||
import "../../components/ha-textarea";
|
||||
import "../../components/input/ha-input";
|
||||
import type { HaInput } from "../../components/input/ha-input";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
@@ -29,7 +28,7 @@ class DialogBox extends LitElement {
|
||||
|
||||
@state() private _validInput = true;
|
||||
|
||||
@query("ha-input, ha-textarea") private _textField?: HaInput;
|
||||
@query("ha-input") private _textField?: HaInput;
|
||||
|
||||
private _closePromise?: Promise<void>;
|
||||
|
||||
@@ -110,7 +109,7 @@ class DialogBox extends LitElement {
|
||||
</ha-dialog-header>
|
||||
<div id="dialog-box-description">
|
||||
${this._params.text ? html` <p>${this._params.text}</p> ` : ""}
|
||||
${this._params.prompt && !this._params.multiline
|
||||
${this._params.prompt
|
||||
? html`
|
||||
<ha-input
|
||||
autofocus
|
||||
@@ -132,19 +131,7 @@ class DialogBox extends LitElement {
|
||||
: nothing}
|
||||
</ha-input>
|
||||
`
|
||||
: this._params.prompt && this._params.multiline
|
||||
? html`
|
||||
<ha-textarea
|
||||
resize="auto"
|
||||
autofocus
|
||||
.value=${this._params.defaultValue}
|
||||
.placeholder=${this._params.placeholder}
|
||||
.label=${this._params.inputLabel}
|
||||
.disabled=${this._loading}
|
||||
@input=${this._validateInput}
|
||||
></ha-textarea>
|
||||
`
|
||||
: nothing}
|
||||
: nothing}
|
||||
</div>
|
||||
<ha-dialog-footer slot="footer">
|
||||
${confirmPrompt
|
||||
|
||||
@@ -33,7 +33,6 @@ export interface PromptDialogParams extends BaseDialogBoxParams {
|
||||
inputMin?: number | string;
|
||||
inputMax?: number | string;
|
||||
action?: (value?: string) => Promise<void>;
|
||||
multiline?: boolean;
|
||||
}
|
||||
|
||||
export interface DialogBoxParams
|
||||
|
||||
@@ -37,7 +37,7 @@ import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-tooltip";
|
||||
import { showJoinMediaPlayersDialog } from "../../../components/media-player/show-join-media-players-dialog";
|
||||
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
|
||||
import { isUnavailableState } from "../../../data/entity/entity";
|
||||
import { UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import type {
|
||||
MediaPickedEvent,
|
||||
MediaPlayerEntity,
|
||||
@@ -275,7 +275,8 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
protected _renderGrouping() {
|
||||
if (
|
||||
!this.stateObj ||
|
||||
isUnavailableState(this.stateObj.state) ||
|
||||
// Compare against `unavailable` so we allow `unknown`
|
||||
this.stateObj.state === UNAVAILABLE ||
|
||||
!supportsFeature(this.stateObj, MediaPlayerEntityFeature.GROUPING)
|
||||
) {
|
||||
return nothing;
|
||||
@@ -315,7 +316,7 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
if (isUnavailableState(this.stateObj.state)) {
|
||||
if (this.stateObj.state === UNAVAILABLE) {
|
||||
return this._renderEmptyCover(this.hass.formatEntityState(this.stateObj));
|
||||
}
|
||||
|
||||
@@ -461,7 +462,7 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
: nothing}
|
||||
${this._renderVolumeControl()}
|
||||
<div class="controls-row">
|
||||
${!isUnavailableState(stateObj.state) &&
|
||||
${stateObj.state !== UNAVAILABLE &&
|
||||
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA)
|
||||
? this._renderControlButton(
|
||||
"browse_media",
|
||||
|
||||
@@ -107,7 +107,6 @@ export default class HaAutomationActionEditor extends LitElement {
|
||||
ev.stopPropagation();
|
||||
const value = {
|
||||
...(this.action.alias ? { alias: this.action.alias } : {}),
|
||||
...(this.action.comment ? { comment: this.action.comment } : {}),
|
||||
...ev.detail.value,
|
||||
};
|
||||
fireEvent(this, "value-changed", { value });
|
||||
|
||||
@@ -4,12 +4,9 @@ import {
|
||||
mdiAlertCircleCheck,
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiArrowDown,
|
||||
mdiArrowRightThin,
|
||||
mdiArrowUp,
|
||||
mdiCheckboxBlankOutline,
|
||||
mdiCheckboxOutline,
|
||||
mdiCommentEditOutline,
|
||||
mdiCommentTextOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -335,10 +332,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
${type !== "condition" &&
|
||||
(this.action as NonConditionAction).continue_on_error === true
|
||||
? html`<ha-svg-icon
|
||||
class="arrow-right"
|
||||
.path=${mdiArrowRightThin}
|
||||
></ha-svg-icon
|
||||
><ha-svg-icon
|
||||
id="svg-icon"
|
||||
.path=${mdiAlertCircleCheck}
|
||||
></ha-svg-icon>
|
||||
@@ -348,24 +341,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
)}
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
${this.action.comment?.trim()
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
id="comment-icon"
|
||||
.path=${mdiCommentTextOutline}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
class="comment-indicator"
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip for="comment-icon"
|
||||
>${this.action.comment.substring(0, 250)}${this.action.comment
|
||||
.length > 250
|
||||
? "..."
|
||||
: nothing}</ha-tooltip
|
||||
>
|
||||
`
|
||||
: nothing}
|
||||
</h3>
|
||||
<ha-automation-row-event-chip
|
||||
.show=${this._running}
|
||||
@@ -409,14 +384,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item value="edit_comment">
|
||||
<ha-svg-icon slot="icon" .path=${mdiCommentEditOutline}></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.action.comment ? "edit" : "add"}`
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<wa-divider></wa-divider>
|
||||
<ha-dropdown-item value="duplicate" .disabled=${this.disabled}>
|
||||
<ha-svg-icon
|
||||
@@ -943,38 +910,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
}
|
||||
};
|
||||
|
||||
private _editCommentAction = async (): Promise<void> => {
|
||||
const comment = await showPromptDialog(this, {
|
||||
title: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.action.comment ? "edit" : "add"}`
|
||||
),
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
),
|
||||
inputType: "string",
|
||||
defaultValue: this.action.comment,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
multiline: true,
|
||||
});
|
||||
if (comment !== null) {
|
||||
const value = { ...this.action };
|
||||
if (comment === "") {
|
||||
delete value.comment;
|
||||
} else {
|
||||
value.comment = comment;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value,
|
||||
});
|
||||
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(value); // refresh sidebar
|
||||
} else if (this._yamlMode) {
|
||||
this._actionEditor?.yamlEditor?.setValue(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private _duplicateAction = () => {
|
||||
fireEvent(this, "duplicate");
|
||||
};
|
||||
@@ -1091,7 +1026,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
rename: () => {
|
||||
this._renameAction();
|
||||
},
|
||||
editComment: this._editCommentAction,
|
||||
toggleYamlMode: () => {
|
||||
this._toggleYamlMode();
|
||||
this.openSidebar();
|
||||
@@ -1187,9 +1121,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
case "rename":
|
||||
this._renameAction();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this._editCommentAction();
|
||||
break;
|
||||
case "duplicate":
|
||||
this._duplicateAction();
|
||||
break;
|
||||
@@ -1227,9 +1158,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
rowStyles,
|
||||
overflowStyles,
|
||||
css`
|
||||
ha-svg-icon.arrow-right {
|
||||
--icon-primary-color: var(--ha-color-fill-neutral-loud-resting);
|
||||
}
|
||||
ha-svg-icon#svg-icon {
|
||||
--icon-primary-color: var(--ha-color-fill-neutral-loud-active);
|
||||
}
|
||||
|
||||
@@ -186,10 +186,6 @@ export class HaDeviceAction extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
ha-device-picker {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
|
||||
@@ -123,7 +123,6 @@ export default class HaAutomationConditionEditor extends LitElement {
|
||||
ev.stopPropagation();
|
||||
const value = {
|
||||
...(this.condition.alias ? { alias: this.condition.alias } : {}),
|
||||
...(this.condition.comment ? { comment: this.condition.comment } : {}),
|
||||
...ev.detail.value,
|
||||
};
|
||||
fireEvent(this, "value-changed", { value });
|
||||
|
||||
@@ -4,8 +4,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiArrowDown,
|
||||
mdiArrowUp,
|
||||
mdiCommentEditOutline,
|
||||
mdiCommentTextOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -25,7 +23,7 @@ import type {
|
||||
} from "home-assistant-js-websocket";
|
||||
import { dump } from "js-yaml";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { LitElement, html, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
@@ -41,6 +39,7 @@ import { debounce } from "../../../../common/util/debounce";
|
||||
import "../../../../components/automation/ha-automation-row";
|
||||
import type { HaAutomationRow } from "../../../../components/automation/ha-automation-row";
|
||||
import "../../../../components/automation/ha-automation-row-event-chip";
|
||||
import "../../../../components/automation/ha-automation-row-live-test";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-condition-icon";
|
||||
import "../../../../components/ha-dropdown";
|
||||
@@ -48,7 +47,6 @@ import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-tooltip";
|
||||
import type {
|
||||
AutomationClipboard,
|
||||
Condition,
|
||||
@@ -219,24 +217,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
conditionTargetSpec
|
||||
)
|
||||
: nothing}
|
||||
${this.condition.comment?.trim()
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
id="comment-icon"
|
||||
.path=${mdiCommentTextOutline}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
class="comment-indicator"
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip for="comment-icon"
|
||||
>${this.condition.comment.substring(0, 250)}${this.condition
|
||||
.comment.length > 250
|
||||
? "..."
|
||||
: nothing}</ha-tooltip
|
||||
>
|
||||
`
|
||||
: nothing}
|
||||
</h3>
|
||||
<ha-automation-row-event-chip
|
||||
.show=${this._testing}
|
||||
@@ -284,14 +264,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item value="edit_comment">
|
||||
<ha-svg-icon slot="icon" .path=${mdiCommentEditOutline}></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.condition.comment ? "edit" : "add"}`
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
@@ -526,23 +498,15 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
@click=${this._toggleSidebar}
|
||||
@toggle-collapsed=${this._toggleCollapse}
|
||||
>${this._renderRow()}
|
||||
<div
|
||||
<ha-automation-row-live-test
|
||||
slot="icons"
|
||||
id="live-test"
|
||||
class=${this._liveTestResult.state}
|
||||
role="status"
|
||||
tabindex="0"
|
||||
aria-label=${this.hass.localize(
|
||||
.state=${this._liveTestResult.state}
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.conditions.live_test_state.${this._liveTestResult.state}`
|
||||
)}
|
||||
>
|
||||
${this._liveTestResult.message
|
||||
? html`<ha-tooltip for="live-test">
|
||||
${this._liveTestResult.message}
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
</div></ha-automation-row
|
||||
>`
|
||||
.message=${this._liveTestResult.message}
|
||||
></ha-automation-row-live-test
|
||||
></ha-automation-row>`
|
||||
: html`
|
||||
<ha-expansion-panel
|
||||
left-chevron
|
||||
@@ -849,38 +813,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
};
|
||||
|
||||
private _editCommentCondition = async (): Promise<void> => {
|
||||
const comment = await showPromptDialog(this, {
|
||||
title: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.condition.comment ? "edit" : "add"}`
|
||||
),
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
),
|
||||
inputType: "string",
|
||||
defaultValue: this.condition.comment,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
multiline: true,
|
||||
});
|
||||
if (comment !== null) {
|
||||
const value = { ...this.condition };
|
||||
if (comment === "") {
|
||||
delete value.comment;
|
||||
} else {
|
||||
value.comment = comment;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value,
|
||||
});
|
||||
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(value); // refresh sidebar
|
||||
} else if (this._yamlMode) {
|
||||
this.conditionEditor?.yamlEditor?.setValue(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private _duplicateCondition = () => {
|
||||
fireEvent(this, "duplicate");
|
||||
};
|
||||
@@ -1022,7 +954,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
rename: () => {
|
||||
this._renameCondition();
|
||||
},
|
||||
editComment: this._editCommentCondition,
|
||||
toggleYamlMode: () => {
|
||||
this._toggleYamlMode();
|
||||
this.openSidebar();
|
||||
@@ -1094,9 +1025,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
case "rename":
|
||||
this._renameCondition();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this._editCommentCondition();
|
||||
break;
|
||||
case "duplicate":
|
||||
this._duplicateCondition();
|
||||
break;
|
||||
@@ -1128,52 +1056,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
rowStyles,
|
||||
overflowStyles,
|
||||
css`
|
||||
#live-test {
|
||||
position: absolute;
|
||||
inset-inline-end: -6px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: var(--ha-border-radius-circle);
|
||||
border: 3px solid;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--card-background-color);
|
||||
transition: all var(--ha-animation-duration-normal) ease-in-out;
|
||||
}
|
||||
#live-test.pass {
|
||||
background-color: var(--ha-color-fill-success-loud-resting);
|
||||
border-color: var(--ha-color-fill-success-loud-resting);
|
||||
}
|
||||
#live-test.pass:hover {
|
||||
background-color: var(--ha-color-fill-success-loud-hover);
|
||||
border-color: var(--ha-color-fill-success-loud-hover);
|
||||
}
|
||||
#live-test.fail {
|
||||
border-color: var(--ha-color-fill-warning-loud-resting);
|
||||
}
|
||||
#live-test.fail:hover {
|
||||
background-color: var(--ha-color-fill-warning-loud-hover);
|
||||
border-color: var(--ha-color-fill-warning-loud-hover);
|
||||
}
|
||||
#live-test.invalid {
|
||||
border-color: var(--ha-color-fill-danger-loud-resting);
|
||||
}
|
||||
#live-test.invalid:hover {
|
||||
background-color: var(--ha-color-fill-danger-loud-hover);
|
||||
border-color: var(--ha-color-fill-danger-loud-hover);
|
||||
}
|
||||
#live-test.unknown {
|
||||
border-color: var(--ha-color-fill-neutral-loud-resting);
|
||||
}
|
||||
#live-test.unknown:hover {
|
||||
background-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
border-color: var(--ha-color-fill-neutral-loud-hover);
|
||||
}
|
||||
`,
|
||||
];
|
||||
return [rowStyles, overflowStyles];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,10 +188,6 @@ export class HaDeviceCondition extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
ha-device-picker {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
|
||||
+1
-9
@@ -1,5 +1,5 @@
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import {
|
||||
@@ -22,7 +22,6 @@ import type { HomeAssistant } from "../../../../../types";
|
||||
|
||||
const numericStateConditionStruct = object({
|
||||
alias: optional(string()),
|
||||
comment: optional(string()),
|
||||
condition: literal("numeric_state"),
|
||||
entity_id: optional(string()),
|
||||
attribute: optional(string()),
|
||||
@@ -256,13 +255,6 @@ export default class HaNumericStateCondition extends LitElement {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import {
|
||||
array,
|
||||
assert,
|
||||
boolean,
|
||||
literal,
|
||||
@@ -11,9 +10,10 @@ import {
|
||||
optional,
|
||||
string,
|
||||
union,
|
||||
array,
|
||||
} from "superstruct";
|
||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import "../../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
@@ -25,7 +25,6 @@ import type { ConditionElement } from "../ha-automation-condition-row";
|
||||
|
||||
const stateConditionStruct = object({
|
||||
alias: optional(string()),
|
||||
comment: optional(string()),
|
||||
condition: literal("state"),
|
||||
entity_id: optional(string()),
|
||||
attribute: optional(string()),
|
||||
@@ -143,13 +142,6 @@ export class HaStateCondition extends LitElement implements ConditionElement {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-settings-row";
|
||||
import { internationalizationContext } from "../../../data/context";
|
||||
|
||||
@customElement("ha-automation-comment")
|
||||
export class HaAutomationComment extends LitElement {
|
||||
@property() public comment!: string;
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-settings-row narrow>
|
||||
<div class="heading" slot="heading">
|
||||
<span class="title" id="comment-label">
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
</span>
|
||||
<ha-button
|
||||
@click=${this._handleClick}
|
||||
size="small"
|
||||
appearance="plain"
|
||||
>
|
||||
${this._i18n.localize("ui.common.edit")}
|
||||
</ha-button>
|
||||
</div>
|
||||
<p aria-labelledby="comment-label">${this.comment}</p>
|
||||
</ha-settings-row>
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleClick() {
|
||||
fireEvent(this, "edit-comment");
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-settings-row {
|
||||
margin-inline: calc(-1 * var(--ha-space-4));
|
||||
}
|
||||
ha-settings-row::part(heading) {
|
||||
padding-inline-end: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
.heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
p {
|
||||
margin: var(--ha-space-2) 0 0;
|
||||
border: var(--ha-border-width-sm) solid
|
||||
var(--ha-color-border-neutral-quiet);
|
||||
padding: var(--ha-space-1) var(--ha-space-3);
|
||||
border-radius: var(--ha-border-radius-lg);
|
||||
background-color: var(--ha-color-fill-neutral-quiet-resting);
|
||||
}
|
||||
ha-button {
|
||||
margin-inline-end: calc(-1 * var(--ha-space-3));
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-automation-comment": HaAutomationComment;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
"edit-comment": undefined;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiArrowDown,
|
||||
mdiArrowUp,
|
||||
mdiCommentEditOutline,
|
||||
mdiCommentTextOutline,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiPlusCircleMultipleOutline,
|
||||
@@ -39,11 +37,11 @@ import type { Action, Option } from "../../../../data/script";
|
||||
import { showPromptDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { isMac } from "../../../../util/is_mac";
|
||||
import { showEditorToast } from "../editor-toast";
|
||||
import "../action/ha-automation-action";
|
||||
import type HaAutomationAction from "../action/ha-automation-action";
|
||||
import "../condition/ha-automation-condition";
|
||||
import type HaAutomationCondition from "../condition/ha-automation-condition";
|
||||
import { showEditorToast } from "../editor-toast";
|
||||
import {
|
||||
editorStyles,
|
||||
indentStyle,
|
||||
@@ -152,24 +150,6 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.type.choose.default"
|
||||
)}
|
||||
${this.option?.comment?.trim()
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
id="comment-icon"
|
||||
.path=${mdiCommentTextOutline}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
class="comment-indicator"
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip for="comment-icon"
|
||||
>${this.option.comment.substring(0, 250)}${this.option.comment
|
||||
.length > 250
|
||||
? "..."
|
||||
: nothing}</ha-tooltip
|
||||
>
|
||||
`
|
||||
: nothing}
|
||||
</h3>
|
||||
|
||||
<slot name="icons" slot="icons"></slot>
|
||||
@@ -197,17 +177,6 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item value="edit_comment">
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCommentEditOutline}
|
||||
></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.option?.comment ? "edit" : "add"}`
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
|
||||
<ha-dropdown-item value="duplicate" .disabled=${this.disabled}>
|
||||
<ha-svg-icon
|
||||
@@ -392,9 +361,6 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
case "rename":
|
||||
this._renameOption();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this._editCommentOption();
|
||||
break;
|
||||
case "delete":
|
||||
this._removeOption();
|
||||
break;
|
||||
@@ -458,39 +424,6 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
}
|
||||
};
|
||||
|
||||
private _editCommentOption = async (): Promise<void> => {
|
||||
if (!this.option) {
|
||||
return;
|
||||
}
|
||||
const comment = await showPromptDialog(this, {
|
||||
title: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.option.comment ? "edit" : "add"}`
|
||||
),
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
),
|
||||
inputType: "string",
|
||||
defaultValue: this.option.comment,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
multiline: true,
|
||||
});
|
||||
if (comment !== null) {
|
||||
const value: Option = { ...this.option };
|
||||
if (comment === "") {
|
||||
delete value.comment;
|
||||
} else {
|
||||
value.comment = comment;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value,
|
||||
});
|
||||
|
||||
if (this._selected) {
|
||||
this.openSidebar(value); // refresh sidebar
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private _conditionChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
const conditions = ev.detail.value as Condition[];
|
||||
@@ -522,8 +455,7 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
this.openSidebar();
|
||||
}
|
||||
|
||||
public openSidebar(option?: Option): void {
|
||||
const sidebarOption = option ?? this.option;
|
||||
public openSidebar(): void {
|
||||
fireEvent(this, "open-sidebar", {
|
||||
close: (focus?: boolean) => {
|
||||
this._selected = false;
|
||||
@@ -535,11 +467,9 @@ export default class HaAutomationOptionRow extends LitElement {
|
||||
rename: () => {
|
||||
this._renameOption();
|
||||
},
|
||||
editComment: this._editCommentOption,
|
||||
delete: this._removeOption,
|
||||
duplicate: this._duplicateOption,
|
||||
defaultOption: !!this.defaultActions,
|
||||
comment: sidebarOption?.comment,
|
||||
} satisfies OptionSidebarConfig);
|
||||
this._selected = true;
|
||||
this._collapsed = false;
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCheckboxBlankOutline,
|
||||
mdiCheckboxOutline,
|
||||
mdiCommentEditOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -27,8 +26,8 @@ import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import { ACTION_BUILDING_BLOCKS } from "../../../../data/action";
|
||||
import type { ActionSidebarConfig } from "../../../../data/automation";
|
||||
import type { DomainManifestLookup } from "../../../../data/integration";
|
||||
import { domainToName } from "../../../../data/integration";
|
||||
import type { DomainManifestLookup } from "../../../../data/integration";
|
||||
import type {
|
||||
NonConditionAction,
|
||||
RepeatAction,
|
||||
@@ -39,7 +38,6 @@ import { isMac } from "../../../../util/is_mac";
|
||||
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
|
||||
import { getAutomationActionType } from "../action/ha-automation-action-row";
|
||||
import { getRepeatType } from "../action/types/ha-automation-action-repeat";
|
||||
import "../ha-automation-comment";
|
||||
import { overflowStyles, sidebarEditorStyles } from "../styles";
|
||||
import "./ha-automation-sidebar-card";
|
||||
|
||||
@@ -177,15 +175,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item slot="menu-items" value="edit_comment">
|
||||
<ha-svg-icon slot="icon" .path=${mdiCommentEditOutline}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.config.config.action.comment ? "edit" : "add"}`
|
||||
)}
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
|
||||
<wa-divider slot="menu-items"></wa-divider>
|
||||
<ha-dropdown-item
|
||||
@@ -388,12 +377,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
||||
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
||||
></ha-automation-action-editor>`
|
||||
)}
|
||||
${this.config.config.action.comment?.trim() && !this.yamlMode
|
||||
? html`<ha-automation-comment
|
||||
@edit-comment=${this.config.editComment}
|
||||
.comment=${this.config.config.action.comment}
|
||||
></ha-automation-comment>`
|
||||
: nothing}
|
||||
</ha-automation-sidebar-card>`;
|
||||
}
|
||||
|
||||
@@ -442,9 +425,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
||||
case "rename":
|
||||
this.config.rename();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this.config.editComment();
|
||||
break;
|
||||
case "run":
|
||||
this.config.run();
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCommentEditOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -35,7 +34,6 @@ import type { HomeAssistant } from "../../../../types";
|
||||
import { isMac } from "../../../../util/is_mac";
|
||||
import "../condition/ha-automation-condition-editor";
|
||||
import type HaAutomationConditionEditor from "../condition/ha-automation-condition-editor";
|
||||
import "../ha-automation-comment";
|
||||
import { overflowStyles, sidebarEditorStyles } from "../styles";
|
||||
import "./ha-automation-sidebar-card";
|
||||
|
||||
@@ -151,19 +149,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="edit_comment"
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiCommentEditOutline}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.config.config.comment ? "edit" : "add"}`
|
||||
)}
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
|
||||
<wa-divider slot="menu-items"></wa-divider>
|
||||
|
||||
@@ -347,12 +332,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
||||
sidebar
|
||||
></ha-automation-condition-editor>`
|
||||
)}
|
||||
${this.config.config.comment?.trim() && !this.yamlMode
|
||||
? html`<ha-automation-comment
|
||||
@edit-comment=${this.config.editComment}
|
||||
.comment=${this.config.config.comment}
|
||||
></ha-automation-comment>`
|
||||
: nothing}
|
||||
<div class="testing-wrapper">
|
||||
<div
|
||||
class="testing ${classMap({
|
||||
@@ -417,9 +396,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
||||
case "rename":
|
||||
this.config.rename();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this.config.editComment();
|
||||
break;
|
||||
case "test":
|
||||
this.config.test();
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCommentEditOutline,
|
||||
mdiDelete,
|
||||
mdiPlusCircleMultipleOutline,
|
||||
mdiRenameBox,
|
||||
@@ -15,7 +14,6 @@ import type { OptionSidebarConfig } from "../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { isMac } from "../../../../util/is_mac";
|
||||
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
|
||||
import "../ha-automation-comment";
|
||||
import { overflowStyles, sidebarEditorStyles } from "../styles";
|
||||
import "./ha-automation-sidebar-card";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
@@ -74,22 +72,6 @@ export default class HaAutomationSidebarOption extends LitElement {
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="edit_comment"
|
||||
.disabled=${!!disabled}
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCommentEditOutline}
|
||||
></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.config.comment ? "edit" : "add"}`
|
||||
)}
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
@@ -144,12 +126,6 @@ export default class HaAutomationSidebarOption extends LitElement {
|
||||
`}
|
||||
|
||||
<div class="description">${description}</div>
|
||||
${!this.config.defaultOption && this.config.comment?.trim()
|
||||
? html`<ha-automation-comment
|
||||
@edit-comment=${this.config.editComment}
|
||||
.comment=${this.config.comment}
|
||||
></ha-automation-comment>`
|
||||
: nothing}
|
||||
</ha-automation-sidebar-card>`;
|
||||
}
|
||||
|
||||
@@ -164,9 +140,6 @@ export default class HaAutomationSidebarOption extends LitElement {
|
||||
case "rename":
|
||||
this.config.rename();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this.config.editComment();
|
||||
break;
|
||||
case "duplicate":
|
||||
this.config.duplicate();
|
||||
break;
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCommentEditOutline,
|
||||
mdiDelete,
|
||||
mdiPlaylistEdit,
|
||||
} from "@mdi/js";
|
||||
import { mdiAppleKeyboardCommand, mdiDelete, mdiPlaylistEdit } from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { keyed } from "lit/directives/keyed";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { isMac } from "../../../../util/is_mac";
|
||||
import "../../script/ha-script-field-editor";
|
||||
import type HaAutomationConditionEditor from "../action/ha-automation-action-editor";
|
||||
import "../ha-automation-comment";
|
||||
import { overflowStyles, sidebarEditorStyles } from "../styles";
|
||||
import "./ha-automation-sidebar-card";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
|
||||
@customElement("ha-automation-sidebar-script-field")
|
||||
export default class HaAutomationSidebarScriptField extends LitElement {
|
||||
@@ -68,15 +62,6 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
>
|
||||
<span slot="title">${title}</span>
|
||||
<ha-dropdown-item slot="menu-items" value="edit_comment">
|
||||
<ha-svg-icon slot="icon" .path=${mdiCommentEditOutline}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.config.config.field.description ? "edit" : "add"}`
|
||||
)}
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="toggle_yaml_mode"
|
||||
@@ -136,12 +121,6 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
||||
@yaml-changed=${this._yamlChangedSidebar}
|
||||
></ha-script-field-editor>`
|
||||
)}
|
||||
${this.config.config.field.description?.trim() && !this.yamlMode
|
||||
? html`<ha-automation-comment
|
||||
@edit-comment=${this.config.editComment}
|
||||
.comment=${this.config.config.field.description}
|
||||
></ha-automation-comment>`
|
||||
: nothing}
|
||||
</ha-automation-sidebar-card>`;
|
||||
}
|
||||
|
||||
@@ -189,9 +168,6 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
||||
case "toggle_yaml_mode":
|
||||
this._toggleYamlMode();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this.config.editComment();
|
||||
break;
|
||||
case "delete":
|
||||
this.config.delete();
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCommentEditOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -19,12 +18,9 @@ import { customElement, property, query, state } from "lit/decorators";
|
||||
import { keyed } from "lit/directives/keyed";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
import "../../../../components/ha-dropdown-item";
|
||||
import type {
|
||||
LegacyTrigger,
|
||||
Trigger,
|
||||
TriggerList,
|
||||
TriggerSidebarConfig,
|
||||
} from "../../../../data/automation";
|
||||
import {
|
||||
@@ -34,11 +30,11 @@ import {
|
||||
} from "../../../../data/trigger";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { isMac } from "../../../../util/is_mac";
|
||||
import "../ha-automation-comment";
|
||||
import { overflowStyles, sidebarEditorStyles } from "../styles";
|
||||
import "../trigger/ha-automation-trigger-editor";
|
||||
import type HaAutomationTriggerEditor from "../trigger/ha-automation-trigger-editor";
|
||||
import "./ha-automation-sidebar-card";
|
||||
import type { HaDropdownSelectEvent } from "../../../../components/ha-dropdown";
|
||||
|
||||
@customElement("ha-automation-sidebar-trigger")
|
||||
export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
@@ -129,24 +125,7 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
${type !== "list"
|
||||
? html`<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="edit_comment"
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCommentEditOutline}
|
||||
></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${(this.config.config as Exclude<Trigger, TriggerList>).comment ? "edit" : "add"}`
|
||||
)}
|
||||
<span class="shortcut-placeholder ${isMac ? "mac" : ""}"></span>
|
||||
</div>
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
|
||||
${!this.yamlMode &&
|
||||
!("id" in this.config.config) &&
|
||||
!this._requestShowId
|
||||
@@ -342,14 +321,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
sidebar
|
||||
></ha-automation-trigger-editor>`
|
||||
)}
|
||||
${!isTriggerList(this.config.config) &&
|
||||
this.config.config.comment?.trim() &&
|
||||
!this.yamlMode
|
||||
? html`<ha-automation-comment
|
||||
@edit-comment=${this.config.editComment}
|
||||
.comment=${this.config.config.comment}
|
||||
></ha-automation-comment>`
|
||||
: nothing}
|
||||
</ha-automation-sidebar-card>
|
||||
`;
|
||||
}
|
||||
@@ -401,9 +372,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
case "rename":
|
||||
this.config.rename();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this.config.editComment();
|
||||
break;
|
||||
case "show_id":
|
||||
this._showTriggerId();
|
||||
break;
|
||||
|
||||
@@ -4,7 +4,6 @@ export const baseTriggerStruct = object({
|
||||
trigger: string(),
|
||||
id: optional(string()),
|
||||
enabled: optional(boolean()),
|
||||
comment: optional(string()),
|
||||
});
|
||||
|
||||
export const forDictStruct = object({
|
||||
|
||||
@@ -52,14 +52,6 @@ export const rowStyles = css`
|
||||
ha-automation-row-event-chip.event-chip {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.comment-indicator {
|
||||
color: var(--ha-color-on-neutral-normal);
|
||||
}
|
||||
.comment-indicator + ha-tooltip::part(body) {
|
||||
cursor: default;
|
||||
max-width: 300px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const editorStyles = css`
|
||||
|
||||
@@ -141,7 +141,6 @@ export default class HaAutomationTriggerEditor extends LitElement {
|
||||
ev.stopPropagation();
|
||||
const value = {
|
||||
...(this.trigger.alias ? { alias: this.trigger.alias } : {}),
|
||||
...(this.trigger.comment ? { comment: this.trigger.comment } : {}),
|
||||
...ev.detail.value,
|
||||
};
|
||||
fireEvent(this, "value-changed", { value });
|
||||
|
||||
@@ -4,8 +4,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiArrowDown,
|
||||
mdiArrowUp,
|
||||
mdiCommentEditOutline,
|
||||
mdiCommentTextOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
@@ -244,28 +242,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
triggerTargetSpec
|
||||
)
|
||||
: nothing}
|
||||
${type !== "list" &&
|
||||
(this.trigger as Exclude<Trigger, TriggerList>).comment?.trim()
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
id="comment-icon"
|
||||
.path=${mdiCommentTextOutline}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
class="comment-indicator"
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip for="comment-icon"
|
||||
>${(
|
||||
this.trigger as Exclude<Trigger, TriggerList>
|
||||
).comment!.substring(0, 250)}${(
|
||||
this.trigger as Exclude<Trigger, TriggerList>
|
||||
).comment!.length > 250
|
||||
? "..."
|
||||
: nothing}</ha-tooltip
|
||||
>
|
||||
`
|
||||
: nothing}
|
||||
</h3>
|
||||
<ha-automation-row-event-chip
|
||||
.show=${this._triggered}
|
||||
@@ -306,19 +282,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
${type !== "list"
|
||||
? html`<ha-dropdown-item value="edit_comment">
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCommentEditOutline}
|
||||
></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${(this.trigger as Exclude<Trigger, TriggerList>).comment ? "edit" : "add"}`
|
||||
)
|
||||
)}
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<ha-dropdown-item value="duplicate" .disabled=${this.disabled}>
|
||||
@@ -695,7 +659,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
rename: () => {
|
||||
this._renameTrigger();
|
||||
},
|
||||
editComment: this._editCommentTrigger,
|
||||
toggleYamlMode: () => {
|
||||
this._toggleYamlMode();
|
||||
this.openSidebar();
|
||||
@@ -839,40 +802,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
}
|
||||
};
|
||||
|
||||
private _editCommentTrigger = async (): Promise<void> => {
|
||||
if (isTriggerList(this.trigger)) return;
|
||||
const trigger = this.trigger;
|
||||
const comment = await showPromptDialog(this, {
|
||||
title: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${trigger.comment ? "edit" : "add"}`
|
||||
),
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
),
|
||||
inputType: "string",
|
||||
defaultValue: trigger.comment,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
multiline: true,
|
||||
});
|
||||
if (comment !== null) {
|
||||
const value = { ...trigger };
|
||||
if (comment === "") {
|
||||
delete value.comment;
|
||||
} else {
|
||||
value.comment = comment;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value,
|
||||
});
|
||||
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(value); // refresh sidebar
|
||||
} else if (this._yamlMode) {
|
||||
this.triggerEditor?.yamlEditor?.setValue(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private _duplicateTrigger = () => {
|
||||
fireEvent(this, "duplicate");
|
||||
};
|
||||
@@ -984,9 +913,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
case "rename":
|
||||
this._renameTrigger();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this._editCommentTrigger();
|
||||
break;
|
||||
case "duplicate":
|
||||
this._duplicateTrigger();
|
||||
break;
|
||||
|
||||
@@ -212,10 +212,6 @@ export class HaDeviceTrigger extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
ha-device-picker {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { hasTemplate } from "../../../../../common/string/has-template";
|
||||
@@ -11,6 +10,7 @@ import "../../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
||||
import type { NumericStateTrigger } from "../../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||
|
||||
@customElement("ha-automation-trigger-numeric_state")
|
||||
export class HaNumericStateTrigger extends LitElement {
|
||||
@@ -333,13 +333,6 @@ export class HaNumericStateTrigger extends LitElement {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -29,7 +29,6 @@ const DEFAULT_KEYS: (keyof PlatformTrigger)[] = [
|
||||
"trigger",
|
||||
"target",
|
||||
"alias",
|
||||
"comment",
|
||||
"id",
|
||||
"variables",
|
||||
"enabled",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import {
|
||||
array,
|
||||
assert,
|
||||
@@ -14,21 +13,22 @@ import {
|
||||
string,
|
||||
union,
|
||||
} from "superstruct";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { hasTemplate } from "../../../../../common/string/has-template";
|
||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||
import type { StateTrigger } from "../../../../../data/automation";
|
||||
import { ANY_STATE_VALUE } from "../../../../../components/entity/const";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { baseTriggerStruct, forDictStruct } from "../../structs";
|
||||
import type { TriggerElement } from "../ha-automation-trigger-row";
|
||||
import "../../../../../components/ha-form/ha-form";
|
||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../../components/ha-form/types";
|
||||
import type { StateTrigger } from "../../../../../data/automation";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import { baseTriggerStruct, forDictStruct } from "../../structs";
|
||||
import type { TriggerElement } from "../ha-automation-trigger-row";
|
||||
|
||||
const stateTriggerStruct = assign(
|
||||
baseTriggerStruct,
|
||||
@@ -303,13 +303,6 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
||||
? "ui.components.entity.entity-picker.entity"
|
||||
: `ui.panel.config.automation.editor.triggers.type.state.${schema.name}`
|
||||
);
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
mdiAlertCircle,
|
||||
mdiDelete,
|
||||
mdiWater,
|
||||
mdiDragHorizontalVariant,
|
||||
@@ -6,7 +7,7 @@ import {
|
||||
mdiPlus,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
@@ -15,10 +16,12 @@ import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-sortable";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import "../../../../components/ha-tooltip";
|
||||
import type {
|
||||
DeviceConsumptionEnergyPreference,
|
||||
EnergyPreferences,
|
||||
EnergyPreferencesValidation,
|
||||
EnergyValidationIssue,
|
||||
} from "../../../../data/energy";
|
||||
import { saveEnergyPreferences } from "../../../../data/energy";
|
||||
import type { StatisticsMetaData } from "../../../../data/recorder";
|
||||
@@ -93,7 +96,7 @@ export class EnergyDeviceSettingsWater extends LitElement {
|
||||
${repeat(
|
||||
this.preferences.device_consumption_water,
|
||||
(device) => device.stat_consumption,
|
||||
(device) => html`
|
||||
(device, index) => html`
|
||||
<div class="row" .device=${device}>
|
||||
<div class="handle">
|
||||
<ha-svg-icon
|
||||
@@ -108,6 +111,12 @@ export class EnergyDeviceSettingsWater extends LitElement {
|
||||
this.statsMetadata?.[device.stat_consumption]
|
||||
)}</span
|
||||
>
|
||||
${this._renderIssueIndicator(
|
||||
this.validationResult?.device_consumption_water[
|
||||
index
|
||||
],
|
||||
index
|
||||
)}
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize("ui.common.edit")}
|
||||
@click=${this._editDevice}
|
||||
@@ -144,6 +153,31 @@ export class EnergyDeviceSettingsWater extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderIssueIndicator(
|
||||
issues: EnergyValidationIssue[] | undefined,
|
||||
index: number
|
||||
) {
|
||||
if (!issues?.length) {
|
||||
return nothing;
|
||||
}
|
||||
const titles = issues.map(
|
||||
(issue) =>
|
||||
this.hass.localize(`component.energy.issues.${issue.type}.title`) ||
|
||||
issue.type
|
||||
);
|
||||
const label = titles.join("\n");
|
||||
const id = `issue-icon-${index}`;
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
id=${id}
|
||||
class="issue-icon"
|
||||
.path=${mdiAlertCircle}
|
||||
aria-label=${label}
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip .for=${id} placement="top">${label}</ha-tooltip>
|
||||
`;
|
||||
}
|
||||
|
||||
private _itemMoved(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const { oldIndex, newIndex } = ev.detail;
|
||||
@@ -248,6 +282,9 @@ export class EnergyDeviceSettingsWater extends LitElement {
|
||||
cursor: move; /* fallback if grab cursor is unsupported */
|
||||
cursor: grab;
|
||||
}
|
||||
.issue-icon {
|
||||
color: var(--warning-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
mdiAlertCircle,
|
||||
mdiDelete,
|
||||
mdiDevices,
|
||||
mdiDragHorizontalVariant,
|
||||
@@ -6,7 +7,7 @@ import {
|
||||
mdiPlus,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
@@ -15,10 +16,12 @@ import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-sortable";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import "../../../../components/ha-tooltip";
|
||||
import type {
|
||||
DeviceConsumptionEnergyPreference,
|
||||
EnergyPreferences,
|
||||
EnergyPreferencesValidation,
|
||||
EnergyValidationIssue,
|
||||
} from "../../../../data/energy";
|
||||
import { saveEnergyPreferences } from "../../../../data/energy";
|
||||
import type { StatisticsMetaData } from "../../../../data/recorder";
|
||||
@@ -93,7 +96,7 @@ export class EnergyDeviceSettings extends LitElement {
|
||||
${repeat(
|
||||
this.preferences.device_consumption,
|
||||
(device) => device.stat_consumption,
|
||||
(device) => html`
|
||||
(device, index) => html`
|
||||
<div class="row" .device=${device}>
|
||||
<div class="handle">
|
||||
<ha-svg-icon
|
||||
@@ -108,6 +111,10 @@ export class EnergyDeviceSettings extends LitElement {
|
||||
this.statsMetadata?.[device.stat_consumption]
|
||||
)}</span
|
||||
>
|
||||
${this._renderIssueIndicator(
|
||||
this.validationResult?.device_consumption[index],
|
||||
index
|
||||
)}
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize("ui.common.edit")}
|
||||
@click=${this._editDevice}
|
||||
@@ -144,6 +151,31 @@ export class EnergyDeviceSettings extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderIssueIndicator(
|
||||
issues: EnergyValidationIssue[] | undefined,
|
||||
index: number
|
||||
) {
|
||||
if (!issues?.length) {
|
||||
return nothing;
|
||||
}
|
||||
const titles = issues.map(
|
||||
(issue) =>
|
||||
this.hass.localize(`component.energy.issues.${issue.type}.title`) ||
|
||||
issue.type
|
||||
);
|
||||
const label = titles.join("\n");
|
||||
const id = `issue-icon-${index}`;
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
id=${id}
|
||||
class="issue-icon"
|
||||
.path=${mdiAlertCircle}
|
||||
aria-label=${label}
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip .for=${id} placement="top">${label}</ha-tooltip>
|
||||
`;
|
||||
}
|
||||
|
||||
private _itemMoved(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const { oldIndex, newIndex } = ev.detail;
|
||||
@@ -244,6 +276,9 @@ export class EnergyDeviceSettings extends LitElement {
|
||||
cursor: move; /* fallback if grab cursor is unsupported */
|
||||
cursor: grab;
|
||||
}
|
||||
.issue-icon {
|
||||
color: var(--warning-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ export default class HaScriptFieldEditor extends LitElement {
|
||||
name: "key",
|
||||
selector: { text: {} },
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
selector: { text: {} },
|
||||
},
|
||||
{
|
||||
name: "required",
|
||||
selector: { boolean: {} },
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiCommentEditOutline,
|
||||
mdiCommentTextOutline,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiPlaylistEdit,
|
||||
@@ -23,7 +21,6 @@ import "../../../components/ha-dropdown-item";
|
||||
import type { ScriptFieldSidebarConfig } from "../../../data/automation";
|
||||
import type { Field } from "../../../data/script";
|
||||
import { SELECTOR_SELECTOR_BUILDING_BLOCKS } from "../../../data/selector/selector_selector";
|
||||
import { showPromptDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
import { showEditorToast } from "../automation/editor-toast";
|
||||
@@ -93,16 +90,6 @@ export default class HaScriptFieldRow extends LitElement {
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
|
||||
<ha-dropdown-item value="edit_comment">
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCommentEditOutline}
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.field.description ? "edit" : "add"}`
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item value="toggle_yaml_mode">
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
@@ -145,27 +132,7 @@ export default class HaScriptFieldRow extends LitElement {
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
|
||||
<h3 slot="header">
|
||||
${this.field.name ?? this.key}
|
||||
${this.field.description?.trim()
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
id="comment-icon"
|
||||
.path=${mdiCommentTextOutline}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
)}
|
||||
class="comment-indicator"
|
||||
></ha-svg-icon>
|
||||
<ha-tooltip for="comment-icon"
|
||||
>${this.field.description.substring(0, 250)}${this.field
|
||||
.description.length > 250
|
||||
? "..."
|
||||
: nothing}</ha-tooltip
|
||||
>
|
||||
`
|
||||
: nothing}
|
||||
</h3>
|
||||
<h3 slot="header">${this.field.name ?? this.key}</h3>
|
||||
|
||||
<slot name="icons" slot="icons"></slot>
|
||||
</ha-automation-row>
|
||||
@@ -357,46 +324,11 @@ export default class HaScriptFieldRow extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _editComment = async (): Promise<void> => {
|
||||
const comment = await showPromptDialog(this, {
|
||||
title: this.hass.localize(
|
||||
`ui.panel.config.automation.editor.comment.${this.field.description ? "edit" : "add"}`
|
||||
),
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.comment.label"
|
||||
),
|
||||
inputType: "string",
|
||||
defaultValue: this.field.description,
|
||||
confirmText: this.hass.localize("ui.common.submit"),
|
||||
multiline: true,
|
||||
});
|
||||
if (comment !== null) {
|
||||
const value = { ...this.field };
|
||||
if (comment === "") {
|
||||
delete value.description;
|
||||
} else {
|
||||
value.description = comment;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value,
|
||||
});
|
||||
|
||||
if (this._selected) {
|
||||
this.openSidebar(false, value); // refresh sidebar
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public openSidebar(
|
||||
selectorEditor = false,
|
||||
fieldValue?: HaScriptFieldRow["field"]
|
||||
): void {
|
||||
public openSidebar(selectorEditor = false): void {
|
||||
if (!selectorEditor) {
|
||||
this._selected = true;
|
||||
}
|
||||
|
||||
const field = fieldValue ?? this.field;
|
||||
|
||||
fireEvent(this, "open-sidebar", {
|
||||
save: (value) => {
|
||||
fireEvent(this, "value-changed", { value });
|
||||
@@ -421,13 +353,12 @@ export default class HaScriptFieldRow extends LitElement {
|
||||
},
|
||||
delete: this._onDelete,
|
||||
config: {
|
||||
field,
|
||||
field: this.field,
|
||||
selector: selectorEditor,
|
||||
key: this.key,
|
||||
excludeKeys: this.excludeKeys,
|
||||
},
|
||||
yamlMode: this._yamlMode,
|
||||
editComment: this._editComment,
|
||||
} satisfies ScriptFieldSidebarConfig);
|
||||
|
||||
if (this.narrow) {
|
||||
@@ -488,9 +419,6 @@ export default class HaScriptFieldRow extends LitElement {
|
||||
case "delete":
|
||||
this._onDelete();
|
||||
break;
|
||||
case "edit_comment":
|
||||
this._editComment();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ import type { PropertyValues } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { Condition } from "../../common/validate-condition";
|
||||
import { conditionsEntityContext } from "../conditions/context";
|
||||
import "../conditions/ha-card-conditions-editor";
|
||||
import "../conditions/ha-visibility-status";
|
||||
|
||||
@customElement("hui-badge-visibility-editor")
|
||||
export class HuiBadgeVisibilityEditor extends LitElement {
|
||||
@@ -34,11 +34,10 @@ export class HuiBadgeVisibilityEditor extends LitElement {
|
||||
render() {
|
||||
const conditions = this.config.visibility ?? [];
|
||||
return html`
|
||||
<p class="intro">
|
||||
${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_badge.visibility.explanation`
|
||||
)}
|
||||
</p>
|
||||
<ha-visibility-status
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
></ha-visibility-status>
|
||||
<ha-card-conditions-editor
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
@@ -62,10 +61,8 @@ export class HuiBadgeVisibilityEditor extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.intro {
|
||||
margin: 0;
|
||||
color: var(--secondary-text-color);
|
||||
margin-bottom: 8px;
|
||||
ha-visibility-status {
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import type { PropertyValues } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { Condition } from "../../common/validate-condition";
|
||||
import { conditionsEntityContext } from "../conditions/context";
|
||||
import "../conditions/ha-card-conditions-editor";
|
||||
import "../conditions/ha-visibility-status";
|
||||
|
||||
@customElement("hui-card-visibility-editor")
|
||||
export class HuiCardVisibilityEditor extends LitElement {
|
||||
@@ -34,11 +34,10 @@ export class HuiCardVisibilityEditor extends LitElement {
|
||||
render() {
|
||||
const conditions = this.config.visibility ?? [];
|
||||
return html`
|
||||
<p class="intro">
|
||||
${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_card.visibility.explanation`
|
||||
)}
|
||||
</p>
|
||||
<ha-visibility-status
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
></ha-visibility-status>
|
||||
<ha-card-conditions-editor
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
@@ -62,10 +61,8 @@ export class HuiCardVisibilityEditor extends LitElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.intro {
|
||||
margin: 0;
|
||||
color: var(--secondary-text-color);
|
||||
margin-bottom: 8px;
|
||||
ha-visibility-status {
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@ import deepClone from "deep-clone-simple";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { ConditionListenersController } from "../../../../common/controllers/condition-listeners-controller";
|
||||
import { storage } from "../../../../common/decorators/storage";
|
||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||
import "../../../../components/automation/ha-automation-row-event-chip";
|
||||
import "../../../../components/automation/ha-automation-row-live-test";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-dropdown";
|
||||
@@ -33,11 +35,11 @@ import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||
import type {
|
||||
AndCondition,
|
||||
Condition,
|
||||
LegacyCondition,
|
||||
OrCondition,
|
||||
AndCondition,
|
||||
NotCondition,
|
||||
OrCondition,
|
||||
} from "../../common/validate-condition";
|
||||
import {
|
||||
checkConditionsMet,
|
||||
@@ -103,6 +105,13 @@ export class HaCardConditionEditor extends LitElement {
|
||||
|
||||
@state() private _testingResult?: boolean;
|
||||
|
||||
@state() private _liveTestResult: {
|
||||
state: "pass" | "fail" | "invalid" | "unknown";
|
||||
message?: string;
|
||||
} = { state: "unknown" };
|
||||
|
||||
private _listeners = new ConditionListenersController(this);
|
||||
|
||||
private get _editor() {
|
||||
if (!this._condition) return undefined;
|
||||
return customElements.get(
|
||||
@@ -116,6 +125,14 @@ export class HaCardConditionEditor extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _setupConditionListeners() {
|
||||
this._listeners.setup(
|
||||
this.condition ? [this.condition as Condition] : [],
|
||||
this.hass,
|
||||
() => this._evaluateLiveTest()
|
||||
);
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
if (changedProperties.has("condition")) {
|
||||
this._condition = {
|
||||
@@ -143,7 +160,61 @@ export class HaCardConditionEditor extends LitElement {
|
||||
if (!this._uiAvailable && !this._yamlMode) {
|
||||
this._yamlMode = true;
|
||||
}
|
||||
|
||||
this._setupConditionListeners();
|
||||
}
|
||||
|
||||
if (changedProperties.has("condition") || changedProperties.has("hass")) {
|
||||
this._evaluateLiveTest();
|
||||
}
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues<this>): void {
|
||||
if ((changedProperties as Map<string, unknown>).has("_entityContext")) {
|
||||
this._evaluateLiveTest();
|
||||
}
|
||||
}
|
||||
|
||||
private _evaluateLiveTest() {
|
||||
if (!this.condition || !this._condition) {
|
||||
this._liveTestResult = { state: "unknown" };
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isNoEntityCondition(this._condition.condition, this._noEntity) ||
|
||||
containsNoEntityCondition(this._condition, this._noEntity)
|
||||
) {
|
||||
this._liveTestResult = {
|
||||
state: "unknown",
|
||||
message: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.live_test_state.unknown"
|
||||
),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validateConditionalConfig([this.condition])) {
|
||||
this._liveTestResult = {
|
||||
state: "invalid",
|
||||
message: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.live_test_state.invalid"
|
||||
),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const testContext =
|
||||
this._entityContext?.mode === "current"
|
||||
? { entity_id: this._entityContext.entityId }
|
||||
: {};
|
||||
const pass = checkConditionsMet([this.condition], this.hass, testContext);
|
||||
this._liveTestResult = {
|
||||
state: pass ? "pass" : "fail",
|
||||
message: this.hass.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.live_test_state.${pass ? "pass" : "fail"}`
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
protected render() {
|
||||
@@ -151,6 +222,10 @@ export class HaCardConditionEditor extends LitElement {
|
||||
|
||||
if (!condition) return nothing;
|
||||
|
||||
const hideLiveTest =
|
||||
isNoEntityCondition(condition.condition, this._noEntity) ||
|
||||
containsNoEntityCondition(condition, this._noEntity);
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-expansion-panel left-chevron>
|
||||
@@ -164,6 +239,33 @@ export class HaCardConditionEditor extends LitElement {
|
||||
`ui.panel.lovelace.editor.condition-editor.condition.${condition.condition}.label`
|
||||
) || condition.condition}
|
||||
</h3>
|
||||
<ha-automation-row-event-chip
|
||||
.show=${this._testingResult !== undefined}
|
||||
.variant=${this._testingResult ? "success" : "warning"}
|
||||
slot="event"
|
||||
class="event-chip"
|
||||
aria-live="polite"
|
||||
>
|
||||
${this._testingResult
|
||||
? this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.testing_pass"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.testing_error"
|
||||
)}
|
||||
</ha-automation-row-event-chip>
|
||||
${hideLiveTest
|
||||
? nothing
|
||||
: html`
|
||||
<ha-automation-row-live-test
|
||||
slot="icons"
|
||||
.state=${this._liveTestResult.state}
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.live_test_state.${this._liveTestResult.state}`
|
||||
)}
|
||||
.message=${this._liveTestResult.message}
|
||||
></ha-automation-row-live-test>
|
||||
`}
|
||||
<ha-dropdown
|
||||
slot="icons"
|
||||
@wa-select=${this._handleAction}
|
||||
@@ -267,23 +369,6 @@ export class HaCardConditionEditor extends LitElement {
|
||||
`}
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
<div
|
||||
class="testing ${classMap({
|
||||
active: this._testingResult !== undefined,
|
||||
pass: this._testingResult === true,
|
||||
error: this._testingResult === false,
|
||||
})}"
|
||||
>
|
||||
${this._testingResult
|
||||
? this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.testing_pass"
|
||||
)
|
||||
: this._testingResult === false
|
||||
? this.hass.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.testing_error"
|
||||
)
|
||||
: nothing}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -418,41 +503,9 @@ export class HaCardConditionEditor extends LitElement {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
.testing {
|
||||
.event-chip {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
text-transform: uppercase;
|
||||
font-size: var(--ha-font-size-m);
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
background-color: var(--divider-color, #e0e0e0);
|
||||
color: var(--text-primary-color);
|
||||
max-height: 0px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s;
|
||||
text-align: center;
|
||||
border-top-right-radius: calc(
|
||||
var(--ha-card-border-radius, var(--ha-border-radius-lg)) - var(
|
||||
--ha-card-border-width,
|
||||
1px
|
||||
)
|
||||
);
|
||||
border-top-left-radius: calc(
|
||||
var(--ha-card-border-radius, var(--ha-border-radius-lg)) - var(
|
||||
--ha-card-border-width,
|
||||
1px
|
||||
)
|
||||
);
|
||||
}
|
||||
.testing.active {
|
||||
max-height: 100px;
|
||||
}
|
||||
.testing.error {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
.testing.pass {
|
||||
background-color: var(--success-color);
|
||||
inset-inline-end: 40px;
|
||||
}
|
||||
.container {
|
||||
position: relative;
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
import { consume } from "@lit/context";
|
||||
import { mdiAlertCircle, mdiEye, mdiEyeOff } from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ConditionListenersController } from "../../../../common/controllers/condition-listeners-controller";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import { HaRowItem } from "../../../../components/item/ha-row-item";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type {
|
||||
Condition,
|
||||
LegacyCondition,
|
||||
} from "../../common/validate-condition";
|
||||
import {
|
||||
checkConditionsMet,
|
||||
validateConditionalConfig,
|
||||
} from "../../common/validate-condition";
|
||||
import type { ConditionsEntityContext } from "./context";
|
||||
import { conditionsEntityContext } from "./context";
|
||||
|
||||
type VisibilityState = "visible" | "hidden" | "invalid";
|
||||
|
||||
const STATE_ICONS: Record<VisibilityState, string> = {
|
||||
visible: mdiEye,
|
||||
hidden: mdiEyeOff,
|
||||
invalid: mdiAlertCircle,
|
||||
};
|
||||
|
||||
/**
|
||||
* @element ha-visibility-status
|
||||
* @extends {HaRowItem}
|
||||
*
|
||||
* @summary
|
||||
* Row-style banner that surfaces the live visibility result for a set of
|
||||
* lovelace conditions. Replaces the static explanation alert at the top of
|
||||
* card / section / badge / conditional-card visibility editors.
|
||||
*
|
||||
* @attr {"visible"|"hidden"|"invalid"} state - Computed visibility state (reflected for styling).
|
||||
*/
|
||||
@customElement("ha-visibility-status")
|
||||
export class HaVisibilityStatus extends HaRowItem {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
public conditions: (Condition | LegacyCondition)[] = [];
|
||||
|
||||
@state()
|
||||
@consume({ context: conditionsEntityContext, subscribe: true })
|
||||
private _entityContext?: ConditionsEntityContext;
|
||||
|
||||
@property({ reflect: true })
|
||||
public state: VisibilityState = "visible";
|
||||
|
||||
private _listeners = new ConditionListenersController(this);
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
super.willUpdate(changedProperties);
|
||||
if (changedProperties.has("conditions") || changedProperties.has("hass")) {
|
||||
this._listeners.setup(
|
||||
(this.conditions ?? []) as Condition[],
|
||||
this.hass,
|
||||
() => this._evaluate()
|
||||
);
|
||||
}
|
||||
if (
|
||||
changedProperties.has("hass") ||
|
||||
changedProperties.has("conditions") ||
|
||||
(changedProperties as Map<string, unknown>).has("_entityContext")
|
||||
) {
|
||||
this._evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override _renderInner(): TemplateResult {
|
||||
return html`
|
||||
<div part="start" class="start">
|
||||
<ha-svg-icon .path=${STATE_ICONS[this.state]}></ha-svg-icon>
|
||||
</div>
|
||||
<div part="content" class="content">
|
||||
<div part="headline" class="headline">
|
||||
${this.hass?.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.visibility_status.${this.state}.headline`
|
||||
)}
|
||||
</div>
|
||||
<div part="supporting-text" class="supporting">
|
||||
${this.hass?.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.visibility_status.${this.state}.supporting${(this.conditions?.length ?? 0) === 0 ? "_empty" : ""}`
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _evaluate() {
|
||||
const conditions = this.conditions ?? [];
|
||||
let newState: VisibilityState;
|
||||
if (conditions.length === 0) {
|
||||
newState = "visible";
|
||||
} else if (!validateConditionalConfig(conditions)) {
|
||||
newState = "invalid";
|
||||
} else {
|
||||
const context =
|
||||
this._entityContext?.mode === "current"
|
||||
? { entity_id: this._entityContext.entityId }
|
||||
: {};
|
||||
newState = checkConditionsMet(conditions, this.hass, context)
|
||||
? "visible"
|
||||
: "hidden";
|
||||
}
|
||||
if (newState === this.state) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.state = newState;
|
||||
}
|
||||
|
||||
static styles: CSSResultGroup = [
|
||||
HaRowItem.styles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
border-radius: var(--ha-border-radius-xl);
|
||||
transition: background-color var(--ha-animation-duration-normal)
|
||||
ease-in-out;
|
||||
}
|
||||
.base {
|
||||
padding: var(--ha-space-4);
|
||||
}
|
||||
:host([state="visible"]) {
|
||||
background-color: var(--ha-color-fill-success-quiet-resting);
|
||||
--visibility-status-color: var(--ha-color-on-success-normal);
|
||||
}
|
||||
:host([state="hidden"]) {
|
||||
background-color: var(--ha-color-fill-warning-quiet-resting);
|
||||
--visibility-status-color: var(--ha-color-on-warning-normal);
|
||||
}
|
||||
:host([state="invalid"]) {
|
||||
background-color: var(--ha-color-fill-danger-quiet-resting);
|
||||
--visibility-status-color: var(--ha-color-on-danger-normal);
|
||||
}
|
||||
.start {
|
||||
align-self: start;
|
||||
}
|
||||
.start ha-svg-icon {
|
||||
color: var(--visibility-status-color);
|
||||
--mdc-icon-size: 24px;
|
||||
}
|
||||
.headline {
|
||||
font-weight: var(--ha-font-weight-medium);
|
||||
white-space: normal;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-visibility-status": HaVisibilityStatus;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import { any, array, assert, assign, object, optional } from "superstruct";
|
||||
import { storage } from "../../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
import "../../../../components/ha-tab-group";
|
||||
@@ -21,6 +20,7 @@ import "../card-editor/hui-card-element-editor";
|
||||
import type { HuiCardElementEditor } from "../card-editor/hui-card-element-editor";
|
||||
import "../card-editor/hui-card-picker";
|
||||
import "../conditions/ha-card-conditions-editor";
|
||||
import "../conditions/ha-visibility-status";
|
||||
import "../hui-element-editor";
|
||||
import type { ConfigChangedEvent } from "../hui-element-editor";
|
||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||
@@ -147,11 +147,10 @@ export class HuiConditionalCardEditor
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<ha-alert alert-type="info">
|
||||
${this.hass!.localize(
|
||||
"ui.panel.lovelace.editor.condition-editor.explanation"
|
||||
)}
|
||||
</ha-alert>
|
||||
<ha-visibility-status
|
||||
.hass=${this.hass}
|
||||
.conditions=${this._config.conditions ?? []}
|
||||
></ha-visibility-status>
|
||||
<ha-card-conditions-editor
|
||||
.hass=${this.hass}
|
||||
.conditions=${this._config.conditions}
|
||||
@@ -246,9 +245,9 @@ export class HuiConditionalCardEditor
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
ha-alert {
|
||||
display: block;
|
||||
margin-top: 12px;
|
||||
ha-visibility-status {
|
||||
margin-top: var(--ha-space-3);
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
.card {
|
||||
margin-top: 8px;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-alert";
|
||||
import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { Condition } from "../../common/validate-condition";
|
||||
import "../conditions/ha-card-conditions-editor";
|
||||
import "../conditions/ha-visibility-status";
|
||||
|
||||
@customElement("hui-section-visibility-editor")
|
||||
export class HuiDialogEditSection extends LitElement {
|
||||
@@ -16,11 +16,10 @@ export class HuiDialogEditSection extends LitElement {
|
||||
render() {
|
||||
const conditions = this.config.visibility ?? [];
|
||||
return html`
|
||||
<ha-alert alert-type="info">
|
||||
${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_section.visibility.explanation`
|
||||
)}
|
||||
</ha-alert>
|
||||
<ha-visibility-status
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
></ha-visibility-status>
|
||||
<ha-card-conditions-editor
|
||||
.hass=${this.hass}
|
||||
.conditions=${conditions}
|
||||
@@ -30,6 +29,12 @@ export class HuiDialogEditSection extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-visibility-status {
|
||||
margin-bottom: var(--ha-space-3);
|
||||
}
|
||||
`;
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const conditions = ev.detail.value as Condition[];
|
||||
|
||||
@@ -22,7 +22,7 @@ import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-slider";
|
||||
import { isUnavailableState } from "../../../data/entity/entity";
|
||||
import { UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import type {
|
||||
ControlButton,
|
||||
MediaPlayerEntity,
|
||||
@@ -195,7 +195,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
||||
<div class="controls">
|
||||
${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON) &&
|
||||
(!stateActive(stateObj) || assumedState) &&
|
||||
!isUnavailableState(entityState)
|
||||
entityState !== UNAVAILABLE
|
||||
? html`
|
||||
<ha-icon-button
|
||||
.path=${assumedState ? mdiPowerOn : mdiPower}
|
||||
@@ -209,7 +209,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
||||
(stateActive(stateObj) ||
|
||||
assumedState ||
|
||||
!supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON) ||
|
||||
isUnavailableState(entityState))
|
||||
entityState === UNAVAILABLE)
|
||||
? buttons
|
||||
: ""}
|
||||
${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_OFF) &&
|
||||
|
||||
+22
-16
@@ -5043,11 +5043,6 @@
|
||||
"placeholder": "Optional description",
|
||||
"add": "Add description"
|
||||
},
|
||||
"comment": {
|
||||
"label": "Comment",
|
||||
"edit": "Edit comment",
|
||||
"add": "Add comment"
|
||||
},
|
||||
"leave": {
|
||||
"unsaved_new_title": "Save new automation?",
|
||||
"unsaved_new_text": "You can save your changes, or delete this automation. You can't undo this action.",
|
||||
@@ -8934,9 +8929,6 @@
|
||||
"tab_visibility": "Visibility",
|
||||
"tab_layout": "Layout",
|
||||
"paste_condition": "Paste condition",
|
||||
"visibility": {
|
||||
"explanation": "The card will be shown when ALL conditions below are fulfilled. If no conditions are set, the card will always be shown."
|
||||
},
|
||||
"layout": {
|
||||
"full_width": "Full width",
|
||||
"full_width_helper": "Take up the full width of the section whatever its size",
|
||||
@@ -8967,10 +8959,7 @@
|
||||
"cut": "[%key:ui::panel::lovelace::editor::edit_card::cut%]",
|
||||
"duplicate": "[%key:ui::panel::lovelace::editor::edit_card::duplicate%]",
|
||||
"tab_config": "[%key:ui::panel::lovelace::editor::edit_card::tab_config%]",
|
||||
"tab_visibility": "[%key:ui::panel::lovelace::editor::edit_card::tab_visibility%]",
|
||||
"visibility": {
|
||||
"explanation": "The badge will be shown when ALL conditions below are fulfilled. If no conditions are set, the badge will always be shown."
|
||||
}
|
||||
"tab_visibility": "[%key:ui::panel::lovelace::editor::edit_card::tab_visibility%]"
|
||||
},
|
||||
"suggest_badge": {
|
||||
"header": "[%key:ui::panel::lovelace::editor::suggest_card::header%]",
|
||||
@@ -9042,9 +9031,6 @@
|
||||
"background_opacity": "Opacity",
|
||||
"theme": "Theme",
|
||||
"theme_helper": "Apply a specific theme to this section, overriding the view theme"
|
||||
},
|
||||
"visibility": {
|
||||
"explanation": "The section will be shown when ALL conditions below are fulfilled. If no conditions are set, the section will always be shown."
|
||||
}
|
||||
},
|
||||
"suggest_card": {
|
||||
@@ -9086,11 +9072,31 @@
|
||||
}
|
||||
},
|
||||
"condition-editor": {
|
||||
"explanation": "The card will be shown when ALL conditions below are fulfilled.",
|
||||
"add": "Add condition",
|
||||
"test": "[%key:ui::panel::config::automation::editor::conditions::test%]",
|
||||
"testing_pass": "[%key:ui::panel::config::automation::editor::conditions::testing_pass%]",
|
||||
"testing_error": "[%key:ui::panel::config::automation::editor::conditions::testing_error%]",
|
||||
"live_test_state": {
|
||||
"pass": "[%key:ui::panel::config::automation::editor::conditions::testing_pass%]",
|
||||
"fail": "[%key:ui::panel::config::automation::editor::conditions::testing_error%]",
|
||||
"invalid": "[%key:ui::panel::config::automation::editor::conditions::live_test_state::invalid%]",
|
||||
"unknown": "[%key:ui::panel::config::automation::editor::conditions::live_test_state::unknown%]"
|
||||
},
|
||||
"visibility_status": {
|
||||
"visible": {
|
||||
"headline": "Current visibility: Visible",
|
||||
"supporting": "All visibility conditions are met",
|
||||
"supporting_empty": "No visibility conditions are set"
|
||||
},
|
||||
"hidden": {
|
||||
"headline": "Current visibility: Hidden",
|
||||
"supporting": "Not all visibility conditions are met"
|
||||
},
|
||||
"invalid": {
|
||||
"headline": "Visibility status unknown",
|
||||
"supporting": "One or more conditions have an invalid configuration"
|
||||
}
|
||||
},
|
||||
"invalid_config_title": "Invalid configuration",
|
||||
"invalid_config_text": "The condition cannot be tested because the configuration is not valid.",
|
||||
"condition": {
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
export const IFRAME_SANDBOX =
|
||||
"allow-forms allow-popups allow-pointer-lock allow-same-origin allow-scripts allow-modals allow-downloads";
|
||||
"allow-forms allow-popups allow-pointer-lock allow-scripts allow-modals allow-downloads";
|
||||
|
||||
@@ -4335,129 +4335,141 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/basic@npm:^3.7.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/basic@npm:3.9.1"
|
||||
"@tsparticles/basic@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/basic@npm:4.0.0"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
"@tsparticles/move-base": "npm:3.9.1"
|
||||
"@tsparticles/plugin-hex-color": "npm:3.9.1"
|
||||
"@tsparticles/plugin-hsl-color": "npm:3.9.1"
|
||||
"@tsparticles/plugin-rgb-color": "npm:3.9.1"
|
||||
"@tsparticles/shape-circle": "npm:3.9.1"
|
||||
"@tsparticles/updater-color": "npm:3.9.1"
|
||||
"@tsparticles/updater-opacity": "npm:3.9.1"
|
||||
"@tsparticles/updater-out-modes": "npm:3.9.1"
|
||||
"@tsparticles/updater-size": "npm:3.9.1"
|
||||
checksum: 10/a3d0c926e5822931df9762b2038955093ecfb558715807482f691d54efb848286a5d78a55a184885b2d4f46a005bf52c3c54e0013e29e71158ae1ccb5dce08d3
|
||||
"@tsparticles/engine": "npm:4.0.0"
|
||||
"@tsparticles/plugin-hex-color": "npm:4.0.0"
|
||||
"@tsparticles/plugin-hsl-color": "npm:4.0.0"
|
||||
"@tsparticles/plugin-move": "npm:4.0.0"
|
||||
"@tsparticles/plugin-rgb-color": "npm:4.0.0"
|
||||
"@tsparticles/shape-circle": "npm:4.0.0"
|
||||
"@tsparticles/updater-opacity": "npm:4.0.0"
|
||||
"@tsparticles/updater-out-modes": "npm:4.0.0"
|
||||
"@tsparticles/updater-paint": "npm:4.0.0"
|
||||
"@tsparticles/updater-size": "npm:4.0.0"
|
||||
checksum: 10/5e455beb0663019d719bc111928a9e22a0f471450414391eed4be2f00455019c59ec85e1e8b7fadf8da2dc258c803d555ebb9b2e0a497a8f53b5922fffab314e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/engine@npm:3.9.1, @tsparticles/engine@npm:^3.7.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/engine@npm:3.9.1"
|
||||
checksum: 10/91e95f33d526558e0f7251a75dc2971873a7854bb903b61aab95d394c954d3d5f6c2429c151483ebe83445e14e2a7ed9ceadb0fd9c0b7e8c11ec316e4bfd04fa
|
||||
"@tsparticles/engine@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/engine@npm:4.0.0"
|
||||
checksum: 10/05fd84ad82f75c9a9d44280ed948d9340cbfb5b18a18f112ee08c0c7d70ba35687197c9ce7508f7c2600410f42075369f2708504485912eb57e5e6e1cf8394ef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/interaction-particles-links@npm:^3.7.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/interaction-particles-links@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/be3925f0892de0eb9a4bc35b1ad402a462874272174379625bccce4c162a528d4f2a4526398f1b4a8b53ff27dae95e2b42a799a9c81ab99e233a9d16c7123774
|
||||
"@tsparticles/interaction-particles-links@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/interaction-particles-links@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/canvas-utils": 4.0.0
|
||||
"@tsparticles/engine": 4.0.0
|
||||
"@tsparticles/plugin-interactivity": 4.0.0
|
||||
checksum: 10/98d7defc0af362775339f4d7016fa096d352065579036837c99c1a721d88f3207a074075d78130b95236e60a77f66dd29fe957b42e26b7421bdfb797e3271a28
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/move-base@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/move-base@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/d03795bb4d789295ce4179e1b22d618658a15c31915cba5c8f137bf4a8f183186e3969145ef3951df07fddea0e9d1830a4e25a22baa70d904769c488041da40c
|
||||
"@tsparticles/plugin-hex-color@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/plugin-hex-color@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/356310741b0019bcdd352e2affc9090662d7191aff932a1e2743c8d1911f87bd8a49a623a3733cf032911884d52b4e65a291267f37e28513c597d5cd4cadba1e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/plugin-hex-color@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/plugin-hex-color@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/726a2ae6182bc6e40ed443e1d664bae7ddb4e606a108e92a0c5fc50f0623105144672295720c06e915ef0e36c2a2455ed80dc335a850f11e3a1de1ad44e4ed08
|
||||
"@tsparticles/plugin-hsl-color@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/plugin-hsl-color@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/cb04a297a40fdad04f25dfaa10d77a04c70dceded6c24e6f3ab766d5cc70514464011527d822fc883bb5da5003fdd5d8ab92b71046cb290a3c8ca60f7a40483f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/plugin-hsl-color@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/plugin-hsl-color@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/f81aaed365045e437c8f1627c03f3d255dd2bba2d5ff5231b5e90d576b24fbb5dc110f3b860e13d8696ef820feb465414c0e62962a59e55e6e4a86883cb0f003
|
||||
"@tsparticles/plugin-interactivity@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/plugin-interactivity@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/23b089e537f5fed67fe7e3cf6b67aa639d9586ebda6838d349d9a02095449ca7bcfe164040a9fa08bdfd779f44ae5917434a335e5c67db5df6d6a6bfd521819e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/plugin-rgb-color@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/plugin-rgb-color@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/17352010973ad83e6c9292722896dd0eef0b9f4411684d3fbcf110363bd2aa41594a77b28709dbf1ee9945624567d945ef71900cb37630b0da68714375333c6f
|
||||
"@tsparticles/plugin-move@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/plugin-move@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/abc5d175105243171ce440d88ae322f2412fb1c390bd39859fde1dc201b528e5d6099f38fa4a87a47ff110eaf65a930306922c409b1404271ba61d222ca9e48d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/preset-links@npm:3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "@tsparticles/preset-links@npm:3.2.0"
|
||||
dependencies:
|
||||
"@tsparticles/basic": "npm:^3.7.1"
|
||||
"@tsparticles/engine": "npm:^3.7.1"
|
||||
"@tsparticles/interaction-particles-links": "npm:^3.7.1"
|
||||
checksum: 10/1cae6c097d3cac1ba210ed681a40626a79f8579a4e82b1827e0b5864b1cb1fb737471f699800447a7a2bd6e17c706b05db36f84741d9f0c9600bd638e7e29999
|
||||
"@tsparticles/plugin-rgb-color@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/plugin-rgb-color@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/7d2255d5f428c56cd56fcf00839707ca3fa554a25fa59b2353e30c1c275ca24f06b9f2eee28a869633a740c56b3609cb6540135fb7297ec54d5fcc140e2ce575
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/shape-circle@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/shape-circle@npm:3.9.1"
|
||||
"@tsparticles/preset-links@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/preset-links@npm:4.0.0"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/1f0e5add252ee6e59b32b018b585106189a8938798e879a5a09b42434091c82f748b7656206d316705d65821f45e87bb9ef4c7a240c33be4384dbef0def1e2f5
|
||||
"@tsparticles/basic": "npm:4.0.0"
|
||||
"@tsparticles/engine": "npm:4.0.0"
|
||||
"@tsparticles/interaction-particles-links": "npm:4.0.0"
|
||||
"@tsparticles/plugin-interactivity": "npm:4.0.0"
|
||||
checksum: 10/67d8c4c90c44a9f3f940aa249e2b86acef4485a54ac02005de5b947cc3c2d01d4b6b00695dc5ff47ab0a8594faa18ba2ccf05b7510f7fd84993939f7d137121e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/updater-color@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/updater-color@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/5c4cb7fc7f4767461abffd3ba90ee2c5dba8a7cd3a38d6278314bb9d074c7e5f4977844f4c84448af00e24c923e4635f9392b320fffbac644ae59f157c6ed5b0
|
||||
"@tsparticles/shape-circle@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/shape-circle@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/37f010c44ba9b82712532da32c2cb6e482d5f5205aaf3bcd7fb04c87925218cd732a31d69ae424613810f11b2651a80fbbd9ec9d6b9d0e58884022ec68cc9d5b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/updater-opacity@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/updater-opacity@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/c0ecfd623bdb9cf6ece47098403cb19ce4d9c6204b19ca65357c106f400b4faf2e8f3a51a7ae518b9f708ba549073b4ea8ad8f2282dc298016437a62659298f4
|
||||
"@tsparticles/updater-opacity@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/updater-opacity@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/b078a28175372246d6861562bcc013c03dff88f6aeaf9b16558e533477340e1b3cd07d57997bdf11b730636df26ef0117bef9ba4ab1b791a9b9a4cd1d2e6623e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/updater-out-modes@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/updater-out-modes@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/b74bb0987aacabaeabc981fbbeffb362263ad69cea2f1733b0f5b8753a5c7338ca51eb02164a41d0a70b75ae0bd6e2f2c16c0bc0b4805b367122536df110f21a
|
||||
"@tsparticles/updater-out-modes@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/updater-out-modes@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/3b27af0a68a7f320ae2481142ff9d6e342b75f245b94e875ea2bdc3f9f47c0b8e79b7ddbf45fea5eeaa9e4610dbdb7130e10056b1f26618958e7e6c28e25dbbe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/updater-size@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "@tsparticles/updater-size@npm:3.9.1"
|
||||
dependencies:
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
checksum: 10/211038b9cadd1df1a0fb747d2e1eeff9f1ce57fd4828e838ddfe6b5365feb3f625e7f713380bc819601d88c50ba4b122a401eae627449760d94c95cff85efdb3
|
||||
"@tsparticles/updater-paint@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/updater-paint@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/22f9c275ee3eb1409923c74b63fc5984d978b68473bd0f58418d6c28a9be0e9e2e010e338adb7deb482021ab444fab85b962745c06d94066dd40265cf016395d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@tsparticles/updater-size@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@tsparticles/updater-size@npm:4.0.0"
|
||||
peerDependencies:
|
||||
"@tsparticles/engine": 4.0.0
|
||||
checksum: 10/4664fc5c4c961331d733d98287e9fef0079077def528b814034aea163eb95e2f6c0549e1b87e95eef5f376a7cd0983fbf18c2d77023b9f1f1b163698b03ec504
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8762,8 +8774,8 @@ __metadata:
|
||||
"@rspack/dev-server": "npm:2.0.1"
|
||||
"@swc/helpers": "npm:0.5.21"
|
||||
"@thomasloven/round-slider": "npm:0.6.0"
|
||||
"@tsparticles/engine": "npm:3.9.1"
|
||||
"@tsparticles/preset-links": "npm:3.2.0"
|
||||
"@tsparticles/engine": "npm:4.0.0"
|
||||
"@tsparticles/preset-links": "npm:4.0.0"
|
||||
"@types/babel__plugin-transform-runtime": "npm:7.9.5"
|
||||
"@types/chromecast-caf-receiver": "npm:6.0.26"
|
||||
"@types/chromecast-caf-sender": "npm:1.0.11"
|
||||
|
||||
Reference in New Issue
Block a user