mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Filter rows based on linked widgets when exporting view
Summary: Fixes a problem reported here: https://community.getgrist.com/t/exporting-the-records-in-a-linked-view/2556/4 The download CSV/Excel link now contains an additional `linkingFilter` URL parameter containing JSON-encoded `filters` and `operations`. This object is originally created in the frontend in `LinkingState`, and previously it was only used internally in the frontend. It would make its way via `QuerySetManager` to `QuerySet.getFilterFunc` where the actual filtering logic happened. Now most of that logic has been moved to a similar function in `common`. The new function works with a new interface `ColumnGettersByColId` which abstract over the different ways data is accessed in the client and server in this context. There's no significant new logic in the diff, just refactoring and wiring. Test Plan: Expanded two `nbrowser/SelectBy*.ts` test suites to also check the contents of a downloaded CSV in different linking scenarios. Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D3961
This commit is contained in:
@@ -198,6 +198,12 @@ async function checkSelectingRecords(selectBy: string, sourceData: string[][], n
|
||||
}),
|
||||
sourceGroup
|
||||
);
|
||||
const csvCells = await gu.downloadSectionCsvGridCells('LINKTARGET');
|
||||
const expectedCsvCells = sourceGroup.slice(0, -3) // remove 'add new' row of empty strings
|
||||
// visible cells text uses newlines to separate list items,
|
||||
// CSV export uses commas
|
||||
.map(s => s.replace("\n", ", "));
|
||||
assert.deepEqual(csvCells, expectedCsvCells);
|
||||
}
|
||||
|
||||
for (let i = 0; i < sourceData.length; i++) {
|
||||
|
||||
@@ -232,9 +232,6 @@ async function checkSelectingRecords(
|
||||
const targetGroup = targetData[targetGroupIndex];
|
||||
const countCell = await gu.getCell({section: summarySection, col: 'count', rowNum: targetGroupIndex + 1});
|
||||
const numTargetRows = targetGroup.length / 3;
|
||||
if (targetSection === 'TABLE1') {
|
||||
assert.equal(await countCell.getText(), numTargetRows.toString());
|
||||
}
|
||||
await countCell.click();
|
||||
assert.deepEqual(
|
||||
await gu.getVisibleGridCells({
|
||||
@@ -244,6 +241,13 @@ async function checkSelectingRecords(
|
||||
}),
|
||||
targetGroup
|
||||
);
|
||||
if (targetSection === 'TABLE1') {
|
||||
assert.equal(await countCell.getText(), numTargetRows.toString());
|
||||
const csvCells = await gu.downloadSectionCsvGridCells(targetSection);
|
||||
// visible cells text uses newlines to separate list items, CSV export uses commas
|
||||
const expectedCsvCells = targetGroup.map(s => s.replace("\n", ", "));
|
||||
assert.deepEqual(csvCells, expectedCsvCells);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < targetData.length; i++) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { assert, driver as driverOrig, error, Key, WebElement, WebElementPromise
|
||||
import { stackWrapFunc, stackWrapOwnMethods, WebDriver } from 'mocha-webdriver';
|
||||
import * as path from 'path';
|
||||
|
||||
import {csvDecodeRow} from 'app/common/csvFormat';
|
||||
import { decodeUrl } from 'app/common/gristUrls';
|
||||
import { FullUser, UserProfile } from 'app/common/LoginSessionAPI';
|
||||
import { resetOrg } from 'app/common/resetOrg';
|
||||
@@ -29,6 +30,7 @@ import { server } from 'test/nbrowser/testServer';
|
||||
import { Cleanup } from 'test/nbrowser/testUtils';
|
||||
import * as testUtils from 'test/server/testUtils';
|
||||
import type { AssertionError } from 'assert';
|
||||
import axios from 'axios';
|
||||
|
||||
// tslint:disable:no-namespace
|
||||
// Wrap in a namespace so that we can apply stackWrapOwnMethods to all the exports together.
|
||||
@@ -3078,6 +3080,24 @@ export function produceUncaughtError(message: string) {
|
||||
}, message);
|
||||
}
|
||||
|
||||
export async function downloadSectionCsv(
|
||||
section: string, headers: any = {Authorization: 'Bearer api_key_for_chimpy'}
|
||||
) {
|
||||
await openSectionMenu("viewLayout", section);
|
||||
const href = await driver.findWait('.test-download-section', 1000).getAttribute('href');
|
||||
await driver.sendKeys(Key.ESCAPE); // Close section menu
|
||||
const resp = await axios.get(href, { responseType: 'text', headers });
|
||||
return resp.data as string;
|
||||
}
|
||||
|
||||
export async function downloadSectionCsvGridCells(
|
||||
section: string, headers: any = {Authorization: 'Bearer api_key_for_chimpy'}
|
||||
): Promise<string[]> {
|
||||
const csvString = await downloadSectionCsv(section, headers);
|
||||
const csvRows = csvString.split('\n').slice(1).map(csvDecodeRow);
|
||||
return ([] as string[]).concat(...csvRows);
|
||||
}
|
||||
|
||||
} // end of namespace gristUtils
|
||||
|
||||
stackWrapOwnMethods(gristUtils);
|
||||
|
||||
Reference in New Issue
Block a user