mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Fix data table worker (#5921)
This commit is contained in:
parent
bbc16b6bc8
commit
d9bb40f934
@ -21,7 +21,8 @@ import { nextRender } from "../../common/util/render-status";
|
|||||||
import "../ha-checkbox";
|
import "../ha-checkbox";
|
||||||
import type { HaCheckbox } from "../ha-checkbox";
|
import type { HaCheckbox } from "../ha-checkbox";
|
||||||
import "../ha-icon";
|
import "../ha-icon";
|
||||||
import { filterSortData } from "./sort-filter";
|
import { filterData, sortData } from "./sort-filter";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
@ -72,6 +73,10 @@ export interface DataTableRowData {
|
|||||||
selectable?: boolean;
|
selectable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SortableColumnContainer {
|
||||||
|
[key: string]: DataTableSortColumnData;
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("ha-data-table")
|
@customElement("ha-data-table")
|
||||||
export class HaDataTable extends LitElement {
|
export class HaDataTable extends LitElement {
|
||||||
@property({ type: Object }) public columns: DataTableColumnContainer = {};
|
@property({ type: Object }) public columns: DataTableColumnContainer = {};
|
||||||
@ -109,9 +114,7 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
private _checkedRows: string[] = [];
|
private _checkedRows: string[] = [];
|
||||||
|
|
||||||
private _sortColumns: {
|
private _sortColumns: SortableColumnContainer = {};
|
||||||
[key: string]: DataTableSortColumnData;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
private curRequest = 0;
|
private curRequest = 0;
|
||||||
|
|
||||||
@ -179,7 +182,7 @@ export class HaDataTable extends LitElement {
|
|||||||
properties.has("_sortColumn") ||
|
properties.has("_sortColumn") ||
|
||||||
properties.has("_sortDirection")
|
properties.has("_sortDirection")
|
||||||
) {
|
) {
|
||||||
this._filterData();
|
this._sortFilterData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,20 +372,30 @@ export class HaDataTable extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _filterData() {
|
private async _sortFilterData() {
|
||||||
const startTime = new Date().getTime();
|
const startTime = new Date().getTime();
|
||||||
this.curRequest++;
|
this.curRequest++;
|
||||||
const curRequest = this.curRequest;
|
const curRequest = this.curRequest;
|
||||||
|
|
||||||
const filterProm = filterSortData(
|
let filteredData = this.data;
|
||||||
|
if (this._filter) {
|
||||||
|
filteredData = await this._memFilterData(
|
||||||
this.data,
|
this.data,
|
||||||
this._sortColumns,
|
this._sortColumns,
|
||||||
this._filter,
|
this.filter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const prom = this._sortColumn
|
||||||
|
? sortData(
|
||||||
|
filteredData,
|
||||||
|
this._sortColumns,
|
||||||
this._sortDirection,
|
this._sortDirection,
|
||||||
this._sortColumn
|
this._sortColumn
|
||||||
);
|
)
|
||||||
|
: filteredData;
|
||||||
|
|
||||||
const [data] = await Promise.all([filterProm, nextRender]);
|
const [data] = await Promise.all([prom, nextRender]);
|
||||||
|
|
||||||
const curTime = new Date().getTime();
|
const curTime = new Date().getTime();
|
||||||
const elapsed = curTime - startTime;
|
const elapsed = curTime - startTime;
|
||||||
@ -396,6 +409,16 @@ export class HaDataTable extends LitElement {
|
|||||||
this._filteredData = data;
|
this._filteredData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _memFilterData = memoizeOne(
|
||||||
|
async (
|
||||||
|
data: DataTableRowData[],
|
||||||
|
columns: SortableColumnContainer,
|
||||||
|
filter: string
|
||||||
|
): Promise<DataTableRowData[]> => {
|
||||||
|
return filterData(data, columns, filter);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private _handleHeaderClick(ev: Event) {
|
private _handleHeaderClick(ev: Event) {
|
||||||
const columnId = ((ev.target as HTMLElement).closest(
|
const columnId = ((ev.target as HTMLElement).closest(
|
||||||
".mdc-data-table__header-cell"
|
".mdc-data-table__header-cell"
|
||||||
|
@ -1,26 +1,34 @@
|
|||||||
import { wrap } from "comlink";
|
import { wrap } from "comlink";
|
||||||
|
|
||||||
type FilterSortDataType = typeof import("./sort_filter_worker").api["filterSortData"];
|
type FilterDataType = typeof import("./sort_filter_worker").api["filterData"];
|
||||||
type filterSortDataParamTypes = Parameters<FilterSortDataType>;
|
type FilterDataParamTypes = Parameters<FilterDataType>;
|
||||||
|
|
||||||
|
type SortDataType = typeof import("./sort_filter_worker").api["sortData"];
|
||||||
|
type SortDataParamTypes = Parameters<SortDataType>;
|
||||||
|
|
||||||
let worker: any | undefined;
|
let worker: any | undefined;
|
||||||
|
|
||||||
export const filterSortData = async (
|
export const filterData = async (
|
||||||
data: filterSortDataParamTypes[0],
|
data: FilterDataParamTypes[0],
|
||||||
columns: filterSortDataParamTypes[1],
|
columns: FilterDataParamTypes[1],
|
||||||
filter: filterSortDataParamTypes[2],
|
filter: FilterDataParamTypes[2]
|
||||||
direction: filterSortDataParamTypes[3],
|
): Promise<ReturnType<FilterDataType>> => {
|
||||||
sortColumn: filterSortDataParamTypes[4]
|
|
||||||
): Promise<ReturnType<FilterSortDataType>> => {
|
|
||||||
if (!worker) {
|
if (!worker) {
|
||||||
worker = wrap(new Worker("./sort_filter_worker", { type: "module" }));
|
worker = wrap(new Worker("./sort_filter_worker", { type: "module" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return await worker.filterSortData(
|
return await worker.filterData(data, columns, filter);
|
||||||
data,
|
};
|
||||||
columns,
|
|
||||||
filter,
|
export const sortData = async (
|
||||||
direction,
|
data: SortDataParamTypes[0],
|
||||||
sortColumn
|
columns: SortDataParamTypes[1],
|
||||||
);
|
direction: SortDataParamTypes[2],
|
||||||
|
sortColumn: SortDataParamTypes[3]
|
||||||
|
): Promise<ReturnType<SortDataType>> => {
|
||||||
|
if (!worker) {
|
||||||
|
worker = wrap(new Worker("./sort_filter_worker", { type: "module" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return await worker.sortData(data, columns, direction, sortColumn);
|
||||||
};
|
};
|
||||||
|
@ -5,33 +5,16 @@ import type {
|
|||||||
DataTableSortColumnData,
|
DataTableSortColumnData,
|
||||||
DataTableRowData,
|
DataTableRowData,
|
||||||
SortingDirection,
|
SortingDirection,
|
||||||
HaDataTable,
|
SortableColumnContainer,
|
||||||
} from "./ha-data-table";
|
} from "./ha-data-table";
|
||||||
|
|
||||||
type SortableColumnContainer = HaDataTable["_sortColumns"];
|
|
||||||
|
|
||||||
const filterSortData = (
|
|
||||||
data: DataTableRowData[],
|
|
||||||
columns: SortableColumnContainer,
|
|
||||||
filter: string,
|
|
||||||
direction: SortingDirection,
|
|
||||||
sortColumn?: string
|
|
||||||
) => {
|
|
||||||
const filteredData = filter ? filterData(data, columns, filter) : data;
|
|
||||||
|
|
||||||
if (!sortColumn) {
|
|
||||||
return filteredData;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortData(filteredData, columns, direction, sortColumn);
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterData = (
|
const filterData = (
|
||||||
data: DataTableRowData[],
|
data: DataTableRowData[],
|
||||||
columns: SortableColumnContainer,
|
columns: SortableColumnContainer,
|
||||||
filter: string
|
filter: string
|
||||||
) =>
|
) => {
|
||||||
data.filter((row) => {
|
filter = filter.toUpperCase();
|
||||||
|
return data.filter((row) => {
|
||||||
return Object.entries(columns).some((columnEntry) => {
|
return Object.entries(columns).some((columnEntry) => {
|
||||||
const [key, column] = columnEntry;
|
const [key, column] = columnEntry;
|
||||||
if (column.filterable) {
|
if (column.filterable) {
|
||||||
@ -46,6 +29,7 @@ const filterData = (
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const sortData = (
|
const sortData = (
|
||||||
data: DataTableRowData[],
|
data: DataTableRowData[],
|
||||||
@ -85,7 +69,8 @@ const sortData = (
|
|||||||
|
|
||||||
// Export for types
|
// Export for types
|
||||||
export const api = {
|
export const api = {
|
||||||
filterSortData,
|
filterData,
|
||||||
|
sortData,
|
||||||
};
|
};
|
||||||
|
|
||||||
expose(api);
|
expose(api);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user