1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-05-08 09:18:34 +01:00

Rename Add-ons to Apps in more areas (#29076)

* Remove add-ons mention in agents file

* Rename user facing form and selector name

* Everything else

* Update more

* Update more

* Update more

* Update more

* Update key

* Update key

* Update keys

* Use translation

* More changes

* Update key

* Backward / Forward compat

* Drop "the"

Co-authored-by: Norbert Rittel <norbert@rittel.de>

---------

Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
Aidan Timson
2026-01-20 11:39:30 +00:00
committed by GitHub
parent 3b8d485ec6
commit 2d24447c3c
42 changed files with 367 additions and 360 deletions
+1 -2
View File
@@ -621,7 +621,6 @@ this.hass.localize("ui.panel.config.updates.update_available", {
#### Key Terminology
- **"add-on"** (hyphenated, not "addon")
- **"integration"** (preferred over "component")
- **Technical terms**: Use lowercase (automation, entity, device, service)
@@ -713,7 +712,7 @@ this.hass.localize("ui.panel.config.automation.delete_confirm", {
- [ ] American English spelling
- [ ] Friendly, informational tone
- [ ] Avoids abbreviations and jargon
- [ ] Correct terminology (add-on not addon, integration not component)
- [ ] Correct terminology (integration not component)
### Component-Specific Checks
+1 -1
View File
@@ -169,7 +169,7 @@ const SCHEMAS: {
{
title: "Selectors",
translations: {
addon: "Addon",
addon: "App",
entity: "Entity",
device: "Device",
area: "Area",
+1 -1
View File
@@ -239,7 +239,7 @@ const SCHEMAS: {
selector: { config_entry: {} },
},
duration: { name: "Duration", selector: { duration: {} } },
addon: { name: "Addon", selector: { addon: {} } },
addon: { name: "App", selector: { addon: {} } },
number_box: {
name: "Number Box",
selector: {
@@ -83,10 +83,10 @@ export class HassioAddonRepositoryEl extends LitElement {
? this.supervisor.localize(
"common.new_version_available"
)
: this.supervisor.localize("addon.state.installed")
: this.supervisor.localize("app.state.installed")
: addon.available
? this.supervisor.localize("addon.state.not_installed")
: this.supervisor.localize("addon.state.not_available")}
? this.supervisor.localize("app.state.not_installed")
: this.supervisor.localize("app.state.not_available")}
.iconClass=${addon.installed
? addon.update_available
? "update"
+1 -1
View File
@@ -120,7 +120,7 @@ export class HassioAddonStore extends LitElement {
? html`
<div class="advanced">
<a href="/profile" target="_top">
${this.supervisor.localize("store.missing_addons")}
${this.supervisor.localize("store.missing_apps")}
</a>
</div>
`
@@ -44,7 +44,7 @@ class HassioAddonAudio extends LitElement {
return html`
<ha-card
outlined
.header=${this.supervisor.localize("addon.configuration.audio.header")}
.header=${this.supervisor.localize("app.configuration.audio.header")}
>
<div class="card-content">
${this._error
@@ -52,9 +52,7 @@ class HassioAddonAudio extends LitElement {
: nothing}
${this._inputDevices &&
html`<ha-select
.label=${this.supervisor.localize(
"addon.configuration.audio.input"
)}
.label=${this.supervisor.localize("app.configuration.audio.input")}
@selected=${this._setInputDevice}
@closed=${stopPropagation}
fixedMenuPosition
@@ -72,9 +70,7 @@ class HassioAddonAudio extends LitElement {
</ha-select>`}
${this._outputDevices &&
html`<ha-select
.label=${this.supervisor.localize(
"addon.configuration.audio.output"
)}
.label=${this.supervisor.localize("app.configuration.audio.output")}
@selected=${this._setOutputDevice}
@closed=${stopPropagation}
fixedMenuPosition
@@ -153,7 +149,7 @@ class HassioAddonAudio extends LitElement {
const noDevice: HassioHardwareAudioDevice = {
device: "default",
name: this.supervisor.localize("addon.configuration.audio.default"),
name: this.supervisor.localize("app.configuration.audio.default"),
};
try {
@@ -81,7 +81,7 @@ class HassioAddonConfigDashboard extends LitElement {
`
: nothing}
`
: this.supervisor.localize("addon.configuration.no_configuration")}
: this.supervisor.localize("app.configuration.no_configuration")}
</div>
`;
}
@@ -219,7 +219,7 @@ class HassioAddonConfig extends LitElement {
<ha-card outlined>
<div class="header">
<h2>
${this.supervisor.localize("addon.configuration.options.header")}
${this.supervisor.localize("app.configuration.options.header")}
</h2>
<div class="card-menu">
<ha-button-menu @action=${this._handleAction}>
@@ -231,10 +231,10 @@ class HassioAddonConfig extends LitElement {
<ha-list-item .disabled=${!this._canShowSchema || this.disabled}>
${this._yamlMode
? this.supervisor.localize(
"addon.configuration.options.edit_in_ui"
"app.configuration.options.edit_in_ui"
)
: this.supervisor.localize(
"addon.configuration.options.edit_in_yaml"
"app.configuration.options.edit_in_yaml"
)}
</ha-list-item>
<ha-list-item
@@ -279,7 +279,7 @@ class HassioAddonConfig extends LitElement {
: html`
<ha-alert alert-type="error">
${this.supervisor.localize(
"addon.configuration.options.invalid_yaml"
"app.configuration.options.invalid_yaml"
)}
</ha-alert>
`}
@@ -288,7 +288,7 @@ class HassioAddonConfig extends LitElement {
? html`<ha-formfield
class="show-additional"
.label=${this.supervisor.localize(
"addon.configuration.options.show_unused_optional"
"app.configuration.options.show_unused_optional"
)}
>
<ha-switch
@@ -397,7 +397,7 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_reset", {
this._error = this.supervisor.localize("app.failed_to_reset", {
error: extractApiErrorMessage(err),
});
}
@@ -440,7 +440,7 @@ class HassioAddonConfig extends LitElement {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
eventdata.success = false;
@@ -56,14 +56,12 @@ class HassioAddonNetwork extends LitElement {
return html`
<ha-card
outlined
.header=${this.supervisor.localize(
"addon.configuration.network.header"
)}
.header=${this.supervisor.localize("app.configuration.network.header")}
>
<div class="card-content">
<p>
${this.supervisor.localize(
"addon.configuration.network.introduction"
"app.configuration.network.introduction"
)}
</p>
${this._error
@@ -87,7 +85,7 @@ class HassioAddonNetwork extends LitElement {
? html`<ha-formfield
class="show-optional"
.label=${this.supervisor.localize(
"addon.configuration.network.show_disabled"
"app.configuration.network.show_disabled"
)}
>
<ha-switch
@@ -187,7 +185,7 @@ class HassioAddonNetwork extends LitElement {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_reset", {
this._error = this.supervisor.localize("app.failed_to_reset", {
error: extractApiErrorMessage(err),
});
button.actionError();
@@ -229,7 +227,7 @@ class HassioAddonNetwork extends LitElement {
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
}
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
button.actionError();
@@ -83,7 +83,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
);
} catch (err: any) {
this._error = this.supervisor.localize(
"addon.documentation.get_documentation",
"app.documentation.get_documentation",
{ error: extractApiErrorMessage(err) }
);
}
@@ -89,7 +89,7 @@ class HassioAddonDashboard extends LitElement {
const addonTabs: PageNavigation[] = [
{
translationKey: "addon.panel.info",
translationKey: "app.panel.info",
path: `/hassio/addon/${this.addon.slug}/info`,
iconPath: mdiInformationVariant,
},
@@ -97,7 +97,7 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.documentation) {
addonTabs.push({
translationKey: "addon.panel.documentation",
translationKey: "app.panel.documentation",
path: `/hassio/addon/${this.addon.slug}/documentation`,
iconPath: mdiFileDocument,
});
@@ -106,12 +106,12 @@ class HassioAddonDashboard extends LitElement {
if (this.addon.version) {
addonTabs.push(
{
translationKey: "addon.panel.configuration",
translationKey: "app.panel.configuration",
path: `/hassio/addon/${this.addon.slug}/config`,
iconPath: mdiCogs,
},
{
translationKey: "addon.panel.log",
translationKey: "app.panel.log",
path: `/hassio/addon/${this.addon.slug}/logs`,
iconPath: mdiTextBoxOutline,
}
@@ -195,10 +195,10 @@ class HassioAddonDashboard extends LitElement {
) {
if (
!(await showConfirmationDialog(this, {
title: this.supervisor.localize("my.add_addon_repository_title"),
title: this.supervisor.localize("my.add_app_repository_title"),
text: this.supervisor.localize(
"my.add_addon_repository_description",
{ addon: requestedAddon, repository: requestedAddonRepository }
"my.add_app_repository_description",
{ app: requestedAddon, repository: requestedAddonRepository }
),
confirmText: this.supervisor.localize("common.add"),
dismissText: this.supervisor.localize("common.cancel"),
@@ -224,7 +224,7 @@ class HassioAddonDashboard extends LitElement {
(addon) => addon.slug === requestedAddon
);
if (!validAddon) {
this._error = this.supervisor.localize("my.error_addon_not_found");
this._error = this.supervisor.localize("my.error_app_not_found");
} else {
navigate(`/hassio/addon/${requestedAddon}`, { replace: true });
}
+69 -74
View File
@@ -150,11 +150,11 @@ class HassioAddonInfo extends LitElement {
: undefined;
const metrics = [
{
description: this.supervisor.localize("addon.dashboard.cpu_usage"),
description: this.supervisor.localize("app.dashboard.cpu_usage"),
value: this._metrics?.cpu_percent,
},
{
description: this.supervisor.localize("addon.dashboard.ram_usage"),
description: this.supervisor.localize("app.dashboard.ram_usage"),
value: this._metrics?.memory_percent,
tooltip: `${bytesToString(this._metrics?.memory_usage)}/${bytesToString(
this._metrics?.memory_limit
@@ -181,11 +181,11 @@ class HassioAddonInfo extends LitElement {
<ha-alert
alert-type="error"
.title=${this.supervisor.localize(
"addon.dashboard.protection_mode.title"
"app.dashboard.protection_mode.title"
)}
>
${this.supervisor.localize(
"addon.dashboard.protection_mode.content"
"app.dashboard.protection_mode.content"
)}
<ha-button
variant="danger"
@@ -193,7 +193,7 @@ class HassioAddonInfo extends LitElement {
@click=${this._protectionToggled}
>
${this.supervisor.localize(
"addon.dashboard.protection_mode.enable"
"app.dashboard.protection_mode.enable"
)}
</ha-button>
</ha-alert>
@@ -220,7 +220,7 @@ class HassioAddonInfo extends LitElement {
? html`
<ha-svg-icon
.title=${this.supervisor.localize(
"dashboard.addon_running"
"dashboard.app_running"
)}
class="running"
.path=${mdiPlayCircle}
@@ -229,7 +229,7 @@ class HassioAddonInfo extends LitElement {
: html`
<ha-svg-icon
.title=${this.supervisor.localize(
"dashboard.addon_stopped"
"dashboard.app_stopped"
)}
class="stopped"
.path=${mdiCircleOffOutline}
@@ -242,22 +242,19 @@ class HassioAddonInfo extends LitElement {
<div class="description light-color">
${this.addon.version
? html`
${this.supervisor.localize(
"addon.dashboard.current_version",
{ version: this.addon.version }
)}
${this.supervisor.localize("app.dashboard.current_version", {
version: this.addon.version,
})}
<div class="changelog" @click=${this._openChangelog}>
(<span class="changelog-link"
>${this.supervisor.localize(
"addon.dashboard.changelog"
"app.dashboard.changelog"
)}</span
>)
</div>
`
: html`<span class="changelog-link" @click=${this._openChangelog}
>${this.supervisor.localize(
"addon.dashboard.changelog"
)}</span
>${this.supervisor.localize("app.dashboard.changelog")}</span
>`}
</div>
@@ -274,7 +271,7 @@ class HassioAddonInfo extends LitElement {
id="stage"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
`addon.dashboard.capability.stages.${this.addon.stage}`
`app.dashboard.capability.stages.${this.addon.stage}`
)
)}
>
@@ -298,7 +295,7 @@ class HassioAddonInfo extends LitElement {
id="rating"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.rating"
"app.dashboard.capability.label.rating"
)
)}
>
@@ -313,7 +310,7 @@ class HassioAddonInfo extends LitElement {
id="host_network"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.host"
"app.dashboard.capability.label.host"
)
)}
>
@@ -329,7 +326,7 @@ class HassioAddonInfo extends LitElement {
id="full_access"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.hardware"
"app.dashboard.capability.label.hardware"
)
)}
>
@@ -345,7 +342,7 @@ class HassioAddonInfo extends LitElement {
id="homeassistant_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.core"
"app.dashboard.capability.label.core"
)
)}
>
@@ -364,7 +361,7 @@ class HassioAddonInfo extends LitElement {
id="hassio_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
`addon.dashboard.capability.role.${this.addon.hassio_role}`
`app.dashboard.capability.role.${this.addon.hassio_role}`
) || this.addon.hassio_role
)}
>
@@ -383,7 +380,7 @@ class HassioAddonInfo extends LitElement {
id="docker_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.docker"
"app.dashboard.capability.label.docker"
)
)}
>
@@ -399,7 +396,7 @@ class HassioAddonInfo extends LitElement {
id="host_pid"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.host_pid"
"app.dashboard.capability.label.host_pid"
)
)}
>
@@ -416,7 +413,7 @@ class HassioAddonInfo extends LitElement {
id="apparmor"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.apparmor"
"app.dashboard.capability.label.apparmor"
)
)}
>
@@ -432,7 +429,7 @@ class HassioAddonInfo extends LitElement {
id="auth_api"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.auth"
"app.dashboard.capability.label.auth"
)
)}
>
@@ -448,7 +445,7 @@ class HassioAddonInfo extends LitElement {
id="ingress"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.ingress"
"app.dashboard.capability.label.ingress"
)
)}
>
@@ -467,7 +464,7 @@ class HassioAddonInfo extends LitElement {
id="signed"
.label=${capitalizeFirstLetter(
this.supervisor.localize(
"addon.dashboard.capability.label.signed"
"app.dashboard.capability.label.signed"
)
)}
>
@@ -482,7 +479,7 @@ class HassioAddonInfo extends LitElement {
@click=${this._showSystemManagedDialog}
id="system_managed"
.label=${capitalizeFirstLetter(
this.supervisor.localize("addon.system_managed.badge")
this.supervisor.localize("app.system_managed.badge")
)}
>
<ha-svg-icon
@@ -496,7 +493,7 @@ class HassioAddonInfo extends LitElement {
<div class="description light-color">
${this.addon.description}.<br />
${this.supervisor.localize("addon.dashboard.visit_addon_page", {
${this.supervisor.localize("app.dashboard.visit_app_page", {
name: html`<a
href=${this.addon.url!}
target="_blank"
@@ -527,12 +524,12 @@ class HassioAddonInfo extends LitElement {
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.boot.title"
"app.dashboard.option.boot.title"
)}
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.boot.description"
"app.dashboard.option.boot.description"
)}
</span>
<ha-switch
@@ -548,12 +545,12 @@ class HassioAddonInfo extends LitElement {
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.watchdog.title"
"app.dashboard.option.watchdog.title"
)}
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.watchdog.description"
"app.dashboard.option.watchdog.description"
)}
</span>
<ha-switch
@@ -572,12 +569,12 @@ class HassioAddonInfo extends LitElement {
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.auto_update.title"
"app.dashboard.option.auto_update.title"
)}
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.auto_update.description"
"app.dashboard.option.auto_update.description"
)}
</span>
<ha-switch
@@ -595,12 +592,12 @@ class HassioAddonInfo extends LitElement {
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.ingress_panel.title"
"app.dashboard.option.ingress_panel.title"
)}
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.ingress_panel.description"
"app.dashboard.option.ingress_panel.description"
)}
</span>
<ha-switch
@@ -618,12 +615,12 @@ class HassioAddonInfo extends LitElement {
<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize(
"addon.dashboard.option.protected.title"
"app.dashboard.option.protected.title"
)}
</span>
<span slot="description">
${this.supervisor.localize(
"addon.dashboard.option.protected.description"
"app.dashboard.option.protected.description"
)}
</span>
<ha-switch
@@ -644,7 +641,7 @@ class HassioAddonInfo extends LitElement {
${this.addon.version && this.addon.state === "started"
? html`<ha-settings-row ?three-line=${this.narrow}>
<span slot="heading">
${this.supervisor.localize("addon.dashboard.hostname")}
${this.supervisor.localize("app.dashboard.hostname")}
</span>
<code slot="description"> ${this.addon.hostname} </code>
</ha-settings-row>
@@ -671,14 +668,14 @@ class HassioAddonInfo extends LitElement {
? html`
<ha-alert alert-type="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_arch"
"app.dashboard.not_available_arch"
)}
</ha-alert>
`
: html`
<ha-alert alert-type="warning">
${this.supervisor.localize(
"addon.dashboard.not_available_version",
"app.dashboard.not_available_version",
{
core_version_installed: this.supervisor.core.version,
core_version_needed: addonStoreInfo!.homeassistant,
@@ -699,14 +696,14 @@ class HassioAddonInfo extends LitElement {
@click=${this._stopClicked}
.disabled=${systemManaged && !this.controlEnabled}
>
${this.supervisor.localize("addon.dashboard.stop")}
${this.supervisor.localize("app.dashboard.stop")}
</ha-progress-button>
<ha-progress-button
variant="danger"
appearance="plain"
@click=${this._restartClicked}
>
${this.supervisor.localize("addon.dashboard.restart")}
${this.supervisor.localize("app.dashboard.restart")}
</ha-progress-button>
`
: html`
@@ -715,7 +712,7 @@ class HassioAddonInfo extends LitElement {
.progress=${this.addon.state === "startup"}
appearance="plain"
>
${this.supervisor.localize("addon.dashboard.start")}
${this.supervisor.localize("app.dashboard.start")}
</ha-progress-button>
`
: nothing}
@@ -729,7 +726,7 @@ class HassioAddonInfo extends LitElement {
@click=${this._uninstallClicked}
.disabled=${systemManaged && !this.controlEnabled}
>
${this.supervisor.localize("addon.dashboard.uninstall")}
${this.supervisor.localize("app.dashboard.uninstall")}
</ha-progress-button>
${this.addon.build
? html`
@@ -738,7 +735,7 @@ class HassioAddonInfo extends LitElement {
appearance="plain"
@click=${this._rebuildClicked}
>
${this.supervisor.localize("addon.dashboard.rebuild")}
${this.supervisor.localize("app.dashboard.rebuild")}
</ha-progress-button>
`
: nothing}
@@ -761,7 +758,7 @@ class HassioAddonInfo extends LitElement {
: undefined}
>
${this.supervisor.localize(
"addon.dashboard.open_web_ui"
"app.dashboard.open_web_ui"
)}
</ha-button>
`
@@ -772,7 +769,7 @@ class HassioAddonInfo extends LitElement {
.disabled=${!this.addon.available}
@click=${this._installClicked}
>
${this.supervisor.localize("addon.dashboard.install")}
${this.supervisor.localize("app.dashboard.install")}
</ha-progress-button>
`}
</div>
@@ -804,7 +801,7 @@ class HassioAddonInfo extends LitElement {
"state" in this.addon &&
this.addon.state === "startup"
) {
// Addon is starting up, wait for it to start
// App is starting up, wait for it to start
this._scheduleDataUpdate();
}
}
@@ -858,11 +855,11 @@ class HassioAddonInfo extends LitElement {
private _showMoreInfo(ev): void {
const id = ev.currentTarget.id as AddonCapability;
showHassioMarkdownDialog(this, {
title: this.supervisor.localize(`addon.dashboard.capability.${id}.title`),
title: this.supervisor.localize(`app.dashboard.capability.${id}.title`),
content:
id === "stage"
? this.supervisor.localize(
`addon.dashboard.capability.${id}.description`,
`app.dashboard.capability.${id}.description`,
{
icon_stable: `<ha-svg-icon path="${STAGE_ICON.stable}"></ha-svg-icon>`,
icon_experimental: `<ha-svg-icon path="${STAGE_ICON.experimental}"></ha-svg-icon>`,
@@ -870,7 +867,7 @@ class HassioAddonInfo extends LitElement {
}
)
: this.supervisor.localize(
`addon.dashboard.capability.${id}.description`
`app.dashboard.capability.${id}.description`
),
});
}
@@ -936,7 +933,7 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
}
@@ -956,7 +953,7 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
}
@@ -976,7 +973,7 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
}
@@ -996,7 +993,7 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
}
@@ -1016,7 +1013,7 @@ class HassioAddonInfo extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
this._error = this.supervisor.localize("addon.failed_to_save", {
this._error = this.supervisor.localize("app.failed_to_save", {
error: extractApiErrorMessage(err),
});
}
@@ -1030,13 +1027,13 @@ class HassioAddonInfo extends LitElement {
);
showHassioMarkdownDialog(this, {
title: this.supervisor.localize("addon.dashboard.changelog"),
title: this.supervisor.localize("app.dashboard.changelog"),
content: extractChangelog(this.addon as HassioAddonDetails, content),
});
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.get_changelog"
"app.dashboard.action_error.get_changelog"
),
text: extractApiErrorMessage(err),
});
@@ -1066,7 +1063,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.install"),
title: this.supervisor.localize("app.dashboard.action_error.install"),
text: extractApiErrorMessage(err),
});
}
@@ -1091,7 +1088,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.stop"),
title: this.supervisor.localize("app.dashboard.action_error.stop"),
text: extractApiErrorMessage(err),
});
}
@@ -1112,7 +1109,7 @@ class HassioAddonInfo extends LitElement {
fireEvent(this, "hass-api-called", eventdata);
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.restart"),
title: this.supervisor.localize("app.dashboard.action_error.restart"),
text: extractApiErrorMessage(err),
});
}
@@ -1127,7 +1124,7 @@ class HassioAddonInfo extends LitElement {
await rebuildLocalAddon(this.hass, this.addon.slug);
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.rebuild"),
title: this.supervisor.localize("app.dashboard.action_error.rebuild"),
text: extractApiErrorMessage(err),
});
}
@@ -1145,12 +1142,12 @@ class HassioAddonInfo extends LitElement {
if (!validate.valid) {
await showConfirmationDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.start_invalid_config"
"app.dashboard.action_error.start_invalid_config"
),
text: validate.message.split(" Got ")[0],
confirm: () => this._openConfiguration(),
confirmText: this.supervisor.localize(
"addon.dashboard.action_error.go_to_config"
"app.dashboard.action_error.go_to_config"
),
dismissText: this.supervisor.localize("common.cancel"),
});
@@ -1162,7 +1159,7 @@ class HassioAddonInfo extends LitElement {
button.actionError();
button.progress = false;
showAlertDialog(this, {
title: "Failed to validate addon configuration",
title: "Failed to validate app configuration",
text: extractApiErrorMessage(err),
});
return;
@@ -1181,7 +1178,7 @@ class HassioAddonInfo extends LitElement {
button.actionError();
button.progress = false;
showAlertDialog(this, {
title: this.supervisor.localize("addon.dashboard.action_error.start"),
title: this.supervisor.localize("app.dashboard.action_error.start"),
text: extractApiErrorMessage(err),
});
return;
@@ -1207,13 +1204,13 @@ class HassioAddonInfo extends LitElement {
};
const confirmed = await showConfirmationDialog(this, {
title: this.supervisor.localize("dialog.uninstall_addon.title", {
title: this.supervisor.localize("dialog.uninstall_app.title", {
name: this.addon.name,
}),
text: html`
<ha-formfield
.label=${html`<p>
${this.supervisor.localize("dialog.uninstall_addon.remove_data")}
${this.supervisor.localize("dialog.uninstall_app.remove_data")}
</p>`}
>
<ha-switch
@@ -1223,7 +1220,7 @@ class HassioAddonInfo extends LitElement {
></ha-switch>
</ha-formfield>
`,
confirmText: this.supervisor.localize("dialog.uninstall_addon.uninstall"),
confirmText: this.supervisor.localize("dialog.uninstall_app.uninstall"),
dismissText: this.supervisor.localize("common.cancel"),
destructive: true,
});
@@ -1245,9 +1242,7 @@ class HassioAddonInfo extends LitElement {
button.actionSuccess();
} catch (err: any) {
showAlertDialog(this, {
title: this.supervisor.localize(
"addon.dashboard.action_error.uninstall"
),
title: this.supervisor.localize("app.dashboard.action_error.uninstall"),
text: extractApiErrorMessage(err),
});
button.actionError();
@@ -19,14 +19,14 @@ class HassioAddonSystemManaged extends LitElement {
return html`
<ha-alert
alert-type="warning"
.title=${this.supervisor.localize("addon.system_managed.title")}
.title=${this.supervisor.localize("app.system_managed.title")}
.narrow=${this.narrow}
>
${this.supervisor.localize("addon.system_managed.description")}
${this.supervisor.localize("app.system_managed.description")}
${!this.hideButton
? html`
<ha-button slot="action" @click=${this._takeControl}>
${this.supervisor.localize("addon.system_managed.take_control")}
${this.supervisor.localize("app.system_managed.take_control")}
</ha-button>
`
: nothing}
@@ -216,7 +216,7 @@ export class SupervisorBackupContent extends LitElement {
? html`
<ha-formfield
.label=${html`<supervisor-formfield-label
.label=${this.supervisor?.localize("backup.addons")}
.label=${this.supervisor?.localize("backup.apps")}
.iconPath=${mdiPuzzle}
>
</supervisor-formfield-label>`}
+6 -8
View File
@@ -33,13 +33,13 @@ class HassioAddons extends LitElement {
suffix
.filter=${this._filter}
@value-changed=${this._handleSearchChange}
.label=${this.supervisor.localize("dashboard.search_addons")}
.label=${this.supervisor.localize("dashboard.search_apps")}
>
</search-input>
</div>
<div class="content">
${!atLeastVersion(this.hass.config.version, 2021, 12)
? html`<h1>${this.supervisor.localize("dashboard.addons")}</h1>`
? html`<h1>${this.supervisor.localize("dashboard.apps")}</h1>`
: ""}
<div class="card-group">
${!this.supervisor.addon.addons.length
@@ -47,7 +47,7 @@ class HassioAddons extends LitElement {
<ha-card outlined>
<div class="card-content">
<button class="link" @click=${this._openStore}>
${this.supervisor.localize("dashboard.no_addons")}
${this.supervisor.localize("dashboard.no_apps")}
</button>
</div>
</ha-card>
@@ -67,14 +67,12 @@ class HassioAddons extends LitElement {
? mdiArrowUpBoldCircle
: mdiPuzzle}
.iconTitle=${addon.state !== "started"
? this.supervisor.localize("dashboard.addon_stopped")
? this.supervisor.localize("dashboard.app_stopped")
: addon.update_available!
? this.supervisor.localize(
"dashboard.addon_new_version"
"dashboard.app_new_version"
)
: this.supervisor.localize(
"dashboard.addon_running"
)}
: this.supervisor.localize("dashboard.app_running")}
.iconClass=${addon.update_available
? addon.state === "started"
? "update"
+2 -2
View File
@@ -39,7 +39,7 @@ class HassioDashboard extends LitElement {
.narrow=${this.narrow}
.route=${this.route}
back-path="/config"
.header=${this.supervisor.localize("panel.addons")}
.header=${this.supervisor.localize("panel.apps")}
>
<ha-icon-button
slot="toolbar-icon"
@@ -81,7 +81,7 @@ class HassioDashboard extends LitElement {
<span slot="header">
${this.supervisor.localize(
atLeastVersion(this.hass.config.version, 2021, 12)
? "panel.addons"
? "panel.apps"
: "panel.dashboard"
)}
</span>
@@ -64,9 +64,9 @@ class HassioRepositoriesDialog extends LitElement {
repos
.filter(
(repo) =>
repo.slug !== "core" && // The core add-ons repository
repo.slug !== "local" && // Locally managed add-ons
repo.slug !== "a0d7b954" && // Home Assistant Community Add-ons
repo.slug !== "core" && // The core apps repository
repo.slug !== "local" && // Locally managed apps
repo.slug !== "a0d7b954" && // Home Assistant Community Apps
repo.slug !== "5c53de3b" && // The ESPHome repository
repo.slug !== "d5369777" // Music Assistant repository
)
+3 -3
View File
@@ -16,11 +16,11 @@ export const suggestAddonRestart = async (
addon: HassioAddonDetails
): Promise<void> => {
const confirmed = await showConfirmationDialog(element, {
title: supervisor.localize("dialog.restart_addon.title", {
title: supervisor.localize("dialog.restart_app.title", {
name: addon.name,
}),
text: supervisor.localize("dialog.restart_addon.text"),
confirmText: supervisor.localize("dialog.restart_addon.restart"),
text: supervisor.localize("dialog.restart_app.text"),
confirmText: supervisor.localize("dialog.restart_app.restart"),
dismissText: supervisor.localize("common.cancel"),
});
if (confirmed) {
@@ -89,14 +89,12 @@ class HassioSystemManagedDialog extends LitElement {
? html`<img src=${addonImage} alt=${this._addon.name} />`
: html`<ha-svg-icon .path=${mdiPuzzle}></ha-svg-icon>`}
</div>
${this._supervisor.localize("addon.system_managed.title")}.<br />
${this._supervisor.localize("addon.system_managed.description")}
${this._supervisor.localize("app.system_managed.title")}.<br />
${this._supervisor.localize("app.system_managed.description")}
${this._configEntry
? html`
<h3>
${this._supervisor.localize(
"addon.system_managed.managed_by"
)}:
${this._supervisor.localize("app.system_managed.managed_by")}:
</h3>
<ha-md-list>
<ha-md-list-item
+1 -1
View File
@@ -14,7 +14,7 @@ export const supervisorTabs = (hass: HomeAssistant): PageNavigation[] =>
: [
{
translationKey: atLeastVersion(hass.config.version, 2021, 12)
? "panel.addons"
? "panel.apps"
: "panel.dashboard",
path: `/hassio/dashboard`,
iconPath: atLeastVersion(hass.config.version, 2021, 12)
+20 -20
View File
@@ -114,14 +114,14 @@ class HassioIngressView extends LitElement {
}
if (!addonInfo.version) {
await showAlertDialog(this, {
text: this.supervisor.localize("my.error_addon_not_installed"),
text: this.supervisor.localize("my.error_app_not_installed"),
title: addonInfo.name,
});
await nextRender();
navigate(`/hassio/addon/${addonInfo.slug}/info`, { replace: true });
} else if (!addonInfo.ingress) {
await showAlertDialog(this, {
text: this.supervisor.localize("my.error_addon_no_ingress"),
text: this.supervisor.localize("my.error_app_no_ingress"),
title: addonInfo.name,
});
await nextRender();
@@ -162,8 +162,8 @@ class HassioIngressView extends LitElement {
await this.updateComplete;
await showAlertDialog(this, {
text:
this.supervisor.localize("ingress.error_addon_info") ||
"Unable to fetch add-on info to start Ingress",
this.supervisor.localize("ingress.error_app_info") ||
"Unable to fetch app info to start Ingress",
title: "Supervisor",
});
await nextRender();
@@ -175,8 +175,8 @@ class HassioIngressView extends LitElement {
await this.updateComplete;
await showAlertDialog(this, {
text:
this.supervisor.localize("ingress.error_addon_not_installed") ||
"The add-on is not installed. Please install it first",
this.supervisor.localize("ingress.error_app_not_installed") ||
"The app is not installed. Please install it first",
title: addon.name,
});
await nextRender();
@@ -188,8 +188,8 @@ class HassioIngressView extends LitElement {
await this.updateComplete;
await showAlertDialog(this, {
text:
this.supervisor.localize("ingress.error_addon_not_supported") ||
"This add-on does not support Ingress",
this.supervisor.localize("ingress.error_app_not_supported") ||
"This app does not support Ingress",
title: addon.name,
});
await nextRender();
@@ -201,18 +201,18 @@ class HassioIngressView extends LitElement {
await this.updateComplete;
const confirm = await showConfirmationDialog(this, {
text:
this.supervisor.localize("ingress.error_addon_not_running") ||
"The add-on is not running. Do you want to start it now?",
this.supervisor.localize("ingress.error_app_not_running") ||
"The app is not running. Do you want to start it now?",
title: addon.name,
confirmText:
this.supervisor.localize("ingress.start_addon") || "Start add-on",
this.supervisor.localize("ingress.start_app") || "Start app",
dismissText: this.supervisor.localize("common.no") || "No",
});
if (confirm) {
try {
this._loadingMessage =
this.supervisor.localize("ingress.addon_starting") ||
"The add-on is starting, this can take some time...";
this.supervisor.localize("ingress.app_starting") ||
"The app is starting, this can take some time...";
await startHassioAddon(this.hass, addonSlug);
fireEvent(this, "supervisor-collection-refresh", {
collection: "addon",
@@ -222,8 +222,8 @@ class HassioIngressView extends LitElement {
} catch (_err) {
await showAlertDialog(this, {
text:
this.supervisor.localize("ingress.error_starting_addon") ||
"Error starting the add-on",
this.supervisor.localize("ingress.error_starting_app") ||
"Error starting the app",
title: addon.name,
});
await nextRender();
@@ -238,10 +238,10 @@ class HassioIngressView extends LitElement {
}
if (addon.state === "startup") {
// Addon is starting up, wait for it to start
// App is starting up, wait for it to start
this._loadingMessage =
this.supervisor.localize("ingress.addon_starting") ||
"The add-on is starting, this can take some time...";
this.supervisor.localize("ingress.app_starting") ||
"The app is starting, this can take some time...";
this._fetchDataTimeout = window.setTimeout(() => {
this._fetchData(addonSlug);
@@ -301,8 +301,8 @@ class HassioIngressView extends LitElement {
await this.updateComplete;
showConfirmationDialog(this, {
text:
this.supervisor.localize("ingress.error_addon_not_ready") ||
"The add-on seems to not be ready, it might still be starting. Do you want to try again?",
this.supervisor.localize("ingress.error_app_not_ready") ||
"The app seems to not be ready, it might still be starting. Do you want to try again?",
title: this._addon.name,
confirmText: this.supervisor.localize("ingress.retry") || "Retry",
dismissText: this.supervisor.localize("common.no") || "No",
@@ -261,16 +261,16 @@ class UpdateAvailableCard extends LitElement {
private _computeCreateBackupTexts():
| { title: string; description?: string }
| undefined {
// Addon backup
// App backup
if (
this._updateType === "addon" &&
atLeastVersion(this.hass.config.version, 2025, 2, 0)
) {
const version = this._version;
return {
title: this.supervisor.localize("update_available.create_backup.addon"),
title: this.supervisor.localize("update_available.create_backup.app"),
description: this.supervisor.localize(
"update_available.create_backup.addon_description",
"update_available.create_backup.app_description",
{ version: version }
),
};
@@ -363,11 +363,11 @@ class UpdateAvailableCard extends LitElement {
)
) {
this._error = this.supervisor.localize(
"addon.dashboard.not_available_arch"
"app.dashboard.not_available_arch"
);
} else {
this._error = this.supervisor.localize(
"addon.dashboard.not_available_version",
"app.dashboard.not_available_version",
{
core_version_installed: this.supervisor.core.version,
core_version_needed: addonStoreInfo.homeassistant,
+5 -5
View File
@@ -57,13 +57,13 @@ class HaAddonPicker extends LitElement {
}
protected firstUpdated() {
this._getAddons();
this._getApps();
}
protected render() {
const label =
this.label === undefined && this.hass
? this.hass.localize("ui.components.addon-picker.addon")
? this.hass.localize("ui.components.app-picker.app")
: this.label;
if (this._error) {
@@ -92,7 +92,7 @@ class HaAddonPicker extends LitElement {
`;
}
private async _getAddons() {
private async _getApps() {
try {
if (isComponentLoaded(this.hass, "hassio")) {
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
@@ -113,12 +113,12 @@ class HaAddonPicker extends LitElement {
}));
} else {
this._error = this.hass.localize(
"ui.components.addon-picker.error.no_supervisor"
"ui.components.app-picker.error.no_supervisor"
);
}
} catch (_err: any) {
this._error = this.hass.localize(
"ui.components.addon-picker.error.fetch_addons"
"ui.components.app-picker.error.fetch_apps"
);
}
}
+10 -5
View File
@@ -120,6 +120,7 @@ export interface BackupContent {
failed_folders?: string[];
extra_metadata?: {
"supervisor.addon_update"?: string;
"supervisor.app_update"?: string;
};
with_automatic_settings: boolean;
}
@@ -338,14 +339,14 @@ export const computeBackupAgentName = (
export const computeBackupSize = (backup: BackupContent) =>
Math.max(...Object.values(backup.agents).map((agent) => agent.size));
export type BackupType = "automatic" | "manual" | "addon_update";
export type BackupType = "automatic" | "manual" | "app_update";
const BACKUP_TYPE_ORDER: BackupType[] = ["automatic", "addon_update", "manual"];
const BACKUP_TYPE_ORDER: BackupType[] = ["automatic", "app_update", "manual"];
export const getBackupTypes = memoize((isHassio: boolean) =>
isHassio
? BACKUP_TYPE_ORDER
: BACKUP_TYPE_ORDER.filter((type) => type !== "addon_update")
: BACKUP_TYPE_ORDER.filter((type) => type !== "app_update")
);
export const computeBackupType = (
@@ -355,8 +356,12 @@ export const computeBackupType = (
if (backup.with_automatic_settings) {
return "automatic";
}
if (isHassio && backup.extra_metadata?.["supervisor.addon_update"] != null) {
return "addon_update";
if (
isHassio &&
(backup.extra_metadata?.["supervisor.addon_update"] != null ||
backup.extra_metadata?.["supervisor.app_update"] != null)
) {
return "app_update";
}
return "manual";
};
+8 -1
View File
@@ -10,6 +10,9 @@ export type CreateBackupStage =
| "addon_repositories"
| "addons"
| "await_addon_restarts"
| "app_repositories"
| "apps"
| "await_app_restarts"
| "docker_config"
| "finishing_file"
| "folders"
@@ -26,13 +29,17 @@ export type RestoreBackupStage =
| "addon_repositories"
| "addons"
| "await_addon_restarts"
| "app_repositories"
| "apps"
| "await_app_restarts"
| "await_home_assistant_restart"
| "check_home_assistant"
| "docker_config"
| "download_from_agent"
| "folders"
| "home_assistant"
| "remove_delta_addons";
| "remove_delta_addons"
| "remove_delta_apps";
export type RestoreBackupState = "completed" | "failed" | "in_progress";
+3 -3
View File
@@ -8,7 +8,7 @@ import type { HassioResponse } from "./common";
import { extractApiErrorMessage, hassioApiResultExtractor } from "./common";
export type AddonCapability = Exclude<
keyof TranslationDict["supervisor"]["addon"]["dashboard"]["capability"],
keyof TranslationDict["supervisor"]["app"]["dashboard"]["capability"],
"label" | "role" | "stages"
>;
export type AddonStage = "stable" | "experimental" | "deprecated";
@@ -402,8 +402,8 @@ export const fetchAddonInfo = (
supervisorApiCall(
hass,
!supervisor.addon?.addons.find((addon) => addon.slug === addonSlug)
? `/store/addons/${addonSlug}` // Use /store/addons when add-on is not installed
: `/addons/${addonSlug}/info` // Use /addons when add-on is installed
? `/store/addons/${addonSlug}` // Use /store/addons when app is not installed
: `/addons/${addonSlug}/info` // Use /addons when app is installed
);
export const rebuildLocalAddon = async (
@@ -150,16 +150,16 @@ class MoreInfoUpdate extends LitElement {
};
}
// Addon backup
// App backup
if (updateType === "addon") {
const version = this.stateObj.attributes.installed_version;
return {
title: this.hass.localize(
"ui.dialogs.more_info_control.update.create_backup.addon"
"ui.dialogs.more_info_control.update.create_backup.app"
),
description: version
? this.hass.localize(
"ui.dialogs.more_info_control.update.create_backup.addon_description",
"ui.dialogs.more_info_control.update.create_backup.app_description",
{ version: version }
)
: undefined,
@@ -349,7 +349,7 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
});
if (step.type !== "create_entry") {
throw new Error(
`${this.hass.localize("ui.panel.config.voice_assistants.satellite_wizard.local.errors.failed_create_entry", { addon: type === "tts" ? this._ttsProviderName : this._sttProviderName })}${"errors" in step ? `: ${step.errors.base}` : ""}`
`${this.hass.localize("ui.panel.config.voice_assistants.satellite_wizard.local.errors.failed_create_entry", { app: type === "tts" ? this._ttsProviderName : this._sttProviderName })}${"errors" in step ? `: ${step.errors.base}` : ""}`
);
}
}
@@ -129,7 +129,7 @@ class OnboardingRestoreBackupRestore extends LitElement {
this.backup.addons.length > 0
? html`<ha-alert class="supervisor-warning">
${this.localize(
"ui.panel.page-onboarding.restore.details.addons_unsupported"
"ui.panel.page-onboarding.restore.details.apps_unsupported"
)}
<ha-button
slot="action"
+3 -3
View File
@@ -155,7 +155,7 @@ class HaPanelApp extends LitElement {
if (addon && addon !== oldAddon) {
this._loadingMessage = undefined;
// Reset state when switching addons
// Reset state when switching apps
if (this._enabledKioskMode) {
fireEvent(window, "hass-kiosk-mode", { enable: false });
this._enabledKioskMode = false;
@@ -174,7 +174,7 @@ class HaPanelApp extends LitElement {
route?: Route,
panel?: PanelInfo<AppPanelConfig>
): string | undefined {
// First check panel config (for dedicated add-on panels)
// First check panel config (for dedicated app panels)
if (panel?.config?.addon) {
return panel.config.addon;
}
@@ -263,7 +263,7 @@ class HaPanelApp extends LitElement {
}
if (addon.state === "startup") {
// Addon is starting up, wait for it to start
// App is starting up, wait for it to start
this._loadingMessage = this.hass.localize("ui.panel.app.app_starting");
this._fetchDataTimeout = window.setTimeout(() => {
@@ -170,10 +170,10 @@ class SupervisorAppUpdateAvailableCard extends LitElement {
const version = this.addon.version;
return {
title: this.hass.localize(
"ui.panel.config.apps.dashboard.update_available.create_backup.addon"
"ui.panel.config.apps.dashboard.update_available.create_backup.app"
),
description: this.hass.localize(
"ui.panel.config.apps.dashboard.update_available.create_backup.addon_description",
"ui.panel.config.apps.dashboard.update_available.create_backup.app_description",
{ version: version }
),
};
@@ -484,7 +484,7 @@ class SupervisorAppInfo extends LitElement {
<div class="description light-color">
${this.addon.description}.<br />
${this.hass.localize(
"ui.panel.config.apps.dashboard.visit_addon_page",
"ui.panel.config.apps.dashboard.visit_app_page",
{
name: html`<a
href=${this.addon.url!}
@@ -785,7 +785,7 @@ class SupervisorAppInfo extends LitElement {
"state" in this.addon &&
this.addon.state === "startup"
) {
// Addon is starting up, wait for it to start
// App is starting up, wait for it to start
this._scheduleDataUpdate();
}
}
@@ -67,9 +67,9 @@ class AppsRepositoriesDialog extends LitElement {
repos
.filter(
(repo) =>
repo.slug !== "core" && // The core add-ons repository
repo.slug !== "local" && // Locally managed add-ons
repo.slug !== "a0d7b954" && // Home Assistant Community Add-ons
repo.slug !== "core" && // The core apps repository
repo.slug !== "local" && // Locally managed apps
repo.slug !== "a0d7b954" && // Home Assistant Community Apps
repo.slug !== "5c53de3b" && // The ESPHome repository
repo.slug !== "d5369777" // Music Assistant repository
)
@@ -175,7 +175,7 @@ class HaConfigAppDashboard extends LitElement {
// Navigate back to installed apps after uninstall
window.history.back();
} else {
// Reload addon info
// Reload app info
await this._loadAddon();
}
}
@@ -62,7 +62,7 @@ class HaBackupConfigAddon extends LitElement {
</span>
<span slot="supporting-text">
${this.hass.localize(
`ui.panel.config.backup.settings.addon_update_backup.retention_description`
`ui.panel.config.backup.settings.app_update_backup.retention_description`
)}
</span>
<ha-md-textfield
@@ -170,7 +170,7 @@ class HaBackupConfigData extends LitElement {
data.addons_mode === "all" ||
(data.addons_mode === "custom" && data.addons.length > 0)
) {
// It would be better if we could receive individual addon sizes in the WS request instead
// It would be better if we could receive individual app sizes in the WS request instead
totalBytes +=
(segments.addons_data ?? 0) + (segments.addons_config ?? 0);
}
@@ -335,12 +335,12 @@ class HaBackupConfigData extends LitElement {
></ha-svg-icon>
<span slot="headline">
${this.hass.localize(
"ui.panel.config.backup.data.local_addons"
"ui.panel.config.backup.data.local_apps"
)}
</span>
<span slot="supporting-text">
${this.hass.localize(
"ui.panel.config.backup.data.local_addons_description"
"ui.panel.config.backup.data.local_apps_description"
)}
</span>
<ha-switch
@@ -361,12 +361,12 @@ class HaBackupConfigData extends LitElement {
></ha-svg-icon>
<span slot="headline">
${this.hass.localize(
"ui.panel.config.backup.data.addons"
"ui.panel.config.backup.data.apps"
)}
</span>
<span slot="supporting-text">
${this.hass.localize(
"ui.panel.config.backup.data.addons_description"
"ui.panel.config.backup.data.apps_description"
)}
</span>
<ha-md-select
@@ -378,21 +378,21 @@ class HaBackupConfigData extends LitElement {
<ha-md-select-option value="all">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.backup.data.addons_all"
"ui.panel.config.backup.data.apps_all"
)}
</div>
</ha-md-select-option>
<ha-md-select-option value="none">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.backup.data.addons_none"
"ui.panel.config.backup.data.apps_none"
)}
</div>
</ha-md-select-option>
<ha-md-select-option value="custom">
<div slot="headline">
${this.hass.localize(
"ui.panel.config.backup.data.addons_custom"
"ui.panel.config.backup.data.apps_custom"
)}
</div>
</ha-md-select-option>
@@ -405,7 +405,11 @@ class HaBackupConfigData extends LitElement {
</ha-md-list>
${isHassio && this._showAddons && this._addons.length
? html`
<ha-expansion-panel .header=${"Add-ons"} outlined expanded>
<ha-expansion-panel
.header=${this.hass.localize("ui.panel.config.backup.data.apps")}
outlined
expanded
>
<ha-backup-addons-picker
.hass=${this.hass}
.value=${data.addons}
@@ -511,7 +515,7 @@ class HaBackupConfigData extends LitElement {
)}
${addonsNotAccurate
? html`<br /><br />${this.hass.localize(
"ui.panel.config.backup.data.estimated_size_disclaimer_addons_custom"
"ui.panel.config.backup.data.estimated_size_disclaimer_apps_custom"
)}`
: nothing}
</ha-tooltip>
@@ -122,7 +122,7 @@ export class HaBackupDataPicker extends LitElement {
return localize(`ui.panel.${this.translationKeyPanel}.data_picker.ssl`);
case "addons/local":
return localize(
`ui.panel.${this.translationKeyPanel}.data_picker.local_addons`
`ui.panel.${this.translationKeyPanel}.data_picker.local_apps`
);
}
return capitalizeFirstLetter(folder);
@@ -294,7 +294,7 @@ export class HaBackupDataPicker extends LitElement {
<ha-backup-formfield-label
slot="label"
.label=${localize(
`ui.panel.${this.translationKeyPanel}.data_picker.addons`
`ui.panel.${this.translationKeyPanel}.data_picker.apps`
)}
.iconPath=${mdiPuzzle}
>
@@ -34,7 +34,7 @@ class HaBackupDetailsSummary extends LitElement {
if (this.backup.failed_addons?.length) {
errors.push({
title: this.hass.localize(
"ui.panel.config.backup.details.summary.error.failed_addons"
"ui.panel.config.backup.details.summary.error.failed_apps"
),
items: this.backup.failed_addons.map(
(addon) => `${addon.name || addon.slug} (${addon.version})`
@@ -127,7 +127,7 @@ class HaBackupDetailsSummary extends LitElement {
return this.hass.localize(`ui.panel.config.backup.data_picker.ssl`);
case "addons/local":
return this.hass.localize(
`ui.panel.config.backup.data_picker.local_addons`
`ui.panel.config.backup.data_picker.local_apps`
);
}
return capitalizeFirstLetter(folder);
@@ -27,7 +27,7 @@ interface BackupStats {
const TYPE_ICONS: Record<BackupType, string> = {
automatic: mdiCalendarSync,
manual: mdiGestureTap,
addon_update: mdiPuzzle,
app_update: mdiPuzzle,
};
const computeBackupStats = (backups: BackupContent[]): BackupStats =>
@@ -151,18 +151,18 @@ class HaBackupBackupsSummary extends LitElement {
private _addonsDescription(config: BackupConfig): string {
if (config.create_backup.include_all_addons) {
return this.hass.localize(
"ui.panel.config.backup.overview.settings.addons_all"
"ui.panel.config.backup.overview.settings.apps_all"
);
}
const count = config.create_backup.include_addons?.length;
if (count) {
return this.hass.localize(
"ui.panel.config.backup.overview.settings.addons_many",
"ui.panel.config.backup.overview.settings.apps_many",
{ count }
);
}
return this.hass.localize(
"ui.panel.config.backup.overview.settings.addons_none"
"ui.panel.config.backup.overview.settings.apps_none"
);
}
@@ -260,7 +260,7 @@ class HaBackupBackupsSummary extends LitElement {
</div>
<div slot="supporting-text">
${this.hass.localize(
"ui.panel.config.backup.overview.settings.addons"
"ui.panel.config.backup.overview.settings.apps"
)}
</div>
<ha-icon-next slot="end"></ha-icon-next>
@@ -80,7 +80,7 @@ class HaConfigBackupSettings extends LitElement {
// eslint-disable-next-line no-console
console.error(err);
this._supervisorUpdateConfigError = this.hass.localize(
"ui.panel.config.backup.settings.addon_update_backup.error_load",
"ui.panel.config.backup.settings.app_update_backup.error_load",
{
error: err?.message || err,
}
@@ -96,12 +96,12 @@ class HaConfigBackupSettings extends LitElement {
!this._config?.create_backup.include_all_addons &&
this._config?.create_backup.include_addons?.length
) {
// Wait for the addons to be loaded before scrolling because the height can change and location section is below addons.
// Wait for the apps to be loaded before scrolling because the height can change and location section is below apps.
this.addEventListener("backup-addons-fetched", async () => {
await nextRender();
this._scrolltoHash();
});
// Clear hash to cancel the scroll after 500ms if addons doesn't load
// Clear hash to cancel the scroll after 500ms if apps doesn't load
setTimeout(() => {
this._clearHash();
}, 500);
@@ -320,18 +320,18 @@ class HaConfigBackupSettings extends LitElement {
? html`<ha-card>
<div class="card-header">
${this.hass.localize(
"ui.panel.config.backup.settings.addon_update_backup.title"
"ui.panel.config.backup.settings.app_update_backup.title"
)}
</div>
<div class="card-content">
<p>
${this.hass.localize(
"ui.panel.config.backup.settings.addon_update_backup.description"
"ui.panel.config.backup.settings.app_update_backup.description"
)}
</p>
<p>
${this.hass.localize(
"ui.panel.config.backup.settings.addon_update_backup.local_only"
"ui.panel.config.backup.settings.app_update_backup.local_only"
)}
</p>
${this._supervisorUpdateConfigError
@@ -473,7 +473,7 @@ class HaConfigBackupSettings extends LitElement {
// eslint-disable-next-line no-console
console.error(err);
this._supervisorUpdateConfigError = this.hass.localize(
"ui.panel.config.backup.settings.addon_update_backup.error_save",
"ui.panel.config.backup.settings.app_update_backup.error_save",
{
error: err?.message || err?.toString(),
}
+145 -138
View File
@@ -876,11 +876,11 @@
"learn_more": "Learn more about statistics",
"unknown": "Unknown statistic selected"
},
"addon-picker": {
"addon": "Add-on",
"app-picker": {
"app": "App",
"error": {
"no_supervisor": "Add-ons are not supported on your installation.",
"fetch_addons": "There was an error loading add-ons."
"no_supervisor": "Apps are not supported on your installation.",
"fetch_apps": "There was an error loading apps."
}
},
"mount-picker": {
@@ -1422,9 +1422,9 @@
"blueprint": "[%key:ui::panel::config::blueprint::caption%]",
"server_control": "[%key:ui::panel::developer-tools::tabs::yaml::title%]",
"system": "[%key:ui::panel::config::dashboard::system::main%]",
"addon_dashboard": "Add-on dashboard",
"addon_store": "Add-on store",
"addon_info": "{addon} info",
"app_dashboard": "App dashboard",
"app_store": "App store",
"app_info": "{app} info",
"shortcuts": "[%key:ui::panel::config::info::shortcuts%]",
"labs": "[%key:ui::panel::config::labs::caption%]"
}
@@ -1513,8 +1513,8 @@
"automatic_description_none": "No automatic backup yet.",
"manual": "Create manual backup before update",
"manual_description": "Includes Home Assistant settings and history.",
"addon": "Keep backup of the last version",
"addon_description": "For easily restoring to version {version}",
"app": "Keep backup of the last version",
"app_description": "For easily restoring to version {version}",
"generic": "Create backup"
}
},
@@ -1804,9 +1804,9 @@
},
"reboot": {
"title": "Reboot system",
"description": "Restarts the system running Home Assistant and all add-ons.",
"description": "Restarts the system running Home Assistant and all apps.",
"confirm_title": "Reboot system?",
"confirm_description": "This will reboot the complete system which includes Home Assistant and all the add-ons.",
"confirm_description": "This will reboot the complete system which includes Home Assistant and all apps.",
"confirm_action": "Reboot",
"action_toast": "Rebooting system",
"confirm_action_backup": "Wait and reboot",
@@ -1814,9 +1814,9 @@
},
"shutdown": {
"title": "Shut down system",
"description": "Shuts down the system running Home Assistant and all add-ons.",
"description": "Shuts down the system running Home Assistant and all apps.",
"confirm_title": "Shut down system?",
"confirm_description": "This will shut down the complete system which includes Home Assistant and all add-ons.",
"confirm_description": "This will shut down the complete system which includes Home Assistant and all apps.",
"confirm_action": "Shut down",
"confirm_action_backup": "Wait and shut down",
"action_toast": "Shutting down system",
@@ -2398,7 +2398,7 @@
},
"updates": {
"caption": "Updates",
"description": "Manage updates of Home Assistant, add-ons, and devices",
"description": "Manage updates of Home Assistant, apps, and devices",
"no_updates": "No updates available",
"no_update_entities": {
"title": "Unable to check for updates",
@@ -2537,7 +2537,7 @@
"current_version": "Current version: {version}",
"changelog": "Changelog",
"hostname": "Hostname",
"visit_addon_page": "Visit {name} page for more details.",
"visit_app_page": "Visit {name} page for more details.",
"start": "Start",
"stop": "Stop",
"restart": "Restart",
@@ -2682,8 +2682,8 @@
"description": "{name} {newest_version} is available. You are running {version}.",
"updating": "Updating {name} to {version}...",
"create_backup": {
"addon": "Create backup before updating",
"addon_description": "Creates a backup of {version} before updating.",
"app": "Create backup before updating",
"app_description": "Creates a backup of {version} before updating.",
"generic": "Create backup"
}
}
@@ -2848,7 +2848,7 @@
"type": {
"manual": "Manual",
"automatic": "Automatic",
"addon_update": "Add-on update"
"app_update": "App update"
},
"locations": "Locations",
"create": {
@@ -3050,17 +3050,17 @@
"media": "Media",
"media_description": "For example, camera recordings.",
"share_folder": "Share folder",
"share_folder_description": "Folder that is often used by add-ons for advanced or older configurations.",
"local_addons": "Local add-ons folder",
"local_addons_description": "Folder that contains the data of your local add-ons.",
"addons": "Add-ons",
"addons_description": "Select what add-ons you want to include.",
"addons_all": "All",
"addons_none": "None",
"addons_custom": "Custom",
"share_folder_description": "Folder that is often used by apps for advanced or older configurations.",
"local_apps": "Local apps folder",
"local_apps_description": "Folder that contains the data of your local apps.",
"apps": "Apps",
"apps_description": "Select what apps you want to include.",
"apps_all": "All",
"apps_none": "None",
"apps_custom": "Custom",
"estimated_size": "Estimated backup size",
"estimated_size_disclaimer": "This is an approximation based on storage usage and compression. The actual backup size will vary.",
"estimated_size_disclaimer_addons_custom": "This estimate includes all add-ons, and not individual add-on sizes.",
"estimated_size_disclaimer_apps_custom": "This estimate includes all apps, and not individual app sizes.",
"estimated_size_loading": "Loading size estimate..."
},
"data_picker": {
@@ -3068,8 +3068,8 @@
"settings_and_history": "Settings and history",
"media": "Media",
"share_folder": "Share folder",
"local_addons": "Local add-ons folder",
"addons": "Add-ons",
"local_apps": "Local apps folder",
"apps": "Apps",
"ssl": "SSL certificates"
},
"schedule": {
@@ -3159,9 +3159,12 @@
},
"description": {
"create_backup": {
"addon_repositories": "Backing up add-on repositories",
"addons": "Backing up add-ons",
"await_addon_restarts": "Waiting for add-ons to restart",
"addon_repositories": "[%key:ui::panel::config::backup::overview::progress::description::create_backup::app_repositories%]",
"addons": "[%key:ui::panel::config::backup::overview::progress::description::create_backup::apps%]",
"await_addon_restarts": "[%key:ui::panel::config::backup::overview::progress::description::create_backup::await_app_restarts%]",
"app_repositories": "Backing up app repositories",
"apps": "Backing up apps",
"await_app_restarts": "Waiting for apps to restart",
"docker_config": "Backing up Docker configuration",
"finishing_file": "Finishing backup file",
"folders": "Backing up folders",
@@ -3169,16 +3172,20 @@
"upload_to_agents": "Uploading to locations"
},
"restore_backup": {
"addon_repositories": "Restoring add-on repositories",
"addons": "Restoring add-ons",
"await_addon_restarts": "Waiting for add-ons to restart",
"addon_repositories": "[%key:ui::panel::config::backup::overview::progress::description::restore_backup::app_repositories%]",
"addons": "[%key:ui::panel::config::backup::overview::progress::description::restore_backup::apps%]",
"await_addon_restarts": "[%key:ui::panel::config::backup::overview::progress::description::restore_backup::await_app_restarts%]",
"app_repositories": "Restoring app repositories",
"apps": "Restoring apps",
"await_app_restarts": "Waiting for apps to restart",
"await_home_assistant_restart": "Waiting for Home Assistant to restart",
"check_home_assistant": "Checking Home Assistant",
"docker_config": "Restoring Docker configuration",
"download_from_agent": "Downloading from location",
"folders": "Restoring folders",
"home_assistant": "Restoring Home Assistant",
"remove_delta_addons": "Removing delta add-ons"
"remove_delta_addons": "[%key:ui::panel::config::backup::overview::progress::description::restore_backup::remove_delta_apps%]",
"remove_delta_apps": "Removing delta apps"
},
"receive_backup": {
"receive_file": "Receiving file",
@@ -3195,12 +3202,12 @@
"last_backup_failed_heading": "Last automatic backup failed",
"last_backup_failed_description": "The last automatic backup triggered {relative_time} wasn't successful.",
"last_backup_failed_locations_description": "The last automatic backup created {relative_time} wasn't stored in all locations.",
"last_backup_failed_addons_description": "The last automatic backup created {relative_time} was not able to backup all add-ons.",
"last_backup_failed_apps_description": "The last automatic backup created {relative_time} was not able to backup all apps.",
"last_backup_failed_folders_description": "The last automatic backup created {relative_time} was not able to backup all folders.",
"last_backup_failed_addons_folders_description": "The last automatic backup created {relative_time} wasn't able to backup all add-ons and folders.",
"last_backup_failed_locations_addons_description": "The last automatic backup created {relative_time} wasn't able to backup all add-ons and wasn't stored in all locations.",
"last_backup_failed_apps_folders_description": "The last automatic backup created {relative_time} wasn't able to backup all apps and folders.",
"last_backup_failed_locations_apps_description": "The last automatic backup created {relative_time} wasn't able to backup all apps and wasn't stored in all locations.",
"last_backup_failed_locations_folders_description": "The last automatic backup created {relative_time} wasn't able to backup all folders and wasn't stored in all locations.",
"last_backup_failed_locations_addons_folders_description": "The last automatic backup created {relative_time} wasn't able to backup all add-ons and folders and wasn't stored in all locations.",
"last_backup_failed_locations_apps_folders_description": "The last automatic backup created {relative_time} wasn't able to backup all apps and folders and wasn't stored in all locations.",
"last_successful_backup_description": "Last successful automatic backup {relative_time} and stored in {count} {count, plural,\n one {location}\n other {locations}\n}.",
"no_backup_heading": "No automatic backup available",
"no_backup_description": "You have no automatic backups yet.",
@@ -3212,7 +3219,7 @@
"title": "My backups",
"automatic": "{count} automatic {count, plural,\n one {backup}\n other {backups}\n}",
"manual": "{count} manual {count, plural,\n one {backup}\n other {backups}\n}",
"addon_update": "{count} add-on update {count, plural,\n one {backup}\n other {backups}\n}",
"app_update": "{count} app update {count, plural,\n one {backup}\n other {backups}\n}",
"total_size": "{size} in total",
"show_all": "Show all backups"
},
@@ -3235,10 +3242,10 @@
"data": "Home Assistant data that is included",
"data_settings_history": "Settings and history",
"data_settings_only": "Settings only",
"addons": "Add-ons that are included",
"addons_all": "All add-ons",
"addons_many": "{count} {count, plural,\n one {add-on}\n other {add-ons}\n}",
"addons_none": "No add-ons",
"apps": "Apps that are included",
"apps_all": "All apps",
"apps_many": "{count} {count, plural,\n one {app}\n other {apps}\n}",
"apps_none": "No apps",
"locations": "Locations where backup is stored to",
"locations_one": "Store in {name}",
"locations_many": "Store in {count} off-site {count, plural,\n one {location}\n other {locations}\n}",
@@ -3299,9 +3306,9 @@
"title": "Encryption key",
"description": "Keep this encryption key in a safe place, as you will need it to access your backup, allowing it to be restored. Download it as an emergency kit file and store it somewhere safe. Encryption keeps your backups private and secure."
},
"addon_update_backup": {
"title": "Add-on update backups",
"description": "Creates a backup of your add-on and its data. That way you can keep around the previous version of the add-on, so you can always roll back to it if needed.",
"app_update_backup": {
"title": "App update backups",
"description": "Creates a backup of your app and its data. That way you can keep around the previous version of the app, so you can always roll back to it if needed.",
"local_only": "This backup is only saved on this system.",
"retention_description": "Prevent your system from filling up with old versions.",
"error_load": "Error loading Supervisor update config: {error}",
@@ -3320,7 +3327,7 @@
"error": {
"title": "This backup was not created successfully. Some data is missing.",
"failed_locations": "Failed locations",
"failed_addons": "Failed add-ons",
"failed_apps": "Failed apps",
"failed_folders": "Failed folders"
}
},
@@ -4182,11 +4189,11 @@
}
},
"local": {
"title": "Installing add-ons",
"title": "Installing apps",
"secondary": "We are preparing your system for local voice processing.",
"failed_title": "Failed to install add-ons",
"failed_secondary": "We were unable to install the add-ons for speech-to-text and text-to-speech automatically for you. Read the documentation to learn how to install them.",
"not_supported_title": "Installation of add-ons is not supported on your system",
"failed_title": "Failed to install apps",
"failed_secondary": "We were unable to install the apps for speech-to-text and text-to-speech automatically for you. Read the documentation to learn how to install them.",
"not_supported_title": "Installation of apps is not supported on your system",
"not_supported_secondary": "Your system is not supported to automatically install a local TTS and STT provider. Learn how to set up local TTS and STT providers in the documentation.",
"full_local_pipeline": "Full local assistant",
"focused_local_pipeline": "Focused local assistant",
@@ -4203,7 +4210,7 @@
"creating_pipeline": "Creating assistant"
},
"errors": {
"failed_create_entry": "Failed to create entry for {addon}",
"failed_create_entry": "Failed to create entry for {app}",
"could_not_find_entities": "Could not find local TTS and STT entities"
}
},
@@ -6431,7 +6438,7 @@
"network_settings_title": "Network settings",
"change_channel": "Change channel",
"channel_dialog": {
"title": "Multiprotocol add-on in use",
"title": "Multiprotocol app in use",
"text": "Zigbee and Thread share the same adapter and must use the same channel. Change the channel of both networks by reconfiguring multiprotocol from the hardware menu."
}
},
@@ -7388,8 +7395,8 @@
"used": "Used space",
"free": "Free space",
"system": "System",
"addons_data": "Add-on data",
"addons_config": "Add-on configuration",
"apps_data": "App data",
"apps_config": "App configuration",
"media": "Media",
"share": "Share",
"backup": "Backups",
@@ -9910,7 +9917,7 @@
"uploading": "[%key:ui::components::file-upload::uploading%]",
"details": {
"home_assistant_missing": "This backup does not include your Home Assistant configuration, you cannot use it to restore your instance.",
"addons_unsupported": "Your installation method doesnt support add-ons. If you want to restore these, you have to install Home Assistant OS",
"apps_unsupported": "Your installation method doesnt support apps. If you want to restore these, you have to install Home Assistant OS",
"summary": {
"created": "[%key:ui::panel::config::backup::details::summary::created%]",
"content": "Content"
@@ -9932,8 +9939,8 @@
"settings_and_history": "[%key:ui::panel::config::backup::data_picker::settings_and_history%]",
"media": "[%key:ui::panel::config::backup::data_picker::media%]",
"share_folder": "[%key:ui::panel::config::backup::data_picker::share_folder%]",
"local_addons": "[%key:ui::panel::config::backup::data_picker::local_addons%]",
"addons": "[%key:ui::panel::config::backup::data_picker::addons%]",
"local_apps": "[%key:ui::panel::config::backup::data_picker::local_apps%]",
"apps": "[%key:ui::panel::config::backup::data_picker::apps%]",
"ssl": "[%key:ui::panel::config::backup::data_picker::ssl%]"
},
"restore_no_home_assistant": "[%key:supervisor::backup::restore_no_home_assistant%]",
@@ -9952,7 +9959,7 @@
"name": "[%key:supervisor::backup::name%]",
"select_type": "[%key:supervisor::backup::select_type%]",
"folders": "[%key:supervisor::backup::folders%]",
"addons": "[%key:supervisor::backup::addons%]",
"apps": "[%key:supervisor::backup::apps%]",
"password_protection": "[%key:supervisor::backup::password_protection%]",
"password": "[%key:supervisor::backup::password%]",
"confirm_password": "[%key:supervisor::backup::confirm_password%]",
@@ -10131,13 +10138,13 @@
}
},
"supervisor": {
"addon": {
"failed_to_reset": "Failed to reset add-on configuration, {error}",
"failed_to_save": "Failed to save add-on configuration, {error}",
"app": {
"failed_to_reset": "Failed to reset app configuration, {error}",
"failed_to_save": "Failed to save app configuration, {error}",
"state": {
"installed": "Add-on is installed",
"not_installed": "Add-on is not installed",
"not_available": "Add-on is not available on your system"
"installed": "App is installed",
"not_installed": "App is not installed",
"not_available": "App is not available on your system"
},
"panel": {
"configuration": "Configuration",
@@ -10146,7 +10153,7 @@
"log": "Log"
},
"configuration": {
"no_configuration": "This add-on has no configuration.",
"no_configuration": "This app has no configuration.",
"audio": {
"header": "Audio",
"default": "Default",
@@ -10165,19 +10172,19 @@
"disabled": "Disabled",
"header": "Network",
"show_disabled": "Show disabled ports",
"introduction": "Change the ports on your host that are exposed by the add-on"
"introduction": "Change the ports on your host that are exposed by the app"
}
},
"dashboard": {
"changelog": "Changelog",
"current_version": "Current version: {version}",
"cpu_usage": "Add-on CPU usage",
"ram_usage": "Add-on RAM usage",
"cpu_usage": "App CPU usage",
"ram_usage": "App RAM usage",
"hostname": "Hostname",
"new_update_available": "{name} {version} is available",
"not_available_arch": "This add-on is not compatible with the processor of your device or the operating system you have installed on your device.",
"not_available_version": "You are running Home Assistant {core_version_installed}, to update to this version of the add-on you need at least version {core_version_needed} of Home Assistant",
"visit_addon_page": "Visit the {name} page for more details.",
"not_available_arch": "This app is not compatible with the processor of your device or the operating system you have installed on your device.",
"not_available_version": "You are running Home Assistant {core_version_installed}, to update to this version of the app you need at least version {core_version_needed} of Home Assistant",
"visit_app_page": "Visit the {name} page for more details.",
"restart": "Restart",
"start": "Start",
"stop": "Stop",
@@ -10187,57 +10194,57 @@
"open_web_ui": "Open web UI",
"protection_mode": {
"title": "Protection mode is disabled!",
"content": "Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on.",
"content": "Protection mode on this app is disabled! This gives the app full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this app.",
"enable": "[%key:ui::common::enable%]"
},
"capability": {
"stage": {
"title": "Add-on stage",
"description": "Add-ons can have one of three stages:\n\n{icon_stable} **Stable**: These are add-ons ready to be used in production.\n\n{icon_experimental} **Experimental**: These may contain bugs, and may be unfinished.\n\n{icon_deprecated} **Deprecated**: These add-ons will no longer receive any updates."
"title": "App stage",
"description": "Apps can have one of three stages:\n\n{icon_stable} **Stable**: These are apps ready to be used in production.\n\n{icon_experimental} **Experimental**: These may contain bugs, and may be unfinished.\n\n{icon_deprecated} **Deprecated**: These apps will no longer receive any updates."
},
"rating": {
"title": "Add-on security rating",
"description": "Home Assistant provides a security rating to each of the add-ons, which indicates the risks involved when using this add-on. The more access an add-on requires on your system, the lower the score, thus raising the possible security risks.\n\nA score is on a scale from 1 to 8. Where 1 is the lowest score (considered the most insecure and highest risk) and a score of 8 is the highest score (considered the most secure and lowest risk)."
"title": "App security rating",
"description": "Home Assistant provides a security rating to each of the apps, which indicates the risks involved when using this app. The more access an app requires on your system, the lower the score, thus raising the possible security risks.\n\nA score is on a scale from 1 to 8. Where 1 is the lowest score (considered the most insecure and highest risk) and a score of 8 is the highest score (considered the most secure and lowest risk)."
},
"host_network": {
"title": "Host network",
"description": "Add-ons usually run in their own isolated network layer, which prevents them from accessing the network of the host operating system. In some cases, this network isolation can limit add-ons in providing their services and therefore, the isolation can be lifted by the add-on author, giving the add-on full access to the network capabilities of the host machine. This gives the add-on more networking capabilities but lowers the security, hence, the security rating of the add-on will be lowered when this option is used by the add-on."
"description": "Apps usually run in their own isolated network layer, which prevents them from accessing the network of the host operating system. In some cases, this network isolation can limit apps in providing their services and therefore, the isolation can be lifted by the app author, giving the app full access to the network capabilities of the host machine. This gives the app more networking capabilities but lowers the security, hence, the security rating of the app will be lowered when this option is used by the app."
},
"homeassistant_api": {
"title": "Home Assistant API access",
"description": "This add-on is allowed to access your running Home Assistant instance directly via the Home Assistant API. This mode handles authentication for the add-on as well, which enables an add-on to interact with Home Assistant without the need for additional authentication tokens."
"description": "This app is allowed to access your running Home Assistant instance directly via the Home Assistant API. This mode handles authentication for the app as well, which enables an app to interact with Home Assistant without the need for additional authentication tokens."
},
"full_access": {
"title": "Full hardware access",
"description": "This add-on is given full access to the hardware of your system, by request of the add-on author. Access is comparable to the privileged mode in Docker. Since this opens up possible security risks, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
"description": "This app is given full access to the hardware of your system, by request of the app author. Access is comparable to the privileged mode in Docker. Since this opens up possible security risks, this feature impacts the app security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the app manually. Only disable the protection mode if you know, need AND trust the source of this app."
},
"hassio_api": {
"title": "Supervisor API access",
"description": "The add-on was given access to the Supervisor API, by request of the add-on author. By default, the add-on can access general version information of your system. When the add-on requests 'manager' or 'admin' level access to the API, it will gain access to control multiple parts of your Home Assistant system. This permission is indicated by this badge and will impact the security score of the add-on negatively."
"description": "The app was given access to the Supervisor API, by request of the app author. By default, the app can access general version information of your system. When the app requests 'manager' or 'admin' level access to the API, it will gain access to control multiple parts of your Home Assistant system. This permission is indicated by this badge and will impact the security score of the app negatively."
},
"docker_api": {
"title": "Full Docker access",
"description": "The add-on author has requested the add-on to have management access to the Docker instance running on your system. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
"description": "The app author has requested the app to have management access to the Docker instance running on your system. This mode gives the app full access and control to your entire Home Assistant system, which adds security risks, and could damage your system when misused. Therefore, this feature impacts the app security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the app manually. Only disable the protection mode if you know, need AND trust the source of this app."
},
"host_pid": {
"title": "Host processes namespace",
"description": "Usually, the processes run by the add-on are isolated from all other system processes. The add-on author has requested the add-on to have access to the system processes running on the host system instance, and allow the add-on to spawn processes on the host system as well. This mode gives the add-on full access and control to your entire Home Assistant system, which adds security risks and could damage your system when misused. Therefore, this feature impacts the add-on security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the add-on manually. Only disable the protection mode if you know, need AND trust the source of this add-on."
"description": "Usually, the processes run by the app are isolated from all other system processes. The app author has requested the app to have access to the system processes running on the host system instance, and allow the app to spawn processes on the host system as well. This mode gives the app full access and control to your entire Home Assistant system, which adds security risks and could damage your system when misused. Therefore, this feature impacts the app security score negatively.\n\nThis level of access is not granted automatically and needs to be confirmed by you. To do this, you need to disable the protection mode on the app manually. Only disable the protection mode if you know, need AND trust the source of this app."
},
"apparmor": {
"title": "AppArmor",
"description": "AppArmor ('Application Armor') is a Linux kernel security module that restricts add-on capabilities like network access, raw socket access, and permission to read, write, or execute specific files.\n\nAdd-on authors can provide their security profiles, optimized for the add-on, or request it to be disabled. If AppArmor is disabled, it will raise security risks and therefore, has a negative impact on the security score of the add-on."
"description": "AppArmor ('Application Armor') is a Linux kernel security module that restricts app capabilities like network access, raw socket access, and permission to read, write, or execute specific files.\n\nApp authors can provide their security profiles, optimized for the app, or request it to be disabled. If AppArmor is disabled, it will raise security risks and therefore, has a negative impact on the security score of the app."
},
"auth_api": {
"title": "Home Assistant authentication",
"description": "An add-on can authenticate users against Home Assistant, allowing add-ons to give users the possibility to log in to applications running inside add-ons, using their Home Assistant username/password. This badge indicates if the add-on author requests this capability."
"description": "An app can authenticate users against Home Assistant, allowing apps to give users the possibility to log in to applications running inside apps, using their Home Assistant username/password. This badge indicates if the app author requests this capability."
},
"ingress": {
"title": "Ingress",
"description": "This add-on is using Ingress to embed its interface securely into Home Assistant."
"description": "This app is using Ingress to embed its interface securely into Home Assistant."
},
"signed": {
"title": "Signed",
"description": "This add-on signed and verified with Codenotary Community Attestation Service (CAS)."
"description": "This app signed and verified with Codenotary Community Attestation Service (CAS)."
},
"label": {
"core": "Core",
@@ -10267,48 +10274,48 @@
"option": {
"boot": {
"title": "Start on boot",
"description": "Make the add-on start during a system boot"
"description": "Make the app start during a system boot"
},
"watchdog": {
"title": "Watchdog",
"description": "This will restart the add-on if it crashes"
"description": "This will restart the app if it crashes"
},
"auto_update": {
"title": "Automatically update",
"description": "Automatically update the add-on when a new version is available"
"description": "Automatically update the app when a new version is available"
},
"ingress_panel": {
"title": "Add to sidebar",
"description": "Allows users to show or hide the add-on"
"description": "Allows users to show or hide the app"
},
"protected": {
"title": "Protection mode",
"description": "Blocks elevated system access from the add-on"
"description": "Blocks elevated system access from the app"
}
},
"action_error": {
"uninstall": "Failed to uninstall add-on",
"install": "Failed to install add-on",
"stop": "Failed to stop add-on",
"rebuild": "Failed to rebuild add-on",
"restart": "Failed to restart add-on",
"start": "Failed to start add-on",
"uninstall": "Failed to uninstall app",
"install": "Failed to install app",
"stop": "Failed to stop app",
"rebuild": "Failed to rebuild app",
"restart": "Failed to restart app",
"start": "Failed to start app",
"go_to_config": "Edit config",
"start_invalid_config": "Go to configuration",
"validate_config": "Failed to validate add-on configuration",
"get_changelog": "Failed to get add-on changelog"
"validate_config": "Failed to validate app configuration",
"get_changelog": "Failed to get app changelog"
}
},
"documentation": {
"get_documentation": "Failed to get add-on documentation, {error}"
"get_documentation": "Failed to get app documentation, {error}"
},
"logs": {
"get_logs": "Failed to get add-on logs, {error}"
"get_logs": "Failed to get app logs, {error}"
},
"system_managed": {
"badge": "System-managed",
"title": "This add-on is managed by Home Assistant",
"description": "Manually modifying this configuration may cause the add-on or integration to stop working properly.",
"title": "This app is managed by Home Assistant",
"description": "Manually modifying this configuration may cause the app or integration to stop working properly.",
"managed_by": "Managed by",
"take_control": "Take control"
}
@@ -10352,8 +10359,8 @@
"updating": "Updating {name} to version {version}",
"no_update": "No update available for {name}",
"create_backup": {
"addon": "[%key:ui::dialogs::more_info_control::update::create_backup::addon%]",
"addon_description": "[%key:ui::dialogs::more_info_control::update::create_backup::addon_description%]",
"app": "[%key:ui::dialogs::more_info_control::update::create_backup::app%]",
"app_description": "[%key:ui::dialogs::more_info_control::update::create_backup::app_description%]",
"generic": "[%key:ui::dialogs::more_info_control::update::create_backup::generic%]"
}
},
@@ -10368,48 +10375,48 @@
}
},
"dashboard": {
"addon_new_version": "New version available",
"addon_running": "Add-on is running",
"addon_stopped": "Add-on is stopped",
"addons": "Installed add-ons",
"no_addons": "You don't have any add-ons installed yet. Head over to the add-on store to get started!",
"search_addons": "Search add-ons"
"app_new_version": "New version available",
"app_running": "App is running",
"app_stopped": "App is stopped",
"apps": "Installed apps",
"no_apps": "You don't have any apps installed yet. Head over to the app store to get started!",
"search_apps": "Search apps"
},
"store": {
"missing_addons": "Missing add-ons? Enable advanced mode in your user profile page",
"missing_apps": "Missing apps? Enable advanced mode in your user profile page",
"no_results_found": "No results found in {repository}.",
"registries": "Registries",
"repositories": "Repositories",
"check_updates": "Check for updates"
},
"panel": {
"addons": "Add-ons",
"apps": "Apps",
"dashboard": "Dashboard",
"backups": "Backups",
"store": "Add-on store",
"store": "App store",
"system": "System"
},
"my": {
"not_supported": "[%key:ui::panel::my::not_supported%]",
"faq_link": "[%key:ui::panel::my::faq_link%]",
"add_addon_repository_title": "Missing add-on repository",
"add_addon_repository_description": "The add-on ''{addon}'' is a part of the add-on repository ''{repository}'', this repository is missing on your system, do you want to add that now?",
"add_app_repository_title": "Missing app repository",
"add_app_repository_description": "The app ''{app}'' is a part of the app repository ''{repository}'', this repository is missing on your system, do you want to add that now?",
"error": "[%key:ui::panel::my::error%]",
"error_addon_not_found": "Add-on not found",
"error_repository_not_found": "The required repository for this add-on was not found",
"error_addon_not_installed": "The requested add-on is not installed. Please install it first",
"error_addon_no_ingress": "The requested add-on does not support Ingress"
"error_app_not_found": "App not found",
"error_repository_not_found": "The required repository for this app was not found",
"error_app_not_installed": "The requested app is not installed. Please install it first",
"error_app_no_ingress": "The requested app does not support Ingress"
},
"ingress": {
"error_addon_info": "Unable to fetch add-on info to start Ingress",
"error_addon_not_installed": "The add-on is not installed. Please install it first",
"error_addon_not_supported": "This add-on does not support Ingress",
"error_addon_not_running": "The add-on is not running. Do you want to start it now?",
"start_addon": "Start add-on",
"addon_starting": "The add-on is starting, this can take some time...",
"error_starting_addon": "Error starting the add-on",
"error_app_info": "Unable to fetch app info to start Ingress",
"error_app_not_installed": "The app is not installed. Please install it first",
"error_app_not_supported": "This app does not support Ingress",
"error_app_not_running": "The app is not running. Do you want to start it now?",
"start_app": "Start app",
"app_starting": "The app is starting, this can take some time...",
"error_starting_app": "Error starting the app",
"error_creating_session": "Unable to create an Ingress session",
"error_addon_not_ready": "The add-on seems to not be ready, it might still be starting. Do you want to try again?",
"error_app_not_ready": "The app seems to not be ready, it might still be starting. Do you want to try again?",
"retry": "Retry"
},
"system": {
@@ -10523,7 +10530,7 @@
"select_type": "Select what to restore",
"full_backup": "Full backup",
"partial_backup": "Partial backup",
"addons": "Add-ons",
"apps": "Apps",
"folders": "Folders",
"size": "Size",
"password": "Backup encryption key",
@@ -10587,20 +10594,20 @@
"failed_to_remove": "Failed to remove registry"
},
"repositories": {
"title": "Manage add-on repositories",
"title": "Manage app repositories",
"add": "Add",
"remove": "Remove",
"used": "Repository is in use for installed add-ons and can't be removed.",
"used": "Repository is in use for installed apps and can't be removed.",
"no_repositories": "No repositories"
},
"restart_addon": {
"restart_app": {
"title": "Restart {name}?",
"text": "To use the new saved configuration this add-on must be restarted.",
"text": "To use the new saved configuration this app must be restarted.",
"restart": "Restart"
},
"uninstall_addon": {
"uninstall_app": {
"title": "Uninstall {name}?",
"remove_data": "Also permanently delete this add-on's data",
"remove_data": "Also permanently delete this app's data",
"uninstall": "Uninstall"
},
"hardware": {