Add backup sync status in detail page (#23312)

This commit is contained in:
Paul Bottein 2024-12-16 14:36:59 +01:00 committed by GitHub
parent ee292f900f
commit 08459394a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 27 deletions

View File

@ -63,6 +63,7 @@ export interface BackupContent {
protected: boolean; protected: boolean;
size: number; size: number;
agent_ids?: string[]; agent_ids?: string[];
failed_agent_ids?: string[];
with_strategy_settings: boolean; with_strategy_settings: boolean;
} }

View File

@ -492,6 +492,7 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
this._backups = info.backups.map((backup) => ({ this._backups = info.backups.map((backup) => ({
...backup, ...backup,
agent_ids: backup.agent_ids?.sort(compareAgents), agent_ids: backup.agent_ids?.sort(compareAgents),
failed_agent_ids: backup.failed_agent_ids?.sort(compareAgents),
})); }));
} }

View File

@ -36,6 +36,22 @@ import { showConfirmationDialog } from "../../lovelace/custom-card-helpers";
import "./components/ha-backup-data-picker"; import "./components/ha-backup-data-picker";
import { showRestoreBackupEncryptionKeyDialog } from "./dialogs/show-dialog-restore-backup-encryption-key"; import { showRestoreBackupEncryptionKeyDialog } from "./dialogs/show-dialog-restore-backup-encryption-key";
type Agent = {
id: string;
success: boolean;
};
const computeAgents = (agent_ids: string[], failed_agent_ids: string[]) =>
[
...agent_ids.filter((id) => !failed_agent_ids.includes(id)),
...failed_agent_ids,
]
.map<Agent>((id) => ({
id,
success: !failed_agent_ids.includes(id),
}))
.sort((a, b) => compareAgents(a.id, b.id));
@customElement("ha-config-backup-details") @customElement("ha-config-backup-details")
class HaConfigBackupDetails extends LitElement { class HaConfigBackupDetails extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@ -46,6 +62,8 @@ class HaConfigBackupDetails extends LitElement {
@state() private _backup?: BackupContentExtended | null; @state() private _backup?: BackupContentExtended | null;
@state() private _agents: Agent[] = [];
@state() private _error?: string; @state() private _error?: string;
@state() private _selectedBackup?: BackupContentExtended; @state() private _selectedBackup?: BackupContentExtended;
@ -93,9 +111,11 @@ class HaConfigBackupDetails extends LitElement {
${this._error && ${this._error &&
html`<ha-alert alert-type="error">${this._error}</ha-alert>`} html`<ha-alert alert-type="error">${this._error}</ha-alert>`}
${this._backup === null ${this._backup === null
? html`<ha-alert alert-type="warning" title="Not found"> ? html`
<ha-alert alert-type="warning" title="Not found">
Backup matching ${this.backupId} not found Backup matching ${this.backupId} not found
</ha-alert>` </ha-alert>
`
: !this._backup : !this._backup
? html`<ha-circular-progress active></ha-circular-progress>` ? html`<ha-circular-progress active></ha-circular-progress>`
: html` : html`
@ -142,7 +162,9 @@ class HaConfigBackupDetails extends LitElement {
<ha-card header="Locations"> <ha-card header="Locations">
<div class="card-content"> <div class="card-content">
<ha-md-list> <ha-md-list>
${this._backup.agent_ids?.map((agentId) => { ${this._agents.map((agent) => {
const agentId = agent.id;
const success = agent.success;
const domain = computeDomain(agentId); const domain = computeDomain(agentId);
const name = computeBackupAgentName( const name = computeBackupAgentName(
this.hass.localize, this.hass.localize,
@ -176,7 +198,17 @@ class HaConfigBackupDetails extends LitElement {
/> />
`} `}
<div slot="headline">${name}</div> <div slot="headline">${name}</div>
<ha-button-menu <div slot="supporting-text">
<span
class="dot ${success ? "success" : "error"}"
>
</span>
<span>
${success ? "Backup synced" : "Backup failed"}
</span>
</div>
${success
? html`<ha-button-menu
slot="end" slot="end"
@action=${this._handleAgentAction} @action=${this._handleAgentAction}
.agent=${agentId} .agent=${agentId}
@ -184,7 +216,9 @@ class HaConfigBackupDetails extends LitElement {
> >
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass.localize("ui.common.menu")} .label=${this.hass.localize(
"ui.common.menu"
)}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item graphic="icon"> <ha-list-item graphic="icon">
@ -194,7 +228,8 @@ class HaConfigBackupDetails extends LitElement {
></ha-svg-icon> ></ha-svg-icon>
Download from this location Download from this location
</ha-list-item> </ha-list-item>
</ha-button-menu> </ha-button-menu>`
: nothing}
</ha-md-list-item> </ha-md-list-item>
`; `;
})} })}
@ -266,10 +301,11 @@ class HaConfigBackupDetails extends LitElement {
private async _fetchBackup() { private async _fetchBackup() {
try { try {
const response = await fetchBackupDetails(this.hass, this.backupId); const response = await fetchBackupDetails(this.hass, this.backupId);
this._backup = { this._backup = response.backup;
...response.backup, this._agents = computeAgents(
agent_ids: response.backup.agent_ids?.sort(compareAgents), response.backup.agent_ids || [],
}; response.backup.failed_agent_ids || []
);
} catch (err: any) { } catch (err: any) {
this._error = err?.message || "Could not fetch backup details"; this._error = err?.message || "Could not fetch backup details";
} }
@ -357,6 +393,28 @@ class HaConfigBackupDetails extends LitElement {
ha-backup-data-picker { ha-backup-data-picker {
display: block; display: block;
} }
ha-md-list-item [slot="supporting-text"] {
display: flex;
align-items: center;
flex-direction: row;
gap: 8px;
line-height: normal;
}
.dot {
display: block;
position: relative;
width: 8px;
height: 8px;
background-color: var(--disabled-color);
border-radius: 50%;
flex: none;
}
.dot.success {
background-color: var(--success-color);
}
.dot.error {
background-color: var(--error-color);
}
`; `;
} }