Fix data table worker (#5921)

This commit is contained in:
Bram Kragten 2020-05-19 13:59:16 +02:00 committed by GitHub
parent bbc16b6bc8
commit d9bb40f934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 52 deletions

View File

@ -21,7 +21,8 @@ import { nextRender } from "../../common/util/render-status";
import "../ha-checkbox";
import type { HaCheckbox } from "../ha-checkbox";
import "../ha-icon";
import { filterSortData } from "./sort-filter";
import { filterData, sortData } from "./sort-filter";
import memoizeOne from "memoize-one";
declare global {
// for fire event
@ -72,6 +73,10 @@ export interface DataTableRowData {
selectable?: boolean;
}
export interface SortableColumnContainer {
[key: string]: DataTableSortColumnData;
}
@customElement("ha-data-table")
export class HaDataTable extends LitElement {
@property({ type: Object }) public columns: DataTableColumnContainer = {};
@ -109,9 +114,7 @@ export class HaDataTable extends LitElement {
private _checkedRows: string[] = [];
private _sortColumns: {
[key: string]: DataTableSortColumnData;
} = {};
private _sortColumns: SortableColumnContainer = {};
private curRequest = 0;
@ -179,7 +182,7 @@ export class HaDataTable extends LitElement {
properties.has("_sortColumn") ||
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();
this.curRequest++;
const curRequest = this.curRequest;
const filterProm = filterSortData(
this.data,
this._sortColumns,
this._filter,
this._sortDirection,
this._sortColumn
);
let filteredData = this.data;
if (this._filter) {
filteredData = await this._memFilterData(
this.data,
this._sortColumns,
this.filter
);
}
const [data] = await Promise.all([filterProm, nextRender]);
const prom = this._sortColumn
? sortData(
filteredData,
this._sortColumns,
this._sortDirection,
this._sortColumn
)
: filteredData;
const [data] = await Promise.all([prom, nextRender]);
const curTime = new Date().getTime();
const elapsed = curTime - startTime;
@ -396,6 +409,16 @@ export class HaDataTable extends LitElement {
this._filteredData = data;
}
private _memFilterData = memoizeOne(
async (
data: DataTableRowData[],
columns: SortableColumnContainer,
filter: string
): Promise<DataTableRowData[]> => {
return filterData(data, columns, filter);
}
);
private _handleHeaderClick(ev: Event) {
const columnId = ((ev.target as HTMLElement).closest(
".mdc-data-table__header-cell"

View File

@ -1,26 +1,34 @@
import { wrap } from "comlink";
type FilterSortDataType = typeof import("./sort_filter_worker").api["filterSortData"];
type filterSortDataParamTypes = Parameters<FilterSortDataType>;
type FilterDataType = typeof import("./sort_filter_worker").api["filterData"];
type FilterDataParamTypes = Parameters<FilterDataType>;
type SortDataType = typeof import("./sort_filter_worker").api["sortData"];
type SortDataParamTypes = Parameters<SortDataType>;
let worker: any | undefined;
export const filterSortData = async (
data: filterSortDataParamTypes[0],
columns: filterSortDataParamTypes[1],
filter: filterSortDataParamTypes[2],
direction: filterSortDataParamTypes[3],
sortColumn: filterSortDataParamTypes[4]
): Promise<ReturnType<FilterSortDataType>> => {
export const filterData = async (
data: FilterDataParamTypes[0],
columns: FilterDataParamTypes[1],
filter: FilterDataParamTypes[2]
): Promise<ReturnType<FilterDataType>> => {
if (!worker) {
worker = wrap(new Worker("./sort_filter_worker", { type: "module" }));
}
return await worker.filterSortData(
data,
columns,
filter,
direction,
sortColumn
);
return await worker.filterData(data, columns, filter);
};
export const sortData = async (
data: SortDataParamTypes[0],
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);
};

View File

@ -5,33 +5,16 @@ import type {
DataTableSortColumnData,
DataTableRowData,
SortingDirection,
HaDataTable,
SortableColumnContainer,
} 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 = (
data: DataTableRowData[],
columns: SortableColumnContainer,
filter: string
) =>
data.filter((row) => {
) => {
filter = filter.toUpperCase();
return data.filter((row) => {
return Object.entries(columns).some((columnEntry) => {
const [key, column] = columnEntry;
if (column.filterable) {
@ -46,6 +29,7 @@ const filterData = (
return false;
});
});
};
const sortData = (
data: DataTableRowData[],
@ -85,7 +69,8 @@ const sortData = (
// Export for types
export const api = {
filterSortData,
filterData,
sortData,
};
expose(api);