mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-12 18:59:26 +00:00
Compare commits
8 Commits
card_edito
...
column_bre
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1d007a5aaf | ||
![]() |
94c1af7729 | ||
![]() |
d7aaf9bc41 | ||
![]() |
c0aed4325d | ||
![]() |
79a56fabdf | ||
![]() |
14c2b60538 | ||
![]() |
79f3dfdfce | ||
![]() |
3de4dffa02 |
@@ -1,7 +1,16 @@
|
||||
diff --git a/modular/sortable.core.esm.js b/modular/sortable.core.esm.js
|
||||
index 8b5e49b011713c8859c669069fbe85ce53974e1d..6a0afc92787157b8a31c38cc5f67dfa526090a00 100644
|
||||
index 93ba17509e2e8583ab241fea6845fbe714c584a2..de0651ddb5dced30d36f7d764da0dd0b441f523f 100644
|
||||
--- a/modular/sortable.core.esm.js
|
||||
+++ b/modular/sortable.core.esm.js
|
||||
@@ -1461,7 +1461,7 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
}
|
||||
target = parent; // store last element
|
||||
}
|
||||
- /* jshint boss:true */ while (parent = parent.parentNode);
|
||||
+ /* jshint boss:true */ while (parent = parent.parentNode || parent.getRootNode().host);
|
||||
}
|
||||
_unhideGhostForTarget();
|
||||
}
|
||||
@@ -1781,11 +1781,16 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
}
|
||||
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
|
||||
@@ -24,7 +33,7 @@ index 8b5e49b011713c8859c669069fbe85ce53974e1d..6a0afc92787157b8a31c38cc5f67dfa5
|
||||
}
|
||||
parentEl = el; // actualization
|
||||
|
||||
@@ -1802,7 +1807,12 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
@@ -1802,7 +1807,13 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
targetRect = getRect(target);
|
||||
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
|
||||
capture();
|
||||
@@ -35,10 +44,11 @@ index 8b5e49b011713c8859c669069fbe85ce53974e1d..6a0afc92787157b8a31c38cc5f67dfa5
|
||||
+ catch(err) {
|
||||
+ return completed(false);
|
||||
+ }
|
||||
+
|
||||
parentEl = el; // actualization
|
||||
|
||||
changed();
|
||||
@@ -1849,10 +1859,15 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
@@ -1849,12 +1860,17 @@ Sortable.prototype = /** @lends Sortable.prototype */{
|
||||
_silent = true;
|
||||
setTimeout(_unsilent, 30);
|
||||
capture();
|
||||
@@ -46,6 +56,8 @@ index 8b5e49b011713c8859c669069fbe85ce53974e1d..6a0afc92787157b8a31c38cc5f67dfa5
|
||||
- el.appendChild(dragEl);
|
||||
- } else {
|
||||
- target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
|
||||
- }
|
||||
|
||||
+ try {
|
||||
+ if (after && !nextSibling) {
|
||||
+ el.appendChild(dragEl);
|
||||
@@ -55,6 +67,7 @@ index 8b5e49b011713c8859c669069fbe85ce53974e1d..6a0afc92787157b8a31c38cc5f67dfa5
|
||||
+ }
|
||||
+ catch(err) {
|
||||
+ return completed(false);
|
||||
}
|
||||
|
||||
+ }
|
||||
// Undo chrome's scroll adjustment (has no effect on other browsers)
|
||||
if (scrolledPastTop) {
|
||||
scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
|
@@ -64,7 +64,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
{
|
||||
area_id: "backyard",
|
||||
@@ -87,7 +86,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
{
|
||||
area_id: null,
|
||||
@@ -110,7 +108,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
];
|
||||
|
||||
|
@@ -64,7 +64,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
{
|
||||
area_id: "backyard",
|
||||
@@ -87,7 +86,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
{
|
||||
area_id: null,
|
||||
@@ -110,7 +108,6 @@ const DEVICES: DeviceRegistryEntry[] = [
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
];
|
||||
|
||||
|
@@ -232,7 +232,6 @@ const createDeviceRegistryEntries = (
|
||||
labels: [],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
primary_config_entry: null,
|
||||
},
|
||||
];
|
||||
|
||||
|
12
package.json
12
package.json
@@ -118,7 +118,7 @@
|
||||
"leaflet-draw": "1.0.4",
|
||||
"lit": "2.8.0",
|
||||
"luxon": "3.5.0",
|
||||
"marked": "14.1.1",
|
||||
"marked": "14.1.0",
|
||||
"memoize-one": "6.0.0",
|
||||
"node-vibrant": "3.2.1-alpha.1",
|
||||
"proxy-polyfill": "0.3.2",
|
||||
@@ -127,7 +127,7 @@
|
||||
"qrcode": "1.5.4",
|
||||
"roboto-fontface": "0.10.0",
|
||||
"rrule": "2.8.1",
|
||||
"sortablejs": "1.15.3",
|
||||
"sortablejs": "1.15.2",
|
||||
"stacktrace-js": "2.0.2",
|
||||
"superstruct": "2.0.2",
|
||||
"tinykeys": "3.0.0",
|
||||
@@ -198,8 +198,8 @@
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-airbnb-typescript": "18.0.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-import-resolver-webpack": "0.13.9",
|
||||
"eslint-plugin-import": "2.30.0",
|
||||
"eslint-import-resolver-webpack": "0.13.8",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-lit": "1.14.0",
|
||||
"eslint-plugin-lit-a11y": "4.1.4",
|
||||
"eslint-plugin-unused-imports": "4.1.3",
|
||||
@@ -241,7 +241,7 @@
|
||||
"typescript": "5.5.4",
|
||||
"webpack": "5.94.0",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "5.1.0",
|
||||
"webpack-dev-server": "5.0.4",
|
||||
"webpack-manifest-plugin": "5.0.0",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "6.0.1",
|
||||
@@ -255,7 +255,7 @@
|
||||
"clean-css": "5.3.3",
|
||||
"@lit/reactive-element": "1.6.3",
|
||||
"@fullcalendar/daygrid": "6.1.15",
|
||||
"sortablejs@1.15.3": "patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch",
|
||||
"sortablejs@1.15.2": "patch:sortablejs@npm%3A1.15.2#~/.yarn/patches/sortablejs-npm-1.15.2-73347ae85a.patch",
|
||||
"leaflet-draw@1.0.4": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch"
|
||||
},
|
||||
"packageManager": "yarn@4.4.1"
|
||||
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20240909.1"
|
||||
version = "20240904.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { Button } from "@material/mwc-button";
|
||||
import { Corner } from "@material/web/menu/menu";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
|
||||
@@ -15,20 +14,8 @@ export class HaButtonMenuNew extends LitElement {
|
||||
|
||||
@property() public positioning?: "fixed" | "absolute" | "popover";
|
||||
|
||||
@property({ type: Boolean, attribute: "no-horizontal-flip" })
|
||||
public noHorizontalFlip = false;
|
||||
|
||||
@property({ type: Boolean, attribute: "no-vertical-flip" })
|
||||
public noVerticalFlip = false;
|
||||
|
||||
@property({ attribute: "anchor-corner" })
|
||||
public anchorCorner: Corner = Corner.END_START;
|
||||
|
||||
@property({ attribute: "menu-corner" })
|
||||
public menuCorner: Corner = Corner.START_START;
|
||||
|
||||
@property({ type: Boolean, attribute: "has-overflow" })
|
||||
public hasOverflow = false;
|
||||
@property({ type: Boolean, attribute: "has-overflow" }) public hasOverflow =
|
||||
false;
|
||||
|
||||
@query("ha-menu", true) private _menu!: HaMenu;
|
||||
|
||||
@@ -52,10 +39,6 @@ export class HaButtonMenuNew extends LitElement {
|
||||
<ha-menu
|
||||
.positioning=${this.positioning}
|
||||
.hasOverflow=${this.hasOverflow}
|
||||
.anchorCorner=${this.anchorCorner}
|
||||
.menuCorner=${this.menuCorner}
|
||||
.noVerticalFlip=${this.noVerticalFlip}
|
||||
.noHorizontalFlip=${this.noHorizontalFlip}
|
||||
>
|
||||
<slot></slot>
|
||||
</ha-menu>
|
||||
|
@@ -95,10 +95,10 @@ export const computeInitialHaFormData = (
|
||||
} else if (
|
||||
"action" in selector ||
|
||||
"trigger" in selector ||
|
||||
"condition" in selector
|
||||
"condition" in selector ||
|
||||
"media" in selector ||
|
||||
"target" in selector
|
||||
) {
|
||||
data[field.name] = [];
|
||||
} else if ("media" in selector || "target" in selector) {
|
||||
data[field.name] = {};
|
||||
} else {
|
||||
throw new Error(
|
||||
|
@@ -73,10 +73,6 @@ export class HaForm extends LitElement implements HaFormElement {
|
||||
schema: any
|
||||
) => string | undefined;
|
||||
|
||||
@property({ attribute: false }) public localizeValue?: (
|
||||
key: string
|
||||
) => string;
|
||||
|
||||
protected getFormProperties(): Record<string, any> {
|
||||
return {};
|
||||
}
|
||||
@@ -149,7 +145,6 @@ export class HaForm extends LitElement implements HaFormElement {
|
||||
.disabled=${item.disabled || this.disabled || false}
|
||||
.placeholder=${item.required ? "" : item.default}
|
||||
.helper=${this._computeHelper(item)}
|
||||
.localizeValue=${this.localizeValue}
|
||||
.required=${item.required || false}
|
||||
.context=${this._generateContext(item)}
|
||||
></ha-selector>`
|
||||
|
@@ -1,22 +0,0 @@
|
||||
import { MdOutlinedSegmentedButtonSet } from "@material/web/labs/segmentedbuttonset/outlined-segmented-button-set";
|
||||
import { css } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
|
||||
@customElement("ha-outlined-segmented-button-set")
|
||||
export class HaOutlinedSegmentedButtonSet extends MdOutlinedSegmentedButtonSet {
|
||||
static override styles = [
|
||||
...super.styles,
|
||||
css`
|
||||
:host {
|
||||
--ha-icon-display: block;
|
||||
--md-outlined-segmented-button-container-height: 32px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-outlined-segmented-button-set": HaOutlinedSegmentedButtonSet;
|
||||
}
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
import { MdOutlinedSegmentedButton } from "@material/web/labs/segmentedbutton/outlined-segmented-button";
|
||||
import { css } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
|
||||
@customElement("ha-outlined-segmented-button")
|
||||
export class HaOutlinedSegmentedButton extends MdOutlinedSegmentedButton {
|
||||
static override styles = [
|
||||
...super.styles,
|
||||
css`
|
||||
:host {
|
||||
--ha-icon-display: block;
|
||||
--md-outlined-segmented-button-selected-container-color: var(
|
||||
--light-primary-color
|
||||
);
|
||||
--md-outlined-segmented-button-container-height: 32px;
|
||||
--md-outlined-segmented-button-disabled-label-text-color: var(
|
||||
--disabled-text-color
|
||||
);
|
||||
--md-outlined-segmented-button-disabled-icon-color: var(
|
||||
--disabled-text-color
|
||||
);
|
||||
--md-outlined-segmented-button-disabled-outline-color: var(
|
||||
--disabled-text-color
|
||||
);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-outlined-segmented-button": HaOutlinedSegmentedButton;
|
||||
}
|
||||
}
|
@@ -109,7 +109,7 @@ class HaWebRtcPlayer extends LitElement {
|
||||
let candidates = ""; // Build an Offer SDP string with ice candidates
|
||||
const iceResolver = new Promise<void>((resolve) => {
|
||||
peerConnection.addEventListener("icecandidate", async (event) => {
|
||||
if (!event.candidate?.candidate) {
|
||||
if (!event.candidate) {
|
||||
resolve(); // Gathering complete
|
||||
return;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import type { IntegrationType } from "./integration";
|
||||
import type { IntegrationManifest, IntegrationType } from "./integration";
|
||||
|
||||
export interface ConfigEntry {
|
||||
entry_id: string;
|
||||
@@ -149,19 +149,20 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) =>
|
||||
|
||||
export const sortConfigEntries = (
|
||||
configEntries: ConfigEntry[],
|
||||
primaryConfigEntry: string | null
|
||||
manifestLookup: { [domain: string]: IntegrationManifest }
|
||||
): ConfigEntry[] => {
|
||||
if (!primaryConfigEntry) {
|
||||
return configEntries;
|
||||
}
|
||||
const primaryEntry = configEntries.find(
|
||||
(e) => e.entry_id === primaryConfigEntry
|
||||
);
|
||||
if (!primaryEntry) {
|
||||
return configEntries;
|
||||
}
|
||||
const otherEntries = configEntries.filter(
|
||||
(e) => e.entry_id !== primaryConfigEntry
|
||||
);
|
||||
return [primaryEntry, ...otherEntries];
|
||||
const sortedConfigEntries = [...configEntries];
|
||||
|
||||
const getScore = (entry: ConfigEntry) => {
|
||||
const manifest = manifestLookup[entry.domain] as
|
||||
| IntegrationManifest
|
||||
| undefined;
|
||||
const isHelper = manifest?.integration_type === "helper";
|
||||
return isHelper ? -1 : 1;
|
||||
};
|
||||
|
||||
const configEntriesCompare = (a: ConfigEntry, b: ConfigEntry) =>
|
||||
getScore(b) - getScore(a);
|
||||
|
||||
return sortedConfigEntries.sort(configEntriesCompare);
|
||||
};
|
||||
|
@@ -33,7 +33,6 @@ export interface DeviceRegistryEntry extends RegistryEntry {
|
||||
entry_type: "service" | null;
|
||||
disabled_by: "user" | "integration" | "config_entry" | null;
|
||||
configuration_url: string | null;
|
||||
primary_config_entry: string | null;
|
||||
}
|
||||
|
||||
export interface DeviceEntityDisplayLookup {
|
||||
|
@@ -25,6 +25,8 @@ export interface LovelaceBaseViewConfig {
|
||||
// Only used for section view, it should move to a section view config type when the views will have dedicated editor.
|
||||
max_columns?: number;
|
||||
dense_section_placement?: boolean;
|
||||
column_breakpoints?: Record<string, number>;
|
||||
experimental_breakpoints?: boolean;
|
||||
}
|
||||
|
||||
export interface LovelaceViewConfig extends LovelaceBaseViewConfig {
|
||||
|
@@ -83,7 +83,7 @@ export const showConfigFlowDialog = (
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : "";
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}` : "";
|
||||
|
||||
return (
|
||||
hass.localize(
|
||||
|
@@ -650,7 +650,6 @@ export class HaVoiceCommandDialog extends LitElement {
|
||||
margin-inline-end: -24px;
|
||||
margin-inline-start: initial;
|
||||
direction: var(--direction);
|
||||
transform: scaleX(var(--scale-direction));
|
||||
}
|
||||
|
||||
.listening-icon[active] {
|
||||
|
@@ -153,7 +153,7 @@ export class HaConfigDevicePage extends LitElement {
|
||||
.filter((entId) => entId in entryLookup)
|
||||
.map((entry) => entryLookup[entry]);
|
||||
|
||||
return sortConfigEntries(deviceEntries, device.primary_config_entry);
|
||||
return sortConfigEntries(deviceEntries, manifestLookup);
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -388,7 +388,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
||||
device.config_entries
|
||||
.filter((entId) => entId in entryLookup)
|
||||
.map((entId) => entryLookup[entId]),
|
||||
device.primary_config_entry
|
||||
manifestLookup
|
||||
);
|
||||
|
||||
const labels = labelReg && device?.labels;
|
||||
|
@@ -6,18 +6,19 @@ import {
|
||||
mdiCloseCircle,
|
||||
mdiProgressClock,
|
||||
} from "@mdi/js";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { groupBy } from "../../../../../common/util/group-by";
|
||||
import memoizeOne from "memoize-one";
|
||||
import "../../../../../components/ha-alert";
|
||||
import "../../../../../components/ha-card";
|
||||
import "../../../../../components/ha-icon-next";
|
||||
@@ -26,19 +27,25 @@ import "../../../../../components/ha-settings-row";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import "../../../../../components/ha-switch";
|
||||
import "../../../../../components/ha-textfield";
|
||||
import { computeDeviceName } from "../../../../../data/device_registry";
|
||||
import { groupBy } from "../../../../../common/util/group-by";
|
||||
import {
|
||||
computeDeviceName,
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../../../data/device_registry";
|
||||
import {
|
||||
ZWaveJSNodeConfigParam,
|
||||
ZWaveJSNodeConfigParams,
|
||||
ZWaveJSSetConfigParamResult,
|
||||
ZwaveJSNodeMetadata,
|
||||
fetchZwaveNodeConfigParameters,
|
||||
fetchZwaveNodeMetadata,
|
||||
setZwaveNodeConfigParameter,
|
||||
ZWaveJSNodeConfigParam,
|
||||
ZWaveJSNodeConfigParams,
|
||||
ZwaveJSNodeMetadata,
|
||||
ZWaveJSSetConfigParamResult,
|
||||
} from "../../../../../data/zwave_js";
|
||||
import "../../../../../layouts/hass-error-screen";
|
||||
import "../../../../../layouts/hass-loading-screen";
|
||||
import "../../../../../layouts/hass-tabs-subpage";
|
||||
import { SubscribeMixin } from "../../../../../mixins/subscribe-mixin";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import "../../../ha-config-section";
|
||||
@@ -50,8 +57,16 @@ const icons = {
|
||||
error: mdiCloseCircle,
|
||||
};
|
||||
|
||||
const getDevice = memoizeOne(
|
||||
(
|
||||
deviceId: string,
|
||||
entries?: DeviceRegistryEntry[]
|
||||
): DeviceRegistryEntry | undefined =>
|
||||
entries?.find((device) => device.id === deviceId)
|
||||
);
|
||||
|
||||
@customElement("zwave_js-node-config")
|
||||
class ZWaveJSNodeConfig extends LitElement {
|
||||
class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
@@ -64,6 +79,8 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
|
||||
@property() public deviceId!: string;
|
||||
|
||||
@state() private _deviceRegistryEntries?: DeviceRegistryEntry[];
|
||||
|
||||
@state() private _nodeMetadata?: ZwaveJSNodeMetadata;
|
||||
|
||||
@state() private _config?: ZWaveJSNodeConfigParams;
|
||||
@@ -77,8 +94,19 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
this.deviceId = this.route.path.substr(1);
|
||||
}
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeDeviceRegistry(this.hass.connection, (entries) => {
|
||||
this._deviceRegistryEntries = entries;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
if (!this._config || changedProps.has("deviceId")) {
|
||||
if (
|
||||
(!this._config || changedProps.has("deviceId")) &&
|
||||
changedProps.has("_deviceRegistryEntries")
|
||||
) {
|
||||
this._fetchData();
|
||||
}
|
||||
}
|
||||
@@ -97,7 +125,7 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
return html`<hass-loading-screen></hass-loading-screen>`;
|
||||
}
|
||||
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
const device = this._device!;
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
@@ -275,11 +303,6 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
.disabled=${!item.metadata.writeable}
|
||||
@change=${this._numericInputChanged}
|
||||
.suffix=${item.metadata.unit}
|
||||
.helper=${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_config.between_min_max",
|
||||
{ min: item.metadata.min, max: item.metadata.max }
|
||||
)}
|
||||
helperPersistent
|
||||
>
|
||||
</ha-textfield>`;
|
||||
}
|
||||
@@ -361,19 +384,6 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
if (Number(this._config![ev.target.key].value) === value) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(ev.target.min !== undefined && value < ev.target.min) ||
|
||||
(ev.target.max !== undefined && value > ev.target.max)
|
||||
) {
|
||||
this.setError(
|
||||
ev.target.key,
|
||||
this.hass.localize(
|
||||
"ui.panel.config.zwave_js.node_config.error_not_in_range",
|
||||
{ min: ev.target.min, max: ev.target.max }
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.setResult(ev.target.key, undefined);
|
||||
this._updateConfigParameter(ev.target, value);
|
||||
}
|
||||
@@ -382,7 +392,7 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
try {
|
||||
const result = await setZwaveNodeConfigParameter(
|
||||
this.hass,
|
||||
this.deviceId,
|
||||
this._device!.id,
|
||||
target.property,
|
||||
target.endpoint,
|
||||
value,
|
||||
@@ -410,12 +420,16 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
this._results = { ...this._results, [key]: errorParam };
|
||||
}
|
||||
|
||||
private get _device(): DeviceRegistryEntry | undefined {
|
||||
return getDevice(this.deviceId, this._deviceRegistryEntries);
|
||||
}
|
||||
|
||||
private async _fetchData() {
|
||||
if (!this.configEntryId) {
|
||||
if (!this.configEntryId || !this._deviceRegistryEntries) {
|
||||
return;
|
||||
}
|
||||
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
const device = this._device;
|
||||
if (!device) {
|
||||
this._error = "device_not_found";
|
||||
return;
|
||||
|
@@ -250,7 +250,7 @@ export class HaConfigLogs extends LitElement {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
--mdc-icon-size: 36px;
|
||||
}
|
||||
ha-button-menu > ha-button > ha-svg-icon {
|
||||
ha-button-menu > mwc-button > ha-svg-icon {
|
||||
margin-inline-end: 0px;
|
||||
margin-inline-start: 8px;
|
||||
}
|
||||
|
@@ -6,13 +6,14 @@ import {
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { mdiChevronRight } from "@mdi/js";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import "../../../components/chart/state-history-charts";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-icon-button";
|
||||
import {
|
||||
HistoryResult,
|
||||
computeHistory,
|
||||
@@ -208,7 +209,9 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
|
||||
? html`
|
||||
<h1 class="card-header">
|
||||
${this._config.title}
|
||||
<a href=${configUrl}><ha-icon-next></ha-icon-next></a>
|
||||
<a href=${configUrl}
|
||||
><ha-icon-button .path=${mdiChevronRight}></ha-icon-button
|
||||
></a>
|
||||
</h1>
|
||||
`
|
||||
: nothing}
|
||||
@@ -255,7 +258,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
}
|
||||
.card-header ha-icon-next {
|
||||
.card-header ha-icon-button {
|
||||
--mdc-icon-button-size: 24px;
|
||||
line-height: 24px;
|
||||
color: var(--primary-text-color);
|
||||
|
@@ -1,25 +0,0 @@
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
import {
|
||||
getCustomCardEntry,
|
||||
isCustomType,
|
||||
stripCustomPrefix,
|
||||
} from "../../../data/lovelace_custom_cards";
|
||||
|
||||
export const computeCardName = (
|
||||
config: LovelaceCardConfig,
|
||||
localize: LocalizeFunc
|
||||
): string | undefined => {
|
||||
if (isCustomType(config.type)) {
|
||||
// prettier-ignore
|
||||
let cardName = getCustomCardEntry(
|
||||
stripCustomPrefix(config.type)
|
||||
)?.name;
|
||||
// Trim names that end in " Card" so as not to redundantly duplicate it
|
||||
if (cardName?.toLowerCase().endsWith(" card")) {
|
||||
cardName = cardName.substring(0, cardName.length - 5);
|
||||
}
|
||||
return cardName;
|
||||
}
|
||||
return localize(`ui.panel.lovelace.editor.card.${config.type}.name`);
|
||||
};
|
@@ -1,155 +0,0 @@
|
||||
import "@material/mwc-tab-bar/mwc-tab-bar";
|
||||
import "@material/mwc-tab/mwc-tab";
|
||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||
import { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import "./hui-card-element-editor";
|
||||
import type { HuiCardElementEditor } from "./hui-card-element-editor";
|
||||
import "./hui-card-layout-editor";
|
||||
import "./hui-card-visibility-editor";
|
||||
|
||||
const TABS = ["config", "visibility", "layout"] as const;
|
||||
|
||||
@customElement("hui-card-editor")
|
||||
class HuiCardEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public lovelace!: LovelaceConfig;
|
||||
|
||||
@property({ attribute: false }) public config!: LovelaceCardConfig;
|
||||
|
||||
@property({ attribute: false }) public containerConfig!:
|
||||
| LovelaceViewConfig
|
||||
| LovelaceSectionConfig;
|
||||
|
||||
@query("hui-card-element-editor")
|
||||
public elementEditor?: HuiCardElementEditor;
|
||||
|
||||
@state() private _selectedTab: (typeof TABS)[number] = TABS[0];
|
||||
|
||||
private _tabs = memoizeOne(
|
||||
(containerType: string | undefined, cardType: string) =>
|
||||
TABS.filter((tab) => {
|
||||
if (tab === "visibility") return cardType !== "conditional";
|
||||
if (tab === "layout") return containerType === "grid";
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
private _elementConfig = memoizeOne((config: LovelaceCardConfig) => {
|
||||
const { visibility, layout_options, ...elementConfig } = config;
|
||||
return elementConfig;
|
||||
});
|
||||
|
||||
private renderContent() {
|
||||
if (this._selectedTab === "config") {
|
||||
return html`
|
||||
<hui-card-element-editor
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this.lovelace}
|
||||
.value=${this._elementConfig(this.config)}
|
||||
show-toggle-mode-button
|
||||
@config-changed=${this._elementConfigChanged}
|
||||
></hui-card-element-editor>
|
||||
`;
|
||||
}
|
||||
if (this._selectedTab === "visibility") {
|
||||
return html`
|
||||
<hui-card-visibility-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this.config}
|
||||
@value-changed=${this._configChanged}
|
||||
></hui-card-visibility-editor>
|
||||
`;
|
||||
}
|
||||
if (this._selectedTab === "layout") {
|
||||
return html`
|
||||
<hui-card-layout-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this.config}
|
||||
.sectionConfig=${this.containerConfig as LovelaceSectionConfig}
|
||||
@value-changed=${this._configChanged}
|
||||
>
|
||||
</hui-card-layout-editor>
|
||||
`;
|
||||
}
|
||||
return nothing;
|
||||
}
|
||||
|
||||
private _configChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
}
|
||||
|
||||
private _elementConfigChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
const config = ev.detail.config;
|
||||
const newConfig = {
|
||||
...config,
|
||||
visibility: this.config.visibility,
|
||||
layout_options: this.config.layout_options,
|
||||
};
|
||||
fireEvent(this, "config-changed", { config: newConfig });
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const cardType = this.config.type;
|
||||
const containerType = this.containerConfig.type;
|
||||
const tabs = this._tabs(containerType, cardType);
|
||||
|
||||
if (tabs.length <= 1) {
|
||||
return this.renderContent();
|
||||
}
|
||||
return html`
|
||||
<mwc-tab-bar
|
||||
.activeIndex=${tabs.indexOf(this._selectedTab)}
|
||||
@MDCTabBar:activated=${this._handleTabChanged}
|
||||
>
|
||||
${tabs.map(
|
||||
(tab) => html`
|
||||
<mwc-tab
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_card.tab_${tab}`
|
||||
)}
|
||||
>
|
||||
</mwc-tab>
|
||||
`
|
||||
)}
|
||||
</mwc-tab-bar>
|
||||
${this.renderContent()}
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleTabChanged(ev: CustomEvent): void {
|
||||
const cardType = this.config.type;
|
||||
const containerType = this.containerConfig.type;
|
||||
const tabs = this._tabs(containerType, cardType);
|
||||
const newTab = tabs[ev.detail.index];
|
||||
if (newTab === this._selectedTab) {
|
||||
return;
|
||||
}
|
||||
this._selectedTab = newTab;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
mwc-tab-bar {
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-card-editor": HuiCardEditor;
|
||||
}
|
||||
}
|
@@ -1,11 +1,26 @@
|
||||
import { customElement } from "lit/decorators";
|
||||
import "@material/mwc-tab-bar/mwc-tab-bar";
|
||||
import "@material/mwc-tab/mwc-tab";
|
||||
import { CSSResultGroup, TemplateResult, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import { getCardElementClass } from "../../create-element/create-card-element";
|
||||
import type { LovelaceCardEditor, LovelaceConfigForm } from "../../types";
|
||||
import { HuiElementEditor } from "../hui-element-editor";
|
||||
import "./hui-card-layout-editor";
|
||||
import "./hui-card-visibility-editor";
|
||||
import { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||
|
||||
const tabs = ["config", "visibility", "layout"] as const;
|
||||
|
||||
@customElement("hui-card-element-editor")
|
||||
export class HuiCardElementEditor extends HuiElementEditor<LovelaceCardConfig> {
|
||||
@property({ type: Boolean, attribute: "show-visibility-tab" })
|
||||
public showVisibilityTab = false;
|
||||
|
||||
@property({ attribute: false }) public sectionConfig?: LovelaceSectionConfig;
|
||||
|
||||
@state() private _currTab: (typeof tabs)[number] = tabs[0];
|
||||
|
||||
protected async getConfigElement(): Promise<LovelaceCardEditor | undefined> {
|
||||
const elClass = await getCardElementClass(this.configElementType!);
|
||||
|
||||
@@ -27,6 +42,93 @@ export class HuiCardElementEditor extends HuiElementEditor<LovelaceCardConfig> {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _configChanged(ev: CustomEvent): void {
|
||||
ev.stopPropagation();
|
||||
this.value = ev.detail.value;
|
||||
}
|
||||
|
||||
get _showLayoutTab(): boolean {
|
||||
return (
|
||||
!!this.sectionConfig &&
|
||||
(this.sectionConfig.type === undefined ||
|
||||
this.sectionConfig.type === "grid")
|
||||
);
|
||||
}
|
||||
|
||||
protected renderConfigElement(): TemplateResult {
|
||||
const displayedTabs: string[] = ["config"];
|
||||
if (this.showVisibilityTab) displayedTabs.push("visibility");
|
||||
if (this._showLayoutTab) displayedTabs.push("layout");
|
||||
|
||||
if (displayedTabs.length === 1) return super.renderConfigElement();
|
||||
|
||||
let content: TemplateResult<1> | typeof nothing = nothing;
|
||||
|
||||
switch (this._currTab) {
|
||||
case "config":
|
||||
content = html`${super.renderConfigElement()}`;
|
||||
break;
|
||||
case "visibility":
|
||||
content = html`
|
||||
<hui-card-visibility-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this.value}
|
||||
@value-changed=${this._configChanged}
|
||||
></hui-card-visibility-editor>
|
||||
`;
|
||||
break;
|
||||
case "layout":
|
||||
content = html`
|
||||
<hui-card-layout-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this.value}
|
||||
.sectionConfig=${this.sectionConfig!}
|
||||
@value-changed=${this._configChanged}
|
||||
>
|
||||
</hui-card-layout-editor>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<mwc-tab-bar
|
||||
.activeIndex=${tabs.indexOf(this._currTab)}
|
||||
@MDCTabBar:activated=${this._handleTabChanged}
|
||||
>
|
||||
${displayedTabs.map(
|
||||
(tab) => html`
|
||||
<mwc-tab
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_card.tab_${tab}`
|
||||
)}
|
||||
>
|
||||
</mwc-tab>
|
||||
`
|
||||
)}
|
||||
</mwc-tab-bar>
|
||||
${content}
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleTabChanged(ev: CustomEvent): void {
|
||||
const newTab = tabs[ev.detail.index];
|
||||
if (newTab === this._currTab) {
|
||||
return;
|
||||
}
|
||||
this._currTab = newTab;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
HuiElementEditor.styles,
|
||||
css`
|
||||
mwc-tab-bar {
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@@ -1,14 +1,5 @@
|
||||
import "@material/mwc-list";
|
||||
import "@material/web/divider/divider";
|
||||
import {
|
||||
mdiCheck,
|
||||
mdiClose,
|
||||
mdiDotsVertical,
|
||||
mdiHelpCircle,
|
||||
mdiOpenInNew,
|
||||
} from "@mdi/js";
|
||||
import { mdiClose, mdiHelpCircle } from "@mdi/js";
|
||||
import deepFreeze from "deep-freeze";
|
||||
import { dump, load } from "js-yaml";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
@@ -21,30 +12,32 @@ import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-button-menu-new";
|
||||
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
|
||||
import "../../../../components/ha-circular-progress";
|
||||
import "../../../../components/ha-code-editor";
|
||||
import "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-menu-item";
|
||||
import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||
import { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||
import { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
import {
|
||||
getCustomCardEntry,
|
||||
isCustomType,
|
||||
stripCustomPrefix,
|
||||
} from "../../../../data/lovelace_custom_cards";
|
||||
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { showSaveSuccessToast } from "../../../../util/toast-saved-success";
|
||||
import "../../cards/hui-card";
|
||||
import { computeCardName } from "../../common/compute-card-name";
|
||||
import "../../sections/hui-section";
|
||||
import { addCard, replaceCard } from "../config-util";
|
||||
import { getCardDocumentationURL } from "../get-dashboard-documentation-url";
|
||||
import type { ConfigChangedEvent } from "../hui-element-editor";
|
||||
import { findLovelaceContainer } from "../lovelace-path";
|
||||
import "./hui-card-editor";
|
||||
import type { GUIModeChangedEvent } from "../types";
|
||||
import "./hui-card-element-editor";
|
||||
import type { HuiCardElementEditor } from "./hui-card-element-editor";
|
||||
import type { EditCardDialogParams } from "./show-edit-card-dialog";
|
||||
|
||||
@@ -80,10 +73,12 @@ export class HuiDialogEditCard
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
@query("hui-card-editor")
|
||||
@state() private _guiModeAvailable? = true;
|
||||
|
||||
@query("hui-card-element-editor")
|
||||
private _cardEditorEl?: HuiCardElementEditor;
|
||||
|
||||
@state() private _yamlMode = false;
|
||||
@state() private _GUImode = true;
|
||||
|
||||
@state() private _documentationURL?: string;
|
||||
|
||||
@@ -93,7 +88,8 @@ export class HuiDialogEditCard
|
||||
|
||||
public async showDialog(params: EditCardDialogParams): Promise<void> {
|
||||
this._params = params;
|
||||
this._yamlMode = false;
|
||||
this._GUImode = true;
|
||||
this._guiModeAvailable = true;
|
||||
|
||||
const containerConfig = findLovelaceContainer(
|
||||
params.lovelaceConfig,
|
||||
@@ -172,7 +168,21 @@ export class HuiDialogEditCard
|
||||
|
||||
let heading: string;
|
||||
if (this._cardConfig && this._cardConfig.type) {
|
||||
const cardName = computeCardName(this._cardConfig, this.hass!.localize);
|
||||
let cardName: string | undefined;
|
||||
if (isCustomType(this._cardConfig.type)) {
|
||||
// prettier-ignore
|
||||
cardName = getCustomCardEntry(
|
||||
stripCustomPrefix(this._cardConfig.type)
|
||||
)?.name;
|
||||
// Trim names that end in " Card" so as not to redundantly duplicate it
|
||||
if (cardName?.toLowerCase().endsWith(" card")) {
|
||||
cardName = cardName.substring(0, cardName.length - 5);
|
||||
}
|
||||
} else {
|
||||
cardName = this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.${this._cardConfig.type}.name`
|
||||
);
|
||||
}
|
||||
heading = this.hass!.localize(
|
||||
"ui.panel.lovelace.editor.edit_card.typed_header",
|
||||
{ type: cardName }
|
||||
@@ -208,99 +218,36 @@ export class HuiDialogEditCard
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title" @click=${this._enlarge}>${heading}</span>
|
||||
<ha-button-menu-new
|
||||
slot="actionItems"
|
||||
anchor-corner="end-end"
|
||||
menu-corner="start-end"
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
>
|
||||
</ha-icon-button>
|
||||
<ha-menu-item @click=${this._enableGuiMode}>
|
||||
${!this._yamlMode
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
class="selected_menu_item"
|
||||
slot="start"
|
||||
.path=${mdiCheck}
|
||||
></ha-svg-icon>
|
||||
`
|
||||
: html`<span class="blank-icon" slot="start"></span>`}
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.edit_card.edit_ui"
|
||||
)}
|
||||
</div>
|
||||
</ha-menu-item>
|
||||
<ha-menu-item @click=${this._enableYamlMode}>
|
||||
${this._yamlMode
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
class="selected_menu_item"
|
||||
slot="start"
|
||||
.path=${mdiCheck}
|
||||
></ha-svg-icon>
|
||||
`
|
||||
: html`<span class="blank-icon" slot="start"></span>`}
|
||||
<div slot="headline">
|
||||
${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.edit_card.edit_yaml"
|
||||
)}
|
||||
</div>
|
||||
</ha-menu-item>
|
||||
${this._documentationURL !== undefined
|
||||
? html`
|
||||
<md-divider role="separator" tabindex="-1"></md-divider>
|
||||
<ha-menu-item
|
||||
type="link"
|
||||
href=${this._documentationURL}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="start"
|
||||
.path=${mdiHelpCircle}
|
||||
></ha-svg-icon>
|
||||
<div slot="headline">
|
||||
${this.hass!.localize("ui.panel.lovelace.menu.help")}
|
||||
</div>
|
||||
<ha-svg-icon slot="end" .path=${mdiOpenInNew}></ha-svg-icon>
|
||||
</ha-menu-item>
|
||||
`
|
||||
: nothing}
|
||||
</ha-button-menu-new>
|
||||
${this._documentationURL !== undefined
|
||||
? html`
|
||||
<a
|
||||
slot="actionItems"
|
||||
href=${this._documentationURL}
|
||||
title=${this.hass!.localize("ui.panel.lovelace.menu.help")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
dir=${computeRTLDirection(this.hass)}
|
||||
>
|
||||
<ha-icon-button .path=${mdiHelpCircle}></ha-icon-button>
|
||||
</a>
|
||||
`
|
||||
: nothing}
|
||||
</ha-dialog-header>
|
||||
<div class="content">
|
||||
<div class="element-editor">
|
||||
${this._yamlMode
|
||||
? html`
|
||||
<ha-code-editor
|
||||
mode="yaml"
|
||||
autofocus
|
||||
autocomplete-entities
|
||||
autocomplete-icons
|
||||
.hass=${this.hass}
|
||||
.value=${dump(this._cardConfig)}
|
||||
@value-changed=${this._handleYAMLChanged}
|
||||
@keydown=${this._ignoreKeydown}
|
||||
dir="ltr"
|
||||
></ha-code-editor>
|
||||
`
|
||||
: html`
|
||||
<hui-card-editor
|
||||
.containerConfig=${this._containerConfig}
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this._params.lovelaceConfig}
|
||||
.config=${this._cardConfig}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
@editor-save=${this._save}
|
||||
dialogInitialFocus
|
||||
>
|
||||
</hui-card-editor>
|
||||
`}
|
||||
<hui-card-element-editor
|
||||
.showVisibilityTab=${this._cardConfig?.type !== "conditional"}
|
||||
.sectionConfig=${this._isInSection
|
||||
? this._containerConfig
|
||||
: undefined}
|
||||
.hass=${this.hass}
|
||||
.lovelace=${this._params.lovelaceConfig}
|
||||
.value=${this._cardConfig}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
@GUImode-changed=${this._handleGUIModeChanged}
|
||||
@editor-save=${this._save}
|
||||
dialogInitialFocus
|
||||
></hui-card-element-editor>
|
||||
</div>
|
||||
<div class="element-preview">
|
||||
${this._isInSection
|
||||
@@ -330,44 +277,49 @@ export class HuiDialogEditCard
|
||||
: ``}
|
||||
</div>
|
||||
</div>
|
||||
<ha-button
|
||||
@click=${this._cancel}
|
||||
slot="secondaryAction"
|
||||
dialogInitialFocus
|
||||
>
|
||||
${this.hass!.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
${this._cardConfig !== undefined && this._dirty
|
||||
${this._cardConfig !== undefined
|
||||
? html`
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
?disabled=${!this._canSave || this._saving}
|
||||
@click=${this._save}
|
||||
<mwc-button
|
||||
slot="secondaryAction"
|
||||
@click=${this._toggleMode}
|
||||
.disabled=${!this._guiModeAvailable}
|
||||
class="gui-mode-button"
|
||||
>
|
||||
${this._saving
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
aria-label="Saving"
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: this.hass!.localize("ui.common.save")}
|
||||
</ha-button>
|
||||
${this.hass!.localize(
|
||||
!this._cardEditorEl || this._GUImode
|
||||
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
|
||||
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
|
||||
)}
|
||||
</mwc-button>
|
||||
`
|
||||
: nothing}
|
||||
: ""}
|
||||
<div slot="primaryAction" @click=${this._save}>
|
||||
<mwc-button @click=${this._cancel} dialogInitialFocus>
|
||||
${this.hass!.localize("ui.common.cancel")}
|
||||
</mwc-button>
|
||||
${this._cardConfig !== undefined && this._dirty
|
||||
? html`
|
||||
<mwc-button
|
||||
?disabled=${!this._canSave || this._saving}
|
||||
@click=${this._save}
|
||||
>
|
||||
${this._saving
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
aria-label="Saving"
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: this.hass!.localize("ui.common.save")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _enableGuiMode() {
|
||||
this._yamlMode = false;
|
||||
}
|
||||
|
||||
private _enableYamlMode() {
|
||||
this._yamlMode = true;
|
||||
}
|
||||
|
||||
private _enlarge() {
|
||||
this.large = !this.large;
|
||||
}
|
||||
@@ -376,21 +328,27 @@ export class HuiDialogEditCard
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
private _handleYAMLChanged(ev: CustomEvent) {
|
||||
this._cardConfig = load(ev.detail.value) as LovelaceCardConfig;
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
||||
this._cardConfig = deepFreeze(ev.detail.config);
|
||||
this._error = ev.detail.error;
|
||||
this._guiModeAvailable = ev.detail.guiModeAvailable;
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
|
||||
ev.stopPropagation();
|
||||
this._GUImode = ev.detail.guiMode;
|
||||
this._guiModeAvailable = ev.detail.guiModeAvailable;
|
||||
}
|
||||
|
||||
private _toggleMode(): void {
|
||||
this._cardEditorEl?.toggleMode();
|
||||
}
|
||||
|
||||
private _opened() {
|
||||
window.addEventListener("dialog-closed", this._enableEscapeKeyClose);
|
||||
window.addEventListener("hass-more-info", this._disableEscapeKeyClose);
|
||||
// this._cardEditorEl?.focusYamlEditor();
|
||||
this._cardEditorEl?.focusYamlEditor();
|
||||
}
|
||||
|
||||
private get _isInSection() {
|
||||
@@ -593,6 +551,11 @@ export class HuiDialogEditCard
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.gui-mode-button {
|
||||
margin-right: auto;
|
||||
margin-inline-end: auto;
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -602,12 +565,6 @@ export class HuiDialogEditCard
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.selected_menu_item {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.blank-icon {
|
||||
width: 16px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { mdiCodeBraces, mdiListBox } from "@mdi/js";
|
||||
import "@material/mwc-button";
|
||||
import { dump, load } from "js-yaml";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
TemplateResult,
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
@@ -17,17 +16,14 @@ import "../../../components/ha-alert";
|
||||
import "../../../components/ha-circular-progress";
|
||||
import "../../../components/ha-code-editor";
|
||||
import type { HaCodeEditor } from "../../../components/ha-code-editor";
|
||||
import "../../../components/ha-outlined-segmented-button";
|
||||
import "../../../components/ha-outlined-segmented-button-set";
|
||||
import { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge";
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
|
||||
import { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
|
||||
import { LovelaceConfig } from "../../../data/lovelace/config/types";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeatureConfig } from "../card-features/types";
|
||||
import { LovelaceElementConfig } from "../elements/types";
|
||||
import type { LovelaceRowConfig } from "../entity-rows/types";
|
||||
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
||||
import { LovelaceElementConfig } from "../elements/types";
|
||||
import type {
|
||||
LovelaceConfigForm,
|
||||
LovelaceGenericElementEditor,
|
||||
@@ -37,6 +33,7 @@ import type { HuiFormEditor } from "./config-elements/hui-form-editor";
|
||||
import "./config-elements/hui-generic-entity-row-editor";
|
||||
import { GUISupportError } from "./gui-support-error";
|
||||
import { EditSubElementEvent, GUIModeChangedEvent } from "./types";
|
||||
import { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge";
|
||||
|
||||
export interface ConfigChangedEvent {
|
||||
config:
|
||||
@@ -76,9 +73,6 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public context?: C;
|
||||
|
||||
@property({ type: Boolean, attribute: "show-toggle-mode-button" })
|
||||
public showToggleModeButton = false;
|
||||
|
||||
@state() private _yaml?: string;
|
||||
|
||||
@state() private _config?: T;
|
||||
@@ -214,40 +208,8 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const guiModeAvailable = !(
|
||||
this.hasWarning ||
|
||||
this.hasError ||
|
||||
this._guiSupported === false
|
||||
);
|
||||
|
||||
return html`
|
||||
<div class="wrapper">
|
||||
${this.showToggleModeButton
|
||||
? html`
|
||||
<div class="header">
|
||||
<ha-outlined-segmented-button-set
|
||||
@segmented-button-set-selection=${this._handleModeSelected}
|
||||
>
|
||||
<ha-outlined-segmented-button
|
||||
.selected=${this._guiMode}
|
||||
.disabled=${!guiModeAvailable}
|
||||
no-checkmark
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiListBox}></ha-svg-icon>
|
||||
</ha-outlined-segmented-button>
|
||||
<ha-outlined-segmented-button
|
||||
.selected=${!this._guiMode}
|
||||
no-checkmark
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiCodeBraces}
|
||||
></ha-svg-icon>
|
||||
</ha-outlined-segmented-button>
|
||||
</ha-outlined-segmented-button-set>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
${this.GUImode
|
||||
? html`
|
||||
<div class="gui-editor">
|
||||
@@ -279,58 +241,43 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
`}
|
||||
${this._guiSupported === false && this.configElementType
|
||||
? html`
|
||||
<ha-alert
|
||||
alert-type="info"
|
||||
.title=${this.hass.localize(
|
||||
"ui.errors.config.editor_not_supported"
|
||||
)}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.errors.config.editor_not_supported_details",
|
||||
{ type: this.configElementType }
|
||||
)}
|
||||
<br />
|
||||
${this.hass.localize("ui.errors.config.edit_in_yaml_supported")}
|
||||
</ha-alert>
|
||||
<div class="info">
|
||||
${this.hass.localize("ui.errors.config.editor_not_available", {
|
||||
type: this.configElementType,
|
||||
})}
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
: ""}
|
||||
${this.hasError
|
||||
? html`
|
||||
<ha-alert
|
||||
alert-type="error"
|
||||
.title=${this.hass.localize(
|
||||
"ui.errors.config.invalid_configuration"
|
||||
)}
|
||||
>
|
||||
${this.hass.localize("ui.errors.config.error_details")}
|
||||
<div class="error">
|
||||
${this.hass.localize("ui.errors.config.error_detected")}:
|
||||
<br />
|
||||
<ul>
|
||||
${this._errors!.map((error) => html`<li>${error}</li>`)}
|
||||
</ul>
|
||||
</ha-alert>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
: ""}
|
||||
${this.hasWarning
|
||||
? html`
|
||||
<ha-alert
|
||||
alert-type="warning"
|
||||
.title=${this.hass.localize(
|
||||
.title="${this.hass.localize(
|
||||
"ui.errors.config.editor_not_supported"
|
||||
)}
|
||||
)}:"
|
||||
>
|
||||
${this._warnings!.length > 0 && this._warnings![0] !== undefined
|
||||
? html`
|
||||
${this.hass.localize("ui.errors.config.warning_details")}
|
||||
<ul>
|
||||
${this._warnings!.map(
|
||||
(warning) => html`<li>${warning}</li>`
|
||||
)}
|
||||
</ul>
|
||||
`
|
||||
: nothing}
|
||||
? html` <ul>
|
||||
${this._warnings!.map(
|
||||
(warning) => html`<li>${warning}</li>`
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
${this.hass.localize("ui.errors.config.edit_in_yaml_supported")}
|
||||
</ha-alert>
|
||||
`
|
||||
: nothing}
|
||||
: ""}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -364,10 +311,6 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
this.value = config as unknown as T;
|
||||
}
|
||||
|
||||
private _handleModeSelected(ev) {
|
||||
this.GUImode = ev.detail.index === 0;
|
||||
}
|
||||
|
||||
private _handleYAMLChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
const newYaml = ev.detail.value;
|
||||
@@ -509,10 +452,6 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { clamp } from "../../../common/number/clamp";
|
||||
import { listenMediaQuery } from "../../../common/dom/media_query";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-sortable";
|
||||
import "../../../components/ha-svg-icon";
|
||||
@@ -29,8 +29,29 @@ import { showEditSectionDialog } from "../editor/section-editor/show-edit-sectio
|
||||
import { HuiSection } from "../sections/hui-section";
|
||||
import type { Lovelace } from "../types";
|
||||
|
||||
type Breakpoints = Record<string, number>;
|
||||
|
||||
export const DEFAULT_MAX_COLUMNS = 4;
|
||||
|
||||
export const DEFAULT_BREAKPOINTS: Breakpoints = {
|
||||
"0": 1,
|
||||
"768": 2,
|
||||
"1280": 3,
|
||||
"1600": 4,
|
||||
"1920": 5,
|
||||
"2560": 6,
|
||||
};
|
||||
|
||||
const buildMediaQueries = (breakpoints: Breakpoints) =>
|
||||
Object.keys(breakpoints).map((breakpoint, index, array) => {
|
||||
const nextBreakpoint = array[index + 1] as string | undefined;
|
||||
let mediaQuery = `(min-width: ${breakpoint}px)`;
|
||||
if (nextBreakpoint) {
|
||||
mediaQuery += ` and (max-width: ${parseInt(nextBreakpoint) - 1}px)`;
|
||||
}
|
||||
return mediaQuery;
|
||||
});
|
||||
|
||||
const parsePx = (value: string) => parseInt(value.replace("px", ""));
|
||||
|
||||
@customElement("hui-sections-view")
|
||||
@@ -53,11 +74,16 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
|
||||
@state() _dragging = false;
|
||||
|
||||
private _listeners: Array<() => void> = [];
|
||||
|
||||
@state() private _breakpointsColumns: number = 1;
|
||||
|
||||
private _columnsController = new ResizeController(this, {
|
||||
callback: (entries) => {
|
||||
const totalWidth = entries[0]?.contentRect.width;
|
||||
// Don't do anything if we are using breakpoints
|
||||
if (this._config?.experimental_breakpoints) return 1;
|
||||
|
||||
if (!totalWidth) return 1;
|
||||
const totalWidth = entries[0]?.contentRect.width;
|
||||
|
||||
const style = getComputedStyle(this);
|
||||
const container = this.shadowRoot!.querySelector(".container")!;
|
||||
@@ -75,12 +101,17 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
(totalWidth - padding + columnGap) / (minColumnWidth + columnGap)
|
||||
);
|
||||
const maxColumns = this._config?.max_columns ?? DEFAULT_MAX_COLUMNS;
|
||||
return clamp(columns, 1, maxColumns);
|
||||
return Math.max(Math.min(maxColumns, columns), 1);
|
||||
},
|
||||
});
|
||||
|
||||
private get _sizeColumns() {
|
||||
return this._columnsController.value ?? 1;
|
||||
}
|
||||
|
||||
public setConfig(config: LovelaceViewConfig): void {
|
||||
this._config = config;
|
||||
this._attachMediaQueriesListeners();
|
||||
}
|
||||
|
||||
private _sectionConfigKeys = new WeakMap<HuiSection, string>();
|
||||
@@ -103,12 +134,35 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
this._computeSectionsCount();
|
||||
};
|
||||
|
||||
private _attachMediaQueriesListeners() {
|
||||
this._detachMediaQueriesListeners();
|
||||
if (!this._config?.experimental_breakpoints) return;
|
||||
const breakpoints = this._config?.column_breakpoints ?? DEFAULT_BREAKPOINTS;
|
||||
const maxColumns = this._config?.max_columns ?? DEFAULT_MAX_COLUMNS;
|
||||
const mediaQueries = buildMediaQueries(breakpoints);
|
||||
this._listeners = mediaQueries.map((mediaQuery, index) =>
|
||||
listenMediaQuery(mediaQuery, (matches) => {
|
||||
if (matches) {
|
||||
const columns = Object.values(breakpoints)[index];
|
||||
this._breakpointsColumns = Math.min(maxColumns, columns);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _detachMediaQueriesListeners() {
|
||||
while (this._listeners.length) {
|
||||
this._listeners.pop()!();
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this.addEventListener(
|
||||
"section-visibility-changed",
|
||||
this._sectionVisibilityChanged
|
||||
);
|
||||
this._attachMediaQueriesListeners();
|
||||
}
|
||||
|
||||
disconnectedCallback(): void {
|
||||
@@ -117,6 +171,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
"section-visibility-changed",
|
||||
this._sectionVisibilityChanged
|
||||
);
|
||||
this._detachMediaQueriesListeners();
|
||||
}
|
||||
|
||||
willUpdate(changedProperties: PropertyValues<typeof this>): void {
|
||||
@@ -133,7 +188,9 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
this._sectionColumnCount + (this.lovelace?.editMode ? 1 : 0);
|
||||
const editMode = this.lovelace.editMode;
|
||||
|
||||
const maxColumnCount = this._columnsController.value ?? 1;
|
||||
const maxColumnCount = this._config?.experimental_breakpoints
|
||||
? this._breakpointsColumns
|
||||
: this._sizeColumns;
|
||||
|
||||
return html`
|
||||
<hui-view-badges
|
||||
@@ -324,9 +381,9 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
:host {
|
||||
--row-height: var(--ha-view-sections-row-height, 56px);
|
||||
--row-gap: var(--ha-view-sections-row-gap, 8px);
|
||||
--column-gap: var(--ha-view-sections-column-gap, 32px);
|
||||
--column-max-width: var(--ha-view-sections-column-max-width, 500px);
|
||||
--column-gap: var(--ha-view-sections-column-gap, 24px);
|
||||
--column-min-width: var(--ha-view-sections-column-min-width, 320px);
|
||||
--column-max-width: var(--ha-view-sections-column-max-width, 500px);
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@@ -1797,13 +1797,10 @@
|
||||
"errors": {
|
||||
"config": {
|
||||
"no_type_provided": "No type provided.",
|
||||
"invalid_configuration": "Invalid configuration",
|
||||
"error_details": "The configuration contains the following errors:",
|
||||
"error_detected": "Configuration errors detected",
|
||||
"editor_not_available": "No visual editor available for type ''{type}''.",
|
||||
"editor_not_supported": "Visual editor not supported",
|
||||
"editor_not_supported_details": "The visual editor is not supported for type ''{type}''.",
|
||||
"warning_details": "The configuration contains the following warnings:",
|
||||
"edit_in_yaml_supported": "You can still edit the configuration in YAML.",
|
||||
"editor_not_supported": "Visual editor is not supported for this configuration",
|
||||
"edit_in_yaml_supported": "You can still edit your config in YAML.",
|
||||
"key_missing": "Required key ''{key}'' is missing.",
|
||||
"key_not_expected": "Key ''{key}'' is not expected or not supported by the visual editor.",
|
||||
"key_wrong_type": "The provided value for ''{key}'' is not supported by the visual editor. We support ({type_correct}) but received ({type_wrong}).",
|
||||
@@ -4898,8 +4895,6 @@
|
||||
"zwave_js_device_database": "Z-Wave JS Device Database",
|
||||
"battery_device_notice": "Battery devices must be awake to update their config. Please refer to your device manual for instructions on how to wake the device.",
|
||||
"parameter_is_read_only": "This parameter is read-only.",
|
||||
"between_min_max": "Between {min} and {max}",
|
||||
"error_not_in_range": "Value must be between {min} and {max}",
|
||||
"error_device_not_found": "Device not found",
|
||||
"set_param_accepted": "The parameter has been updated.",
|
||||
"set_param_queued": "The parameter change has been queued, and will be updated when the device wakes up.",
|
||||
|
204
yarn.lock
204
yarn.lock
@@ -3889,13 +3889,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rtsao/scc@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "@rtsao/scc@npm:1.1.0"
|
||||
checksum: 10/17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sinonjs/commons@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@sinonjs/commons@npm:2.0.0"
|
||||
@@ -5634,7 +5627,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-includes@npm:^3.1.8":
|
||||
"array-includes@npm:^3.1.7":
|
||||
version: 3.1.8
|
||||
resolution: "array-includes@npm:3.1.8"
|
||||
dependencies:
|
||||
@@ -5662,7 +5655,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array.prototype.findlastindex@npm:^1.2.5":
|
||||
"array.prototype.find@npm:^2.2.2":
|
||||
version: 2.2.3
|
||||
resolution: "array.prototype.find@npm:2.2.3"
|
||||
dependencies:
|
||||
call-bind: "npm:^1.0.7"
|
||||
define-properties: "npm:^1.2.1"
|
||||
es-abstract: "npm:^1.23.2"
|
||||
es-object-atoms: "npm:^1.0.0"
|
||||
es-shim-unscopables: "npm:^1.0.2"
|
||||
checksum: 10/8ee81d37de9c8574a94f4773dffa40b4d200deca11b00f7176dcb328a9ddcf75fef117c97ccce1ab8345b7184c107553156908e7dcaf0d42f1a395a04bbe803e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array.prototype.findlastindex@npm:^1.2.3":
|
||||
version: 1.2.5
|
||||
resolution: "array.prototype.findlastindex@npm:1.2.5"
|
||||
dependencies:
|
||||
@@ -6923,6 +6929,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"default-gateway@npm:^6.0.3":
|
||||
version: 6.0.3
|
||||
resolution: "default-gateway@npm:6.0.3"
|
||||
dependencies:
|
||||
execa: "npm:^5.0.0"
|
||||
checksum: 10/126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"defaults@npm:^1.0.3, defaults@npm:^1.0.4":
|
||||
version: 1.0.4
|
||||
resolution: "defaults@npm:1.0.4"
|
||||
@@ -7506,10 +7521,11 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-import-resolver-webpack@npm:0.13.9":
|
||||
version: 0.13.9
|
||||
resolution: "eslint-import-resolver-webpack@npm:0.13.9"
|
||||
"eslint-import-resolver-webpack@npm:0.13.8":
|
||||
version: 0.13.8
|
||||
resolution: "eslint-import-resolver-webpack@npm:0.13.8"
|
||||
dependencies:
|
||||
array.prototype.find: "npm:^2.2.2"
|
||||
debug: "npm:^3.2.7"
|
||||
enhanced-resolve: "npm:^0.9.1"
|
||||
find-root: "npm:^1.1.0"
|
||||
@@ -7523,47 +7539,46 @@ __metadata:
|
||||
peerDependencies:
|
||||
eslint-plugin-import: ">=1.4.0"
|
||||
webpack: ">=1.11.0"
|
||||
checksum: 10/d359fa2cfe4a19b9a9c5e1d973e2fdc2e95e0374d8a43db1d7b31831fda7ebc8ae1937e8237c1125790d08380fe817a7256d92d7d7dfda128eea83454229a003
|
||||
checksum: 10/b4acdc76ea156d7b22639250c3bc92d88fe1c581e7e8320115319437002a770944f9232807660df9c28a12677450c4954f5d629761bfd04092084c2493a77aaf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-module-utils@npm:^2.9.0":
|
||||
version: 2.11.0
|
||||
resolution: "eslint-module-utils@npm:2.11.0"
|
||||
"eslint-module-utils@npm:^2.8.0":
|
||||
version: 2.8.1
|
||||
resolution: "eslint-module-utils@npm:2.8.1"
|
||||
dependencies:
|
||||
debug: "npm:^3.2.7"
|
||||
peerDependenciesMeta:
|
||||
eslint:
|
||||
optional: true
|
||||
checksum: 10/1ba42cf48c5f9ec3b76dfa42c16f1c24c10508313689425c05ccb1d0eaa34bdc5c5b9c0c033cd402e9c429666bd3eb8c6d0c66565b0c00949fae743ad3643c95
|
||||
checksum: 10/3e7892c0a984c963632da56b30ccf8254c29b535467138f91086c2ecdb2ebd10e2be61b54e553f30e5abf1d14d47a7baa0dac890e3a658fd3cd07dca63afbe6d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-import@npm:2.30.0":
|
||||
version: 2.30.0
|
||||
resolution: "eslint-plugin-import@npm:2.30.0"
|
||||
"eslint-plugin-import@npm:2.29.1":
|
||||
version: 2.29.1
|
||||
resolution: "eslint-plugin-import@npm:2.29.1"
|
||||
dependencies:
|
||||
"@rtsao/scc": "npm:^1.1.0"
|
||||
array-includes: "npm:^3.1.8"
|
||||
array.prototype.findlastindex: "npm:^1.2.5"
|
||||
array-includes: "npm:^3.1.7"
|
||||
array.prototype.findlastindex: "npm:^1.2.3"
|
||||
array.prototype.flat: "npm:^1.3.2"
|
||||
array.prototype.flatmap: "npm:^1.3.2"
|
||||
debug: "npm:^3.2.7"
|
||||
doctrine: "npm:^2.1.0"
|
||||
eslint-import-resolver-node: "npm:^0.3.9"
|
||||
eslint-module-utils: "npm:^2.9.0"
|
||||
hasown: "npm:^2.0.2"
|
||||
is-core-module: "npm:^2.15.1"
|
||||
eslint-module-utils: "npm:^2.8.0"
|
||||
hasown: "npm:^2.0.0"
|
||||
is-core-module: "npm:^2.13.1"
|
||||
is-glob: "npm:^4.0.3"
|
||||
minimatch: "npm:^3.1.2"
|
||||
object.fromentries: "npm:^2.0.8"
|
||||
object.groupby: "npm:^1.0.3"
|
||||
object.values: "npm:^1.2.0"
|
||||
object.fromentries: "npm:^2.0.7"
|
||||
object.groupby: "npm:^1.0.1"
|
||||
object.values: "npm:^1.1.7"
|
||||
semver: "npm:^6.3.1"
|
||||
tsconfig-paths: "npm:^3.15.0"
|
||||
peerDependencies:
|
||||
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
||||
checksum: 10/a5f85dfe76e27286c28a01d137769726ce3f758bcc03aa6b6f9e18700a40a08f57239f82e07efcab763c4b03a02d425edcc29fbecf40aad0124286978c6bc63c
|
||||
checksum: 10/5865f05c38552145423c535326ec9a7113ab2305c7614c8b896ff905cfabc859c8805cac21e979c9f6f742afa333e6f62f812eabf891a7e8f5f0b853a32593c1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7807,6 +7822,23 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"execa@npm:^5.0.0":
|
||||
version: 5.1.1
|
||||
resolution: "execa@npm:5.1.1"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.3"
|
||||
get-stream: "npm:^6.0.0"
|
||||
human-signals: "npm:^2.1.0"
|
||||
is-stream: "npm:^2.0.0"
|
||||
merge-stream: "npm:^2.0.0"
|
||||
npm-run-path: "npm:^4.0.1"
|
||||
onetime: "npm:^5.1.2"
|
||||
signal-exit: "npm:^3.0.3"
|
||||
strip-final-newline: "npm:^2.0.0"
|
||||
checksum: 10/8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"execa@npm:~8.0.1":
|
||||
version: 8.0.1
|
||||
resolution: "execa@npm:8.0.1"
|
||||
@@ -7847,7 +7879,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"express@npm:^4.19.2":
|
||||
"express@npm:^4.17.3":
|
||||
version: 4.19.2
|
||||
resolution: "express@npm:4.19.2"
|
||||
dependencies:
|
||||
@@ -9011,8 +9043,8 @@ __metadata:
|
||||
eslint-config-airbnb-base: "npm:15.0.0"
|
||||
eslint-config-airbnb-typescript: "npm:18.0.0"
|
||||
eslint-config-prettier: "npm:9.1.0"
|
||||
eslint-import-resolver-webpack: "npm:0.13.9"
|
||||
eslint-plugin-import: "npm:2.30.0"
|
||||
eslint-import-resolver-webpack: "npm:0.13.8"
|
||||
eslint-plugin-import: "npm:2.29.1"
|
||||
eslint-plugin-lit: "npm:1.14.0"
|
||||
eslint-plugin-lit-a11y: "npm:4.1.4"
|
||||
eslint-plugin-unused-imports: "npm:4.1.3"
|
||||
@@ -9046,7 +9078,7 @@ __metadata:
|
||||
luxon: "npm:3.5.0"
|
||||
magic-string: "npm:0.30.11"
|
||||
map-stream: "npm:0.0.7"
|
||||
marked: "npm:14.1.1"
|
||||
marked: "npm:14.1.0"
|
||||
memoize-one: "npm:6.0.0"
|
||||
mocha: "npm:10.5.0"
|
||||
node-vibrant: "npm:3.2.1-alpha.1"
|
||||
@@ -9066,7 +9098,7 @@ __metadata:
|
||||
rrule: "npm:2.8.1"
|
||||
serve-handler: "npm:6.1.5"
|
||||
sinon: "npm:18.0.0"
|
||||
sortablejs: "npm:1.15.3"
|
||||
sortablejs: "npm:1.15.2"
|
||||
stacktrace-js: "npm:2.0.2"
|
||||
superstruct: "npm:2.0.2"
|
||||
systemjs: "npm:6.15.1"
|
||||
@@ -9086,7 +9118,7 @@ __metadata:
|
||||
vue2-daterange-picker: "npm:0.6.8"
|
||||
webpack: "npm:5.94.0"
|
||||
webpack-cli: "npm:5.1.4"
|
||||
webpack-dev-server: "npm:5.1.0"
|
||||
webpack-dev-server: "npm:5.0.4"
|
||||
webpack-manifest-plugin: "npm:5.0.0"
|
||||
webpack-stats-plugin: "npm:1.1.3"
|
||||
webpackbar: "npm:6.0.1"
|
||||
@@ -9289,6 +9321,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"human-signals@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "human-signals@npm:2.1.0"
|
||||
checksum: 10/df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"human-signals@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "human-signals@npm:5.0.0"
|
||||
@@ -9597,7 +9636,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1, is-core-module@npm:^2.15.1":
|
||||
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1":
|
||||
version: 2.15.1
|
||||
resolution: "is-core-module@npm:2.15.1"
|
||||
dependencies:
|
||||
@@ -10819,12 +10858,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"marked@npm:14.1.1":
|
||||
version: 14.1.1
|
||||
resolution: "marked@npm:14.1.1"
|
||||
"marked@npm:14.1.0":
|
||||
version: 14.1.0
|
||||
resolution: "marked@npm:14.1.0"
|
||||
bin:
|
||||
marked: bin/marked.js
|
||||
checksum: 10/43851120b9292102b490999cdbd8148dc814992af17fde1eabca68efe841e56951c0d3b0f2fd11f9a2b746f48e16a1959f455e0694677df1091d06fc73b12fc3
|
||||
checksum: 10/1a930dd87a3994cc4fcc72c4668c548429d0e6363b8f7660193c106fa1cadcde5c813cfc3fe4be42b9f18b3652ba73469fb6c718215b0dbf8ddb9de2d1f5ab38
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10956,6 +10995,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mimic-fn@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "mimic-fn@npm:2.1.0"
|
||||
checksum: 10/d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mimic-fn@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "mimic-fn@npm:4.0.0"
|
||||
@@ -11398,6 +11444,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"npm-run-path@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "npm-run-path@npm:4.0.1"
|
||||
dependencies:
|
||||
path-key: "npm:^3.0.0"
|
||||
checksum: 10/5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"npm-run-path@npm:^5.1.0":
|
||||
version: 5.3.0
|
||||
resolution: "npm-run-path@npm:5.3.0"
|
||||
@@ -11463,7 +11518,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object.fromentries@npm:^2.0.8":
|
||||
"object.fromentries@npm:^2.0.7":
|
||||
version: 2.0.8
|
||||
resolution: "object.fromentries@npm:2.0.8"
|
||||
dependencies:
|
||||
@@ -11475,7 +11530,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object.groupby@npm:^1.0.3":
|
||||
"object.groupby@npm:^1.0.1":
|
||||
version: 1.0.3
|
||||
resolution: "object.groupby@npm:1.0.3"
|
||||
dependencies:
|
||||
@@ -11495,7 +11550,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"object.values@npm:^1.2.0":
|
||||
"object.values@npm:^1.1.7":
|
||||
version: 1.2.0
|
||||
resolution: "object.values@npm:1.2.0"
|
||||
dependencies:
|
||||
@@ -11545,6 +11600,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"onetime@npm:^5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "onetime@npm:5.1.2"
|
||||
dependencies:
|
||||
mimic-fn: "npm:^2.1.0"
|
||||
checksum: 10/e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"onetime@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "onetime@npm:6.0.0"
|
||||
@@ -11870,7 +11934,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-key@npm:^3.1.0":
|
||||
"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
|
||||
version: 3.1.1
|
||||
resolution: "path-key@npm:3.1.1"
|
||||
checksum: 10/55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020
|
||||
@@ -13099,6 +13163,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"signal-exit@npm:^3.0.3":
|
||||
version: 3.0.7
|
||||
resolution: "signal-exit@npm:3.0.7"
|
||||
checksum: 10/a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "signal-exit@npm:4.1.0"
|
||||
@@ -13200,17 +13271,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sortablejs@npm:1.15.3":
|
||||
version: 1.15.3
|
||||
resolution: "sortablejs@npm:1.15.3"
|
||||
checksum: 10/85d39a172ef47adedf273afa65daa8aefcbaafd43a5b5c480d8637add93033f5784da697d0d3545d9bb6e11fd71f1847f307ee26be452942f3785a683fd44bb5
|
||||
"sortablejs@npm:1.15.2":
|
||||
version: 1.15.2
|
||||
resolution: "sortablejs@npm:1.15.2"
|
||||
checksum: 10/d149dd04bb05904ea20ca477d97cdfbbbd46edf7ede8c80958f2ad881dd6d7b1633cce31665992b341e0ea01fc7ef9d7571ccb7eb995baf01f9418b44e935eac
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sortablejs@patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch":
|
||||
version: 1.15.3
|
||||
resolution: "sortablejs@patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch::version=1.15.3&hash=fba0ad"
|
||||
checksum: 10/249f4cfd2b4a811f4e1505b25d4d67a97521afabdabd2f5482f985da20785d995c2899d442ad79075c7ba547e477aef81f09b0028f12d1de468cbca4f2b8c043
|
||||
"sortablejs@patch:sortablejs@npm%3A1.15.2#~/.yarn/patches/sortablejs-npm-1.15.2-73347ae85a.patch":
|
||||
version: 1.15.2
|
||||
resolution: "sortablejs@patch:sortablejs@npm%3A1.15.2#~/.yarn/patches/sortablejs-npm-1.15.2-73347ae85a.patch::version=1.15.2&hash=1591ab"
|
||||
checksum: 10/d44399e9ca660157c76b13705eaa26191f71c4bd025e2d47b9f7e50a8f9bdb7deaaa2783a8032e55f39627fa4007042bcfd62cb4bbeb2931f6a5d6ee06047e2e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -13578,6 +13649,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-final-newline@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "strip-final-newline@npm:2.0.0"
|
||||
checksum: 10/69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-final-newline@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "strip-final-newline@npm:3.0.0"
|
||||
@@ -14783,7 +14861,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webpack-dev-middleware@npm:^7.4.2":
|
||||
"webpack-dev-middleware@npm:^7.1.0":
|
||||
version: 7.4.2
|
||||
resolution: "webpack-dev-middleware@npm:7.4.2"
|
||||
dependencies:
|
||||
@@ -14802,9 +14880,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webpack-dev-server@npm:5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "webpack-dev-server@npm:5.1.0"
|
||||
"webpack-dev-server@npm:5.0.4":
|
||||
version: 5.0.4
|
||||
resolution: "webpack-dev-server@npm:5.0.4"
|
||||
dependencies:
|
||||
"@types/bonjour": "npm:^3.5.13"
|
||||
"@types/connect-history-api-fallback": "npm:^1.5.4"
|
||||
@@ -14819,7 +14897,8 @@ __metadata:
|
||||
colorette: "npm:^2.0.10"
|
||||
compression: "npm:^1.7.4"
|
||||
connect-history-api-fallback: "npm:^2.0.0"
|
||||
express: "npm:^4.19.2"
|
||||
default-gateway: "npm:^6.0.3"
|
||||
express: "npm:^4.17.3"
|
||||
graceful-fs: "npm:^4.2.6"
|
||||
html-entities: "npm:^2.4.0"
|
||||
http-proxy-middleware: "npm:^2.0.3"
|
||||
@@ -14827,13 +14906,14 @@ __metadata:
|
||||
launch-editor: "npm:^2.6.1"
|
||||
open: "npm:^10.0.3"
|
||||
p-retry: "npm:^6.2.0"
|
||||
rimraf: "npm:^5.0.5"
|
||||
schema-utils: "npm:^4.2.0"
|
||||
selfsigned: "npm:^2.4.1"
|
||||
serve-index: "npm:^1.9.1"
|
||||
sockjs: "npm:^0.3.24"
|
||||
spdy: "npm:^4.0.2"
|
||||
webpack-dev-middleware: "npm:^7.4.2"
|
||||
ws: "npm:^8.18.0"
|
||||
webpack-dev-middleware: "npm:^7.1.0"
|
||||
ws: "npm:^8.16.0"
|
||||
peerDependencies:
|
||||
webpack: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
@@ -14843,7 +14923,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
webpack-dev-server: bin/webpack-dev-server.js
|
||||
checksum: 10/f23255681cc5e2c2709b23ca7b2185aeed83b1c9912657d4512eda8685625a46d7a103a92446494a55fe2afdfab936f9bd4f037d20b52f7fdfff303e7e7199c7
|
||||
checksum: 10/3896866abf15a1d5cc31ab4fc9c36aacf3431356837ad6debe25cde29289a70c58dcbe40914bbb275ff455463d37437532093d0e8d7744e7643ce1364491fdb4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -15396,7 +15476,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.18.0":
|
||||
"ws@npm:^8.16.0":
|
||||
version: 8.18.0
|
||||
resolution: "ws@npm:8.18.0"
|
||||
peerDependencies:
|
||||
|
Reference in New Issue
Block a user