mirror of
https://github.com/home-assistant/frontend.git
synced 2025-09-29 14:59:38 +00:00
Compare commits
18 Commits
20250203.0
...
fix_statis
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4fa1b60cb1 | ||
![]() |
653aeae3d8 | ||
![]() |
0aea6141ad | ||
![]() |
5243c1d871 | ||
![]() |
6ac6d9c6eb | ||
![]() |
6ba0071296 | ||
![]() |
fef5dc4232 | ||
![]() |
ce58962dbb | ||
![]() |
9fb1e1d2ed | ||
![]() |
a29544c1e6 | ||
![]() |
b2b71edd04 | ||
![]() |
028472fc7b | ||
![]() |
b056ce228b | ||
![]() |
0cd4256c0e | ||
![]() |
e274c5b23f | ||
![]() |
ea57846465 | ||
![]() |
3f2e2bc659 | ||
![]() |
e3f2f66206 |
@@ -11,6 +11,9 @@
|
||||
"DEV_CONTAINER": "1",
|
||||
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
|
||||
},
|
||||
"remoteEnv": {
|
||||
"NODE_OPTIONS": "--max_old_space_size=8192"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
|
@@ -183,8 +183,8 @@
|
||||
"@types/tar": "6.1.13",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "8.21.0",
|
||||
"@typescript-eslint/parser": "8.21.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.22.0",
|
||||
"@typescript-eslint/parser": "8.22.0",
|
||||
"@vitest/coverage-v8": "3.0.4",
|
||||
"babel-loader": "9.2.1",
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import memoizeOne from "memoize-one";
|
||||
import { theme2hex } from "./convert-color";
|
||||
|
||||
export const COLORS = [
|
||||
@@ -74,3 +75,12 @@ export function getGraphColorByIndex(
|
||||
getColorByIndex(index);
|
||||
return theme2hex(themeColor);
|
||||
}
|
||||
|
||||
export const getAllGraphColors = memoizeOne(
|
||||
(style: CSSStyleDeclaration) =>
|
||||
COLORS.map((_color, index) => getGraphColorByIndex(index, style)),
|
||||
(newArgs: [CSSStyleDeclaration], lastArgs: [CSSStyleDeclaration]) =>
|
||||
// this is not ideal, but we need to memoize the colors
|
||||
newArgs[0].getPropertyValue("--graph-color-1") ===
|
||||
lastArgs[0].getPropertyValue("--graph-color-1")
|
||||
);
|
||||
|
@@ -20,6 +20,7 @@ import type { ECOption } from "../../resources/echarts";
|
||||
import { listenMediaQuery } from "../../common/dom/media_query";
|
||||
import type { Themes } from "../../data/ws-themes";
|
||||
import { themesContext } from "../../data/context";
|
||||
import { getAllGraphColors } from "../../common/color/colors";
|
||||
|
||||
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
|
||||
|
||||
@@ -183,10 +184,9 @@ export class HaChartBase extends LitElement {
|
||||
}
|
||||
const echarts = (await import("../../resources/echarts")).default;
|
||||
|
||||
this.chart = echarts.init(
|
||||
container,
|
||||
this._themes.darkMode ? "dark" : "light"
|
||||
);
|
||||
echarts.registerTheme("custom", this._createTheme());
|
||||
|
||||
this.chart = echarts.init(container, "custom");
|
||||
this.chart.on("legendselectchanged", (params: any) => {
|
||||
if (this.externalHidden) {
|
||||
const isSelected = params.selected[params.name];
|
||||
@@ -237,24 +237,14 @@ export class HaChartBase extends LitElement {
|
||||
}
|
||||
|
||||
private _createOptions(): ECOption {
|
||||
const darkMode = this._themes.darkMode ?? false;
|
||||
|
||||
const options = {
|
||||
backgroundColor: "transparent",
|
||||
animation: !this._reducedMotion,
|
||||
darkMode,
|
||||
darkMode: this._themes.darkMode ?? false,
|
||||
aria: {
|
||||
show: true,
|
||||
},
|
||||
dataZoom: this._getDataZoomConfig(),
|
||||
...this.options,
|
||||
legend: this.options?.legend
|
||||
? {
|
||||
// we should create our own theme but this is a quick fix for now
|
||||
inactiveColor: darkMode ? "#444" : "#ccc",
|
||||
...this.options.legend,
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
|
||||
const isMobile = window.matchMedia(
|
||||
@@ -274,6 +264,181 @@ export class HaChartBase extends LitElement {
|
||||
return options;
|
||||
}
|
||||
|
||||
private _createTheme() {
|
||||
const style = getComputedStyle(this);
|
||||
return {
|
||||
color: getAllGraphColors(style),
|
||||
backgroundColor: "transparent",
|
||||
textStyle: {
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
title: {
|
||||
textStyle: {
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
subtextStyle: {
|
||||
color: style.getPropertyValue("--secondary-text-color"),
|
||||
},
|
||||
},
|
||||
line: {
|
||||
lineStyle: {
|
||||
width: 1.5,
|
||||
},
|
||||
symbolSize: 1,
|
||||
symbol: "circle",
|
||||
smooth: false,
|
||||
},
|
||||
bar: {
|
||||
itemStyle: {
|
||||
barBorderWidth: 1.5,
|
||||
},
|
||||
},
|
||||
categoryAxis: {
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
areaStyle: {
|
||||
color: [
|
||||
style.getPropertyValue("--divider-color") + "3F",
|
||||
style.getPropertyValue("--divider-color") + "7F",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
valueAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
areaStyle: {
|
||||
color: [
|
||||
style.getPropertyValue("--divider-color") + "3F",
|
||||
style.getPropertyValue("--divider-color") + "7F",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
logAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
areaStyle: {
|
||||
color: [
|
||||
style.getPropertyValue("--divider-color") + "3F",
|
||||
style.getPropertyValue("--divider-color") + "7F",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
timeAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
areaStyle: {
|
||||
color: [
|
||||
style.getPropertyValue("--divider-color") + "3F",
|
||||
style.getPropertyValue("--divider-color") + "7F",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
textStyle: {
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
inactiveColor: style.getPropertyValue("--disabled-text-color"),
|
||||
},
|
||||
tooltip: {
|
||||
axisPointer: {
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
crossStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
},
|
||||
},
|
||||
timeline: {},
|
||||
};
|
||||
}
|
||||
|
||||
private _getDefaultHeight() {
|
||||
return Math.max(this.clientWidth / 2, 400);
|
||||
}
|
||||
|
@@ -158,9 +158,6 @@ export class StateHistoryChartLine extends LitElement {
|
||||
) {
|
||||
const dayDifference = differenceInDays(this.endTime, this.startTime);
|
||||
const rtl = computeRTL(this.hass);
|
||||
const splitLineStyle = this.hass.themes?.darkMode
|
||||
? { opacity: 0.15 }
|
||||
: {};
|
||||
this._chartOptions = {
|
||||
xAxis: {
|
||||
type: "time",
|
||||
@@ -176,7 +173,6 @@ export class StateHistoryChartLine extends LitElement {
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: splitLineStyle,
|
||||
},
|
||||
minInterval:
|
||||
dayDifference >= 89 // quarter
|
||||
@@ -196,9 +192,8 @@ export class StateHistoryChartLine extends LitElement {
|
||||
nameTextStyle: {
|
||||
align: "left",
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: splitLineStyle,
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
margin: 5,
|
||||
|
@@ -197,9 +197,12 @@ export class StateHistoryChartTimeline extends LitElement {
|
||||
max: this.endTime,
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
opacity: 0.4,
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: getTimeAxisLabelConfig(
|
||||
this.hass.locale,
|
||||
|
@@ -135,7 +135,7 @@ export class StateHistoryCharts extends LitElement {
|
||||
return html``;
|
||||
}
|
||||
if (!Array.isArray(item)) {
|
||||
return html`<div class="entry-container">
|
||||
return html`<div class="entry-container line">
|
||||
<state-history-chart-line
|
||||
.hass=${this.hass}
|
||||
.unit=${item.unit}
|
||||
@@ -299,6 +299,9 @@ export class StateHistoryCharts extends LitElement {
|
||||
|
||||
.entry-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.entry-container.line {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
@@ -56,6 +56,8 @@ export class StatisticsChart extends LitElement {
|
||||
|
||||
@property() public unit?: string;
|
||||
|
||||
@property({ attribute: false }) public startTime?: Date;
|
||||
|
||||
@property({ attribute: false }) public endTime?: Date;
|
||||
|
||||
@property({ attribute: false, type: Array })
|
||||
@@ -124,6 +126,8 @@ export class StatisticsChart extends LitElement {
|
||||
changedProps.has("fitYData") ||
|
||||
changedProps.has("logarithmicScale") ||
|
||||
changedProps.has("hideLegend") ||
|
||||
changedProps.has("startTime") ||
|
||||
changedProps.has("endTime") ||
|
||||
changedProps.has("_legendData")
|
||||
) {
|
||||
this._createOptions();
|
||||
@@ -218,6 +222,8 @@ export class StatisticsChart extends LitElement {
|
||||
this.hass.config,
|
||||
dayDifference
|
||||
),
|
||||
min: this.startTime,
|
||||
max: this.endTime,
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
@@ -449,7 +455,11 @@ export class StatisticsChart extends LitElement {
|
||||
borderWidth: 1.5,
|
||||
}
|
||||
: undefined,
|
||||
color: band ? color + "3F" : color + "7F",
|
||||
color: band
|
||||
? color + "3F"
|
||||
: this.chartType === "bar"
|
||||
? color + "7F"
|
||||
: color,
|
||||
};
|
||||
if (band && this.chartType === "line") {
|
||||
series.stack = `band-${statistic_id}`;
|
||||
|
@@ -106,6 +106,7 @@ export class HaConfigApplicationCredentials extends LitElement {
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
label: localize("ui.panel.config.generic.headers.actions"),
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
hideable: false,
|
||||
|
@@ -378,8 +378,9 @@ class HaBackupConfigData extends LitElement {
|
||||
}
|
||||
@media all and (max-width: 450px) {
|
||||
ha-md-select {
|
||||
min-width: 160px;
|
||||
width: 160px;
|
||||
min-width: 140px;
|
||||
width: 140px;
|
||||
--md-filled-field-content-space: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@@ -403,11 +403,11 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
backup_create: html`<a
|
||||
href=${documentationUrl(
|
||||
this.hass,
|
||||
"/integrations/backup#example-backing-up-every-night-at-300-am"
|
||||
"/integrations/backup/#action-backupcreate_automatic"
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>backup.create</a
|
||||
>backup.create_automatic</a
|
||||
>`,
|
||||
})}</ha-tip
|
||||
>
|
||||
@@ -545,6 +545,12 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
ha-md-select,
|
||||
ha-time-input {
|
||||
min-width: 160px;
|
||||
width: 160px;
|
||||
--md-filled-field-content-space: 0;
|
||||
}
|
||||
ha-time-input {
|
||||
min-width: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
ha-md-textfield#value {
|
||||
@@ -553,6 +559,16 @@ class HaBackupConfigSchedule extends LitElement {
|
||||
ha-md-select#type {
|
||||
min-width: 100px;
|
||||
}
|
||||
@media all and (max-width: 450px) {
|
||||
ha-md-textfield#value {
|
||||
min-width: 60px;
|
||||
margin: 0 -8px;
|
||||
}
|
||||
ha-md-select#type {
|
||||
min-width: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
ha-expansion-panel {
|
||||
--expansion-panel-summary-padding: 0 16px;
|
||||
--expansion-panel-content-padding: 0 16px;
|
||||
|
@@ -141,7 +141,10 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
};
|
||||
|
||||
private _columns = memoizeOne(
|
||||
(localize: LocalizeFunc): DataTableColumnContainer<BackupRow> => ({
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
maxDisplayedAgents: number
|
||||
): DataTableColumnContainer<BackupRow> => ({
|
||||
name: {
|
||||
title: localize("ui.panel.config.backup.name"),
|
||||
main: true,
|
||||
@@ -172,54 +175,75 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
locations: {
|
||||
title: localize("ui.panel.config.backup.locations"),
|
||||
showNarrow: true,
|
||||
minWidth: "60px",
|
||||
template: (backup) => html`
|
||||
<div style="display: flex; gap: 4px;">
|
||||
${(backup.agent_ids || []).map((agentId) => {
|
||||
const name = computeBackupAgentName(
|
||||
this.hass.localize,
|
||||
agentId,
|
||||
this.agents
|
||||
);
|
||||
if (isLocalAgent(agentId)) {
|
||||
// 24 icon size, 4 gap, 16 left and right padding
|
||||
minWidth: `${maxDisplayedAgents * 24 + (maxDisplayedAgents - 1) * 4 + 32}px`,
|
||||
template: (backup) => {
|
||||
const agentIds = backup.agent_ids;
|
||||
const displayedAgentIds =
|
||||
agentIds.length > maxDisplayedAgents
|
||||
? [...agentIds].splice(0, maxDisplayedAgents - 1)
|
||||
: agentIds;
|
||||
const agentsMore = Math.max(
|
||||
agentIds.length - displayedAgentIds.length,
|
||||
0
|
||||
);
|
||||
return html`
|
||||
<div style="display: flex; gap: 4px;">
|
||||
${displayedAgentIds.map((agentId) => {
|
||||
const name = computeBackupAgentName(
|
||||
this.hass.localize,
|
||||
agentId,
|
||||
this.agents
|
||||
);
|
||||
if (isLocalAgent(agentId)) {
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiHarddisk}
|
||||
title=${name}
|
||||
style="flex-shrink: 0;"
|
||||
></ha-svg-icon>
|
||||
`;
|
||||
}
|
||||
if (isNetworkMountAgent(agentId)) {
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiNas}
|
||||
title=${name}
|
||||
style="flex-shrink: 0;"
|
||||
></ha-svg-icon>
|
||||
`;
|
||||
}
|
||||
const domain = computeDomain(agentId);
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiHarddisk}
|
||||
<img
|
||||
title=${name}
|
||||
.src=${brandsUrl({
|
||||
domain,
|
||||
type: "icon",
|
||||
useFallback: true,
|
||||
darkOptimized: this.hass.themes?.darkMode,
|
||||
})}
|
||||
height="24"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
alt=${name}
|
||||
slot="graphic"
|
||||
style="flex-shrink: 0;"
|
||||
></ha-svg-icon>
|
||||
/>
|
||||
`;
|
||||
}
|
||||
if (isNetworkMountAgent(agentId)) {
|
||||
return html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiNas}
|
||||
title=${name}
|
||||
style="flex-shrink: 0;"
|
||||
></ha-svg-icon>
|
||||
`;
|
||||
}
|
||||
const domain = computeDomain(agentId);
|
||||
return html`
|
||||
<img
|
||||
title=${name}
|
||||
.src=${brandsUrl({
|
||||
domain,
|
||||
type: "icon",
|
||||
useFallback: true,
|
||||
darkOptimized: this.hass.themes?.darkMode,
|
||||
})}
|
||||
height="24"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
alt=${name}
|
||||
slot="graphic"
|
||||
style="flex-shrink: 0;"
|
||||
/>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
`,
|
||||
})}
|
||||
${agentsMore
|
||||
? html`
|
||||
<span
|
||||
style="display: flex; align-items: center; font-size: 14px;"
|
||||
>
|
||||
+${agentsMore}
|
||||
</span>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
@@ -293,20 +317,31 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
return filteredBackups.map((backup) => {
|
||||
const type = backup.with_automatic_settings ? "automatic" : "manual";
|
||||
const agentIds = Object.keys(backup.agents);
|
||||
return {
|
||||
...backup,
|
||||
size: computeBackupSize(backup),
|
||||
agent_ids: Object.keys(backup.agents).sort(compareAgents),
|
||||
agent_ids: agentIds.sort(compareAgents),
|
||||
formatted_type: localize(`ui.panel.config.backup.type.${type}`),
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
private _maxAgents = memoizeOne((data: BackupRow[]): number =>
|
||||
Math.max(...data.map((row) => row.agent_ids.length))
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const backupInProgress =
|
||||
"state" in this.manager && this.manager.state === "in_progress";
|
||||
|
||||
const data = this._data(this.backups, this._filters, this.hass.localize);
|
||||
const maxDisplayedAgents = Math.min(
|
||||
this._maxAgents(data),
|
||||
this.narrow ? 3 : 5
|
||||
);
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage-data-table
|
||||
has-fab
|
||||
@@ -343,8 +378,8 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
@selection-changed=${this._handleSelectionChanged}
|
||||
.route=${this.route}
|
||||
@row-click=${this._showBackupDetails}
|
||||
.columns=${this._columns(this.hass.localize)}
|
||||
.data=${this._data(this.backups, this._filters, this.hass.localize)}
|
||||
.columns=${this._columns(this.hass.localize, maxDisplayedAgents)}
|
||||
.data=${data}
|
||||
.noDataText=${this.hass.localize("ui.panel.config.backup.no_backups")}
|
||||
.searchLabel=${this.hass.localize(
|
||||
"ui.panel.config.backup.picker.search"
|
||||
|
@@ -50,9 +50,11 @@ class HaConfigBackupSettings extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
protected firstUpdated(_changedProperties: PropertyValues): void {
|
||||
super.firstUpdated(_changedProperties);
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._scrollToSection();
|
||||
// Update config the page is displayed (e.g. when coming back from a location detail page)
|
||||
this._config = this.config;
|
||||
}
|
||||
|
||||
private async _scrollToSection() {
|
||||
|
@@ -119,6 +119,7 @@ class HaConfigBackup extends SubscribeMixin(HassRouterPage) {
|
||||
settings: {
|
||||
tag: "ha-config-backup-settings",
|
||||
load: () => import("./ha-config-backup-settings"),
|
||||
cache: true,
|
||||
},
|
||||
location: {
|
||||
tag: "ha-config-backup-location",
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { storage } from "../../../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||
import type {
|
||||
@@ -11,9 +12,6 @@ import type {
|
||||
} from "../../../../../components/data-table/ha-data-table";
|
||||
import "../../../../../components/ha-fab";
|
||||
import "../../../../../components/ha-icon-button";
|
||||
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import type {
|
||||
BluetoothDeviceData,
|
||||
BluetoothScannersDetails,
|
||||
@@ -22,6 +20,10 @@ import {
|
||||
subscribeBluetoothAdvertisements,
|
||||
subscribeBluetoothScannersDetails,
|
||||
} from "../../../../../data/bluetooth";
|
||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import "../../../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import { showBluetoothDeviceInfoDialog } from "./show-dialog-bluetooth-device-info";
|
||||
|
||||
@customElement("bluetooth-advertisement-monitor")
|
||||
@@ -38,6 +40,22 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
|
||||
@state() private _scanners: BluetoothScannersDetails = {};
|
||||
|
||||
@state() private _sourceDevices: Record<string, DeviceRegistryEntry> = {};
|
||||
|
||||
@storage({
|
||||
key: "bluetooth-advertisement-table-grouping",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
})
|
||||
private _activeGrouping?: string = "source";
|
||||
|
||||
@storage({
|
||||
key: "bluetooth-advertisement-table-collapsed",
|
||||
state: false,
|
||||
subscribe: false,
|
||||
})
|
||||
private _activeCollapsed: string[] = [];
|
||||
|
||||
private _unsub_advertisements?: UnsubscribeFunc;
|
||||
|
||||
private _unsub_scanners?: UnsubscribeFunc;
|
||||
@@ -57,6 +75,19 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
this._scanners = scanners;
|
||||
}
|
||||
);
|
||||
|
||||
const devices = Object.values(this.hass.devices);
|
||||
const bluetoothDevices = devices.filter((device) =>
|
||||
device.connections.find((connection) => connection[0] === "bluetooth")
|
||||
);
|
||||
this._sourceDevices = Object.fromEntries(
|
||||
bluetoothDevices.map((device) => {
|
||||
const connection = device.connections.find(
|
||||
(c) => c[0] === "bluetooth"
|
||||
)!;
|
||||
return [connection[1], device];
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,21 +115,35 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
hideable: false,
|
||||
moveable: false,
|
||||
direction: "asc",
|
||||
flex: 2,
|
||||
flex: 1,
|
||||
},
|
||||
name: {
|
||||
title: localize("ui.panel.config.bluetooth.name"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
},
|
||||
device: {
|
||||
title: localize("ui.panel.config.bluetooth.device"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
template: (data) => html`${data.device || "-"}`,
|
||||
},
|
||||
source: {
|
||||
title: localize("ui.panel.config.bluetooth.source"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
groupable: true,
|
||||
},
|
||||
source_address: {
|
||||
title: localize("ui.panel.config.bluetooth.source_address"),
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
defaultHidden: true,
|
||||
},
|
||||
rssi: {
|
||||
title: localize("ui.panel.config.bluetooth.rssi"),
|
||||
type: "numeric",
|
||||
maxWidth: "60px",
|
||||
sortable: true,
|
||||
},
|
||||
};
|
||||
@@ -108,11 +153,22 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
);
|
||||
|
||||
private _dataWithNamedSourceAndIds = memoizeOne((data) =>
|
||||
data.map((row) => ({
|
||||
...row,
|
||||
id: row.address,
|
||||
source: this._scanners[row.source]?.name || row.source,
|
||||
}))
|
||||
data.map((row) => {
|
||||
const device = this._sourceDevices[row.address];
|
||||
const scannerDevice = this._sourceDevices[row.source];
|
||||
const scanner = this._scanners[row.source];
|
||||
return {
|
||||
...row,
|
||||
id: row.address,
|
||||
source_address: row.source,
|
||||
source:
|
||||
scannerDevice?.name_by_user ||
|
||||
scannerDevice?.name ||
|
||||
scanner?.name ||
|
||||
row.source,
|
||||
device: device?.name_by_user || device?.name || undefined,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
@@ -124,11 +180,23 @@ export class BluetoothAdvertisementMonitorPanel extends LitElement {
|
||||
.columns=${this._columns(this.hass.localize)}
|
||||
.data=${this._dataWithNamedSourceAndIds(this._data)}
|
||||
@row-click=${this._handleRowClicked}
|
||||
.initialGroupColumn=${this._activeGrouping}
|
||||
.initialCollapsedGroups=${this._activeCollapsed}
|
||||
@grouping-changed=${this._handleGroupingChanged}
|
||||
@collapsed-changed=${this._handleCollapseChanged}
|
||||
clickable
|
||||
></hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleGroupingChanged(ev: CustomEvent) {
|
||||
this._activeGrouping = ev.detail.value;
|
||||
}
|
||||
|
||||
private _handleCollapseChanged(ev: CustomEvent) {
|
||||
this._activeCollapsed = ev.detail.value;
|
||||
}
|
||||
|
||||
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
||||
const entry = this._data.find((ent) => ent.address === ev.detail.id);
|
||||
showBluetoothDeviceInfoDialog(this, {
|
||||
|
@@ -53,8 +53,6 @@ class DialogBluetoothDeviceInfo extends LitElement implements HassDialog {
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
|
@@ -314,8 +314,9 @@ export class HuiEnergyDevicesDetailGraphCard
|
||||
|
||||
processedData.forEach((device) => {
|
||||
device.data.forEach((datapoint) => {
|
||||
totalDeviceConsumption[datapoint[0]] =
|
||||
(totalDeviceConsumption[datapoint[0]] || 0) + datapoint[1];
|
||||
totalDeviceConsumption[datapoint[compare ? 2 : 0]] =
|
||||
(totalDeviceConsumption[datapoint[compare ? 2 : 0]] || 0) +
|
||||
datapoint[1];
|
||||
});
|
||||
});
|
||||
const compareOffset = compare
|
||||
@@ -333,10 +334,12 @@ export class HuiEnergyDevicesDetailGraphCard
|
||||
}
|
||||
untrackedConsumption.push(dataPoint);
|
||||
});
|
||||
// random id to always add untracked at the end
|
||||
const order = Date.now();
|
||||
const dataset: BarSeriesOption = {
|
||||
type: "bar",
|
||||
cursor: "default",
|
||||
id: compare ? "compare-untracked" : "untracked",
|
||||
id: compare ? `compare-untracked-${order}` : `untracked-${order}`,
|
||||
name: this.hass.localize(
|
||||
"ui.panel.lovelace.cards.energy.energy_devices_detail_graph.untracked_consumption"
|
||||
),
|
||||
@@ -419,9 +422,10 @@ export class HuiEnergyDevicesDetailGraphCard
|
||||
data.push({
|
||||
type: "bar",
|
||||
cursor: "default",
|
||||
// add order to id, otherwise echarts refuses to reorder them
|
||||
id: compare
|
||||
? `compare-${source.stat_consumption}`
|
||||
: source.stat_consumption,
|
||||
? `compare-${source.stat_consumption}-${order}`
|
||||
: `${source.stat_consumption}-${order}`,
|
||||
name:
|
||||
source.name ||
|
||||
getStatisticLabel(
|
||||
@@ -438,7 +442,9 @@ export class HuiEnergyDevicesDetailGraphCard
|
||||
stack: compare ? "devicesCompare" : "devices",
|
||||
});
|
||||
});
|
||||
return data;
|
||||
return sorted_devices.map(
|
||||
(device) => data.find((d) => (d.id as string).includes(device))!
|
||||
);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
|
@@ -88,7 +88,7 @@ export class HuiEnergyDevicesGraphCard
|
||||
<ha-chart-base
|
||||
.hass=${this.hass}
|
||||
.data=${this._chartData}
|
||||
.options=${this._createOptions(this.hass.themes?.darkMode)}
|
||||
.options=${this._createOptions(this._chartData)}
|
||||
.height=${`${(this._chartData[0]?.data?.length || 0) * 28 + 50}px`}
|
||||
@chart-click=${this._handleChartClick}
|
||||
></ha-chart-base>
|
||||
@@ -110,18 +110,17 @@ export class HuiEnergyDevicesGraphCard
|
||||
}
|
||||
|
||||
private _createOptions = memoizeOne(
|
||||
(darkMode: boolean): ECOption => ({
|
||||
(data: BarSeriesOption[]): ECOption => ({
|
||||
xAxis: {
|
||||
type: "value",
|
||||
name: "kWh",
|
||||
splitLine: {
|
||||
lineStyle: darkMode ? { opacity: 0.15 } : {},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "category",
|
||||
inverse: true,
|
||||
triggerEvent: true,
|
||||
// take order from data
|
||||
data: data[0]?.data?.map((d: any) => d.value[1]),
|
||||
axisLabel: {
|
||||
formatter: this._getDeviceName.bind(this),
|
||||
overflow: "truncate",
|
||||
|
@@ -6,7 +6,10 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import "../../../components/ha-card";
|
||||
import { getEnergyDataCollection } from "../../../data/energy";
|
||||
import { getSuggestedPeriod } from "./energy/common/energy-chart-options";
|
||||
import {
|
||||
getSuggestedMax,
|
||||
getSuggestedPeriod,
|
||||
} from "./energy/common/energy-chart-options";
|
||||
import type {
|
||||
Statistics,
|
||||
StatisticsMetaData,
|
||||
@@ -274,10 +277,19 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {
|
||||
.unit=${this._unit}
|
||||
.minYAxis=${this._config.min_y_axis}
|
||||
.maxYAxis=${this._config.max_y_axis}
|
||||
.startTime=${this._energyStart}
|
||||
.endTime=${this._energyEnd && this._energyStart
|
||||
? getSuggestedMax(
|
||||
differenceInDays(this._energyEnd, this._energyStart),
|
||||
this._energyEnd
|
||||
)
|
||||
: undefined}
|
||||
.fitYData=${this._config.fit_y_data || false}
|
||||
.hideLegend=${this._config.hide_legend || false}
|
||||
.logarithmicScale=${this._config.logarithmic_scale || false}
|
||||
.daysToShow=${this._config.days_to_show || DEFAULT_DAYS_TO_SHOW}
|
||||
.daysToShow=${this._energyStart && this._energyEnd
|
||||
? differenceInDays(this._energyEnd, this._energyStart)
|
||||
: this._config.days_to_show || DEFAULT_DAYS_TO_SHOW}
|
||||
.height=${this._config.grid_options?.rows ? "100%" : undefined}
|
||||
></statistics-chart>
|
||||
</div>
|
||||
|
@@ -200,10 +200,9 @@ export class HuiGenericEntityRow extends LitElement {
|
||||
padding-inline-start: 16px;
|
||||
padding-inline-end: 8px;
|
||||
flex: 1 1 30%;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.info:not(:has(.secondary)) {
|
||||
line-height: 40px;
|
||||
}
|
||||
.info,
|
||||
.info > * {
|
||||
@@ -237,9 +236,7 @@ export class HuiGenericEntityRow extends LitElement {
|
||||
}
|
||||
.value {
|
||||
direction: ltr;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 40px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
@@ -2678,19 +2678,19 @@
|
||||
"encryption": {
|
||||
"title": "Encryption",
|
||||
"description": "All your backups are encrypted by default to keep your data private and secure.",
|
||||
"location_encrypted": "This location is encrypted",
|
||||
"location_unencrypted": "This location is unencrypted",
|
||||
"location_encrypted_description": "Your data private and secure by securing it with your encryption key.",
|
||||
"location_encrypted": "Backups made to this location will be encrypted",
|
||||
"location_unencrypted": "Backups made to this location will be unencrypted",
|
||||
"location_encrypted_description": "Your data is private and secure by encrypting backups with your encryption key.",
|
||||
"location_encrypted_cloud_description": "Home Assistant Cloud is the privacy-focused cloud. This is why it will only accept encrypted backups and why we don’t store your encryption key.",
|
||||
"location_encrypted_cloud_learn_more": "Learn more",
|
||||
"location_unencrypted_description": "Please keep your backups private and secure.",
|
||||
"encryption_turn_on": "Turn on",
|
||||
"encryption_turn_off": "Turn off",
|
||||
"encryption_turn_off_confirm_title": "Turn encryption off?",
|
||||
"encryption_turn_off_confirm_text": "All your next backups will not be encrypted for this location. Please keep your backups private and secure.",
|
||||
"encryption_turn_off_confirm_text": "After confirming, backups created will be unencrypted for this location. Please ensure your backups remain private and secure.",
|
||||
"encryption_turn_off_confirm_action": "Turn encryption off",
|
||||
"warning_encryption_turn_off": "Encryption turned off",
|
||||
"warning_encryption_turn_off_description": "All your next backups will not be encrypted."
|
||||
"warning_encryption_turn_off_description": "Backups will be unencrypted."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5330,6 +5330,8 @@
|
||||
"name": "Name",
|
||||
"source": "Source",
|
||||
"rssi": "RSSI",
|
||||
"source_address": "Source address",
|
||||
"device": "Device",
|
||||
"device_information": "Device information",
|
||||
"advertisement_data": "Advertisement data",
|
||||
"manufacturer_data": "Manufacturer data",
|
||||
|
104
yarn.lock
104
yarn.lock
@@ -5000,15 +5000,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.21.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.22.0"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.10.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.21.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.21.0"
|
||||
"@typescript-eslint/utils": "npm:8.21.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.21.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.22.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.22.0"
|
||||
"@typescript-eslint/utils": "npm:8.22.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.22.0"
|
||||
graphemer: "npm:^1.4.0"
|
||||
ignore: "npm:^5.3.1"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
@@ -5017,64 +5017,64 @@ __metadata:
|
||||
"@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: ">=4.8.4 <5.8.0"
|
||||
checksum: 10/4c7c274bd0f7d8ee2097278d9fb0829b883c28783b9a1c41e5f4e74dee0412c53063978db3590ad7609d538a38058e43f832895746e6af677da7558a8b16fbdd
|
||||
checksum: 10/7211ad95f20a27182e2b55ef50102dfee4a7084c267c4e24cca24f0a28daa0360074a38bb71e407dad6d99db1165096b324b708cf35904b1d4f62fc9d5fd0f98
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.21.0"
|
||||
"@typescript-eslint/parser@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.22.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:8.21.0"
|
||||
"@typescript-eslint/types": "npm:8.21.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.21.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.21.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.22.0"
|
||||
"@typescript-eslint/types": "npm:8.22.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.22.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.22.0"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: ">=4.8.4 <5.8.0"
|
||||
checksum: 10/c403f56b0a856ad25ffc0d78d4f0ede64d622edb279ace8bc7554c82518c0462f608a1e06d62111633a57b9ffcc37e063378c3980fba138f93d14a7aad5d0db1
|
||||
checksum: 10/6b7fee52345e8a32d8cfea1ac4aeb563cb0c44ba46290686afde1cd541b787fcf61bec0e6960559f544e9ba3b72670a68f8eda860384aebb5744101f0f1a68c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.21.0"
|
||||
"@typescript-eslint/scope-manager@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.22.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.21.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.21.0"
|
||||
checksum: 10/99aa8257c758546c8c4905bd34381be446adea7642dbc279269039308dc33b8dbcf3d7b7d12da7bec8f8d8760b813a5852dc53d75e953cbe327fac05d3f18fc4
|
||||
"@typescript-eslint/types": "npm:8.22.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.22.0"
|
||||
checksum: 10/7fb4bae6d9f8b86a43405b24828cd36ba0751cce4346d86821a4827cded93227f92668044e5e6d802a32096b50cfcaf2ce9ab65322310fa68f5e3819bef70168
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.21.0"
|
||||
"@typescript-eslint/type-utils@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.22.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": "npm:8.21.0"
|
||||
"@typescript-eslint/utils": "npm:8.21.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.22.0"
|
||||
"@typescript-eslint/utils": "npm:8.22.0"
|
||||
debug: "npm:^4.3.4"
|
||||
ts-api-utils: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: ">=4.8.4 <5.8.0"
|
||||
checksum: 10/b4bce1325a2e5e1a74b6919b3187356b7246475ac4d62898134ed68572e39e52fe5daa89d0bb66d78aef7b2057612cccc00400c0b81f9d5b75acec3174114c8d
|
||||
checksum: 10/1da2447ce12f09370082daeef88f8922842e39d2a7b0abe3def21442f85bf4250524c60cbb97276d5cd876783b976dcb0ed85aeb8c0b100d83b7f3a59cdfccbf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/types@npm:8.21.0"
|
||||
checksum: 10/a22c99f5687358c7343789b942c9885bc1b49eb239562b792f22e2ac4f0d3f04102f204cd2d749202d6888767566fba86f54447894955310890ec307fec8ed8d
|
||||
"@typescript-eslint/types@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/types@npm:8.22.0"
|
||||
checksum: 10/b43ea5b05ed0b43dcee8d2fa98b2c3f79c604780cbd56e6ba7f89e3066798b7169848694f59523fd2003e8fa699ddc97f28b0860a4eb04eea26c96d5ac9346bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.21.0"
|
||||
"@typescript-eslint/typescript-estree@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.22.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.21.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.21.0"
|
||||
"@typescript-eslint/types": "npm:8.22.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.22.0"
|
||||
debug: "npm:^4.3.4"
|
||||
fast-glob: "npm:^3.3.2"
|
||||
is-glob: "npm:^4.0.3"
|
||||
@@ -5083,32 +5083,32 @@ __metadata:
|
||||
ts-api-utils: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <5.8.0"
|
||||
checksum: 10/1a8bcd2968490dcf047273a36e1d2cd51725e893ad874e554e4b81e62bf54e4ff2b7ee2af206208a2ae9ac2cc5c8b50e2244dd4fe9c42ef34122df4360e9f9c2
|
||||
checksum: 10/e3c0b191e2a0f55101c3e3333904f3a255d635e4ea0d026981cc25e83b62660a3a8a7993ac4a3d0c8756afb7dc272099eec48fd93e100a2b8467a5b80ef0026c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.21.0"
|
||||
"@typescript-eslint/utils@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.22.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.4.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.21.0"
|
||||
"@typescript-eslint/types": "npm:8.21.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.21.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.22.0"
|
||||
"@typescript-eslint/types": "npm:8.22.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.22.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: ">=4.8.4 <5.8.0"
|
||||
checksum: 10/e44b4e87b8227f7524b4cd16e833ea37fbb73d3829caf484e7ca737060908817788755b9481d053bc4371bbcc99d2477e32b7ad43a421a3e61ce46c2c48c0bd7
|
||||
checksum: 10/92a5ae5d79a5988e88fdda8d5e88f73e7b9ce24b339098d72698dba766ded274c24d0e2857bcb799c0aa7a59257e54a273eabdaaab39a5cd20283669201eeb53
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:8.21.0":
|
||||
version: 8.21.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.21.0"
|
||||
"@typescript-eslint/visitor-keys@npm:8.22.0":
|
||||
version: 8.22.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.22.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.21.0"
|
||||
"@typescript-eslint/types": "npm:8.22.0"
|
||||
eslint-visitor-keys: "npm:^4.2.0"
|
||||
checksum: 10/781cafa354177de4e864511435dbe61d896a7d1331bca76dd0a151295cc27b9677412444d47e1d5c6d2e7de5fee29b7bef0489d76c494fa59139e421f860506a
|
||||
checksum: 10/1a172620d46e23362c5d1e1e7c8186856dff6b6f1c2697d67f9aac1b3dfd0de96c2c73487e4deed80fad3bfa5cf74cfed3519221657c6ede602b04ac091525a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9230,8 +9230,8 @@ __metadata:
|
||||
"@types/tar": "npm:6.1.13"
|
||||
"@types/ua-parser-js": "npm:0.7.39"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.21.0"
|
||||
"@typescript-eslint/parser": "npm:8.21.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.22.0"
|
||||
"@typescript-eslint/parser": "npm:8.22.0"
|
||||
"@vaadin/combo-box": "npm:24.6.2"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:24.6.2"
|
||||
"@vibrant/color": "npm:4.0.0"
|
||||
|
Reference in New Issue
Block a user