mirror of
https://github.com/home-assistant/frontend.git
synced 2026-02-04 01:10:33 -06:00
Merge branch 'rc'
This commit is contained in:
commit
2b937a30e3
@ -34,3 +34,5 @@ Check the [webawesome documentation](https://webawesome.com/docs/components/slid
|
||||
**CSS Custom Properties**
|
||||
|
||||
- `--ha-slider-track-size` - Height of the slider track. Defaults to `4px`.
|
||||
- `--ha-slider-thumb-color` - Color of the slider thumb. Defaults to `var(--primary-color)`.
|
||||
- `--ha-slider-indicator-color` - Color of the filled portion of the slider track. Defaults to `var(--primary-color)`.
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
"@fullcalendar/list": "6.1.19",
|
||||
"@fullcalendar/luxon3": "6.1.19",
|
||||
"@fullcalendar/timegrid": "6.1.19",
|
||||
"@home-assistant/webawesome": "3.0.0-beta.6.ha.0",
|
||||
"@home-assistant/webawesome": "3.0.0-beta.6.ha.4",
|
||||
"@lezer/highlight": "1.2.1",
|
||||
"@lit-labs/motion": "1.0.9",
|
||||
"@lit-labs/observers": "2.0.6",
|
||||
|
||||
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20251001.0"
|
||||
version = "20251001.1"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*"]
|
||||
description = "The Home Assistant frontend"
|
||||
|
||||
8
src/common/util/xss.ts
Normal file
8
src/common/util/xss.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import xss from "xss";
|
||||
|
||||
export const filterXSS = (html: string) =>
|
||||
xss(html, {
|
||||
whiteList: {},
|
||||
stripIgnoreTag: true,
|
||||
stripIgnoreTagBody: true,
|
||||
});
|
||||
@ -25,6 +25,7 @@ import type { ECOption } from "../../resources/echarts";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { isMac } from "../../util/is_mac";
|
||||
import "../ha-icon-button";
|
||||
import { filterXSS } from "../../common/util/xss";
|
||||
import { formatTimeLabel } from "./axis-label";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import "../chips/ha-assist-chip";
|
||||
@ -811,7 +812,8 @@ export class HaChartBase extends LitElement {
|
||||
};
|
||||
}
|
||||
}
|
||||
return { ...s, data };
|
||||
const name = filterXSS(String(s.name ?? s.id ?? ""));
|
||||
return { ...s, name, data };
|
||||
});
|
||||
return series as ECOption["series"];
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import type { ECOption } from "../../resources/echarts";
|
||||
import { measureTextWidth } from "../../util/text";
|
||||
import { filterXSS } from "../../common/util/xss";
|
||||
import "./ha-chart-base";
|
||||
import { NODE_SIZE } from "../trace/hat-graph-const";
|
||||
import "../ha-alert";
|
||||
@ -92,12 +93,12 @@ export class HaSankeyChart extends LitElement {
|
||||
: data.value;
|
||||
if (data.id) {
|
||||
const node = this.data.nodes.find((n) => n.id === data.id);
|
||||
return `${params.marker} ${node?.label ?? data.id}<br>${value}`;
|
||||
return `${params.marker} ${filterXSS(node?.label ?? data.id)}<br>${value}`;
|
||||
}
|
||||
if (data.source && data.target) {
|
||||
const source = this.data.nodes.find((n) => n.id === data.source);
|
||||
const target = this.data.nodes.find((n) => n.id === data.target);
|
||||
return `${source?.label ?? data.source} → ${target?.label ?? data.target}<br>${value}`;
|
||||
return `${filterXSS(source?.label ?? data.source)} → ${filterXSS(target?.label ?? data.target)}<br>${value}`;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@ -42,8 +42,8 @@ export class HaBottomSheet extends LitElement {
|
||||
static styles = css`
|
||||
wa-drawer {
|
||||
--wa-color-surface-raised: var(
|
||||
--ha-dialog-surface-background,
|
||||
var(--mdc-theme-surface, #fff)
|
||||
--ha-bottom-sheet-surface-background,
|
||||
var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff)),
|
||||
);
|
||||
--spacing: 0;
|
||||
--size: auto;
|
||||
@ -51,8 +51,14 @@ export class HaBottomSheet extends LitElement {
|
||||
--hide-duration: ${BOTTOM_SHEET_ANIMATION_DURATION_MS}ms;
|
||||
}
|
||||
wa-drawer::part(dialog) {
|
||||
border-top-left-radius: var(--ha-border-radius-lg);
|
||||
border-top-right-radius: var(--ha-border-radius-lg);
|
||||
border-top-left-radius: var(
|
||||
--ha-bottom-sheet-border-radius,
|
||||
var(--ha-dialog-border-radius, var(--ha-border-radius-2xl))
|
||||
);
|
||||
border-top-right-radius: var(
|
||||
--ha-bottom-sheet-border-radius,
|
||||
var(--ha-dialog-border-radius, var(--ha-border-radius-2xl))
|
||||
);
|
||||
max-height: 90vh;
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-left: var(--safe-area-inset-left);
|
||||
|
||||
@ -41,8 +41,7 @@ export class HaButton extends Button {
|
||||
return [
|
||||
Button.styles,
|
||||
css`
|
||||
.button {
|
||||
/* set theme vars */
|
||||
:host {
|
||||
--wa-form-control-padding-inline: 16px;
|
||||
--wa-font-weight-action: var(--ha-font-weight-medium);
|
||||
--wa-form-control-border-radius: var(
|
||||
@ -54,7 +53,8 @@ export class HaButton extends Button {
|
||||
--ha-button-height,
|
||||
var(--button-height, 40px)
|
||||
);
|
||||
|
||||
}
|
||||
.button {
|
||||
font-size: var(--ha-font-size-m);
|
||||
line-height: 1;
|
||||
|
||||
|
||||
@ -139,7 +139,9 @@ export class HaDialog extends DialogBase {
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
.mdc-dialog .mdc-dialog__surface {
|
||||
min-height: 100vh;
|
||||
min-height: 100svh;
|
||||
max-height: 100vh;
|
||||
max-height: 100svh;
|
||||
padding-top: var(--safe-area-inset-top);
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-left: var(--safe-area-inset-left);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, query, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { BOTTOM_SHEET_ANIMATION_DURATION_MS } from "./ha-bottom-sheet";
|
||||
|
||||
@ -37,13 +36,14 @@ export class HaResizableBottomSheet extends LitElement {
|
||||
return html`<dialog
|
||||
open
|
||||
@transitionend=${this._handleTransitionEnd}
|
||||
style=${styleMap({
|
||||
height: this._dialogViewportHeight
|
||||
? `${this._dialogViewportHeight}vh`
|
||||
: "auto",
|
||||
maxHeight: `${this._dialogMaxViewpointHeight}vh`,
|
||||
minHeight: `${this._dialogMinViewpointHeight}vh`,
|
||||
})}
|
||||
style=${`
|
||||
--height: ${this._dialogViewportHeight}vh;
|
||||
--height: ${this._dialogViewportHeight}dvh;
|
||||
--max-height: ${this._dialogMaxViewpointHeight}vh;
|
||||
--max-height: ${this._dialogMaxViewpointHeight}dvh;
|
||||
--min-height: ${this._dialogMinViewpointHeight}vh;
|
||||
--min-height: ${this._dialogMinViewpointHeight}dvh;
|
||||
`}
|
||||
>
|
||||
<div class="handle-wrapper">
|
||||
<div
|
||||
@ -213,12 +213,14 @@ export class HaResizableBottomSheet extends LitElement {
|
||||
cursor: grabbing;
|
||||
}
|
||||
dialog {
|
||||
height: auto;
|
||||
max-height: 70vh;
|
||||
min-height: 30vh;
|
||||
height: var(--height, auto);
|
||||
max-height: var(--max-height, 70vh);
|
||||
max-height: var(--max-height, 70dvh);
|
||||
min-height: var(--min-height, 30vh);
|
||||
min-height: var(--min-height, 30dvh);
|
||||
background-color: var(
|
||||
--ha-dialog-surface-background,
|
||||
var(--mdc-theme-surface, #fff)
|
||||
--ha-bottom-sheet-surface-background,
|
||||
var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff)),
|
||||
);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -239,12 +241,12 @@ export class HaResizableBottomSheet extends LitElement {
|
||||
inset-inline-start: 0;
|
||||
box-shadow: 0px -8px 16px rgba(0, 0, 0, 0.2);
|
||||
border-top-left-radius: var(
|
||||
--ha-dialog-border-radius,
|
||||
var(--ha-border-radius-2xl)
|
||||
--ha-bottom-sheet-border-radius,
|
||||
var(--ha-dialog-border-radius, var(--ha-border-radius-2xl))
|
||||
);
|
||||
border-top-right-radius: var(
|
||||
--ha-dialog-border-radius,
|
||||
var(--ha-border-radius-2xl)
|
||||
--ha-bottom-sheet-border-radius,
|
||||
var(--ha-dialog-border-radius, var(--ha-border-radius-2xl))
|
||||
);
|
||||
transform: translateY(100%);
|
||||
transition: transform ${BOTTOM_SHEET_ANIMATION_DURATION_MS}ms ease;
|
||||
@ -254,7 +256,6 @@ export class HaResizableBottomSheet extends LitElement {
|
||||
border-bottom-width: 0;
|
||||
border-style: var(--ha-bottom-sheet-border-style);
|
||||
border-color: var(--ha-bottom-sheet-border-color);
|
||||
margin-bottom: var(--safe-area-inset-bottom);
|
||||
margin-left: var(--safe-area-inset-left);
|
||||
margin-right: var(--safe-area-inset-right);
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ export class HaSlider extends Slider {
|
||||
Slider.styles,
|
||||
css`
|
||||
:host {
|
||||
--wa-form-control-activated-color: var(--ha-control-color);
|
||||
--track-size: var(--ha-slider-track-size, 4px);
|
||||
--marker-height: calc(var(--ha-slider-track-size, 4px) / 2);
|
||||
--marker-width: calc(var(--ha-slider-track-size, 4px) / 2);
|
||||
@ -54,6 +53,7 @@ export class HaSlider extends Slider {
|
||||
|
||||
#thumb {
|
||||
border: none;
|
||||
background-color: var(--ha-slider-thumb-color, var(--primary-color));
|
||||
}
|
||||
|
||||
#slider:focus-visible:not(.disabled) #thumb,
|
||||
@ -62,14 +62,21 @@ export class HaSlider extends Slider {
|
||||
outline: var(--wa-focus-ring);
|
||||
}
|
||||
|
||||
#indicator {
|
||||
background-color: var(
|
||||
--ha-slider-indicator-color,
|
||||
var(--primary-color)
|
||||
);
|
||||
}
|
||||
|
||||
:host([size="medium"]) {
|
||||
--thumb-width: var(--ha-font-size-l, 1.25em);
|
||||
--thumb-height: var(--ha-font-size-l, 1.25em);
|
||||
--thumb-width: 20px;
|
||||
--thumb-height: 20px;
|
||||
}
|
||||
|
||||
:host([size="small"]) {
|
||||
--thumb-width: var(--ha-font-size-m, 1em);
|
||||
--thumb-height: var(--ha-font-size-m, 1em);
|
||||
--thumb-width: 16px;
|
||||
--thumb-height: 16px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@ -17,7 +17,7 @@ export class HaTooltip extends Tooltip {
|
||||
css`
|
||||
:host {
|
||||
--wa-tooltip-background-color: var(--secondary-background-color);
|
||||
--wa-tooltip-color: var(--primary-text-color);
|
||||
--wa-tooltip-content-color: var(--primary-text-color);
|
||||
--wa-tooltip-font-family: var(
|
||||
--ha-tooltip-font-family,
|
||||
var(--ha-font-family-body)
|
||||
|
||||
@ -12,6 +12,7 @@ export const DISCOVERY_SOURCES = [
|
||||
"bluetooth",
|
||||
"dhcp",
|
||||
"discovery",
|
||||
"esphome",
|
||||
"hardware",
|
||||
"hassio",
|
||||
"homekit",
|
||||
|
||||
@ -9,8 +9,9 @@ import {
|
||||
mdiVolumeOff,
|
||||
mdiVolumePlus,
|
||||
} from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
@ -19,7 +20,7 @@ import { formatDurationDigital } from "../../../common/datetime/format_duration"
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-select";
|
||||
import "../../../components/ha-slider";
|
||||
import type { HaSlider } from "../../../components/ha-slider";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
|
||||
@ -30,6 +31,8 @@ import type {
|
||||
MediaPlayerEntity,
|
||||
} from "../../../data/media-player";
|
||||
import {
|
||||
cleanupMediaTitle,
|
||||
computeMediaDescription,
|
||||
computeMediaControls,
|
||||
handleMediaControlClick,
|
||||
MediaPlayerEntityFeature,
|
||||
@ -48,6 +51,16 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public stateObj?: MediaPlayerEntity;
|
||||
|
||||
@query("#position-slider")
|
||||
private _positionSlider?: HaSlider;
|
||||
|
||||
protected firstUpdated(_changedProperties: PropertyValues) {
|
||||
if (this._positionSlider) {
|
||||
this._positionSlider.valueFormatter = (value: number) =>
|
||||
this._formatDuration(value);
|
||||
}
|
||||
}
|
||||
|
||||
private _formatDuration(duration: number) {
|
||||
const hours = Math.floor(duration / 3600);
|
||||
const minutes = Math.floor((duration % 3600) / 60);
|
||||
@ -269,8 +282,8 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
const remaining = Math.max(duration - position, 0);
|
||||
const remainingFormatted = this._formatDuration(remaining);
|
||||
const positionFormatted = this._formatDuration(position);
|
||||
const primaryTitle = playerObj.primaryTitle;
|
||||
const secondaryTitle = playerObj.secondaryTitle;
|
||||
const primaryTitle = cleanupMediaTitle(stateObj.attributes.media_title);
|
||||
const secondaryTitle = computeMediaDescription(stateObj);
|
||||
const turnOn = controls?.find((c) => c.action === "turn_on");
|
||||
const turnOff = controls?.find((c) => c.action === "turn_off");
|
||||
|
||||
@ -316,6 +329,7 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
? html`
|
||||
<div class="position-bar">
|
||||
<ha-slider
|
||||
id="position-slider"
|
||||
min="0"
|
||||
max=${duration}
|
||||
step="1"
|
||||
@ -350,28 +364,31 @@ class MoreInfoMediaPlayer extends LitElement {
|
||||
</ha-icon-button>`
|
||||
: html`<span class="spacer"></span>`;
|
||||
})}
|
||||
${["media_play_pause", "media_pause", "media_play"].map(
|
||||
(action) => {
|
||||
const control = controls?.find((c) => c.action === action);
|
||||
return control
|
||||
? html`<ha-button
|
||||
variant="brand"
|
||||
appearance="filled"
|
||||
size="medium"
|
||||
action=${action}
|
||||
@click=${this._handleClick}
|
||||
class="center-control"
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${control.icon}
|
||||
aria-label=${this.hass.localize(
|
||||
`ui.card.media_player.${control.action}`
|
||||
)}
|
||||
></ha-svg-icon>
|
||||
</ha-button>`
|
||||
: nothing;
|
||||
}
|
||||
)}
|
||||
${[
|
||||
"media_play_pause",
|
||||
"media_pause",
|
||||
"media_play",
|
||||
"media_stop",
|
||||
].map((action) => {
|
||||
const control = controls?.find((c) => c.action === action);
|
||||
return control
|
||||
? html`<ha-button
|
||||
variant="brand"
|
||||
appearance="filled"
|
||||
size="medium"
|
||||
action=${action}
|
||||
@click=${this._handleClick}
|
||||
class="center-control"
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${control.icon}
|
||||
aria-label=${this.hass.localize(
|
||||
`ui.card.media_player.${control.action}`
|
||||
)}
|
||||
></ha-svg-icon>
|
||||
</ha-button>`
|
||||
: nothing;
|
||||
})}
|
||||
${["media_next_track", "shuffle_set"].map((action) => {
|
||||
const control = controls?.find((c) => c.action === action);
|
||||
return control
|
||||
|
||||
@ -5,8 +5,8 @@ import { restoreScroll } from "../common/decorators/restore-scroll";
|
||||
import { goBack } from "../common/navigate";
|
||||
import "../components/ha-icon-button-arrow-prev";
|
||||
import "../components/ha-menu-button";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
@customElement("hass-subpage")
|
||||
class HassSubpage extends LitElement {
|
||||
@ -154,9 +154,15 @@ class HassSubpage extends LitElement {
|
||||
1px - var(--header-height, 0px) - var(
|
||||
--safe-area-inset-top,
|
||||
0px
|
||||
) - var(--safe-area-inset-bottom, 0px)
|
||||
) - var(
|
||||
--hass-subpage-bottom-inset,
|
||||
var(--safe-area-inset-bottom, 0px)
|
||||
)
|
||||
);
|
||||
margin-bottom: var(
|
||||
--hass-subpage-bottom-inset,
|
||||
var(--safe-area-inset-bottom)
|
||||
);
|
||||
margin-bottom: var(--safe-area-inset-bottom);
|
||||
margin-right: var(--safe-area-inset-right);
|
||||
overflow-y: auto;
|
||||
overflow: auto;
|
||||
|
||||
@ -12,11 +12,11 @@ export const KeyboardShortcutMixin = <T extends Constructor<LitElement>>(
|
||||
class extends superClass {
|
||||
private _keydownEvent = (event: KeyboardEvent) => {
|
||||
const supportedShortcuts = this.supportedShortcuts();
|
||||
const key = event.shiftKey ? event.key.toUpperCase() : event.key;
|
||||
if (
|
||||
(event.ctrlKey || event.metaKey) &&
|
||||
!event.shiftKey &&
|
||||
!event.altKey &&
|
||||
event.key in supportedShortcuts
|
||||
key in supportedShortcuts
|
||||
) {
|
||||
// Only capture the event if the user is not focused on an input
|
||||
if (!canOverrideAlphanumericInput(event.composedPath())) {
|
||||
@ -27,14 +27,14 @@ export const KeyboardShortcutMixin = <T extends Constructor<LitElement>>(
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
supportedShortcuts[event.key]();
|
||||
supportedShortcuts[key]();
|
||||
return;
|
||||
}
|
||||
|
||||
const supportedSingleKeyShortcuts = this.supportedSingleKeyShortcuts();
|
||||
if (event.key in supportedSingleKeyShortcuts) {
|
||||
if (key in supportedSingleKeyShortcuts) {
|
||||
event.preventDefault();
|
||||
supportedSingleKeyShortcuts[event.key]();
|
||||
supportedSingleKeyShortcuts[key]();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -74,8 +74,10 @@ import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info
|
||||
import "../../../layouts/hass-subpage";
|
||||
import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { UndoRedoMixin } from "../../../mixins/undo-redo-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { Entries, HomeAssistant, Route } from "../../../types";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import "../ha-config-section";
|
||||
@ -87,8 +89,6 @@ import {
|
||||
import "./blueprint-automation-editor";
|
||||
import "./manual-automation-editor";
|
||||
import type { HaManualAutomationEditor } from "./manual-automation-editor";
|
||||
import { UndoRedoMixin } from "../../../mixins/undo-redo-mixin";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
@ -261,9 +261,16 @@ export class HaAutomationEditor extends UndoRedoMixin<
|
||||
<ha-tooltip placement="bottom" for="button-redo">
|
||||
${this.hass.localize("ui.common.redo")}
|
||||
<span class="shortcut">
|
||||
(<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Y</span>)
|
||||
(
|
||||
${isMac
|
||||
? html`<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Shift</span>
|
||||
<span>+</span>
|
||||
<span>Z</span>`
|
||||
: html`<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Y</span>`})
|
||||
</span>
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
@ -1196,6 +1203,7 @@ export class HaAutomationEditor extends UndoRedoMixin<
|
||||
Delete: () => this._deleteSelectedRow(),
|
||||
Backspace: () => this._deleteSelectedRow(),
|
||||
z: () => this.undo(),
|
||||
Z: () => this.redo(),
|
||||
y: () => this.redo(),
|
||||
};
|
||||
}
|
||||
@ -1249,6 +1257,7 @@ export class HaAutomationEditor extends UndoRedoMixin<
|
||||
--ha-automation-editor-width,
|
||||
1540px
|
||||
);
|
||||
--hass-subpage-bottom-inset: 0px;
|
||||
}
|
||||
ha-fade-in {
|
||||
display: flex;
|
||||
|
||||
@ -292,9 +292,7 @@ export default class HaAutomationSidebar extends LitElement {
|
||||
:host {
|
||||
z-index: 6;
|
||||
outline: none;
|
||||
height: calc(
|
||||
100% - var(--safe-area-inset-top) - var(--safe-area-inset-bottom)
|
||||
);
|
||||
height: calc(100% - var(--safe-area-inset-top, 0px));
|
||||
--ha-card-border-radius: var(
|
||||
--ha-dialog-border-radius,
|
||||
var(--ha-border-radius-2xl)
|
||||
@ -304,7 +302,6 @@ export default class HaAutomationSidebar extends LitElement {
|
||||
--ha-bottom-sheet-border-style: solid;
|
||||
--ha-bottom-sheet-border-color: var(--primary-color);
|
||||
margin-top: var(--safe-area-inset-top);
|
||||
margin-bottom: var(--safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
@media all and (max-width: 870px) {
|
||||
|
||||
@ -145,24 +145,19 @@ export const manualEditorStyles = css`
|
||||
|
||||
.content {
|
||||
padding-top: 24px;
|
||||
padding-bottom: 72px;
|
||||
padding-bottom: max(var(--safe-area-inset-bottom), 32px);
|
||||
transition: padding-bottom 180ms ease-in-out;
|
||||
}
|
||||
|
||||
.content.has-bottom-sheet {
|
||||
padding-bottom: calc(90vh - 72px);
|
||||
padding-bottom: calc(90vh - max(var(--safe-area-inset-bottom), 32px));
|
||||
}
|
||||
|
||||
ha-automation-sidebar {
|
||||
position: fixed;
|
||||
top: calc(var(--header-height) + 16px);
|
||||
height: calc(
|
||||
-81px +
|
||||
100dvh - var(--safe-area-inset-top, 0px) - var(
|
||||
--safe-area-inset-bottom,
|
||||
0px
|
||||
)
|
||||
);
|
||||
height: calc(-81px + 100vh - var(--safe-area-inset-top, 0px));
|
||||
height: calc(-81px + 100dvh - var(--safe-area-inset-top, 0px));
|
||||
width: var(--sidebar-width);
|
||||
display: block;
|
||||
}
|
||||
|
||||
@ -65,8 +65,10 @@ import "../../../layouts/hass-subpage";
|
||||
import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { UndoRedoMixin } from "../../../mixins/undo-redo-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { Entries, HomeAssistant, Route } from "../../../types";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAutomationModeDialog } from "../automation/automation-mode-dialog/show-dialog-automation-mode";
|
||||
import type { EntityRegistryUpdate } from "../automation/automation-save-dialog/show-dialog-automation-save";
|
||||
@ -75,8 +77,6 @@ import { showAssignCategoryDialog } from "../category/show-dialog-assign-categor
|
||||
import "./blueprint-script-editor";
|
||||
import "./manual-script-editor";
|
||||
import type { HaManualScriptEditor } from "./manual-script-editor";
|
||||
import { UndoRedoMixin } from "../../../mixins/undo-redo-mixin";
|
||||
import { isMac } from "../../../util/is_mac";
|
||||
|
||||
const baseEditorMixins = SubscribeMixin(
|
||||
PreventUnsavedMixin(KeyboardShortcutMixin(LitElement))
|
||||
@ -212,10 +212,17 @@ export class HaScriptEditor extends UndoRedoMixin<
|
||||
</ha-icon-button>
|
||||
<ha-tooltip placement="bottom" for="button-redo">
|
||||
${this.hass.localize("ui.common.redo")}
|
||||
<span class="shortcut">
|
||||
(<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Y</span>)
|
||||
<span class="shortcut"
|
||||
>(
|
||||
${isMac
|
||||
? html`<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Shift</span>
|
||||
<span>+</span>
|
||||
<span>Z</span>`
|
||||
: html`<span>${shortcutIcon}</span>
|
||||
<span>+</span>
|
||||
<span>Y</span>`})
|
||||
</span>
|
||||
</ha-tooltip>`
|
||||
: nothing}
|
||||
@ -1104,6 +1111,7 @@ export class HaScriptEditor extends UndoRedoMixin<
|
||||
Delete: () => this._deleteSelectedRow(),
|
||||
Backspace: () => this._deleteSelectedRow(),
|
||||
z: () => this.undo(),
|
||||
Z: () => this.redo(),
|
||||
y: () => this.redo(),
|
||||
};
|
||||
}
|
||||
@ -1157,6 +1165,7 @@ export class HaScriptEditor extends UndoRedoMixin<
|
||||
--ha-automation-editor-width,
|
||||
1540px
|
||||
);
|
||||
--hass-subpage-bottom-inset: 0px;
|
||||
}
|
||||
.yaml-mode {
|
||||
height: 100%;
|
||||
|
||||
@ -26,6 +26,7 @@ import {
|
||||
} from "../../../../../common/datetime/format_date";
|
||||
import { formatTime } from "../../../../../common/datetime/format_time";
|
||||
import type { ECOption } from "../../../../../resources/echarts";
|
||||
import { filterXSS } from "../../../../../common/util/xss";
|
||||
|
||||
export function getSuggestedMax(dayDifference: number, end: Date): number {
|
||||
let suggestedMax = new Date(end);
|
||||
@ -191,7 +192,7 @@ function formatTooltip(
|
||||
countNegative++;
|
||||
}
|
||||
}
|
||||
return `${param.marker} ${param.seriesName}: ${value} ${unit}`;
|
||||
return `${param.marker} ${filterXSS(param.seriesName!)}: ${value} ${unit}`;
|
||||
})
|
||||
.filter(Boolean);
|
||||
let footer = "";
|
||||
|
||||
@ -6,6 +6,7 @@ import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { BarSeriesOption } from "echarts/charts";
|
||||
import type { ECElementEvent } from "echarts/types/dist/shared";
|
||||
import { filterXSS } from "../../../../common/util/xss";
|
||||
import { getGraphColorByIndex } from "../../../../common/color/colors";
|
||||
import { formatNumber } from "../../../../common/number/format_number";
|
||||
import "../../../../components/chart/ha-chart-base";
|
||||
@ -96,9 +97,8 @@ export class HuiEnergyDevicesGraphCard
|
||||
}
|
||||
|
||||
private _renderTooltip(params: any) {
|
||||
const title = `<h4 style="text-align: center; margin: 0;">${this._getDeviceName(
|
||||
params.value[1]
|
||||
)}</h4>`;
|
||||
const deviceName = filterXSS(this._getDeviceName(params.value[1]));
|
||||
const title = `<h4 style="text-align: center; margin: 0;">${deviceName}</h4>`;
|
||||
const value = `${formatNumber(
|
||||
params.value[0] as number,
|
||||
this.hass.locale,
|
||||
|
||||
@ -157,8 +157,10 @@ export const haStyleDialog = css`
|
||||
ha-dialog {
|
||||
--mdc-dialog-min-width: 100vw;
|
||||
--mdc-dialog-max-width: 100vw;
|
||||
--mdc-dialog-min-height: 100%;
|
||||
--mdc-dialog-max-height: 100%;
|
||||
--mdc-dialog-min-height: 100vh;
|
||||
--mdc-dialog-min-height: 100svh;
|
||||
--mdc-dialog-max-height: 100vh;
|
||||
--mdc-dialog-max-height: 100svh;
|
||||
--vertical-align-dialog: flex-end;
|
||||
--ha-dialog-border-radius: 0;
|
||||
}
|
||||
|
||||
@ -273,9 +273,6 @@ export const colorStyles = css`
|
||||
--material-background-color: var(--card-background-color);
|
||||
--material-secondary-background-color: var(--secondary-background-color);
|
||||
--material-secondary-text-color: var(--secondary-text-color);
|
||||
|
||||
/* Color for Home Assistant input controls e.g. slider, radio buttons */
|
||||
--ha-control-color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
79
yarn.lock
79
yarn.lock
@ -1284,7 +1284,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/view@npm:6.38.2, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
||||
"@codemirror/view@npm:6.38.2":
|
||||
version: 6.38.2
|
||||
resolution: "@codemirror/view@npm:6.38.2"
|
||||
dependencies:
|
||||
@ -1296,6 +1296,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
|
||||
version: 6.38.4
|
||||
resolution: "@codemirror/view@npm:6.38.4"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.5.0"
|
||||
crelt: "npm:^1.0.6"
|
||||
style-mod: "npm:^4.1.0"
|
||||
w3c-keyname: "npm:^2.2.4"
|
||||
checksum: 10/86b3894e9e7c2113aabb1db8684d0520378339c194fa56a688fc26cd7d40336bb9df1f5f19f68309d95f14b80ecf0b70c0ffe5e43f2ec11c4bab18f2d5ee4494
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@csstools/color-helpers@npm:^5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "@csstools/color-helpers@npm:5.1.0"
|
||||
@ -1940,9 +1952,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@home-assistant/webawesome@npm:3.0.0-beta.6.ha.0":
|
||||
version: 3.0.0-beta.6.ha.0
|
||||
resolution: "@home-assistant/webawesome@npm:3.0.0-beta.6.ha.0"
|
||||
"@home-assistant/webawesome@npm:3.0.0-beta.6.ha.4":
|
||||
version: 3.0.0-beta.6.ha.4
|
||||
resolution: "@home-assistant/webawesome@npm:3.0.0-beta.6.ha.4"
|
||||
dependencies:
|
||||
"@ctrl/tinycolor": "npm:4.1.0"
|
||||
"@floating-ui/dom": "npm:^1.6.13"
|
||||
@ -1953,7 +1965,7 @@ __metadata:
|
||||
lit: "npm:^3.2.1"
|
||||
nanoid: "npm:^5.1.5"
|
||||
qr-creator: "npm:^1.0.0"
|
||||
checksum: 10/ec9d74585b544e5755f7b2644a0d7f9318b5776bedf51430c8f8729918fddb6e54cce46acace674960383385362846cc4c0f2da5245fa622bce8c54733a31865
|
||||
checksum: 10/d9072b321126ef458468ed2cf040e0b04cb2aff73336c6e742c0cfb25d9fb674b7672e7c9abcf5bcb0aa0b2fe953c20186f0910f485024c827bfe4cf399f10a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3468,13 +3480,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/endpoint@npm:^11.0.0":
|
||||
version: 11.0.0
|
||||
resolution: "@octokit/endpoint@npm:11.0.0"
|
||||
"@octokit/endpoint@npm:^11.0.1":
|
||||
version: 11.0.1
|
||||
resolution: "@octokit/endpoint@npm:11.0.1"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^14.0.0"
|
||||
"@octokit/types": "npm:^15.0.0"
|
||||
universal-user-agent: "npm:^7.0.2"
|
||||
checksum: 10/d7583a44f8560343b0fbd191aa9d2653e563cdd78f550c83cf7440a66edbe47bab6d0d6c52ae271bcbd35703356154ed590b22881aa8ee690f0d8f249ce6bde0
|
||||
checksum: 10/7b702e1f4f85892a1228efe555774a6e002097f2960a7f1a0d57e1210ad4c9e7dad3116b6ae71fbac8bc93b4d1a506b741836746de4e4826c635b63f4f9c1589
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3566,25 +3578,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/request-error@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "@octokit/request-error@npm:7.0.0"
|
||||
"@octokit/request-error@npm:^7.0.0, @octokit/request-error@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "@octokit/request-error@npm:7.0.1"
|
||||
dependencies:
|
||||
"@octokit/types": "npm:^14.0.0"
|
||||
checksum: 10/c4370d2c31f599c1f366c480d5a02bc93442e5a0e151ec5caf0d5a5b0f0f91b50ecedc945aa6ea61b4c9ed1e89153dc7727daf4317680d33e916f829da7d141b
|
||||
"@octokit/types": "npm:^15.0.0"
|
||||
checksum: 10/f99dffa4e257a4cb3724c633c26e5334af881c54669ee0013de96b846bb327ac77e68b36459be183817b84f6f7518e6b70c9e7926b5547a9665b2607b1afddd6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/request@npm:^10.0.2":
|
||||
version: 10.0.3
|
||||
resolution: "@octokit/request@npm:10.0.3"
|
||||
version: 10.0.5
|
||||
resolution: "@octokit/request@npm:10.0.5"
|
||||
dependencies:
|
||||
"@octokit/endpoint": "npm:^11.0.0"
|
||||
"@octokit/request-error": "npm:^7.0.0"
|
||||
"@octokit/types": "npm:^14.0.0"
|
||||
"@octokit/endpoint": "npm:^11.0.1"
|
||||
"@octokit/request-error": "npm:^7.0.1"
|
||||
"@octokit/types": "npm:^15.0.0"
|
||||
fast-content-type-parse: "npm:^3.0.0"
|
||||
universal-user-agent: "npm:^7.0.2"
|
||||
checksum: 10/f32a2c3fe97e0354390c0748a443e2f600a4e169b1014deb0b668ac3c52aa25cab523e87508751a1247806e3998c41f8849ad41ee3da531936975f5d32ab4c02
|
||||
checksum: 10/0281e0f0c47f77a6431408d6b5137fbe23390c776738721a5e9ee550aa3da19b36046ad12d920cb81c78b28831cdbd37aaa8bc805014e23f31e04b3780a16acc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -9396,7 +9408,7 @@ __metadata:
|
||||
"@fullcalendar/list": "npm:6.1.19"
|
||||
"@fullcalendar/luxon3": "npm:6.1.19"
|
||||
"@fullcalendar/timegrid": "npm:6.1.19"
|
||||
"@home-assistant/webawesome": "npm:3.0.0-beta.6.ha.0"
|
||||
"@home-assistant/webawesome": "npm:3.0.0-beta.6.ha.4"
|
||||
"@lezer/highlight": "npm:1.2.1"
|
||||
"@lit-labs/motion": "npm:1.0.9"
|
||||
"@lit-labs/observers": "npm:2.0.6"
|
||||
@ -11476,12 +11488,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minizlib@npm:^3.0.1":
|
||||
version: 3.0.2
|
||||
resolution: "minizlib@npm:3.0.2"
|
||||
"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "minizlib@npm:3.1.0"
|
||||
dependencies:
|
||||
minipass: "npm:^7.1.2"
|
||||
checksum: 10/c075bed1594f68dcc8c35122333520112daefd4d070e5d0a228bd4cf5580e9eed3981b96c0ae1d62488e204e80fd27b2b9d0068ca9a5ef3993e9565faf63ca41
|
||||
checksum: 10/f47365cc2cb7f078cbe7e046eb52655e2e7e97f8c0a9a674f4da60d94fb0624edfcec9b5db32e8ba5a99a5f036f595680ae6fe02a262beaa73026e505cc52f99
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14090,7 +14102,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar@npm:7.4.3, tar@npm:^7.4.3":
|
||||
"tar@npm:7.4.3":
|
||||
version: 7.4.3
|
||||
resolution: "tar@npm:7.4.3"
|
||||
dependencies:
|
||||
@ -14104,6 +14116,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar@npm:^7.4.3":
|
||||
version: 7.5.1
|
||||
resolution: "tar@npm:7.5.1"
|
||||
dependencies:
|
||||
"@isaacs/fs-minipass": "npm:^4.0.0"
|
||||
chownr: "npm:^3.0.0"
|
||||
minipass: "npm:^7.1.2"
|
||||
minizlib: "npm:^3.1.0"
|
||||
yallist: "npm:^5.0.0"
|
||||
checksum: 10/4848cd2fa2fcaf0734cf54e14bc685056eb43a74d7cc7f954c3ac88fea88c85d95b1d7896619f91aab6f2234c5eec731c18aaa201a78fcf86985bdc824ed7a00
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"teex@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "teex@npm:1.0.1"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user