From bd52665f963d7c5a3d6f6cddbc7ddc839a0c4e51 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Mon, 18 Dec 2023 19:50:57 +0200 Subject: [PATCH] (core) Allow adding rows to widgets filtered by a link using a formula column Summary: When a widget `A` is selected by a widget `B` so that `A` is filtered, adding a new row to `A` uses the values in the selected row of `B` and the columns relevant to the linking as default values for the new row. This ensures that the new row matches the current linking filter and remains visible. However this would previously cause a sandbox error when one of the linking columns was a formula column, which doesn't allow setting values. This diff ignores formula columns when picking default values. Since the value of the formula column in the new row typically won't match the linking filter, extra measures are needed to avoid the new row immediately disappearing. Regular filters already have a mechanism for this, but I didn't manage to extend it to also work for linking. Thanks @dsagal for creating `UnionRowSource` (originally in D4017) which is now used as the solution for temporarily exempting rows from both kinds of filtering. While testing, I also came across another bug in linking summary tables that caused incorrect filtering, which I fixed with some changes to `DynamicQuerySet`. Test Plan: Extended an nbrowser test, which both tests for the main change as well as the secondary bugfix. Reviewers: georgegevoian Reviewed By: georgegevoian Subscribers: dsagal Differential Revision: https://phab.getgrist.com/D4135 --- app/client/components/BaseView.js | 32 +++++++----- app/client/components/BaseView2.ts | 17 +++++++ app/client/models/QuerySet.ts | 34 ++++++++----- app/client/models/SectionFilter.ts | 58 ++++++---------------- app/client/models/UnionRowSource.ts | 59 +++++++++++++++++++++++ app/client/models/rowset.ts | 58 ++++++++++++++++------ app/client/ui/ColumnFilterMenu.ts | 11 ++--- app/client/widgets/ErrorDom.ts | 1 + app/client/widgets/FieldBuilder.ts | 1 + test/client/models/rowset.js | 16 +++--- test/fixtures/docs/SelectBySummary.grist | Bin 622592 -> 180224 bytes test/nbrowser/SelectByRefList.ts | 5 +- test/nbrowser/SelectBySummary.ts | 49 +++++++++++++++++-- 13 files changed, 237 insertions(+), 104 deletions(-) create mode 100644 app/client/models/UnionRowSource.ts diff --git a/app/client/components/BaseView.js b/app/client/components/BaseView.js index 68af3bc8..10f3bd4b 100644 --- a/app/client/components/BaseView.js +++ b/app/client/components/BaseView.js @@ -13,6 +13,7 @@ const {DynamicQuerySet} = require('../models/QuerySet'); const {SortFunc} = require('app/common/SortFunc'); const rowset = require('../models/rowset'); const Base = require('./Base'); +const {getDefaultColValues} = require("./BaseView2"); const {Cursor} = require('./Cursor'); const FieldBuilder = require('../widgets/FieldBuilder'); const commands = require('./commands'); @@ -21,6 +22,7 @@ const {ClientColumnGetters} = require('app/client/models/ClientColumnGetters'); const {reportError, reportSuccess} = require('app/client/models/errors'); const {urlState} = require('app/client/models/gristUrlState'); const {SectionFilter} = require('app/client/models/SectionFilter'); +const {UnionRowSource} = require('app/client/models/UnionRowSource'); const {copyToClipboard} = require('app/client/lib/clipboardUtils'); const {setTestState} = require('app/client/lib/testState'); const {ExtraRows} = require('app/client/models/DataTableModelWithDiff'); @@ -70,17 +72,24 @@ function BaseView(gristDoc, viewSectionModel, options) { this._mainRowSource = rowset.ExtendedRowSource.create(this, this._mainRowSource, extraRowIds); } + // Rows that should temporarily be visible even if they don't match filters. + // This is so that a newly added row doesn't immediately disappear, which would be confusing. + this._exemptFromFilterRows = rowset.ExemptFromFilterRowSource.create(this); + this._exemptFromFilterRows.subscribeTo(this.tableModel); + // Create a section filter and a filtered row source that subscribes to its changes. - // `sectionFilter` also provides an `addTemporaryRow()` to allow views to display newly inserted rows, - // and `setFilterOverride()` to allow controlling a filter from a column menu. - this._sectionFilter = SectionFilter.create(this, this.viewSection, this.tableModel.tableData); + // `sectionFilter` also provides `setFilterOverride()` to allow controlling a filter from a column menu. + // Whenever changes are made to filters, exempt rows are reset. + this._sectionFilter = SectionFilter.create( + this, this.viewSection, this.tableModel.tableData, () => this._exemptFromFilterRows.reset() + ); this._filteredRowSource = rowset.FilteredRowSource.create(this, this._sectionFilter.sectionFilterFunc.get()); this._filteredRowSource.subscribeTo(this._mainRowSource); this.autoDispose(this._sectionFilter.sectionFilterFunc.addListener(filterFunc => { this._filteredRowSource.updateFilter(filterFunc); })); - this.rowSource = this._filteredRowSource; + this.rowSource = UnionRowSource.create(this, [this._filteredRowSource, this._exemptFromFilterRows]); // Sorted collection of all rows to show in this view. this.sortedRows = rowset.SortedRowSet.create(this, null, this.tableModel.tableData); @@ -96,7 +105,7 @@ function BaseView(gristDoc, viewSectionModel, options) { }, this)); // Here we are subscribed to the bulk of the data (main table, possibly filtered). - this.sortedRows.subscribeTo(this._filteredRowSource); + this.sortedRows.subscribeTo(this.rowSource); // We create a special one-row RowSource for the "Add new" row, in case we need it. this.newRowSource = rowset.RowSource.create(this); @@ -201,6 +210,7 @@ function BaseView(gristDoc, viewSectionModel, options) { this._queryRowSource.makeQuery(linkingFilter.filters, linkingFilter.operations, (err) => { if (this.isDisposed()) { return; } if (err) { reportError(err); } + this._exemptFromFilterRows.reset(); this.onTableLoaded(); }); })); @@ -442,7 +452,7 @@ BaseView.prototype.insertRow = function(index) { return this.sendTableAction(['AddRecord', null, { 'manualSort': insertPos }]) .then(rowId => { if (!this.isDisposed()) { - this._sectionFilter.addTemporaryRow(rowId); + this._exemptFromFilterRows.addExemptRow(rowId); this.setCursorPos({rowId}); } return rowId; @@ -450,11 +460,7 @@ BaseView.prototype.insertRow = function(index) { }; BaseView.prototype._getDefaultColValues = function() { - const linkingState = this.viewSection.linkingState.peek(); - if (!linkingState) { - return {}; - } - return linkingState.getDefaultColValues(); + return getDefaultColValues(this.viewSection); }; /** @@ -562,7 +568,7 @@ BaseView.prototype._saveEditRowField = function(editRowModel, colName, value) { // Once we know the new row's rowId, add it to column filters to make sure it's displayed. .then(rowId => { if (!this.isDisposed()) { - this._sectionFilter.addTemporaryRow(rowId); + this._exemptFromFilterRows.addExemptRow(rowId); this.setCursorPos({rowId}); } return rowId; @@ -581,7 +587,7 @@ BaseView.prototype._saveEditRowField = function(editRowModel, colName, value) { // unless the filter is on a Bool column .then((result) => { if (!this.isDisposed() && this.currentColumn().pureType() !== 'Bool') { - this._sectionFilter.addTemporaryRow(rowId); + this._exemptFromFilterRows.addExemptRow(rowId); } return result; }) diff --git a/app/client/components/BaseView2.ts b/app/client/components/BaseView2.ts index 151d06ca..e3fb5f95 100644 --- a/app/client/components/BaseView2.ts +++ b/app/client/components/BaseView2.ts @@ -9,7 +9,9 @@ import {UserAction} from 'app/common/DocActions'; import {isFullReferencingType} from 'app/common/gristTypes'; import {SchemaTypes} from 'app/common/schema'; import {BulkColValues} from 'app/plugin/GristData'; +import {ViewSectionRec} from "app/client/models/entities/ViewSectionRec"; import omit = require('lodash/omit'); +import pick = require('lodash/pick'); /** * Given a 2-d paste column-oriented paste data and target cols, transform the data to omit @@ -87,3 +89,18 @@ export async function parsePasteForView( return result; } + +/** + * Get default values for a new record so that it continues to satisfy the current linking filters. + * Exclude formula columns since we can't set their values. + */ +export function getDefaultColValues(viewSection: ViewSectionRec): Record { + const linkingState = viewSection.linkingState.peek(); + if (!linkingState) { + return {}; + } + const dataColIds = viewSection.columns.peek() + .filter(col => !col.isRealFormula.peek()) + .map(col => col.colId.peek()); + return pick(linkingState.getDefaultColValues(), dataColIds); +} diff --git a/app/client/models/QuerySet.ts b/app/client/models/QuerySet.ts index 269f1583..48a7ad09 100644 --- a/app/client/models/QuerySet.ts +++ b/app/client/models/QuerySet.ts @@ -117,6 +117,22 @@ export class QuerySetManager extends Disposable { * RowSource. */ export class DynamicQuerySet extends RowSource { + /** + * Replace the query represented by this DynamicQuerySet. If multiple makeQuery() calls are made + * quickly (while waiting for the server), cb() may only be called for the latest one. + * + * If there is an error fetching data, cb(err) will be called with that error. The second + * argument to cb() is true if any data was changed, and false if not. Note that for a series of + * makeQuery() calls, cb() is always called at least once, and always asynchronously. + * + * It's possible for this to be called very quickly in succession, + * e.g. when selecting another row of a linked summary table grouped by multiple columns, + * as an observable gets triggered for each one. + * We only want to keep the last call, and _updateQuerySetDebounced may not be called + * in the correct order, so we first debounce here. + */ + public readonly makeQuery = debounce(tbind(this._makeQuery, this), 0); + // Holds a reference to the currently active QuerySet. private _holder = Holder.create>(this); @@ -147,17 +163,13 @@ export class DynamicQuerySet extends RowSource { return this._querySet ? this._querySet.isTruncated : false; } - /** - * Replace the query represented by this DynamicQuerySet. If multiple makeQuery() calls are made - * quickly (while waiting for the server), cb() may only be called for the latest one. - * - * If there is an error fetching data, cb(err) will be called with that error. The second - * argument to cb() is true if any data was changed, and false if not. Note that for a series of - * makeQuery() calls, cb() is always called at least once, and always asynchronously. - */ - public makeQuery(filters: {[colId: string]: any[]}, - operations: {[colId: string]: QueryOperation}, - cb: (err: Error|null, changed: boolean) => void): void { + private _makeQuery(filters: { [colId: string]: any[] }, + operations: {[colId: string]: QueryOperation}, + cb: (err: Error|null, changed: boolean) => void): void { + if (this.isDisposed()) { + cb(new Error('Disposed'), false); + return; + } const query: ClientQuery = {tableId: this._tableModel.tableData.tableId, filters, operations}; const newQuerySet = this._querySetManager.useQuerySet(this._holder, query); diff --git a/app/client/models/SectionFilter.ts b/app/client/models/SectionFilter.ts index bbf3f74b..fa38194d 100644 --- a/app/client/models/SectionFilter.ts +++ b/app/client/models/SectionFilter.ts @@ -4,7 +4,7 @@ import {TableData} from 'app/client/models/TableData'; import {buildColFilter, ColumnFilterFunc} from 'app/common/ColumnFilterFunc'; import {buildRowFilter, RowFilterFunc, RowValueFunc } from 'app/common/RowFilterFunc'; import {UIRowId} from 'app/plugin/GristAPI'; -import {Computed, Disposable, MutableObsArray, obsArray, Observable, UseCB} from 'grainjs'; +import {Computed, Disposable, Observable, UseCB} from 'grainjs'; export type {ColumnFilterFunc}; @@ -21,20 +21,21 @@ type ColFilterCB = (fieldOrColumn: ViewFieldRec|ColumnRec, colFilter: ColumnFilt * subscribe to in order to update their FilteredRowSource. * * Additionally, `setFilterOverride()` provides a way to override the current filter for a given colRef, - * to reflect the changes in an open filter dialog. Also, `addTemporaryRow()` allows to add a rowId - * that should be present regardless of filters. These rows are removed automatically when an update to the filter - * results in their being displayed (obviating the need to maintain their rowId explicitly). + * to reflect the changes in an open filter dialog. */ export class SectionFilter extends Disposable { public readonly sectionFilterFunc: Observable>; private _openFilterOverride: Observable = Observable.create(this, null); - private _tempRows: MutableObsArray = obsArray(); - constructor(public viewSection: ViewSectionRec, private _tableData: TableData) { + constructor( + public viewSection: ViewSectionRec, + private _tableData: TableData, + private _resetExemptRows: () => void, + ) { super(); - const columnFilterFunc = Computed.create(this, this._openFilterOverride, (use, openFilter) => { + this.sectionFilterFunc = Computed.create(this, this._openFilterOverride, (use, openFilter) => { const openFilterFilterFunc = openFilter && use(openFilter.colFilter.filterFunc); function getFilterFunc(fieldOrColumn: ViewFieldRec|ColumnRec, colFilter: ColumnFilterFunc|null) { if (openFilter?.colRef === fieldOrColumn.origCol().getRowId()) { @@ -42,16 +43,8 @@ export class SectionFilter extends Disposable { } return colFilter; } - return this._buildPlainFilterFunc(getFilterFunc, use); + return this.buildFilterFunc(getFilterFunc, use); }); - - this.sectionFilterFunc = Computed.create(this, columnFilterFunc, this._tempRows, - (_use, filterFunc, tempRows) => this._addRowsToFilter(filterFunc, tempRows)); - - // Prune temporary rowIds that are no longer being filtered out. - this.autoDispose(columnFilterFunc.addListener(f => { - this._tempRows.set(this._tempRows.get().filter(rowId => !f(rowId))); - })); } /** @@ -68,37 +61,14 @@ export class SectionFilter extends Disposable { }); } - public addTemporaryRow(rowId: number) { - // Only add the rowId if it would otherwise be filtered out - if (!this.sectionFilterFunc.get()(rowId)) { - this._tempRows.push(rowId); - } - } - - public resetTemporaryRows() { - this._tempRows.set([]); - } - /** * Builds a filter function that combines the filter function of all the columns. You can use - * `getFilterFunc(column, colFilter)` to customize the filter func for each columns. It calls - * `getFilterFunc` right away. Also, all the rows that were added with `addTemporaryRow()` bypass - * the filter. + * `getFilterFunc(column, colFilter)` to customize the filter func for each column. It calls + * `getFilterFunc` right away. + * This also immediately resets rows that were temporarily exempted from filtering. */ public buildFilterFunc(getFilterFunc: ColFilterCB, use: UseCB) { - return this._addRowsToFilter(this._buildPlainFilterFunc(getFilterFunc, use), this._tempRows.get()); - } - - private _addRowsToFilter(filterFunc: RowFilterFunc, rows: UIRowId[]) { - return (rowId: UIRowId) => rows.includes(rowId) || (typeof rowId !== 'number') || filterFunc(rowId); - } - - /** - * Internal that helps build a filter function that combines the filter function of all - * columns. You can use `getFilterFunc(column, colFilter)` to customize the filter func for each - * column. It calls `getFilterFunc` right away. - */ - private _buildPlainFilterFunc(getFilterFunc: ColFilterCB, use: UseCB): RowFilterFunc { + this._resetExemptRows(); const filters = use(this.viewSection.filters); const funcs: Array | null> = filters.map(({filter, fieldOrColumn}) => { const colFilter = buildColFilter(use(filter), use(use(fieldOrColumn.origCol).type)); @@ -111,6 +81,6 @@ export class SectionFilter extends Disposable { return buildRowFilter(getter as RowValueFunc, filterFunc); }).filter(f => f !== null); // Filter out columns that don't have a filter - return (rowId: UIRowId) => funcs.every(f => Boolean(f && f(rowId))); + return (rowId: UIRowId) => rowId === 'new' || funcs.every(f => Boolean(f && f(rowId))); } } diff --git a/app/client/models/UnionRowSource.ts b/app/client/models/UnionRowSource.ts new file mode 100644 index 00000000..6334a0cc --- /dev/null +++ b/app/client/models/UnionRowSource.ts @@ -0,0 +1,59 @@ +import {RowList, RowListener, RowSource} from 'app/client/models/rowset'; +import {UIRowId} from "app/plugin/GristAPI"; + +export class UnionRowSource extends RowListener implements RowSource { + protected _allRows = new Map>(); + + constructor(parentRowSources: RowSource[]) { + super(); + for (const p of parentRowSources) { + this.subscribeTo(p); + } + } + + public getAllRows(): RowList { + return this._allRows.keys(); + } + + public getNumRows(): number { + return this._allRows.size; + } + + public onAddRows(rows: RowList, rowSource: RowSource) { + const outputRows = []; + for (const r of rows) { + let sources = this._allRows.get(r); + if (!sources) { + sources = new Set(); + this._allRows.set(r, sources); + outputRows.push(r); + } + sources.add(rowSource); + } + if (outputRows.length > 0) { + this.trigger('rowChange', 'add', outputRows); + } + } + + public onRemoveRows(rows: RowList, rowSource: RowSource) { + const outputRows = []; + for (const r of rows) { + const sources = this._allRows.get(r); + if (!sources) { + continue; + } + sources.delete(rowSource); + if (sources.size === 0) { + outputRows.push(r); + this._allRows.delete(r); + } + } + if (outputRows.length > 0) { + this.trigger('rowChange', 'remove', outputRows); + } + } + + public onUpdateRows(rows: RowList) { + this.trigger('rowChange', 'update', rows); + } +} diff --git a/app/client/models/rowset.ts b/app/client/models/rowset.ts index f11fcb36..c2d5960a 100644 --- a/app/client/models/rowset.ts +++ b/app/client/models/rowset.ts @@ -82,10 +82,10 @@ export class RowListener extends DisposableWithEvents { * Subscribes to the given rowSource and adds the rows currently in it. */ public subscribeTo(rowSource: RowSource): void { - this.onAddRows(rowSource.getAllRows()); + this.onAddRows(rowSource.getAllRows(), rowSource); this.listenTo(rowSource, 'rowChange', (changeType: ChangeType, rows: RowList) => { const method: ChangeMethod = _changeTypes[changeType]; - this[method](rows); + this[method](rows, rowSource); }); this.listenTo(rowSource, 'rowNotify', this.onRowNotify); } @@ -103,17 +103,17 @@ export class RowListener extends DisposableWithEvents { /** * Process row additions. To be implemented by derived classes. */ - protected onAddRows(rows: RowList) { /* no-op */ } + protected onAddRows(rows: RowList, rowSource?: RowSource) { /* no-op */ } /** * Process row removals. To be implemented by derived classes. */ - protected onRemoveRows(rows: RowList) { /* no-op */ } + protected onRemoveRows(rows: RowList, rowSource?: RowSource) { /* no-op */ } /** * Process row updates. To be implemented by derived classes. */ - protected onUpdateRows(rows: RowList) { /* no-op */ } + protected onUpdateRows(rows: RowList, rowSource?: RowSource) { /* no-op */ } /** * Derived classes may override this event to handle row notifications. By default, it re-triggers @@ -128,15 +128,6 @@ export class RowListener extends DisposableWithEvents { // MappedRowSource // ---------------------------------------------------------------------- -/** - * A trivial RowSource returning a fixed list of rows. - */ -export abstract class ArrayRowSource extends RowSource { - constructor(private _rows: UIRowId[]) { super(); } - public getAllRows(): RowList { return this._rows; } - public getNumRows(): number { return this._rows.length; } -} - /** * MappedRowSource wraps any other RowSource, and passes through all rows, replacing each row * identifier with the result of mapperFunc(row) call. @@ -773,3 +764,42 @@ function _allRowsSorted(array: T[], allRows: Set, sortedRows: Iterable, } return true; } + + +/** + * Track rows that should temporarily be visible even if they don't match filters. + * This is so that a newly added row doesn't immediately disappear, which would be confusing. + * This doesn't have much to do with BaseFilteredRowSource, it's just reusing some implementation. + */ +export class ExemptFromFilterRowSource extends BaseFilteredRowSource { + public constructor() { + super(() => false); + } + + /** + * Call this when one or more new rows are added to keep them temporarily visible. + */ + public addExemptRows(rows: RowList) { + const newRows = []; + for (const r of rows) { + if (!this._matchingRows.has(r)) { + this._matchingRows.add(r); + newRows.push(r); + } + } + if (newRows.length > 0) { + this.trigger('rowChange', 'add', newRows); + } + } + + public addExemptRow(rowId: number) { + this.addExemptRows([rowId]); + } + + /** + * Call this when linking or filters change to clear out the temporary rows. + */ + public reset() { + this.onRemoveRows(this.getAllRows()); + } +} diff --git a/app/client/ui/ColumnFilterMenu.ts b/app/client/ui/ColumnFilterMenu.ts index e59b1707..b3b3879b 100644 --- a/app/client/ui/ColumnFilterMenu.ts +++ b/app/client/ui/ColumnFilterMenu.ts @@ -54,7 +54,7 @@ export interface IFilterMenuOptions { rangeInputOptions?: IRangeInputOptions; showAllFiltersButton?: boolean; doCancel(): void; - doSave(reset: boolean): void; + doSave(): void; renderValue(key: CellValue, value: IFilterCount): DomElementArg; onClose(): void; valueParser?(val: string): any; @@ -104,7 +104,6 @@ export function columnFilterMenu(owner: IDisposableOwner, opts: IFilterMenuOptio let searchInput: HTMLInputElement; let cancel = false; - let reset = false; const filterMenu: HTMLElement = cssMenu( { tabindex: '-1' }, // Allow menu to be focused @@ -128,7 +127,7 @@ export function columnFilterMenu(owner: IDisposableOwner, opts: IFilterMenuOptio dom.cls(menuCssClass), dom.autoDispose(filterListener), // Save or cancel on disposal, which should always happen as part of closing. - dom.onDispose(() => cancel ? doCancel() : doSave(reset)), + dom.onDispose(() => cancel ? doCancel() : doSave()), dom.onKeyDown({ Enter: () => onClose(), Escape: () => onClose(), @@ -327,7 +326,6 @@ export function columnFilterMenu(owner: IDisposableOwner, opts: IFilterMenuOptio dom('div', cssPrimaryButton('Close', testId('apply-btn'), dom.on('click', () => { - reset = true; onClose(); }), ), @@ -696,16 +694,13 @@ export function createFilterMenu(params: ICreateFilterMenuParams) { model, valueCounts, onClose: () => { openCtl.close(); onClose(); }, - doSave: (reset: boolean = false) => { + doSave: () => { const spec = columnFilter.makeFilterJson(); const {viewSection} = sectionFilter; viewSection.setFilter( fieldOrColumn.origCol().origColRef(), {filter: spec} ); - if (reset) { - sectionFilter.resetTemporaryRows(); - } // Check if the save was for a new filter, and if that new filter was pinned. If it was, and // it is the second pinned filter in the section, trigger a tip that explains how multiple diff --git a/app/client/widgets/ErrorDom.ts b/app/client/widgets/ErrorDom.ts index 8559c2a1..4aae661f 100644 --- a/app/client/widgets/ErrorDom.ts +++ b/app/client/widgets/ErrorDom.ts @@ -7,6 +7,7 @@ import {dom} from 'grainjs'; export function buildErrorDom(row: DataRowModel, field: ViewFieldRec) { const value = row.cells[field.colId.peek()]; + if (value === undefined) { return null; } // Work around JS errors during field removal. const options = field.widgetOptionsJson; // The "invalid" class sets the pink background, as long as the error text is non-empty. return dom('div.field_clip.invalid', diff --git a/app/client/widgets/FieldBuilder.ts b/app/client/widgets/FieldBuilder.ts index 9139b343..f2343fdd 100644 --- a/app/client/widgets/FieldBuilder.ts +++ b/app/client/widgets/FieldBuilder.ts @@ -685,6 +685,7 @@ export class FieldBuilder extends Disposable { kd.scope(widgetObs, (widget: NewAbstractWidget) => { if (this.isDisposed()) { return null; } // Work around JS errors during field removal. const cellDom = widget ? widget.buildDom(row) : buildErrorDom(row, this.field); + if (cellDom === null) { return null; } return dom(cellDom, kd.toggleClass('has_cursor', isActive), kd.toggleClass('field-error-from-style', errorInStyle), kd.toggleClass('font-bold', fontBold), diff --git a/test/client/models/rowset.js b/test/client/models/rowset.js index c010e690..143a8a59 100644 --- a/test/client/models/rowset.js +++ b/test/client/models/rowset.js @@ -15,15 +15,15 @@ describe('rowset', function() { sinon.spy(lis, "onUpdateRows"); lis.subscribeTo(src); - assert.deepEqual(lis.onAddRows.args, [[[1, 2, 3]]]); + assert.deepEqual(lis.onAddRows.args, [[[1, 2, 3], src]]); lis.onAddRows.resetHistory(); src.trigger('rowChange', 'add', [5, 6]); src.trigger('rowChange', 'remove', [6, 1]); src.trigger('rowChange', 'update', [3, 5]); - assert.deepEqual(lis.onAddRows.args, [[[5, 6]]]); - assert.deepEqual(lis.onRemoveRows.args, [[[6, 1]]]); - assert.deepEqual(lis.onUpdateRows.args, [[[3, 5]]]); + assert.deepEqual(lis.onAddRows.args, [[[5, 6], src]]); + assert.deepEqual(lis.onRemoveRows.args, [[[6, 1], src]]); + assert.deepEqual(lis.onUpdateRows.args, [[[3, 5], src]]); }); it('should support subscribing to multiple sources', function() { @@ -40,18 +40,18 @@ describe('rowset', function() { lis.subscribeTo(src1); lis.subscribeTo(src2); - assert.deepEqual(lis.onAddRows.args, [[[1, 2, 3]], [["a", "b", "c"]]]); + assert.deepEqual(lis.onAddRows.args, [[[1, 2, 3], src1], [["a", "b", "c"], src2]]); src1.trigger('rowChange', 'update', [2, 3]); src2.trigger('rowChange', 'remove', ["b"]); - assert.deepEqual(lis.onUpdateRows.args, [[[2, 3]]]); - assert.deepEqual(lis.onRemoveRows.args, [[["b"]]]); + assert.deepEqual(lis.onUpdateRows.args, [[[2, 3], src1]]); + assert.deepEqual(lis.onRemoveRows.args, [[["b"], src2]]); lis.onAddRows.resetHistory(); lis.unsubscribeFrom(src1); src1.trigger('rowChange', 'add', [4]); src2.trigger('rowChange', 'add', ["d"]); - assert.deepEqual(lis.onAddRows.args, [[["d"]]]); + assert.deepEqual(lis.onAddRows.args, [[["d"], src2]]); }); }); diff --git a/test/fixtures/docs/SelectBySummary.grist b/test/fixtures/docs/SelectBySummary.grist index 453c483fad3d3776eb1fcdd04de12ae0e9cf850e..bb28532c0b206b7ffc06614fc046a4bbfcfba776 100644 GIT binary patch delta 2541 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

