mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-09 10:59:50 +00:00
Compare commits
3 Commits
update-hov
...
feature/ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcaabfb326 | ||
|
|
defc379a92 | ||
|
|
b539ffcc50 |
@@ -1106,7 +1106,7 @@ export default {
|
|||||||
friendly_name: "Philips Hue",
|
friendly_name: "Philips Hue",
|
||||||
entity_picture: null,
|
entity_picture: null,
|
||||||
description:
|
description:
|
||||||
"Press the button on the bridge to register Philips Hue with Home Assistant.",
|
"Press the button on the bridge to register Philips Hue with Home Assistant.\n\n",
|
||||||
submit_caption: "I have pressed the button",
|
submit_caption: "I have pressed the button",
|
||||||
},
|
},
|
||||||
last_changed: "2018-07-19T10:44:46.515160+00:00",
|
last_changed: "2018-07-19T10:44:46.515160+00:00",
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
"lit": "3.3.1",
|
"lit": "3.3.1",
|
||||||
"lit-html": "3.3.1",
|
"lit-html": "3.3.1",
|
||||||
"luxon": "3.7.1",
|
"luxon": "3.7.1",
|
||||||
"marked": "16.2.1",
|
"marked": "16.2.0",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
"node-vibrant": "4.0.3",
|
"node-vibrant": "4.0.3",
|
||||||
"object-hash": "3.0.0",
|
"object-hash": "3.0.0",
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
"@octokit/plugin-retry": "8.0.1",
|
"@octokit/plugin-retry": "8.0.1",
|
||||||
"@octokit/rest": "22.0.0",
|
"@octokit/rest": "22.0.0",
|
||||||
"@rsdoctor/rspack-plugin": "1.2.3",
|
"@rsdoctor/rspack-plugin": "1.2.3",
|
||||||
"@rspack/core": "1.5.1",
|
"@rspack/core": "1.4.11",
|
||||||
"@rspack/dev-server": "1.1.4",
|
"@rspack/dev-server": "1.1.4",
|
||||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||||
"@types/chromecast-caf-receiver": "6.0.22",
|
"@types/chromecast-caf-receiver": "6.0.22",
|
||||||
|
|||||||
BIN
public/static/images/config_philips_hue.jpg
Normal file
BIN
public/static/images/config_philips_hue.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -25,8 +25,6 @@ export class HaAutomationRow extends LitElement {
|
|||||||
@property({ type: Boolean, reflect: true, attribute: "building-block" })
|
@property({ type: Boolean, reflect: true, attribute: "building-block" })
|
||||||
public buildingBlock = false;
|
public buildingBlock = false;
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true }) public highlight?: boolean;
|
|
||||||
|
|
||||||
@query(".row")
|
@query(".row")
|
||||||
private _rowElement?: HTMLDivElement;
|
private _rowElement?: HTMLDivElement;
|
||||||
|
|
||||||
@@ -170,20 +168,9 @@ export class HaAutomationRow extends LitElement {
|
|||||||
margin: 0 12px;
|
margin: 0 12px;
|
||||||
}
|
}
|
||||||
:host([sort-selected]) .row {
|
:host([sort-selected]) .row {
|
||||||
outline: solid;
|
box-shadow:
|
||||||
outline-color: rgba(var(--rgb-accent-color), 0.6);
|
0px 0px 8px 4px rgba(var(--rgb-accent-color), 0.8),
|
||||||
outline-offset: -2px;
|
inset 0px 2px 8px 4px rgba(var(--rgb-accent-color), 0.4);
|
||||||
outline-width: 2px;
|
|
||||||
background-color: rgba(var(--rgb-accent-color), 0.08);
|
|
||||||
}
|
|
||||||
.row:hover {
|
|
||||||
background-color: rgba(var(--rgb-primary-text-color), 0.04);
|
|
||||||
}
|
|
||||||
:host([highlight]) .row {
|
|
||||||
background-color: rgba(var(--rgb-primary-color), 0.08);
|
|
||||||
}
|
|
||||||
:host([highlight]) .row:hover {
|
|
||||||
background-color: rgba(var(--rgb-primary-color), 0.16);
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -393,13 +393,10 @@ export class HaItemDisplayEditor extends LitElement {
|
|||||||
--md-list-item-one-line-container-height: 48px;
|
--md-list-item-one-line-container-height: 48px;
|
||||||
}
|
}
|
||||||
ha-md-list-item.drag-selected {
|
ha-md-list-item.drag-selected {
|
||||||
--md-focus-ring-color: rgba(var(--rgb-accent-color), 0.6);
|
box-shadow:
|
||||||
|
0px 0px 8px 4px rgba(var(--rgb-accent-color), 0.8),
|
||||||
|
inset 0px 2px 8px 4px rgba(var(--rgb-accent-color), 0.4);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
outline: solid;
|
|
||||||
outline-color: rgba(var(--rgb-accent-color), 0.6);
|
|
||||||
outline-offset: -2px;
|
|
||||||
outline-width: 2px;
|
|
||||||
background-color: rgba(var(--rgb-accent-color), 0.08);
|
|
||||||
}
|
}
|
||||||
ha-md-list-item ha-icon-button {
|
ha-md-list-item ha-icon-button {
|
||||||
margin-left: -12px;
|
margin-left: -12px;
|
||||||
|
|||||||
@@ -53,15 +53,9 @@ export class HaMediaSelector extends LitElement {
|
|||||||
|
|
||||||
private _contextEntities: string[] | undefined;
|
private _contextEntities: string[] | undefined;
|
||||||
|
|
||||||
private get _hasAccept(): boolean {
|
|
||||||
return !!this.selector?.media?.accept?.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
willUpdate(changedProps: PropertyValues<this>) {
|
willUpdate(changedProps: PropertyValues<this>) {
|
||||||
if (changedProps.has("context")) {
|
if (changedProps.has("context")) {
|
||||||
if (!this._hasAccept) {
|
this._contextEntities = ensureArray(this.context?.filter_entity);
|
||||||
this._contextEntities = ensureArray(this.context?.filter_entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changedProps.has("value")) {
|
if (changedProps.has("value")) {
|
||||||
@@ -105,8 +99,10 @@ export class HaMediaSelector extends LitElement {
|
|||||||
(stateObj &&
|
(stateObj &&
|
||||||
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA));
|
supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA));
|
||||||
|
|
||||||
|
const hasAccept = this.selector?.media?.accept?.length;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this._hasAccept ||
|
${hasAccept ||
|
||||||
(this._contextEntities && this._contextEntities.length <= 1)
|
(this._contextEntities && this._contextEntities.length <= 1)
|
||||||
? nothing
|
? nothing
|
||||||
: html`
|
: html`
|
||||||
@@ -152,7 +148,7 @@ export class HaMediaSelector extends LitElement {
|
|||||||
: this.value.metadata?.title || this.value.media_content_id}
|
: this.value.metadata?.title || this.value.media_content_id}
|
||||||
@click=${this._pickMedia}
|
@click=${this._pickMedia}
|
||||||
@keydown=${this._handleKeyDown}
|
@keydown=${this._handleKeyDown}
|
||||||
class=${this.disabled || (!entityId && !this._hasAccept)
|
class=${this.disabled || (!entityId && !hasAccept)
|
||||||
? "disabled"
|
? "disabled"
|
||||||
: ""}
|
: ""}
|
||||||
>
|
>
|
||||||
@@ -219,7 +215,7 @@ export class HaMediaSelector extends LitElement {
|
|||||||
|
|
||||||
private _entityChanged(ev: CustomEvent) {
|
private _entityChanged(ev: CustomEvent) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (!this._hasAccept && this.context?.filter_entity) {
|
if (this.context?.filter_entity) {
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: {
|
value: {
|
||||||
media_content_id: "",
|
media_content_id: "",
|
||||||
@@ -261,7 +257,7 @@ export class HaMediaSelector extends LitElement {
|
|||||||
media_content_type: id.media_content_type,
|
media_content_type: id.media_content_type,
|
||||||
media_content_id: id.media_content_id,
|
media_content_id: id.media_content_id,
|
||||||
})),
|
})),
|
||||||
...(!this._hasAccept && this.context?.filter_entity
|
...(this.context?.filter_entity
|
||||||
? { browse_entity_id: this._getActiveEntityId() }
|
? { browse_entity_id: this._getActiveEntityId() }
|
||||||
: {}),
|
: {}),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -556,6 +556,7 @@ export interface AutomationClipboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BaseSidebarConfig {
|
export interface BaseSidebarConfig {
|
||||||
|
toggleYamlMode: () => boolean;
|
||||||
delete: () => void;
|
delete: () => void;
|
||||||
close: (focus?: boolean) => void;
|
close: (focus?: boolean) => void;
|
||||||
}
|
}
|
||||||
@@ -567,7 +568,6 @@ export interface TriggerSidebarConfig extends BaseSidebarConfig {
|
|||||||
duplicate: () => void;
|
duplicate: () => void;
|
||||||
cut: () => void;
|
cut: () => void;
|
||||||
copy: () => void;
|
copy: () => void;
|
||||||
toggleYamlMode: () => void;
|
|
||||||
config: Trigger;
|
config: Trigger;
|
||||||
yamlMode: boolean;
|
yamlMode: boolean;
|
||||||
uiSupported: boolean;
|
uiSupported: boolean;
|
||||||
@@ -581,7 +581,6 @@ export interface ConditionSidebarConfig extends BaseSidebarConfig {
|
|||||||
duplicate: () => void;
|
duplicate: () => void;
|
||||||
cut: () => void;
|
cut: () => void;
|
||||||
copy: () => void;
|
copy: () => void;
|
||||||
toggleYamlMode: () => void;
|
|
||||||
config: Condition;
|
config: Condition;
|
||||||
yamlMode: boolean;
|
yamlMode: boolean;
|
||||||
uiSupported: boolean;
|
uiSupported: boolean;
|
||||||
@@ -595,7 +594,6 @@ export interface ActionSidebarConfig extends BaseSidebarConfig {
|
|||||||
cut: () => void;
|
cut: () => void;
|
||||||
copy: () => void;
|
copy: () => void;
|
||||||
run: () => void;
|
run: () => void;
|
||||||
toggleYamlMode: () => void;
|
|
||||||
config: {
|
config: {
|
||||||
action: Action;
|
action: Action;
|
||||||
};
|
};
|
||||||
@@ -617,7 +615,6 @@ export interface ScriptFieldSidebarConfig extends BaseSidebarConfig {
|
|||||||
key: string;
|
key: string;
|
||||||
excludeKeys: string[];
|
excludeKeys: string[];
|
||||||
};
|
};
|
||||||
toggleYamlMode: () => void;
|
|
||||||
yamlMode: boolean;
|
yamlMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default class HaAutomationActionEditor extends LitElement {
|
|||||||
if (!ev.detail.isValid) {
|
if (!ev.detail.isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fireEvent(this, "yaml-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: migrateAutomationAction(ev.detail.value),
|
value: migrateAutomationAction(ev.detail.value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,8 +151,6 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public last?: boolean;
|
@property({ type: Boolean }) public last?: boolean;
|
||||||
|
|
||||||
@property({ type: Boolean }) public highlight?: boolean;
|
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "sidebar" })
|
@property({ type: Boolean, attribute: "sidebar" })
|
||||||
public optionsInSidebar = false;
|
public optionsInSidebar = false;
|
||||||
|
|
||||||
@@ -449,7 +447,6 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
))}
|
))}
|
||||||
.collapsed=${this._collapsed}
|
.collapsed=${this._collapsed}
|
||||||
.selected=${this._selected}
|
.selected=${this._selected}
|
||||||
.highlight=${this.highlight}
|
|
||||||
@toggle-collapsed=${this._toggleCollapse}
|
@toggle-collapsed=${this._toggleCollapse}
|
||||||
.buildingBlock=${[
|
.buildingBlock=${[
|
||||||
...ACTION_BUILDING_BLOCKS,
|
...ACTION_BUILDING_BLOCKS,
|
||||||
@@ -691,7 +688,7 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
},
|
},
|
||||||
toggleYamlMode: () => {
|
toggleYamlMode: () => {
|
||||||
this._toggleYamlMode();
|
this._toggleYamlMode();
|
||||||
this.openSidebar();
|
return this._yamlMode;
|
||||||
},
|
},
|
||||||
disable: this._onDisable,
|
disable: this._onDisable,
|
||||||
delete: this._onDelete,
|
delete: this._onDelete,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { LitElement, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, queryAll, state } from "lit/decorators";
|
import { customElement, property, queryAll, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nextRender } from "../../../../common/util/render-status";
|
import { nextRender } from "../../../../common/util/render-status";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-sortable";
|
import "../../../../components/ha-sortable";
|
||||||
@@ -45,6 +46,8 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar =
|
@property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar =
|
||||||
false;
|
false;
|
||||||
|
|
||||||
|
@state() private _showReorder = false;
|
||||||
|
|
||||||
@state() private _rowSortSelected?: number;
|
@state() private _rowSortSelected?: number;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
@@ -65,12 +68,27 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
|
|
||||||
private _actionKeys = new WeakMap<Action, string>();
|
private _actionKeys = new WeakMap<Action, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
draggable-selector="ha-automation-action-row"
|
draggable-selector="ha-automation-action-row"
|
||||||
.disabled=${this.disabled}
|
.disabled=${!this._showReorder || this.disabled}
|
||||||
group="actions"
|
group="actions"
|
||||||
invert-swap
|
invert-swap
|
||||||
@item-moved=${this._actionMoved}
|
@item-moved=${this._actionMoved}
|
||||||
@@ -97,12 +115,12 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
@move-up=${this._moveUp}
|
@move-up=${this._moveUp}
|
||||||
@value-changed=${this._actionChanged}
|
@value-changed=${this._actionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.highlight=${this.highlightedActions?.includes(action)}
|
?highlight=${this.highlightedActions?.includes(action)}
|
||||||
.optionsInSidebar=${this.optionsInSidebar}
|
.optionsInSidebar=${this.optionsInSidebar}
|
||||||
.sortSelected=${this._rowSortSelected === idx}
|
.sortSelected=${this._rowSortSelected === idx}
|
||||||
@stop-sort-selection=${this._stopSortSelection}
|
@stop-sort-selection=${this._stopSortSelection}
|
||||||
>
|
>
|
||||||
${!this.disabled
|
${this._showReorder && !this.disabled
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@@ -391,7 +409,14 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = automationRowsStyles;
|
static styles = [
|
||||||
|
automationRowsStyles,
|
||||||
|
css`
|
||||||
|
:host([root]) .rows {
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -103,7 +103,8 @@ export default class HaAutomationConditionEditor extends LitElement {
|
|||||||
if (!ev.detail.isValid) {
|
if (!ev.detail.isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fireEvent(this, "yaml-changed", { value: ev.detail.value });
|
// @ts-ignore
|
||||||
|
fireEvent(this, "value-changed", { value: ev.detail.value, yaml: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onUiChanged(ev: CustomEvent) {
|
private _onUiChanged(ev: CustomEvent) {
|
||||||
|
|||||||
@@ -116,8 +116,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public highlight?: boolean;
|
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "sort-selected" })
|
@property({ type: Boolean, attribute: "sort-selected" })
|
||||||
public sortSelected = false;
|
public sortSelected = false;
|
||||||
|
|
||||||
@@ -357,7 +355,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
)}
|
)}
|
||||||
.collapsed=${this._collapsed}
|
.collapsed=${this._collapsed}
|
||||||
.selected=${this._selected}
|
.selected=${this._selected}
|
||||||
.highlight=${this.highlight}
|
|
||||||
@click=${this._toggleSidebar}
|
@click=${this._toggleSidebar}
|
||||||
@toggle-collapsed=${this._toggleCollapse}
|
@toggle-collapsed=${this._toggleCollapse}
|
||||||
.buildingBlock=${CONDITION_BUILDING_BLOCKS.includes(
|
.buildingBlock=${CONDITION_BUILDING_BLOCKS.includes(
|
||||||
@@ -663,7 +660,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
},
|
},
|
||||||
toggleYamlMode: () => {
|
toggleYamlMode: () => {
|
||||||
this._toggleYamlMode();
|
this._toggleYamlMode();
|
||||||
this.openSidebar();
|
return this._yamlMode;
|
||||||
},
|
},
|
||||||
disable: this._onDisable,
|
disable: this._onDisable,
|
||||||
delete: this._onDelete,
|
delete: this._onDelete,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, queryAll, state } from "lit/decorators";
|
import { customElement, property, queryAll, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nextRender } from "../../../../common/util/render-status";
|
import { nextRender } from "../../../../common/util/render-status";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
@@ -43,6 +44,8 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar =
|
@property({ type: Boolean, attribute: "sidebar" }) public optionsInSidebar =
|
||||||
false;
|
false;
|
||||||
|
|
||||||
|
@state() private _showReorder = false;
|
||||||
|
|
||||||
@state() private _rowSortSelected?: number;
|
@state() private _rowSortSelected?: number;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
@@ -63,6 +66,21 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
|
|
||||||
private _conditionKeys = new WeakMap<Condition, string>();
|
private _conditionKeys = new WeakMap<Condition, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected updated(changedProperties: PropertyValues) {
|
protected updated(changedProperties: PropertyValues) {
|
||||||
if (!changedProperties.has("conditions")) {
|
if (!changedProperties.has("conditions")) {
|
||||||
return;
|
return;
|
||||||
@@ -147,7 +165,7 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
draggable-selector="ha-automation-condition-row"
|
draggable-selector="ha-automation-condition-row"
|
||||||
.disabled=${this.disabled}
|
.disabled=${!this._showReorder || this.disabled}
|
||||||
group="conditions"
|
group="conditions"
|
||||||
invert-swap
|
invert-swap
|
||||||
@item-moved=${this._conditionMoved}
|
@item-moved=${this._conditionMoved}
|
||||||
@@ -175,12 +193,12 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
@move-up=${this._moveUp}
|
@move-up=${this._moveUp}
|
||||||
@value-changed=${this._conditionChanged}
|
@value-changed=${this._conditionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.highlight=${this.highlightedConditions?.includes(cond)}
|
?highlight=${this.highlightedConditions?.includes(cond)}
|
||||||
.optionsInSidebar=${this.optionsInSidebar}
|
.optionsInSidebar=${this.optionsInSidebar}
|
||||||
.sortSelected=${this._rowSortSelected === idx}
|
.sortSelected=${this._rowSortSelected === idx}
|
||||||
@stop-sort-selection=${this._stopSortSelection}
|
@stop-sort-selection=${this._stopSortSelection}
|
||||||
>
|
>
|
||||||
${!this.disabled
|
${this._showReorder && !this.disabled
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@@ -410,7 +428,14 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = automationRowsStyles;
|
static styles = [
|
||||||
|
automationRowsStyles,
|
||||||
|
css`
|
||||||
|
:host([root]) .rows {
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1181,6 +1181,27 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:not(.yaml-mode) > .alert-wrapper {
|
||||||
|
position: sticky;
|
||||||
|
top: -24px;
|
||||||
|
margin-top: -24px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(.yaml-mode) > .alert-wrapper ha-alert {
|
||||||
|
background-color: var(--card-background-color);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: var(--ha-border-radius-sm);
|
||||||
|
margin-bottom: 0;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
manual-automation-editor {
|
manual-automation-editor {
|
||||||
max-width: 1540px;
|
max-width: 1540px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import "../../../components/ha-bottom-sheet";
|
import "../../../components/ha-bottom-sheet";
|
||||||
import type { HaBottomSheet } from "../../../components/ha-bottom-sheet";
|
import type { HaBottomSheet } from "../../../components/ha-bottom-sheet";
|
||||||
import {
|
import {
|
||||||
@@ -33,8 +34,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _yamlMode = false;
|
@state() private _yamlMode = false;
|
||||||
|
|
||||||
@query("ha-bottom-sheet") private _bottomSheetElement?: HaBottomSheet;
|
@query("ha-bottom-sheet") private _bottomSheetElement?: HaBottomSheet;
|
||||||
@@ -53,7 +52,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.yamlMode=${this._yamlMode}
|
.yamlMode=${this._yamlMode}
|
||||||
.sidebarKey=${this.sidebarKey}
|
|
||||||
@toggle-yaml-mode=${this._toggleYamlMode}
|
@toggle-yaml-mode=${this._toggleYamlMode}
|
||||||
@close-sidebar=${this._handleCloseSidebar}
|
@close-sidebar=${this._handleCloseSidebar}
|
||||||
></ha-automation-sidebar-trigger>
|
></ha-automation-sidebar-trigger>
|
||||||
@@ -69,7 +67,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.yamlMode=${this._yamlMode}
|
.yamlMode=${this._yamlMode}
|
||||||
.sidebarKey=${this.sidebarKey}
|
|
||||||
@toggle-yaml-mode=${this._toggleYamlMode}
|
@toggle-yaml-mode=${this._toggleYamlMode}
|
||||||
@close-sidebar=${this._handleCloseSidebar}
|
@close-sidebar=${this._handleCloseSidebar}
|
||||||
></ha-automation-sidebar-condition>
|
></ha-automation-sidebar-condition>
|
||||||
@@ -85,7 +82,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.yamlMode=${this._yamlMode}
|
.yamlMode=${this._yamlMode}
|
||||||
.sidebarKey=${this.sidebarKey}
|
|
||||||
@toggle-yaml-mode=${this._toggleYamlMode}
|
@toggle-yaml-mode=${this._toggleYamlMode}
|
||||||
@close-sidebar=${this._handleCloseSidebar}
|
@close-sidebar=${this._handleCloseSidebar}
|
||||||
></ha-automation-sidebar-action>
|
></ha-automation-sidebar-action>
|
||||||
@@ -114,7 +110,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.yamlMode=${this._yamlMode}
|
.yamlMode=${this._yamlMode}
|
||||||
.sidebarKey=${this.sidebarKey}
|
|
||||||
@toggle-yaml-mode=${this._toggleYamlMode}
|
@toggle-yaml-mode=${this._toggleYamlMode}
|
||||||
@close-sidebar=${this._handleCloseSidebar}
|
@close-sidebar=${this._handleCloseSidebar}
|
||||||
></ha-automation-sidebar-script-field-selector>
|
></ha-automation-sidebar-script-field-selector>
|
||||||
@@ -130,7 +125,6 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.yamlMode=${this._yamlMode}
|
.yamlMode=${this._yamlMode}
|
||||||
.sidebarKey=${this.sidebarKey}
|
|
||||||
@toggle-yaml-mode=${this._toggleYamlMode}
|
@toggle-yaml-mode=${this._toggleYamlMode}
|
||||||
@close-sidebar=${this._handleCloseSidebar}
|
@close-sidebar=${this._handleCloseSidebar}
|
||||||
></ha-automation-sidebar-script-field>
|
></ha-automation-sidebar-script-field>
|
||||||
@@ -203,7 +197,13 @@ export default class HaAutomationSidebar extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
(this.config as ActionSidebarConfig)?.toggleYamlMode();
|
this._yamlMode = this.config!.toggleYamlMode();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
...this.config,
|
||||||
|
yamlMode: this._yamlMode,
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
@@ -235,8 +235,5 @@ declare global {
|
|||||||
|
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"toggle-yaml-mode": undefined;
|
"toggle-yaml-mode": undefined;
|
||||||
"yaml-changed": {
|
|
||||||
value: unknown;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
extractSearchParam,
|
extractSearchParam,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../../common/url/search-params";
|
} from "../../../common/url/search-params";
|
||||||
|
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||||
import "../../../components/ha-button";
|
import "../../../components/ha-button";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
@@ -92,7 +93,8 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
@state() private _sidebarConfig?: SidebarConfig;
|
@state() private _sidebarConfig?: SidebarConfig;
|
||||||
|
|
||||||
@state() private _sidebarKey?: string;
|
@query(".content")
|
||||||
|
private _contentElement?: HTMLDivElement;
|
||||||
|
|
||||||
@query("ha-automation-sidebar") private _sidebarElement?: HaAutomationSidebar;
|
@query("ha-automation-sidebar") private _sidebarElement?: HaAutomationSidebar;
|
||||||
|
|
||||||
@@ -258,7 +260,8 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"has-sidebar": this._sidebarConfig && !this.narrow,
|
"split-view": true,
|
||||||
|
"sidebar-hidden": !this._sidebarConfig,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -266,32 +269,31 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
<slot name="alerts"></slot>
|
<slot name="alerts"></slot>
|
||||||
${this._renderContent()}
|
${this._renderContent()}
|
||||||
</div>
|
</div>
|
||||||
<div class="fab-positioner">
|
<ha-fab
|
||||||
<ha-fab
|
slot="fab"
|
||||||
slot="fab"
|
class=${this.dirty ? "dirty" : ""}
|
||||||
class=${this.dirty ? "dirty" : ""}
|
.label=${this.hass.localize("ui.common.save")}
|
||||||
.label=${this.hass.localize("ui.common.save")}
|
.disabled=${this.saving}
|
||||||
.disabled=${this.saving}
|
extended
|
||||||
extended
|
@click=${this._saveAutomation}
|
||||||
@click=${this._saveAutomation}
|
>
|
||||||
>
|
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
||||||
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
</ha-fab>
|
||||||
</ha-fab>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-positioner">
|
|
||||||
<ha-automation-sidebar
|
|
||||||
tabindex="-1"
|
|
||||||
class=${classMap({ hidden: !this._sidebarConfig })}
|
|
||||||
.isWide=${this.isWide}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.config=${this._sidebarConfig}
|
|
||||||
@value-changed=${this._sidebarConfigChanged}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
.sidebarKey=${this._sidebarKey}
|
|
||||||
></ha-automation-sidebar>
|
|
||||||
</div>
|
</div>
|
||||||
|
<ha-automation-sidebar
|
||||||
|
tabindex="-1"
|
||||||
|
class=${classMap({
|
||||||
|
sidebar: true,
|
||||||
|
overlay: !this.isWide && !this.narrow,
|
||||||
|
rtl: computeRTL(this.hass),
|
||||||
|
})}
|
||||||
|
.isWide=${this.isWide}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.config=${this._sidebarConfig}
|
||||||
|
@value-changed=${this._sidebarConfigChanged}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
></ha-automation-sidebar>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -317,7 +319,6 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
// deselect previous selected row
|
// deselect previous selected row
|
||||||
this._sidebarConfig?.close?.();
|
this._sidebarConfig?.close?.();
|
||||||
this._sidebarConfig = ev.detail;
|
this._sidebarConfig = ev.detail;
|
||||||
this._sidebarKey = JSON.stringify(this._sidebarConfig);
|
|
||||||
|
|
||||||
await this._sidebarElement?.updateComplete;
|
await this._sidebarElement?.updateComplete;
|
||||||
this._sidebarElement?.focus();
|
this._sidebarElement?.focus();
|
||||||
@@ -343,6 +344,8 @@ export class HaManualAutomationEditor extends LitElement {
|
|||||||
|
|
||||||
private _handleCloseSidebar() {
|
private _handleCloseSidebar() {
|
||||||
this._sidebarConfig = undefined;
|
this._sidebarConfig = undefined;
|
||||||
|
// fix content shift when bottom rows are scrolled into view
|
||||||
|
this._contentElement?.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _triggerChanged(ev: CustomEvent): void {
|
private _triggerChanged(ev: CustomEvent): void {
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ export default class HaAutomationOptionRow extends LitElement {
|
|||||||
rename: () => {
|
rename: () => {
|
||||||
this._renameOption();
|
this._renameOption();
|
||||||
},
|
},
|
||||||
|
toggleYamlMode: () => false, // no yaml mode for options
|
||||||
delete: this._removeOption,
|
delete: this._removeOption,
|
||||||
duplicate: this._duplicateOption,
|
duplicate: this._duplicateOption,
|
||||||
defaultOption: !!this.defaultActions,
|
defaultOption: !!this.defaultActions,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { customElement, property, queryAll, state } from "lit/decorators";
|
|||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nextRender } from "../../../../common/util/render-status";
|
import { nextRender } from "../../../../common/util/render-status";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-sortable";
|
import "../../../../components/ha-sortable";
|
||||||
@@ -34,6 +35,8 @@ export default class HaAutomationOption extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "show-default" })
|
@property({ type: Boolean, attribute: "show-default" })
|
||||||
public showDefaultActions = false;
|
public showDefaultActions = false;
|
||||||
|
|
||||||
|
@state() private _showReorder = false;
|
||||||
|
|
||||||
@state() private _rowSortSelected?: number;
|
@state() private _rowSortSelected?: number;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
@@ -54,12 +57,27 @@ export default class HaAutomationOption extends LitElement {
|
|||||||
|
|
||||||
private _optionsKeys = new WeakMap<Option, string>();
|
private _optionsKeys = new WeakMap<Option, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
draggable-selector="ha-automation-option-row"
|
draggable-selector="ha-automation-option-row"
|
||||||
.disabled=${this.disabled}
|
.disabled=${!this._showReorder || this.disabled}
|
||||||
group="options"
|
group="options"
|
||||||
invert-swap
|
invert-swap
|
||||||
@item-moved=${this._optionMoved}
|
@item-moved=${this._optionMoved}
|
||||||
@@ -89,7 +107,7 @@ export default class HaAutomationOption extends LitElement {
|
|||||||
.sortSelected=${this._rowSortSelected === idx}
|
.sortSelected=${this._rowSortSelected === idx}
|
||||||
@stop-sort-selection=${this._stopSortSelection}
|
@stop-sort-selection=${this._stopSortSelection}
|
||||||
>
|
>
|
||||||
${!this.disabled
|
${this._showReorder && !this.disabled
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { css, type CSSResultGroup, html, LitElement, nothing } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { css, type CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import "../../../../components/ha-button";
|
|
||||||
import { createCloseHeading } from "../../../../components/ha-dialog";
|
|
||||||
import "../../../../components/ha-yaml-editor";
|
|
||||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||||
|
import { createCloseHeading } from "../../../../components/ha-dialog";
|
||||||
|
import "../trigger/ha-automation-trigger-row";
|
||||||
import type { PasteReplaceDialogParams } from "./show-dialog-paste-replace";
|
import type { PasteReplaceDialogParams } from "./show-dialog-paste-replace";
|
||||||
|
|
||||||
@customElement("ha-dialog-paste-replace")
|
@customElement("ha-dialog-paste-replace")
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import type { LocalizeKeys } from "../../../../common/translations/localize";
|
import type { LocalizeKeys } from "../../../../common/translations/localize";
|
||||||
@@ -42,8 +41,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@query(".sidebar-editor")
|
@query(".sidebar-editor")
|
||||||
@@ -184,22 +181,18 @@ export default class HaAutomationSidebarAction extends LitElement {
|
|||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
${description && !this.yamlMode
|
${description && !this.yamlMode
|
||||||
? html`<div class="description">${description}</div>`
|
? html`<div class="description">${description}</div>`
|
||||||
: keyed(
|
: html`<ha-automation-action-editor
|
||||||
this.sidebarKey,
|
class="sidebar-editor"
|
||||||
html`<ha-automation-action-editor
|
.hass=${this.hass}
|
||||||
class="sidebar-editor"
|
.action=${actionConfig}
|
||||||
.hass=${this.hass}
|
.yamlMode=${this.yamlMode}
|
||||||
.action=${actionConfig}
|
.uiSupported=${this.config.uiSupported}
|
||||||
.yamlMode=${this.yamlMode}
|
@value-changed=${this._valueChangedSidebar}
|
||||||
.uiSupported=${this.config.uiSupported}
|
sidebar
|
||||||
@value-changed=${this._valueChangedSidebar}
|
narrow
|
||||||
@yaml-changed=${this._yamlChangedSidebar}
|
.disabled=${this.disabled}
|
||||||
sidebar
|
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
||||||
narrow
|
></ha-automation-action-editor>`}
|
||||||
.disabled=${this.disabled}
|
|
||||||
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
|
||||||
></ha-automation-action-editor>`
|
|
||||||
)}
|
|
||||||
</ha-automation-sidebar-card>`;
|
</ha-automation-sidebar-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,12 +220,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _yamlChangedSidebar(ev: CustomEvent) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
this.config?.save?.(ev.detail.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
fireEvent(this, "toggle-yaml-mode");
|
fireEvent(this, "toggle-yaml-mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import type { ConditionSidebarConfig } from "../../../../data/automation";
|
import type { ConditionSidebarConfig } from "../../../../data/automation";
|
||||||
@@ -36,8 +35,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@query(".sidebar-editor")
|
@query(".sidebar-editor")
|
||||||
@@ -176,21 +173,17 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
|||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
${description && !this.yamlMode
|
${description && !this.yamlMode
|
||||||
? html`<div class="description">${description}</div>`
|
? html`<div class="description">${description}</div>`
|
||||||
: keyed(
|
: html`<ha-automation-condition-editor
|
||||||
this.sidebarKey,
|
class="sidebar-editor"
|
||||||
html`<ha-automation-condition-editor
|
.hass=${this.hass}
|
||||||
class="sidebar-editor"
|
.condition=${this.config.config}
|
||||||
.hass=${this.hass}
|
.yamlMode=${this.yamlMode}
|
||||||
.condition=${this.config.config}
|
.uiSupported=${this.config.uiSupported}
|
||||||
.yamlMode=${this.yamlMode}
|
@value-changed=${this._valueChangedSidebar}
|
||||||
.uiSupported=${this.config.uiSupported}
|
.disabled=${this.disabled}
|
||||||
@value-changed=${this._valueChangedSidebar}
|
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
||||||
@yaml-changed=${this._yamlChangedSidebar}
|
sidebar
|
||||||
.disabled=${this.disabled}
|
></ha-automation-condition-editor> `}
|
||||||
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
|
||||||
sidebar
|
|
||||||
></ha-automation-condition-editor>`
|
|
||||||
)}
|
|
||||||
</ha-automation-sidebar-card>`;
|
</ha-automation-sidebar-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,12 +209,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _yamlChangedSidebar(ev: CustomEvent) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
this.config?.save?.(ev.detail.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
fireEvent(this, "toggle-yaml-mode");
|
fireEvent(this, "toggle-yaml-mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
|
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import type { LocalizeKeys } from "../../../../common/translations/localize";
|
import type { LocalizeKeys } from "../../../../common/translations/localize";
|
||||||
import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
|
import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
|
||||||
@@ -25,8 +24,6 @@ export default class HaAutomationSidebarScriptFieldSelector extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@query(".sidebar-editor")
|
@query(".sidebar-editor")
|
||||||
@@ -84,18 +81,14 @@ export default class HaAutomationSidebarScriptFieldSelector extends LitElement {
|
|||||||
)}
|
)}
|
||||||
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
${keyed(
|
<ha-script-field-selector-editor
|
||||||
this.sidebarKey,
|
class="sidebar-editor"
|
||||||
html`<ha-script-field-selector-editor
|
.hass=${this.hass}
|
||||||
class="sidebar-editor"
|
.field=${this.config.config.field}
|
||||||
.hass=${this.hass}
|
.disabled=${this.disabled}
|
||||||
.field=${this.config.config.field}
|
@value-changed=${this._valueChangedSidebar}
|
||||||
.disabled=${this.disabled}
|
.yamlMode=${this.yamlMode}
|
||||||
@value-changed=${this._valueChangedSidebar}
|
></ha-script-field-selector-editor>
|
||||||
@yaml-changed=${this._yamlChangedSidebar}
|
|
||||||
.yamlMode=${this.yamlMode}
|
|
||||||
></ha-script-field-selector-editor>`
|
|
||||||
)}
|
|
||||||
</ha-automation-sidebar-card>`;
|
</ha-automation-sidebar-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,12 +116,6 @@ export default class HaAutomationSidebarScriptFieldSelector extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _yamlChangedSidebar(ev: CustomEvent) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
this.config?.save?.(ev.detail.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
fireEvent(this, "toggle-yaml-mode");
|
fireEvent(this, "toggle-yaml-mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
|
import { mdiDelete, mdiPlaylistEdit } from "@mdi/js";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
|
import type { ScriptFieldSidebarConfig } from "../../../../data/automation";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
@@ -24,8 +23,6 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@query(".sidebar-editor")
|
@query(".sidebar-editor")
|
||||||
@@ -77,20 +74,16 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
|||||||
)}
|
)}
|
||||||
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
${keyed(
|
<ha-script-field-editor
|
||||||
this.sidebarKey,
|
class="sidebar-editor"
|
||||||
html`<ha-script-field-editor
|
.hass=${this.hass}
|
||||||
class="sidebar-editor"
|
.field=${this.config.config.field}
|
||||||
.hass=${this.hass}
|
.key=${this.config.config.key}
|
||||||
.field=${this.config.config.field}
|
.excludeKeys=${this.config.config.excludeKeys}
|
||||||
.key=${this.config.config.key}
|
.disabled=${this.disabled}
|
||||||
.excludeKeys=${this.config.config.excludeKeys}
|
.yamlMode=${this.yamlMode}
|
||||||
.disabled=${this.disabled}
|
@value-changed=${this._valueChangedSidebar}
|
||||||
.yamlMode=${this.yamlMode}
|
></ha-script-field-editor>
|
||||||
@value-changed=${this._valueChangedSidebar}
|
|
||||||
@yaml-changed=${this._yamlChangedSidebar}
|
|
||||||
></ha-script-field-editor>`
|
|
||||||
)}
|
|
||||||
</ha-automation-sidebar-card>`;
|
</ha-automation-sidebar-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +110,6 @@ export default class HaAutomationSidebarScriptField extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _yamlChangedSidebar(ev: CustomEvent) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
this.config?.save?.(ev.detail.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
fireEvent(this, "toggle-yaml-mode");
|
fireEvent(this, "toggle-yaml-mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import { html, LitElement, nothing } from "lit";
|
import { html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { keyed } from "lit/directives/keyed";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import type { TriggerSidebarConfig } from "../../../../data/automation";
|
import type { TriggerSidebarConfig } from "../../../../data/automation";
|
||||||
@@ -36,8 +35,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ attribute: "sidebar-key" }) public sidebarKey?: string;
|
|
||||||
|
|
||||||
@state() private _requestShowId = false;
|
@state() private _requestShowId = false;
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
@@ -186,22 +183,18 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
|||||||
)}
|
)}
|
||||||
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
<ha-svg-icon slot="start" .path=${mdiDelete}></ha-svg-icon>
|
||||||
</ha-md-menu-item>
|
</ha-md-menu-item>
|
||||||
${keyed(
|
<ha-automation-trigger-editor
|
||||||
this.sidebarKey,
|
class="sidebar-editor"
|
||||||
html`<ha-automation-trigger-editor
|
.hass=${this.hass}
|
||||||
class="sidebar-editor"
|
.trigger=${this.config.config}
|
||||||
.hass=${this.hass}
|
@value-changed=${this._valueChangedSidebar}
|
||||||
.trigger=${this.config.config}
|
.uiSupported=${this.config.uiSupported}
|
||||||
@value-changed=${this._valueChangedSidebar}
|
.showId=${this._requestShowId}
|
||||||
@yaml-changed=${this._yamlChangedSidebar}
|
.yamlMode=${this.yamlMode}
|
||||||
.uiSupported=${this.config.uiSupported}
|
.disabled=${this.disabled}
|
||||||
.showId=${this._requestShowId}
|
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
||||||
.yamlMode=${this.yamlMode}
|
sidebar
|
||||||
.disabled=${this.disabled}
|
></ha-automation-trigger-editor>
|
||||||
@ui-mode-not-available=${this._handleUiModeNotAvailable}
|
|
||||||
sidebar
|
|
||||||
></ha-automation-trigger-editor>`
|
|
||||||
)}
|
|
||||||
</ha-automation-sidebar-card>
|
</ha-automation-sidebar-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -228,12 +221,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _yamlChangedSidebar(ev: CustomEvent) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
this.config?.save?.(ev.detail.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggleYamlMode = () => {
|
private _toggleYamlMode = () => {
|
||||||
fireEvent(this, "toggle-yaml-mode");
|
fireEvent(this, "toggle-yaml-mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ export const rowStyles = css`
|
|||||||
ha-tooltip {
|
ha-tooltip {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
:host([highlight]) ha-card {
|
||||||
|
--shadow-default: var(--ha-card-box-shadow, 0 0 0 0 transparent);
|
||||||
|
--shadow-focus: 0 0 0 1px var(--state-inactive-color);
|
||||||
|
border-color: var(--state-inactive-color);
|
||||||
|
box-shadow: var(--shadow-default), var(--shadow-focus);
|
||||||
|
}
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -63,7 +69,7 @@ export const indentStyle = css`
|
|||||||
.selector-row,
|
.selector-row,
|
||||||
:host([indent]) ha-form {
|
:host([indent]) ha-form {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
padding: 12px 0 16px 16px;
|
padding: 12px 20px 16px 16px;
|
||||||
border-left: 2px solid var(--ha-color-border-neutral-quiet);
|
border-left: 2px solid var(--ha-color-border-neutral-quiet);
|
||||||
border-bottom: 2px solid var(--ha-color-border-neutral-quiet);
|
border-bottom: 2px solid var(--ha-color-border-neutral-quiet);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
@@ -102,59 +108,77 @@ export const saveFabStyles = css`
|
|||||||
export const manualEditorStyles = css`
|
export const manualEditorStyles = css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
--sidebar-width: 0;
|
|
||||||
--sidebar-gap: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-sidebar {
|
.split-view {
|
||||||
--sidebar-width: min(35vw, 500px);
|
|
||||||
--sidebar-gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fab-positioner {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
flex-direction: row;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fab-positioner ha-fab {
|
.split-view.sidebar-hidden {
|
||||||
position: fixed;
|
gap: 0;
|
||||||
right: unset;
|
|
||||||
left: unset;
|
|
||||||
bottom: calc(-80px - var(--safe-area-inset-bottom));
|
|
||||||
transition: bottom 0.3s;
|
|
||||||
}
|
|
||||||
.fab-positioner ha-fab.dirty {
|
|
||||||
bottom: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
padding-right: calc(var(--sidebar-width) + var(--sidebar-gap));
|
position: relative;
|
||||||
padding-inline-end: calc(var(--sidebar-width) + var(--sidebar-gap));
|
flex: 6;
|
||||||
padding-inline-start: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding-top: 24px;
|
padding: 32px 16px 64px 0;
|
||||||
padding-bottom: 72px;
|
height: calc(100vh - 153px);
|
||||||
|
height: calc(100dvh - 153px);
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-automation-sidebar {
|
.sidebar {
|
||||||
|
padding: 12px 0;
|
||||||
|
flex: 4;
|
||||||
|
height: calc(100vh - 81px);
|
||||||
|
height: calc(100dvh - 81px);
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
.split-view.sidebar-hidden .sidebar {
|
||||||
|
border-color: transparent;
|
||||||
|
border-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: calc(var(--header-height) + 16px);
|
bottom: 8px;
|
||||||
height: calc(-81px + 100dvh);
|
right: 8px;
|
||||||
width: var(--sidebar-width);
|
height: calc(100% - 70px);
|
||||||
display: block;
|
padding: 0;
|
||||||
|
z-index: 5;
|
||||||
|
box-shadow: -8px 0 16px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-automation-sidebar.hidden {
|
.sidebar.overlay.rtl {
|
||||||
display: none;
|
right: unset;
|
||||||
|
left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-positioner {
|
@media all and (max-width: 870px) {
|
||||||
display: flex;
|
.split-view {
|
||||||
justify-content: flex-end;
|
gap: 0;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-view.sidebar-hidden .sidebar.overlay {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
.description {
|
.description {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -165,6 +189,9 @@ export const manualEditorStyles = css`
|
|||||||
|
|
||||||
export const automationRowsStyles = css`
|
export const automationRowsStyles = css`
|
||||||
.rows {
|
.rows {
|
||||||
|
padding: 16px 0 16px 16px;
|
||||||
|
margin: -16px;
|
||||||
|
margin-right: -20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export default class HaAutomationTriggerEditor extends LitElement {
|
|||||||
if (!ev.detail.isValid) {
|
if (!ev.detail.isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fireEvent(this, "yaml-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: migrateAutomationTrigger(ev.detail.value),
|
value: migrateAutomationTrigger(ev.detail.value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,8 +113,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public last?: boolean;
|
@property({ type: Boolean }) public last?: boolean;
|
||||||
|
|
||||||
@property({ type: Boolean }) public highlight?: boolean;
|
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "sidebar" })
|
@property({ type: Boolean, attribute: "sidebar" })
|
||||||
public optionsInSidebar = false;
|
public optionsInSidebar = false;
|
||||||
|
|
||||||
@@ -351,7 +349,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
this.trigger.enabled === false}
|
this.trigger.enabled === false}
|
||||||
@click=${this._toggleSidebar}
|
@click=${this._toggleSidebar}
|
||||||
.selected=${this._selected}
|
.selected=${this._selected}
|
||||||
.highlight=${this.highlight}
|
|
||||||
.sortSelected=${this.sortSelected}
|
.sortSelected=${this.sortSelected}
|
||||||
>${this._selected
|
>${this._selected
|
||||||
? "selected"
|
? "selected"
|
||||||
@@ -497,7 +494,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
},
|
},
|
||||||
toggleYamlMode: () => {
|
toggleYamlMode: () => {
|
||||||
this._toggleYamlMode();
|
this._toggleYamlMode();
|
||||||
this.openSidebar();
|
return this._yamlMode;
|
||||||
},
|
},
|
||||||
disable: this._onDisable,
|
disable: this._onDisable,
|
||||||
delete: this._onDelete,
|
delete: this._onDelete,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { mdiDrag, mdiPlus } from "@mdi/js";
|
import { mdiDrag, mdiPlus } from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { listenMediaQuery } from "../../../../common/dom/media_query";
|
||||||
import { nextRender } from "../../../../common/util/render-status";
|
import { nextRender } from "../../../../common/util/render-status";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
@@ -44,6 +45,8 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public root = false;
|
@property({ type: Boolean }) public root = false;
|
||||||
|
|
||||||
|
@state() private _showReorder = false;
|
||||||
|
|
||||||
@state() private _rowSortSelected?: number;
|
@state() private _rowSortSelected?: number;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
@@ -61,12 +64,27 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
|
|
||||||
private _triggerKeys = new WeakMap<Trigger, string>();
|
private _triggerKeys = new WeakMap<Trigger, string>();
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery("(min-width: 600px)", (matches) => {
|
||||||
|
this._showReorder = matches;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<ha-sortable
|
<ha-sortable
|
||||||
handle-selector=".handle"
|
handle-selector=".handle"
|
||||||
draggable-selector="ha-automation-trigger-row"
|
draggable-selector="ha-automation-trigger-row"
|
||||||
.disabled=${this.disabled}
|
.disabled=${!this._showReorder || this.disabled}
|
||||||
group="triggers"
|
group="triggers"
|
||||||
invert-swap
|
invert-swap
|
||||||
@item-moved=${this._triggerMoved}
|
@item-moved=${this._triggerMoved}
|
||||||
@@ -92,12 +110,12 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.highlight=${this.highlightedTriggers?.includes(trg)}
|
?highlight=${this.highlightedTriggers?.includes(trg)}
|
||||||
.optionsInSidebar=${this.optionsInSidebar}
|
.optionsInSidebar=${this.optionsInSidebar}
|
||||||
.sortSelected=${this._rowSortSelected === idx}
|
.sortSelected=${this._rowSortSelected === idx}
|
||||||
@stop-sort-selection=${this._stopSortSelection}
|
@stop-sort-selection=${this._stopSortSelection}
|
||||||
>
|
>
|
||||||
${!this.disabled
|
${this._showReorder && !this.disabled
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@@ -350,7 +368,14 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
this._rowSortSelected = undefined;
|
this._rowSortSelected = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = automationRowsStyles;
|
static styles = [
|
||||||
|
automationRowsStyles,
|
||||||
|
css`
|
||||||
|
:host([root]) .rows {
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -34,16 +34,6 @@ const UPDATE_THROTTLE_TIME = 10000;
|
|||||||
const CORE_SOURCE_ID = "ha";
|
const CORE_SOURCE_ID = "ha";
|
||||||
const CORE_SOURCE_LABEL = "Home Assistant";
|
const CORE_SOURCE_LABEL = "Home Assistant";
|
||||||
|
|
||||||
const RSSI_COLOR_THRESHOLDS: [number, string][] = [
|
|
||||||
[-70, "--green-color"], // Excellent: > -70 dBm
|
|
||||||
[-75, "--lime-color"], // Good: -70 to -75 dBm
|
|
||||||
[-80, "--yellow-color"], // Okay: -75 to -80 dBm
|
|
||||||
[-85, "--amber-color"], // Marginal: -80 to -85 dBm
|
|
||||||
[-90, "--orange-color"], // Weak: -85 to -90 dBm
|
|
||||||
[-95, "--deep-orange-color"], // Poor: -90 to -95 dBm
|
|
||||||
[-Infinity, "--red-color"], // Very poor: < -95 dBm
|
|
||||||
];
|
|
||||||
|
|
||||||
@customElement("bluetooth-network-visualization")
|
@customElement("bluetooth-network-visualization")
|
||||||
export class BluetoothNetworkVisualization extends LitElement {
|
export class BluetoothNetworkVisualization extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@@ -135,16 +125,6 @@ export class BluetoothNetworkVisualization extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getRssiColorVar = memoizeOne((rssi: number): string => {
|
|
||||||
for (const [threshold, colorVar] of RSSI_COLOR_THRESHOLDS) {
|
|
||||||
if (rssi > threshold) {
|
|
||||||
return colorVar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fallback (should never reach here)
|
|
||||||
return "--red-color";
|
|
||||||
});
|
|
||||||
|
|
||||||
private _formatNetworkData = memoizeOne(
|
private _formatNetworkData = memoizeOne(
|
||||||
(
|
(
|
||||||
data: BluetoothDeviceData[],
|
data: BluetoothDeviceData[],
|
||||||
@@ -226,7 +206,7 @@ export class BluetoothNetworkVisualization extends LitElement {
|
|||||||
symbol: "none",
|
symbol: "none",
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: this._getLineWidth(node.rssi),
|
width: this._getLineWidth(node.rssi),
|
||||||
color: style.getPropertyValue(this._getRssiColorVar(node.rssi)),
|
color: style.getPropertyValue("--primary-color"),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -247,7 +227,7 @@ export class BluetoothNetworkVisualization extends LitElement {
|
|||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: this._getLineWidth(node.rssi),
|
width: this._getLineWidth(node.rssi),
|
||||||
color: device
|
color: device
|
||||||
? style.getPropertyValue(this._getRssiColorVar(node.rssi))
|
? style.getPropertyValue("--primary-color")
|
||||||
: style.getPropertyValue("--disabled-color"),
|
: style.getPropertyValue("--disabled-color"),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -199,10 +199,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
"ui.panel.config.lovelace.dashboards.picker.headers.require_admin"
|
"ui.panel.config.lovelace.dashboards.picker.headers.require_admin"
|
||||||
),
|
),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
hidden: narrow,
|
|
||||||
type: "icon",
|
type: "icon",
|
||||||
minWidth: "120px",
|
hidden: narrow,
|
||||||
maxWidth: "120px",
|
|
||||||
template: (dashboard) =>
|
template: (dashboard) =>
|
||||||
dashboard.require_admin
|
dashboard.require_admin
|
||||||
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
||||||
@@ -212,10 +210,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
title: localize(
|
title: localize(
|
||||||
"ui.panel.config.lovelace.dashboards.picker.headers.sidebar"
|
"ui.panel.config.lovelace.dashboards.picker.headers.sidebar"
|
||||||
),
|
),
|
||||||
hidden: narrow,
|
|
||||||
type: "icon",
|
type: "icon",
|
||||||
minWidth: "120px",
|
hidden: narrow,
|
||||||
maxWidth: "120px",
|
|
||||||
template: (dashboard) =>
|
template: (dashboard) =>
|
||||||
dashboard.show_in_sidebar
|
dashboard.show_in_sidebar
|
||||||
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
? html`<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>`
|
||||||
|
|||||||
@@ -152,12 +152,7 @@ export default class HaScriptFieldEditor extends LitElement {
|
|||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const value = { ...ev.detail.value };
|
const value = { ...ev.detail.value };
|
||||||
|
|
||||||
if (
|
if (typeof value !== "object" || Object.keys(value).length !== 1) {
|
||||||
typeof value !== "object" ||
|
|
||||||
Object.keys(value).length !== 1 ||
|
|
||||||
!value[Object.keys(value)[0]] ||
|
|
||||||
!value[Object.keys(value)[0]].selector
|
|
||||||
) {
|
|
||||||
this._yamlError = "yaml_error";
|
this._yamlError = "yaml_error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -170,7 +165,7 @@ export default class HaScriptFieldEditor extends LitElement {
|
|||||||
|
|
||||||
const newValue = { ...value[key], key };
|
const newValue = { ...value[key], key };
|
||||||
|
|
||||||
fireEvent(this, "yaml-changed", { value: newValue });
|
fireEvent(this, "value-changed", { value: newValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
private _computeLabelCallback = (
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ export default class HaScriptFieldRow extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public narrow = false;
|
@property({ type: Boolean }) public narrow = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public highlight?: boolean;
|
|
||||||
|
|
||||||
@state() private _yamlMode = false;
|
@state() private _yamlMode = false;
|
||||||
|
|
||||||
@state() private _selected = false;
|
@state() private _selected = false;
|
||||||
@@ -63,7 +61,6 @@ export default class HaScriptFieldRow extends LitElement {
|
|||||||
left-chevron
|
left-chevron
|
||||||
@toggle-collapsed=${this._toggleCollapse}
|
@toggle-collapsed=${this._toggleCollapse}
|
||||||
.collapsed=${this._collapsed}
|
.collapsed=${this._collapsed}
|
||||||
.highlight=${this.highlight}
|
|
||||||
>
|
>
|
||||||
<h3 slot="header">${this.key}</h3>
|
<h3 slot="header">${this.key}</h3>
|
||||||
|
|
||||||
@@ -86,7 +83,6 @@ export default class HaScriptFieldRow extends LitElement {
|
|||||||
.leftChevron=${SELECTOR_SELECTOR_BUILDING_BLOCKS.includes(
|
.leftChevron=${SELECTOR_SELECTOR_BUILDING_BLOCKS.includes(
|
||||||
Object.keys(this.field.selector)[0]
|
Object.keys(this.field.selector)[0]
|
||||||
)}
|
)}
|
||||||
.highlight=${this.highlight}
|
|
||||||
>
|
>
|
||||||
<h3 slot="header">
|
<h3 slot="header">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@@ -222,7 +218,7 @@ export default class HaScriptFieldRow extends LitElement {
|
|||||||
},
|
},
|
||||||
toggleYamlMode: () => {
|
toggleYamlMode: () => {
|
||||||
this._toggleYamlMode();
|
this._toggleYamlMode();
|
||||||
this.openSidebar();
|
return this._yamlMode;
|
||||||
},
|
},
|
||||||
delete: this._onDelete,
|
delete: this._onDelete,
|
||||||
config: {
|
config: {
|
||||||
@@ -335,6 +331,13 @@ export default class HaScriptFieldRow extends LitElement {
|
|||||||
li[role="separator"] {
|
li[role="separator"] {
|
||||||
border-bottom-color: var(--divider-color);
|
border-bottom-color: var(--divider-color);
|
||||||
}
|
}
|
||||||
|
:host([highlight]) ha-card {
|
||||||
|
--shadow-default: var(--ha-card-box-shadow, 0 0 0 0 transparent);
|
||||||
|
--shadow-focus: 0 0 0 1px var(--state-inactive-color);
|
||||||
|
border-color: var(--state-inactive-color);
|
||||||
|
box-shadow: var(--shadow-default), var(--shadow-focus);
|
||||||
|
}
|
||||||
|
|
||||||
.selector-row {
|
.selector-row {
|
||||||
padding: 12px 0 16px 16px;
|
padding: 12px 0 16px 16px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export default class HaScriptFieldSelectorEditor extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fireEvent(this, "yaml-changed", { value });
|
fireEvent(this, "value-changed", { value });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
private _computeLabelCallback = (
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default class HaScriptFields extends LitElement {
|
|||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
@value-changed=${this._fieldChanged}
|
@value-changed=${this._fieldChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.highlight=${this.highlightedFields?.[key] !== undefined}
|
?highlight=${this.highlightedFields?.[key] !== undefined}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
>
|
>
|
||||||
</ha-script-field-row>
|
</ha-script-field-row>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
extractSearchParam,
|
extractSearchParam,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../../common/url/search-params";
|
} from "../../../common/url/search-params";
|
||||||
|
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-markdown";
|
import "../../../components/ha-markdown";
|
||||||
import type { SidebarConfig } from "../../../data/automation";
|
import type { SidebarConfig } from "../../../data/automation";
|
||||||
@@ -73,8 +74,6 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
|
|
||||||
@state() private _sidebarConfig?: SidebarConfig;
|
@state() private _sidebarConfig?: SidebarConfig;
|
||||||
|
|
||||||
@state() private _sidebarKey?: string;
|
|
||||||
|
|
||||||
@query("ha-script-fields")
|
@query("ha-script-fields")
|
||||||
private _scriptFields?: HaScriptFields;
|
private _scriptFields?: HaScriptFields;
|
||||||
|
|
||||||
@@ -200,7 +199,8 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"has-sidebar": this._sidebarConfig && !this.narrow,
|
"split-view": true,
|
||||||
|
"sidebar-hidden": !this._sidebarConfig,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@@ -208,34 +208,31 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
<slot name="alerts"></slot>
|
<slot name="alerts"></slot>
|
||||||
${this._renderContent()}
|
${this._renderContent()}
|
||||||
</div>
|
</div>
|
||||||
<div class="fab-positioner">
|
<ha-fab
|
||||||
<div class="fab-positioner">
|
slot="fab"
|
||||||
<ha-fab
|
class=${this.dirty ? "dirty" : ""}
|
||||||
slot="fab"
|
.label=${this.hass.localize("ui.common.save")}
|
||||||
class=${this.dirty ? "dirty" : ""}
|
.disabled=${this.saving}
|
||||||
.label=${this.hass.localize("ui.common.save")}
|
extended
|
||||||
.disabled=${this.saving}
|
@click=${this._saveScript}
|
||||||
extended
|
>
|
||||||
@click=${this._saveScript}
|
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
||||||
>
|
</ha-fab>
|
||||||
<ha-svg-icon slot="icon" .path=${mdiContentSave}></ha-svg-icon>
|
|
||||||
</ha-fab>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-positioner">
|
|
||||||
<ha-automation-sidebar
|
|
||||||
.sidebarKey=${this._sidebarKey}
|
|
||||||
tabindex="-1"
|
|
||||||
class=${classMap({ hidden: !this._sidebarConfig })}
|
|
||||||
.narrow=${this.narrow}
|
|
||||||
.isWide=${this.isWide}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.config=${this._sidebarConfig}
|
|
||||||
@value-changed=${this._sidebarConfigChanged}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
></ha-automation-sidebar>
|
|
||||||
</div>
|
</div>
|
||||||
|
<ha-automation-sidebar
|
||||||
|
tabindex="-1"
|
||||||
|
class=${classMap({
|
||||||
|
sidebar: true,
|
||||||
|
overlay: !this.isWide,
|
||||||
|
rtl: computeRTL(this.hass),
|
||||||
|
})}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.isWide=${this.isWide}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.config=${this._sidebarConfig}
|
||||||
|
@value-changed=${this._sidebarConfigChanged}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
></ha-automation-sidebar>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -466,7 +463,6 @@ export class HaManualScriptEditor extends LitElement {
|
|||||||
// deselect previous selected row
|
// deselect previous selected row
|
||||||
this._sidebarConfig?.close?.();
|
this._sidebarConfig?.close?.();
|
||||||
this._sidebarConfig = ev.detail;
|
this._sidebarConfig = ev.detail;
|
||||||
this._sidebarKey = JSON.stringify(this._sidebarConfig);
|
|
||||||
|
|
||||||
await this._sidebarElement?.updateComplete;
|
await this._sidebarElement?.updateComplete;
|
||||||
this._sidebarElement?.focus();
|
this._sidebarElement?.focus();
|
||||||
|
|||||||
@@ -568,10 +568,6 @@ class HaPanelDevState extends LitElement {
|
|||||||
margin: 0 8px 16px;
|
margin: 0 8px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-expansion-panel p {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputs {
|
.inputs {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
@@ -583,9 +579,8 @@ class HaPanelDevState extends LitElement {
|
|||||||
|
|
||||||
.button-row {
|
.button-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 8px 0;
|
margin-top: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([narrow]) .state-wrapper {
|
:host([narrow]) .state-wrapper {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import type {
|
|||||||
import { getSensorNumericDeviceClasses } from "../../../data/sensor";
|
import { getSensorNumericDeviceClasses } from "../../../data/sensor";
|
||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||||
|
import { getGraphColorByIndex } from "../../../common/color/colors";
|
||||||
import { computeTimelineColor } from "../../../components/chart/timeline-color";
|
import { computeTimelineColor } from "../../../components/chart/timeline-color";
|
||||||
import { downSampleLineData } from "../../../components/chart/down-sample";
|
import { downSampleLineData } from "../../../components/chart/down-sample";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
@@ -92,19 +93,20 @@ class HuiHistoryChartCardFeature
|
|||||||
const width = this.clientWidth;
|
const width = this.clientWidth;
|
||||||
const height = this.clientHeight;
|
const height = this.clientHeight;
|
||||||
if (line) {
|
if (line) {
|
||||||
const { points, yAxisOrigin } = this._generateLinePoints(line);
|
const points = this._generateLinePoints(line);
|
||||||
const { paths, filledPaths } = this._getLinePaths(points, yAxisOrigin);
|
const { paths, filledPaths } = this._getLinePaths(points);
|
||||||
|
const color = getGraphColorByIndex(0, this.style);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="line" @click=${this._handleClick}>
|
<div class="line" @click=${this._handleClick}>
|
||||||
${svg`<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
${svg`<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
||||||
${paths.map(
|
${paths.map(
|
||||||
(path) =>
|
(path) =>
|
||||||
svg`<path d="${path}" stroke="var(--feature-color)" stroke-width="1" stroke-linecap="round" fill="none" />`
|
svg`<path d="${path}" stroke="${color}" stroke-width="1" stroke-linecap="round" fill="none" />`
|
||||||
)}
|
)}
|
||||||
${filledPaths.map(
|
${filledPaths.map(
|
||||||
(path) =>
|
(path) =>
|
||||||
svg`<path d="${path}" stroke="none" stroke-linecap="round" fill="var(--feature-color)" fill-opacity="0.2" />`
|
svg`<path d="${path}" stroke="none" stroke-linecap="round" fill="${color}" fill-opacity="0.2" />`
|
||||||
)}
|
)}
|
||||||
</svg>`}
|
</svg>`}
|
||||||
</div>
|
</div>
|
||||||
@@ -159,13 +161,9 @@ class HuiHistoryChartCardFeature
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _generateLinePoints(line: LineChartUnit): {
|
private _generateLinePoints(line: LineChartUnit): { x: number; y: number }[] {
|
||||||
points: { x: number; y: number }[];
|
|
||||||
yAxisOrigin: number;
|
|
||||||
} {
|
|
||||||
const width = this.clientWidth;
|
const width = this.clientWidth;
|
||||||
const height = this.clientHeight;
|
const height = this.clientHeight;
|
||||||
let yAxisOrigin = height;
|
|
||||||
let minY = Number(line.data[0].states[0].state);
|
let minY = Number(line.data[0].states[0].state);
|
||||||
let maxY = Number(line.data[0].states[0].state);
|
let maxY = Number(line.data[0].states[0].state);
|
||||||
const minX = line.data[0].states[0].last_changed;
|
const minX = line.data[0].states[0].last_changed;
|
||||||
@@ -174,7 +172,8 @@ class HuiHistoryChartCardFeature
|
|||||||
const stateValue = Number(stateData.state);
|
const stateValue = Number(stateData.state);
|
||||||
if (stateValue < minY) {
|
if (stateValue < minY) {
|
||||||
minY = stateValue;
|
minY = stateValue;
|
||||||
} else if (stateValue > maxY) {
|
}
|
||||||
|
if (stateValue > maxY) {
|
||||||
maxY = stateValue;
|
maxY = stateValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -188,21 +187,9 @@ class HuiHistoryChartCardFeature
|
|||||||
minX,
|
minX,
|
||||||
maxX
|
maxX
|
||||||
);
|
);
|
||||||
if (maxY < 0) {
|
// add margin to the min and max
|
||||||
// all values are negative
|
minY -= rangeY * 0.1;
|
||||||
// add margin
|
maxY += rangeY * 0.1;
|
||||||
maxY += rangeY * 0.1;
|
|
||||||
maxY = Math.min(0, maxY);
|
|
||||||
yAxisOrigin = 0;
|
|
||||||
} else if (minY < 0) {
|
|
||||||
// some values are negative
|
|
||||||
yAxisOrigin = (maxY / (maxY - minY || 1)) * height;
|
|
||||||
} else {
|
|
||||||
// all values are positive
|
|
||||||
// add margin
|
|
||||||
minY -= rangeY * 0.1;
|
|
||||||
minY = Math.max(0, minY);
|
|
||||||
}
|
|
||||||
const yDenom = maxY - minY || 1;
|
const yDenom = maxY - minY || 1;
|
||||||
const xDenom = maxX - minX || 1;
|
const xDenom = maxX - minX || 1;
|
||||||
const points = sampledData!.map((point) => {
|
const points = sampledData!.map((point) => {
|
||||||
@@ -211,7 +198,7 @@ class HuiHistoryChartCardFeature
|
|||||||
return { x, y };
|
return { x, y };
|
||||||
});
|
});
|
||||||
points.push({ x: width, y: points[points.length - 1].y });
|
points.push({ x: width, y: points[points.length - 1].y });
|
||||||
return { points, yAxisOrigin };
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _generateTimelineRanges(timeline: TimelineEntity) {
|
private _generateTimelineRanges(timeline: TimelineEntity) {
|
||||||
@@ -247,10 +234,7 @@ class HuiHistoryChartCardFeature
|
|||||||
return ranges;
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getLinePaths(
|
private _getLinePaths(points: { x: number; y: number }[]) {
|
||||||
points: { x: number; y: number }[],
|
|
||||||
yAxisOrigin: number
|
|
||||||
) {
|
|
||||||
const paths: string[] = [];
|
const paths: string[] = [];
|
||||||
const filledPaths: string[] = [];
|
const filledPaths: string[] = [];
|
||||||
if (!points.length) {
|
if (!points.length) {
|
||||||
@@ -285,7 +269,7 @@ class HuiHistoryChartCardFeature
|
|||||||
paths.push(path);
|
paths.push(path);
|
||||||
filledPaths.push(
|
filledPaths.push(
|
||||||
path +
|
path +
|
||||||
` L ${next!.x},${yAxisOrigin} L ${pathPoints[0].x},${yAxisOrigin} Z`
|
` L ${next!.x},${this.clientHeight} L ${pathPoints[0].x},${this.clientHeight} Z`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
type MediaPlayerEntity,
|
type MediaPlayerEntity,
|
||||||
} from "../../../data/media-player";
|
} from "../../../data/media-player";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import type { LovelaceCardFeature } from "../types";
|
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||||
import { cardFeatureStyles } from "./common/card-feature-styles";
|
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||||
import type {
|
import type {
|
||||||
LovelaceCardFeatureContext,
|
LovelaceCardFeatureContext,
|
||||||
@@ -58,6 +58,15 @@ class HuiMediaPlayerVolumeSliderCardFeature
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||||
|
await import(
|
||||||
|
"../editor/config-elements/hui-media-player-volume-slider-card-feature-editor"
|
||||||
|
);
|
||||||
|
return document.createElement(
|
||||||
|
"hui-media-player-volume-slider-card-feature-editor"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
|
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
throw new Error("Invalid configuration");
|
throw new Error("Invalid configuration");
|
||||||
@@ -84,8 +93,9 @@ class HuiMediaPlayerVolumeSliderCardFeature
|
|||||||
return html`
|
return html`
|
||||||
<ha-control-slider
|
<ha-control-slider
|
||||||
.value=${position}
|
.value=${position}
|
||||||
min="0"
|
.min=${this._config.min ?? 0}
|
||||||
max="100"
|
.max=${this._config.max ?? 100}
|
||||||
|
.step=${this._config.step ?? 1}
|
||||||
.showHandle=${stateActive(this._stateObj)}
|
.showHandle=${stateActive(this._stateObj)}
|
||||||
.disabled=${!this._stateObj || isUnavailableState(this._stateObj.state)}
|
.disabled=${!this._stateObj || isUnavailableState(this._stateObj.state)}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ export interface MediaPlayerPlaybackCardFeatureConfig {
|
|||||||
|
|
||||||
export interface MediaPlayerVolumeSliderCardFeatureConfig {
|
export interface MediaPlayerVolumeSliderCardFeatureConfig {
|
||||||
type: "media-player-volume-slider";
|
type: "media-player-volume-slider";
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FanDirectionCardFeatureConfig {
|
export interface FanDirectionCardFeatureConfig {
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ export class HuiHeadingCard extends LitElement implements LovelaceCard {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 24px;
|
|
||||||
}
|
}
|
||||||
[role="button"] {
|
[role="button"] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -148,7 +147,7 @@ export class HuiHeadingCard extends LitElement implements LovelaceCard {
|
|||||||
transition: transform 180ms ease-in-out;
|
transition: transform 180ms ease-in-out;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
padding: 0 4px;
|
padding: 2px 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
@@ -1,372 +0,0 @@
|
|||||||
import { css, html, LitElement, nothing } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import { classMap } from "lit/directives/class-map";
|
|
||||||
import { ifDefined } from "lit/directives/if-defined";
|
|
||||||
import { styleMap } from "lit/directives/style-map";
|
|
||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
|
||||||
import { generateEntityFilter } from "../../../common/entity/entity_filter";
|
|
||||||
import { formatNumber } from "../../../common/number/format_number";
|
|
||||||
import "../../../components/ha-card";
|
|
||||||
import "../../../components/ha-icon";
|
|
||||||
import "../../../components/ha-ripple";
|
|
||||||
import "../../../components/tile/ha-tile-icon";
|
|
||||||
import "../../../components/tile/ha-tile-info";
|
|
||||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
|
||||||
import "../../../state-display/state-display";
|
|
||||||
import type { HomeAssistant } from "../../../types";
|
|
||||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
|
||||||
import { handleAction } from "../common/handle-action";
|
|
||||||
import { hasAction } from "../common/has-action";
|
|
||||||
import {
|
|
||||||
findEntities,
|
|
||||||
getSummaryLabel,
|
|
||||||
HOME_SUMMARIES_FILTERS,
|
|
||||||
HOME_SUMMARIES_ICONS,
|
|
||||||
type HomeSummary,
|
|
||||||
} from "../strategies/home/helpers/home-summaries";
|
|
||||||
import type { LovelaceCard, LovelaceGridOptions } from "../types";
|
|
||||||
import type { HomeSummaryCard } from "./types";
|
|
||||||
|
|
||||||
const COLORS: Record<HomeSummary, string> = {
|
|
||||||
lights: "amber",
|
|
||||||
climate: "deep-orange",
|
|
||||||
security: "blue",
|
|
||||||
media_players: "purple",
|
|
||||||
};
|
|
||||||
|
|
||||||
@customElement("hui-home-summary-card")
|
|
||||||
export class HuiHomeSummaryCard extends LitElement implements LovelaceCard {
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@state() private _config?: HomeSummaryCard;
|
|
||||||
|
|
||||||
public setConfig(config: HomeSummaryCard): void {
|
|
||||||
this._config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getCardSize(): number {
|
|
||||||
return this._config?.vertical ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getGridOptions(): LovelaceGridOptions {
|
|
||||||
const columns = 6;
|
|
||||||
let min_columns = 6;
|
|
||||||
let rows = 1;
|
|
||||||
|
|
||||||
if (this._config?.vertical) {
|
|
||||||
rows++;
|
|
||||||
min_columns = 3;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
columns,
|
|
||||||
rows,
|
|
||||||
min_columns,
|
|
||||||
min_rows: rows,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleAction(ev: ActionHandlerEvent) {
|
|
||||||
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _hasCardAction() {
|
|
||||||
return (
|
|
||||||
hasAction(this._config?.tap_action) ||
|
|
||||||
hasAction(this._config?.hold_action) ||
|
|
||||||
hasAction(this._config?.double_tap_action)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeSummaryState(): string {
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const allEntities = Object.keys(this.hass!.states);
|
|
||||||
|
|
||||||
const areas = Object.values(this.hass.areas);
|
|
||||||
const areasFilter = generateEntityFilter(this.hass, {
|
|
||||||
area: areas.map((area) => area.area_id),
|
|
||||||
});
|
|
||||||
|
|
||||||
const entitiesInsideArea = allEntities.filter(areasFilter);
|
|
||||||
|
|
||||||
switch (this._config.summary) {
|
|
||||||
case "lights": {
|
|
||||||
// Number of lights on
|
|
||||||
const lightsFilters = HOME_SUMMARIES_FILTERS.lights.map((filter) =>
|
|
||||||
generateEntityFilter(this.hass!, filter)
|
|
||||||
);
|
|
||||||
|
|
||||||
const lightEntities = findEntities(entitiesInsideArea, lightsFilters);
|
|
||||||
|
|
||||||
const onLights = lightEntities.filter((entityId) => {
|
|
||||||
const s = this.hass!.states[entityId]?.state;
|
|
||||||
return s === "on";
|
|
||||||
});
|
|
||||||
|
|
||||||
return onLights.length
|
|
||||||
? this.hass.localize("ui.card.home-summary.count_lights_on", {
|
|
||||||
count: onLights.length,
|
|
||||||
})
|
|
||||||
: this.hass.localize("ui.card.home-summary.all_lights_off");
|
|
||||||
}
|
|
||||||
case "climate": {
|
|
||||||
// Min/Max temperature of the areas
|
|
||||||
const areaSensors = areas
|
|
||||||
.map((area) => area.temperature_entity_id)
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
const sensorsValues = areaSensors
|
|
||||||
.map(
|
|
||||||
(entityId) => parseFloat(this.hass!.states[entityId!].state) || NaN
|
|
||||||
)
|
|
||||||
.filter((value) => !isNaN(value));
|
|
||||||
|
|
||||||
if (sensorsValues.length === 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const minTemp = Math.min(...sensorsValues);
|
|
||||||
const maxTemp = Math.max(...sensorsValues);
|
|
||||||
|
|
||||||
if (isNaN(minTemp) || isNaN(maxTemp)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const formattedMinTemp = formatNumber(minTemp, this.hass?.locale, {
|
|
||||||
minimumFractionDigits: 1,
|
|
||||||
maximumFractionDigits: 1,
|
|
||||||
});
|
|
||||||
const formattedMaxTemp = formatNumber(maxTemp, this.hass?.locale, {
|
|
||||||
minimumFractionDigits: 1,
|
|
||||||
maximumFractionDigits: 1,
|
|
||||||
});
|
|
||||||
return formattedMinTemp === formattedMaxTemp
|
|
||||||
? `${formattedMinTemp}°`
|
|
||||||
: `${formattedMinTemp} - ${formattedMaxTemp}°`;
|
|
||||||
}
|
|
||||||
case "security": {
|
|
||||||
// Alarm and lock status
|
|
||||||
const securityFilters = HOME_SUMMARIES_FILTERS.security.map((filter) =>
|
|
||||||
generateEntityFilter(this.hass!, filter)
|
|
||||||
);
|
|
||||||
|
|
||||||
const securityEntities = findEntities(
|
|
||||||
entitiesInsideArea,
|
|
||||||
securityFilters
|
|
||||||
);
|
|
||||||
|
|
||||||
const locks = securityEntities.filter((entityId) => {
|
|
||||||
const domain = computeDomain(entityId);
|
|
||||||
return domain === "lock";
|
|
||||||
});
|
|
||||||
|
|
||||||
const alarms = securityEntities.filter((entityId) => {
|
|
||||||
const domain = computeDomain(entityId);
|
|
||||||
return domain === "alarm_control_panel";
|
|
||||||
});
|
|
||||||
|
|
||||||
const disarmedAlarms = alarms.filter((entityId) => {
|
|
||||||
const s = this.hass!.states[entityId]?.state;
|
|
||||||
return s === "disarmed";
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!locks.length && !alarms.length) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const unlockedLocks = locks.filter((entityId) => {
|
|
||||||
const s = this.hass!.states[entityId]?.state;
|
|
||||||
return s === "unlocked" || s === "jammed" || s === "open";
|
|
||||||
});
|
|
||||||
|
|
||||||
if (unlockedLocks.length) {
|
|
||||||
return this.hass.localize(
|
|
||||||
"ui.card.home-summary.count_locks_unlocked",
|
|
||||||
{
|
|
||||||
count: unlockedLocks.length,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (disarmedAlarms.length) {
|
|
||||||
return this.hass.localize(
|
|
||||||
"ui.card.home-summary.count_alarms_disarmed",
|
|
||||||
{
|
|
||||||
count: disarmedAlarms.length,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.hass.localize("ui.card.home-summary.all_secure");
|
|
||||||
}
|
|
||||||
case "media_players": {
|
|
||||||
// Playing media
|
|
||||||
const mediaPlayerFilters = HOME_SUMMARIES_FILTERS.media_players.map(
|
|
||||||
(filter) => generateEntityFilter(this.hass!, filter)
|
|
||||||
);
|
|
||||||
|
|
||||||
const mediaPlayerEntities = findEntities(
|
|
||||||
entitiesInsideArea,
|
|
||||||
mediaPlayerFilters
|
|
||||||
);
|
|
||||||
|
|
||||||
const playingMedia = mediaPlayerEntities.filter((entityId) => {
|
|
||||||
const s = this.hass!.states[entityId]?.state;
|
|
||||||
return s === "playing";
|
|
||||||
});
|
|
||||||
|
|
||||||
return playingMedia.length
|
|
||||||
? this.hass.localize("ui.card.home-summary.count_media_playing", {
|
|
||||||
count: playingMedia.length,
|
|
||||||
})
|
|
||||||
: this.hass.localize("ui.card.home-summary.no_media_playing");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentClasses = { vertical: Boolean(this._config.vertical) };
|
|
||||||
|
|
||||||
const color = computeCssColor(COLORS[this._config.summary]);
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
"--tile-color": color,
|
|
||||||
};
|
|
||||||
|
|
||||||
const secondary = this._computeSummaryState();
|
|
||||||
|
|
||||||
const label = getSummaryLabel(this.hass.localize, this._config.summary);
|
|
||||||
const icon = HOME_SUMMARIES_ICONS[this._config.summary];
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-card style=${styleMap(style)}>
|
|
||||||
<div
|
|
||||||
class="background"
|
|
||||||
@action=${this._handleAction}
|
|
||||||
.actionHandler=${actionHandler({
|
|
||||||
hasHold: hasAction(this._config!.hold_action),
|
|
||||||
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
|
||||||
})}
|
|
||||||
role=${ifDefined(this._hasCardAction ? "button" : undefined)}
|
|
||||||
tabindex=${ifDefined(this._hasCardAction ? "0" : undefined)}
|
|
||||||
aria-labelledby="info"
|
|
||||||
>
|
|
||||||
<ha-ripple .disabled=${!this._hasCardAction}></ha-ripple>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
<div class="content ${classMap(contentClasses)}">
|
|
||||||
<ha-tile-icon>
|
|
||||||
<ha-icon slot="icon" .icon=${icon}></ha-icon>
|
|
||||||
</ha-tile-icon>
|
|
||||||
<ha-tile-info
|
|
||||||
id="info"
|
|
||||||
.primary=${label}
|
|
||||||
.secondary=${secondary}
|
|
||||||
></ha-tile-info>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
:host {
|
|
||||||
--tile-color: var(--state-inactive-color);
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
}
|
|
||||||
ha-card:has(.background:focus-visible) {
|
|
||||||
--shadow-default: var(--ha-card-box-shadow, 0 0 0 0 transparent);
|
|
||||||
--shadow-focus: 0 0 0 1px var(--tile-color);
|
|
||||||
border-color: var(--tile-color);
|
|
||||||
box-shadow: var(--shadow-default), var(--shadow-focus);
|
|
||||||
}
|
|
||||||
ha-card {
|
|
||||||
--ha-ripple-color: var(--tile-color);
|
|
||||||
--ha-ripple-hover-opacity: 0.04;
|
|
||||||
--ha-ripple-pressed-opacity: 0.12;
|
|
||||||
height: 100%;
|
|
||||||
transition:
|
|
||||||
box-shadow 180ms ease-in-out,
|
|
||||||
border-color 180ms ease-in-out;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
ha-card.active {
|
|
||||||
--tile-color: var(--state-icon-color);
|
|
||||||
}
|
|
||||||
[role="button"] {
|
|
||||||
cursor: pointer;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
[role="button"]:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
.background {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
border-radius: var(--ha-card-border-radius, 12px);
|
|
||||||
margin: calc(-1 * var(--ha-card-border-width, 1px));
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
margin: calc(-1 * var(--ha-card-border-width, 1px));
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.container.horizontal {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
pointer-events: none;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vertical {
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.vertical ha-tile-info {
|
|
||||||
width: 100%;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-tile-icon {
|
|
||||||
--tile-icon-color: var(--tile-color);
|
|
||||||
position: relative;
|
|
||||||
padding: 6px;
|
|
||||||
margin: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-tile-info {
|
|
||||||
position: relative;
|
|
||||||
min-width: 0;
|
|
||||||
transition: background-color 180ms ease-in-out;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hui-home-summary-card": HuiHomeSummaryCard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,6 @@ import type {
|
|||||||
import type { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
import type { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
||||||
import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types";
|
import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types";
|
||||||
import type { TimeFormat } from "../../../data/translation";
|
import type { TimeFormat } from "../../../data/translation";
|
||||||
import type { HomeSummary } from "../strategies/home/helpers/home-summaries";
|
|
||||||
|
|
||||||
export type AlarmPanelCardConfigState =
|
export type AlarmPanelCardConfigState =
|
||||||
| "arm_away"
|
| "arm_away"
|
||||||
@@ -589,11 +588,3 @@ export interface HeadingCardConfig extends LovelaceCardConfig {
|
|||||||
/** @deprecated Use `badges` instead */
|
/** @deprecated Use `badges` instead */
|
||||||
entities?: LovelaceHeadingBadgeConfig[];
|
entities?: LovelaceHeadingBadgeConfig[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HomeSummaryCard extends LovelaceCardConfig {
|
|
||||||
summary: HomeSummary;
|
|
||||||
vertical?: boolean;
|
|
||||||
tap_action?: ActionConfig;
|
|
||||||
hold_action?: ActionConfig;
|
|
||||||
double_tap_action?: ActionConfig;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ const LAZY_LOAD_TYPES = {
|
|||||||
"energy-sankey": () => import("../cards/energy/hui-energy-sankey-card"),
|
"energy-sankey": () => import("../cards/energy/hui-energy-sankey-card"),
|
||||||
"entity-filter": () => import("../cards/hui-entity-filter-card"),
|
"entity-filter": () => import("../cards/hui-entity-filter-card"),
|
||||||
error: () => import("../cards/hui-error-card"),
|
error: () => import("../cards/hui-error-card"),
|
||||||
"home-summary": () => import("../cards/hui-home-summary-card"),
|
|
||||||
gauge: () => import("../cards/hui-gauge-card"),
|
gauge: () => import("../cards/hui-gauge-card"),
|
||||||
"history-graph": () => import("../cards/hui-history-graph-card"),
|
"history-graph": () => import("../cards/hui-history-graph-card"),
|
||||||
"horizontal-stack": () => import("../cards/hui-horizontal-stack-card"),
|
"horizontal-stack": () => import("../cards/hui-horizontal-stack-card"),
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
|
|||||||
"fan-preset-modes",
|
"fan-preset-modes",
|
||||||
"humidifier-modes",
|
"humidifier-modes",
|
||||||
"lawn-mower-commands",
|
"lawn-mower-commands",
|
||||||
|
"media-player-volume-slider",
|
||||||
"numeric-input",
|
"numeric-input",
|
||||||
"select-options",
|
"select-options",
|
||||||
"update-actions",
|
"update-actions",
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import { html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import { assign, assert, number, object, optional } from "superstruct";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-form/ha-form";
|
||||||
|
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||||
|
import type {
|
||||||
|
MediaPlayerVolumeSliderCardFeatureConfig,
|
||||||
|
LovelaceCardFeatureContext,
|
||||||
|
} from "../../card-features/types";
|
||||||
|
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||||
|
|
||||||
|
const cardConfigStruct = assign(
|
||||||
|
baseLovelaceCardConfig,
|
||||||
|
object({
|
||||||
|
min: optional(number()),
|
||||||
|
max: optional(number()),
|
||||||
|
step: optional(number()),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
@customElement("hui-media-player-volume-slider-card-feature-editor")
|
||||||
|
export class HuiMediaPlayerVolumeSliderCardFeatureEditor
|
||||||
|
extends LitElement
|
||||||
|
implements LovelaceCardFeatureEditor
|
||||||
|
{
|
||||||
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||||
|
|
||||||
|
@state() private _config?: MediaPlayerVolumeSliderCardFeatureConfig;
|
||||||
|
|
||||||
|
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
|
||||||
|
assert(config, cardConfigStruct);
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _schema = memoizeOne(
|
||||||
|
() =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "min",
|
||||||
|
selector: {
|
||||||
|
number: {
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
mode: "slider",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "max",
|
||||||
|
selector: {
|
||||||
|
number: {
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
mode: "slider",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "step",
|
||||||
|
selector: {
|
||||||
|
number: {
|
||||||
|
min: 1,
|
||||||
|
max: 40,
|
||||||
|
mode: "slider",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
);
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.hass || !this._config) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: MediaPlayerVolumeSliderCardFeatureConfig = {
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
...this._config,
|
||||||
|
};
|
||||||
|
|
||||||
|
const schema = this._schema();
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-form
|
||||||
|
.hass=${this.hass}
|
||||||
|
.data=${data}
|
||||||
|
.schema=${schema}
|
||||||
|
.computeLabel=${this._computeLabelCallback}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></ha-form>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeLabelCallback = (
|
||||||
|
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
||||||
|
) =>
|
||||||
|
this.hass!.localize(
|
||||||
|
`ui.panel.lovelace.editor.features.types.media-player-volume-slider.${schema.name}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-media-player-volume-slider-card-feature-editor": HuiMediaPlayerVolumeSliderCardFeatureEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -355,10 +355,7 @@ class HUIRoot extends LitElement {
|
|||||||
overflowItems.forEach((i) => {
|
overflowItems.forEach((i) => {
|
||||||
const title = [this.hass!.localize(i.key), i.suffix].join(" ");
|
const title = [this.hass!.localize(i.key), i.suffix].join(" ");
|
||||||
const action = i.subItems
|
const action = i.subItems
|
||||||
? (e) => {
|
? () => {
|
||||||
if (!shouldHandleRequestSelectedEvent(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showListItemsDialog(this, {
|
showListItemsDialog(this, {
|
||||||
title: title,
|
title: title,
|
||||||
items: i.subItems!.map((si) => ({
|
items: i.subItems!.map((si) => ({
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import type { HomeAssistant } from "../../../../../types";
|
|||||||
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
|
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
|
||||||
import { supportsCoverOpenCloseCardFeature } from "../../../card-features/hui-cover-open-close-card-feature";
|
import { supportsCoverOpenCloseCardFeature } from "../../../card-features/hui-cover-open-close-card-feature";
|
||||||
import { supportsFanSpeedCardFeature } from "../../../card-features/hui-fan-speed-card-feature";
|
import { supportsFanSpeedCardFeature } from "../../../card-features/hui-fan-speed-card-feature";
|
||||||
|
import { supportsHistoryChartCardFeature } from "../../../card-features/hui-history-chart-card-feature";
|
||||||
import { supportsLightBrightnessCardFeature } from "../../../card-features/hui-light-brightness-card-feature";
|
import { supportsLightBrightnessCardFeature } from "../../../card-features/hui-light-brightness-card-feature";
|
||||||
import { supportsLockCommandsCardFeature } from "../../../card-features/hui-lock-commands-card-feature";
|
import { supportsLockCommandsCardFeature } from "../../../card-features/hui-lock-commands-card-feature";
|
||||||
import { supportsTargetTemperatureCardFeature } from "../../../card-features/hui-target-temperature-card-feature";
|
import { supportsTargetTemperatureCardFeature } from "../../../card-features/hui-target-temperature-card-feature";
|
||||||
@@ -237,7 +238,12 @@ export const computeAreaTileCardConfig =
|
|||||||
|
|
||||||
let feature: LovelaceCardFeatureConfig | undefined;
|
let feature: LovelaceCardFeatureConfig | undefined;
|
||||||
if (includeFeature) {
|
if (includeFeature) {
|
||||||
if (supportsLightBrightnessCardFeature(hass, context)) {
|
if (supportsHistoryChartCardFeature(hass, context)) {
|
||||||
|
feature = {
|
||||||
|
type: "history-chart",
|
||||||
|
hours_to_show: 24,
|
||||||
|
};
|
||||||
|
} else if (supportsLightBrightnessCardFeature(hass, context)) {
|
||||||
feature = {
|
feature = {
|
||||||
type: "light-brightness",
|
type: "light-brightness",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,12 +29,8 @@ export class HuiHomeDashboardStrategyEditor
|
|||||||
<ha-entities-picker
|
<ha-entities-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._config.favorite_entities || []}
|
.value=${this._config.favorite_entities || []}
|
||||||
label=${this.hass.localize(
|
label="Favorite entities"
|
||||||
"ui.panel.lovelace.editor.strategy.home.favorite_entities"
|
placeholder="Add favorite entity"
|
||||||
)}
|
|
||||||
placeholder=${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.editor.strategy.home.add_favorite_entity"
|
|
||||||
)}
|
|
||||||
reorder
|
reorder
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import type {
|
|||||||
EntityFilter,
|
EntityFilter,
|
||||||
EntityFilterFunc,
|
EntityFilterFunc,
|
||||||
} from "../../../../../common/entity/entity_filter";
|
} from "../../../../../common/entity/entity_filter";
|
||||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
|
||||||
|
|
||||||
export const HOME_SUMMARIES = [
|
export const HOME_SUMMARIES = [
|
||||||
"lights",
|
"lights",
|
||||||
@@ -11,16 +10,16 @@ export const HOME_SUMMARIES = [
|
|||||||
"media_players",
|
"media_players",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type HomeSummary = (typeof HOME_SUMMARIES)[number];
|
export type HomeSummaries = (typeof HOME_SUMMARIES)[number];
|
||||||
|
|
||||||
export const HOME_SUMMARIES_ICONS: Record<HomeSummary, string> = {
|
export const HOME_SUMMARIES_ICONS: Record<HomeSummaries, string> = {
|
||||||
lights: "mdi:lamps",
|
lights: "mdi:lamps",
|
||||||
climate: "mdi:home-thermometer",
|
climate: "mdi:home-thermometer",
|
||||||
security: "mdi:security",
|
security: "mdi:security",
|
||||||
media_players: "mdi:multimedia",
|
media_players: "mdi:multimedia",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HOME_SUMMARIES_FILTERS: Record<HomeSummary, EntityFilter[]> = {
|
export const HOME_SUMMARIES_FILTERS: Record<HomeSummaries, EntityFilter[]> = {
|
||||||
lights: [{ domain: "light", entity_category: "none" }],
|
lights: [{ domain: "light", entity_category: "none" }],
|
||||||
climate: [
|
climate: [
|
||||||
{ domain: "climate", entity_category: "none" },
|
{ domain: "climate", entity_category: "none" },
|
||||||
@@ -91,6 +90,3 @@ export const findEntities = (
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSummaryLabel = (localize: LocalizeFunc, summary: HomeSummary) =>
|
|
||||||
localize(`ui.panel.lovelace.strategy.home.summary_list.${summary}`);
|
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ import type { HeadingCardConfig } from "../../cards/types";
|
|||||||
import { computeAreaTileCardConfig } from "../areas/helpers/areas-strategy-helper";
|
import { computeAreaTileCardConfig } from "../areas/helpers/areas-strategy-helper";
|
||||||
import {
|
import {
|
||||||
findEntities,
|
findEntities,
|
||||||
getSummaryLabel,
|
|
||||||
HOME_SUMMARIES,
|
HOME_SUMMARIES,
|
||||||
HOME_SUMMARIES_FILTERS,
|
HOME_SUMMARIES_FILTERS,
|
||||||
HOME_SUMMARIES_ICONS,
|
HOME_SUMMARIES_ICONS,
|
||||||
type HomeSummary,
|
type HomeSummaries,
|
||||||
} from "./helpers/home-summaries";
|
} from "./helpers/home-summaries";
|
||||||
|
|
||||||
export interface HomeAreaViewStrategyConfig {
|
export interface HomeAreaViewStrategyConfig {
|
||||||
@@ -97,7 +96,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
acc[summary] = findEntities(areaEntities, filterFunctions);
|
acc[summary] = findEntities(areaEntities, filterFunctions);
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as Record<HomeSummary, string[]>
|
{} as Record<HomeSummaries, string[]>
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -111,11 +110,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
sections.push({
|
sections.push({
|
||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [
|
||||||
computeHeadingCard(
|
computeHeadingCard("Lights", HOME_SUMMARIES_ICONS.lights, "lights"),
|
||||||
getSummaryLabel(hass.localize, "lights"),
|
|
||||||
HOME_SUMMARIES_ICONS.lights,
|
|
||||||
"lights"
|
|
||||||
),
|
|
||||||
...lights.map(computeTileCard),
|
...lights.map(computeTileCard),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -126,7 +121,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [
|
||||||
computeHeadingCard(
|
computeHeadingCard(
|
||||||
getSummaryLabel(hass.localize, "climate"),
|
"Climate",
|
||||||
HOME_SUMMARIES_ICONS.climate,
|
HOME_SUMMARIES_ICONS.climate,
|
||||||
"climate"
|
"climate"
|
||||||
),
|
),
|
||||||
@@ -140,7 +135,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [
|
||||||
computeHeadingCard(
|
computeHeadingCard(
|
||||||
getSummaryLabel(hass.localize, "security"),
|
"Security",
|
||||||
HOME_SUMMARIES_ICONS.security,
|
HOME_SUMMARIES_ICONS.security,
|
||||||
"security"
|
"security"
|
||||||
),
|
),
|
||||||
@@ -154,7 +149,7 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [
|
||||||
computeHeadingCard(
|
computeHeadingCard(
|
||||||
getSummaryLabel(hass.localize, "media_players"),
|
"Media players",
|
||||||
HOME_SUMMARIES_ICONS.media_players,
|
HOME_SUMMARIES_ICONS.media_players,
|
||||||
"media-players"
|
"media-players"
|
||||||
),
|
),
|
||||||
@@ -234,11 +229,9 @@ export class HomeAreaViewStrategy extends ReactiveElement {
|
|||||||
const device = hass.devices[deviceId];
|
const device = hass.devices[deviceId];
|
||||||
let heading = "";
|
let heading = "";
|
||||||
if (device) {
|
if (device) {
|
||||||
heading =
|
heading = computeDeviceName(device) || "Unnamed device";
|
||||||
computeDeviceName(device) ||
|
|
||||||
hass.localize("ui.panel.lovelace.strategy.home.unamed_device");
|
|
||||||
} else {
|
} else {
|
||||||
heading = hass.localize("ui.panel.lovelace.strategy.home.others");
|
heading = "Others";
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceSections.push({
|
deviceSections.push({
|
||||||
|
|||||||
@@ -12,30 +12,11 @@ import {
|
|||||||
} from "../areas/helpers/areas-strategy-helper";
|
} from "../areas/helpers/areas-strategy-helper";
|
||||||
import { getHomeStructure } from "./helpers/home-structure";
|
import { getHomeStructure } from "./helpers/home-structure";
|
||||||
import { findEntities, HOME_SUMMARIES_FILTERS } from "./helpers/home-summaries";
|
import { findEntities, HOME_SUMMARIES_FILTERS } from "./helpers/home-summaries";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import { computeObjectId } from "../../../../common/entity/compute_object_id";
|
|
||||||
|
|
||||||
export interface HomeClimateViewStrategyConfig {
|
export interface HomeClimateViewStrategyConfig {
|
||||||
type: "home-climate";
|
type: "home-climate";
|
||||||
}
|
}
|
||||||
|
|
||||||
const createTempHumidBadge = (hass: HomeAssistant, entityId: string) => {
|
|
||||||
const stateObj = hass.states[entityId];
|
|
||||||
return {
|
|
||||||
type: "tile",
|
|
||||||
entity: entityId,
|
|
||||||
name: stateObj
|
|
||||||
? computeStateName(stateObj)
|
|
||||||
: computeObjectId(entityId).replace(/_/g, " "),
|
|
||||||
features: [
|
|
||||||
{
|
|
||||||
type: "history-chart",
|
|
||||||
hours_to_show: 3,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const processAreasForClimate = (
|
const processAreasForClimate = (
|
||||||
areaIds: string[],
|
areaIds: string[],
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@@ -65,14 +46,10 @@ const processAreasForClimate = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (hass.areas[areaId].temperature_entity_id) {
|
if (hass.areas[areaId].temperature_entity_id) {
|
||||||
cards.push(
|
cards.push(computeTileCard(hass.areas[areaId].temperature_entity_id));
|
||||||
createTempHumidBadge(hass, hass.areas[areaId].temperature_entity_id)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (hass.areas[areaId].humidity_entity_id) {
|
if (hass.areas[areaId].humidity_entity_id) {
|
||||||
cards.push(
|
cards.push(computeTileCard(hass.areas[areaId].humidity_entity_id));
|
||||||
createTempHumidBadge(hass, hass.areas[areaId].humidity_entity_id)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const entityId of areaEntities) {
|
for (const entityId of areaEntities) {
|
||||||
@@ -118,10 +95,7 @@ export class HomeClimateViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? floor.name : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? floor.name
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -142,10 +116,7 @@ export class HomeClimateViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? "Other areas" : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? hass.localize("ui.panel.lovelace.strategy.home.other_areas")
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ import type { LovelaceViewRawConfig } from "../../../../data/lovelace/config/vie
|
|||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import { getAreas } from "../areas/helpers/areas-strategy-helper";
|
import { getAreas } from "../areas/helpers/areas-strategy-helper";
|
||||||
import type { LovelaceStrategyEditor } from "../types";
|
import type { LovelaceStrategyEditor } from "../types";
|
||||||
import {
|
import { HOME_SUMMARIES_ICONS } from "./helpers/home-summaries";
|
||||||
getSummaryLabel,
|
|
||||||
HOME_SUMMARIES_ICONS,
|
|
||||||
} from "./helpers/home-summaries";
|
|
||||||
import type { HomeAreaViewStrategyConfig } from "./home-area-view-strategy";
|
import type { HomeAreaViewStrategyConfig } from "./home-area-view-strategy";
|
||||||
import type { HomeMainViewStrategyConfig } from "./home-main-view-strategy";
|
import type { HomeMainViewStrategyConfig } from "./home-main-view-strategy";
|
||||||
|
|
||||||
@@ -63,7 +60,7 @@ export class HomeDashboardStrategy extends ReactiveElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const lightView = {
|
const lightView = {
|
||||||
title: getSummaryLabel(hass.localize, "lights"),
|
title: "Lights",
|
||||||
path: "lights",
|
path: "lights",
|
||||||
subview: true,
|
subview: true,
|
||||||
strategy: {
|
strategy: {
|
||||||
@@ -73,7 +70,7 @@ export class HomeDashboardStrategy extends ReactiveElement {
|
|||||||
} satisfies LovelaceViewRawConfig;
|
} satisfies LovelaceViewRawConfig;
|
||||||
|
|
||||||
const climateView = {
|
const climateView = {
|
||||||
title: getSummaryLabel(hass.localize, "climate"),
|
title: "Climate",
|
||||||
path: "climate",
|
path: "climate",
|
||||||
subview: true,
|
subview: true,
|
||||||
strategy: {
|
strategy: {
|
||||||
@@ -83,7 +80,7 @@ export class HomeDashboardStrategy extends ReactiveElement {
|
|||||||
} satisfies LovelaceViewRawConfig;
|
} satisfies LovelaceViewRawConfig;
|
||||||
|
|
||||||
const securityView = {
|
const securityView = {
|
||||||
title: getSummaryLabel(hass.localize, "security"),
|
title: "Security",
|
||||||
path: "security",
|
path: "security",
|
||||||
subview: true,
|
subview: true,
|
||||||
strategy: {
|
strategy: {
|
||||||
@@ -93,7 +90,7 @@ export class HomeDashboardStrategy extends ReactiveElement {
|
|||||||
} satisfies LovelaceViewRawConfig;
|
} satisfies LovelaceViewRawConfig;
|
||||||
|
|
||||||
const mediaPlayersView = {
|
const mediaPlayersView = {
|
||||||
title: getSummaryLabel(hass.localize, "media_players"),
|
title: "Media players",
|
||||||
path: "media-players",
|
path: "media-players",
|
||||||
subview: true,
|
subview: true,
|
||||||
strategy: {
|
strategy: {
|
||||||
|
|||||||
@@ -89,10 +89,7 @@ export class HomeLightsViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? floor.name : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? floor.name
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -113,10 +110,7 @@ export class HomeLightsViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? "Other areas" : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? hass.localize("ui.panel.lovelace.strategy.home.other_areas")
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
|||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type {
|
import type {
|
||||||
AreaCardConfig,
|
AreaCardConfig,
|
||||||
HomeSummaryCard,
|
ButtonCardConfig,
|
||||||
MarkdownCardConfig,
|
MarkdownCardConfig,
|
||||||
TileCardConfig,
|
TileCardConfig,
|
||||||
WeatherForecastCardConfig,
|
WeatherForecastCardConfig,
|
||||||
} from "../../cards/types";
|
} from "../../cards/types";
|
||||||
import { getAreas } from "../areas/helpers/areas-strategy-helper";
|
import { getAreas } from "../areas/helpers/areas-strategy-helper";
|
||||||
|
import { HOME_SUMMARIES_ICONS } from "./helpers/home-summaries";
|
||||||
|
|
||||||
export interface HomeMainViewStrategyConfig {
|
export interface HomeMainViewStrategyConfig {
|
||||||
type: "home-main";
|
type: "home-main";
|
||||||
@@ -62,7 +63,7 @@ export class HomeMainViewStrategy extends ReactiveElement {
|
|||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading_style: "title",
|
heading_style: "title",
|
||||||
heading: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
heading: "Areas",
|
||||||
},
|
},
|
||||||
...areas.map<AreaCardConfig>((area) =>
|
...areas.map<AreaCardConfig>((area) =>
|
||||||
computeAreaCard(area.area_id, hass)
|
computeAreaCard(area.area_id, hass)
|
||||||
@@ -107,60 +108,64 @@ export class HomeMainViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading: hass.localize("ui.panel.lovelace.strategy.home.summaries"),
|
heading: "Summaries",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "home-summary",
|
type: "button",
|
||||||
summary: "lights",
|
icon: HOME_SUMMARIES_ICONS.lights,
|
||||||
vertical: true,
|
name: "Lights",
|
||||||
|
icon_height: "24px",
|
||||||
|
grid_options: {
|
||||||
|
rows: 2,
|
||||||
|
columns: 4,
|
||||||
|
},
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "navigate",
|
action: "navigate",
|
||||||
navigation_path: "lights",
|
navigation_path: "lights",
|
||||||
},
|
},
|
||||||
|
} satisfies ButtonCardConfig,
|
||||||
|
{
|
||||||
|
type: "button",
|
||||||
|
icon: HOME_SUMMARIES_ICONS.climate,
|
||||||
|
name: "Climate",
|
||||||
|
icon_height: "30px",
|
||||||
grid_options: {
|
grid_options: {
|
||||||
rows: 2,
|
rows: 2,
|
||||||
columns: 4,
|
columns: 4,
|
||||||
},
|
},
|
||||||
} satisfies HomeSummaryCard,
|
|
||||||
{
|
|
||||||
type: "home-summary",
|
|
||||||
summary: "climate",
|
|
||||||
vertical: true,
|
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "navigate",
|
action: "navigate",
|
||||||
navigation_path: "climate",
|
navigation_path: "climate",
|
||||||
},
|
},
|
||||||
|
} satisfies ButtonCardConfig,
|
||||||
|
{
|
||||||
|
type: "button",
|
||||||
|
icon: HOME_SUMMARIES_ICONS.security,
|
||||||
|
name: "Security",
|
||||||
|
icon_height: "30px",
|
||||||
grid_options: {
|
grid_options: {
|
||||||
rows: 2,
|
rows: 2,
|
||||||
columns: 4,
|
columns: 4,
|
||||||
},
|
},
|
||||||
} satisfies HomeSummaryCard,
|
|
||||||
{
|
|
||||||
type: "home-summary",
|
|
||||||
summary: "security",
|
|
||||||
vertical: true,
|
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "navigate",
|
action: "navigate",
|
||||||
navigation_path: "security",
|
navigation_path: "security",
|
||||||
},
|
},
|
||||||
|
} satisfies ButtonCardConfig,
|
||||||
|
{
|
||||||
|
type: "button",
|
||||||
|
icon: HOME_SUMMARIES_ICONS.media_players,
|
||||||
|
name: "Media Players",
|
||||||
|
icon_height: "30px",
|
||||||
grid_options: {
|
grid_options: {
|
||||||
rows: 2,
|
rows: 2,
|
||||||
columns: 4,
|
columns: 4,
|
||||||
},
|
},
|
||||||
} satisfies HomeSummaryCard,
|
|
||||||
{
|
|
||||||
type: "home-summary",
|
|
||||||
summary: "media_players",
|
|
||||||
vertical: true,
|
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "navigate",
|
action: "navigate",
|
||||||
navigation_path: "media-players",
|
navigation_path: "media-players",
|
||||||
},
|
},
|
||||||
grid_options: {
|
} satisfies ButtonCardConfig,
|
||||||
rows: 2,
|
|
||||||
columns: 4,
|
|
||||||
},
|
|
||||||
} satisfies HomeSummaryCard,
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -227,7 +232,7 @@ export class HomeMainViewStrategy extends ReactiveElement {
|
|||||||
card: {
|
card: {
|
||||||
type: "markdown",
|
type: "markdown",
|
||||||
text_only: true,
|
text_only: true,
|
||||||
content: `## ${hass.localize("ui.panel.lovelace.strategy.home.welcome_user", { user: "{{ user }}" })}`,
|
content: "## Welcome {{user}}",
|
||||||
} satisfies MarkdownCardConfig,
|
} satisfies MarkdownCardConfig,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,10 +87,7 @@ export class HomeMMediaPlayersViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? floor.name : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? floor.name
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -111,10 +108,7 @@ export class HomeMMediaPlayersViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? "Other areas" : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? hass.localize("ui.panel.lovelace.strategy.home.other_areas")
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import {
|
|||||||
import { getHomeStructure } from "./helpers/home-structure";
|
import { getHomeStructure } from "./helpers/home-structure";
|
||||||
import { findEntities, HOME_SUMMARIES_FILTERS } from "./helpers/home-summaries";
|
import { findEntities, HOME_SUMMARIES_FILTERS } from "./helpers/home-summaries";
|
||||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import { computeObjectId } from "../../../../common/entity/compute_object_id";
|
|
||||||
|
|
||||||
export interface HomeSecurityViewStrategyConfig {
|
export interface HomeSecurityViewStrategyConfig {
|
||||||
type: "home-security";
|
type: "home-security";
|
||||||
@@ -27,6 +25,7 @@ const processAreasForSecurity = (
|
|||||||
): LovelaceCardConfig[] => {
|
): LovelaceCardConfig[] => {
|
||||||
const cards: LovelaceCardConfig[] = [];
|
const cards: LovelaceCardConfig[] = [];
|
||||||
const computeTileCard = computeAreaTileCardConfig(hass, "", false);
|
const computeTileCard = computeAreaTileCardConfig(hass, "", false);
|
||||||
|
const computeTileCardWithFeature = computeAreaTileCardConfig(hass, "", true);
|
||||||
|
|
||||||
for (const areaId of areaIds) {
|
for (const areaId of areaIds) {
|
||||||
const area = hass.areas[areaId];
|
const area = hass.areas[areaId];
|
||||||
@@ -49,23 +48,10 @@ const processAreasForSecurity = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const entityId of areaEntities) {
|
for (const entityId of areaEntities) {
|
||||||
const stateObj = hass.states[entityId];
|
|
||||||
cards.push(
|
cards.push(
|
||||||
computeDomain(entityId) === "binary_sensor" &&
|
computeDomain(entityId) === "binary_sensor" &&
|
||||||
stateObj?.attributes.device_class === "motion"
|
hass.states[entityId]?.attributes.device_class === "motion"
|
||||||
? {
|
? computeTileCardWithFeature(entityId)
|
||||||
type: "tile",
|
|
||||||
entity: entityId,
|
|
||||||
name: stateObj
|
|
||||||
? computeStateName(stateObj)
|
|
||||||
: computeObjectId(entityId).replace(/_/g, " "),
|
|
||||||
features: [
|
|
||||||
{
|
|
||||||
type: "history-chart",
|
|
||||||
hours_to_show: 6,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
: computeTileCard(entityId)
|
: computeTileCard(entityId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -109,10 +95,7 @@ export class HomeSecurityViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? floor.name : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? floor.name
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -133,10 +116,7 @@ export class HomeSecurityViewStrategy extends ReactiveElement {
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
type: "heading",
|
type: "heading",
|
||||||
heading:
|
heading: floorCount > 1 ? "Other areas" : "Areas",
|
||||||
floorCount > 1
|
|
||||||
? hass.localize("ui.panel.lovelace.strategy.home.other_areas")
|
|
||||||
: hass.localize("ui.panel.lovelace.strategy.home.areas"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -201,15 +201,6 @@
|
|||||||
"open_door_confirm": "Really open?",
|
"open_door_confirm": "Really open?",
|
||||||
"open_door_done": "Done"
|
"open_door_done": "Done"
|
||||||
},
|
},
|
||||||
"home-summary": {
|
|
||||||
"all_lights_off": "All off",
|
|
||||||
"count_lights_on": "{count} {count, plural,\n one {on}\n other {on}\n}",
|
|
||||||
"count_locks_unlocked": "{count} {count, plural,\n one {unlocked}\n other {unlocked}\n}",
|
|
||||||
"count_alarms_disarmed": "{count} {count, plural,\n one {disarmed}\n other {disarmed}\n}",
|
|
||||||
"all_secure": "All secure",
|
|
||||||
"no_media_playing": "No media playing",
|
|
||||||
"count_media_playing": "{count} {count, plural,\n one {playing}\n other {playing}\n}"
|
|
||||||
},
|
|
||||||
"media_player": {
|
"media_player": {
|
||||||
"source": "Source",
|
"source": "Source",
|
||||||
"sound_mode": "Sound mode",
|
"sound_mode": "Sound mode",
|
||||||
@@ -5127,7 +5118,7 @@
|
|||||||
"integration": "Integration",
|
"integration": "Integration",
|
||||||
"config_entry": "Config entry"
|
"config_entry": "Config entry"
|
||||||
},
|
},
|
||||||
"enabled_description": "Disabled devices and services will not be shown and entities belonging to them will be disabled, too.",
|
"enabled_description": "Disabled devices will not be shown and entities belonging to the device will be disabled and not added to Home Assistant.",
|
||||||
"open_configuration_url": "Visit",
|
"open_configuration_url": "Visit",
|
||||||
"set_up_voice_assistant": "Set up voice assistant",
|
"set_up_voice_assistant": "Set up voice assistant",
|
||||||
"download_diagnostics": "Download diagnostics",
|
"download_diagnostics": "Download diagnostics",
|
||||||
@@ -6826,20 +6817,6 @@
|
|||||||
},
|
},
|
||||||
"other_areas": "Other areas",
|
"other_areas": "Other areas",
|
||||||
"areas": "Areas"
|
"areas": "Areas"
|
||||||
},
|
|
||||||
"home": {
|
|
||||||
"summary_list": {
|
|
||||||
"climate": "Climate",
|
|
||||||
"lights": "Lights",
|
|
||||||
"security": "Security",
|
|
||||||
"media_players": "Media players"
|
|
||||||
},
|
|
||||||
"welcome_user": "Welcome {user}",
|
|
||||||
"summaries": "Summaries",
|
|
||||||
"areas": "Areas",
|
|
||||||
"other_areas": "Other areas",
|
|
||||||
"unamed_device": "Unnamed device",
|
|
||||||
"others": "Others"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cards": {
|
"cards": {
|
||||||
@@ -8011,7 +7988,10 @@
|
|||||||
"label": "Media player playback controls"
|
"label": "Media player playback controls"
|
||||||
},
|
},
|
||||||
"media-player-volume-slider": {
|
"media-player-volume-slider": {
|
||||||
"label": "Media player volume slider"
|
"label": "Media player volume slider",
|
||||||
|
"min": "Minimum volume",
|
||||||
|
"max": "Maximum volume",
|
||||||
|
"step": "Step size"
|
||||||
},
|
},
|
||||||
"vacuum-commands": {
|
"vacuum-commands": {
|
||||||
"label": "Vacuum commands",
|
"label": "Vacuum commands",
|
||||||
@@ -8199,10 +8179,6 @@
|
|||||||
"no_entities": "No entities in this group, the section will not be displayed",
|
"no_entities": "No entities in this group, the section will not be displayed",
|
||||||
"use_compact_card": "Use compact card",
|
"use_compact_card": "Use compact card",
|
||||||
"use_large_card": "Use large card"
|
"use_large_card": "Use large card"
|
||||||
},
|
|
||||||
"home": {
|
|
||||||
"favorite_entities": "Favorite entities",
|
|
||||||
"add_favorite_entity": "Add favorite entity"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
|
|||||||
178
yarn.lock
178
yarn.lock
@@ -3281,58 +3281,58 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/error-codes@npm:0.18.0":
|
"@module-federation/error-codes@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/error-codes@npm:0.18.0"
|
resolution: "@module-federation/error-codes@npm:0.17.1"
|
||||||
checksum: 10/ccd00f6b2504ec2e685bda6d175ed86df27e21994b36869140a18059595716e9ea7db5d0b516a095891ec9e6c90e702f42a366743df3652bf91ff3bb4f895991
|
checksum: 10/5f5f02a90a423479c84e4ff4398a3a9e31b66bd545e7c978ecb8a417f33162b86e749356baab14c006e741c9cebae549335a4c99e94ce7ef54210269fdf74f7f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/runtime-core@npm:0.18.0":
|
"@module-federation/runtime-core@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/runtime-core@npm:0.18.0"
|
resolution: "@module-federation/runtime-core@npm:0.17.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@module-federation/error-codes": "npm:0.18.0"
|
"@module-federation/error-codes": "npm:0.17.1"
|
||||||
"@module-federation/sdk": "npm:0.18.0"
|
"@module-federation/sdk": "npm:0.17.1"
|
||||||
checksum: 10/82af795408f2e92bea9c801a2057f1a6ed85eaf131195d5deaa4ef9a6a88db9e2cb851b4416e6e43a841459986b5ebb84e98b4625fb9bbd98cee11929f1ede6b
|
checksum: 10/b0c945379bde13af84ceb833e3bfe3c8cf11fd265af0ad7640a1506017529458f408a4a3f1bd0f4b5983da71438913d5c25ed25e20908eb1f789bd1483616650
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/runtime-tools@npm:0.18.0":
|
"@module-federation/runtime-tools@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/runtime-tools@npm:0.18.0"
|
resolution: "@module-federation/runtime-tools@npm:0.17.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@module-federation/runtime": "npm:0.18.0"
|
"@module-federation/runtime": "npm:0.17.1"
|
||||||
"@module-federation/webpack-bundler-runtime": "npm:0.18.0"
|
"@module-federation/webpack-bundler-runtime": "npm:0.17.1"
|
||||||
checksum: 10/c6b1483899865e4c73be0ae77e6e1a5f517798f7ab3b8c6df2bb7ed22463e7a471f68d5f9528b2aff5b45e2db67596805028206f3956aafec5a36dcefb94afd2
|
checksum: 10/2e183e357b644dbe015d0e51df3fe601852ca79ffe3a30c582eee7a2050d7600eb3253f5de15e476c60741d0a1dd70add1ade7b5a3537cd2ee12bfee286284ea
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/runtime@npm:0.18.0":
|
"@module-federation/runtime@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/runtime@npm:0.18.0"
|
resolution: "@module-federation/runtime@npm:0.17.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@module-federation/error-codes": "npm:0.18.0"
|
"@module-federation/error-codes": "npm:0.17.1"
|
||||||
"@module-federation/runtime-core": "npm:0.18.0"
|
"@module-federation/runtime-core": "npm:0.17.1"
|
||||||
"@module-federation/sdk": "npm:0.18.0"
|
"@module-federation/sdk": "npm:0.17.1"
|
||||||
checksum: 10/6164597782b21840e3b8f159000338d8e20a817a60909015c11402e9e6442d60d9c3b4b6f25d92d7261011ef1fc0e8caafbb91f25c29b372f28764cbea8ef9eb
|
checksum: 10/f5405968dff4fa2cf510127701ec1722105f44298fd09eafeecead450b7bb95a05450749157fe2fc39caf6241bec9e45caa9a55375b48e7f195db84799a8df0c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/sdk@npm:0.18.0":
|
"@module-federation/sdk@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/sdk@npm:0.18.0"
|
resolution: "@module-federation/sdk@npm:0.17.1"
|
||||||
checksum: 10/f397dc53c705ad1f1e19530a8ff79116bb5aeeef92a79b3acaaa6140ae4e5784b42e81d1445eabf536c007c9383857f6764506ed725a6352464fe1ce581af89a
|
checksum: 10/daaaa49ed900c00a69641130cf673ad5d5b8623d82fb4bd03a67c839a6da760a0a5ae29b836ba66eeb95ee5392e558588ffd987a2c00b05c2b0a7c5039ed042d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@module-federation/webpack-bundler-runtime@npm:0.18.0":
|
"@module-federation/webpack-bundler-runtime@npm:0.17.1":
|
||||||
version: 0.18.0
|
version: 0.17.1
|
||||||
resolution: "@module-federation/webpack-bundler-runtime@npm:0.18.0"
|
resolution: "@module-federation/webpack-bundler-runtime@npm:0.17.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@module-federation/runtime": "npm:0.18.0"
|
"@module-federation/runtime": "npm:0.17.1"
|
||||||
"@module-federation/sdk": "npm:0.18.0"
|
"@module-federation/sdk": "npm:0.17.1"
|
||||||
checksum: 10/c80f26e02d497948a0864283bedf13118d5c188ac8165e71edce5da72776091db6da2dc5da5d47a53fbb6914bfbff1ddfce16a6b9c18485a9a41a04bc4060e34
|
checksum: 10/72e5030529dbc53df6271fa78bdb63976d0601fe9fde5105f8a7325e0fa296bc35277b9b084e52995cd314b89e12d33f8b869c1d63a13231c2948d4c741e72fd
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -3990,92 +3990,92 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-darwin-arm64@npm:1.5.1":
|
"@rspack/binding-darwin-arm64@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-darwin-arm64@npm:1.5.1"
|
resolution: "@rspack/binding-darwin-arm64@npm:1.4.11"
|
||||||
conditions: os=darwin & cpu=arm64
|
conditions: os=darwin & cpu=arm64
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-darwin-x64@npm:1.5.1":
|
"@rspack/binding-darwin-x64@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-darwin-x64@npm:1.5.1"
|
resolution: "@rspack/binding-darwin-x64@npm:1.4.11"
|
||||||
conditions: os=darwin & cpu=x64
|
conditions: os=darwin & cpu=x64
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-linux-arm64-gnu@npm:1.5.1":
|
"@rspack/binding-linux-arm64-gnu@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-linux-arm64-gnu@npm:1.5.1"
|
resolution: "@rspack/binding-linux-arm64-gnu@npm:1.4.11"
|
||||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-linux-arm64-musl@npm:1.5.1":
|
"@rspack/binding-linux-arm64-musl@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-linux-arm64-musl@npm:1.5.1"
|
resolution: "@rspack/binding-linux-arm64-musl@npm:1.4.11"
|
||||||
conditions: os=linux & cpu=arm64 & libc=musl
|
conditions: os=linux & cpu=arm64 & libc=musl
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-linux-x64-gnu@npm:1.5.1":
|
"@rspack/binding-linux-x64-gnu@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-linux-x64-gnu@npm:1.5.1"
|
resolution: "@rspack/binding-linux-x64-gnu@npm:1.4.11"
|
||||||
conditions: os=linux & cpu=x64 & libc=glibc
|
conditions: os=linux & cpu=x64 & libc=glibc
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-linux-x64-musl@npm:1.5.1":
|
"@rspack/binding-linux-x64-musl@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-linux-x64-musl@npm:1.5.1"
|
resolution: "@rspack/binding-linux-x64-musl@npm:1.4.11"
|
||||||
conditions: os=linux & cpu=x64 & libc=musl
|
conditions: os=linux & cpu=x64 & libc=musl
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-wasm32-wasi@npm:1.5.1":
|
"@rspack/binding-wasm32-wasi@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-wasm32-wasi@npm:1.5.1"
|
resolution: "@rspack/binding-wasm32-wasi@npm:1.4.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@napi-rs/wasm-runtime": "npm:^1.0.1"
|
"@napi-rs/wasm-runtime": "npm:^1.0.1"
|
||||||
conditions: cpu=wasm32
|
conditions: cpu=wasm32
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-win32-arm64-msvc@npm:1.5.1":
|
"@rspack/binding-win32-arm64-msvc@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-win32-arm64-msvc@npm:1.5.1"
|
resolution: "@rspack/binding-win32-arm64-msvc@npm:1.4.11"
|
||||||
conditions: os=win32 & cpu=arm64
|
conditions: os=win32 & cpu=arm64
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-win32-ia32-msvc@npm:1.5.1":
|
"@rspack/binding-win32-ia32-msvc@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-win32-ia32-msvc@npm:1.5.1"
|
resolution: "@rspack/binding-win32-ia32-msvc@npm:1.4.11"
|
||||||
conditions: os=win32 & cpu=ia32
|
conditions: os=win32 & cpu=ia32
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding-win32-x64-msvc@npm:1.5.1":
|
"@rspack/binding-win32-x64-msvc@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding-win32-x64-msvc@npm:1.5.1"
|
resolution: "@rspack/binding-win32-x64-msvc@npm:1.4.11"
|
||||||
conditions: os=win32 & cpu=x64
|
conditions: os=win32 & cpu=x64
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/binding@npm:1.5.1":
|
"@rspack/binding@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/binding@npm:1.5.1"
|
resolution: "@rspack/binding@npm:1.4.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@rspack/binding-darwin-arm64": "npm:1.5.1"
|
"@rspack/binding-darwin-arm64": "npm:1.4.11"
|
||||||
"@rspack/binding-darwin-x64": "npm:1.5.1"
|
"@rspack/binding-darwin-x64": "npm:1.4.11"
|
||||||
"@rspack/binding-linux-arm64-gnu": "npm:1.5.1"
|
"@rspack/binding-linux-arm64-gnu": "npm:1.4.11"
|
||||||
"@rspack/binding-linux-arm64-musl": "npm:1.5.1"
|
"@rspack/binding-linux-arm64-musl": "npm:1.4.11"
|
||||||
"@rspack/binding-linux-x64-gnu": "npm:1.5.1"
|
"@rspack/binding-linux-x64-gnu": "npm:1.4.11"
|
||||||
"@rspack/binding-linux-x64-musl": "npm:1.5.1"
|
"@rspack/binding-linux-x64-musl": "npm:1.4.11"
|
||||||
"@rspack/binding-wasm32-wasi": "npm:1.5.1"
|
"@rspack/binding-wasm32-wasi": "npm:1.4.11"
|
||||||
"@rspack/binding-win32-arm64-msvc": "npm:1.5.1"
|
"@rspack/binding-win32-arm64-msvc": "npm:1.4.11"
|
||||||
"@rspack/binding-win32-ia32-msvc": "npm:1.5.1"
|
"@rspack/binding-win32-ia32-msvc": "npm:1.4.11"
|
||||||
"@rspack/binding-win32-x64-msvc": "npm:1.5.1"
|
"@rspack/binding-win32-x64-msvc": "npm:1.4.11"
|
||||||
dependenciesMeta:
|
dependenciesMeta:
|
||||||
"@rspack/binding-darwin-arm64":
|
"@rspack/binding-darwin-arm64":
|
||||||
optional: true
|
optional: true
|
||||||
@@ -4097,23 +4097,23 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
"@rspack/binding-win32-x64-msvc":
|
"@rspack/binding-win32-x64-msvc":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10/a6756a35bda55fd9e21b1ce142ca18e228d92832dc213027a19314981f8f12e6510dd862a9724ee96dee61755b3dd30ce73b2bb117d150e9f5ce73ba8fe4b57a
|
checksum: 10/8bb94774204f41888ff442afec06f019d008abba79964b74d566acf64f7216a148a1842f90c44b3bf680e69b697d8e5cd0f1cca6fd0b8a94df5f97c2a3f05510
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rspack/core@npm:1.5.1":
|
"@rspack/core@npm:1.4.11":
|
||||||
version: 1.5.1
|
version: 1.4.11
|
||||||
resolution: "@rspack/core@npm:1.5.1"
|
resolution: "@rspack/core@npm:1.4.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@module-federation/runtime-tools": "npm:0.18.0"
|
"@module-federation/runtime-tools": "npm:0.17.1"
|
||||||
"@rspack/binding": "npm:1.5.1"
|
"@rspack/binding": "npm:1.4.11"
|
||||||
"@rspack/lite-tapable": "npm:1.0.1"
|
"@rspack/lite-tapable": "npm:1.0.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@swc/helpers": ">=0.5.1"
|
"@swc/helpers": ">=0.5.1"
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
"@swc/helpers":
|
"@swc/helpers":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10/b7a6269d5bdbcad140d172ebe951f4693711573d4f38e4c676c250a9cc6c1bdf602ad5187eeacc07ff12b74d510b746c92e3f112c8ab4dca46846c595d2876b0
|
checksum: 10/77d463bd90feb2d24f7bc56df198f0b7ad310a9eb676070eac8d78014d151e783943c5b44c64700a51a36708c626a341eeaa9b3287e358616d09dfe25ab04e77
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -9377,7 +9377,7 @@ __metadata:
|
|||||||
"@octokit/rest": "npm:22.0.0"
|
"@octokit/rest": "npm:22.0.0"
|
||||||
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
||||||
"@rsdoctor/rspack-plugin": "npm:1.2.3"
|
"@rsdoctor/rspack-plugin": "npm:1.2.3"
|
||||||
"@rspack/core": "npm:1.5.1"
|
"@rspack/core": "npm:1.4.11"
|
||||||
"@rspack/dev-server": "npm:1.1.4"
|
"@rspack/dev-server": "npm:1.1.4"
|
||||||
"@shoelace-style/shoelace": "npm:2.20.1"
|
"@shoelace-style/shoelace": "npm:2.20.1"
|
||||||
"@swc/helpers": "npm:0.5.17"
|
"@swc/helpers": "npm:0.5.17"
|
||||||
@@ -9466,7 +9466,7 @@ __metadata:
|
|||||||
lodash.template: "npm:4.5.0"
|
lodash.template: "npm:4.5.0"
|
||||||
luxon: "npm:3.7.1"
|
luxon: "npm:3.7.1"
|
||||||
map-stream: "npm:0.0.7"
|
map-stream: "npm:0.0.7"
|
||||||
marked: "npm:16.2.1"
|
marked: "npm:16.2.0"
|
||||||
memoize-one: "npm:6.0.0"
|
memoize-one: "npm:6.0.0"
|
||||||
node-vibrant: "npm:4.0.3"
|
node-vibrant: "npm:4.0.3"
|
||||||
object-hash: "npm:3.0.0"
|
object-hash: "npm:3.0.0"
|
||||||
@@ -11137,12 +11137,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"marked@npm:16.2.1":
|
"marked@npm:16.2.0":
|
||||||
version: 16.2.1
|
version: 16.2.0
|
||||||
resolution: "marked@npm:16.2.1"
|
resolution: "marked@npm:16.2.0"
|
||||||
bin:
|
bin:
|
||||||
marked: bin/marked.js
|
marked: bin/marked.js
|
||||||
checksum: 10/67e911a7dd416869649dee18dc4a9683c0ccd8e72ba0fee3b3f578f857416e69780013e9d63762c600e6f9cf997c5af9fa0507a2053f8e65d39c5459c245c0cd
|
checksum: 10/0a73dcfbe500514d2f1106da99708beed8a31de586e2826e1aa47ca0e0a4850b1e9598569b09d5366d4f4dee2d279a13f32616ed1ee75c832068eb7dd660f66f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user