Compare commits

..

6 Commits

Author SHA1 Message Date
renovate[bot]
cc12981581 Update CodeMirror 2025-11-23 16:58:08 +00:00
Franck Nijhof
4674384f7d Allow deleting helpers directly from helpers panel (#28044)
* Allow deleting helpers directly from helpers panel

* Fix error handling in helper deletion logic

Address review feedback by improving the logic in _deleteHelper:
- Throw error when entity is not found in registry or component not loaded
- Move return statement outside of nested condition to ensure proper control flow
- Prevent fallthrough to config entry deletion for old-style helpers

Addresses review comment from @MindFreeze

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-23 15:20:20 +01:00
steinmn
2e7c95a8cc Translate dashboard panel url error message (#27306)
* Translate dashboard panel url error message

* Use backend provided translations
2025-11-23 14:54:21 +01:00
Simon Lamon
9630b175a1 Remove open from ha-dropdown (#28037) 2025-11-22 14:30:06 +02:00
Petar Petrov
be319503f7 Update color scheme in ZHA network visualization (#28032) 2025-11-21 19:09:37 +01:00
Paul Bottein
9b1fe28018 Rename defaultPanel to default_panel (#28035) 2025-11-21 16:24:34 +01:00
15 changed files with 244 additions and 285 deletions

View File

@@ -11,7 +11,7 @@ A compact, accessible dropdown menu for choosing actions or settings. `ha-dropdo
### Example usage (composition)
```html
<ha-dropdown open>
<ha-dropdown>
<ha-button slot="trigger" with-caret>Dropdown</ha-button>
<ha-dropdown-item>

View File

@@ -28,7 +28,7 @@ export class DemoHaDropdown extends LitElement {
<div class=${mode}>
<ha-card header="ha-button in ${mode}">
<div class="card-content">
<ha-dropdown open>
<ha-dropdown>
<ha-button slot="trigger" with-caret>Dropdown</ha-button>
<ha-dropdown-item>

View File

@@ -28,13 +28,13 @@
"dependencies": {
"@babel/runtime": "7.28.4",
"@braintree/sanitize-url": "7.1.1",
"@codemirror/autocomplete": "6.19.1",
"@codemirror/autocomplete": "6.20.0",
"@codemirror/commands": "6.10.0",
"@codemirror/language": "6.11.3",
"@codemirror/legacy-modes": "6.5.2",
"@codemirror/search": "6.5.11",
"@codemirror/state": "6.5.2",
"@codemirror/view": "6.38.6",
"@codemirror/view": "6.38.8",
"@date-fns/tz": "1.4.1",
"@egjs/hammerjs": "2.0.17",
"@formatjs/intl-datetimeformat": "6.18.2",

View File

@@ -3,7 +3,7 @@ import type { Connection } from "home-assistant-js-websocket";
export interface CoreFrontendUserData {
showAdvanced?: boolean;
showEntityIdPicker?: boolean;
defaultPanel?: string;
default_panel?: string;
}
export interface SidebarFrontendUserData {
@@ -12,7 +12,7 @@ export interface SidebarFrontendUserData {
}
export interface CoreFrontendSystemData {
defaultPanel?: string;
default_panel?: string;
}
export interface HomeFrontendSystemData {

View File

@@ -9,8 +9,8 @@ export const getLegacyDefaultPanelUrlPath = (): string | null => {
};
export const getDefaultPanelUrlPath = (hass: HomeAssistant): string =>
hass.userData?.defaultPanel ||
hass.systemData?.defaultPanel ||
hass.userData?.default_panel ||
hass.systemData?.default_panel ||
getLegacyDefaultPanelUrlPath() ||
DEFAULT_PANEL;

View File

@@ -1,187 +0,0 @@
import { ResizeController } from "@lit-labs/observers/resize-controller";
import { css, html } from "lit";
import type {
CSSResultGroup,
LitElement,
PropertyValues,
TemplateResult,
} from "lit";
import { classMap } from "lit/directives/class-map";
import { state } from "lit/decorators";
import type { Constructor } from "../types";
const stylesArray = (styles?: CSSResultGroup | CSSResultGroup[]) =>
styles === undefined ? [] : Array.isArray(styles) ? styles : [styles];
export const ScrollableFadeMixin = <T extends Constructor<LitElement>>(
superClass: T
) => {
class ScrollableFadeClass extends superClass {
@state() protected _contentScrolled = false;
@state() protected _contentScrollable = false;
private _scrollTarget?: HTMLElement | null;
private _onScroll = (ev: Event) => {
const target = ev.currentTarget as HTMLElement;
this._contentScrolled = (target.scrollTop ?? 0) > 0;
this._updateScrollableState(target);
};
private _resize = new ResizeController(this, {
target: null,
callback: (entries) => {
const target = entries[0]?.target as HTMLElement | undefined;
if (target) {
this._updateScrollableState(target);
}
},
});
private static readonly DEFAULT_SAFE_AREA_PADDING = 16;
private static readonly DEFAULT_SCROLLABLE_ELEMENT: HTMLElement | null =
null;
protected get scrollFadeSafeAreaPadding() {
return ScrollableFadeClass.DEFAULT_SAFE_AREA_PADDING;
}
protected get scrollableElement(): HTMLElement | null {
return ScrollableFadeClass.DEFAULT_SCROLLABLE_ELEMENT;
}
protected firstUpdated(changedProperties: PropertyValues) {
super.firstUpdated?.(changedProperties);
this._attachScrollableElement();
}
protected updated(changedProperties: PropertyValues) {
super.updated?.(changedProperties);
this._attachScrollableElement();
}
disconnectedCallback() {
this._detachScrollableElement();
super.disconnectedCallback();
}
protected renderScrollableFades(rounded = false): TemplateResult {
return html`
<div
class=${classMap({
"fade-top": true,
rounded,
visible: this._contentScrolled,
})}
></div>
<div
class=${classMap({
"fade-bottom": true,
rounded,
visible: this._contentScrollable,
})}
></div>
`;
}
static get styles() {
const superCtor = Object.getPrototypeOf(this) as
| typeof LitElement
| undefined;
const inheritedStyles = stylesArray(
(superCtor?.styles ?? []) as CSSResultGroup | CSSResultGroup[]
);
return [
...inheritedStyles,
css`
.fade-top,
.fade-bottom {
position: absolute;
left: var(--ha-space-0);
right: var(--ha-space-0);
height: var(--ha-space-4);
pointer-events: none;
transition: opacity 180ms ease-in-out;
background: linear-gradient(
to bottom,
var(--shadow-color),
transparent
);
border-radius: var(--ha-border-radius-square);
z-index: 100;
opacity: 0;
}
.fade-top {
top: var(--ha-space-0);
}
.fade-bottom {
bottom: var(--ha-space-0);
transform: rotate(180deg);
}
.fade-top.visible,
.fade-bottom.visible {
opacity: 1;
}
.fade-top.rounded,
.fade-bottom.rounded {
border-radius: var(
--ha-card-border-radius,
var(--ha-border-radius-lg)
);
border-bottom-left-radius: var(--ha-border-radius-square);
border-bottom-right-radius: var(--ha-border-radius-square);
}
.fade-top.rounded {
border-top-left-radius: var(--ha-border-radius-square);
border-top-right-radius: var(--ha-border-radius-square);
}
.fade-bottom.rounded {
border-bottom-left-radius: var(--ha-border-radius-square);
border-bottom-right-radius: var(--ha-border-radius-square);
}
`,
];
}
private _attachScrollableElement() {
const element = this.scrollableElement;
if (element === this._scrollTarget) {
return;
}
this._detachScrollableElement();
if (!element) {
return;
}
this._scrollTarget = element;
element.addEventListener("scroll", this._onScroll, { passive: true });
this._resize.observe(element);
this._updateScrollableState(element);
}
private _detachScrollableElement() {
if (!this._scrollTarget) {
return;
}
this._scrollTarget.removeEventListener("scroll", this._onScroll);
this._resize.unobserve?.(this._scrollTarget);
this._scrollTarget = undefined;
}
private _updateScrollableState(element: HTMLElement) {
const safeAreaInsetBottom =
parseFloat(
getComputedStyle(element).getPropertyValue("--safe-area-inset-bottom")
) || 0;
const { scrollHeight = 0, clientHeight = 0, scrollTop = 0 } = element;
this._contentScrollable =
scrollHeight - clientHeight >
scrollTop + safeAreaInsetBottom + this.scrollFadeSafeAreaPadding;
}
}
return ScrollableFadeClass;
};

View File

@@ -1,6 +1,14 @@
import { ResizeController } from "@lit-labs/observers/resize-controller";
import { mdiClose, mdiDotsVertical } from "@mdi/js";
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query } from "lit/decorators";
import {
customElement,
eventOptions,
property,
query,
state,
} from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../common/dom/stop_propagation";
@@ -9,10 +17,8 @@ import "../../../../components/ha-dialog-header";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-md-button-menu";
import "../../../../components/ha-md-divider";
import { haStyleScrollbar } from "../../../../resources/styles";
import type { HomeAssistant } from "../../../../types";
import "../ha-automation-editor-warning";
import { ScrollableFadeMixin } from "../../../../mixins/scrollable-fade-mixin";
export interface SidebarOverflowMenuEntry {
clickAction: () => void;
@@ -25,9 +31,7 @@ export interface SidebarOverflowMenuEntry {
export type SidebarOverflowMenu = (SidebarOverflowMenuEntry | "separator")[];
@customElement("ha-automation-sidebar-card")
export default class HaAutomationSidebarCard extends ScrollableFadeMixin(
LitElement
) {
export default class HaAutomationSidebarCard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean, attribute: "wide" }) public isWide = false;
@@ -38,10 +42,23 @@ export default class HaAutomationSidebarCard extends ScrollableFadeMixin(
@property({ type: Boolean }) public narrow = false;
@state() private _contentScrolled = false;
@state() private _contentScrollable = false;
@query(".card-content") private _contentElement!: HTMLDivElement;
protected get scrollableElement(): HTMLElement | null {
return this._contentElement;
private _contentSize = new ResizeController(this, {
target: null,
callback: (entries) => {
if (entries[0]?.target) {
this._canScrollDown(entries[0].target);
}
},
});
protected firstUpdated(_changedProperties: PropertyValues): void {
this._contentSize.observe(this._contentElement);
}
protected render() {
@@ -53,7 +70,9 @@ export default class HaAutomationSidebarCard extends ScrollableFadeMixin(
yaml: this.yamlMode,
})}
>
<ha-dialog-header>
<ha-dialog-header
class=${classMap({ scrolled: this._contentScrolled })}
>
<ha-icon-button
slot="navigationIcon"
.label=${this.hass.localize("ui.common.close")}
@@ -88,14 +107,34 @@ export default class HaAutomationSidebarCard extends ScrollableFadeMixin(
>
</ha-automation-editor-warning>`
: nothing}
<div class="card-content ha-scrollbar">
<div class="card-content" @scroll=${this._onScroll}>
<slot></slot>
${this.renderScrollableFades(this.isWide)}
</div>
<div
class=${classMap({ fade: true, scrollable: this._contentScrollable })}
></div>
</ha-card>
`;
}
@eventOptions({ passive: true })
private _onScroll(ev) {
const top = ev.target.scrollTop ?? 0;
this._contentScrolled = top > 0;
this._canScrollDown(ev.target);
}
private _canScrollDown(element: HTMLElement) {
const safeAreaInsetBottom =
parseFloat(
getComputedStyle(element).getPropertyValue("--safe-area-inset-bottom")
) || 0;
this._contentScrollable =
(element.scrollHeight ?? 0) - (element.clientHeight ?? 0) >
(element.scrollTop ?? 0) + safeAreaInsetBottom + 16;
}
private _closeSidebar() {
fireEvent(this, "close-sidebar");
}
@@ -105,63 +144,86 @@ export default class HaAutomationSidebarCard extends ScrollableFadeMixin(
ev.preventDefault();
}
static get styles() {
return [
...super.styles,
haStyleScrollbar,
css`
ha-card {
position: relative;
height: 100%;
width: 100%;
border-color: var(--primary-color);
border-width: 2px;
display: flex;
flex-direction: column;
}
static styles = css`
ha-card {
position: relative;
height: 100%;
width: 100%;
border-color: var(--primary-color);
border-width: 2px;
display: flex;
flex-direction: column;
}
@media all and (max-width: 870px) {
ha-card.mobile {
border: none;
box-shadow: none;
}
ha-card.mobile {
border-bottom-right-radius: var(--ha-border-radius-square);
border-bottom-left-radius: var(--ha-border-radius-square);
}
}
@media all and (max-width: 870px) {
ha-card.mobile {
border: none;
box-shadow: none;
}
ha-card.mobile {
border-bottom-right-radius: var(--ha-border-radius-square);
border-bottom-left-radius: var(--ha-border-radius-square);
}
}
ha-dialog-header {
border-radius: var(--ha-card-border-radius);
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
position: relative;
background-color: var(
--ha-dialog-surface-background,
var(--mdc-theme-surface, #fff)
);
}
ha-dialog-header {
border-radius: var(--ha-card-border-radius);
box-shadow: none;
transition: box-shadow 180ms ease-in-out;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
position: relative;
background-color: var(
--ha-dialog-surface-background,
var(--mdc-theme-surface, #fff)
);
}
.card-content {
flex: 1 1 auto;
min-height: 0;
overflow: auto;
margin-top: 0;
padding-bottom: max(var(--safe-area-inset-bottom, 0px), 32px);
}
ha-dialog-header.scrolled {
box-shadow: var(--bar-box-shadow);
}
.fade-top {
top: var(--ha-space-17);
}
.fade {
position: absolute;
bottom: 1px;
left: 1px;
right: 1px;
height: 16px;
pointer-events: none;
transition: box-shadow 180ms ease-in-out;
background-color: var(
--ha-dialog-surface-background,
var(--mdc-theme-surface, #fff)
);
transform: rotate(180deg);
border-radius: var(--ha-card-border-radius);
border-bottom-left-radius: var(--ha-border-radius-square);
border-bottom-right-radius: var(--ha-border-radius-square);
}
@media all and (max-width: 870px) {
.card-content {
padding-bottom: 42px;
}
}
`,
];
}
.fade.scrollable {
box-shadow: var(--bar-box-shadow);
}
.card-content {
flex: 1 1 auto;
min-height: 0;
overflow: auto;
margin-top: 0;
padding-bottom: max(var(--safe-area-inset-bottom, 0px), 32px);
}
@media all and (max-width: 870px) {
.fade {
bottom: 0;
border-radius: var(--ha-border-radius-square);
}
.card-content {
padding-bottom: 42px;
}
}
`;
}
declare global {

View File

@@ -5,6 +5,7 @@ import {
mdiCancel,
mdiChevronRight,
mdiCog,
mdiDelete,
mdiDotsVertical,
mdiMenuDown,
mdiPencilOff,
@@ -109,10 +110,11 @@ import { configSections } from "../ha-panel-config";
import "../integrations/ha-integration-overflow-menu";
import { renderConfigEntryError } from "../integrations/ha-config-integration-page";
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
import { isHelperDomain } from "./const";
import { isHelperDomain, type HelperDomain } from "./const";
import { showHelperDetailDialog } from "./show-dialog-helper-detail";
import { slugify } from "../../../common/string/slugify";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { HELPERS_CRUD } from "../../../data/helpers_crud";
import {
fetchDiagnosticHandlers,
getConfigEntryDiagnosticsDownloadUrl,
@@ -451,6 +453,19 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
},
]
: []),
...(helper.editable && helper.entity
? [
{
divider: true,
},
{
path: mdiDelete,
label: this.hass.localize("ui.common.delete"),
warning: true,
action: () => this._deleteHelper(helper),
},
]
: []),
]}
>
</ha-icon-overflow-menu>
@@ -1280,6 +1295,62 @@ ${rejected
}
}
private async _deleteHelper(helper: HelperItem) {
if (!helper.entity_id) {
return;
}
const confirmed = await showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.config.helpers.picker.delete_confirm_title"
),
text: this.hass.localize(
"ui.panel.config.helpers.picker.delete_confirm_text",
{ name: helper.name }
),
confirmText: this.hass.localize("ui.common.delete"),
dismissText: this.hass.localize("ui.common.cancel"),
destructive: true,
});
if (!confirmed) {
return;
}
try {
// For old-style helpers (input_boolean, etc.), use HELPERS_CRUD
if (isHelperDomain(helper.type)) {
const entityReg = this._entityReg.find(
(e) => e.entity_id === helper.entity_id
);
if (
!entityReg?.unique_id ||
!isComponentLoaded(this.hass, helper.type)
) {
throw new Error(
this.hass.localize("ui.panel.config.helpers.picker.delete_failed")
);
}
await HELPERS_CRUD[helper.type as HelperDomain].delete(
this.hass,
entityReg.unique_id
);
return;
}
// For config entry-based helpers, delete the config entry
if (helper.configEntry) {
await deleteConfigEntry(this.hass, helper.configEntry.entry_id);
}
} catch (err: any) {
showAlertDialog(this, {
text:
err.message ||
this.hass.localize("ui.panel.config.helpers.picker.delete_failed"),
});
}
}
private _createHelper() {
showHelperDetailDialog(this, {});
}

View File

@@ -295,7 +295,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
color:
route.route_status === "Active"
? primaryColor
: style.getPropertyValue("--disabled-color"),
: style.getPropertyValue("--dark-primary-color"),
type: ["Child", "Parent"].includes(neighbor.relationship)
? "solid"
: "dotted",
@@ -335,7 +335,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
symbolSize: 5,
lineStyle: {
width: 1,
color: style.getPropertyValue("--disabled-color"),
color: style.getPropertyValue("--dark-primary-color"),
type: "dotted",
},
ignoreForceLayout: true,

View File

@@ -62,7 +62,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
return nothing;
}
const defaultPanelUrlPath =
this.hass.systemData?.defaultPanel || DEFAULT_PANEL;
this.hass.systemData?.default_panel || DEFAULT_PANEL;
const titleInvalid = !this._data.title || !this._data.title.trim();
return html`
@@ -260,7 +260,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
return;
}
const defaultPanel = this.hass.systemData?.defaultPanel || DEFAULT_PANEL;
const defaultPanel = this.hass.systemData?.default_panel || DEFAULT_PANEL;
// Add warning dialog to saying that this will change the default dashboard for all users
const confirm = await showConfirmationDialog(this, {
title: this.hass.localize(
@@ -284,7 +284,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
saveFrontendSystemData(this.hass.connection, "core", {
...this.hass.systemData,
defaultPanel: urlPath === defaultPanel ? undefined : urlPath,
default_panel: urlPath === defaultPanel ? undefined : urlPath,
});
}
@@ -309,7 +309,20 @@ export class DialogLovelaceDashboardDetail extends LitElement {
}
this.closeDialog();
} catch (err: any) {
this._error = { base: err?.message || "Unknown error" };
let localizedErrorMessage: string | undefined;
if (err?.translation_domain && err?.translation_key) {
const localize = await this.hass.loadBackendTranslation(
"exceptions",
err.translation_domain
);
localizedErrorMessage = localize(
`component.${err.translation_domain}.exceptions.${err.translation_key}.message`,
err.translation_placeholders
);
}
this._error = {
base: localizedErrorMessage || err?.message || "Unknown error",
};
} finally {
this._submitting = false;
}

View File

@@ -404,7 +404,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
return html` <hass-loading-screen></hass-loading-screen> `;
}
const defaultPanel = this.hass.systemData?.defaultPanel || DEFAULT_PANEL;
const defaultPanel = this.hass.systemData?.default_panel || DEFAULT_PANEL;
return html`
<hass-tabs-subpage-data-table

View File

@@ -25,7 +25,7 @@ class HaPickDashboardRow extends LitElement {
}
protected render(): TemplateResult {
const value = this.hass.userData?.defaultPanel || USE_SYSTEM_VALUE;
const value = this.hass.userData?.default_panel || USE_SYSTEM_VALUE;
return html`
<ha-settings-row .narrow=${this.narrow}>
<span slot="heading">
@@ -84,12 +84,12 @@ class HaPickDashboardRow extends LitElement {
return;
}
const urlPath = value === USE_SYSTEM_VALUE ? undefined : value;
if (urlPath === this.hass.userData?.defaultPanel) {
if (urlPath === this.hass.userData?.default_panel) {
return;
}
saveFrontendUserData(this.hass.connection, "core", {
...this.hass.userData,
defaultPanel: urlPath,
default_panel: urlPath,
});
}
}

View File

@@ -20,7 +20,6 @@ export const colorStyles = css`
--divider-color: rgba(0, 0, 0, 0.12);
--outline-color: rgba(0, 0, 0, 0.12);
--outline-hover-color: rgba(0, 0, 0, 0.24);
--shadow-color: rgba(0, 0, 0, 0.16);
/* rgb */
--rgb-primary-color: 0, 154, 199;
@@ -225,7 +224,7 @@ export const colorStyles = css`
--table-row-alternative-background-color: var(--secondary-background-color);
--data-table-background-color: var(--card-background-color);
--markdown-code-background-color: var(--primary-background-color);
--bar-box-shadow: 0 2px 12px var(--shadow-color);
--bar-box-shadow: 0 2px 12px rgba(0, 0, 0, 0.16);
/* https://github.com/material-components/material-web/blob/master/docs/theming.md */
--mdc-theme-primary: var(--primary-color);
@@ -308,8 +307,6 @@ export const darkColorStyles = css`
--divider-color: rgba(225, 225, 225, 0.12);
--outline-color: rgba(225, 225, 225, 0.12);
--outline-hover-color: rgba(225, 225, 225, 0.24);
--shadow-color: rgba(0, 0, 0, 0.48);
--mdc-ripple-color: #aaaaaa;
--mdc-linear-progress-buffer-color: rgba(255, 255, 255, 0.1);
@@ -353,7 +350,7 @@ export const darkColorStyles = css`
--ha-button-neutral-color: #d9dae0;
--ha-button-neutral-light-color: #6a7081;
--bar-box-shadow: 0 2px 12px var(--shadow-color);
--bar-box-shadow: 0 2px 12px rgba(0, 0, 0, 0.48);
}
`;

View File

@@ -3265,7 +3265,10 @@
"create_helper": "Create helper",
"no_helpers": "Looks like you don't have any helpers yet!",
"search": "Search {number} {number, plural,\n one {helper}\n other {helpers}\n}",
"error_information": "Error information"
"error_information": "Error information",
"delete_confirm_title": "Delete helper?",
"delete_confirm_text": "Are you sure you want to delete {name}?",
"delete_failed": "Failed to delete helper"
},
"dialog": {
"create": "Create",

View File

@@ -1215,15 +1215,15 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/autocomplete@npm:6.19.1":
version: 6.19.1
resolution: "@codemirror/autocomplete@npm:6.19.1"
"@codemirror/autocomplete@npm:6.20.0":
version: 6.20.0
resolution: "@codemirror/autocomplete@npm:6.20.0"
dependencies:
"@codemirror/language": "npm:^6.0.0"
"@codemirror/state": "npm:^6.0.0"
"@codemirror/view": "npm:^6.17.0"
"@lezer/common": "npm:^1.0.0"
checksum: 10/6b5a6f3eb869057696c8e1e601eec97f4c68eebb6ca3890d0aea264b2e7888c555a57c74ae53731d3bc2cc98466be1778cc64b0f7f591ba90b61cd334e7095a8
checksum: 10/ba3603b860c30dd4f8b7c20085680d2f491022db95fe1f3aa6a58363c64678efb3ba795d715755c8a02121631317cf7fbe44cfa3b4cdb01ebca2b4ed36ea5d8a
languageName: node
linkType: hard
@@ -1282,15 +1282,15 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/view@npm:6.38.6, @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.6
resolution: "@codemirror/view@npm:6.38.6"
"@codemirror/view@npm:6.38.8, @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.8
resolution: "@codemirror/view@npm:6.38.8"
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/5a047337a98de111817ce8c8d39e6429c90ca0b0a4d2678d6e161e9e5961b1d476a891f447ab7a05cac395d4a93530e7c68bedd93191285265f0742a308ad00b
checksum: 10/81b1508015a378e4719d0239254173f0c5cd340c2abf96eb488fe5fb474bdb37ec1f010b9890ced774accd7aeb9443e7337cb6a89544b954273e5ddabece7cea
languageName: node
linkType: hard
@@ -9202,13 +9202,13 @@ __metadata:
"@babel/runtime": "npm:7.28.4"
"@braintree/sanitize-url": "npm:7.1.1"
"@bundle-stats/plugin-webpack-filter": "npm:4.21.6"
"@codemirror/autocomplete": "npm:6.19.1"
"@codemirror/autocomplete": "npm:6.20.0"
"@codemirror/commands": "npm:6.10.0"
"@codemirror/language": "npm:6.11.3"
"@codemirror/legacy-modes": "npm:6.5.2"
"@codemirror/search": "npm:6.5.11"
"@codemirror/state": "npm:6.5.2"
"@codemirror/view": "npm:6.38.6"
"@codemirror/view": "npm:6.38.8"
"@date-fns/tz": "npm:1.4.1"
"@egjs/hammerjs": "npm:2.0.17"
"@formatjs/intl-datetimeformat": "npm:6.18.2"