mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
75d979abdb
Summary: In a selector table, when a selected row is filtered out of view, linked widgets should update based on the newly selected row. There were a few bugs that contributed to this wrong behavior: - Gridview wasn't subscribing to the current row id, and the row with id 'new' was being converted to the first row - Cursor was keeping track of the currently selected row id, it was hiding a problem behind the proper rowIndex - Undo/redo somehow leveraged the wrong rowId from the cursor during the position restore. The `No data` text was also changed to be more meaningful. Test Plan: Added and updated. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3937
216 lines
9.5 KiB
TypeScript
216 lines
9.5 KiB
TypeScript
import {assert, WebElement} from 'mocha-webdriver';
|
|
import * as gu from 'test/nbrowser/gristUtils';
|
|
import {setupTestSuite} from 'test/nbrowser/testUtils';
|
|
|
|
describe('LinkingSelector', function() {
|
|
this.timeout(20000);
|
|
|
|
const cleanup = setupTestSuite({team: true});
|
|
let session: gu.Session;
|
|
let docId: string;
|
|
|
|
afterEach(() => gu.checkForErrors());
|
|
|
|
before(async function() {
|
|
session = await gu.session().login();
|
|
docId = (await session.tempDoc(cleanup, 'Class Enrollment.grist')).id;
|
|
});
|
|
|
|
it('should update linked grid view on filter change', async function() {
|
|
// Add new page with summarized classes by Start_Date.
|
|
await gu.addNewPage('Table', 'Classes', {
|
|
summarize: ['Start_Date'],
|
|
});
|
|
|
|
// Add a new linked widget that shows classes by this date.
|
|
await gu.addNewSection('Table', 'Classes', {
|
|
selectBy: 'CLASSES [by Start_Date]'
|
|
});
|
|
|
|
// Click on the first date.
|
|
await gu.getCell('Start_Date', 1, 'CLASSES [by Start_Date]').click();
|
|
// Make sure we know which row is selected.
|
|
assert.equal(await gu.getCell('Start_Date', 1).getText(), '2018-09-13');
|
|
|
|
// Show only Start_Date in the linked section.
|
|
await gu.selectSectionByTitle('CLASSES');
|
|
await gu.openWidgetPanel();
|
|
await gu.selectAllVisibleColumns();
|
|
await gu.toggleVisibleColumn('Start_Date');
|
|
await gu.hideVisibleColumns();
|
|
|
|
// Make sure we see the same date.
|
|
await gu.getCell('Start_Date', 1, 'CLASSES').click();
|
|
assert.equal(await gu.getCell('Start_Date', 1).getText(), '2018-09-13');
|
|
|
|
// Now filter the summary table to not show the selected date.
|
|
await gu.selectSectionByTitle('CLASSES [by Start_Date]');
|
|
await gu.filterBy('Start_Date', false, ['2018-09-14']);
|
|
// Make sure this is filtered out.
|
|
assert.equal(await gu.getCell('Start_Date', 1, 'CLASSES [by Start_Date]').getText(), '2018-09-14');
|
|
// Make sure the linked section is updated.
|
|
assert.equal(await gu.getCell('Start_Date', 1, 'CLASSES').getText(), '2018-09-14');
|
|
});
|
|
|
|
it('should update linked card on filter change with same record linking', async function() {
|
|
// Test the same for the card view and same record linking (it uses different code).
|
|
// Add a list and a card view of the same table and link them together.
|
|
await gu.addNewPage('Table', 'Classes');
|
|
|
|
// Hide all columns in the list view.
|
|
await gu.openWidgetPanel();
|
|
await gu.selectAllVisibleColumns();
|
|
await gu.toggleVisibleColumn('Start_Date');
|
|
await gu.hideVisibleColumns();
|
|
|
|
// Rename it to list.
|
|
await gu.renameActiveSection('List');
|
|
|
|
// Now add a card view.
|
|
await gu.addNewSection('Card', 'Classes', {
|
|
'selectBy': 'List'
|
|
});
|
|
await gu.renameActiveSection('Card');
|
|
await gu.selectAllVisibleColumns();
|
|
await gu.toggleVisibleColumn('Start_Date');
|
|
await gu.hideVisibleColumns();
|
|
|
|
// Select the second row.
|
|
await gu.selectSectionByTitle('List');
|
|
await gu.getCell('Start_Date', 2).click();
|
|
// Make sure we know the second row is selected.
|
|
assert.equal(await gu.getCell('Start_Date', 2).getText(), '2018-09-14');
|
|
assert.equal((await gu.getCursorPosition()).rowNum, 2);
|
|
|
|
// Make sure it was also updated in the card view.
|
|
await gu.selectSectionByTitle('Card');
|
|
assert.equal(await gu.getDetailCell('Start_Date', 1).getText(), '2018-09-14');
|
|
|
|
// Now filter it out, using pinned filters (to not alter the cursor position).
|
|
await gu.selectSectionByTitle('List');
|
|
// Pin the filter to the panel by just adding it (it is pinned by default).
|
|
await gu.sortAndFilter()
|
|
.then(x => x.addColumn())
|
|
.then(x => x.clickColumn('Start_Date'))
|
|
.then(x => x.close())
|
|
.then(x => x.click());
|
|
|
|
// Open the pinned filter, and filter out the date.
|
|
await gu.openPinnedFilter('Start_Date')
|
|
.then(x => x.toggleValue('2018-09-14'))
|
|
.then(x => x.close());
|
|
|
|
// Make sure we see it as the first row
|
|
assert.equal(await gu.getCell('Start_Date', 1).getText(), '2018-09-13');
|
|
assert.equal(await gu.getCell('Start_Date', 2).getText(), '2019-01-27');
|
|
// And cursor was moved to the first row.
|
|
assert.equal((await gu.getCursorPosition()).rowNum, 1);
|
|
// Make sure the card view is updated.
|
|
await gu.selectSectionByTitle('Card');
|
|
assert.equal(await gu.getDetailCell('Start_Date', 1).getText(), '2018-09-13');
|
|
});
|
|
|
|
it('should update linked section for the first row', async function() {
|
|
// There was a bug here. First row wasn't somehow triggering the linked section to update itself,
|
|
// when it was filtered out, for self-linking.
|
|
await gu.selectSectionByTitle('List');
|
|
await gu.removeFilters();
|
|
|
|
// Select first row.
|
|
await gu.getCell('Start_Date', 1).click();
|
|
// Make sure we know what we selected.
|
|
assert.equal(await gu.getCell('Start_Date', 1, 'List').getText(), '2018-09-13');
|
|
// Make sure that card reflects it.
|
|
assert.equal(await gu.getDetailCell('Start_Date', 1, 'Card').getText(), '2018-09-13');
|
|
// Now unfilter it.
|
|
await gu.openColumnFilter('Start_Date')
|
|
.then(x => x.toggleValue('2018-09-13'))
|
|
.then(x => x.close());
|
|
// Make sure that List is updated in the first row.
|
|
assert.equal(await gu.getCell('Start_Date', 1, 'List').getText(), '2018-09-14');
|
|
// Make sure that Card is updated accordingly.
|
|
assert.equal(await gu.getDetailCell('Start_Date', 1, 'Card').getText(), '2018-09-14');
|
|
});
|
|
|
|
it('should mark selected row used for linking', async function() {
|
|
await session.loadDoc(`/doc/${docId}/p/7`);
|
|
|
|
const families = gu.getSection('FAMILIES');
|
|
const students = gu.getSection('STUDENTS');
|
|
const enrollments = gu.getSection('ENROLLMENTS');
|
|
|
|
// Initially FAMILIES first row should be selected and marked as selector.
|
|
assert.deepEqual(await getCursorSelectorInfo(families), {linkSelector: 1, cursor: {rowNum: 1, col: 0}});
|
|
assert.deepEqual(await gu.getActiveCell().getText(), 'Fin');
|
|
|
|
// STUDENTS shows appropriate records.
|
|
assert.deepEqual(await gu.getVisibleGridCells({section: students, col: 'First_Name', rowNums: [1, 2, 3, 4]}),
|
|
['Brockie', 'Care', 'Alfonso', '']);
|
|
|
|
// STUDENTS also has a selector row, but no active cursor.
|
|
assert.deepEqual(await getCursorSelectorInfo(students), {linkSelector: 1, cursor: false});
|
|
assert.deepEqual(await getCursorSelectorInfo(enrollments), {linkSelector: false, cursor: false});
|
|
|
|
// Select a different Family
|
|
await gu.getCell({section: families, rowNum: 3, col: 'First_Name'}).click();
|
|
assert.deepEqual(await gu.getActiveCell().getText(), 'Pat');
|
|
assert.deepEqual(await getCursorSelectorInfo(families), {linkSelector: 3, cursor: {rowNum: 3, col: 0}});
|
|
|
|
// STUDENTS shows new values, has a new selector row
|
|
assert.deepEqual(await gu.getVisibleGridCells({section: students, col: 'First_Name', rowNums: [1, 2, 3]}),
|
|
['Mordy', 'Noam', '']);
|
|
assert.deepEqual(await getCursorSelectorInfo(students), {linkSelector: 1, cursor: false});
|
|
|
|
// STUDENTS Card shows appropriate value
|
|
assert.deepEqual(await gu.getVisibleDetailCells(
|
|
{section: 'STUDENTS Card', cols: ['First_Name', 'Policy_Number'], rowNums: [1]}),
|
|
['Mordy', '468617']);
|
|
|
|
// Select another student
|
|
await gu.getCell({section: students, rowNum: 2, col: 'Last_Name'}).click();
|
|
assert.deepEqual(await getCursorSelectorInfo(students), {linkSelector: 2, cursor: {rowNum: 2, col: 1}});
|
|
assert.deepEqual(await gu.getVisibleDetailCells(
|
|
{section: 'STUDENTS Card', cols: ['First_Name', 'Policy_Number'], rowNums: [1]}),
|
|
['Noam', '663208']);
|
|
|
|
// There is no longer a cursor in FAMILIES, but still a link-selector.
|
|
assert.deepEqual(await getCursorSelectorInfo(families), {linkSelector: 3, cursor: false});
|
|
|
|
// Enrollments is linked to the selected student, but still shows no cursor or selector.
|
|
assert.deepEqual(await getCursorSelectorInfo(enrollments), {linkSelector: false, cursor: false});
|
|
assert.deepEqual(await gu.getVisibleGridCells({section: enrollments, col: 'Class', rowNums: [1, 2, 3]}),
|
|
['2019F-Yoga', '2019S-Yoga', '']);
|
|
|
|
// Click into an enrollment; it will become the only section with a cursor.
|
|
await gu.getCell({section: enrollments, rowNum: 2, col: 'Status'}).click();
|
|
assert.deepEqual(await getCursorSelectorInfo(enrollments), {linkSelector: false, cursor: {rowNum: 2, col: 2}});
|
|
assert.deepEqual(await getCursorSelectorInfo(students), {linkSelector: 2, cursor: false});
|
|
assert.deepEqual(await getCursorSelectorInfo(families), {linkSelector: 3, cursor: false});
|
|
});
|
|
|
|
it('should show correct state on reload after cursors are positioned', async function() {
|
|
await gu.reloadDoc();
|
|
const families = gu.getSection('FAMILIES');
|
|
const students = gu.getSection('STUDENTS');
|
|
const enrollments = gu.getSection('ENROLLMENTS');
|
|
assert.deepEqual(await getCursorSelectorInfo(enrollments), {linkSelector: false, cursor: {rowNum: 2, col: 2}});
|
|
assert.deepEqual(await getCursorSelectorInfo(students), {linkSelector: 2, cursor: false});
|
|
assert.deepEqual(await getCursorSelectorInfo(families), {linkSelector: 3, cursor: false});
|
|
});
|
|
});
|
|
|
|
|
|
interface CursorSelectorInfo {
|
|
linkSelector: false | number;
|
|
cursor: false | {rowNum: number, col: number};
|
|
}
|
|
|
|
async function getCursorSelectorInfo(section: WebElement): Promise<CursorSelectorInfo> {
|
|
const hasCursor = await section.find('.active_cursor').isPresent();
|
|
const hasSelector = await section.find('.link_selector_row').isPresent();
|
|
return {
|
|
linkSelector: hasSelector && Number(await section.find('.link_selector_row .gridview_data_row_num').getText()),
|
|
cursor: hasCursor && await gu.getCursorPosition(section),
|
|
};
|
|
}
|