diff --git a/src/panels/config/backup/components/config/ha-backup-config-agents.ts b/src/panels/config/backup/components/config/ha-backup-config-agents.ts index 3d6463af8c..4444e917a2 100644 --- a/src/panels/config/backup/components/config/ha-backup-config-agents.ts +++ b/src/panels/config/backup/components/config/ha-backup-config-agents.ts @@ -1,4 +1,4 @@ -import { mdiCog, mdiHarddisk, mdiNas } from "@mdi/js"; +import { mdiCog, mdiDelete, mdiHarddisk, mdiNas } from "@mdi/js"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; @@ -41,13 +41,6 @@ class HaBackupConfigAgents extends LitElement { @state() private value?: string[]; - private _availableAgents = memoizeOne( - (agents: BackupAgent[], cloudStatus: CloudStatus) => - agents.filter( - (agent) => agent.agent_id !== CLOUD_AGENT || cloudStatus.logged_in - ) - ); - private get _value() { return this.value ?? DEFAULT_AGENTS; } @@ -86,19 +79,84 @@ class HaBackupConfigAgents extends LitElement { return ""; } - protected render() { - const agents = this._availableAgents(this.agents, this.cloudStatus); + private _availableAgents = memoizeOne( + (agents: BackupAgent[], cloudStatus: CloudStatus) => + agents.filter( + (agent) => agent.agent_id !== CLOUD_AGENT || cloudStatus.logged_in + ) + ); + + private _unavailableAgents = memoizeOne( + ( + agents: BackupAgent[], + cloudStatus: CloudStatus, + selectedAgentIds: string[] + ) => { + const availableAgentIds = this._availableAgents(agents, cloudStatus).map( + (agent) => agent.agent_id + ); + + return selectedAgentIds + .filter((agent) => !availableAgentIds.includes(agent)) + .map((id) => ({ + agent_id: id, + name: id.split(".")[1] || id, // Use the id as name as it is not available in the list + })); + } + ); + + private _renderAgentIcon(agentId: string) { + if (isLocalAgent(agentId)) { + return html` + + `; + } + + if (isNetworkMountAgent(agentId)) { + return html``; + } + + const domain = computeDomain(agentId); + return html` - ${agents.length > 0 + + `; + } + + protected render() { + const availableAgents = this._availableAgents( + this.agents, + this.cloudStatus + ); + const unavailableAgents = this._unavailableAgents( + this.agents, + this.cloudStatus, + this._value + ); + + const allAgents = [...availableAgents, ...unavailableAgents]; + + return html` + ${allAgents.length > 0 ? html` - ${agents.map((agent) => { + ${availableAgents.map((agent) => { const agentId = agent.agent_id; - const domain = computeDomain(agentId); const name = computeBackupAgentName( this.hass.localize, agentId, - this.agents + allAgents ); const description = this._description(agentId); const noCloudSubscription = @@ -108,32 +166,7 @@ class HaBackupConfigAgents extends LitElement { return html` - ${isLocalAgent(agentId) - ? html` - - - ` - : isNetworkMountAgent(agentId) - ? html` - - ` - : html` - - `} + ${this._renderAgentIcon(agentId)}
${name}
${description ? html`
${description}
` @@ -151,14 +184,44 @@ class HaBackupConfigAgents extends LitElement {
`; })} + ${unavailableAgents.length > 0 && this.showSettings + ? html` +

+ ${this.hass.localize( + "ui.panel.config.backup.agents.unavailable_agents" + )} +

+ ${unavailableAgents.map((agent) => { + const agentId = agent.agent_id; + const name = computeBackupAgentName( + this.hass.localize, + agentId, + allAgents + ); + + return html` + + ${this._renderAgentIcon(agentId)} +
${name}
+ +
+ `; + })} + ` + : nothing}
` : html` @@ -174,6 +237,13 @@ class HaBackupConfigAgents extends LitElement { navigate(`/config/backup/location/${agentId}`); } + private _deleteAgent(ev): void { + ev.stopPropagation(); + const agentId = ev.currentTarget.id; + this.value = this._value.filter((agent) => agent !== agentId); + fireEvent(this, "value-changed", { value: this.value }); + } + private _agentToggled(ev) { ev.stopPropagation(); const value = ev.currentTarget.checked; @@ -185,19 +255,8 @@ class HaBackupConfigAgents extends LitElement { this.value = this._value.filter((agent) => agent !== agentId); } - const availableAgents = this._availableAgents( - this.agents, - this.cloudStatus - ); - // Ensure we don't have duplicates, agents exist in the list and cloud is logged in - this.value = [...new Set(this.value)] - .filter((id) => availableAgents.some((agent) => agent.agent_id === id)) - .filter( - (id) => - id !== CLOUD_AGENT || - (this.cloudStatus.logged_in && this.cloudStatus.active_subscription) - ); + this.value = [...new Set(this.value)]; fireEvent(this, "value-changed", { value: this.value }); } diff --git a/src/translations/en.json b/src/translations/en.json index 8a6d0d9172..7de53853a1 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2408,6 +2408,7 @@ "cloud_agent_description": "Note: It stores only the most recent backup, regardless of your retention settings, with a maximum size of 5 GB.", "cloud_agent_no_subcription": "You currently do not have an active Home Assistant Cloud subscription.", "network_mount_agent_description": "Network storage", + "unavailable_agents": "Unavailable locations", "no_agents": "No locations configured", "encryption_turned_off": "Encryption turned off", "local_agent": "This system"