mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-23 00:17:27 +00:00
Compare commits
17 Commits
sec_pypi_p
...
quick-bar-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d67ea5c61 | ||
|
|
d6bcb143cc | ||
|
|
41054400bf | ||
|
|
704887999b | ||
|
|
3194fe9a30 | ||
|
|
5ce7308194 | ||
|
|
f9a9cf0ba0 | ||
|
|
bf90c6829f | ||
|
|
36d4097ff8 | ||
|
|
92bf8c3d47 | ||
|
|
4251f3468b | ||
|
|
a6869e7c14 | ||
|
|
bd46c358fb | ||
|
|
30b8ea1ae8 | ||
|
|
a24dacf50d | ||
|
|
7cbd07e33e | ||
|
|
c72ad83532 |
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -36,14 +36,14 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
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@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -57,4 +57,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||
|
||||
30
package.json
30
package.json
@@ -29,7 +29,7 @@
|
||||
"@babel/runtime": "7.28.4",
|
||||
"@braintree/sanitize-url": "7.1.1",
|
||||
"@codemirror/autocomplete": "6.20.0",
|
||||
"@codemirror/commands": "6.10.0",
|
||||
"@codemirror/commands": "6.10.1",
|
||||
"@codemirror/language": "6.11.3",
|
||||
"@codemirror/legacy-modes": "6.5.2",
|
||||
"@codemirror/search": "6.5.11",
|
||||
@@ -37,15 +37,15 @@
|
||||
"@codemirror/view": "6.39.4",
|
||||
"@date-fns/tz": "1.4.1",
|
||||
"@egjs/hammerjs": "2.0.17",
|
||||
"@formatjs/intl-datetimeformat": "7.0.1",
|
||||
"@formatjs/intl-displaynames": "7.0.1",
|
||||
"@formatjs/intl-durationformat": "0.8.1",
|
||||
"@formatjs/intl-getcanonicallocales": "3.0.1",
|
||||
"@formatjs/intl-listformat": "8.0.1",
|
||||
"@formatjs/intl-locale": "5.0.1",
|
||||
"@formatjs/intl-numberformat": "9.0.2",
|
||||
"@formatjs/intl-pluralrules": "6.0.1",
|
||||
"@formatjs/intl-relativetimeformat": "12.0.2",
|
||||
"@formatjs/intl-datetimeformat": "7.0.2",
|
||||
"@formatjs/intl-displaynames": "7.0.2",
|
||||
"@formatjs/intl-durationformat": "0.8.2",
|
||||
"@formatjs/intl-getcanonicallocales": "3.0.2",
|
||||
"@formatjs/intl-listformat": "8.0.2",
|
||||
"@formatjs/intl-locale": "5.0.2",
|
||||
"@formatjs/intl-numberformat": "9.0.3",
|
||||
"@formatjs/intl-pluralrules": "6.0.2",
|
||||
"@formatjs/intl-relativetimeformat": "12.0.3",
|
||||
"@fullcalendar/core": "6.1.19",
|
||||
"@fullcalendar/daygrid": "6.1.19",
|
||||
"@fullcalendar/interaction": "6.1.19",
|
||||
@@ -112,7 +112,7 @@
|
||||
"hls.js": "1.6.15",
|
||||
"home-assistant-js-websocket": "9.6.0",
|
||||
"idb-keyval": "6.2.2",
|
||||
"intl-messageformat": "11.0.1",
|
||||
"intl-messageformat": "11.0.2",
|
||||
"js-yaml": "4.1.1",
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
|
||||
@@ -151,12 +151,12 @@
|
||||
"@babel/plugin-transform-runtime": "7.28.5",
|
||||
"@babel/preset-env": "7.28.5",
|
||||
"@bundle-stats/plugin-webpack-filter": "4.21.7",
|
||||
"@lokalise/node-api": "15.4.0",
|
||||
"@lokalise/node-api": "15.5.0",
|
||||
"@octokit/auth-oauth-device": "8.0.3",
|
||||
"@octokit/plugin-retry": "8.0.3",
|
||||
"@octokit/rest": "22.0.1",
|
||||
"@rsdoctor/rspack-plugin": "1.3.16",
|
||||
"@rspack/core": "1.6.7",
|
||||
"@rspack/core": "1.6.8",
|
||||
"@rspack/dev-server": "1.1.4",
|
||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||
"@types/chromecast-caf-receiver": "6.0.25",
|
||||
@@ -191,7 +191,7 @@
|
||||
"eslint-plugin-unused-imports": "4.3.0",
|
||||
"eslint-plugin-wc": "3.0.2",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.2",
|
||||
"fs-extra": "11.3.3",
|
||||
"glob": "13.0.0",
|
||||
"gulp": "5.0.1",
|
||||
"gulp-brotli": "3.0.0",
|
||||
@@ -216,7 +216,7 @@
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.50.0",
|
||||
"vite-tsconfig-paths": "6.0.1",
|
||||
"vite-tsconfig-paths": "6.0.3",
|
||||
"vitest": "4.0.16",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
|
||||
@@ -473,6 +473,7 @@ export class HaStatisticPicker extends LitElement {
|
||||
.allowCustomValue=${this.allowCustomEntity}
|
||||
.disabled=${this.disabled}
|
||||
.label=${this.label}
|
||||
use-top-label
|
||||
.placeholder=${placeholder}
|
||||
.value=${this.value}
|
||||
.notFoundLabel=${this._notFoundLabel}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { listenMediaQuery } from "../common/dom/media_query";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-bottom-sheet";
|
||||
import "./ha-dialog-header";
|
||||
import "./ha-icon-button";
|
||||
@@ -118,27 +118,29 @@ export class HaAdaptiveDialog extends LitElement {
|
||||
if (this._mode === "bottom-sheet") {
|
||||
return html`
|
||||
<ha-bottom-sheet .open=${this.open} flexcontent>
|
||||
<ha-dialog-header
|
||||
slot="header"
|
||||
.subtitlePosition=${this.headerSubtitlePosition}
|
||||
>
|
||||
<slot name="headerNavigationIcon" slot="navigationIcon">
|
||||
<ha-icon-button
|
||||
data-drawer="close"
|
||||
.label=${this.hass?.localize("ui.common.close") ?? "Close"}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
</slot>
|
||||
${this.headerTitle !== undefined
|
||||
? html`<span slot="title" class="title" id="ha-wa-dialog-title">
|
||||
${this.headerTitle}
|
||||
</span>`
|
||||
: html`<slot name="headerTitle" slot="title"></slot>`}
|
||||
${this.headerSubtitle !== undefined
|
||||
? html`<span slot="subtitle">${this.headerSubtitle}</span>`
|
||||
: html`<slot name="headerSubtitle" slot="subtitle"></slot>`}
|
||||
<slot name="headerActionItems" slot="actionItems"></slot>
|
||||
</ha-dialog-header>
|
||||
<slot name="header" slot="header">
|
||||
<ha-dialog-header
|
||||
slot="header"
|
||||
.subtitlePosition=${this.headerSubtitlePosition}
|
||||
>
|
||||
<slot name="headerNavigationIcon" slot="navigationIcon">
|
||||
<ha-icon-button
|
||||
data-drawer="close"
|
||||
.label=${this.hass?.localize("ui.common.close") ?? "Close"}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
</slot>
|
||||
${this.headerTitle !== undefined
|
||||
? html`<span slot="title" class="title" id="ha-wa-dialog-title">
|
||||
${this.headerTitle}
|
||||
</span>`
|
||||
: html`<slot name="headerTitle" slot="title"></slot>`}
|
||||
${this.headerSubtitle !== undefined
|
||||
? html`<span slot="subtitle">${this.headerSubtitle}</span>`
|
||||
: html`<slot name="headerSubtitle" slot="subtitle"></slot>`}
|
||||
<slot name="headerActionItems" slot="actionItems"></slot>
|
||||
</ha-dialog-header>
|
||||
</slot>
|
||||
<slot></slot>
|
||||
<slot name="footer" slot="footer"></slot>
|
||||
</ha-bottom-sheet>
|
||||
@@ -157,10 +159,18 @@ export class HaAdaptiveDialog extends LitElement {
|
||||
.headerSubtitlePosition=${this.headerSubtitlePosition}
|
||||
flexcontent
|
||||
>
|
||||
<slot name="headerNavigationIcon" slot="headerNavigationIcon"></slot>
|
||||
<slot name="headerTitle" slot="headerTitle"></slot>
|
||||
<slot name="headerSubtitle" slot="headerSubtitle"></slot>
|
||||
<slot name="headerActionItems" slot="headerActionItems"></slot>
|
||||
<slot name="header" slot="header">
|
||||
<slot name="headerNavigationIcon" slot="headerNavigationIcon">
|
||||
<ha-icon-button
|
||||
data-dialog="close"
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
</slot>
|
||||
<slot name="headerTitle" slot="headerTitle"></slot>
|
||||
<slot name="headerSubtitle" slot="headerSubtitle"></slot>
|
||||
<slot name="headerActionItems" slot="headerActionItems"></slot>
|
||||
</slot>
|
||||
<slot></slot>
|
||||
<slot name="footer" slot="footer"></slot>
|
||||
</ha-wa-dialog>
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { animate } from "@lit-labs/motion";
|
||||
|
||||
import { mdiClose, mdiDelete } from "@mdi/js";
|
||||
import {
|
||||
mdiClose,
|
||||
mdiDelete,
|
||||
mdiCheckboxBlankOutline,
|
||||
mdiCheckboxMarkedOutline,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
||||
import { deleteImage, getIdFromUrl } from "../../data/image_upload";
|
||||
import type { MediaPlayerItem } from "../../data/media-player";
|
||||
import { MediaClassBrowserSettings } from "../../data/media-player";
|
||||
@@ -18,12 +22,13 @@ import {
|
||||
removeLocalMedia,
|
||||
} from "../../data/media_source";
|
||||
import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box";
|
||||
import { haStyleDialog, haStyleDialogFixedTop } from "../../resources/styles";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../ha-button";
|
||||
import "../ha-check-list-item";
|
||||
import "../ha-dialog";
|
||||
import "../ha-wa-dialog";
|
||||
import "../ha-dialog-header";
|
||||
import "../ha-dialog-footer";
|
||||
import "../ha-icon-button";
|
||||
import "../ha-list";
|
||||
import "../ha-spinner";
|
||||
import "../ha-svg-icon";
|
||||
@@ -46,14 +51,24 @@ class DialogMediaManage extends LitElement {
|
||||
|
||||
@state() private _selected = new Set<number>();
|
||||
|
||||
@state() private _open = false;
|
||||
|
||||
@state() private _filteredChildren: MediaPlayerItem[] = [];
|
||||
|
||||
private _filesChanged = false;
|
||||
|
||||
public showDialog(params: MediaManageDialogParams): void {
|
||||
this._params = params;
|
||||
this._refreshMedia();
|
||||
this._open = true;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._open = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private _dialogClosed(): void {
|
||||
if (this._filesChanged && this._params!.onClose) {
|
||||
this._params!.onClose();
|
||||
}
|
||||
@@ -65,88 +80,68 @@ class DialogMediaManage extends LitElement {
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected willUpdate() {
|
||||
this._filteredChildren =
|
||||
this._currentItem?.children?.filter((child) => !child.can_expand) || [];
|
||||
if (this._filteredChildren.length === 0 && this._selected.size !== 0) {
|
||||
// When running delete all, sometimes the list can throw off a spurious
|
||||
// select event that makes it think that 1 item is still selected. Clear selected
|
||||
// if nothing can be selected.
|
||||
this._selected = new Set();
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._params) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const children =
|
||||
this._currentItem?.children?.filter((child) => !child.can_expand) || [];
|
||||
|
||||
let fileIndex = 0;
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
hideActions
|
||||
flexContent
|
||||
.heading=${this._params.currentItem.title}
|
||||
@closed=${this.closeDialog}
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
?prevent-scrim-close=${this._uploading || this._deleting}
|
||||
@closed=${this._dialogClosed}
|
||||
>
|
||||
<ha-dialog-header slot="heading">
|
||||
<ha-dialog-header slot="header">
|
||||
${!(this._uploading || this._deleting)
|
||||
? html`<slot name="headerNavigationIcon" slot="navigationIcon">
|
||||
<ha-icon-button
|
||||
data-dialog="close"
|
||||
.label=${this.hass?.localize("ui.common.close") ?? "Close"}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button
|
||||
></slot>`
|
||||
: nothing}
|
||||
<span class="title" slot="title" id="dialog-box-title">
|
||||
${this.hass.localize(
|
||||
"ui.components.media-browser.file_management.title"
|
||||
)}
|
||||
</span>
|
||||
${this._selected.size === 0
|
||||
? html`
|
||||
<span slot="title">
|
||||
${this.hass.localize(
|
||||
"ui.components.media-browser.file_management.title"
|
||||
)}
|
||||
</span>
|
||||
|
||||
<ha-media-upload-button
|
||||
.disabled=${this._deleting}
|
||||
.hass=${this.hass}
|
||||
.currentItem=${this._params.currentItem}
|
||||
@uploading=${this._startUploading}
|
||||
@media-refresh=${this._doneUploading}
|
||||
slot="actionItems"
|
||||
></ha-media-upload-button>
|
||||
${this._uploading
|
||||
? ""
|
||||
: html`
|
||||
<ha-icon-button
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
dialogAction="close"
|
||||
slot="navigationIcon"
|
||||
dir=${computeRTLDirection(this.hass)}
|
||||
></ha-icon-button>
|
||||
`}
|
||||
`
|
||||
: html`
|
||||
<ha-button
|
||||
variant="danger"
|
||||
slot="navigationIcon"
|
||||
.disabled=${this._deleting}
|
||||
@click=${this._handleDelete}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.components.media-browser.file_management.${
|
||||
this._deleting ? "deleting" : "delete"
|
||||
}`,
|
||||
{ count: this._selected.size }
|
||||
)}
|
||||
</ha-button>
|
||||
|
||||
${this._deleting
|
||||
? ""
|
||||
: html`
|
||||
<ha-button
|
||||
slot="actionItems"
|
||||
@click=${this._handleDeselectAll}
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${mdiClose}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.components.media-browser.file_management.deselect_all`
|
||||
)}
|
||||
</ha-button>
|
||||
`}
|
||||
`}
|
||||
? html`<ha-media-upload-button
|
||||
.hass=${this.hass}
|
||||
.currentItem=${this._params.currentItem}
|
||||
@uploading=${this._startUploading}
|
||||
@media-refresh=${this._doneUploading}
|
||||
slot="actionItems"
|
||||
></ha-media-upload-button>`
|
||||
: html`<ha-button
|
||||
variant="danger"
|
||||
slot="actionItems"
|
||||
.disabled=${this._deleting}
|
||||
@click=${this._handleDelete}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.components.media-browser.file_management.${
|
||||
this._deleting ? "deleting" : "delete"
|
||||
}`,
|
||||
{ count: this._selected.size }
|
||||
)}
|
||||
</ha-button>`}
|
||||
</ha-dialog-header>
|
||||
${!this._currentItem
|
||||
? html`
|
||||
@@ -154,7 +149,7 @@ class DialogMediaManage extends LitElement {
|
||||
<ha-spinner></ha-spinner>
|
||||
</div>
|
||||
`
|
||||
: !children.length
|
||||
: !this._filteredChildren.length
|
||||
? html`<div class="no-items">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
@@ -170,9 +165,38 @@ class DialogMediaManage extends LitElement {
|
||||
: ""}
|
||||
</div>`
|
||||
: html`
|
||||
<div class="buttons" slot="footer">
|
||||
<ha-button
|
||||
appearance="filled"
|
||||
@click=${this._handleDeselectAll}
|
||||
.disabled=${this._selected.size === 0}
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${mdiCheckboxBlankOutline}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.components.media-browser.file_management.deselect_all`
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
appearance="filled"
|
||||
@click=${this._handleSelectAll}
|
||||
.disabled=${this._selected.size ===
|
||||
this._filteredChildren.length}
|
||||
>
|
||||
<ha-svg-icon
|
||||
.path=${mdiCheckboxMarkedOutline}
|
||||
slot="start"
|
||||
></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
`ui.components.media-browser.file_management.select_all`
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
<ha-list multi @selected=${this._handleSelected}>
|
||||
${repeat(
|
||||
children,
|
||||
this._filteredChildren,
|
||||
(item) => item.media_content_id,
|
||||
(item) => {
|
||||
const icon = html`
|
||||
@@ -220,7 +244,7 @@ class DialogMediaManage extends LitElement {
|
||||
)}
|
||||
</ha-tip>`
|
||||
: nothing}
|
||||
</ha-dialog>
|
||||
</ha-wa-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -244,6 +268,10 @@ class DialogMediaManage extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleSelectAll() {
|
||||
this._selected = new Set([...Array(this._filteredChildren.length).keys()]);
|
||||
}
|
||||
|
||||
private async _handleDelete() {
|
||||
if (
|
||||
!(await showConfirmationDialog(this, {
|
||||
@@ -304,23 +332,10 @@ class DialogMediaManage extends LitElement {
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
haStyleDialogFixedTop,
|
||||
css`
|
||||
ha-dialog {
|
||||
--dialog-z-index: 9;
|
||||
ha-wa-dialog {
|
||||
--dialog-content-padding: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
ha-dialog {
|
||||
--mdc-dialog-max-width: 800px;
|
||||
--mdc-dialog-max-height: calc(
|
||||
100vh - var(--ha-space-18) - var(--safe-area-inset-y)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ha-dialog-header ha-media-upload-button,
|
||||
ha-dialog-header ha-button {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
@@ -338,7 +353,11 @@ class DialogMediaManage extends LitElement {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.no-items {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -268,6 +268,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
|
||||
now.setHours(now.getHours() - this._hoursToShow);
|
||||
const configUrl = `/history?${createSearchParam({
|
||||
entity_id: this._entityIds.join(","),
|
||||
back: "1",
|
||||
start_date: now.toISOString(),
|
||||
})}`;
|
||||
|
||||
|
||||
@@ -1105,6 +1105,7 @@
|
||||
"delete": "Delete {count}",
|
||||
"deleting": "Deleting {count}",
|
||||
"deselect_all": "Deselect all",
|
||||
"select_all": "[%key:ui::components::subpage-data-table::select_all%]",
|
||||
"tip_media_storage": "[%key:ui::panel::config::tips::media_storage%]",
|
||||
"tip_storage_panel": "storage"
|
||||
},
|
||||
@@ -1333,6 +1334,7 @@
|
||||
"text": "Home Assistant is running in safe mode, custom integrations and frontend modules are not available. Restart Home Assistant to exit safe mode."
|
||||
},
|
||||
"quick-bar": {
|
||||
"commands_title": "Commands",
|
||||
"commands": {
|
||||
"reload": {
|
||||
"all": "[%key:ui::panel::developer-tools::tabs::yaml::section::reloading::all%]",
|
||||
@@ -4303,7 +4305,7 @@
|
||||
"entity": "Entity with timestamp",
|
||||
"offset_by": "offset by {offset}",
|
||||
"mode": "Mode",
|
||||
"weekday": "Weekdays",
|
||||
"weekday": "Days of the Week",
|
||||
"weekdays": {
|
||||
"mon": "[%key:ui::weekdays::monday%]",
|
||||
"tue": "[%key:ui::weekdays::tuesday%]",
|
||||
|
||||
Reference in New Issue
Block a user