diff --git a/src/app/duckdb.service.ts b/src/app/duckdb.service.ts index c15cc6b..1a9e85f 100644 --- a/src/app/duckdb.service.ts +++ b/src/app/duckdb.service.ts @@ -7,6 +7,11 @@ export interface Column { type: string; } +export interface SortColumn { + name: string; + sortType: 'asc' | 'desc'; +} + export interface RowsResponse { rows: any[]; totalRows: bigint; @@ -98,6 +103,7 @@ export class DuckdbService { start: number, numRows: number, columns: Column[], + sorts: SortColumn[], filters: unknown[], aggregations: unknown[], ): Promise { @@ -107,9 +113,12 @@ export class DuckdbService { `SELECT COUNT(1) totalRows FROM ${sanitisedFileName(file)}`, ); const { totalRows } = totalRowResponse.get(0)?.toJSON()!; - const response = await conn.query( - `SELECT ${columns.map((column) => `"${column.name}"`).join(', ')} FROM ${sanitisedFileName(file)} LIMIT ${numRows} OFFSET ${start}`, - ); + let query = `SELECT ${columns.map((column) => `"${column.name}"`).join(', ')} FROM ${sanitisedFileName(file)} `; + if (sorts.length > 0) { + query += ` ORDER BY ${sorts.map((sort) => `"${sort.name}" ${sort.sortType}`).join(', ')}`; + } + query += ` LIMIT ${numRows} OFFSET ${start}`; + const response = await conn.query(query); const rows = []; for (let i = 0; i < response.numRows; i++) { rows.push(response.get(i)?.toJSON()!); diff --git a/src/app/file-viewer/file-viewer.component.ts b/src/app/file-viewer/file-viewer.component.ts index 8a99f9c..cfc5bc5 100644 --- a/src/app/file-viewer/file-viewer.component.ts +++ b/src/app/file-viewer/file-viewer.component.ts @@ -20,6 +20,7 @@ import { Column, DuckdbService } from '../duckdb.service'; template: ` @if (file() && columns().length > 0) { @for (col of columns; track $index) { - - {{ col.name }} + + {{ col.name }} } @@ -71,7 +76,6 @@ export class FileViewerComponent { file = input(); private duckdbService = inject(DuckdbService); - private cdr = inject(ChangeDetectorRef); // Can't be computed since effect has to run first so file exists in duckdb protected columns = signal([]); @@ -92,6 +96,7 @@ export class FileViewerComponent { this.columns(), [], [], + [], ); const newValue = Array.from({ length: Number(rows.totalRows) }); this.currentValue.set(newValue); @@ -107,6 +112,10 @@ export class FileViewerComponent { event.first ?? 0, event.rows ?? 0, this.columns(), + event.multiSortMeta?.map((meta) => ({ + name: meta.field, + sortType: meta.order < 0 ? 'desc' : 'asc', + })) ?? [], [], [], ); @@ -122,7 +131,7 @@ export class FileViewerComponent { } // Can't update the current value, otherwise we get an infinite loop this.currentValue().splice(event.first!, event.rows!, ...rows.rows); - this.cdr.markForCheck(); + event.forceUpdate!(); } } }