mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Fix some bugs with repositioning rows.
Summary: - Fixed an issue with manualSort values being very close floats. It is already handled by the data engine, but the client was being unnecessarily proactive and introduced a bug. - The fix also helps with rearranging rows in filtered situations: they will now stay next to the row before which they were inserted. - The fix accidentally improves (though doesn't fully fix) the issue where new columns show up in unexpected places in the raw-data column list. - Fixed another rare bug with row order not getting updated correctly when positions update. Test Plan: Added test cases for the improved behavior; fixed affected tests. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3462
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { insertPositions } from "app/client/lib/tableUtil";
|
||||
import { BulkColValues, UserAction } from "app/common/DocActions";
|
||||
import { nativeCompare } from "app/common/gutil";
|
||||
import { obsArray, ObsArray } from "grainjs";
|
||||
@@ -155,24 +154,21 @@ export class TreeNodeRecord implements TreeNode {
|
||||
const indentations = records.map((rec, i) => rec.indentation + indent - records[0].indentation);
|
||||
|
||||
// adjust positions
|
||||
let upperPos, lowerPos: number|null;
|
||||
let upperPos: number|null;
|
||||
if (nextChild) {
|
||||
const index = nextChild.index;
|
||||
upperPos = this._records[index].pagePos;
|
||||
lowerPos = index ? this._records[index - 1].pagePos : null;
|
||||
} else {
|
||||
const lastIndex = this.findLastIndex();
|
||||
if (lastIndex !== "root") {
|
||||
upperPos = (this._records[lastIndex + 1] || {pagePos: null}).pagePos;
|
||||
lowerPos = this._records[lastIndex].pagePos;
|
||||
} else {
|
||||
upperPos = lowerPos = null;
|
||||
upperPos = null;
|
||||
}
|
||||
}
|
||||
const positions = insertPositions(lowerPos, upperPos, records.length);
|
||||
|
||||
// do update
|
||||
const update = records.map((rec, i) => ({...rec, indentation: indentations[i], pagePos: positions[i]}));
|
||||
const update = records.map((rec, i) => ({...rec, indentation: indentations[i], pagePos: upperPos!}));
|
||||
await this.sendActions({update});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ export class SortedRowSet extends RowListener {
|
||||
// Note that the logic is all or none, since we can't assume that a single row is in its right
|
||||
// place by comparing to neighbors because the neighbors might themselves be affected and wrong.
|
||||
const sortedRows = Array.from(rows).sort(this._compareFunc);
|
||||
if (_allRowsSorted(this._koArray.peek(), sortedRows, this._compareFunc)) {
|
||||
if (_allRowsSorted(this._koArray.peek(), this._allRows, sortedRows, this._compareFunc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -724,12 +724,15 @@ function _isIndexInOrder<T>(array: T[], index: number, compareFunc: CompareFunc<
|
||||
* Helper function to tell if each of sortedRows, if present in the array, is in order relative to
|
||||
* its neighbors. sortedRows should be sorted the same way as the array.
|
||||
*/
|
||||
function _allRowsSorted<T>(array: T[], sortedRows: Iterable<T>, compareFunc: CompareFunc<T>): boolean {
|
||||
function _allRowsSorted<T>(array: T[], allRows: Set<T>, sortedRows: Iterable<T>, compareFunc: CompareFunc<T>): boolean {
|
||||
let last = 0;
|
||||
for (const r of sortedRows) {
|
||||
if (!allRows.has(r)) {
|
||||
continue;
|
||||
}
|
||||
const index = array.indexOf(r, last);
|
||||
if (index === -1) { continue; }
|
||||
if (!_isIndexInOrder(array, index, compareFunc)) {
|
||||
if (index === -1 || !_isIndexInOrder(array, index, compareFunc)) {
|
||||
// rows of sortedRows are not present in the array in the same relative order.
|
||||
return false;
|
||||
}
|
||||
last = index;
|
||||
|
||||
Reference in New Issue
Block a user