P1>l 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 P7?@*Vj)DJgG4THYGP<@y diff --git a/test/nbrowser/SelectByRefList.ts b/test/nbrowser/SelectByRefList.ts index a80a8610..3f7e2d52 100644 --- a/test/nbrowser/SelectByRefList.ts +++ b/test/nbrowser/SelectByRefList.ts @@ -106,10 +106,9 @@ describe('SelectByRefList', function() { ], ]; // LINKTARGET is being filtered by the `id` column - // There's no column to set a default value for that would help - // The newly added row disappears immediately + // There's no column to set a default value for. // TODO should we be appending the new row ID to the reflist in the source table? - newRow = ['', '', '']; + newRow = ['99', '', '']; await checkSelectingRecords('REFLISTS • LinkTarget_reflist', sourceData, newRow); // Similar to the above but indirect. We connect LINKTARGET.ref and REFLISTS.reflist, diff --git a/test/nbrowser/SelectBySummary.ts b/test/nbrowser/SelectBySummary.ts index 30f81415..a2bd492e 100644 --- a/test/nbrowser/SelectBySummary.ts +++ b/test/nbrowser/SelectBySummary.ts @@ -118,17 +118,60 @@ describe('SelectBySummary', function() { // so those values will be used as defaults in the source table await gu.getCell({section: 'TABLE1 [by onetwo, choices]', col: 'rownum', rowNum: 2}).click(); - // Create a new record with rownum=99 + // Create new records with rownum = 99 and 100 await gu.getCell({section: 'TABLE1', col: 'rownum', rowNum: 3}).click(); await gu.enterCell('99'); + await gu.enterCell('100'); assert.deepEqual( await gu.getVisibleGridCells({ section: 'TABLE1', cols: ['onetwo', 'choices', 'rownum'], - rowNums: [3], + rowNums: [1, 2, 3, 4, 5], }), - ['2', 'a', '99'], + [ + '2', 'a', '2', + '2', 'a\nb', '6', + // The two rows we just added. + // The filter link sets the default value 'a'. + // It can't set a default value for 'onetwo' because that's a formula column. + // This first row doesn't match the filter link, but it still shows temporarily. + '1', 'a', '99', + '2', 'a', '100', + '', '', '', // new row + ], + ); + + // Select a different record in the summary table, sanity check the linked table. + await gu.getCell({section: 'TABLE1 [by onetwo, choices]', col: 'rownum', rowNum: 3}).click(); + assert.deepEqual( + await gu.getVisibleGridCells({ + section: 'TABLE1', + cols: ['onetwo', 'choices', 'rownum'], + rowNums: [1, 2, 3], + }), + [ + '1', 'b', '3', + '1', 'a\nb', '5', + '', '', '', // new row + ], + ); + + // Now go back to the previously selected summary table row. + await gu.getCell({section: 'TABLE1 [by onetwo, choices]', col: 'rownum', rowNum: 2}).click(); + assert.deepEqual( + await gu.getVisibleGridCells({ + section: 'TABLE1', + cols: ['onetwo', 'choices', 'rownum'], + rowNums: [1, 2, 3, 4], + }), + [ + '2', 'a', '2', + '2', 'a\nb', '6', + // The row ['1', 'a', '99'] is now filtered out as normal. + '2', 'a', '100', + '', '', '', // new row + ], ); }) );