diff --git a/.github/workflows/translations.yaml b/.github/workflows/translations.yaml index 5c74aa7579..f9d6a8852c 100644 --- a/.github/workflows/translations.yaml +++ b/.github/workflows/translations.yaml @@ -1,6 +1,7 @@ name: Translations on: + workflow_dispatch: push: branches: - dev diff --git a/public/static/images/dashboard-options/dark/icon-dashboard-areas.svg b/public/static/images/dashboard-options/dark/icon-dashboard-areas.svg index 136bf63783..b40c0a3976 100644 --- a/public/static/images/dashboard-options/dark/icon-dashboard-areas.svg +++ b/public/static/images/dashboard-options/dark/icon-dashboard-areas.svg @@ -1,35 +1,31 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/public/static/images/dashboard-options/light/icon-dashboard-areas.svg b/public/static/images/dashboard-options/light/icon-dashboard-areas.svg index 3ff70fef26..781d738a72 100644 --- a/public/static/images/dashboard-options/light/icon-dashboard-areas.svg +++ b/public/static/images/dashboard-options/light/icon-dashboard-areas.svg @@ -1,35 +1,31 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/script/translations_upload_base b/script/translations_upload_base index 2fb60613c6..156ba85d29 100755 --- a/script/translations_upload_base +++ b/script/translations_upload_base @@ -33,7 +33,7 @@ fi docker run \ -v ${LOCAL_FILE}:/opt/src/${LOCAL_FILE} \ - lokalise/lokalise-cli-2:v2.6.10 lokalise2 \ + lokalise/lokalise-cli-2:v3.1.4 lokalise2 \ --token ${LOKALISE_TOKEN} \ --project-id ${PROJECT_ID} \ file upload \ diff --git a/src/common/entity/compute_state_display.ts b/src/common/entity/compute_state_display.ts index bd61083c82..cf69669ac6 100644 --- a/src/common/entity/compute_state_display.ts +++ b/src/common/entity/compute_state_display.ts @@ -165,6 +165,7 @@ export const computeStateDisplayFromEntityAttributes = ( // state is a timestamp if ( [ + "ai_task", "button", "conversation", "event", diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 09d3bd0d44..e6a0bef350 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -29,6 +29,7 @@ import { formatTimeLabel } from "./axis-label"; import { ensureArray } from "../../common/array/ensure-array"; import "../chips/ha-assist-chip"; import { downSampleLineData } from "./down-sample"; +import { colorVariables } from "../../resources/theme/color.globals"; export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000; const LEGEND_OVERFLOW_LIMIT = 10; @@ -348,6 +349,13 @@ export class HaChartBase extends LitElement { const { start, end } = e.batch?.[0] ?? e; this._isZoomed = start !== 0 || end !== 100; this._zoomRatio = (end - start) / 100; + if (this._isTouchDevice) { + // zooming changes the axis pointer so we need to hide it + this.chart?.dispatchAction({ + type: "hideTip", + from: "datazoom", + }); + } }); this.chart.on("click", (e: ECElementEvent) => { fireEvent(this, "chart-click", e); @@ -369,6 +377,74 @@ export class HaChartBase extends LitElement { this._lastTapTime = Date.now(); } }); + // show axis pointer handle on touch devices + let dragJustEnded = false; + let lastTipX: number | undefined; + let lastTipY: number | undefined; + this.chart.on("showTip", (e: any) => { + lastTipX = e.x; + lastTipY = e.y; + this.chart?.setOption({ + xAxis: ensureArray(this.chart?.getOption().xAxis as any).map( + (axis: XAXisOption) => + axis.show + ? { + ...axis, + axisPointer: { + ...axis.axisPointer, + status: "show", + handle: { + color: colorVariables["primary-color"], + margin: 0, + size: 20, + ...axis.axisPointer?.handle, + show: true, + }, + }, + } + : axis + ), + }); + }); + this.chart.on("hideTip", (e: any) => { + // the drag end event doesn't have a `from` property + if (e.from) { + if (dragJustEnded) { + // hideTip is fired twice when the drag ends, so we need to ignore the second one + dragJustEnded = false; + return; + } + this.chart?.setOption({ + xAxis: ensureArray(this.chart?.getOption().xAxis as any).map( + (axis: XAXisOption) => + axis.show + ? { + ...axis, + axisPointer: { + ...axis.axisPointer, + handle: { + ...axis.axisPointer?.handle, + show: false, + }, + status: "hide", + }, + } + : axis + ), + }); + this.chart?.dispatchAction({ + type: "downplay", + }); + } else if (lastTipX != null && lastTipY != null) { + // echarts hides the tip as soon as the drag ends, so we need to show it again + dragJustEnded = true; + this.chart?.dispatchAction({ + type: "showTip", + x: lastTipX, + y: lastTipY, + }); + } + }); } const legend = ensureArray(this.options?.legend || [])[0] as diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index 332e11f0d3..4d5ad2a57e 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -59,6 +59,15 @@ class HaHLSPlayer extends LitElement { private static streamCount = 0; + private _handleVisibilityChange = () => { + if (document.hidden) { + this._cleanUp(); + } else { + this._resetError(); + this._startHls(); + } + }; + public connectedCallback() { super.connectedCallback(); HaHLSPlayer.streamCount += 1; @@ -66,10 +75,15 @@ class HaHLSPlayer extends LitElement { this._resetError(); this._startHls(); } + document.addEventListener("visibilitychange", this._handleVisibilityChange); } public disconnectedCallback() { super.disconnectedCallback(); + document.removeEventListener( + "visibilitychange", + this._handleVisibilityChange + ); HaHLSPlayer.streamCount -= 1; this._cleanUp(); } diff --git a/src/components/ha-web-rtc-player.ts b/src/components/ha-web-rtc-player.ts index 7d9528f38a..e44b9b0001 100644 --- a/src/components/ha-web-rtc-player.ts +++ b/src/components/ha-web-rtc-player.ts @@ -61,6 +61,14 @@ class HaWebRtcPlayer extends LitElement { private _candidatesList: RTCIceCandidate[] = []; + private _handleVisibilityChange = () => { + if (document.hidden) { + this._cleanUp(); + } else { + this._startWebRtc(); + } + }; + protected override render(): TemplateResult { if (this._error) { return html`${this._error}`; @@ -88,10 +96,15 @@ class HaWebRtcPlayer extends LitElement { if (this.hasUpdated && this.entityid) { this._startWebRtc(); } + document.addEventListener("visibilitychange", this._handleVisibilityChange); } public override disconnectedCallback() { super.disconnectedCallback(); + document.removeEventListener( + "visibilitychange", + this._handleVisibilityChange + ); this._cleanUp(); } diff --git a/src/dialogs/more-info/more-info-content.ts b/src/dialogs/more-info/more-info-content.ts index 0cf3e3dbf0..3e3808ca21 100644 --- a/src/dialogs/more-info/more-info-content.ts +++ b/src/dialogs/more-info/more-info-content.ts @@ -11,6 +11,9 @@ import { importMoreInfoControl } from "../../panels/lovelace/custom-card-helpers import "../../panels/lovelace/sections/hui-section"; import type { HomeAssistant } from "../../types"; import { stateMoreInfoType } from "./state_more_info_control"; +import type { LovelaceCardFeatureConfig } from "../../panels/lovelace/card-features/types"; +import { supportsLightBrightnessCardFeature } from "../../panels/lovelace/card-features/hui-light-brightness-card-feature"; +import { supportsCoverPositionCardFeature } from "../../panels/lovelace/card-features/hui-cover-position-card-feature"; @customElement("more-info-content") class MoreInfoContent extends LitElement { @@ -73,16 +76,32 @@ class MoreInfoContent extends LitElement { ); } - private _entitiesSectionConfig = memoizeOne((entityIds: string[]) => ({ - type: "grid", - cards: entityIds.map( - (entityId) => - ({ - type: "tile", - entity: entityId, - }) as TileCardConfig - ), - })); + private _entitiesSectionConfig = memoizeOne((entityIds: string[]) => { + const cards = entityIds.map((entityId) => { + const features: LovelaceCardFeatureConfig[] = []; + const context = { entity_id: entityId }; + if (supportsCoverPositionCardFeature(this.hass!, context)) { + features.push({ + type: "cover-position", + }); + } else if (supportsLightBrightnessCardFeature(this.hass!, context)) { + features.push({ + type: "light-brightness", + }); + } + return { + type: "tile", + entity: entityId, + features_position: "inline", + features, + grid_options: { columns: 12 }, + } as TileCardConfig; + }); + return { + type: "grid", + cards, + }; + }); static styles = css` hui-section { diff --git a/src/panels/config/integrations/ha-config-entry-row.ts b/src/panels/config/integrations/ha-config-entry-row.ts index 37b1020096..d0aa4b48c0 100644 --- a/src/panels/config/integrations/ha-config-entry-row.ts +++ b/src/panels/config/integrations/ha-config-entry-row.ts @@ -22,6 +22,8 @@ import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; +import { caseInsensitiveStringCompare } from "../../../common/string/compare"; +import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name"; import { isDevVersion } from "../../../common/config/version"; import { deleteApplicationCredential, @@ -491,18 +493,34 @@ class HaConfigEntryRow extends LitElement { ); private _getDevices = (): DeviceRegistryEntry[] => - Object.values(this.hass.devices).filter( - (device) => - device.config_entries.includes(this.entry.entry_id) && - device.entry_type !== "service" - ); + Object.values(this.hass.devices) + .filter( + (device) => + device.config_entries.includes(this.entry.entry_id) && + device.entry_type !== "service" + ) + .sort((a, b) => + caseInsensitiveStringCompare( + computeDeviceNameDisplay(a, this.hass), + computeDeviceNameDisplay(b, this.hass), + this.hass.locale.language + ) + ); private _getServices = (): DeviceRegistryEntry[] => - Object.values(this.hass.devices).filter( - (device) => - device.config_entries.includes(this.entry.entry_id) && - device.entry_type === "service" - ); + Object.values(this.hass.devices) + .filter( + (device) => + device.config_entries.includes(this.entry.entry_id) && + device.entry_type === "service" + ) + .sort((a, b) => + caseInsensitiveStringCompare( + computeDeviceNameDisplay(a, this.hass), + computeDeviceNameDisplay(b, this.hass), + this.hass.locale.language + ) + ); private _toggleExpand() { this._expanded = !this._expanded; diff --git a/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts b/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts index 7ad33565ff..5a5481c837 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts @@ -290,7 +290,8 @@ export class ZHANetworkVisualizationPage extends LitElement { }, symbolSize: (width / 4) * 6 + 3, // range 3-9 // By default, all links should be ignored for force layout - ignoreForceLayout: true, + // unless it's a route to the coordinator + ignoreForceLayout: route.dest_nwk !== "0x0000", }; links.push(link); existingLinks.push(link); @@ -331,7 +332,7 @@ export class ZHANetworkVisualizationPage extends LitElement { } }); - // Now set ignoreForceLayout to false for the strongest connection of each device + // Now set ignoreForceLayout to false for the best connection of each device // Except for the coordinator which can have multiple strong connections devices.forEach((device) => { if (device.device_type === "Coordinator") { @@ -342,18 +343,21 @@ export class ZHANetworkVisualizationPage extends LitElement { }); } else { // Find the link that corresponds to this strongest connection - let strongestLink: NetworkLink | undefined; - links.forEach((link) => { - if ( - (link.source === device.ieee || link.target === device.ieee) && - link.value! > (strongestLink?.value ?? 0) - ) { - strongestLink = link; + let bestLink: NetworkLink | undefined; + const alreadyHasBestLink = links.some((link) => { + if (link.source === device.ieee || link.target === device.ieee) { + if (!link.ignoreForceLayout) { + return true; + } + if (link.value! > (bestLink?.value ?? -1)) { + bestLink = link; + } } + return false; }); - if (strongestLink) { - strongestLink.ignoreForceLayout = false; + if (!alreadyHasBestLink && bestLink) { + bestLink.ignoreForceLayout = false; } } }); diff --git a/src/resources/ha-icons.ts b/src/resources/ha-icons.ts index 50513bd9f4..8855aa7cee 100644 --- a/src/resources/ha-icons.ts +++ b/src/resources/ha-icons.ts @@ -1,4 +1,4 @@ export const haCardSizeLarge = "M21 1C22.1046 1 23 1.89543 23 3V21C23 22.1046 22.1046 23 21 23H3C1.89543 23 1 22.1046 1 21V3C1 1.89543 1.89543 1 3 1H21ZM4.5 18C3.67157 18 3 18.6716 3 19.5C3 20.3284 3.67157 21 4.5 21H10.5C11.3284 21 12 20.3284 12 19.5C12 18.6716 11.3284 18 10.5 18H4.5ZM4.5 13C3.67157 13 3 13.6716 3 14.5C3 15.3284 3.67157 16 4.5 16H7.5C8.32843 16 9 15.3284 9 14.5C9 13.6716 8.32843 13 7.5 13H4.5ZM4 3C3.44772 3 3 3.44772 3 4V10C3 10.5523 3.44772 11 4 11H20C20.5523 11 21 10.5523 21 10V4C21 3.44772 20.5523 3 20 3H4Z"; export const haCardSizeSmall = - "M3 7C1.89543 7 1 7.89543 1 9V17C1 18.1046 1.89543 19 3 19H21C22.1046 19 23 18.1046 23 17V9C23 7.89543 22.1046 7 21 7H3ZM3 10.5C3 9.67157 3.67157 9 4.5 9H7.5C8.32843 9 9 9.67157 9 10.5C9 11.3284 8.32843 12 7.5 12H4.5C3.67157 12 3 11.3284 3 10.5ZM4.5 14C3.67157 14 3 14.6716 3 15.5C3 16.3284 3.67157 17 4.5 17H10.5C11.3284 17 12 16.3284 12 15.5C12 14.6716 11.3284 14 10.5 14H4.5Z"; + "M21 6C22.1046 6 23 6.89543 23 8V16C23 17.1046 22.1046 18 21 18H3C1.89543 18 1 17.1046 1 16V8C1 6.89543 1.89543 6 3 6H21ZM4.5 13C3.67157 13 3 13.6716 3 14.5C3 15.3284 3.67157 16 4.5 16H10.5C11.3284 16 12 15.3284 12 14.5C12 13.6716 11.3284 13 10.5 13H4.5ZM4.5 8C3.67157 8 3 8.67157 3 9.5C3 10.3284 3.67157 11 4.5 11H7.5C8.32843 11 9 10.3284 9 9.5C9 8.67157 8.32843 8 7.5 8H4.5Z"; diff --git a/src/translations/en.json b/src/translations/en.json index 4465f0fd6e..f129e93f62 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -888,7 +888,7 @@ "now-7d": "Last 7 days", "now-30d": "Last 30 days", "this_year": "This year", - "now-12m": "Last 12 month" + "now-12m": "Last 12 months" } }, "grid-size-picker": { @@ -3183,7 +3183,7 @@ }, "url": { "caption": "Home Assistant URL", - "description": "Configure what website addresses Home Assistant should share with other devices when they need to fetch data from Home Assistant (eg. to play text-to-speech or other hosted media).", + "description": "Configure what website addresses Home Assistant should share with other devices when they need to fetch data from Home Assistant (e.g. to play text-to-speech or other hosted media).", "internal_url_label": "Local network", "external_url_label": "Internet", "external_use_ha_cloud": "Use Home Assistant Cloud", @@ -3210,7 +3210,7 @@ "attributes": "Attributes" }, "reboot_moved_title": "Reboot and shutdown moved", - "reboot_moved_description": "Reboot and shutdown actions has been moved to system page.", + "reboot_moved_description": "Reboot and shutdown actions have been moved to system page.", "reboot_moved_link": "Go to system page.", "processor": "Processor", "memory": "Memory", @@ -3924,7 +3924,7 @@ "description": { "picker": "When Home Assistant starts up or shuts down.", "started": "When Home Assistant is started", - "shutdown": "When Home Assistant is shutdown" + "shutdown": "When Home Assistant is shut down" } }, "mqtt": { @@ -4148,7 +4148,7 @@ "upper_limit": "[%key:ui::panel::config::automation::editor::triggers::type::numeric_state::upper_limit%]", "value_template": "[%key:ui::panel::config::automation::editor::triggers::type::numeric_state::value_template%]", "description": { - "picker": "If the numeric value of an entity''s state (or attribute''s value) is above or below a given threshold.", + "picker": "If the numeric value of an entity's state (or attribute's value) is above or below a given threshold.", "above": "If {attribute, select, \n undefined {} \n other {{attribute} from }\n }{entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} above {above}", "below": "If {attribute, select, \n undefined {} \n other {{attribute} from }\n }{entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} below {below}", "above-below": "If {attribute, select, \n undefined {} \n other {{attribute} from }\n }{entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} above {above} and below {below}" @@ -4641,7 +4641,7 @@ "delete": "[%key:ui::common::delete%]", "duplicate": "[%key:ui::common::duplicate%]", "empty_header": "Create your first script", - "empty_text": "A script is a sequence of actions that can be run from a dashboard, an automation, or be triggered by voice. For example, a ''Wake-up routine''' script that gradually turns on the light in the bedroom and opens the blinds after a delay.", + "empty_text": "A script is a sequence of actions that can be run from a dashboard, an automation, or be triggered by voice. For example, a ''Wake-up routine'' script that gradually turns on the light in the bedroom and opens the blinds after a delay.", "search": "Search {number} {number, plural,\n one {script}\n other {scripts}\n}", "migrate_script": "Migrate script?", "migrate_script_description": "You can migrate this script, so it can be edited from the UI. After it is migrated and you have saved it, you will have to manually delete your old script from your configuration. Do you want to migrate this script?" @@ -4814,7 +4814,7 @@ "introduction": "Home Assistant Cloud provides you with a secure remote connection to your instance while away from home. It also allows you to connect with cloud-only services: Amazon Alexa and Google Assistant.", "introduction2": "This service is run by our partner ", "introduction2a": ", a company founded by the founders of Home Assistant.", - "introduction3": "Home Assistant Cloud is a subscription service with a free one month trial. No payment information necessary.", + "introduction3": "Home Assistant Cloud is a subscription service with a free one-month trial. No payment information necessary.", "learn_more_link": "Learn more about Home Assistant Cloud", "sign_in": "Sign in", "email": "Email", @@ -4826,7 +4826,7 @@ "cancel": "Cancel", "submit": "Submit", "forgot_password": "Forgot password?", - "start_trial": "Start your free 1 month trial", + "start_trial": "Start your free 1-month trial", "trial_info": "No payment information necessary", "alert_password_change_required": "You need to change your password before logging in.", "alert_email_confirm_necessary": "You need to confirm your email before logging in.", @@ -4839,7 +4839,7 @@ "forgot_password": { "title": "Forgot password", "subtitle": "Forgot your password", - "instructions": "Enter your email address and we will send you a link to reset your password.", + "instructions": "Enter your email address, and we will send you a link to reset your password.", "email": "Email", "email_error_msg": "Invalid email", "send_reset_email": "Send reset email", @@ -4848,7 +4848,7 @@ "register": { "title": "Register account", "headline": "Start your free trial", - "information": "Create an account to start your free one month trial with Home Assistant Cloud. No payment information necessary.", + "information": "Create an account to start your free one-month trial with Home Assistant Cloud. No payment information necessary.", "information2": "The trial will give you access to all the benefits of Home Assistant Cloud, including:", "feature_remote_control": "Control of Home Assistant away from home", "feature_google_home": "Integration with Google Assistant", @@ -4998,7 +4998,7 @@ }, "dialog_already_connected": { "heading": "Account linked to other Home Assistant", - "description": "We noticed that another instance is currently connected to your Home Assistant Cloud account. Your Home Assistant Cloud account can only be signed into one Home Assistant instance at a time. If you log in here, the other instance will be disconnected along with its Cloud services and you will need to be physically present to reconnect it. Nabu Casa support is unable to remotely reconnect a disconnected Home Assistant instance.", + "description": "We noticed that another instance is currently connected to your Home Assistant Cloud account. Your Home Assistant Cloud account can only be signed in to one Home Assistant instance at a time. If you log in here, the other instance will be disconnected along with its Cloud services and you will need to be physically present to reconnect it. Nabu Casa support is unable to remotely reconnect a disconnected Home Assistant instance.", "other_home_assistant": "Other Home Assistant", "instance_name": "Instance name", "instance_version": "Instance version", @@ -8896,7 +8896,7 @@ "password": "[%key:supervisor::backup::password%]", "confirm_password": "[%key:supervisor::backup::confirm_password%]", "confirm_restore_partial_backup_title": "[%key:supervisor::backup::confirm_restore_partial_backup_title%]", - "confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again and you see the login screen. If it fails it will bring you back to the onboarding.", + "confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shut down and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again and you see the login screen. If it fails it will bring you back to the onboarding.", "confirm_restore_full_backup_title": "[%key:supervisor::backup::confirm_restore_full_backup_title%]", "confirm_restore_full_backup_text": "Depending on the size of the backup, this can take up to 45 minutes. Home Assistant will restart and you will see the login screen when it’s restored.", "restore": "[%key:supervisor::backup::restore%]", @@ -9253,7 +9253,7 @@ "failed_to_update_name": "Failed to update {name}", "learn_more": "Learn more", "new_version_available": "New version available", - "newest_version": "Newest Version", + "newest_version": "Newest version", "refresh": "[%key:ui::common::refresh%]", "release_notes": "Release notes", "reload": "Reload", @@ -9401,7 +9401,7 @@ "host": { "failed_to_get_hardware_list": "Failed to get hardware list", "failed_to_reboot": "Failed to reboot the host", - "failed_to_shutdown": "Failed to shutdown the host", + "failed_to_shutdown": "Failed to shut down the host", "failed_to_set_hostname": "Setting hostname failed", "failed_to_import_from_usb": "Failed to import from USB", "failed_to_move": "Failed to move data disk", @@ -9417,8 +9417,8 @@ "emmc_lifetime_used": "eMMC lifetime used", "reboot_host": "Reboot host", "confirm_reboot": "Are you sure you want to reboot the host?", - "confirm_shutdown": "Are you sure you want to shutdown the host?", - "shutdown_host": "Shutdown host", + "confirm_shutdown": "Are you sure you want to shut down the host?", + "shutdown_host": "Shut down host", "hardware": "Hardware", "import_from_usb": "Import from USB", "move_datadisk": "Move data disk" @@ -9464,9 +9464,9 @@ "passwords_not_matching": "The passwords do not match", "backup_already_running": "A backup or restore is already running. Creating a new backup is currently not possible, try again later.", "confirm_restore_partial_backup_title": "Restore partial backup", - "confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.", + "confirm_restore_partial_backup_text": "The backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shut down and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.", "confirm_restore_full_backup_title": "Restore full backup", - "confirm_restore_full_backup_text": "Your entire system will be wiped and the backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shutdown and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.", + "confirm_restore_full_backup_text": "Your entire system will be wiped and the backup will be restored. Depending on the size of the backup, this can take up to 45 min. Home Assistant needs to shut down and the restore progress is running in the background. If it succeeds, Home Assistant will automatically start again.", "confirm_delete_title": "Delete backup", "confirm_delete_text": "This backup will be permanently deleted and cannot be restored later.", "restore": "Restore", diff --git a/yarn.lock b/yarn.lock index b3743d35d2..1e2bc4fb88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6028,13 +6028,13 @@ __metadata: linkType: hard "axios@npm:^1.10.0": - version: 1.10.0 - resolution: "axios@npm:1.10.0" + version: 1.11.0 + resolution: "axios@npm:1.11.0" dependencies: follow-redirects: "npm:^1.15.6" - form-data: "npm:^4.0.0" + form-data: "npm:^4.0.4" proxy-from-env: "npm:^1.1.0" - checksum: 10/d43c80316a45611fd395743e15d16ea69a95f2b7f7095f2bb12cb78f9ca0a905194a02e52a3bf4e0db9f85fd1186d6c690410644c10ecd8bb0a468e57c2040e4 + checksum: 10/232df4af7a4e4e07baa84621b9cc4b0c518a757b4eacc7f635c0eb3642cb98dff347326739f24b891b3b4481b7b838c79a3a0c4819c9fbc1fc40232431b9c5dc languageName: node linkType: hard @@ -8713,7 +8713,7 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.0": +"form-data@npm:^4.0.0, form-data@npm:^4.0.4": version: 4.0.4 resolution: "form-data@npm:4.0.4" dependencies: