From efcd57934a44a158677c55f75002e7698e5db4f3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 16 Dec 2024 12:23:17 +0100 Subject: [PATCH] Improve backup data-table on mobile (#23283) * Improve backup data-table on mobile * Group by default * Fix top-header slot on mobile --- src/layouts/hass-tabs-subpage-data-table.ts | 21 +++++- .../backup/ha-config-backup-dashboard.ts | 75 ++++++++++++++++--- src/panels/config/backup/ha-config-backup.ts | 1 + 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index 1858895621..3807b8c292 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -468,7 +468,7 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) { ${!this.narrow ? html`
- +
${this.hasFilters && !this.showFilters @@ -478,13 +478,19 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
` - : html`
+ : html` +
+ +
${this.hasFilters && !this.showFilters ? html`${filterButton}` : nothing} - ${selectModeBtn}${groupByMenu}${sortByMenu}${settingsButton} -
`} + ${selectModeBtn} +
+ ${groupByMenu}${sortByMenu}${settingsButton} +
+ `} `}
@@ -835,13 +841,20 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) { .narrow-header-row { display: flex; align-items: center; + min-width: 100%; gap: 16px; padding: 0 16px; + box-sizing: border-box; overflow-x: scroll; -ms-overflow-style: none; scrollbar-width: none; } + .narrow-header-row .flex { + flex: 1; + margin-left: -16px; + } + .selection-bar { background: rgba(var(--rgb-primary-color), 0.1); width: 100%; diff --git a/src/panels/config/backup/ha-config-backup-dashboard.ts b/src/panels/config/backup/ha-config-backup-dashboard.ts index 6eeb53f63b..0a6da83f2c 100644 --- a/src/panels/config/backup/ha-config-backup-dashboard.ts +++ b/src/panels/config/backup/ha-config-backup-dashboard.ts @@ -13,13 +13,14 @@ import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { relativeTime } from "../../../common/datetime/relative_time"; +import { storage } from "../../../common/decorators/storage"; import type { HASSDomEvent } from "../../../common/dom/fire_event"; +import { computeDomain } from "../../../common/entity/compute_domain"; import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event"; import { navigate } from "../../../common/navigate"; import type { LocalizeFunc } from "../../../common/translations/localize"; import type { DataTableColumnContainer, - DataTableRowData, RowClickedEvent, SelectionChangedEvent, } from "../../../components/data-table/ha-data-table"; @@ -71,7 +72,15 @@ import { showBackupOnboardingDialog } from "./dialogs/show-dialog-backup_onboard import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup"; import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup"; import { showUploadBackupDialog } from "./dialogs/show-dialog-upload-backup"; -import { computeDomain } from "../../../common/entity/compute_domain"; +import { capitalizeFirstLetter } from "../../../common/string/capitalize-first-letter"; + +interface BackupRow extends BackupContent { + formatted_type: string; +} + +type BackupType = "strategy" | "custom"; + +const TYPE_ORDER: Array = ["strategy", "custom"]; @customElement("ha-config-backup-dashboard") class HaConfigBackupDashboard extends SubscribeMixin(LitElement) { @@ -91,20 +100,29 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) { @state() private _config?: BackupConfig; + @storage({ key: "backups-table-grouping", state: false, subscribe: false }) + private _activeGrouping?: string = "formatted_type"; + + @storage({ + key: "backups-table-collapsed", + state: false, + subscribe: false, + }) + private _activeCollapsed?: string; + private _subscribed?: Promise<() => void>; @query("hass-tabs-subpage-data-table", true) private _dataTable!: HaTabsSubpageDataTable; private _columns = memoizeOne( - (localize: LocalizeFunc): DataTableColumnContainer => ({ + (localize: LocalizeFunc): DataTableColumnContainer => ({ name: { title: localize("ui.panel.config.backup.name"), main: true, sortable: true, filterable: true, - flex: 2, - template: (backup) => backup.name, + flex: 3, }, size: { title: localize("ui.panel.config.backup.size"), @@ -120,15 +138,17 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) { template: (backup) => relativeTime(new Date(backup.date), this.hass.locale), }, - with_strategy_settings: { + formatted_type: { title: "Type", filterable: true, sortable: true, - template: (backup) => - backup.with_strategy_settings ? "Strategy" : "Custom", + groupable: true, }, locations: { title: "Locations", + showNarrow: true, + minWidth: "60px", + maxWidth: "120px", template: (backup) => html`
${(backup.agent_ids || []).map((agentId) => { @@ -198,18 +218,44 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) { }) ); + private _groupOrder = memoizeOne((activeGrouping: string | undefined) => + activeGrouping === "formatted_type" + ? TYPE_ORDER.map((type) => this._formatBackupType(type)) + : undefined + ); + + private _handleGroupingChanged(ev: CustomEvent) { + this._activeGrouping = ev.detail.value; + } + + private _handleCollapseChanged(ev: CustomEvent) { + this._activeCollapsed = ev.detail.value; + } + private _handleSelectionChanged( ev: HASSDomEvent ): void { this._selected = ev.detail.value; } + private _formatBackupType(type: BackupType): string { + // Todo translate + return capitalizeFirstLetter(type); + } + + private _data = memoizeOne((backups: BackupContent[]): BackupRow[] => + backups.map((backup) => ({ + ...backup, + formatted_type: this._formatBackupType( + backup.with_strategy_settings ? "strategy" : "custom" + ), + })) + ); + protected render(): TemplateResult { const backupInProgress = "state" in this._manager && this._manager.state === "in_progress"; - const data: DataTableRowData[] = this._backups; - return html` -
+
${this._fetching ? html`