2023-07-19 17:37:22 +00:00
|
|
|
import {ColumnGetter, ColumnGetters, ColumnGettersByColId} from 'app/common/ColumnGetters';
|
2020-07-21 13:20:51 +00:00
|
|
|
import * as gristTypes from 'app/common/gristTypes';
|
2023-07-19 17:37:22 +00:00
|
|
|
import {safeJsonParse} from 'app/common/gutil';
|
|
|
|
import {choiceGetter} from 'app/common/SortFunc';
|
|
|
|
import {Sort} from 'app/common/SortSpec';
|
|
|
|
import {BulkColValues} from 'app/plugin/GristData';
|
2020-07-21 13:20:51 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* An implementation of ColumnGetters for the server, currently
|
|
|
|
* drawing on the data and metadata prepared for CSV export.
|
|
|
|
*
|
|
|
|
*/
|
2023-07-19 17:37:22 +00:00
|
|
|
export class ServerColumnGetters implements ColumnGetters, ColumnGettersByColId {
|
2020-07-21 13:20:51 +00:00
|
|
|
private _rowIndices: Map<number, number>;
|
|
|
|
private _colIndices: Map<number, string>;
|
|
|
|
|
2023-07-19 17:37:22 +00:00
|
|
|
constructor(rowIds: number[], private _dataByColId: BulkColValues, private _columns: any[]) {
|
2021-11-03 11:44:28 +00:00
|
|
|
this._rowIndices = new Map<number, number>(rowIds.map((rowId, index) => [rowId, index] as [number, number]));
|
2020-07-21 13:20:51 +00:00
|
|
|
this._colIndices = new Map<number, string>(_columns.map(col => [col.id, col.colId] as [number, string]));
|
|
|
|
}
|
|
|
|
|
2021-11-03 11:44:28 +00:00
|
|
|
public getColGetter(colSpec: Sort.ColSpec): ColumnGetter | null {
|
|
|
|
const colRef = Sort.getColRef(colSpec);
|
2024-05-21 16:27:06 +00:00
|
|
|
if (typeof colRef !== 'number') {
|
|
|
|
// colRef might be string for virtual tables, but we don't support them here.
|
|
|
|
throw new Error(`Unsupported colRef type: ${typeof colRef}`);
|
|
|
|
}
|
2020-07-21 13:20:51 +00:00
|
|
|
const colId = this._colIndices.get(colRef);
|
|
|
|
if (colId === undefined) {
|
|
|
|
return null;
|
|
|
|
}
|
2023-07-19 17:37:22 +00:00
|
|
|
let getter = this.getColGetterByColId(colId);
|
|
|
|
if (!getter) {
|
|
|
|
return null;
|
|
|
|
}
|
2021-11-03 11:44:28 +00:00
|
|
|
const details = Sort.specToDetails(colSpec);
|
|
|
|
if (details.orderByChoice) {
|
|
|
|
const rowModel = this._columns.find(c => c.id == colRef);
|
|
|
|
if (rowModel?.type === 'Choice') {
|
|
|
|
const choices: string[] = safeJsonParse(rowModel.widgetOptions, {}).choices || [];
|
|
|
|
getter = choiceGetter(getter, choices);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return getter;
|
2020-07-21 13:20:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public getManualSortGetter(): ((rowId: number) => any) | null {
|
|
|
|
const manualSortCol = this._columns.find(c => c.colId === gristTypes.MANUALSORT);
|
|
|
|
if (!manualSortCol) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.getColGetter(manualSortCol.id);
|
|
|
|
}
|
2023-07-19 17:37:22 +00:00
|
|
|
|
|
|
|
public getColGetterByColId(colId: string): ColumnGetter | null {
|
|
|
|
if (colId === "id") {
|
|
|
|
return (rowId: number) => rowId;
|
|
|
|
}
|
|
|
|
const col = this._dataByColId[colId];
|
|
|
|
if (!col) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return (rowId: number) => {
|
|
|
|
const idx = this._rowIndices.get(rowId);
|
|
|
|
if (idx === undefined) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return col[idx];
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-07-21 13:20:51 +00:00
|
|
|
}
|