mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-17 06:16:33 +00:00
Improve backup data-table on mobile (#23283)
* Improve backup data-table on mobile * Group by default * Fix top-header slot on mobile
This commit is contained in:
parent
1efe61445f
commit
efcd57934a
@ -468,7 +468,7 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
|
|||||||
${!this.narrow
|
${!this.narrow
|
||||||
? html`
|
? html`
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<slot name="top_header"></slot>
|
<slot name="top-header"></slot>
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
${this.hasFilters && !this.showFilters
|
${this.hasFilters && !this.showFilters
|
||||||
@ -478,13 +478,19 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
|
|||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: html`<div slot="header"></div>
|
: html`
|
||||||
|
<div slot="header">
|
||||||
|
<slot name="top-header"></slot>
|
||||||
|
</div>
|
||||||
<div slot="header-row" class="narrow-header-row">
|
<div slot="header-row" class="narrow-header-row">
|
||||||
${this.hasFilters && !this.showFilters
|
${this.hasFilters && !this.showFilters
|
||||||
? html`${filterButton}`
|
? html`${filterButton}`
|
||||||
: nothing}
|
: nothing}
|
||||||
${selectModeBtn}${groupByMenu}${sortByMenu}${settingsButton}
|
${selectModeBtn}
|
||||||
</div>`}
|
<div class="flex"></div>
|
||||||
|
${groupByMenu}${sortByMenu}${settingsButton}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
</ha-data-table>`}
|
</ha-data-table>`}
|
||||||
<div slot="fab"><slot name="fab"></slot></div>
|
<div slot="fab"><slot name="fab"></slot></div>
|
||||||
</hass-tabs-subpage>
|
</hass-tabs-subpage>
|
||||||
@ -835,13 +841,20 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
|
|||||||
.narrow-header-row {
|
.narrow-header-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
min-width: 100%;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.narrow-header-row .flex {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: -16px;
|
||||||
|
}
|
||||||
|
|
||||||
.selection-bar {
|
.selection-bar {
|
||||||
background: rgba(var(--rgb-primary-color), 0.1);
|
background: rgba(var(--rgb-primary-color), 0.1);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -13,13 +13,14 @@ import { classMap } from "lit/directives/class-map";
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
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 { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
import type {
|
import type {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
DataTableRowData,
|
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} 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 { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup";
|
||||||
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
|
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
|
||||||
import { showUploadBackupDialog } from "./dialogs/show-dialog-upload-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<BackupType> = ["strategy", "custom"];
|
||||||
|
|
||||||
@customElement("ha-config-backup-dashboard")
|
@customElement("ha-config-backup-dashboard")
|
||||||
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
||||||
@ -91,20 +100,29 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _config?: BackupConfig;
|
@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>;
|
private _subscribed?: Promise<() => void>;
|
||||||
|
|
||||||
@query("hass-tabs-subpage-data-table", true)
|
@query("hass-tabs-subpage-data-table", true)
|
||||||
private _dataTable!: HaTabsSubpageDataTable;
|
private _dataTable!: HaTabsSubpageDataTable;
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(localize: LocalizeFunc): DataTableColumnContainer<BackupContent> => ({
|
(localize: LocalizeFunc): DataTableColumnContainer<BackupRow> => ({
|
||||||
name: {
|
name: {
|
||||||
title: localize("ui.panel.config.backup.name"),
|
title: localize("ui.panel.config.backup.name"),
|
||||||
main: true,
|
main: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
flex: 2,
|
flex: 3,
|
||||||
template: (backup) => backup.name,
|
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
title: localize("ui.panel.config.backup.size"),
|
title: localize("ui.panel.config.backup.size"),
|
||||||
@ -120,15 +138,17 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
template: (backup) =>
|
template: (backup) =>
|
||||||
relativeTime(new Date(backup.date), this.hass.locale),
|
relativeTime(new Date(backup.date), this.hass.locale),
|
||||||
},
|
},
|
||||||
with_strategy_settings: {
|
formatted_type: {
|
||||||
title: "Type",
|
title: "Type",
|
||||||
filterable: true,
|
filterable: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
template: (backup) =>
|
groupable: true,
|
||||||
backup.with_strategy_settings ? "Strategy" : "Custom",
|
|
||||||
},
|
},
|
||||||
locations: {
|
locations: {
|
||||||
title: "Locations",
|
title: "Locations",
|
||||||
|
showNarrow: true,
|
||||||
|
minWidth: "60px",
|
||||||
|
maxWidth: "120px",
|
||||||
template: (backup) => html`
|
template: (backup) => html`
|
||||||
<div style="display: flex; gap: 4px;">
|
<div style="display: flex; gap: 4px;">
|
||||||
${(backup.agent_ids || []).map((agentId) => {
|
${(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(
|
private _handleSelectionChanged(
|
||||||
ev: HASSDomEvent<SelectionChangedEvent>
|
ev: HASSDomEvent<SelectionChangedEvent>
|
||||||
): void {
|
): void {
|
||||||
this._selected = ev.detail.value;
|
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 {
|
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: DataTableRowData[] = this._backups;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage-data-table
|
<hass-tabs-subpage-data-table
|
||||||
hasFab
|
hasFab
|
||||||
@ -226,17 +272,22 @@ class HaConfigBackupDashboard extends SubscribeMixin(LitElement) {
|
|||||||
id="backup_id"
|
id="backup_id"
|
||||||
selectable
|
selectable
|
||||||
.selected=${this._selected.length}
|
.selected=${this._selected.length}
|
||||||
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.groupOrder=${this._groupOrder(this._activeGrouping)}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@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)}
|
||||||
.data=${data}
|
.data=${this._data(this._backups)}
|
||||||
.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"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div slot="top_header" class="header">
|
<div slot="top-header" class="header">
|
||||||
${this._fetching
|
${this._fetching
|
||||||
? html`
|
? html`
|
||||||
<ha-backup-summary-card
|
<ha-backup-summary-card
|
||||||
|
@ -37,6 +37,7 @@ class HaConfigBackup extends HassRouterPage {
|
|||||||
protected updatePageEl(pageEl, changedProps: PropertyValues) {
|
protected updatePageEl(pageEl, changedProps: PropertyValues) {
|
||||||
pageEl.hass = this.hass;
|
pageEl.hass = this.hass;
|
||||||
pageEl.route = this.routeTail;
|
pageEl.route = this.routeTail;
|
||||||
|
pageEl.narrow = this.narrow;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(!changedProps || changedProps.has("route")) &&
|
(!changedProps || changedProps.has("route")) &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user