@rickcedwhat/playwright-smart-table 6.21.0 → 6.22.0-next.28cae60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/rowFinder.d.ts +3 -3
- package/dist/engine/rowFinder.js +4 -6
- package/dist/engine/tableIteration.d.ts +1 -1
- package/dist/engine/tableIteration.js +4 -3
- package/dist/index.d.ts +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/plugins/index.d.ts +9 -9
- package/dist/presets/mui.js +33 -36
- package/dist/smartRow.js +14 -3
- package/dist/strategies/filter.js +2 -3
- package/dist/strategies/viewport.js +26 -10
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +68 -32
- package/dist/types.d.ts +66 -32
- package/dist/useTable.js +35 -26
- package/dist/utils/cssSelector.d.ts +14 -0
- package/dist/utils/cssSelector.js +28 -0
- package/dist/utils/loadingWait.d.ts +15 -0
- package/dist/utils/loadingWait.js +43 -0
- package/dist/utils/pageIndex.d.ts +12 -0
- package/dist/utils/pageIndex.js +19 -0
- package/dist/utils/resolveCellLocator.d.ts +2 -2
- package/dist/utils/resolveCellLocator.js +4 -4
- package/dist/utils/smartRowInternals.d.ts +14 -0
- package/dist/utils/smartRowInternals.js +6 -0
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ export declare class RowFinder<T = any> {
|
|
|
13
13
|
private tableState;
|
|
14
14
|
private advancePage;
|
|
15
15
|
private resolve;
|
|
16
|
-
constructor(rootLocator: Locator, config: FinalTableConfig, resolve: (item: Selector, parent: Locator | Page) => Locator, filterEngine: FilterEngine, tableMapper: TableMapper, makeSmartRow: (loc: Locator, map: Map<string, number>, index: number | undefined, tablePageIndex?: number, barrier?: NavigationBarrier,
|
|
16
|
+
constructor(rootLocator: Locator, config: FinalTableConfig, resolve: (item: Selector, parent: Locator | Page) => Locator, filterEngine: FilterEngine, tableMapper: TableMapper, makeSmartRow: (loc: Locator, map: Map<string, number>, index: number | undefined, tablePageIndex?: number, barrier?: NavigationBarrier, healSelector?: string) => SmartRow<T>, tableState?: {
|
|
17
17
|
currentPageIndex: number;
|
|
18
18
|
}, advancePage?: (useBulk: boolean) => Promise<boolean>);
|
|
19
19
|
private splitFilters;
|
|
@@ -38,8 +38,8 @@ export declare class RowFinder<T = any> {
|
|
|
38
38
|
* every row calling elementHandle() + evaluate() per row (O(n) CDP roundtrips, and
|
|
39
39
|
* elementHandle() is soft-deprecated). We resolve the target once and let evaluateAll
|
|
40
40
|
* compare it against the full row set in the browser. The row set is resolved through the
|
|
41
|
-
* same selector/scope as everywhere else, so a string
|
|
42
|
-
*
|
|
41
|
+
* same selector/scope as everywhere else, so a string or function rowSelector behave
|
|
42
|
+
* identically. (#350)
|
|
43
43
|
*/
|
|
44
44
|
private throwIfAmbiguous;
|
|
45
45
|
private scanDomPosition;
|
package/dist/engine/rowFinder.js
CHANGED
|
@@ -9,6 +9,7 @@ const navigationBarrier_1 = require("../utils/navigationBarrier");
|
|
|
9
9
|
const rowResolution_1 = require("./rowResolution");
|
|
10
10
|
const resolveCellLocator_1 = require("../utils/resolveCellLocator");
|
|
11
11
|
const scanPages_1 = require("./scanPages");
|
|
12
|
+
const loadingWait_1 = require("../utils/loadingWait");
|
|
12
13
|
class RowFinder {
|
|
13
14
|
constructor(rootLocator, config, resolve, filterEngine, tableMapper, makeSmartRow, tableState = { currentPageIndex: 0 }, advancePage = async () => false) {
|
|
14
15
|
this.rootLocator = rootLocator;
|
|
@@ -131,10 +132,7 @@ class RowFinder {
|
|
|
131
132
|
page: this.rootLocator.page(),
|
|
132
133
|
resolve: this.resolve
|
|
133
134
|
};
|
|
134
|
-
|
|
135
|
-
(0, debugUtils_1.logDebug)(this.config, 'verbose', 'Table is loading... waiting');
|
|
136
|
-
await this.rootLocator.page().waitForTimeout(200);
|
|
137
|
-
}
|
|
135
|
+
await (0, loadingWait_1.waitWhileTableLoading)(this.config, context, this.rootLocator.page(), 'waitForTableReady');
|
|
138
136
|
}
|
|
139
137
|
async findRows(filters = {}, options) {
|
|
140
138
|
var _a, _b, _c;
|
|
@@ -271,8 +269,8 @@ class RowFinder {
|
|
|
271
269
|
* every row calling elementHandle() + evaluate() per row (O(n) CDP roundtrips, and
|
|
272
270
|
* elementHandle() is soft-deprecated). We resolve the target once and let evaluateAll
|
|
273
271
|
* compare it against the full row set in the browser. The row set is resolved through the
|
|
274
|
-
* same selector/scope as everywhere else, so a string
|
|
275
|
-
*
|
|
272
|
+
* same selector/scope as everywhere else, so a string or function rowSelector behave
|
|
273
|
+
* identically. (#350)
|
|
276
274
|
*/
|
|
277
275
|
async throwIfAmbiguous(rows, filters, map) {
|
|
278
276
|
const sampleData = [];
|
|
@@ -7,7 +7,7 @@ export interface TableIterationEnv<T = any> {
|
|
|
7
7
|
getRowLocators: () => Locator;
|
|
8
8
|
getMap: () => Map<string, number>;
|
|
9
9
|
advancePage: (useBulk: boolean) => Promise<boolean>;
|
|
10
|
-
makeSmartRow: (rowLocator: Locator, map: Map<string, number>, rowIndex: number, tablePageIndex?: number, barrier?: NavigationBarrier,
|
|
10
|
+
makeSmartRow: (rowLocator: Locator, map: Map<string, number>, rowIndex: number, tablePageIndex?: number, barrier?: NavigationBarrier, healSelector?: string) => SmartRow<T>;
|
|
11
11
|
createSmartRowArray: (rows: SmartRow<T>[]) => SmartRowArray<T>;
|
|
12
12
|
config: FinalTableConfig<T>;
|
|
13
13
|
getPage: () => Page;
|
|
@@ -9,6 +9,7 @@ const navigationBarrier_1 = require("../utils/navigationBarrier");
|
|
|
9
9
|
const mutex_1 = require("../utils/mutex");
|
|
10
10
|
const rowResolution_1 = require("./rowResolution");
|
|
11
11
|
const scanPages_1 = require("./scanPages");
|
|
12
|
+
const smartRowInternals_1 = require("../utils/smartRowInternals");
|
|
12
13
|
function log(config, msg) {
|
|
13
14
|
(0, debugUtils_1.logDebug)(config, 'verbose', msg);
|
|
14
15
|
}
|
|
@@ -28,8 +29,8 @@ async function runMap(env, callback, options = {}, label = 'map') {
|
|
|
28
29
|
const effectiveMaxPages = (_a = options.maxPages) !== null && _a !== void 0 ? _a : env.config.maxPages;
|
|
29
30
|
const dedupeStrategy = (_b = options.dedupe) !== null && _b !== void 0 ? _b : env.config.strategies.dedupe;
|
|
30
31
|
const dedupeKeys = dedupeStrategy ? new Set() : null;
|
|
31
|
-
|
|
32
|
-
const concurrency = (_d = (_c = options.concurrency) !== null && _c !== void 0 ? _c : env.config.concurrency) !== null && _d !== void 0 ? _d :
|
|
32
|
+
// Sequential by default for all iteration labels (#434) — parallel is opt-in for read-only maps.
|
|
33
|
+
const concurrency = (_d = (_c = options.concurrency) !== null && _c !== void 0 ? _c : env.config.concurrency) !== null && _d !== void 0 ? _d : 'sequential';
|
|
33
34
|
const useBarrier = concurrency === 'synchronized';
|
|
34
35
|
// Mutex must not pair with the navigation barrier: synchronized mode needs every row
|
|
35
36
|
// to enter barrier.sync concurrently; serializing callbacks here deadlocks (first row waits
|
|
@@ -112,7 +113,7 @@ async function runMap(env, callback, options = {}, label = 'map') {
|
|
|
112
113
|
const sr = env.makeSmartRow(pageRows[idx], map, logicalIndex, env.getCurrentPageIndex(), barrier, resolved === null || resolved === void 0 ? void 0 : resolved.selector);
|
|
113
114
|
// Mark as part of an iteration batch so toJSON's #366 re-pin uses rescan-only recovery
|
|
114
115
|
// (no scroll-back) — scrolling here would disrupt sibling rows' positional locators.
|
|
115
|
-
sr._inBatch = true;
|
|
116
|
+
(0, smartRowInternals_1.internals)(sr)._inBatch = true;
|
|
116
117
|
return sr;
|
|
117
118
|
}));
|
|
118
119
|
// enumIndex = visit-order counter (ctx.index); row.rowIndex = logical (ctx.rowIndex).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { PLAYWRIGHT_SMART_TABLE_VERSION } from './packageVersion';
|
|
2
2
|
export { useTable } from './useTable';
|
|
3
|
-
export type { TableConfig, TableResult, SmartRow, SmartCell, Selector, FilterValue, PaginationPrimitives, SortingStrategy, FillOptions, RowIterationContext, RowIterationOptions, TableContext, StrategyContext, BeforeCellReadFn, GetCellLocatorFn, GetActiveCellFn, DebugConfig, SyntheticColumnDef, ColumnOverride, ColumnOverrideReadContext, TableStrategies, LoadingStrategy, ViewportStrategy, FilterStrategy, NavigationPrimitives, DedupeStrategy, ContentReadyStrategy, FillStrategy, PaginationStrategy, HeaderStrategy, } from './types';
|
|
3
|
+
export type { TableConfig, TableResult, SmartRow, SmartCell, Selector, TableSelector, FilterValue, PaginationPrimitives, SortingStrategy, FillOptions, RowIterationContext, RowIterationOptions, TableContext, StrategyContext, BeforeCellReadFn, GetCellLocatorFn, GetActiveCellFn, DebugConfig, SyntheticColumnDef, ColumnOverride, ColumnOverrideReadContext, TableStrategies, LoadingStrategy, ViewportStrategy, FilterStrategy, NavigationPrimitives, DedupeStrategy, ContentReadyStrategy, FillStrategy, PaginationStrategy, HeaderStrategy, } from './types';
|
|
4
4
|
export { Strategies } from './strategies';
|
|
5
5
|
export * as presets from './presets';
|
|
6
6
|
/**
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Generated by scripts/embed-version.mjs from package.json
|
|
4
4
|
*/
|
|
5
5
|
/** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
|
|
6
|
-
export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.
|
|
6
|
+
export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.22.0-next.28cae60";
|
package/dist/packageVersion.js
CHANGED
|
@@ -6,4 +6,4 @@ exports.PLAYWRIGHT_SMART_TABLE_VERSION = void 0;
|
|
|
6
6
|
* Generated by scripts/embed-version.mjs from package.json
|
|
7
7
|
*/
|
|
8
8
|
/** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
|
|
9
|
-
exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.
|
|
9
|
+
exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.22.0-next.28cae60";
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -27,9 +27,9 @@ export declare const Plugins: {
|
|
|
27
27
|
};
|
|
28
28
|
pagination: import("..").PaginationPrimitives;
|
|
29
29
|
};
|
|
30
|
-
headerSelector?:
|
|
31
|
-
rowSelector?:
|
|
32
|
-
cellSelector?:
|
|
30
|
+
headerSelector?: import("..").TableSelector | undefined;
|
|
31
|
+
rowSelector?: import("..").TableSelector | undefined;
|
|
32
|
+
cellSelector?: import("..").TableSelector | undefined;
|
|
33
33
|
maxPages?: number | undefined;
|
|
34
34
|
concurrency?: import("../types").RowIterationMode | undefined;
|
|
35
35
|
headerTransformer?: ((args: {
|
|
@@ -68,9 +68,9 @@ export declare const Plugins: {
|
|
|
68
68
|
locator: any;
|
|
69
69
|
} | null>;
|
|
70
70
|
};
|
|
71
|
-
headerSelector?:
|
|
72
|
-
rowSelector?:
|
|
73
|
-
cellSelector?:
|
|
71
|
+
headerSelector?: import("..").TableSelector | undefined;
|
|
72
|
+
rowSelector?: import("..").TableSelector | undefined;
|
|
73
|
+
cellSelector?: import("..").TableSelector | undefined;
|
|
74
74
|
maxPages?: number | undefined;
|
|
75
75
|
concurrency?: import("../types").RowIterationMode | undefined;
|
|
76
76
|
headerTransformer?: ((args: {
|
|
@@ -93,9 +93,9 @@ export declare const Plugins: {
|
|
|
93
93
|
*/
|
|
94
94
|
MUI: {
|
|
95
95
|
Strategies: import("..").TableStrategies | undefined;
|
|
96
|
-
headerSelector?:
|
|
97
|
-
rowSelector?:
|
|
98
|
-
cellSelector?:
|
|
96
|
+
headerSelector?: import("..").TableSelector | undefined;
|
|
97
|
+
rowSelector?: import("..").TableSelector | undefined;
|
|
98
|
+
cellSelector?: import("..").TableSelector | undefined;
|
|
99
99
|
maxPages?: number | undefined;
|
|
100
100
|
concurrency?: import("../types").RowIterationMode | undefined;
|
|
101
101
|
headerTransformer?: ((args: {
|
package/dist/presets/mui.js
CHANGED
|
@@ -4,6 +4,12 @@ exports.muiDataGrid = exports.muiTable = void 0;
|
|
|
4
4
|
exports.createMuiTable = createMuiTable;
|
|
5
5
|
exports.createMuiDataGrid = createMuiDataGrid;
|
|
6
6
|
const debugUtils_1 = require("../utils/debugUtils");
|
|
7
|
+
const cssSelector_1 = require("../utils/cssSelector");
|
|
8
|
+
// Fallbacks for in-browser queries when the configured selector is a function.
|
|
9
|
+
// Only DataGrid rows carry data-rowindex, so this can't match cells or headers.
|
|
10
|
+
const MUI_ROW_CSS = '[data-rowindex]';
|
|
11
|
+
const MUI_HEADER_CSS = '.MuiDataGrid-columnHeader';
|
|
12
|
+
const cssOr = (selector, fallback) => typeof selector === 'string' ? selector : fallback;
|
|
7
13
|
const DEFAULT_LABELS = {
|
|
8
14
|
nextPage: 'Go to next page',
|
|
9
15
|
previousPage: 'Go to previous page',
|
|
@@ -146,22 +152,14 @@ function createMuiTable(opts) {
|
|
|
146
152
|
return 'asc';
|
|
147
153
|
return 'none';
|
|
148
154
|
},
|
|
149
|
-
doSort: async ({ columnName,
|
|
150
|
-
|
|
155
|
+
doSort: async ({ columnName, context }) => {
|
|
156
|
+
// Trigger-only: core `sorting.apply` owns retries + state checks (#434).
|
|
151
157
|
if (!context.getHeaderCell)
|
|
152
158
|
return;
|
|
153
159
|
const header = await context.getHeaderCell(columnName);
|
|
154
160
|
const sortLabel = header.locator('.MuiTableSortLabel-root').first();
|
|
155
161
|
const target = await sortLabel.isVisible().catch(() => false) ? sortLabel : header;
|
|
156
|
-
|
|
157
|
-
let attempts = 0;
|
|
158
|
-
// Click until the state matches the target direction, max 3 times (none -> asc -> desc)
|
|
159
|
-
while (current !== direction && attempts < 3) {
|
|
160
|
-
await target.click();
|
|
161
|
-
await context.page.waitForTimeout(100);
|
|
162
|
-
current = await ((_b = context.config.strategies.sorting) === null || _b === void 0 ? void 0 : _b.getSortState({ columnName, context })) || 'none';
|
|
163
|
-
attempts++;
|
|
164
|
-
}
|
|
162
|
+
await target.click();
|
|
165
163
|
}
|
|
166
164
|
},
|
|
167
165
|
dedupe: async (row) => {
|
|
@@ -303,28 +301,22 @@ function createMuiDataGrid(opts) {
|
|
|
303
301
|
return 'desc';
|
|
304
302
|
return 'none';
|
|
305
303
|
},
|
|
306
|
-
doSort: async ({ columnName,
|
|
307
|
-
|
|
304
|
+
doSort: async ({ columnName, context }) => {
|
|
305
|
+
// Trigger-only: core `sorting.apply` owns retries + state checks (#434).
|
|
308
306
|
if (!context.getHeaderCell)
|
|
309
307
|
return;
|
|
310
308
|
const header = await context.getHeaderCell(columnName);
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const clickTarget = header.locator('.MuiDataGrid-columnHeaderTitleContainer').first();
|
|
315
|
-
if (await clickTarget.isVisible()) {
|
|
316
|
-
await clickTarget.click({ force: true });
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
await header.click({ force: true });
|
|
320
|
-
}
|
|
321
|
-
// Wait for stabilization (using DataGrid specific overlay check inside helper)
|
|
322
|
-
const displayedRows = context.root.locator('.MuiTablePagination-displayedRows');
|
|
323
|
-
const text = await displayedRows.innerText().catch(() => '');
|
|
324
|
-
await waitForMuiPaginationStabilization(context, displayedRows, text);
|
|
325
|
-
current = await ((_b = context.config.strategies.sorting) === null || _b === void 0 ? void 0 : _b.getSortState({ columnName, context })) || 'none';
|
|
326
|
-
attempts++;
|
|
309
|
+
const clickTarget = header.locator('.MuiDataGrid-columnHeaderTitleContainer').first();
|
|
310
|
+
if (await clickTarget.isVisible()) {
|
|
311
|
+
await clickTarget.click({ force: true });
|
|
327
312
|
}
|
|
313
|
+
else {
|
|
314
|
+
await header.click({ force: true });
|
|
315
|
+
}
|
|
316
|
+
// One stabilization wait after the click; core also polls isTableLoading.
|
|
317
|
+
const displayedRows = context.root.locator('.MuiTablePagination-displayedRows');
|
|
318
|
+
const text = await displayedRows.innerText().catch(() => '');
|
|
319
|
+
await waitForMuiPaginationStabilization(context, displayedRows, text);
|
|
328
320
|
}
|
|
329
321
|
},
|
|
330
322
|
dedupe: async (row) => {
|
|
@@ -345,7 +337,7 @@ function createMuiDataGrid(opts) {
|
|
|
345
337
|
// scroll methods use querySelector rather than closest().
|
|
346
338
|
viewport: {
|
|
347
339
|
getVisibleRowRange: async ({ root, config }) => {
|
|
348
|
-
const rowSel = config.rowSelector;
|
|
340
|
+
const rowSel = cssOr(config.rowSelector, MUI_ROW_CSS);
|
|
349
341
|
return root.evaluate((el, rowSel) => {
|
|
350
342
|
const indices = Array.from(el.querySelectorAll(rowSel))
|
|
351
343
|
.map(r => Number(r.getAttribute('data-rowindex')))
|
|
@@ -359,8 +351,13 @@ function createMuiDataGrid(opts) {
|
|
|
359
351
|
// the DOM positions of rows overlapping the virtualScroller's bounds so map/forEach
|
|
360
352
|
// skip the overscan rows MUI keeps mounted above/below the fold. The scroller is a
|
|
361
353
|
// descendant of root, so querySelector (not closest).
|
|
362
|
-
getVisibleRowIndices: async ({ root, config }) => {
|
|
363
|
-
|
|
354
|
+
getVisibleRowIndices: async ({ root, config, resolve }) => {
|
|
355
|
+
// Positions must index into the configured row set, so no CSS fallback here.
|
|
356
|
+
const rowSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'rowSelector', 'MUI DataGrid overscan filtering');
|
|
357
|
+
if (!rowSel) {
|
|
358
|
+
const count = await resolve(config.rowSelector, root).count();
|
|
359
|
+
return Array.from({ length: count }, (_, i) => i);
|
|
360
|
+
}
|
|
364
361
|
return root.evaluate((el, rowSel) => {
|
|
365
362
|
const scroller = el.querySelector('.MuiDataGrid-virtualScroller');
|
|
366
363
|
const rows = Array.from(el.querySelectorAll(rowSel));
|
|
@@ -381,7 +378,7 @@ function createMuiDataGrid(opts) {
|
|
|
381
378
|
}, rowSel);
|
|
382
379
|
},
|
|
383
380
|
getVisibleColumnRange: async ({ root, config }) => {
|
|
384
|
-
const rowSel = config.rowSelector;
|
|
381
|
+
const rowSel = cssOr(config.rowSelector, MUI_ROW_CSS);
|
|
385
382
|
const cellSel = typeof config.cellSelector === 'string' ? config.cellSelector : '[aria-colindex]';
|
|
386
383
|
return root.evaluate((el, { rowSel, cellSel }) => {
|
|
387
384
|
const scroller = el.querySelector('.MuiDataGrid-virtualScroller');
|
|
@@ -423,7 +420,7 @@ function createMuiDataGrid(opts) {
|
|
|
423
420
|
}, { rowSel, cellSel });
|
|
424
421
|
},
|
|
425
422
|
scrollToRow: async ({ root, config }, rowIndex) => {
|
|
426
|
-
const rowSel = config.rowSelector;
|
|
423
|
+
const rowSel = cssOr(config.rowSelector, MUI_ROW_CSS);
|
|
427
424
|
await root.evaluate((el, { rowSel, idx }) => {
|
|
428
425
|
const scroller = el.querySelector('.MuiDataGrid-virtualScroller');
|
|
429
426
|
if (!scroller)
|
|
@@ -477,10 +474,10 @@ function createMuiDataGrid(opts) {
|
|
|
477
474
|
.catch(() => { });
|
|
478
475
|
},
|
|
479
476
|
scrollToColumn: async ({ root, config, page }, colIndex) => {
|
|
480
|
-
const headerSel =
|
|
477
|
+
const headerSel = cssOr(config.headerSelector, MUI_HEADER_CSS);
|
|
481
478
|
await root.evaluate((el, { headerSel, idx }) => {
|
|
482
479
|
const scroller = el.querySelector('.MuiDataGrid-virtualScroller');
|
|
483
|
-
if (!scroller
|
|
480
|
+
if (!scroller)
|
|
484
481
|
return;
|
|
485
482
|
const headers = Array.from(el.querySelectorAll(headerSel));
|
|
486
483
|
const targetAriaIdx = idx + 1; // aria-colindex is 1-based
|
package/dist/smartRow.js
CHANGED
|
@@ -7,13 +7,20 @@ const stringUtils_1 = require("./utils/stringUtils");
|
|
|
7
7
|
const debugUtils_1 = require("./utils/debugUtils");
|
|
8
8
|
const paginationPath_1 = require("./utils/paginationPath");
|
|
9
9
|
const sentinel_1 = require("./utils/sentinel");
|
|
10
|
+
const pageIndex_1 = require("./utils/pageIndex");
|
|
10
11
|
/**
|
|
11
12
|
* Internal helper to navigate to a cell with active cell optimization.
|
|
12
13
|
* Uses `strategies.navigation` primitives (goUp/goDown/goLeft/goRight, optional snap/seek/goHome).
|
|
13
14
|
* Returns the target cell locator after navigation.
|
|
14
15
|
*/
|
|
15
16
|
const _navigateToCell = async (params) => {
|
|
16
|
-
|
|
17
|
+
var _a;
|
|
18
|
+
const { config, rootLocator, page, resolve, getHeaders, column, index, rowLocator, barrier, allowMissingCell } = params;
|
|
19
|
+
// getRowByIndex supplies a position in the mounted row set. Resolve it while the
|
|
20
|
+
// selected row is still mounted, before horizontal scrolling can evict it.
|
|
21
|
+
const rowIndex = params.renderWindowPosition && config.strategies.viewport && config.strategies.resolveRowIndex
|
|
22
|
+
? (_a = (await (0, rowResolution_1.resolveLogicalRowIndex)(rowLocator, config, () => undefined))) === null || _a === void 0 ? void 0 : _a.index
|
|
23
|
+
: params.rowIndex;
|
|
17
24
|
const rowLabel = typeof rowIndex === 'number' ? `row ${rowIndex}` : 'row ?';
|
|
18
25
|
(0, debugUtils_1.logDebug)(config, 'verbose', `_navigateToCell: resolving column "${column}" (colIndex ${index}), ${rowLabel}`);
|
|
19
26
|
// Get active cell if strategy is available
|
|
@@ -357,6 +364,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
357
364
|
index: idx,
|
|
358
365
|
rowLocator,
|
|
359
366
|
rowIndex,
|
|
367
|
+
renderWindowPosition,
|
|
360
368
|
barrier: smart._barrier
|
|
361
369
|
});
|
|
362
370
|
// Run beforeCellRead hook (same as toJSON does after navigation).
|
|
@@ -418,6 +426,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
418
426
|
index: idx,
|
|
419
427
|
rowLocator,
|
|
420
428
|
rowIndex,
|
|
429
|
+
renderWindowPosition,
|
|
421
430
|
barrier: smart._barrier,
|
|
422
431
|
allowMissingCell: !!(columnOverride === null || columnOverride === void 0 ? void 0 : columnOverride.read),
|
|
423
432
|
});
|
|
@@ -717,6 +726,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
717
726
|
index: idx,
|
|
718
727
|
rowLocator: stableRow,
|
|
719
728
|
rowIndex,
|
|
729
|
+
renderWindowPosition,
|
|
720
730
|
barrier: smart._barrier,
|
|
721
731
|
allowMissingCell: !!mapper,
|
|
722
732
|
});
|
|
@@ -833,6 +843,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
833
843
|
index: colIdx,
|
|
834
844
|
rowLocator,
|
|
835
845
|
rowIndex,
|
|
846
|
+
renderWindowPosition,
|
|
836
847
|
barrier: smart._barrier
|
|
837
848
|
});
|
|
838
849
|
const columnOverride = (_c = config.columnOverrides) === null || _c === void 0 ? void 0 : _c[colName];
|
|
@@ -885,7 +896,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
885
896
|
const primitives = config.strategies.pagination;
|
|
886
897
|
const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
|
|
887
898
|
const getCurrent = () => parentTable.currentPageIndex;
|
|
888
|
-
const setCurrent = (n) => { parentTable
|
|
899
|
+
const setCurrent = (n) => { (0, pageIndex_1.setCurrentPageIndex)(parentTable, n); };
|
|
889
900
|
if (primitives.goToPage) {
|
|
890
901
|
(0, debugUtils_1.logDebug)(config, 'info', `bringIntoView: Navigating to page ${tablePageIndex} (goToPage retry loop)`);
|
|
891
902
|
await (0, paginationPath_1.executeNavigationWithGoToPageRetry)(tablePageIndex, primitives, context, getCurrent, setCurrent);
|
|
@@ -910,7 +921,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
|
|
|
910
921
|
if (!ok)
|
|
911
922
|
throw new Error(`bringIntoView: goNext failed before reaching page ${tablePageIndex}.`);
|
|
912
923
|
}
|
|
913
|
-
parentTable
|
|
924
|
+
(0, pageIndex_1.setCurrentPageIndex)(parentTable, tablePageIndex);
|
|
914
925
|
}
|
|
915
926
|
else {
|
|
916
927
|
(0, debugUtils_1.logDebug)(config, 'error', `Cannot bring row on page ${tablePageIndex} into view. No backwards pagination strategies (goToPage, goPrevious, goPreviousBulk, or goToFirst+goNext) provided.`);
|
|
@@ -8,9 +8,8 @@ exports.FilterStrategies = void 0;
|
|
|
8
8
|
exports.FilterStrategies = {
|
|
9
9
|
default: {
|
|
10
10
|
apply({ rows, filter, colIndex, tableContext }) {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const cellTemplate = resolve(tableContext.config.cellSelector, page);
|
|
11
|
+
const scopeRow = tableContext.page.locator(':scope');
|
|
12
|
+
const cellTemplate = tableContext.resolve(tableContext.config.cellSelector, scopeRow);
|
|
14
13
|
const targetCell = cellTemplate.nth(colIndex);
|
|
15
14
|
if (typeof filter.value === 'function') {
|
|
16
15
|
return rows.filter({ has: filter.value(targetCell) });
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ViewportStrategies = void 0;
|
|
4
4
|
const debugUtils_1 = require("../utils/debugUtils");
|
|
5
|
+
const cssSelector_1 = require("../utils/cssSelector");
|
|
5
6
|
/**
|
|
6
7
|
* Viewport strategies for tables where row and cell elements carry a DOM attribute
|
|
7
8
|
* equal to their index (e.g. Braintrust logs table, TanStack-style grids).
|
|
@@ -46,7 +47,9 @@ const dataAttribute = (options) => {
|
|
|
46
47
|
const scrollPadding = (_g = options === null || options === void 0 ? void 0 : options.scrollPadding) !== null && _g !== void 0 ? _g : 20;
|
|
47
48
|
return {
|
|
48
49
|
getVisibleColumnRange: async ({ root, config }) => {
|
|
49
|
-
const rowSel = config
|
|
50
|
+
const rowSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'rowSelector', 'dataAttribute viewport column range');
|
|
51
|
+
if (!rowSel)
|
|
52
|
+
return cssSelector_1.UNKNOWN_RANGE;
|
|
50
53
|
const cellSel = typeof config.cellSelector === 'string' ? config.cellSelector : `[${colAttr}]`;
|
|
51
54
|
const result = await root.evaluate((el, { rowSel, cellSel, colAttr, colOffset }) => {
|
|
52
55
|
const firstRow = el.querySelector(rowSel);
|
|
@@ -65,8 +68,12 @@ const dataAttribute = (options) => {
|
|
|
65
68
|
}
|
|
66
69
|
return { first: result.first, last: result.last };
|
|
67
70
|
},
|
|
68
|
-
getVisibleRowIndices: async ({ root, config }) => {
|
|
69
|
-
const rowSel = config
|
|
71
|
+
getVisibleRowIndices: async ({ root, config, resolve }) => {
|
|
72
|
+
const rowSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'rowSelector', 'dataAttribute viewport overscan filtering');
|
|
73
|
+
if (!rowSel) {
|
|
74
|
+
const count = await resolve(config.rowSelector, root).count();
|
|
75
|
+
return Array.from({ length: count }, (_, i) => i);
|
|
76
|
+
}
|
|
70
77
|
// Geometry-based (mirrors getVisibleRowRange's inclusive intersection), but returns
|
|
71
78
|
// the rows' DOM positions so the iteration engine can drop overscan rows (#353/#357).
|
|
72
79
|
return root.evaluate((el, { rowSel, containerSel }) => {
|
|
@@ -92,7 +99,9 @@ const dataAttribute = (options) => {
|
|
|
92
99
|
}, { rowSel, containerSel });
|
|
93
100
|
},
|
|
94
101
|
getVisibleRowRange: async ({ root, config }) => {
|
|
95
|
-
const rowSel = config
|
|
102
|
+
const rowSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'rowSelector', 'dataAttribute viewport row range');
|
|
103
|
+
if (!rowSel)
|
|
104
|
+
return cssSelector_1.UNKNOWN_RANGE;
|
|
96
105
|
const result = await root.evaluate((el, { rowSel, rowAttr, rowOffset, containerSel }) => {
|
|
97
106
|
const rows = Array.from(el.querySelectorAll(rowSel));
|
|
98
107
|
const container = containerSel
|
|
@@ -120,9 +129,11 @@ const dataAttribute = (options) => {
|
|
|
120
129
|
}
|
|
121
130
|
return { first: result.first, last: result.last };
|
|
122
131
|
},
|
|
123
|
-
scrollToColumn: async ({ root, config }, colIndex) => {
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
scrollToColumn: async ({ root, config, resolve }, colIndex) => {
|
|
133
|
+
if (!containerSel)
|
|
134
|
+
return;
|
|
135
|
+
const headerSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'headerSelector', 'dataAttribute viewport scrollToColumn');
|
|
136
|
+
if (!headerSel)
|
|
126
137
|
return;
|
|
127
138
|
const cellSel = typeof config.cellSelector === 'string' ? config.cellSelector : `[${colAttr}]`;
|
|
128
139
|
const canScroll = await root.evaluate((el, { containerSel, headerSel, cellSel, idx, columnWidth, scrollPadding }) => {
|
|
@@ -157,15 +168,20 @@ const dataAttribute = (options) => {
|
|
|
157
168
|
if (!canScroll)
|
|
158
169
|
return;
|
|
159
170
|
// Wait for a cell at this column index to mount in any row
|
|
160
|
-
|
|
161
|
-
.locator(
|
|
171
|
+
const rows = typeof config.rowSelector === 'string'
|
|
172
|
+
? root.locator(config.rowSelector)
|
|
173
|
+
: resolve(config.rowSelector, root);
|
|
174
|
+
await rows
|
|
175
|
+
.locator(`[${colAttr}="${colIndex + colOffset}"]`)
|
|
162
176
|
.first()
|
|
163
177
|
.waitFor({ state: 'attached', timeout: attachTimeout });
|
|
164
178
|
},
|
|
165
179
|
scrollToRow: async ({ root, config }, rowIndex) => {
|
|
166
180
|
if (!containerSel)
|
|
167
181
|
return;
|
|
168
|
-
const rowSel = config
|
|
182
|
+
const rowSel = (0, cssSelector_1.cssSelectorOrWarn)(config, 'rowSelector', 'dataAttribute viewport scrollToRow');
|
|
183
|
+
if (!rowSel)
|
|
184
|
+
return;
|
|
169
185
|
const canScroll = await root.evaluate((el, { containerSel, rowSel, rowAttr, idx, rowOffset, rowHeight, scrollPadding }) => {
|
|
170
186
|
const container = el.closest(containerSel);
|
|
171
187
|
if (!container)
|