mirror of
https://github.com/home-assistant/frontend.git
synced 2026-07-03 05:33:16 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 36330d8220 | |||
| 0df3919a49 | |||
| b5e03b23b9 | |||
| ca1ab06384 | |||
| fb7ed8bfd4 | |||
| b72b6c77bf | |||
| 7f0ddae91e | |||
| 71e4303fa5 | |||
| 9bb7704a3a | |||
| 3cc9817b90 | |||
| 674755e430 | |||
| f84664909f | |||
| 4fd631f229 | |||
| 18cf41b793 | |||
| e28788cb95 |
@@ -67,7 +67,7 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
||||
<!--
|
||||
If your issue is about how an entity is shown in the UI, please add the state
|
||||
and attributes for all situations with a screenshot of the UI.
|
||||
You can find this information at `/config/developer-tools/state`
|
||||
You can find this information at `/config/tools/state`
|
||||
-->
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -94,8 +94,8 @@ body:
|
||||
label: State of relevant entities
|
||||
description: >
|
||||
If your issue is about how an entity is shown in the UI, please add the
|
||||
state and attributes for all situations. You can find this information
|
||||
at Developer Tools -> States.
|
||||
state and attributes for all situations. You can find this
|
||||
information in the Details view of the More info dialog.
|
||||
render: txt
|
||||
- type: textarea
|
||||
attributes:
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
if: github.event_name != 'push'
|
||||
environment:
|
||||
name: Cast Development
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
url: ${{ steps.deploy.outputs.netlify_url }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
@@ -46,7 +46,8 @@ jobs:
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=cast/dist --alias dev
|
||||
npx -y netlify-cli deploy --dir=cast/dist --alias dev --json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
if: github.event_name == 'push'
|
||||
environment:
|
||||
name: Cast Production
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
url: ${{ steps.deploy.outputs.netlify_url }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
@@ -82,7 +83,8 @@ jobs:
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=cast/dist --prod
|
||||
npx -y netlify-cli deploy --dir=cast/dist --prod --json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
|
||||
|
||||
@@ -2,64 +2,42 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev, master]
|
||||
branches:
|
||||
- dev
|
||||
- master
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [dev]
|
||||
branches:
|
||||
- dev
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ["javascript"]
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
timeout-minutes: 360
|
||||
permissions:
|
||||
contents: read # To check out the repository
|
||||
security-events: write # To upload CodeQL results
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
persist-credentials: false
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
languages: javascript-typescript
|
||||
build-mode: none
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
with:
|
||||
category: "/language:javascript-typescript"
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
if: github.event_name != 'push' || github.ref_name != 'master'
|
||||
environment:
|
||||
name: Demo Development
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
url: ${{ steps.deploy.outputs.netlify_url }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
@@ -47,7 +47,8 @@ jobs:
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod --json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }}
|
||||
@@ -58,7 +59,7 @@ jobs:
|
||||
if: github.event_name == 'push' && github.ref_name == 'master'
|
||||
environment:
|
||||
name: Demo Production
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
url: ${{ steps.deploy.outputs.netlify_url }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
@@ -83,7 +84,8 @@ jobs:
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod --json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }}
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: Design
|
||||
url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}
|
||||
url: ${{ steps.deploy.outputs.netlify_url }}
|
||||
steps:
|
||||
- name: Check out files from GitHub
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
@@ -40,7 +40,8 @@ jobs:
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=gallery/dist --prod
|
||||
npx -y netlify-cli deploy --dir=gallery/dist --prod --json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
|
||||
|
||||
@@ -47,11 +47,10 @@ jobs:
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}" \
|
||||
--json > deploy_output.json
|
||||
echo "netlify_url=$(jq -r '.url // .deploy_url' deploy_output.json)" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
|
||||
|
||||
- name: Generate summary
|
||||
run: |
|
||||
NETLIFY_LIVE_URL=$(jq -r '.deploy_url' deploy_output.json)
|
||||
echo "$NETLIFY_LIVE_URL" >> "$GITHUB_STEP_SUMMARY"
|
||||
run: echo "${{ steps.deploy.outputs.netlify_url }}" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
+6
-6
@@ -102,7 +102,7 @@
|
||||
"gulp-zopfli-green": "7.0.0",
|
||||
"hls.js": "1.6.16",
|
||||
"home-assistant-js-websocket": "9.6.0",
|
||||
"idb-keyval": "6.2.5",
|
||||
"idb-keyval": "6.2.6",
|
||||
"intl-messageformat": "11.2.9",
|
||||
"js-yaml": "5.2.0",
|
||||
"leaflet": "1.9.4",
|
||||
@@ -147,7 +147,7 @@
|
||||
"@octokit/plugin-retry": "8.1.0",
|
||||
"@octokit/rest": "22.0.1",
|
||||
"@playwright/test": "1.61.1",
|
||||
"@rsdoctor/rspack-plugin": "1.5.16",
|
||||
"@rsdoctor/rspack-plugin": "1.5.17",
|
||||
"@rspack/core": "2.1.1",
|
||||
"@rspack/dev-server": "2.1.0",
|
||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||
@@ -178,7 +178,7 @@
|
||||
"eslint-plugin-unused-imports": "4.4.1",
|
||||
"eslint-plugin-wc": "3.1.0",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.5",
|
||||
"fs-extra": "11.3.6",
|
||||
"generate-license-file": "4.2.1",
|
||||
"glob": "13.0.6",
|
||||
"globals": "17.7.0",
|
||||
@@ -196,9 +196,9 @@
|
||||
"lodash.merge": "4.6.2",
|
||||
"lodash.template": "4.18.1",
|
||||
"map-stream": "0.0.7",
|
||||
"minify-literals": "2.0.2",
|
||||
"minify-literals": "2.1.0",
|
||||
"pinst": "3.0.0",
|
||||
"prettier": "3.9.1",
|
||||
"prettier": "3.9.4",
|
||||
"rspack-manifest-plugin": "5.2.2",
|
||||
"serve": "14.2.6",
|
||||
"sinon": "22.0.0",
|
||||
@@ -206,7 +206,7 @@
|
||||
"terser-webpack-plugin": "5.6.1",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.62.0",
|
||||
"typescript-eslint": "8.62.1",
|
||||
"vite-tsconfig-paths": "6.1.1",
|
||||
"vitest": "4.1.9",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type { NumberSelector } from "../../data/selector";
|
||||
import { isSafari } from "../../util/is_safari";
|
||||
import "../ha-input-helper-text";
|
||||
import "../ha-slider";
|
||||
import "../input/ha-input";
|
||||
@@ -66,6 +67,16 @@ export class HaNumberSelector extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
// On iOS/iPadOS the numeric and decimal on-screen keypads have no minus key,
|
||||
// so negatives can only be typed with the full "text" keyboard. Other
|
||||
// platforms include a minus on their number keypads, so restrict this
|
||||
// workaround to Safari/WebKit and only when the selector allows negatives
|
||||
// (e.g. numeric_state triggers/conditions).
|
||||
const useTextInputMode =
|
||||
isSafari &&
|
||||
this.selector.number?.min !== undefined &&
|
||||
this.selector.number.min < 0;
|
||||
|
||||
const translationKey = this.selector.number?.translation_key;
|
||||
let unit = this.selector.number?.unit_of_measurement;
|
||||
if (isBox && unit && this.localizeValue && translationKey) {
|
||||
@@ -100,11 +111,13 @@ export class HaNumberSelector extends LitElement {
|
||||
: nothing
|
||||
}
|
||||
<ha-input
|
||||
.inputMode=${
|
||||
this.selector.number?.step === "any" ||
|
||||
(this.selector.number?.step ?? 1) % 1 !== 0
|
||||
? "decimal"
|
||||
: "numeric"
|
||||
.inputmode=${
|
||||
useTextInputMode
|
||||
? "text"
|
||||
: this.selector.number?.step === "any" ||
|
||||
(this.selector.number?.step ?? 1) % 1 !== 0
|
||||
? "decimal"
|
||||
: "numeric"
|
||||
}
|
||||
.label=${!isBox ? undefined : this.label}
|
||||
.placeholder=${
|
||||
|
||||
@@ -525,10 +525,10 @@ export class HaServiceControl extends LitElement {
|
||||
this._manifest
|
||||
? html` <a
|
||||
href=${
|
||||
this._manifest.is_built_in
|
||||
this._manifest.is_built_in && this._value?.action
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this._manifest.domain}`
|
||||
`/actions/${this._value.action}`
|
||||
)
|
||||
: this._manifest.documentation
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ export const CONFIG_SUB_ROUTES: Record<
|
||||
translationKey: "ui.components.navigation-picker.route.scripts",
|
||||
iconPath: mdiScriptText,
|
||||
},
|
||||
"developer-tools": {
|
||||
translationKey: "ui.components.navigation-picker.route.developer_tools",
|
||||
tools: {
|
||||
translationKey: "ui.components.navigation-picker.route.tools",
|
||||
iconPath: mdiHammer,
|
||||
},
|
||||
integrations: {
|
||||
|
||||
@@ -28,6 +28,21 @@ const useHash = __DEMO__;
|
||||
const curPath = () =>
|
||||
useHash ? location.hash.substring(1) : location.pathname;
|
||||
|
||||
// Developer tools was renamed to Tools (/config/tools) in 2026.8; it had moved
|
||||
// from /developer-tools to /config in 2026.2. Redirect both old locations to
|
||||
// the new one. Applied on the initial route and on every navigation so
|
||||
// bookmarks and external links to the old URLs resolve too, not just in-app
|
||||
// navigation.
|
||||
const redirectLegacyToolsPath = (path: string): string => {
|
||||
if (path.startsWith("/config/developer-tools")) {
|
||||
return path.replace("/config/developer-tools", "/config/tools");
|
||||
}
|
||||
if (path.startsWith("/developer-tools")) {
|
||||
return path.replace("/developer-tools", "/config/tools");
|
||||
}
|
||||
return path;
|
||||
};
|
||||
|
||||
const panelUrl = (path: string) => {
|
||||
const dividerPos = path.indexOf("/", 1);
|
||||
return dividerPos === -1 ? path.substring(1) : path.substring(1, dividerPos);
|
||||
@@ -50,7 +65,7 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const path = curPath();
|
||||
const path = redirectLegacyToolsPath(curPath());
|
||||
|
||||
this._route = {
|
||||
prefix: "",
|
||||
@@ -106,10 +121,7 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
|
||||
|
||||
// Navigation
|
||||
const updateRoute = (path = curPath()) => {
|
||||
// Developer tools panel was moved to config in 2026.2
|
||||
if (path.startsWith("/developer-tools")) {
|
||||
path = path.replace("/developer-tools", "/config/developer-tools");
|
||||
}
|
||||
path = redirectLegacyToolsPath(path);
|
||||
if (this._route && path === this._route.path) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ export class HaPlatformCondition extends LitElement {
|
||||
this._manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this._manifest.domain}`
|
||||
`/conditions/${this.condition.condition}`
|
||||
)
|
||||
: this._manifest.documentation
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ export class HaPlatformTrigger extends LitElement {
|
||||
this._manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this._manifest.domain}`
|
||||
`/triggers/${this.trigger.trigger}`
|
||||
)
|
||||
: this._manifest.documentation
|
||||
}
|
||||
|
||||
@@ -211,8 +211,8 @@ export const configSections: Record<string, PageNavigation[]> = {
|
||||
adminOnly: true,
|
||||
},
|
||||
{
|
||||
path: "/config/developer-tools",
|
||||
translationKey: "developer_tools",
|
||||
path: "/config/tools",
|
||||
translationKey: "tools",
|
||||
iconPath: mdiHammer,
|
||||
iconColor: "#7A5AA6",
|
||||
core: true,
|
||||
@@ -328,10 +328,10 @@ export const configSections: Record<string, PageNavigation[]> = {
|
||||
adminOnly: true,
|
||||
},
|
||||
],
|
||||
developer_tools: [
|
||||
tools: [
|
||||
{
|
||||
path: "/config/developer-tools",
|
||||
translationKey: "ui.panel.config.dashboard.developer_tools.main",
|
||||
path: "/config/tools",
|
||||
translationKey: "ui.panel.config.dashboard.tools.main",
|
||||
iconPath: mdiHammer,
|
||||
iconColor: "#7A5AA6",
|
||||
core: true,
|
||||
|
||||
@@ -70,9 +70,9 @@ class HaPanelConfig extends HassRouterPage {
|
||||
tag: "ha-config-system-navigation",
|
||||
load: () => import("./core/ha-config-system-navigation"),
|
||||
},
|
||||
"developer-tools": {
|
||||
tag: "ha-panel-developer-tools",
|
||||
load: () => import("./developer-tools/ha-panel-developer-tools"),
|
||||
tools: {
|
||||
tag: "ha-panel-tools",
|
||||
load: () => import("./tools/ha-panel-tools"),
|
||||
cache: true,
|
||||
},
|
||||
logs: {
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
import { fixStatisticsIssue } from "../developer-tools/statistics/fix-statistics";
|
||||
import { fixStatisticsIssue } from "../tools/statistics/fix-statistics";
|
||||
import { showVacuumSegmentMappingDialog } from "../entities/dialogs/show-dialog-vacuum-segment-mapping";
|
||||
import { showRepairsFlowDialog } from "./show-dialog-repair-flow";
|
||||
import { showRepairsIssueDialog } from "./show-repair-issue-dialog";
|
||||
@@ -171,7 +171,7 @@ class HaConfigRepairs extends LitElement {
|
||||
issue.translation_key &&
|
||||
STATISTIC_TYPES.includes(issue.translation_key as any)
|
||||
) {
|
||||
this.hass.loadFragmentTranslation("developer-tools");
|
||||
this.hass.loadFragmentTranslation("config");
|
||||
const data = await fetchRepairsIssueData(
|
||||
this.hass.connection,
|
||||
issue.domain,
|
||||
|
||||
+23
-25
@@ -48,7 +48,7 @@ import { resolveMediaSource } from "../../../../data/media_source";
|
||||
import { MatchMinHeightMixin } from "../../../../mixins/match-min-height-mixin";
|
||||
import { withViewTransition } from "../../../../common/util/view-transition";
|
||||
|
||||
@customElement("developer-tools-action")
|
||||
@customElement("tools-action")
|
||||
class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -130,14 +130,12 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
|
||||
const modeButtons: ToggleButton[] = [
|
||||
{
|
||||
label: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.ui_mode"
|
||||
),
|
||||
label: this.hass.localize("ui.panel.config.tools.tabs.actions.ui_mode"),
|
||||
value: "ui",
|
||||
},
|
||||
{
|
||||
label: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.yaml_mode"
|
||||
"ui.panel.config.tools.tabs.actions.yaml_mode"
|
||||
),
|
||||
value: "yaml",
|
||||
},
|
||||
@@ -163,7 +161,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
<div class="header-row">
|
||||
<div class="header-title">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.title"
|
||||
"ui.panel.config.tools.tabs.actions.title"
|
||||
)}
|
||||
</div>
|
||||
<ha-button-toggle-group
|
||||
@@ -177,7 +175,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
</div>
|
||||
<p class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.description"
|
||||
"ui.panel.config.tools.tabs.actions.description"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -220,14 +218,14 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
!this._uiAvailable
|
||||
? html`<span class="error"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.no_template_ui_support"
|
||||
"ui.panel.config.tools.tabs.actions.no_template_ui_support"
|
||||
)}</span
|
||||
>`
|
||||
: nothing
|
||||
}
|
||||
<ha-progress-button raised @click=${this._callService}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.call_service"
|
||||
"ui.panel.config.tools.tabs.actions.call_service"
|
||||
)}
|
||||
</ha-progress-button>
|
||||
</div>
|
||||
@@ -238,7 +236,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
? html`<div class="content response">
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.response"
|
||||
"ui.panel.config.tools.tabs.actions.response"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
@@ -253,7 +251,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
slot="extra-actions"
|
||||
@click=${this._copyTemplate}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.copy_clipboard_template"
|
||||
"ui.panel.config.tools.tabs.actions.copy_clipboard_template"
|
||||
)}</ha-button
|
||||
>
|
||||
</ha-yaml-editor>
|
||||
@@ -270,10 +268,10 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
.header=${
|
||||
this._yamlMode
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.all_parameters"
|
||||
"ui.panel.config.tools.tabs.actions.all_parameters"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.yaml_parameters"
|
||||
"ui.panel.config.tools.tabs.actions.yaml_parameters"
|
||||
)
|
||||
}
|
||||
outlined
|
||||
@@ -287,7 +285,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
target
|
||||
? html`
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.accepts_target"
|
||||
"ui.panel.config.tools.tabs.actions.accepts_target"
|
||||
)}
|
||||
`
|
||||
: ""
|
||||
@@ -322,17 +320,17 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
<tr>
|
||||
<th>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.column_parameter"
|
||||
"ui.panel.config.tools.tabs.actions.column_parameter"
|
||||
)}
|
||||
</th>
|
||||
<th>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.column_description"
|
||||
"ui.panel.config.tools.tabs.actions.column_description"
|
||||
)}
|
||||
</th>
|
||||
<th>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.column_example"
|
||||
"ui.panel.config.tools.tabs.actions.column_example"
|
||||
)}
|
||||
</th>
|
||||
</tr>
|
||||
@@ -371,7 +369,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
appearance="plain"
|
||||
@click=${this._fillExampleData}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.fill_example_data"
|
||||
"ui.panel.config.tools.tabs.actions.fill_example_data"
|
||||
)}</ha-button
|
||||
>`
|
||||
: ""
|
||||
@@ -406,14 +404,14 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
const errorCategory = yamlMode ? "yaml" : "ui";
|
||||
if (!serviceData?.action) {
|
||||
return localize(
|
||||
`ui.panel.config.developer-tools.tabs.actions.errors.${errorCategory}.no_action`
|
||||
`ui.panel.config.tools.tabs.actions.errors.${errorCategory}.no_action`
|
||||
);
|
||||
}
|
||||
const domain = computeDomain(serviceData.action);
|
||||
const service = computeObjectId(serviceData.action);
|
||||
if (!domain || !service) {
|
||||
return localize(
|
||||
`ui.panel.config.developer-tools.tabs.actions.errors.${errorCategory}.invalid_action`
|
||||
`ui.panel.config.tools.tabs.actions.errors.${errorCategory}.invalid_action`
|
||||
);
|
||||
}
|
||||
const dataIsTemplate =
|
||||
@@ -427,7 +425,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
!serviceData.data?.area_id
|
||||
) {
|
||||
return localize(
|
||||
`ui.panel.config.developer-tools.tabs.actions.errors.${errorCategory}.no_target`
|
||||
`ui.panel.config.tools.tabs.actions.errors.${errorCategory}.no_target`
|
||||
);
|
||||
}
|
||||
for (const field of fields) {
|
||||
@@ -437,7 +435,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
(!serviceData.data || serviceData.data[field.key] === undefined)
|
||||
) {
|
||||
return localize(
|
||||
`ui.panel.config.developer-tools.tabs.actions.errors.${errorCategory}.missing_required_field`,
|
||||
`ui.panel.config.tools.tabs.actions.errors.${errorCategory}.missing_required_field`,
|
||||
{ key: field.key }
|
||||
);
|
||||
}
|
||||
@@ -496,7 +494,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
forwardHaptic(this, "failure");
|
||||
button.actionError();
|
||||
this._error = this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.errors.yaml.invalid_yaml"
|
||||
"ui.panel.config.tools.tabs.actions.errors.yaml.invalid_yaml"
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -569,7 +567,7 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
rel="noreferrer"
|
||||
><ha-button>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.actions.open_media"
|
||||
"ui.panel.config.tools.tabs.actions.open_media"
|
||||
)}
|
||||
</ha-button></a
|
||||
>
|
||||
@@ -829,6 +827,6 @@ class HaPanelDevAction extends MatchMinHeightMixin(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-action": HaPanelDevAction;
|
||||
"tools-action": HaPanelDevAction;
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -25,7 +25,7 @@ interface SentenceParsingResult {
|
||||
result: AssistDebugResult | null;
|
||||
}
|
||||
|
||||
@customElement("developer-tools-assist")
|
||||
@customElement("tools-assist")
|
||||
class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -118,14 +118,14 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
<div class="content">
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.title"
|
||||
"ui.panel.config.tools.tabs.assist.title"
|
||||
)}
|
||||
class="form"
|
||||
>
|
||||
<div class="card-content">
|
||||
<p class="description">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.description"
|
||||
"ui.panel.config.tools.tabs.assist.description"
|
||||
)}
|
||||
</p>
|
||||
${
|
||||
@@ -143,7 +143,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
<ha-textarea
|
||||
resize="auto"
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.sentences"
|
||||
"ui.panel.config.tools.tabs.assist.sentences"
|
||||
)}
|
||||
id="sentences-input"
|
||||
@input=${this._textAreaInput}
|
||||
@@ -157,7 +157,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
.disabled=${!this._language || !this._validInput}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.parse_sentences"
|
||||
"ui.panel.config.tools.tabs.assist.parse_sentences"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
@@ -184,7 +184,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
.path=${mdiDownload}
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.download_results"
|
||||
"ui.panel.config.tools.tabs.assist.download_results"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
@@ -204,7 +204,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
</div>
|
||||
<div class="info">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.language"
|
||||
"ui.panel.config.tools.tabs.assist.language"
|
||||
)}:
|
||||
${formatLanguageCode(language, this.hass.locale)}
|
||||
(${language})
|
||||
@@ -221,7 +221,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
`
|
||||
: html`<ha-alert alert-type="error">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.assist.no_match"
|
||||
"ui.panel.config.tools.tabs.assist.no_match"
|
||||
)}
|
||||
</ha-alert>`
|
||||
}
|
||||
@@ -304,6 +304,6 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-assist": HaPanelDevAssist;
|
||||
"tools-assist": HaPanelDevAssist;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,12 +17,12 @@ class HaDebugConnectionRow extends LitElement {
|
||||
<ha-list-item-base>
|
||||
<span slot="headline"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.debug_connection.title"
|
||||
"ui.panel.config.tools.tabs.debug.debug_connection.title"
|
||||
)}</span
|
||||
>
|
||||
<span slot="supporting-text"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.debug_connection.description"
|
||||
"ui.panel.config.tools.tabs.debug.debug_connection.description"
|
||||
)}</span
|
||||
>
|
||||
<ha-switch
|
||||
+2
-2
@@ -20,12 +20,12 @@ class HaDebugDisableViewTransitionRow extends LitElement {
|
||||
<ha-list-item-base>
|
||||
<span slot="headline"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.disable_view_transition.title"
|
||||
"ui.panel.config.tools.tabs.debug.disable_view_transition.title"
|
||||
)}</span
|
||||
>
|
||||
<span slot="supporting-text"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.disable_view_transition.description"
|
||||
"ui.panel.config.tools.tabs.debug.disable_view_transition.description"
|
||||
)}</span
|
||||
>
|
||||
<ha-switch
|
||||
+2
-2
@@ -230,13 +230,13 @@ export class HaDebugViewportEnvironmentCard extends LitElement {
|
||||
return html`
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.viewport_environment.title"
|
||||
"ui.panel.config.tools.tabs.debug.viewport_environment.title"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
<p class="explanation">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.viewport_environment.description"
|
||||
"ui.panel.config.tools.tabs.debug.viewport_environment.description"
|
||||
)}
|
||||
</p>
|
||||
<ha-code-editor
|
||||
+6
-6
@@ -20,7 +20,7 @@ import "./ha-debug-connection-row";
|
||||
import "./ha-debug-disable-view-transition-row";
|
||||
import "./ha-debug-viewport-environment-card";
|
||||
|
||||
@customElement("developer-tools-debug")
|
||||
@customElement("tools-debug")
|
||||
class HaPanelDevDebug extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -31,7 +31,7 @@ class HaPanelDevDebug extends SubscribeMixin(LitElement) {
|
||||
<div class="content">
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.title"
|
||||
"ui.panel.config.tools.tabs.debug.title"
|
||||
)}
|
||||
>
|
||||
<ha-list-base>
|
||||
@@ -45,13 +45,13 @@ class HaPanelDevDebug extends SubscribeMixin(LitElement) {
|
||||
</ha-card>
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.entity_diagnostic.title"
|
||||
"ui.panel.config.tools.tabs.debug.entity_diagnostic.title"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
<ha-entity-picker
|
||||
.helper=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.entity_diagnostic.description"
|
||||
"ui.panel.config.tools.tabs.debug.entity_diagnostic.description"
|
||||
)}
|
||||
@value-changed=${this._entityPicked}
|
||||
></ha-entity-picker>
|
||||
@@ -62,7 +62,7 @@ class HaPanelDevDebug extends SubscribeMixin(LitElement) {
|
||||
appearance="filled"
|
||||
.disabled=${!this._entityId}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.entity_diagnostic.copy_to_clipboard"
|
||||
"ui.panel.config.tools.tabs.debug.entity_diagnostic.copy_to_clipboard"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>
|
||||
@@ -136,6 +136,6 @@ class HaPanelDevDebug extends SubscribeMixin(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-debug": HaPanelDevDebug;
|
||||
"tools-debug": HaPanelDevDebug;
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -76,7 +76,7 @@ class EventSubscribeCard extends LitElement {
|
||||
return html`
|
||||
<ha-card
|
||||
header=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.listen_to_events"
|
||||
"ui.panel.config.tools.tabs.events.listen_to_events"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
@@ -84,10 +84,10 @@ class EventSubscribeCard extends LitElement {
|
||||
.label=${
|
||||
this._subscribed
|
||||
? this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.listening_to"
|
||||
"ui.panel.config.tools.tabs.events.listening_to"
|
||||
)
|
||||
: this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.subscribe_to"
|
||||
"ui.panel.config.tools.tabs.events.subscribe_to"
|
||||
)
|
||||
}
|
||||
.disabled=${this._subscribed !== undefined}
|
||||
@@ -96,11 +96,11 @@ class EventSubscribeCard extends LitElement {
|
||||
></ha-input>
|
||||
<ha-input
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.filter_events"
|
||||
"ui.panel.config.tools.tabs.events.filter_events"
|
||||
)}
|
||||
.value=${this._eventFilter}
|
||||
.disabled=${this._subscribed !== undefined}
|
||||
.hint=${`${this.hass!.localize("ui.panel.config.developer-tools.tabs.events.filter_helper")}${this._ignoredEventsCount ? ` ${this.hass!.localize("ui.panel.config.developer-tools.tabs.events.filter_ignored", { count: this._ignoredEventsCount })}` : ""}`}
|
||||
.hint=${`${this.hass!.localize("ui.panel.config.tools.tabs.events.filter_helper")}${this._ignoredEventsCount ? ` ${this.hass!.localize("ui.panel.config.tools.tabs.events.filter_ignored", { count: this._ignoredEventsCount })}` : ""}`}
|
||||
@input=${this._filterChanged}
|
||||
></ha-input>
|
||||
${
|
||||
@@ -118,10 +118,10 @@ class EventSubscribeCard extends LitElement {
|
||||
${
|
||||
this._subscribed
|
||||
? this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.stop_listening"
|
||||
"ui.panel.config.tools.tabs.events.stop_listening"
|
||||
)
|
||||
: this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.start_listening"
|
||||
"ui.panel.config.tools.tabs.events.start_listening"
|
||||
)
|
||||
}
|
||||
</ha-button>
|
||||
@@ -131,7 +131,7 @@ class EventSubscribeCard extends LitElement {
|
||||
@click=${this._clearEvents}
|
||||
>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.clear_events"
|
||||
"ui.panel.config.tools.tabs.events.clear_events"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
@@ -144,10 +144,10 @@ class EventSubscribeCard extends LitElement {
|
||||
if (!this._events.length) {
|
||||
const message = this._subscribed
|
||||
? this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.waiting_for_events"
|
||||
"ui.panel.config.tools.tabs.events.waiting_for_events"
|
||||
)
|
||||
: this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.subscribe_prompt"
|
||||
"ui.panel.config.tools.tabs.events.subscribe_prompt"
|
||||
);
|
||||
return html`
|
||||
<ha-card class="events-card">
|
||||
@@ -172,7 +172,7 @@ class EventSubscribeCard extends LitElement {
|
||||
.path=${mdiChevronDoubleLeft}
|
||||
.disabled=${index >= bufferTotal - 1}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.oldest_event"
|
||||
"ui.panel.config.tools.tabs.events.oldest_event"
|
||||
)}
|
||||
@click=${this._showOldest}
|
||||
></ha-icon-button>
|
||||
@@ -180,13 +180,13 @@ class EventSubscribeCard extends LitElement {
|
||||
.path=${mdiChevronLeft}
|
||||
.disabled=${index >= bufferTotal - 1}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.older_event"
|
||||
"ui.panel.config.tools.tabs.events.older_event"
|
||||
)}
|
||||
@click=${this._showOlder}
|
||||
></ha-icon-button>
|
||||
<div class="event-info">
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.event_fired",
|
||||
"ui.panel.config.tools.tabs.events.event_fired",
|
||||
{
|
||||
name: position,
|
||||
time: formatTimeWithSeconds(
|
||||
@@ -208,7 +208,7 @@ class EventSubscribeCard extends LitElement {
|
||||
<ha-tooltip for="buffer-info" placement="bottom">
|
||||
<span class="buffer-tooltip">
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.buffer_disclaimer",
|
||||
"ui.panel.config.tools.tabs.events.buffer_disclaimer",
|
||||
{ count: MAX_BUFFERED_EVENTS }
|
||||
)}
|
||||
</span>
|
||||
@@ -221,7 +221,7 @@ class EventSubscribeCard extends LitElement {
|
||||
.path=${mdiChevronRight}
|
||||
.disabled=${atNewest}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.newer_event"
|
||||
"ui.panel.config.tools.tabs.events.newer_event"
|
||||
)}
|
||||
@click=${this._showNewer}
|
||||
></ha-icon-button>
|
||||
@@ -229,7 +229,7 @@ class EventSubscribeCard extends LitElement {
|
||||
.path=${mdiChevronDoubleRight}
|
||||
.disabled=${atNewest}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.newest_event"
|
||||
"ui.panel.config.tools.tabs.events.newest_event"
|
||||
)}
|
||||
@click=${this._showNewest}
|
||||
></ha-icon-button>
|
||||
@@ -362,13 +362,13 @@ class EventSubscribeCard extends LitElement {
|
||||
}, this._eventType);
|
||||
} catch (error) {
|
||||
this._error = this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.subscribe_failed",
|
||||
"ui.panel.config.tools.tabs.events.subscribe_failed",
|
||||
{
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: this.hass!.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.unknown_error"
|
||||
"ui.panel.config.tools.tabs.events.unknown_error"
|
||||
),
|
||||
}
|
||||
);
|
||||
+1
-1
@@ -27,7 +27,7 @@ class EventsList extends LitElement {
|
||||
>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.count_listeners",
|
||||
"ui.panel.config.tools.tabs.events.count_listeners",
|
||||
{
|
||||
count: event.listener_count,
|
||||
}
|
||||
+10
-10
@@ -14,7 +14,7 @@ import { documentationUrl } from "../../../../util/documentation-url";
|
||||
import "./event-subscribe-card";
|
||||
import "./events-list";
|
||||
|
||||
@customElement("developer-tools-event")
|
||||
@customElement("tools-event")
|
||||
class HaPanelDevEvent extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -40,7 +40,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
<div class="card-content">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.description"
|
||||
"ui.panel.config.tools.tabs.events.description"
|
||||
)}
|
||||
<a
|
||||
href=${documentationUrl(
|
||||
@@ -51,14 +51,14 @@ class HaPanelDevEvent extends LitElement {
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.documentation"
|
||||
"ui.panel.config.tools.tabs.events.documentation"
|
||||
)}
|
||||
</a>
|
||||
</p>
|
||||
<div class="inputs">
|
||||
<ha-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.type"
|
||||
"ui.panel.config.tools.tabs.events.type"
|
||||
)}
|
||||
autofocus
|
||||
required
|
||||
@@ -67,7 +67,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
></ha-input>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.data"
|
||||
"ui.panel.config.tools.tabs.events.data"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -85,7 +85,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
appearance="filled"
|
||||
.disabled=${!this._isValid}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.fire_event"
|
||||
"ui.panel.config.tools.tabs.events.fire_event"
|
||||
)}</ha-button
|
||||
>
|
||||
</div>
|
||||
@@ -101,7 +101,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
<div>
|
||||
<h2>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.active_listeners"
|
||||
"ui.panel.config.tools.tabs.events.active_listeners"
|
||||
)}
|
||||
</h2>
|
||||
<events-list
|
||||
@@ -131,7 +131,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
if (!this._eventType) {
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.alert_event_type"
|
||||
"ui.panel.config.tools.tabs.events.alert_event_type"
|
||||
),
|
||||
});
|
||||
return;
|
||||
@@ -143,7 +143,7 @@ class HaPanelDevEvent extends LitElement {
|
||||
);
|
||||
fireEvent(this, "hass-notification", {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.events.notification_event_fired",
|
||||
"ui.panel.config.tools.tabs.events.notification_event_fired",
|
||||
{ type: this._eventType }
|
||||
),
|
||||
});
|
||||
@@ -221,6 +221,6 @@ class HaPanelDevEvent extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-event": HaPanelDevEvent;
|
||||
"tools-event": HaPanelDevEvent;
|
||||
}
|
||||
}
|
||||
+21
-25
@@ -12,42 +12,42 @@ import "../../../components/ha-tab-group";
|
||||
import "../../../components/ha-tab-group-tab";
|
||||
import "../../../components/ha-top-app-bar-fixed";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import "./developer-tools-router";
|
||||
import "./tools-router";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
const DEVELOPER_TOOLS_TABS = [
|
||||
const TOOLS_TABS = [
|
||||
{
|
||||
panel: "yaml",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.yaml.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.yaml.title",
|
||||
},
|
||||
{
|
||||
panel: "state",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.states.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.states.title",
|
||||
},
|
||||
{
|
||||
panel: "action",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.actions.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.actions.title",
|
||||
},
|
||||
{
|
||||
panel: "template",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.templates.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.templates.title",
|
||||
},
|
||||
{
|
||||
panel: "event",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.events.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.events.title",
|
||||
},
|
||||
{
|
||||
panel: "statistics",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.statistics.title",
|
||||
translationKey: "ui.panel.config.tools.tabs.statistics.title",
|
||||
},
|
||||
{
|
||||
panel: "assist",
|
||||
translationKey: "ui.panel.config.developer-tools.tabs.assist.tab",
|
||||
translationKey: "ui.panel.config.tools.tabs.assist.tab",
|
||||
},
|
||||
] as const;
|
||||
|
||||
@customElement("ha-panel-developer-tools")
|
||||
class PanelDeveloperTools extends LitElement {
|
||||
@customElement("ha-panel-tools")
|
||||
class PanelTools extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
@@ -68,9 +68,7 @@ class PanelDeveloperTools extends LitElement {
|
||||
@click=${this._handleBack}
|
||||
></ha-icon-button-arrow-prev>
|
||||
<div slot="title">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.dashboard.developer_tools.main"
|
||||
)}
|
||||
${this.hass.localize("ui.panel.config.dashboard.tools.main")}
|
||||
</div>
|
||||
<ha-dropdown slot="actionItems" @wa-select=${this._handleMenuAction}>
|
||||
<ha-icon-button
|
||||
@@ -79,13 +77,11 @@ class PanelDeveloperTools extends LitElement {
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
<ha-dropdown-item value="debug">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.debug.title"
|
||||
)}
|
||||
${this.hass.localize("ui.panel.config.tools.tabs.debug.title")}
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
<ha-tab-group @wa-tab-show=${this._handlePageSelected} slot="subRow">
|
||||
${DEVELOPER_TOOLS_TABS.map(
|
||||
${TOOLS_TABS.map(
|
||||
(tab) => html`
|
||||
<ha-tab-group-tab
|
||||
slot="nav"
|
||||
@@ -93,7 +89,7 @@ class PanelDeveloperTools extends LitElement {
|
||||
.active=${page === tab.panel}
|
||||
>
|
||||
<a
|
||||
href="/config/developer-tools/${tab.panel}"
|
||||
href="/config/tools/${tab.panel}"
|
||||
@click=${this._handleTabAnchorClick}
|
||||
>${this.hass.localize(tab.translationKey)}</a
|
||||
>
|
||||
@@ -101,11 +97,11 @@ class PanelDeveloperTools extends LitElement {
|
||||
`
|
||||
)}
|
||||
</ha-tab-group>
|
||||
<developer-tools-router
|
||||
<tools-router
|
||||
.route=${this.route}
|
||||
.narrow=${this.narrow}
|
||||
.hass=${this.hass}
|
||||
></developer-tools-router>
|
||||
></tools-router>
|
||||
</ha-top-app-bar-fixed>
|
||||
`;
|
||||
}
|
||||
@@ -124,7 +120,7 @@ class PanelDeveloperTools extends LitElement {
|
||||
return;
|
||||
}
|
||||
if (newPage !== this._page) {
|
||||
navigate(`/config/developer-tools/${newPage}`);
|
||||
navigate(`/config/tools/${newPage}`);
|
||||
} else {
|
||||
scrollTo({ behavior: "smooth", top: 0 });
|
||||
}
|
||||
@@ -133,7 +129,7 @@ class PanelDeveloperTools extends LitElement {
|
||||
private async _handleMenuAction(ev: HaDropdownSelectEvent) {
|
||||
const action = ev.detail.item.value;
|
||||
if (action === "debug") {
|
||||
navigate(`/config/developer-tools/debug`);
|
||||
navigate(`/config/tools/debug`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +142,7 @@ class PanelDeveloperTools extends LitElement {
|
||||
}
|
||||
|
||||
static readonly styles: CSSResultGroup = css`
|
||||
developer-tools-router {
|
||||
tools-router {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -170,6 +166,6 @@ class PanelDeveloperTools extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-panel-developer-tools": PanelDeveloperTools;
|
||||
"ha-panel-tools": PanelTools;
|
||||
}
|
||||
}
|
||||
+10
-14
@@ -24,7 +24,7 @@ import { haStyle } from "../../../../resources/styles";
|
||||
import { loadVirtualizer } from "../../../../resources/virtualizer";
|
||||
import { showToast } from "../../../../util/toast";
|
||||
|
||||
@customElement("developer-tools-state-renderer")
|
||||
@customElement("tools-state-renderer")
|
||||
class HaPanelDevStateRenderer extends LitElement {
|
||||
@property({ attribute: false }) public entities: HassEntity[] = [];
|
||||
|
||||
@@ -79,16 +79,12 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
<div class="row" role="row" aria-rowindex="1">
|
||||
<div class="header" role="columnheader">
|
||||
<span class="padded">
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.entity"
|
||||
)}
|
||||
${this._i18n.localize("ui.panel.config.tools.tabs.states.entity")}
|
||||
</span>
|
||||
</div>
|
||||
<div class="header" role="columnheader">
|
||||
<span class="padded">
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.state"
|
||||
)}
|
||||
${this._i18n.localize("ui.panel.config.tools.tabs.states.state")}
|
||||
</span>
|
||||
</div>
|
||||
<div class="header" role="columnheader" ?hidden=${!showDevice}>
|
||||
@@ -106,7 +102,7 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
<div class="header" role="columnheader">
|
||||
<span class="padded">
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.attributes"
|
||||
"ui.panel.config.tools.tabs.states.attributes"
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -134,7 +130,7 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
<div class="cell" role="cell" aria-colspan="5">
|
||||
<span class="padded">
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.no_entities"
|
||||
"ui.panel.config.tools.tabs.states.no_entities"
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -195,10 +191,10 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
@click=${this._copyEntity}
|
||||
.entity=${item}
|
||||
alt=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.copy_id"
|
||||
"ui.panel.config.tools.tabs.states.copy_id"
|
||||
)}
|
||||
title=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.copy_id"
|
||||
"ui.panel.config.tools.tabs.states.copy_id"
|
||||
)}
|
||||
.path=${mdiClipboardTextMultipleOutline}
|
||||
></ha-svg-icon>
|
||||
@@ -211,10 +207,10 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
@click=${this._entityMoreInfo}
|
||||
.entity=${item}
|
||||
alt=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.more_info"
|
||||
"ui.panel.config.tools.tabs.states.more_info"
|
||||
)}
|
||||
title=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.more_info"
|
||||
"ui.panel.config.tools.tabs.states.more_info"
|
||||
)}
|
||||
.path=${mdiInformationOutline}
|
||||
></ha-svg-icon>
|
||||
@@ -438,7 +434,7 @@ class HaPanelDevStateRenderer extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-state-renderer": HaPanelDevStateRenderer;
|
||||
"tools-state-renderer": HaPanelDevStateRenderer;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
+20
-20
@@ -42,7 +42,7 @@ import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant, HomeAssistantRegistries } from "../../../../types";
|
||||
import { showToast } from "../../../../util/toast";
|
||||
import "./developer-tools-state-renderer";
|
||||
import "./tools-state-renderer";
|
||||
|
||||
// Use virtualizer after threshold to avoid performance issues
|
||||
// NOTE: If virtualizer is used when filtered entiity state
|
||||
@@ -51,7 +51,7 @@ import "./developer-tools-state-renderer";
|
||||
// virtualized list, an undesirable effect.
|
||||
const VIRTUALIZE_THRESHOLD = 100;
|
||||
|
||||
@customElement("developer-tools-state")
|
||||
@customElement("tools-state")
|
||||
class HaPanelDevState extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -165,7 +165,7 @@ class HaPanelDevState extends LitElement {
|
||||
<div class="heading">
|
||||
<h1>
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.current_entities"
|
||||
"ui.panel.config.tools.tabs.states.current_entities"
|
||||
)}
|
||||
</h1>
|
||||
${
|
||||
@@ -192,7 +192,7 @@ class HaPanelDevState extends LitElement {
|
||||
@change=${this._saveAttributeCheckboxState}
|
||||
>
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.attributes"
|
||||
"ui.panel.config.tools.tabs.states.attributes"
|
||||
)}
|
||||
</ha-checkbox>
|
||||
`
|
||||
@@ -201,7 +201,7 @@ class HaPanelDevState extends LitElement {
|
||||
</div>
|
||||
<ha-expansion-panel
|
||||
.header=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.set_state"
|
||||
"ui.panel.config.tools.tabs.states.set_state"
|
||||
)}
|
||||
outlined
|
||||
.expanded=${this._expanded}
|
||||
@@ -209,10 +209,10 @@ class HaPanelDevState extends LitElement {
|
||||
>
|
||||
<p>
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.description1"
|
||||
"ui.panel.config.tools.tabs.states.description1"
|
||||
)}<br />
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.description2"
|
||||
"ui.panel.config.tools.tabs.states.description2"
|
||||
)}
|
||||
</p>
|
||||
${
|
||||
@@ -237,7 +237,7 @@ class HaPanelDevState extends LitElement {
|
||||
.path=${mdiContentCopy}
|
||||
@click=${this._copyStateEntity}
|
||||
title=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.copy_id"
|
||||
"ui.panel.config.tools.tabs.states.copy_id"
|
||||
)}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
@@ -246,7 +246,7 @@ class HaPanelDevState extends LitElement {
|
||||
}
|
||||
<ha-input
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.state"
|
||||
"ui.panel.config.tools.tabs.states.state"
|
||||
)}
|
||||
required
|
||||
autocapitalize="none"
|
||||
@@ -259,7 +259,7 @@ class HaPanelDevState extends LitElement {
|
||||
></ha-input>
|
||||
<p>
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.state_attributes"
|
||||
"ui.panel.config.tools.tabs.states.state_attributes"
|
||||
)}
|
||||
</p>
|
||||
<ha-yaml-editor
|
||||
@@ -274,7 +274,7 @@ class HaPanelDevState extends LitElement {
|
||||
.disabled=${!this._validJSON}
|
||||
raised
|
||||
>${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.set_state"
|
||||
"ui.panel.config.tools.tabs.states.set_state"
|
||||
)}</ha-button
|
||||
>
|
||||
<ha-icon-button
|
||||
@@ -290,7 +290,7 @@ class HaPanelDevState extends LitElement {
|
||||
? html`<p>
|
||||
<b
|
||||
>${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.last_changed"
|
||||
"ui.panel.config.tools.tabs.states.last_changed"
|
||||
)}:</b
|
||||
><br />
|
||||
<a href=${this._historyFromLastChanged(this._entity)}
|
||||
@@ -300,7 +300,7 @@ class HaPanelDevState extends LitElement {
|
||||
<p>
|
||||
<b
|
||||
>${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.last_updated"
|
||||
"ui.panel.config.tools.tabs.states.last_updated"
|
||||
)}:</b
|
||||
><br />
|
||||
<a href=${this._historyFromLastUpdated(this._entity)}
|
||||
@@ -312,7 +312,7 @@ class HaPanelDevState extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
<developer-tools-state-renderer
|
||||
<tools-state-renderer
|
||||
.narrow=${this.narrow}
|
||||
.entities=${entities}
|
||||
.virtualize=${entities.length > VIRTUALIZE_THRESHOLD}
|
||||
@@ -324,7 +324,7 @@ class HaPanelDevState extends LitElement {
|
||||
<ha-input-search
|
||||
slot="filter-entities"
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.filter_entities"
|
||||
"ui.panel.config.tools.tabs.states.filter_entities"
|
||||
)}
|
||||
.value=${this._entityFilter}
|
||||
@input=${this._entityFilterChanged}
|
||||
@@ -332,7 +332,7 @@ class HaPanelDevState extends LitElement {
|
||||
<ha-input-search
|
||||
slot="filter-states"
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.filter_states"
|
||||
"ui.panel.config.tools.tabs.states.filter_states"
|
||||
)}
|
||||
type="search"
|
||||
.value=${this._stateFilter}
|
||||
@@ -357,13 +357,13 @@ class HaPanelDevState extends LitElement {
|
||||
<ha-input-search
|
||||
slot="filter-attributes"
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.filter_attributes"
|
||||
"ui.panel.config.tools.tabs.states.filter_attributes"
|
||||
)}
|
||||
type="search"
|
||||
.value=${this._attributeFilter}
|
||||
@input=${this._attributeFilterChanged}
|
||||
></ha-input-search>
|
||||
</developer-tools-state-renderer>
|
||||
</tools-state-renderer>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ class HaPanelDevState extends LitElement {
|
||||
if (!this._entityId) {
|
||||
showAlertDialog(this, {
|
||||
text: this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.states.alert_entity_field"
|
||||
"ui.panel.config.tools.tabs.states.alert_entity_field"
|
||||
),
|
||||
});
|
||||
return;
|
||||
@@ -758,6 +758,6 @@ class HaPanelDevState extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-state": HaPanelDevState;
|
||||
"tools-state": HaPanelDevState;
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -132,7 +132,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
@click=${this._fetchOutliers}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.outliers"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.outliers"
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-button slot="primaryAction" data-dialog="close">
|
||||
@@ -156,7 +156,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
@click=${this._fixIssue}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.adjust"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.adjust"
|
||||
)}</ha-button
|
||||
>
|
||||
`;
|
||||
@@ -166,7 +166,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
<ha-dialog
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.title"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.title"
|
||||
)}
|
||||
.preventScrimClose=${this.isDirtyState}
|
||||
@closed=${this._dialogClosed}
|
||||
@@ -194,7 +194,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
} else if (this._statsHour.length < 1 && this._stats5min.length < 1) {
|
||||
stats = html`<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.no_statistics_found"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.no_statistics_found"
|
||||
)}
|
||||
</p>`;
|
||||
} else {
|
||||
@@ -234,20 +234,20 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
return html`
|
||||
<div class="text-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.info_text_1"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.info_text_1"
|
||||
)}
|
||||
</div>
|
||||
<div class="text-content">
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.statistic"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.statistic"
|
||||
)}</b
|
||||
>
|
||||
${this._params!.statistic.statistic_id}
|
||||
</div>
|
||||
<ha-selector-datetime
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.pick_a_time"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.pick_a_time"
|
||||
)}
|
||||
.hass=${this.hass}
|
||||
.selector=${this._dateTimeSelector}
|
||||
@@ -289,7 +289,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
<div class="text-content">
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.statistic"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.statistic"
|
||||
)}</b
|
||||
>
|
||||
${this._params!.statistic.statistic_id}
|
||||
@@ -298,7 +298,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
<div class="table-row">
|
||||
<span
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.start"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.start"
|
||||
)}</span
|
||||
>
|
||||
<span
|
||||
@@ -313,7 +313,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
<div class="table-row">
|
||||
<span
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.end"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.end"
|
||||
)}</span
|
||||
>
|
||||
<span
|
||||
@@ -327,7 +327,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
|
||||
<ha-selector-number
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.new_value"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.new_value"
|
||||
)}
|
||||
.hass=${this.hass}
|
||||
.selector=${this._amountSelector(unit || undefined, this._precision)}
|
||||
@@ -506,7 +506,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
this._busy = false;
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.error_sum_adjusted",
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.error_sum_adjusted",
|
||||
{ message: err.message || err }
|
||||
),
|
||||
});
|
||||
@@ -514,7 +514,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends DirtyStateProvid
|
||||
}
|
||||
showToast(this, {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.adjust_sum.sum_adjusted"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.adjust_sum.sum_adjusted"
|
||||
),
|
||||
});
|
||||
this._markDirtyStateClean();
|
||||
+8
-8
@@ -53,13 +53,13 @@ export class DialogStatisticsFixUnitsChanged extends LitElement {
|
||||
<ha-dialog
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.title"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.title"
|
||||
)}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.info_text_1",
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.info_text_1",
|
||||
{
|
||||
name: getStatisticLabel(
|
||||
this.hass,
|
||||
@@ -72,16 +72,16 @@ export class DialogStatisticsFixUnitsChanged extends LitElement {
|
||||
}
|
||||
)}<br />
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.info_text_2"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.info_text_2"
|
||||
)}<br />
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.info_text_3"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.info_text_3"
|
||||
)}
|
||||
</p>
|
||||
|
||||
<ha-radio-group
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.how_to_fix"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.how_to_fix"
|
||||
)}
|
||||
.value=${this._action}
|
||||
name="action"
|
||||
@@ -89,13 +89,13 @@ export class DialogStatisticsFixUnitsChanged extends LitElement {
|
||||
>
|
||||
<ha-radio-option value="update" autofocus>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.update",
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.update",
|
||||
this._params.issue.data
|
||||
)}
|
||||
</ha-radio-option>
|
||||
<ha-radio-option value="clear">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.fix_issue.units_changed.clear`
|
||||
`ui.panel.config.tools.tabs.statistics.fix_issue.units_changed.clear`
|
||||
)}
|
||||
</ha-radio-option>
|
||||
</ha-radio-group>
|
||||
@@ -110,7 +110,7 @@ export class DialogStatisticsFixUnitsChanged extends LitElement {
|
||||
</ha-button>
|
||||
<ha-button slot="primaryAction" @click=${this._fixIssue}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.fix"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.fix"
|
||||
)}
|
||||
</ha-button>
|
||||
</ha-dialog-footer>
|
||||
+17
-17
@@ -50,13 +50,13 @@ export class DialogStatisticsFix extends LitElement {
|
||||
<ha-dialog
|
||||
.open=${this._open}
|
||||
header-title=${this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.fix_issue.${issue.type}.title`
|
||||
`ui.panel.config.tools.tabs.statistics.fix_issue.${issue.type}.title`
|
||||
)}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_1`,
|
||||
`ui.panel.config.tools.tabs.statistics.fix_issue.${issue.type}.info_text_1`,
|
||||
{
|
||||
name: getStatisticLabel(
|
||||
this.hass,
|
||||
@@ -67,24 +67,24 @@ export class DialogStatisticsFix extends LitElement {
|
||||
...(issue.type === "mean_type_changed"
|
||||
? {
|
||||
metadata_mean_type: this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.mean_type.${issue.data.metadata_mean_type}`
|
||||
`ui.panel.config.tools.tabs.statistics.mean_type.${issue.data.metadata_mean_type}`
|
||||
),
|
||||
state_mean_type: this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.mean_type.${issue.data.state_mean_type}`
|
||||
`ui.panel.config.tools.tabs.statistics.mean_type.${issue.data.state_mean_type}`
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
)}<br /><br />
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_2`,
|
||||
`ui.panel.config.tools.tabs.statistics.fix_issue.${issue.type}.info_text_2`,
|
||||
{ statistic_id: issue.data.statistic_id }
|
||||
)}
|
||||
${
|
||||
issue.type === "mean_type_changed"
|
||||
? html`<br /><br />
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.mean_type_changed.info_text_3",
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.mean_type_changed.info_text_3",
|
||||
{ statistic_id: issue.data.statistic_id }
|
||||
)}`
|
||||
: issue.type === "entity_not_recorded"
|
||||
@@ -98,7 +98,7 @@ export class DialogStatisticsFix extends LitElement {
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
|
||||
)}</a
|
||||
>`
|
||||
: issue.type === "entity_no_longer_recorded"
|
||||
@@ -111,22 +111,22 @@ export class DialogStatisticsFix extends LitElement {
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link"
|
||||
)}</a
|
||||
><br /><br />
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4"
|
||||
)}`
|
||||
: issue.type === "state_class_removed"
|
||||
? html`<ul>
|
||||
<li>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_3"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.state_class_removed.info_text_3"
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.state_class_removed.info_text_4"
|
||||
)}
|
||||
<a
|
||||
href="https://developers.home-assistant.io/docs/core/entity/sensor/#long-term-statistics"
|
||||
@@ -134,18 +134,18 @@ export class DialogStatisticsFix extends LitElement {
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_4_link"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.state_class_removed.info_text_4_link"
|
||||
)}</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_5"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.state_class_removed.info_text_5"
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_6",
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.state_class_removed.info_text_6",
|
||||
{ statistic_id: issue.data.statistic_id }
|
||||
)}`
|
||||
: nothing
|
||||
@@ -195,15 +195,15 @@ export class DialogStatisticsFix extends LitElement {
|
||||
title:
|
||||
err.code === "timeout"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.clearing_timeout_title"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.clearing_timeout_title"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.clearing_failed"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.clearing_failed"
|
||||
),
|
||||
text:
|
||||
err.code === "timeout"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.clearing_timeout_text"
|
||||
"ui.panel.config.tools.tabs.statistics.fix_issue.clearing_timeout_text"
|
||||
)
|
||||
: err.message,
|
||||
});
|
||||
+19
-23
@@ -98,7 +98,7 @@ type DisplayedStatisticData = StatisticData & {
|
||||
issues_string?: string;
|
||||
};
|
||||
|
||||
@customElement("developer-tools-statistics")
|
||||
@customElement("tools-statistics")
|
||||
class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
@property({ type: Boolean, reflect: true }) public narrow = false;
|
||||
|
||||
@@ -188,7 +188,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
?.map(
|
||||
(issue) =>
|
||||
localize(
|
||||
`ui.panel.config.developer-tools.tabs.statistics.issues.${issue.type}`,
|
||||
`ui.panel.config.tools.tabs.statistics.issues.${issue.type}`,
|
||||
issue.data
|
||||
) || issue.type
|
||||
)
|
||||
@@ -204,7 +204,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
): DataTableColumnContainer<DisplayedStatisticData> => ({
|
||||
displayName: {
|
||||
title: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.name"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.name"
|
||||
),
|
||||
main: true,
|
||||
sortable: true,
|
||||
@@ -225,7 +225,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
area: getAreaTableColumn(localize),
|
||||
statistic_id: {
|
||||
title: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.statistic_id"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.statistic_id"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
@@ -233,7 +233,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
},
|
||||
statistics_unit_of_measurement: {
|
||||
title: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.statistics_unit"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.statistics_unit"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
@@ -241,7 +241,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
},
|
||||
source: {
|
||||
title: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.source"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.source"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
@@ -249,7 +249,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
},
|
||||
issues_string: {
|
||||
title: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.issue"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.issue"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
@@ -259,14 +259,12 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
template: (statistic) =>
|
||||
html`${
|
||||
statistic.issues_string ??
|
||||
localize("ui.panel.config.developer-tools.tabs.statistics.no_issue")
|
||||
localize("ui.panel.config.tools.tabs.statistics.no_issue")
|
||||
}`,
|
||||
},
|
||||
fix: {
|
||||
title: "",
|
||||
label: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.fix_issue.fix"
|
||||
),
|
||||
label: localize("ui.panel.config.tools.tabs.statistics.fix_issue.fix"),
|
||||
type: "icon",
|
||||
template: (statistic) =>
|
||||
html`${
|
||||
@@ -281,8 +279,8 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
statistic.issues.some((issue) =>
|
||||
FIXABLE_ISSUES.includes(issue.type)
|
||||
)
|
||||
? "ui.panel.config.developer-tools.tabs.statistics.fix_issue.fix"
|
||||
: "ui.panel.config.developer-tools.tabs.statistics.fix_issue.info"
|
||||
? "ui.panel.config.tools.tabs.statistics.fix_issue.fix"
|
||||
: "ui.panel.config.tools.tabs.statistics.fix_issue.info"
|
||||
)}
|
||||
</ha-button>`
|
||||
: "—"
|
||||
@@ -293,9 +291,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
},
|
||||
actions: {
|
||||
title: "",
|
||||
label: localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.adjust_sum"
|
||||
),
|
||||
label: localize("ui.panel.config.tools.tabs.statistics.adjust_sum"),
|
||||
type: "icon-button",
|
||||
showNarrow: true,
|
||||
template: (statistic) =>
|
||||
@@ -303,7 +299,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
? html`
|
||||
<ha-icon-button
|
||||
.label=${localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.adjust_sum"
|
||||
"ui.panel.config.tools.tabs.statistics.adjust_sum"
|
||||
)}
|
||||
.path=${mdiSlopeUphill}
|
||||
.statistic=${statistic}
|
||||
@@ -500,7 +496,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item @click=${this._selectAllIssues}>
|
||||
${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.select_all_issues"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.select_all_issues"
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
<ha-dropdown-item @click=${this._selectNone}>
|
||||
@@ -529,7 +525,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
</div>
|
||||
<ha-assist-chip
|
||||
.label=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.delete_selected"
|
||||
"ui.panel.config.tools.tabs.statistics.delete_selected"
|
||||
)}
|
||||
.disabled=${!this._selected.length}
|
||||
@click=${this._clearSelected}
|
||||
@@ -563,7 +559,7 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
this._registries.areas
|
||||
)}
|
||||
.noDataText=${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.data_table.no_statistics"
|
||||
"ui.panel.config.tools.tabs.statistics.data_table.no_statistics"
|
||||
)}
|
||||
.filter=${this.filter}
|
||||
.selectable=${this._selectMode}
|
||||
@@ -770,10 +766,10 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
|
||||
await showConfirmationDialog(this, {
|
||||
title: this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.multi_delete.title"
|
||||
"ui.panel.config.tools.tabs.statistics.multi_delete.title"
|
||||
),
|
||||
text: html`${this._i18n.localize(
|
||||
"ui.panel.config.developer-tools.tabs.statistics.multi_delete.info_text",
|
||||
"ui.panel.config.tools.tabs.statistics.multi_delete.info_text",
|
||||
{ statistic_count: deletableIds.length }
|
||||
)}`,
|
||||
confirmText: this._i18n.localize("ui.common.delete"),
|
||||
@@ -925,6 +921,6 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-statistics": HaPanelDevStatistics;
|
||||
"tools-statistics": HaPanelDevStatistics;
|
||||
}
|
||||
}
|
||||
+67
-41
@@ -4,6 +4,7 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
||||
import type { LocalizeKeys } from "../../../../common/translations/localize";
|
||||
import { debounce } from "../../../../common/util/debounce";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-button";
|
||||
@@ -40,7 +41,16 @@ For loop example getting entity values in the weather domain:
|
||||
{{ state.name | lower }} is {{state.state_with_unit}}
|
||||
{%- endfor %}.`;
|
||||
|
||||
@customElement("developer-tools-template")
|
||||
// key resolves the label/description translation keys; path is passed through
|
||||
// documentationUrl().
|
||||
const TEMPLATE_DOCS_LINKS: { key: string; path: string }[] = [
|
||||
{ key: "docs_introduction", path: "/docs/templating/introduction/" },
|
||||
{ key: "docs_states", path: "/docs/templating/states/" },
|
||||
{ key: "docs_debugging", path: "/docs/templating/debugging/" },
|
||||
{ key: "docs_functions", path: "/template-functions/" },
|
||||
];
|
||||
|
||||
@customElement("tools-template")
|
||||
class HaPanelDevTemplate extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@@ -108,7 +118,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
<div class="content">
|
||||
<ha-expansion-panel
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.about"
|
||||
"ui.panel.config.tools.tabs.templates.about"
|
||||
)}
|
||||
outlined
|
||||
.expanded=${this._descriptionExpanded}
|
||||
@@ -117,34 +127,39 @@ class HaPanelDevTemplate extends LitElement {
|
||||
<div class="description">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.description"
|
||||
"ui.panel.config.tools.tabs.templates.description"
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.tools.tabs.templates.engine_info"
|
||||
)}
|
||||
</p>
|
||||
<h3>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.tools.tabs.templates.learn_more"
|
||||
)}
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://jinja.palletsprojects.com/en/latest/templates/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.jinja_documentation"
|
||||
)}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href=${documentationUrl(
|
||||
this.hass,
|
||||
"/docs/configuration/templating/"
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.template_extensions"
|
||||
)}</a
|
||||
>
|
||||
</li>
|
||||
${TEMPLATE_DOCS_LINKS.map(
|
||||
(link) => html`
|
||||
<li>
|
||||
<a
|
||||
href=${documentationUrl(this.hass, link.path)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
`ui.panel.config.tools.tabs.templates.${link.key}` as LocalizeKeys
|
||||
)}</a
|
||||
>
|
||||
<span class="link-description"
|
||||
>${this.hass.localize(
|
||||
`ui.panel.config.tools.tabs.templates.${link.key}_description` as LocalizeKeys
|
||||
)}</span
|
||||
>
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
@@ -159,7 +174,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
<ha-card
|
||||
class="edit-pane"
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.editor"
|
||||
"ui.panel.config.tools.tabs.templates.editor"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
@@ -177,7 +192,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
<div class="card-actions">
|
||||
<ha-button appearance="plain" @click=${this._restoreDemo}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.reset"
|
||||
"ui.panel.config.tools.tabs.templates.reset"
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-button appearance="plain" @click=${this._clear}>
|
||||
@@ -186,7 +201,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
</div>
|
||||
<ha-tip>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.keyboard_tip",
|
||||
"ui.panel.config.tools.tabs.templates.keyboard_tip",
|
||||
{
|
||||
autocomplete: html`<kbd>Ctrl</kbd>+<kbd>Space</kbd>`,
|
||||
}
|
||||
@@ -197,7 +212,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
<ha-card
|
||||
class="render-pane"
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.result"
|
||||
"ui.panel.config.tools.tabs.templates.result"
|
||||
)}
|
||||
>
|
||||
<div class="card-content ha-scrollbar">
|
||||
@@ -231,7 +246,7 @@ ${
|
||||
}</pre>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.result_type"
|
||||
"ui.panel.config.tools.tabs.templates.result_type"
|
||||
)}:
|
||||
${resultType}
|
||||
</p>
|
||||
@@ -240,7 +255,7 @@ ${
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.time"
|
||||
"ui.panel.config.tools.tabs.templates.time"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
@@ -253,7 +268,7 @@ ${
|
||||
? html`
|
||||
<p class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.all_listeners"
|
||||
"ui.panel.config.tools.tabs.templates.all_listeners"
|
||||
)}
|
||||
</p>
|
||||
`
|
||||
@@ -262,7 +277,7 @@ ${
|
||||
? html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.listeners"
|
||||
"ui.panel.config.tools.tabs.templates.listeners"
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
@@ -273,7 +288,7 @@ ${
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.domain"
|
||||
"ui.panel.config.tools.tabs.templates.domain"
|
||||
)}</b
|
||||
>: ${domain}
|
||||
</li>
|
||||
@@ -286,7 +301,7 @@ ${
|
||||
<li>
|
||||
<b
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.entity"
|
||||
"ui.panel.config.tools.tabs.templates.entity"
|
||||
)}</b
|
||||
>: ${entity_id}
|
||||
</li>
|
||||
@@ -297,7 +312,7 @@ ${
|
||||
: !this._templateResult.listeners.time
|
||||
? html`<span class="all_listeners">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.no_listeners"
|
||||
"ui.panel.config.tools.tabs.templates.no_listeners"
|
||||
)}
|
||||
</span>`
|
||||
: nothing
|
||||
@@ -441,6 +456,17 @@ ${
|
||||
margin-block-start: var(--ha-space-1);
|
||||
margin-block-end: var(--ha-space-1);
|
||||
}
|
||||
.description > h3 {
|
||||
font-size: var(--ha-font-size-m);
|
||||
font-weight: var(--ha-font-weight-medium);
|
||||
margin-block-end: var(--ha-space-1);
|
||||
}
|
||||
.description li {
|
||||
margin-block-end: var(--ha-space-1);
|
||||
}
|
||||
.description .link-description {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.render-pane .card-content {
|
||||
user-select: text;
|
||||
@@ -596,7 +622,7 @@ ${
|
||||
if (
|
||||
!(await showConfirmationDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.confirm_reset"
|
||||
"ui.panel.config.tools.tabs.templates.confirm_reset"
|
||||
),
|
||||
warning: true,
|
||||
}))
|
||||
@@ -612,7 +638,7 @@ ${
|
||||
if (
|
||||
!(await showConfirmationDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.templates.confirm_clear"
|
||||
"ui.panel.config.tools.tabs.templates.confirm_clear"
|
||||
),
|
||||
warning: true,
|
||||
}))
|
||||
@@ -632,6 +658,6 @@ ${
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-template": HaPanelDevTemplate;
|
||||
"tools-template": HaPanelDevTemplate;
|
||||
}
|
||||
}
|
||||
+19
-19
@@ -3,8 +3,8 @@ import type { RouterOptions } from "../../../layouts/hass-router-page";
|
||||
import { HassRouterPage } from "../../../layouts/hass-router-page";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
|
||||
@customElement("developer-tools-router")
|
||||
class DeveloperToolsRouter extends HassRouterPage {
|
||||
@customElement("tools-router")
|
||||
class ToolsRouter extends HassRouterPage {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
@@ -22,37 +22,37 @@ class DeveloperToolsRouter extends HassRouterPage {
|
||||
showLoading: true,
|
||||
routes: {
|
||||
event: {
|
||||
tag: "developer-tools-event",
|
||||
load: () => import("./event/developer-tools-event"),
|
||||
tag: "tools-event",
|
||||
load: () => import("./event/tools-event"),
|
||||
},
|
||||
service: "action",
|
||||
action: {
|
||||
tag: "developer-tools-action",
|
||||
load: () => import("./action/developer-tools-action"),
|
||||
tag: "tools-action",
|
||||
load: () => import("./action/tools-action"),
|
||||
},
|
||||
state: {
|
||||
tag: "developer-tools-state",
|
||||
load: () => import("./state/developer-tools-state"),
|
||||
tag: "tools-state",
|
||||
load: () => import("./state/tools-state"),
|
||||
},
|
||||
template: {
|
||||
tag: "developer-tools-template",
|
||||
load: () => import("./template/developer-tools-template"),
|
||||
tag: "tools-template",
|
||||
load: () => import("./template/tools-template"),
|
||||
},
|
||||
statistics: {
|
||||
tag: "developer-tools-statistics",
|
||||
load: () => import("./statistics/developer-tools-statistics"),
|
||||
tag: "tools-statistics",
|
||||
load: () => import("./statistics/tools-statistics"),
|
||||
},
|
||||
yaml: {
|
||||
tag: "developer-yaml-config",
|
||||
load: () => import("./yaml_configuration/developer-yaml-config"),
|
||||
tag: "tools-yaml-config",
|
||||
load: () => import("./yaml_configuration/tools-yaml-config"),
|
||||
},
|
||||
assist: {
|
||||
tag: "developer-tools-assist",
|
||||
load: () => import("./assist/developer-tools-assist"),
|
||||
tag: "tools-assist",
|
||||
load: () => import("./assist/tools-assist"),
|
||||
},
|
||||
debug: {
|
||||
tag: "developer-tools-debug",
|
||||
load: () => import("./debug/developer-tools-debug"),
|
||||
tag: "tools-debug",
|
||||
load: () => import("./debug/tools-debug"),
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -77,6 +77,6 @@ class DeveloperToolsRouter extends HassRouterPage {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-router": DeveloperToolsRouter;
|
||||
"tools-router": ToolsRouter;
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -16,7 +16,7 @@ import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant, Route, TranslationDict } from "../../../../types";
|
||||
|
||||
type ReloadableDomain = Exclude<
|
||||
keyof TranslationDict["ui"]["panel"]["config"]["developer-tools"]["tabs"]["yaml"]["section"]["reloading"],
|
||||
keyof TranslationDict["ui"]["panel"]["config"]["tools"]["tabs"]["yaml"]["section"]["reloading"],
|
||||
"heading" | "introduction" | "reload"
|
||||
>;
|
||||
|
||||
@@ -25,8 +25,8 @@ interface TranslatedReloadableDomain {
|
||||
name: string;
|
||||
}
|
||||
|
||||
@customElement("developer-yaml-config")
|
||||
export class DeveloperYamlConfig extends LitElement {
|
||||
@customElement("tools-yaml-config")
|
||||
export class ToolsYamlConfig extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
@@ -61,10 +61,10 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
domain,
|
||||
name:
|
||||
this.hass.localize(
|
||||
`ui.panel.config.developer-tools.tabs.yaml.section.reloading.${domain}`
|
||||
`ui.panel.config.tools.tabs.yaml.section.reloading.${domain}`
|
||||
) ||
|
||||
this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.reloading.reload",
|
||||
"ui.panel.config.tools.tabs.yaml.section.reloading.reload",
|
||||
{ domain: domainToName(this.hass.localize, domain) }
|
||||
),
|
||||
}))
|
||||
@@ -80,12 +80,12 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
<ha-card
|
||||
outlined
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.heading"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.heading"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.introduction"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.introduction"
|
||||
)}
|
||||
${
|
||||
!this._validateResult
|
||||
@@ -103,10 +103,10 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
${
|
||||
this._validateResult.result === "valid"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.valid"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.valid"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.invalid"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.invalid"
|
||||
)
|
||||
}
|
||||
</div>
|
||||
@@ -116,7 +116,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
? html`<ha-alert
|
||||
alert-type="error"
|
||||
.title=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.errors"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.errors"
|
||||
)}
|
||||
>
|
||||
<!-- prettier-ignore -->
|
||||
@@ -131,7 +131,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
.title=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.warnings"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.warnings"
|
||||
)}
|
||||
>
|
||||
<!-- prettier-ignore -->
|
||||
@@ -148,7 +148,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
<div class="card-actions">
|
||||
<ha-button appearance="plain" @click=${this._validateConfig}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.validation.check_config"
|
||||
"ui.panel.config.tools.tabs.yaml.section.validation.check_config"
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
@@ -158,7 +158,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
.disabled=${this._validateResult?.result === "invalid"}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.server_management.restart"
|
||||
"ui.panel.config.tools.tabs.yaml.section.server_management.restart"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
@@ -166,18 +166,18 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
<ha-card
|
||||
outlined
|
||||
header=${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.reloading.heading"
|
||||
"ui.panel.config.tools.tabs.yaml.section.reloading.heading"
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.reloading.introduction"
|
||||
"ui.panel.config.tools.tabs.yaml.section.reloading.introduction"
|
||||
)}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-service-button domain="homeassistant" service="reload_all"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.reloading.all"
|
||||
"ui.panel.config.tools.tabs.yaml.section.reloading.all"
|
||||
)}
|
||||
</ha-call-service-button>
|
||||
</div>
|
||||
@@ -186,7 +186,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
domain="homeassistant"
|
||||
service="reload_core_config"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.developer-tools.tabs.yaml.section.reloading.core"
|
||||
"ui.panel.config.tools.tabs.yaml.section.reloading.core"
|
||||
)}
|
||||
</ha-call-service-button>
|
||||
</div>
|
||||
@@ -269,6 +269,6 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-yaml-config": DeveloperYamlConfig;
|
||||
"tools-yaml-config": ToolsYamlConfig;
|
||||
}
|
||||
}
|
||||
@@ -369,6 +369,22 @@ export function computeStatMidpoint(
|
||||
return (start + end) / 2;
|
||||
}
|
||||
|
||||
const PERIOD_MS: Record<string, number> = {
|
||||
"5minute": 5 * 60 * 1000,
|
||||
hour: 60 * 60 * 1000,
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset from a period's start to its midpoint, for centering sub-daily bars
|
||||
* (and forecast lines) between axis ticks — 0 for daily+ periods, which sit at
|
||||
* the start. Derived from the period, not from the data, so the first/only
|
||||
* bucket centers identically to every other bucket. (Previously estimated from
|
||||
* the gap between the first two entries, which collapsed to 0 with one bucket.)
|
||||
*/
|
||||
export function getPeriodMidpointOffset(period: string): number {
|
||||
return (PERIOD_MS[period] ?? 0) / 2;
|
||||
}
|
||||
|
||||
export interface UntrackedSplit {
|
||||
/** Untracked consumption per timestamp, clamped to >= 0. */
|
||||
positive: Record<number, number>;
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
type EnergyDataPoint,
|
||||
fillDataGapsAndRoundCaps,
|
||||
getCompareTransform,
|
||||
getPeriodMidpointOffset,
|
||||
splitUntrackedConsumption,
|
||||
} from "./common/energy-chart-options";
|
||||
import { getEnergyColor } from "./common/color";
|
||||
@@ -237,12 +238,15 @@ function processUntracked(
|
||||
const sortedTimes = Object.keys(consumptionData.used_total).sort(
|
||||
(a, b) => Number(a) - Number(b)
|
||||
);
|
||||
// Only start timestamps available here, so estimate midpoint from the gap
|
||||
// between the first two entries. Assumes uniform period spacing.
|
||||
// Only start timestamps available here, so center sub-daily bars using the
|
||||
// gap between the first two entries. With a lone first-of-day bucket there is
|
||||
// no gap to measure, so fall back to the nominal period midpoint — which
|
||||
// matches the device bars' computeStatMidpoint instead of collapsing to the
|
||||
// period start and splitting into a second stack.
|
||||
const periodOffset =
|
||||
(period === "hour" || period === "5minute") && sortedTimes.length >= 2
|
||||
? (Number(sortedTimes[1]) - Number(sortedTimes[0])) / 2
|
||||
: 0;
|
||||
: getPeriodMidpointOffset(period);
|
||||
sortedTimes.forEach((time) => {
|
||||
const ts = Number(time);
|
||||
const x = compare
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
type EnergyDataPoint,
|
||||
fillDataGapsAndRoundCaps,
|
||||
getCompareTransform,
|
||||
getPeriodMidpointOffset,
|
||||
} from "./common/energy-chart-options";
|
||||
|
||||
export interface EnergySolarGraphDataParams {
|
||||
@@ -323,7 +324,8 @@ function processForecast(
|
||||
const solarForecastData: LineSeriesOption["data"] = [];
|
||||
// Only center forecast points for sub-daily periods to align with bars.
|
||||
// Only start timestamps available, so estimate midpoint from the gap
|
||||
// between the first two entries. Assumes uniform spacing.
|
||||
// between the first two entries; with a lone first bucket there is no
|
||||
// gap to measure, so fall back to the nominal period midpoint.
|
||||
let forecastOffset = 0;
|
||||
if (period === "hour" || period === "5minute") {
|
||||
const forecastTimes = Object.keys(forecastsData)
|
||||
@@ -332,7 +334,7 @@ function processForecast(
|
||||
forecastOffset =
|
||||
forecastTimes.length >= 2
|
||||
? (forecastTimes[1] - forecastTimes[0]) / 2
|
||||
: 0;
|
||||
: getPeriodMidpointOffset(period);
|
||||
}
|
||||
for (const [time, value] of Object.entries(forecastsData)) {
|
||||
const kWh = value / 1000;
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
fillDataGapsAndRoundCaps,
|
||||
getCommonOptions,
|
||||
getCompareTransform,
|
||||
getPeriodMidpointOffset,
|
||||
} from "./common/energy-chart-options";
|
||||
import type { HaECOption } from "../../../../resources/echarts/echarts";
|
||||
import type { CustomLegendOption } from "../../../../components/chart/ha-chart-base";
|
||||
@@ -595,14 +596,15 @@ export class HuiEnergyUsageGraphCard
|
||||
|
||||
const uniqueKeys = summedData.timestamps;
|
||||
|
||||
// Only center bars for sub-daily periods (hour/5min).
|
||||
// Only start timestamps available here, so estimate midpoint from the gap
|
||||
// between the first two entries. Assumes uniform period spacing.
|
||||
// Only center bars for sub-daily periods (hour/5min). Only start timestamps
|
||||
// available here, so estimate midpoint from the gap between the first two
|
||||
// entries; with a lone first-of-day bucket there is no gap to measure, so
|
||||
// fall back to the nominal period midpoint so the bar stays centered.
|
||||
const period = getSuggestedPeriod(this._start, this._end);
|
||||
const periodOffset =
|
||||
(period === "hour" || period === "5minute") && uniqueKeys.length >= 2
|
||||
? (uniqueKeys[1] - uniqueKeys[0]) / 2
|
||||
: 0;
|
||||
: getPeriodMidpointOffset(period);
|
||||
|
||||
const compareTransform = getCompareTransform(
|
||||
this._start,
|
||||
|
||||
@@ -25,35 +25,65 @@ export const getMyRedirects = (): Redirects => ({
|
||||
application_credentials: {
|
||||
redirect: "/config/application_credentials",
|
||||
},
|
||||
tools_assist: {
|
||||
redirect: "/config/tools/assist",
|
||||
},
|
||||
tools_debug: {
|
||||
redirect: "/config/tools/debug",
|
||||
},
|
||||
tools_states: {
|
||||
redirect: "/config/tools/state",
|
||||
},
|
||||
tools_actions: {
|
||||
redirect: "/config/tools/action",
|
||||
},
|
||||
tools_perform_action: {
|
||||
redirect: "/config/tools/action",
|
||||
params: {
|
||||
service: "string",
|
||||
},
|
||||
},
|
||||
tools_template: {
|
||||
redirect: "/config/tools/template",
|
||||
},
|
||||
tools_events: {
|
||||
redirect: "/config/tools/event",
|
||||
},
|
||||
tools_statistics: {
|
||||
redirect: "/config/tools/statistics",
|
||||
},
|
||||
tools_yaml: {
|
||||
redirect: "/config/tools/yaml",
|
||||
},
|
||||
developer_assist: {
|
||||
redirect: "/config/developer-tools/assist",
|
||||
redirect: "/config/tools/assist",
|
||||
},
|
||||
developer_debug: {
|
||||
redirect: "/config/developer-tools/debug",
|
||||
redirect: "/config/tools/debug",
|
||||
},
|
||||
developer_states: {
|
||||
redirect: "/config/developer-tools/state",
|
||||
redirect: "/config/tools/state",
|
||||
},
|
||||
developer_services: {
|
||||
redirect: "/config/developer-tools/action",
|
||||
redirect: "/config/tools/action",
|
||||
},
|
||||
developer_call_service: {
|
||||
redirect: "/config/developer-tools/action",
|
||||
redirect: "/config/tools/action",
|
||||
params: {
|
||||
service: "string",
|
||||
},
|
||||
},
|
||||
developer_template: {
|
||||
redirect: "/config/developer-tools/template",
|
||||
redirect: "/config/tools/template",
|
||||
},
|
||||
developer_events: {
|
||||
redirect: "/config/developer-tools/event",
|
||||
redirect: "/config/tools/event",
|
||||
},
|
||||
developer_statistics: {
|
||||
redirect: "/config/developer-tools/statistics",
|
||||
redirect: "/config/tools/statistics",
|
||||
},
|
||||
server_controls: {
|
||||
redirect: "/config/developer-tools/yaml",
|
||||
redirect: "/config/tools/yaml",
|
||||
},
|
||||
calendar: {
|
||||
component: "calendar",
|
||||
|
||||
+62
-54
@@ -1459,7 +1459,7 @@
|
||||
"automations": "[%key:ui::panel::config::automation::caption%]",
|
||||
"scenes": "[%key:ui::panel::config::scene::caption%]",
|
||||
"scripts": "[%key:ui::panel::config::script::caption%]",
|
||||
"developer_tools": "[%key:ui::panel::config::dashboard::developer_tools::main%]",
|
||||
"tools": "[%key:ui::panel::config::dashboard::tools::main%]",
|
||||
"integrations": "[%key:ui::panel::config::integrations::caption%]",
|
||||
"devices": "[%key:ui::panel::config::devices::caption%]",
|
||||
"entities": "[%key:ui::panel::config::entities::caption%]"
|
||||
@@ -1485,45 +1485,45 @@
|
||||
"navigate_title": "Navigate",
|
||||
"commands": {
|
||||
"reload": {
|
||||
"all": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::all%]",
|
||||
"reload": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::reload%]",
|
||||
"core": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::core%]",
|
||||
"group": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::group%]",
|
||||
"automation": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::automation%]",
|
||||
"script": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::script%]",
|
||||
"scene": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::scene%]",
|
||||
"person": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::person%]",
|
||||
"zone": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::zone%]",
|
||||
"input_boolean": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_boolean%]",
|
||||
"input_button": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_button%]",
|
||||
"input_text": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_text%]",
|
||||
"input_number": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_number%]",
|
||||
"input_datetime": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_datetime%]",
|
||||
"input_select": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::input_select%]",
|
||||
"template": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::template%]",
|
||||
"universal": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::universal%]",
|
||||
"rest": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::rest%]",
|
||||
"command_line": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::command_line%]",
|
||||
"filter": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::filter%]",
|
||||
"statistics": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::statistics%]",
|
||||
"generic": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::generic%]",
|
||||
"generic_thermostat": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::generic_thermostat%]",
|
||||
"homekit": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::homekit%]",
|
||||
"min_max": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::min_max%]",
|
||||
"history_stats": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::history_stats%]",
|
||||
"trend": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::trend%]",
|
||||
"ping": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::ping%]",
|
||||
"filesize": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::filesize%]",
|
||||
"telegram": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::telegram%]",
|
||||
"smtp": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::smtp%]",
|
||||
"mqtt": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::mqtt%]",
|
||||
"rpi_gpio": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::rpi_gpio%]",
|
||||
"themes": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::reloading::themes%]"
|
||||
"all": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::all%]",
|
||||
"reload": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::reload%]",
|
||||
"core": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::core%]",
|
||||
"group": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::group%]",
|
||||
"automation": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::automation%]",
|
||||
"script": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::script%]",
|
||||
"scene": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::scene%]",
|
||||
"person": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::person%]",
|
||||
"zone": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::zone%]",
|
||||
"input_boolean": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_boolean%]",
|
||||
"input_button": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_button%]",
|
||||
"input_text": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_text%]",
|
||||
"input_number": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_number%]",
|
||||
"input_datetime": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_datetime%]",
|
||||
"input_select": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::input_select%]",
|
||||
"template": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::template%]",
|
||||
"universal": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::universal%]",
|
||||
"rest": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::rest%]",
|
||||
"command_line": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::command_line%]",
|
||||
"filter": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::filter%]",
|
||||
"statistics": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::statistics%]",
|
||||
"generic": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::generic%]",
|
||||
"generic_thermostat": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::generic_thermostat%]",
|
||||
"homekit": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::homekit%]",
|
||||
"min_max": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::min_max%]",
|
||||
"history_stats": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::history_stats%]",
|
||||
"trend": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::trend%]",
|
||||
"ping": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::ping%]",
|
||||
"filesize": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::filesize%]",
|
||||
"telegram": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::telegram%]",
|
||||
"smtp": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::smtp%]",
|
||||
"mqtt": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::mqtt%]",
|
||||
"rpi_gpio": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::rpi_gpio%]",
|
||||
"themes": "[%key:ui::panel::config::tools::tabs::yaml::section::reloading::themes%]"
|
||||
},
|
||||
"home_assistant_control": {
|
||||
"perform_action": "{action} Home Assistant",
|
||||
"restart": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::server_management::restart%]",
|
||||
"stop": "[%key:ui::panel::config::developer-tools::tabs::yaml::section::server_management::stop%]"
|
||||
"restart": "[%key:ui::panel::config::tools::tabs::yaml::section::server_management::restart%]",
|
||||
"stop": "[%key:ui::panel::config::tools::tabs::yaml::section::server_management::stop%]"
|
||||
},
|
||||
"types": {
|
||||
"reload": "Reload",
|
||||
@@ -1559,14 +1559,14 @@
|
||||
"analytics": "[%key:ui::panel::config::analytics::caption%]",
|
||||
"system_health": "[%key:ui::panel::config::system_health::caption%]",
|
||||
"blueprint": "[%key:ui::panel::config::blueprint::caption%]",
|
||||
"server_control": "[%key:ui::panel::config::developer-tools::tabs::yaml::title%]",
|
||||
"server_control": "[%key:ui::panel::config::tools::tabs::yaml::title%]",
|
||||
"system": "[%key:ui::panel::config::dashboard::system::main%]",
|
||||
"apps": "Apps",
|
||||
"app_store": "App store",
|
||||
"app_info": "{app} info",
|
||||
"shortcuts": "[%key:ui::panel::config::info::shortcuts%]",
|
||||
"labs": "[%key:ui::panel::config::labs::caption%]",
|
||||
"developer-tools": "[%key:ui::panel::config::dashboard::developer_tools::main%]",
|
||||
"tools": "[%key:ui::panel::config::dashboard::tools::main%]",
|
||||
"matter": "[%key:ui::panel::config::dashboard::matter::main%]",
|
||||
"zha": "[%key:ui::panel::config::dashboard::zha::main%]",
|
||||
"zwave_js": "[%key:ui::panel::config::dashboard::zwave_js::main%]",
|
||||
@@ -2154,12 +2154,12 @@
|
||||
"data": "Additional data"
|
||||
},
|
||||
"template": {
|
||||
"time": "[%key:ui::panel::config::developer-tools::tabs::templates::time%]",
|
||||
"all_listeners": "[%key:ui::panel::config::developer-tools::tabs::templates::all_listeners%]",
|
||||
"no_listeners": "[%key:ui::panel::config::developer-tools::tabs::templates::no_listeners%]",
|
||||
"listeners": "[%key:ui::panel::config::developer-tools::tabs::templates::listeners%]",
|
||||
"entity": "[%key:ui::panel::config::developer-tools::tabs::templates::entity%]",
|
||||
"domain": "[%key:ui::panel::config::developer-tools::tabs::templates::domain%]"
|
||||
"time": "[%key:ui::panel::config::tools::tabs::templates::time%]",
|
||||
"all_listeners": "[%key:ui::panel::config::tools::tabs::templates::all_listeners%]",
|
||||
"no_listeners": "[%key:ui::panel::config::tools::tabs::templates::no_listeners%]",
|
||||
"listeners": "[%key:ui::panel::config::tools::tabs::templates::listeners%]",
|
||||
"entity": "[%key:ui::panel::config::tools::tabs::templates::entity%]",
|
||||
"domain": "[%key:ui::panel::config::tools::tabs::templates::domain%]"
|
||||
}
|
||||
},
|
||||
"options_flow": {
|
||||
@@ -2638,9 +2638,9 @@
|
||||
"main": "System",
|
||||
"secondary": "Create backups, check logs, or reboot your system"
|
||||
},
|
||||
"developer_tools": {
|
||||
"main": "Developer tools",
|
||||
"secondary": "Tools to inspect and debug your system"
|
||||
"tools": {
|
||||
"main": "Tools",
|
||||
"secondary": "Inspect and debug your system"
|
||||
},
|
||||
"about": {
|
||||
"main": "About",
|
||||
@@ -3786,7 +3786,7 @@
|
||||
"companion_apps": "Companion apps"
|
||||
}
|
||||
},
|
||||
"developer-tools": {
|
||||
"tools": {
|
||||
"tabs": {
|
||||
"assist": {
|
||||
"tab": "Assist",
|
||||
@@ -3904,7 +3904,9 @@
|
||||
},
|
||||
"templates": {
|
||||
"title": "Template",
|
||||
"description": "Templates are rendered using the Jinja2 template engine with some Home Assistant specific extensions.",
|
||||
"description": "Templates let you generate dynamic content from your Home Assistant data, such as a notification that lists which lights are on, or a sensor whose value is calculated from several other entities.",
|
||||
"engine_info": "Home Assistant uses the Jinja templating engine, extended with functions for working with your entities, areas, devices, and more. Write a template in the editor below and its result updates live as your states change.",
|
||||
"learn_more": "Learn more",
|
||||
"about": "About templates",
|
||||
"editor": "Template editor",
|
||||
"result": "Result",
|
||||
@@ -3912,8 +3914,14 @@
|
||||
"confirm_reset": "Do you want to reset your current template back to the demo template?",
|
||||
"confirm_clear": "Do you want to clear your current template?",
|
||||
"result_type": "Result type",
|
||||
"jinja_documentation": "Jinja2 template documentation",
|
||||
"template_extensions": "Home Assistant template extensions",
|
||||
"docs_introduction": "Introduction to templating",
|
||||
"docs_introduction_description": "Start here for a step-by-step guide.",
|
||||
"docs_states": "Working with states",
|
||||
"docs_states_description": "Read entity states and attributes in templates.",
|
||||
"docs_debugging": "Debugging templates",
|
||||
"docs_debugging_description": "Find and fix problems in your templates.",
|
||||
"docs_functions": "Template functions reference",
|
||||
"docs_functions_description": "Search every available function, filter, and test.",
|
||||
"unknown_error_template": "Unknown error rendering template",
|
||||
"time": "This template updates at the start of each minute.",
|
||||
"all_listeners": "This template listens for all state changed events.",
|
||||
@@ -4819,7 +4827,7 @@
|
||||
"run_text_pipeline": "Run text pipeline",
|
||||
"run_audio_pipeline": "Run audio pipeline",
|
||||
"run_audio_with_wake": "Run audio pipeline with wake word detection",
|
||||
"response": "[%key:ui::panel::config::developer-tools::tabs::actions::response%]",
|
||||
"response": "[%key:ui::panel::config::tools::tabs::actions::response%]",
|
||||
"send": "Send",
|
||||
"continue_listening": "Continue listening for wake word",
|
||||
"continue_talking": "Continue talking",
|
||||
@@ -5120,7 +5128,7 @@
|
||||
"type_script_plural": "[%key:ui::panel::config::blueprint::overview::types_plural::script%]",
|
||||
"type_scene_plural": "scenes",
|
||||
"new_automation_setup_failed_title": "New {type} setup timed out",
|
||||
"new_automation_setup_failed_text": "Your new {type} was saved, but waiting for it to set up has timed out. This could be due to errors parsing your configuration.yaml, please check the configuration in developer tools. Your {type} will not be visible until this is corrected and {types} are reloaded. Changes to area, category, or labels were not saved and must be reapplied.",
|
||||
"new_automation_setup_failed_text": "Your new {type} was saved, but waiting for it to set up has timed out. This could be due to errors parsing your configuration.yaml, please check the configuration in the Tools panel. Your {type} will not be visible until this is corrected and {types} are reloaded. Changes to area, category, or labels were not saved and must be reapplied.",
|
||||
"new_automation_setup_keep_waiting": "You may continue to wait for a response from the server, in case it is just taking an unusually long time to process this {type}.",
|
||||
"new_automation_setup_timedout_success": "The server has responded and this has now set up successfully. You may now close this dialog.",
|
||||
"item_pasted": "{item} pasted",
|
||||
|
||||
+148
-9
@@ -99,7 +99,7 @@ test.describe("App shell", () => {
|
||||
await goToPanel(page, "/lovelace");
|
||||
|
||||
// Regular panels use #sidebar-panel-{urlPath} inside ha-sidebar's shadow root
|
||||
for (const urlPath of ["lovelace", "energy", "history"]) {
|
||||
for (const urlPath of ["lovelace", "map", "energy", "history"]) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await expect(
|
||||
page.locator(
|
||||
@@ -115,6 +115,71 @@ test.describe("App shell", () => {
|
||||
).toBeAttached();
|
||||
});
|
||||
|
||||
test("sidebar navigation changes the active panel", async ({ page }) => {
|
||||
await goToPanel(page, "/lovelace");
|
||||
|
||||
const sidebar = page.locator(
|
||||
"ha-test >> home-assistant-main >> ha-sidebar"
|
||||
);
|
||||
await expect(sidebar).toBeAttached({ timeout: SHELL_TIMEOUT });
|
||||
|
||||
const historyLink = sidebar.locator("#sidebar-panel-history");
|
||||
if (!(await historyLink.isVisible().catch(() => false))) {
|
||||
await page.locator("ha-test >> home-assistant-main").evaluate((el) => {
|
||||
el.dispatchEvent(
|
||||
new CustomEvent("hass-toggle-menu", {
|
||||
detail: { open: true },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
await expect(historyLink).toBeVisible({ timeout: SHELL_TIMEOUT });
|
||||
await historyLink.click();
|
||||
|
||||
await expect(page).toHaveURL(/\/#\/history$/, { timeout: SHELL_TIMEOUT });
|
||||
await expect(
|
||||
page.locator("ha-panel-history, history-panel").first()
|
||||
).toBeAttached({ timeout: PANEL_TIMEOUT });
|
||||
});
|
||||
|
||||
test("sidebar renders notification badge", async ({ page }) => {
|
||||
await goToPanel(page, "/lovelace");
|
||||
|
||||
const sidebar = page.locator(
|
||||
"ha-test >> home-assistant-main >> ha-sidebar"
|
||||
);
|
||||
await expect(sidebar).toBeAttached({ timeout: SHELL_TIMEOUT });
|
||||
|
||||
const notificationsLink = sidebar.locator("#sidebar-notifications");
|
||||
await expect(notificationsLink).toBeAttached({ timeout: SHELL_TIMEOUT });
|
||||
await expect(notificationsLink.locator(".badge").first()).toHaveText("1", {
|
||||
timeout: SHELL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
|
||||
test("sidebar marks the active panel as selected", async ({ page }) => {
|
||||
const sidebar = page.locator(
|
||||
"ha-test >> home-assistant-main >> ha-sidebar"
|
||||
);
|
||||
const lovelaceLink = sidebar.locator("#sidebar-panel-lovelace");
|
||||
const historyLink = sidebar.locator("#sidebar-panel-history");
|
||||
|
||||
await goToPanel(page, "/lovelace");
|
||||
await expect(lovelaceLink).toHaveClass(/selected/, {
|
||||
timeout: SHELL_TIMEOUT,
|
||||
});
|
||||
await expect(historyLink).not.toHaveClass(/selected/);
|
||||
|
||||
await goToPanel(page, "/history");
|
||||
await expect(historyLink).toHaveClass(/selected/, {
|
||||
timeout: SHELL_TIMEOUT,
|
||||
});
|
||||
await expect(lovelaceLink).not.toHaveClass(/selected/);
|
||||
});
|
||||
|
||||
test("non-admin user does NOT see config panel in sidebar", async ({
|
||||
page,
|
||||
}) => {
|
||||
@@ -158,6 +223,15 @@ test.describe("Panel navigation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("navigates to map panel", async ({ page }) => {
|
||||
await goToPanel(page, "/map");
|
||||
await expect(
|
||||
page.locator("ha-panel-lovelace, hui-root").first()
|
||||
).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
|
||||
test("navigates to history panel", async ({ page }) => {
|
||||
await goToPanel(page, "/history");
|
||||
await expect(
|
||||
@@ -167,14 +241,6 @@ test.describe("Panel navigation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("navigates to developer-tools panel", async ({ page }) => {
|
||||
// Since 2026.2 developer-tools is part of the config panel
|
||||
await goToPanel(page, "/config/developer-tools");
|
||||
await expect(
|
||||
page.locator("ha-panel-config, developer-tools-main").first()
|
||||
).toBeAttached({ timeout: PANEL_TIMEOUT });
|
||||
});
|
||||
|
||||
test("navigates to profile panel", async ({ page }) => {
|
||||
await goToPanel(page, "/profile");
|
||||
await expect(
|
||||
@@ -183,6 +249,79 @@ test.describe("Panel navigation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tools panel (formerly Developer tools)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Every tool sub-page reachable under /config/tools, mapped to the custom
|
||||
* element tools-router mounts for it (see tools-router.ts). Asserting on the
|
||||
* specific element proves the route actually rendered its tool, not just the
|
||||
* shared ha-panel-tools shell.
|
||||
*/
|
||||
const TOOLS_SUBPAGES: { route: string; element: string }[] = [
|
||||
{ route: "yaml", element: "tools-yaml-config" },
|
||||
{ route: "state", element: "tools-state" },
|
||||
{ route: "action", element: "tools-action" },
|
||||
{ route: "template", element: "tools-template" },
|
||||
{ route: "event", element: "tools-event" },
|
||||
{ route: "statistics", element: "tools-statistics" },
|
||||
{ route: "assist", element: "tools-assist" },
|
||||
{ route: "debug", element: "tools-debug" },
|
||||
];
|
||||
|
||||
test.describe("Tools panel", () => {
|
||||
test("base path renders the tools panel", async ({ page }) => {
|
||||
await goToPanel(page, "/config/tools");
|
||||
await expect(page.locator("ha-panel-tools")).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
|
||||
for (const { route, element } of TOOLS_SUBPAGES) {
|
||||
test(`renders the ${route} sub-page`, async ({ page }) => {
|
||||
await goToPanel(page, `/config/tools/${route}`);
|
||||
await expect(page.locator(element)).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test("service is an alias for the action tool", async ({ page }) => {
|
||||
await goToPanel(page, "/config/tools/service");
|
||||
await expect(page.locator("tools-action")).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tools redirects (old developer-tools URLs)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
test.describe("Tools redirects", () => {
|
||||
// The panel moved from top-level /developer-tools (pre-2026.2) to
|
||||
// /config/developer-tools (2026.2), then was renamed to /config/tools
|
||||
// (2026.8). Both old locations must redirect to the new one, and deep links
|
||||
// must keep their sub-page. See the updateRoute() redirect in
|
||||
// src/layouts/home-assistant.ts.
|
||||
for (const oldBase of ["/developer-tools", "/config/developer-tools"]) {
|
||||
test(`redirects ${oldBase} to the tools panel`, async ({ page }) => {
|
||||
await goToPanel(page, oldBase);
|
||||
await expect(page.locator("ha-panel-tools")).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
|
||||
test(`redirects ${oldBase}/state to the state tool`, async ({ page }) => {
|
||||
await goToPanel(page, `${oldBase}/state`);
|
||||
await expect(page.locator("tools-state")).toBeAttached({
|
||||
timeout: PANEL_TIMEOUT,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Lovelace
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -43,11 +43,4 @@ export const e2eTestPanels: Panels = {
|
||||
config: null,
|
||||
url_path: "profile",
|
||||
},
|
||||
"developer-tools": {
|
||||
component_name: "developer-tools",
|
||||
icon: "mdi:hammer",
|
||||
title: "developer_tools",
|
||||
config: null,
|
||||
url_path: "developer-tools",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ export class HaTest extends HomeAssistantAppEl {
|
||||
: scenarios.default;
|
||||
|
||||
const initial: Partial<MockHomeAssistant> = {
|
||||
// Use the full panel map (history + config + developer-tools enabled)
|
||||
// Use the full panel map (history + config enabled)
|
||||
panels: e2eTestPanels,
|
||||
panelUrl: (() => {
|
||||
const path = window.location.pathname;
|
||||
|
||||
Vendored
+5
-1
@@ -89,6 +89,8 @@ export interface EnergyDataOptions {
|
||||
period?: "5minute" | "hour" | "day";
|
||||
compare?: boolean;
|
||||
prefs?: EnergyPreferences;
|
||||
/** Probability a period is missing (creates gaps); 0 for a dense dataset. */
|
||||
gapChance?: number;
|
||||
}
|
||||
|
||||
const statisticIdsForPrefs = (prefs: EnergyPreferences): string[] => {
|
||||
@@ -115,7 +117,7 @@ export const generateEnergyData = (
|
||||
seed: number,
|
||||
options: EnergyDataOptions
|
||||
): EnergyData => {
|
||||
const { days, period = "hour", compare = false } = options;
|
||||
const { days, period = "hour", compare = false, gapChance } = options;
|
||||
const prefs = options.prefs ?? generateEnergyPreferences();
|
||||
const ids = statisticIdsForPrefs(prefs);
|
||||
const dayMs = 24 * 60 * 60 * 1000;
|
||||
@@ -124,6 +126,7 @@ export const generateEnergyData = (
|
||||
ids,
|
||||
period,
|
||||
days,
|
||||
gapChance,
|
||||
sumStatistics: true,
|
||||
});
|
||||
const statsCompare = compare
|
||||
@@ -132,6 +135,7 @@ export const generateEnergyData = (
|
||||
period,
|
||||
days,
|
||||
startMs: FIXED_EPOCH_MS - days * dayMs,
|
||||
gapChance,
|
||||
sumStatistics: true,
|
||||
})
|
||||
: ({} as EnergyData["statsCompare"]);
|
||||
|
||||
@@ -164,6 +164,57 @@ describe("generateEnergyDevicesDetailGraphData", () => {
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// Regression test for #52937: at the start of the day only the first hour
|
||||
// has data. The untracked/over-reported bars must center on the same period
|
||||
// midpoint as the device bars so they stack as one bar instead of splitting
|
||||
// into a second stack at the period start.
|
||||
it("stacks untracked bars on the device bars for a lone first-of-day bucket", () => {
|
||||
// Full-day range (so getSuggestedPeriod stays "hour") but keep only the
|
||||
// first hourly bucket in every stat. gapChance: 0 makes the bucket dense.
|
||||
const full = generateEnergyData(1, {
|
||||
days: 1,
|
||||
period: "hour",
|
||||
gapChance: 0,
|
||||
prefs: buildPrefs(false),
|
||||
});
|
||||
const firstStart = full.start.getTime();
|
||||
const energyData = {
|
||||
...full,
|
||||
stats: Object.fromEntries(
|
||||
Object.entries(full.stats).map(
|
||||
([id, values]) =>
|
||||
[id, values.filter((s) => s.start === firstStart)] as const
|
||||
)
|
||||
),
|
||||
};
|
||||
|
||||
const result = generateEnergyDevicesDetailGraphData({
|
||||
...baseParams,
|
||||
energyData,
|
||||
});
|
||||
|
||||
// Collect the display x of every bar across all series.
|
||||
const xs = new Set<number>();
|
||||
let nonEmptySeries = 0;
|
||||
for (const series of result.chartData) {
|
||||
const points = series.data ?? [];
|
||||
if (points.length) {
|
||||
nonEmptySeries++;
|
||||
}
|
||||
for (const point of points as any[]) {
|
||||
const x = Array.isArray(point) ? point[0] : point?.value?.[0];
|
||||
if (x != null) {
|
||||
xs.add(Number(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Device bars + at least one untracked series are present...
|
||||
assert.isAtLeast(nonEmptySeries, 2);
|
||||
// ...and they all share a single x, so they render as one full stack.
|
||||
assert.equal(xs.size, 1);
|
||||
});
|
||||
|
||||
// The seeded fixtures above all happen to produce fully-negative untracked
|
||||
// (devices reference the source stats, so they consume all of used_total).
|
||||
// These two cases pin the branches those snapshots can't reach.
|
||||
|
||||
@@ -4618,22 +4618,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/client@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/client@npm:1.5.16"
|
||||
checksum: 10/dcda4e8034a296090b073102423050764e636f9801f2e5a5904e1f2744b1fe26d5f8202aed7a785c9fc809044e1aef5c4b6a16b63974caec79d1b5996ec35d34
|
||||
"@rsdoctor/client@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/client@npm:1.5.17"
|
||||
checksum: 10/0eb788455390a1b41aa31d982d93ceab3dd30671776e40e8a4ea3256b4713f6441066e079ff9a14413825e21d547b9b7d4ba52059f8995644e26724ff07bbf56
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/core@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/core@npm:1.5.16"
|
||||
"@rsdoctor/core@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/core@npm:1.5.17"
|
||||
dependencies:
|
||||
"@rsbuild/plugin-check-syntax": "npm:^1.6.1"
|
||||
"@rsdoctor/graph": "npm:1.5.16"
|
||||
"@rsdoctor/sdk": "npm:1.5.16"
|
||||
"@rsdoctor/types": "npm:1.5.16"
|
||||
"@rsdoctor/utils": "npm:1.5.16"
|
||||
"@rsdoctor/graph": "npm:1.5.17"
|
||||
"@rsdoctor/sdk": "npm:1.5.17"
|
||||
"@rsdoctor/types": "npm:1.5.17"
|
||||
"@rsdoctor/utils": "npm:1.5.17"
|
||||
"@rspack/resolver": "npm:^0.2.8"
|
||||
browserslist-load-config: "npm:^1.0.2"
|
||||
es-toolkit: "npm:^1.47.0"
|
||||
@@ -4641,60 +4641,60 @@ __metadata:
|
||||
fs-extra: "npm:^11.1.1"
|
||||
semver: "npm:^7.7.4"
|
||||
source-map: "npm:^0.7.6"
|
||||
checksum: 10/be7b03b5a5a8a9be47f94159469c35488f98046c99e2ccd7daed325c3dd2a8b21c654c12ac6d40c2775546efade373f429f630e8905cc17a5c9151978a0caaf9
|
||||
checksum: 10/a797d5243d1d3f758d8b38cea1a3195345525c3158c4061f5e78d875fe2001198c8967587153059eb7c5ff764f27b4685ce13fd55a27dccdcfe7cd8061fb30c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/graph@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/graph@npm:1.5.16"
|
||||
"@rsdoctor/graph@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/graph@npm:1.5.17"
|
||||
dependencies:
|
||||
"@rsdoctor/types": "npm:1.5.16"
|
||||
"@rsdoctor/utils": "npm:1.5.16"
|
||||
"@rsdoctor/types": "npm:1.5.17"
|
||||
"@rsdoctor/utils": "npm:1.5.17"
|
||||
es-toolkit: "npm:^1.47.0"
|
||||
path-browserify: "npm:1.0.1"
|
||||
source-map: "npm:^0.7.6"
|
||||
checksum: 10/949e3a2cc48ccbb2d554becb2270c4df4b4fc8a6e10bd55bf9dc4d5f9a5fb2823c3e11a30dce890beaaa1b0ab0039bba1554ad0e7ddc5e2ea47641222d454633
|
||||
checksum: 10/e58ed532ea8cc743e45dd66b678e1da3d48939fe711ebfade47834ffc581be6089d611d18c97c3e12010e2c609049cb325d07021a5dc51ef651314f8fe9f5741
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/rspack-plugin@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/rspack-plugin@npm:1.5.16"
|
||||
"@rsdoctor/rspack-plugin@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/rspack-plugin@npm:1.5.17"
|
||||
dependencies:
|
||||
"@rsdoctor/core": "npm:1.5.16"
|
||||
"@rsdoctor/graph": "npm:1.5.16"
|
||||
"@rsdoctor/sdk": "npm:1.5.16"
|
||||
"@rsdoctor/types": "npm:1.5.16"
|
||||
"@rsdoctor/utils": "npm:1.5.16"
|
||||
"@rsdoctor/core": "npm:1.5.17"
|
||||
"@rsdoctor/graph": "npm:1.5.17"
|
||||
"@rsdoctor/sdk": "npm:1.5.17"
|
||||
"@rsdoctor/types": "npm:1.5.17"
|
||||
"@rsdoctor/utils": "npm:1.5.17"
|
||||
peerDependencies:
|
||||
"@rspack/core": "*"
|
||||
peerDependenciesMeta:
|
||||
"@rspack/core":
|
||||
optional: true
|
||||
checksum: 10/2bebf2b8dfc5ffde77b46b45fedc7d5d9b96f4fe3e5e1b3762bff5de6f278d9288fe6c361fa1df5bb17926a45ae3c6038e165d4f1f5e867724df0a530590b36a
|
||||
checksum: 10/336bd813010a7c164770033ae5a30644bf165ce0dff250b9160c7c003401c214bfd96e528c5941c09834bb21949a4815c46ecae0ca4d9200b2b946b9c3164f8a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/sdk@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/sdk@npm:1.5.16"
|
||||
"@rsdoctor/sdk@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/sdk@npm:1.5.17"
|
||||
dependencies:
|
||||
"@rsdoctor/client": "npm:1.5.16"
|
||||
"@rsdoctor/graph": "npm:1.5.16"
|
||||
"@rsdoctor/types": "npm:1.5.16"
|
||||
"@rsdoctor/utils": "npm:1.5.16"
|
||||
"@rsdoctor/client": "npm:1.5.17"
|
||||
"@rsdoctor/graph": "npm:1.5.17"
|
||||
"@rsdoctor/types": "npm:1.5.17"
|
||||
"@rsdoctor/utils": "npm:1.5.17"
|
||||
launch-editor: "npm:^2.13.2"
|
||||
safer-buffer: "npm:2.1.2"
|
||||
socket.io: "npm:4.8.1"
|
||||
tapable: "npm:2.3.3"
|
||||
checksum: 10/8a845468e13c66b93f9784c7887f7040b1df24f43e9304b50c3a7258c6b172c2bc3ca5f6e5e9d15801d1634e3e48f6bc78115a7a0242890548d111ae512caf7d
|
||||
checksum: 10/d8a146a43726d61a9d7d2cfca7e2cd48c42a7ba28c9d280353f986f1647c0a33f05ec68a45af4f22104df8a8dae7dc14d621e56a15f11c3967d78c21216be234
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/types@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/types@npm:1.5.16"
|
||||
"@rsdoctor/types@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/types@npm:1.5.17"
|
||||
dependencies:
|
||||
"@types/connect": "npm:3.4.38"
|
||||
"@types/estree": "npm:1.0.5"
|
||||
@@ -4708,16 +4708,16 @@ __metadata:
|
||||
optional: true
|
||||
webpack:
|
||||
optional: true
|
||||
checksum: 10/f470a7047474669bd466c9cee15b5ef3e4b854d4347e3dd4f251f1d1f92bd9b7b5e6863349f5d3550485c3484497a1e8be71cefc56e883c81f8a734960d1fc5e
|
||||
checksum: 10/4767825ae55498e25d1dfbecc0aebe2685b67701dae004617f4d95a68b85f19f29afe75f72b8efeab4fe49185bb9a3c85dcfce8f99852c49d4ee37a4f6b7d888
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rsdoctor/utils@npm:1.5.16":
|
||||
version: 1.5.16
|
||||
resolution: "@rsdoctor/utils@npm:1.5.16"
|
||||
"@rsdoctor/utils@npm:1.5.17":
|
||||
version: 1.5.17
|
||||
resolution: "@rsdoctor/utils@npm:1.5.17"
|
||||
dependencies:
|
||||
"@babel/code-frame": "npm:7.26.2"
|
||||
"@rsdoctor/types": "npm:1.5.16"
|
||||
"@rsdoctor/types": "npm:1.5.17"
|
||||
"@types/estree": "npm:1.0.5"
|
||||
acorn: "npm:^8.10.0"
|
||||
acorn-import-attributes: "npm:^1.9.5"
|
||||
@@ -4731,7 +4731,7 @@ __metadata:
|
||||
picocolors: "npm:^1.1.1"
|
||||
rslog: "npm:^2.1.2"
|
||||
strip-ansi: "npm:^6.0.1"
|
||||
checksum: 10/d73062cc01f4e2def276d6515f2810f54bfd7f819f1d3a00dd884621f9c008eda4b31ae6e6d96efaec81d1bbad98f0f49cb77e14a028d5f53c97aca84b6b07d4
|
||||
checksum: 10/7c9b4a3824de61f6254df50f80c5efe53df662f30cb07047afa956a9bc3917dc71bf0aa73c8edde7f73f9577a9cb051e1a81caaffa118db414a4b655223fe92a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5741,105 +5741,105 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.62.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.62.1"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.12.2"
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.62.0"
|
||||
"@typescript-eslint/utils": "npm:8.62.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.1"
|
||||
"@typescript-eslint/type-utils": "npm:8.62.1"
|
||||
"@typescript-eslint/utils": "npm:8.62.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.1"
|
||||
ignore: "npm:^7.0.5"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
"@typescript-eslint/parser": ^8.62.0
|
||||
"@typescript-eslint/parser": ^8.62.1
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/a093962c84e49d7524078a97c3ecfdedfaa217a6f68047d3eedb29677425210acfacaa2fe88f447e9662063979f31c8268e4568caca038df09deee9f06124d7f
|
||||
checksum: 10/5db2952d68176ef82a40ae82e26bbab02e48d1b8ea706fb2a45f68a2404a45a1be8a2c765233acbae8db45802c0322512c5200263656ecf15fe9f1fcd39e0bff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.62.0"
|
||||
"@typescript-eslint/parser@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/parser@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.0"
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.1"
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/d0abbf12080532f6460af186098fab15f1f3695ee4817f96209ecfb00ef7ec89ec476051bde35a396217c8e37d5e441f3814807eb082e11904a0a1dc4b6d3b14
|
||||
checksum: 10/4d8c72b03a41966b6157f2a893026cab81b9d13544431e9c426e03c033ecfea5325708786331fd5a6182e2cab519754863fecd9a0b05267f6e2a793649adf016
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/project-service@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/project-service@npm:8.62.0"
|
||||
"@typescript-eslint/project-service@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/project-service@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.62.0"
|
||||
"@typescript-eslint/types": "npm:^8.62.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:^8.62.1"
|
||||
"@typescript-eslint/types": "npm:^8.62.1"
|
||||
debug: "npm:^4.4.3"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/e296f3aaaf7b4fc56e6410420a98a995f59bf45187445c9ad94d76de557a47071558869414c8ec179dfefce4f65ef8c15fcda7db653ed8fb95ff25b8119f9bb1
|
||||
checksum: 10/efb7a04325e81159311e7d0e5247b8ada03594ded01d117f75209e13366ed8bf34cddccf2d9b7906ffedb6d357e91f49ce7048e052b1dad41889a81962a277da
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.62.0"
|
||||
"@typescript-eslint/scope-manager@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.0"
|
||||
checksum: 10/6477062eb056986c9f94b35761c0b67bb9995798ba94c5d2bcb01932e525604715ce62e816468b2c80a8f05daa33b3339ea40646a31f733ea9840cee1dd3e82d
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.1"
|
||||
checksum: 10/c3bdd78491dc7babe94b43ebd3cd4a1342f6fea768267974c97908e9a65c5d56726b174b83627181595f91998896c8c1a5f0d48b3e1be3135b116e3f6ae402ef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.62.0, @typescript-eslint/tsconfig-utils@npm:^8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.62.0"
|
||||
"@typescript-eslint/tsconfig-utils@npm:8.62.1, @typescript-eslint/tsconfig-utils@npm:^8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/tsconfig-utils@npm:8.62.1"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/578f486df8eb2d2ec3939afc37102b89521d531d409d76e30a8ac3e9f48a3ae410e19e40c2aba3810f28391925a35ed391204ff786cc230542de82817efafda0
|
||||
checksum: 10/6aa5d874dd03fb4d4ba4a710e1ea64a73cb273565bf2f0be0e1ee8b4b3aa90619058c34cd2e22ed4ac6b9634a84ce8000fa126eb3eb6eb7f516661fc36dca296
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.62.0"
|
||||
"@typescript-eslint/type-utils@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.0"
|
||||
"@typescript-eslint/utils": "npm:8.62.0"
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.1"
|
||||
"@typescript-eslint/utils": "npm:8.62.1"
|
||||
debug: "npm:^4.4.3"
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/e1627d2bd792cf856c36db4f4e9c89e3111ad9bf81fc7489e957d26d36f89ab00226eee1838ee499947a898e37c1f30338bca4fa05ca437154c1813d54831b7e
|
||||
checksum: 10/33b61fe7914ac5bff421b0994a2c21cefbc4b226c45909540134cb541d15883c4cbd370897e389e2524ad2a6423c5aa44cffd259365deac47ba621faa14034a7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:8.62.0, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/types@npm:8.62.0"
|
||||
checksum: 10/459f5834dedbb73fc80c8eb92de693faef0f0f341d3b4d65426dbf43640f98a50104f6e15108808aed2c3c66d518db15a648c72c40831f498d36bfb62be564cb
|
||||
"@typescript-eslint/types@npm:8.62.1, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/types@npm:8.62.1"
|
||||
checksum: 10/855ebe6ec951e724ac28e9b09c57d68e69f1ccf4d505457017d8d34b91fa031c89d4e94d07e867c283b4fecc8161523197097f55e86dbaab6420139f9c888a8e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.62.0"
|
||||
"@typescript-eslint/typescript-estree@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/project-service": "npm:8.62.0"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.62.0"
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.0"
|
||||
"@typescript-eslint/project-service": "npm:8.62.1"
|
||||
"@typescript-eslint/tsconfig-utils": "npm:8.62.1"
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.62.1"
|
||||
debug: "npm:^4.4.3"
|
||||
minimatch: "npm:^10.2.2"
|
||||
semver: "npm:^7.7.3"
|
||||
@@ -5847,32 +5847,32 @@ __metadata:
|
||||
ts-api-utils: "npm:^2.5.0"
|
||||
peerDependencies:
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/c3ae8e13671957e4a1c4acfc861b40e1545a9d32fe9d5cc851992186314f5a1dbe780cecc8f16b8448a1350f4c11648572352b5d04b77bb62e8dac3e6f3a2e04
|
||||
checksum: 10/6146babb0986425dcf98c96ee13d5b6d7d8ae7dcd94f54b6ae0bf77d39f73cae0d3915d5d17ecb0e063652bb7f4e2e8a840838d5910e4633a9ff756556f7a313
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.62.0"
|
||||
"@typescript-eslint/utils@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/utils@npm:8.62.1"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.9.1"
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.0"
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.62.1"
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/95fed9feb823106f09b517637b0cf00e39fdc3537d05023f84710f23d00457898d8f1c68a69115d624a686411136b5cfdd7b84b657d6b51aea410cf2eb7fde7a
|
||||
checksum: 10/6bd20e725dbe2bde1ea6c9c6775b87c549b3493d2f23a64df905c09d5e2163a2e9a6243c2e1e4c61c21934c9c10e8e15d451833c3f12ae87cbc92e06cf502946
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.62.0"
|
||||
"@typescript-eslint/visitor-keys@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.62.0"
|
||||
"@typescript-eslint/types": "npm:8.62.1"
|
||||
eslint-visitor-keys: "npm:^5.0.0"
|
||||
checksum: 10/63d66db628befb1d160c02f3fe3b00b7c7ffc47a477335591affde2108e913a72d4a327bdd15d91f5784c3c3624e9b347e9351754390a61ca182bb7e1788d350
|
||||
checksum: 10/9a2fdfa40806f46b5e5c4ce4fc390bf0db2326624566000ec9b5431144ca94b75d0965148386b6e2a9678fb4cc0484b757fc325babd43a2d320fcf213109d6b6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6357,7 +6357,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.10.0, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0":
|
||||
"acorn@npm:^8.10.0, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0, acorn@npm:^8.17.0":
|
||||
version: 8.17.0
|
||||
resolution: "acorn@npm:8.17.0"
|
||||
bin:
|
||||
@@ -9148,14 +9148,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fs-extra@npm:11.3.5, fs-extra@npm:^11.1.1":
|
||||
version: 11.3.5
|
||||
resolution: "fs-extra@npm:11.3.5"
|
||||
"fs-extra@npm:11.3.6, fs-extra@npm:^11.1.1":
|
||||
version: 11.3.6
|
||||
resolution: "fs-extra@npm:11.3.6"
|
||||
dependencies:
|
||||
graceful-fs: "npm:^4.2.0"
|
||||
jsonfile: "npm:^6.0.1"
|
||||
universalify: "npm:^2.0.0"
|
||||
checksum: 10/dc8408818eec8b03efad8742d079ecab749a2f7bc9f208e429b447fcac7632fae52e09312d6d42218efe7e2efa97f03ff232d639ade4aa7fcd8c00ebe9ad0c0c
|
||||
checksum: 10/34a981697b199002ea3b85c3483bcf353637d33ec4c922b136a8d8a597faa0495638d69b20c181448be041c31778c2bb7f7799d589819edf33da50f75b1abde9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9771,7 +9771,7 @@ __metadata:
|
||||
"@octokit/rest": "npm:22.0.1"
|
||||
"@playwright/test": "npm:1.61.1"
|
||||
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
||||
"@rsdoctor/rspack-plugin": "npm:1.5.16"
|
||||
"@rsdoctor/rspack-plugin": "npm:1.5.17"
|
||||
"@rspack/core": "npm:2.1.1"
|
||||
"@rspack/dev-server": "npm:2.1.0"
|
||||
"@swc/helpers": "npm:0.5.23"
|
||||
@@ -9823,7 +9823,7 @@ __metadata:
|
||||
eslint-plugin-unused-imports: "npm:4.4.1"
|
||||
eslint-plugin-wc: "npm:3.1.0"
|
||||
fancy-log: "npm:2.0.0"
|
||||
fs-extra: "npm:11.3.5"
|
||||
fs-extra: "npm:11.3.6"
|
||||
fuse.js: "npm:7.4.2"
|
||||
generate-license-file: "npm:4.2.1"
|
||||
glob: "npm:13.0.6"
|
||||
@@ -9837,7 +9837,7 @@ __metadata:
|
||||
home-assistant-js-websocket: "npm:9.6.0"
|
||||
html-minifier-terser: "npm:7.2.0"
|
||||
husky: "npm:9.1.7"
|
||||
idb-keyval: "npm:6.2.5"
|
||||
idb-keyval: "npm:6.2.6"
|
||||
intl-messageformat: "npm:11.2.9"
|
||||
js-yaml: "npm:5.2.0"
|
||||
jsdom: "npm:29.1.1"
|
||||
@@ -9856,11 +9856,11 @@ __metadata:
|
||||
map-stream: "npm:0.0.7"
|
||||
marked: "npm:18.0.5"
|
||||
memoize-one: "npm:6.0.0"
|
||||
minify-literals: "npm:2.0.2"
|
||||
minify-literals: "npm:2.1.0"
|
||||
node-vibrant: "npm:4.0.4"
|
||||
object-hash: "npm:3.0.0"
|
||||
pinst: "npm:3.0.0"
|
||||
prettier: "npm:3.9.1"
|
||||
prettier: "npm:3.9.4"
|
||||
punycode: "npm:2.3.1"
|
||||
qr-scanner: "npm:1.4.2"
|
||||
qrcode: "npm:1.5.4"
|
||||
@@ -9877,7 +9877,7 @@ __metadata:
|
||||
tinykeys: "patch:tinykeys@npm%3A4.0.0#~/.yarn/patches/tinykeys-npm-4.0.0-a6ca3fd771.patch"
|
||||
ts-lit-plugin: "npm:2.0.2"
|
||||
typescript: "npm:6.0.3"
|
||||
typescript-eslint: "npm:8.62.0"
|
||||
typescript-eslint: "npm:8.62.1"
|
||||
vite-tsconfig-paths: "npm:6.1.1"
|
||||
vitest: "npm:4.1.9"
|
||||
webpack-stats-plugin: "npm:1.1.3"
|
||||
@@ -9935,9 +9935,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"html-minifier-next@npm:^6.2.8":
|
||||
version: 6.2.11
|
||||
resolution: "html-minifier-next@npm:6.2.11"
|
||||
"html-minifier-next@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "html-minifier-next@npm:7.0.0"
|
||||
dependencies:
|
||||
commander: "npm:^15.0.0"
|
||||
entities: "npm:^8.0.0"
|
||||
@@ -9952,7 +9952,7 @@ __metadata:
|
||||
bin:
|
||||
hmn: cli.js
|
||||
html-minifier-next: cli.js
|
||||
checksum: 10/d2b3923f77fff918ab09a9cfdfc3819b89dd928e1e64c60dcb39a2b08ddf6bbd3c696d90e8feb830fed11cd5d5757b271de65cb9d1713ddc171ee9668708eda6
|
||||
checksum: 10/4c0ade3459281ae3c30147d28c7ec77d371d8a1a2e0b61873b555179e071a32e596e7a962c1e072c89355cef72dd627a60ce7bc8cf07763e9f3ed6b0d46250b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10056,10 +10056,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"idb-keyval@npm:6.2.5":
|
||||
version: 6.2.5
|
||||
resolution: "idb-keyval@npm:6.2.5"
|
||||
checksum: 10/ac645882b3258ff07347d085baab91b871bac7be4f46ff8e20a7c036c2df35d3f695a30050009f27237b99045203568f2a842a35295a48f9b815959ee51a347e
|
||||
"idb-keyval@npm:6.2.6":
|
||||
version: 6.2.6
|
||||
resolution: "idb-keyval@npm:6.2.6"
|
||||
checksum: 10/8d0f8b9bd5eead685731a900510095dbc58936968739755bfd1de1c69a710daa5eb2b5cf185d0a7c7e9ce1daf4544fa5f58a2c7a37258a6826dd40f9e2614245
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11663,16 +11663,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minify-literals@npm:2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "minify-literals@npm:2.0.2"
|
||||
"minify-literals@npm:2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "minify-literals@npm:2.1.0"
|
||||
dependencies:
|
||||
"@sveltejs/acorn-typescript": "npm:^1.0.10"
|
||||
acorn: "npm:^8.16.0"
|
||||
html-minifier-next: "npm:^6.2.8"
|
||||
acorn: "npm:^8.17.0"
|
||||
html-minifier-next: "npm:^7.0.0"
|
||||
lightningcss: "npm:^1.32.0"
|
||||
magic-string: "npm:^0.30.21"
|
||||
checksum: 10/51de4b6affcebe082f00709241b8d1587aff06164cf9fd5797ffc45b322c14d0f77e9085171bd78cc35c5a9b0a22c5211f36d177a50fe5d0f8c57e6c10735838
|
||||
checksum: 10/95bcd25afcf638c00bcd8981c2e6409be8c2feb4fd8f954bc9a547b2ade917810cef17bb075ad95e5ceaac6fffc8e625c161ab77b2363c36de53da6d139de872
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -12746,12 +12746,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "prettier@npm:3.9.1"
|
||||
"prettier@npm:3.9.4":
|
||||
version: 3.9.4
|
||||
resolution: "prettier@npm:3.9.4"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10/1b4317674aa9e90ff79c347fd19f91bb305df98b3122e7131d6815291707781305c45a13cd982474c2f74ed748f2fd0a9aa094f9856609ed1b6f092de8152058
|
||||
checksum: 10/4a0dc4389d442f5aca0beb12778c90b6ceb9831940b01a1df5eba9150b5ce96fa52eda9074a10a370e732adc03e2f645597dfd8b7e3f1e94dee28df01004a0fd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14876,18 +14876,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript-eslint@npm:8.62.0":
|
||||
version: 8.62.0
|
||||
resolution: "typescript-eslint@npm:8.62.0"
|
||||
"typescript-eslint@npm:8.62.1":
|
||||
version: 8.62.1
|
||||
resolution: "typescript-eslint@npm:8.62.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.62.0"
|
||||
"@typescript-eslint/parser": "npm:8.62.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.0"
|
||||
"@typescript-eslint/utils": "npm:8.62.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:8.62.1"
|
||||
"@typescript-eslint/parser": "npm:8.62.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.62.1"
|
||||
"@typescript-eslint/utils": "npm:8.62.1"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||
typescript: ">=4.8.4 <6.1.0"
|
||||
checksum: 10/c75b16115a3e6f7704f71a9fe14d8cf52129db7e0578755f10a344a0e22474cc0b5383822ef0344cd886b98300af4cce19a306ccda391b2e1eed6c07088f3019
|
||||
checksum: 10/30e52ee7bec1920cf32a03562df5cd5320070c99cc41902aa49d86a8cc50515ea7bb2e9010a89704f3c36c22479c3120f2792d646197eac34d69569fe2d51643
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user