Skip to content

Commit a479d6c

Browse files
authored
fix: Use correct offset in snapshot (#2217)
- Was using `row.offsetInSnapshot`, which was a "protected" API and recently removed from the JS API - API was removed in JS API refactoring: deephaven/deephaven-core#5890 - Instead just use the viewport `offset` and add the index of the row in the snapshot, which is there in both versions of the API - New API does support `row.index`, but this way is compatible with both - Updated unit tests - Tested using a deephaven.ui.list_view: ```python from deephaven import time_table, ui import datetime initial_row_count = 200 column_types = time_table( "PT1S", start_time=datetime.datetime.now() - datetime.timedelta(seconds=initial_row_count), ).update( [ "Id=new Integer(i)", "Display=new String(`Display `+i)", ] ) @ui.component def ui_list_view_table(): value, set_value = ui.use_state([]) lv = ui.list_view( column_types, aria_label="List View", on_change=set_value, selected_keys=value, ) text = ui.text("Selection: " + ", ".join(map(str, value))) return ui.flex( lv, text, direction="column", margin=10, gap=10, width=500, # necessary to avoid overflowing container height min_height=0, ) lv_table = ui_list_view_table() ```
1 parent 99b8d59 commit a479d6c

3 files changed

Lines changed: 17 additions & 57 deletions

File tree

packages/jsapi-components/src/useViewportData.test.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { dh as DhType } from '@deephaven/jsapi-types';
33
import dh from '@deephaven/jsapi-shim';
44
import {
55
OnTableUpdatedEvent,
6-
ViewportRow,
76
generateEmptyKeyedItems,
87
isClosed,
98
ITEM_KEY_PREFIX,
@@ -23,13 +22,9 @@ jest.mock('@deephaven/react-hooks', () => ({
2322
jest.mock('./useSetPaddedViewportCallback');
2423
jest.mock('./useTableSize');
2524

26-
function mockViewportRow(offsetInSnapshot: number): ViewportRow {
27-
return { offsetInSnapshot } as ViewportRow;
28-
}
29-
3025
function mockUpdateEvent(
3126
offset: number,
32-
rows: ViewportRow[]
27+
rows: DhType.Row[]
3328
): OnTableUpdatedEvent {
3429
return {
3530
detail: {
@@ -213,14 +208,14 @@ it('should update state on dh.Table.EVENT_UPDATED event', () => {
213208
);
214209

215210
const offset = 3;
216-
const row = mockViewportRow(5);
211+
const row = TestUtils.createMockProxy<DhType.Row>();
217212
const event = mockUpdateEvent(offset, [row]);
218213

219214
act(() => {
220215
updateEventHandler?.(event);
221216
});
222217

223-
const expectedKeyIndex = offset + row.offsetInSnapshot;
218+
const expectedKeyIndex = offset;
224219
const expectedInitialItems = [...generateEmptyKeyedItems(0, table.size - 1)];
225220
const expectedItems = [
226221
...expectedInitialItems.slice(0, expectedKeyIndex),

packages/jsapi-utils/src/ViewportDataUtils.test.ts

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import {
55
ITEM_KEY_PREFIX,
66
OnTableUpdatedEvent,
77
RowDeserializer,
8-
ViewportRow,
9-
createKeyFromOffsetRow,
108
createOnTableUpdatedHandler,
119
defaultRowDeserializer,
1210
generateEmptyKeyedItems,
@@ -18,10 +16,6 @@ import {
1816

1917
const { asMock, createMockProxy } = TestUtils;
2018

21-
function mockViewportRow(offsetInSnapshot: number): ViewportRow {
22-
return { offsetInSnapshot } as ViewportRow;
23-
}
24-
2519
function mockColumn(name: string) {
2620
return {
2721
name,
@@ -44,28 +38,15 @@ describe('createdKeyedItemKey', () => {
4438
});
4539
});
4640

47-
describe('createKeyFromOffsetRow', () => {
48-
it.each([
49-
[{ offsetInSnapshot: 4 } as ViewportRow, 5, `${ITEM_KEY_PREFIX}_9`],
50-
[{ offsetInSnapshot: 27 } as ViewportRow, 99, `${ITEM_KEY_PREFIX}_126`],
51-
] as const)(
52-
'should create a string key based on the actual row offset: %o',
53-
(row, offset, expected) => {
54-
const actual = createKeyFromOffsetRow(row, offset);
55-
expect(actual).toEqual(expected);
56-
}
57-
);
58-
});
59-
6041
describe('createOnTableUpdatedHandler', () => {
6142
const mock = {
6243
deserializeRow: jest.fn() as RowDeserializer<unknown>,
6344
rows: [
64-
createMockProxy<ViewportRow>({ offsetInSnapshot: 0 }),
65-
createMockProxy<ViewportRow>({ offsetInSnapshot: 1 }),
66-
createMockProxy<ViewportRow>({ offsetInSnapshot: 2 }),
45+
createMockProxy<dh.Row>(),
46+
createMockProxy<dh.Row>(),
47+
createMockProxy<dh.Row>(),
6748
],
68-
updateEvent: (offset: number, rows: ViewportRow[], columns: dh.Column[]) =>
49+
updateEvent: (offset: number, rows: dh.Row[], columns: dh.Column[]) =>
6950
createMockProxy<OnTableUpdatedEvent>({
7051
detail: {
7152
offset,
@@ -107,10 +88,11 @@ describe('createOnTableUpdatedHandler', () => {
10788

10889
describe('defaultRowDeserializer', () => {
10990
it('should map all columns with original names', () => {
110-
const row = mockViewportRow(10);
111-
// mock our get function by mapping capital column name to lowercase value
112-
// e.g. A: 'a'
113-
row.get = jest.fn(({ name }: { name: string }) => name.toLowerCase());
91+
const row = createMockProxy<dh.Row>({
92+
// mock our get function by mapping capital column name to lowercase value
93+
// e.g. A: 'a'
94+
get: jest.fn(({ name }: { name: string }) => name.toLowerCase()),
95+
});
11496

11597
const actual = defaultRowDeserializer(row, [
11698
mockColumn('A'),

packages/jsapi-utils/src/ViewportDataUtils.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ export const ITEM_KEY_PREFIX = 'DH_ITEM_KEY';
99
export type OnTableUpdatedEvent = CustomEvent<{
1010
offset: number;
1111
columns: dh.Column[];
12-
rows: ViewportRow[];
12+
rows: dh.Row[];
1313
}>;
1414

15-
export type RowDeserializer<T> = (row: ViewportRow, columns: dh.Column[]) => T;
16-
17-
export type ViewportRow = dh.Row & { offsetInSnapshot: number };
15+
export type RowDeserializer<T> = (row: dh.Row, columns: dh.Column[]) => T;
1816

1917
const log = Log.module('ViewportDataUtils');
2018

@@ -29,21 +27,6 @@ export function createKeyedItemKey(index: number): string {
2927
return `${ITEM_KEY_PREFIX}_${index}`;
3028
}
3129

32-
/**
33-
* Create a unique string key for a row based on its ordinal position in its
34-
* source table. This is calculated based on it's offset in the viewport
35-
* (row.offsetInSnapshot) + the offset of the snapshot.
36-
* @param row Row from a Table update event.
37-
* @param offset Offset of the current viewport.
38-
* @returns Unique string key for the ordinal position of the given row.
39-
*/
40-
export function createKeyFromOffsetRow(
41-
row: ViewportRow,
42-
offset: number
43-
): string {
44-
return createKeyedItemKey(row.offsetInSnapshot + offset);
45-
}
46-
4730
/**
4831
* Creates a handler function for a `dh.Table.EVENT_UPDATED` event. Rows that
4932
* get passed to the handler will be bulk updated in the given `viewportData`
@@ -66,9 +49,9 @@ export function createOnTableUpdatedHandler<T>(
6649

6750
const updateKeyMap = new Map<Key, KeyedItem<T>>();
6851

69-
rows.forEach(row => {
52+
rows.forEach((row, offsetInSnapshot) => {
7053
const item = deserializeRow(row, columns);
71-
const key = createKeyFromOffsetRow(row, offset);
54+
const key = createKeyedItemKey(offset + offsetInSnapshot);
7255
updateKeyMap.set(key, { key, item });
7356
});
7457

@@ -86,7 +69,7 @@ export function createOnTableUpdatedHandler<T>(
8669
* @returns A key / value object for the row.
8770
*/
8871
export function defaultRowDeserializer<T>(
89-
row: ViewportRow,
72+
row: dh.Row,
9073
columns: dh.Column[]
9174
): T {
9275
return columns.reduce((result, col) => {

0 commit comments

Comments
 (0)