import DataUnit from './DataUnit.js'; import { Record } from './interfaces/dataUnit.js'; import { DataType } from './metadata/DataType.js'; import { LoadDataRequest, LoadDataResponse, PaginationInfo, Sort, SortMode, StringUtils } from '../index.js'; const DISTINCT_FILTER_NAME_PREFIX = 'FILTRO_COLUNA_'; interface FilterSimplified { column: string; values: string[]; } function sortRecords(sort: Array, records: Record[]) { sort.forEach(sortItem => { records = records.sort((recordA, recordB) => { const fieldA = recordA[sortItem.field]; const fieldB = recordB[sortItem.field]; const sortFn = getSortFn(sortItem.dataType); return sortFn(fieldA, fieldB) * (sortItem.mode == SortMode.ASC ? 1 : -1); }); }); return records; } export function defaultDataLoader(dataUnit: DataUnit, request: LoadDataRequest, recordsIn: Array): Promise { const filters = getColumnFilters(dataUnit); let records = applyFilters(filters, recordsIn, dataUnit); records = request.sort ? sortRecords(request.sort, records) : records; return Promise.resolve({ records: records, paginationInfo: buildPaginationInfo(request, records) }); } function buildPaginationInfo({ offset, limit }: LoadDataRequest, records: Array): PaginationInfo | undefined { if (offset === undefined || limit === undefined || records === undefined) { return undefined; } const total = records?.length || 0; const lastRecord = Math.min(offset + limit, total); return { currentPage: limit === 0 ? 0 : Math.ceil(offset / limit), firstRecord: offset + 1, lastRecord: lastRecord, total: total, hasMore: !!(total - lastRecord), }; } function filterRecords(record: Record, filter: FilterSimplified, dataUnit: DataUnit) { let fieldValue = record[filter.column]; if (dataUnit.getField(filter.column)?.dataType === DataType.OBJECT) { fieldValue = fieldValue.value; } return filter.values.includes(fieldValue?.toString()); } function applyFilters(filters: FilterSimplified[], recordsIn: Array, dataUnit: DataUnit) { let records = [...recordsIn]; filters.forEach(filter => { records = records.filter(record => filterRecords(record, filter, dataUnit)); }); return records; } function getColumnFilters(dataUnit: DataUnit): FilterSimplified[] { const allFilters = dataUnit.getFilters() ?? []; const columnFilters = allFilters.filter(({name}) => name?.includes(DISTINCT_FILTER_NAME_PREFIX)) ?? []; return columnFilters.map(({name, params}) => { return { column: name?.replace(DISTINCT_FILTER_NAME_PREFIX, '') ?? '', values: params?.map(param => param.value), }; }) as FilterSimplified[]; } function getSortFn(type: DataType): any { switch (type) { case DataType.NUMBER: return sortNumber; case DataType.DATE: return sortDate; case DataType.OBJECT: return sortObject; default: return StringUtils.compare; } } function sortObject(a: any, b: any): number { return StringUtils.compare(a?.['label'], b?.['label']); } function sortNumber(a: number, b: number): number { return a - b; } function sortDate(a: Date, b: Date): number { const timeA = a.getTime(), timeB = b.getTime(); return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1); }