Fix location icon when many locations in backup datatable (#23964)

* Fix location icon when many locations in backup datatable

* Reuse data

* Don't copy twice

* Improve naming
This commit is contained in:
Paul Bottein 2025-01-30 18:02:56 +01:00 committed by GitHub
parent ce58962dbb
commit fef5dc4232
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -141,7 +141,10 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
}; };
private _columns = memoizeOne( private _columns = memoizeOne(
(localize: LocalizeFunc): DataTableColumnContainer<BackupRow> => ({ (
localize: LocalizeFunc,
maxDisplayedAgents: number
): DataTableColumnContainer<BackupRow> => ({
name: { name: {
title: localize("ui.panel.config.backup.name"), title: localize("ui.panel.config.backup.name"),
main: true, main: true,
@ -172,54 +175,75 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
locations: { locations: {
title: localize("ui.panel.config.backup.locations"), title: localize("ui.panel.config.backup.locations"),
showNarrow: true, showNarrow: true,
minWidth: "60px", // 24 icon size, 4 gap, 16 left and right padding
template: (backup) => html` minWidth: `${maxDisplayedAgents * 24 + (maxDisplayedAgents - 1) * 4 + 32}px`,
<div style="display: flex; gap: 4px;"> template: (backup) => {
${(backup.agent_ids || []).map((agentId) => { const agentIds = backup.agent_ids;
const name = computeBackupAgentName( const displayedAgentIds =
this.hass.localize, agentIds.length > maxDisplayedAgents
agentId, ? [...agentIds].splice(0, maxDisplayedAgents - 1)
this.agents : agentIds;
); const agentsMore = Math.max(
if (isLocalAgent(agentId)) { agentIds.length - displayedAgentIds.length,
0
);
return html`
<div style="display: flex; gap: 4px;">
${displayedAgentIds.map((agentId) => {
const name = computeBackupAgentName(
this.hass.localize,
agentId,
this.agents
);
if (isLocalAgent(agentId)) {
return html`
<ha-svg-icon
.path=${mdiHarddisk}
title=${name}
style="flex-shrink: 0;"
></ha-svg-icon>
`;
}
if (isNetworkMountAgent(agentId)) {
return html`
<ha-svg-icon
.path=${mdiNas}
title=${name}
style="flex-shrink: 0;"
></ha-svg-icon>
`;
}
const domain = computeDomain(agentId);
return html` return html`
<ha-svg-icon <img
.path=${mdiHarddisk}
title=${name} title=${name}
.src=${brandsUrl({
domain,
type: "icon",
useFallback: true,
darkOptimized: this.hass.themes?.darkMode,
})}
height="24"
crossorigin="anonymous"
referrerpolicy="no-referrer"
alt=${name}
slot="graphic"
style="flex-shrink: 0;" style="flex-shrink: 0;"
></ha-svg-icon> />
`; `;
} })}
if (isNetworkMountAgent(agentId)) { ${agentsMore
return html` ? html`
<ha-svg-icon <span
.path=${mdiNas} style="display: flex; align-items: center; font-size: 14px;"
title=${name} >
style="flex-shrink: 0;" +${agentsMore}
></ha-svg-icon> </span>
`; `
} : nothing}
const domain = computeDomain(agentId); </div>
return html` `;
<img },
title=${name}
.src=${brandsUrl({
domain,
type: "icon",
useFallback: true,
darkOptimized: this.hass.themes?.darkMode,
})}
height="24"
crossorigin="anonymous"
referrerpolicy="no-referrer"
alt=${name}
slot="graphic"
style="flex-shrink: 0;"
/>
`;
})}
</div>
`,
}, },
actions: { actions: {
title: "", title: "",
@ -293,20 +317,31 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
} }
return filteredBackups.map((backup) => { return filteredBackups.map((backup) => {
const type = backup.with_automatic_settings ? "automatic" : "manual"; const type = backup.with_automatic_settings ? "automatic" : "manual";
const agentIds = Object.keys(backup.agents);
return { return {
...backup, ...backup,
size: computeBackupSize(backup), size: computeBackupSize(backup),
agent_ids: Object.keys(backup.agents).sort(compareAgents), agent_ids: agentIds.sort(compareAgents),
formatted_type: localize(`ui.panel.config.backup.type.${type}`), formatted_type: localize(`ui.panel.config.backup.type.${type}`),
}; };
}); });
} }
); );
private _maxAgents = memoizeOne((data: BackupRow[]): number =>
Math.max(...data.map((row) => row.agent_ids.length))
);
protected render(): TemplateResult { protected render(): TemplateResult {
const backupInProgress = const backupInProgress =
"state" in this.manager && this.manager.state === "in_progress"; "state" in this.manager && this.manager.state === "in_progress";
const data = this._data(this.backups, this._filters, this.hass.localize);
const maxDisplayedAgents = Math.min(
this._maxAgents(data),
this.narrow ? 3 : 5
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
has-fab has-fab
@ -343,8 +378,8 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
.route=${this.route} .route=${this.route}
@row-click=${this._showBackupDetails} @row-click=${this._showBackupDetails}
.columns=${this._columns(this.hass.localize)} .columns=${this._columns(this.hass.localize, maxDisplayedAgents)}
.data=${this._data(this.backups, this._filters, this.hass.localize)} .data=${data}
.noDataText=${this.hass.localize("ui.panel.config.backup.no_backups")} .noDataText=${this.hass.localize("ui.panel.config.backup.no_backups")}
.searchLabel=${this.hass.localize( .searchLabel=${this.hass.localize(
"ui.panel.config.backup.picker.search" "ui.panel.config.backup.picker.search"