@dxos/react-ui-table 0.8.4-main.c1de068 → 0.8.4-main.f5c0578
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/lib/browser/{chunk-5XLSHLOG.mjs → chunk-ZAOSIG3L.mjs} +382 -319
- package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +404 -381
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +4 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-ZOFFI3JJ.mjs} +382 -319
- package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +404 -381
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +4 -2
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/{relations.stories.d.ts → Relations.stories.d.ts} +2 -2
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +1 -0
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +5 -5
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +3 -2
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +2 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +2 -2
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/src/util/table.d.ts +2 -1
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -38
- package/src/components/Table/ColumnActionsMenu.tsx +1 -1
- package/src/components/Table/ColumnSettings.tsx +1 -1
- package/src/components/Table/CreateRefPanel.tsx +1 -1
- package/src/components/Table/DynamicTable.stories.tsx +3 -2
- package/src/components/Table/DynamicTable.tsx +4 -3
- package/src/components/Table/{relations.stories.tsx → Relations.stories.tsx} +12 -4
- package/src/components/Table/RowActionsMenu.tsx +3 -3
- package/src/components/Table/Table.stories.tsx +12 -7
- package/src/components/Table/Table.tsx +56 -45
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +4 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +16 -20
- package/src/components/TableCellEditor/extension.ts +2 -2
- package/src/components/TableToolbar/TableToolbar.tsx +2 -2
- package/src/components/testing.ts +1 -1
- package/src/hooks/useTableModel.ts +1 -1
- package/src/model/modal-controller.ts +1 -1
- package/src/model/selection-model.ts +3 -2
- package/src/model/table-model.test.ts +2 -1
- package/src/model/table-model.ts +13 -10
- package/src/model/table-presentation.test.ts +3 -2
- package/src/model/table-presentation.ts +28 -6
- package/src/model/table-sorting.ts +3 -3
- package/src/playwright/smoke.spec.ts +92 -0
- package/src/testing/useTestTableModel.ts +3 -2
- package/src/translations.ts +2 -2
- package/src/util/dynamic-table.ts +2 -2
- package/src/util/schema.ts +1 -1
- package/src/util/table-buttons.ts +2 -1
- package/src/util/table-controls.ts +4 -1
- package/src/util/table.ts +7 -3
- package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
- package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
type ActionGraphEdges,
|
|
12
12
|
type ActionGraphNodes,
|
|
13
13
|
type ActionGraphProps,
|
|
14
|
-
createGapSeparator,
|
|
15
|
-
createMenuAction,
|
|
16
14
|
type MenuAction,
|
|
17
15
|
MenuProvider,
|
|
18
16
|
ToolbarMenu,
|
|
17
|
+
createGapSeparator,
|
|
18
|
+
createMenuAction,
|
|
19
19
|
useMenuActions,
|
|
20
20
|
} from '@dxos/react-ui-menu';
|
|
21
21
|
import { rxFromSignal } from '@dxos/react-ui-menu';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
import { useEffect } from 'react';
|
|
7
7
|
|
|
8
|
-
import { FormatEnum, ObjectId,
|
|
8
|
+
import { FormatEnum, ObjectId, TypeEnum, TypedObject, setValue } from '@dxos/echo-schema';
|
|
9
9
|
import { live } from '@dxos/live-object';
|
|
10
10
|
import { faker } from '@dxos/random';
|
|
11
11
|
import { type ProjectionModel } from '@dxos/schema';
|
|
@@ -13,7 +13,7 @@ import { useSelected, useSelectionActions } from '@dxos/react-ui-attention';
|
|
|
13
13
|
import { type DataType, type ProjectionModel } from '@dxos/schema';
|
|
14
14
|
import { isNonNullable } from '@dxos/util';
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { TableModel, type TableModelProps, type TableRow, type TableRowAction } from '../model';
|
|
17
17
|
|
|
18
18
|
export type UseTableModelParams<T extends TableRow = TableRow> = {
|
|
19
19
|
view?: DataType.View;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { signal } from '@preact/signals-core';
|
|
6
|
-
import { type
|
|
6
|
+
import { type MutableRefObject, type RefObject } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type Live } from '@dxos/live-object';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type ReadonlySignal, type Signal, computed, effect, signal } from '@preact/signals-core';
|
|
6
6
|
|
|
7
7
|
import { Resource } from '@dxos/context';
|
|
8
8
|
|
|
9
|
-
import { type TableRow } from './table-model';
|
|
10
9
|
import { touch } from '../util';
|
|
11
10
|
|
|
11
|
+
import { type TableRow } from './table-model';
|
|
12
|
+
|
|
12
13
|
export type SelectionMode = 'single' | 'multiple';
|
|
13
14
|
|
|
14
15
|
export class SelectionModel<T extends TableRow> extends Resource {
|
|
@@ -14,9 +14,10 @@ import { live } from '@dxos/live-object';
|
|
|
14
14
|
import { createEchoSchema } from '@dxos/live-object/testing';
|
|
15
15
|
import { createView } from '@dxos/schema';
|
|
16
16
|
|
|
17
|
-
import { TableModel, type TableModelProps } from './table-model';
|
|
18
17
|
import { TableView } from '../types';
|
|
19
18
|
|
|
19
|
+
import { TableModel, type TableModelProps } from './table-model';
|
|
20
|
+
|
|
20
21
|
// TODO(burdon): Tests are disabled in project.json since they bring in plugin deps.
|
|
21
22
|
// Restore once factored out into react-ui-table.
|
|
22
23
|
|
package/src/model/table-model.ts
CHANGED
|
@@ -2,40 +2,42 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { computed, effect, signal
|
|
5
|
+
import { type ReadonlySignal, computed, effect, signal } from '@preact/signals-core';
|
|
6
6
|
|
|
7
7
|
import { Resource } from '@dxos/context';
|
|
8
8
|
import { Obj, Ref } from '@dxos/echo';
|
|
9
9
|
import {
|
|
10
10
|
type FieldSortType,
|
|
11
11
|
FormatEnum,
|
|
12
|
-
getValue,
|
|
13
|
-
setValue,
|
|
14
12
|
type JsonProp,
|
|
15
|
-
|
|
13
|
+
type JsonSchemaType,
|
|
16
14
|
getSchema,
|
|
15
|
+
getSnapshot,
|
|
16
|
+
getValue,
|
|
17
|
+
setValue,
|
|
17
18
|
toEffectSchema,
|
|
18
|
-
type JsonSchemaType,
|
|
19
19
|
} from '@dxos/echo-schema';
|
|
20
20
|
import { invariant } from '@dxos/invariant';
|
|
21
21
|
import { ObjectId } from '@dxos/keys';
|
|
22
22
|
import { isLiveObject } from '@dxos/live-object';
|
|
23
23
|
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
24
|
+
import { type Label } from '@dxos/react-ui';
|
|
24
25
|
import { formatForEditing, parseValue } from '@dxos/react-ui-form';
|
|
25
26
|
import {
|
|
26
27
|
type DxGridAxisMeta,
|
|
27
|
-
type DxGridPlaneRange,
|
|
28
28
|
type DxGridPlanePosition,
|
|
29
|
+
type DxGridPlaneRange,
|
|
29
30
|
type DxGridPosition,
|
|
30
31
|
} from '@dxos/react-ui-grid';
|
|
31
|
-
import { type DataType, ProjectionModel, type PropertyType,
|
|
32
|
+
import { type DataType, ProjectionModel, type PropertyType, type ValidationError, validateSchema } from '@dxos/schema';
|
|
32
33
|
|
|
33
|
-
import { type SelectionMode, SelectionModel } from './selection-model';
|
|
34
|
-
import { TableSorting } from './table-sorting';
|
|
35
34
|
import { TableView } from '../types';
|
|
36
35
|
import { touch } from '../util';
|
|
37
36
|
import { extractTagIds } from '../util/tag';
|
|
38
37
|
|
|
38
|
+
import { type SelectionMode, SelectionModel } from './selection-model';
|
|
39
|
+
import { TableSorting } from './table-sorting';
|
|
40
|
+
|
|
39
41
|
// Domain types for cell classification
|
|
40
42
|
export type TableCellType = 'standard' | 'draft' | 'header';
|
|
41
43
|
|
|
@@ -53,7 +55,7 @@ export type TableRow = Record<JsonProp, any> & { id: string };
|
|
|
53
55
|
|
|
54
56
|
export type TableRowAction = {
|
|
55
57
|
id: string;
|
|
56
|
-
|
|
58
|
+
label: Label;
|
|
57
59
|
};
|
|
58
60
|
|
|
59
61
|
export type TableFeatures = {
|
|
@@ -497,6 +499,7 @@ export class TableModel<T extends TableRow = TableRow> extends Resource {
|
|
|
497
499
|
setValue(snapshot, field.path, transformedValue);
|
|
498
500
|
|
|
499
501
|
const validationErrors = this.validateDraftRowData(snapshot);
|
|
502
|
+
// TODO(thure): These errors sometimes result in a useless message like “is missing” (what is missing?)
|
|
500
503
|
if (validationErrors.length > 0) {
|
|
501
504
|
const error = validationErrors.find((err) => err.path === field.path);
|
|
502
505
|
if (error) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
|
-
import { describe, expect, it
|
|
6
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
7
7
|
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
9
|
import { TypedObject } from '@dxos/echo-schema';
|
|
@@ -11,9 +11,10 @@ import { live } from '@dxos/live-object';
|
|
|
11
11
|
import { createEchoSchema } from '@dxos/live-object/testing';
|
|
12
12
|
import { createView } from '@dxos/schema';
|
|
13
13
|
|
|
14
|
+
import { TableView } from '../types';
|
|
15
|
+
|
|
14
16
|
import { TableModel, type TableModelProps } from './table-model';
|
|
15
17
|
import { TablePresentation } from './table-presentation';
|
|
16
|
-
import { TableView } from '../types';
|
|
17
18
|
|
|
18
19
|
describe('TablePresentation', () => {
|
|
19
20
|
describe('row reactivity', () => {
|
|
@@ -6,7 +6,7 @@ import { signal } from '@preact/signals-core';
|
|
|
6
6
|
import { isNotNullable } from 'effect/Predicate';
|
|
7
7
|
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
|
-
import { FormatEnum,
|
|
9
|
+
import { FormatEnum, TypeEnum, getValue } from '@dxos/echo-schema';
|
|
10
10
|
import { cellClassesForFieldType, formatForDisplay } from '@dxos/react-ui-form';
|
|
11
11
|
import {
|
|
12
12
|
type DxGridCellValue,
|
|
@@ -16,12 +16,13 @@ import {
|
|
|
16
16
|
toPlaneCellIndex,
|
|
17
17
|
} from '@dxos/react-ui-grid';
|
|
18
18
|
import { mx } from '@dxos/react-ui-theme';
|
|
19
|
-
import {
|
|
19
|
+
import { type FieldType, VIEW_FIELD_LIMIT } from '@dxos/schema';
|
|
20
20
|
|
|
21
|
-
import { type SelectionMode } from './selection-model';
|
|
22
|
-
import { type TableRow, type TableModel } from './table-model';
|
|
23
21
|
import { tableButtons, tableControls } from '../util';
|
|
24
22
|
|
|
23
|
+
import { type SelectionMode } from './selection-model';
|
|
24
|
+
import { type TableModel, type TableRow } from './table-model';
|
|
25
|
+
|
|
25
26
|
/**
|
|
26
27
|
* Presentation layer for a table component, handling cell rendering and grid display logic.
|
|
27
28
|
* Manages rendering of table cells, headers, selection columns, and action columns across
|
|
@@ -67,6 +68,9 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
67
68
|
case 'frozenRowsEnd':
|
|
68
69
|
cells = this.getDraftRowCells(range);
|
|
69
70
|
break;
|
|
71
|
+
case 'fixedEndStart':
|
|
72
|
+
cells = this.getDraftSelectCells(range);
|
|
73
|
+
break;
|
|
70
74
|
case 'fixedEndEnd':
|
|
71
75
|
cells = this.getDraftActionCells(range);
|
|
72
76
|
break;
|
|
@@ -199,7 +203,7 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
199
203
|
const targetObj = getValue(obj, field.path)?.target;
|
|
200
204
|
if (targetObj) {
|
|
201
205
|
const dxn = Obj.getDXN(targetObj)?.toString();
|
|
202
|
-
cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-
|
|
206
|
+
cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-2 block-start-[.2rem]" data-dx-grid-action="accessory"><dx-icon icon="ph--link-simple--regular"/></dx-ref-tag>`;
|
|
203
207
|
}
|
|
204
208
|
}
|
|
205
209
|
|
|
@@ -278,6 +282,7 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
278
282
|
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
279
283
|
const draftRow = draftRows[row];
|
|
280
284
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
285
|
+
const cellIndex = toPlaneCellIndex({ col, row });
|
|
281
286
|
const field = fields[col];
|
|
282
287
|
if (!field) {
|
|
283
288
|
continue;
|
|
@@ -286,7 +291,6 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
286
291
|
this.createDataCell(cells, draftRow.data, field, col, row);
|
|
287
292
|
|
|
288
293
|
if (this.model.hasDraftRowValidationError(row, field.path)) {
|
|
289
|
-
const cellIndex = toPlaneCellIndex({ col, row });
|
|
290
294
|
const cellValue = cells[cellIndex];
|
|
291
295
|
if (cellValue) {
|
|
292
296
|
const existingClasses = cellValue.className || '';
|
|
@@ -294,6 +298,8 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
294
298
|
cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
|
|
295
299
|
}
|
|
296
300
|
}
|
|
301
|
+
|
|
302
|
+
cells[cellIndex].className += ' !bg-toolbarSurface';
|
|
297
303
|
}
|
|
298
304
|
}
|
|
299
305
|
|
|
@@ -408,6 +414,22 @@ export class TablePresentation<T extends TableRow = TableRow> {
|
|
|
408
414
|
value: '',
|
|
409
415
|
readonly: true,
|
|
410
416
|
accessoryHtml: tableButtons.saveDraftRow.render({ rowIndex: row, disabled }),
|
|
417
|
+
className: '!bg-toolbarSurface',
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return cells;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private getDraftSelectCells(range: DxGridPlaneRange): DxGridPlaneCells {
|
|
425
|
+
const cells: DxGridPlaneCells = {};
|
|
426
|
+
const draftRows = this.model.draftRows.value;
|
|
427
|
+
|
|
428
|
+
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
429
|
+
cells[toPlaneCellIndex({ col: 0, row })] = {
|
|
430
|
+
value: '',
|
|
431
|
+
readonly: true,
|
|
432
|
+
className: '!bg-toolbarSurface',
|
|
411
433
|
};
|
|
412
434
|
}
|
|
413
435
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type ReadonlySignal, type Signal, computed, signal } from '@preact/signals-core';
|
|
6
6
|
import orderBy from 'lodash.orderby';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { type FieldSortType, FormatEnum, type SortDirectionType, TypeEnum, getValue } from '@dxos/echo-schema';
|
|
9
9
|
import { formatForDisplay } from '@dxos/react-ui-form';
|
|
10
|
-
import type {
|
|
10
|
+
import type { DataType, FieldType, ProjectionModel, PropertyType } from '@dxos/schema';
|
|
11
11
|
|
|
12
12
|
import { type TableRow } from './table-model';
|
|
13
13
|
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import { expect, test } from '@playwright/test';
|
|
6
6
|
|
|
7
|
+
import { type DxGrid } from '@dxos/lit-grid';
|
|
7
8
|
import { setupPage, storybookUrl } from '@dxos/test-utils/playwright';
|
|
8
9
|
|
|
9
10
|
import { TableManager } from './TableManager';
|
|
10
11
|
|
|
11
12
|
const storyUrl = storybookUrl('ui-react-ui-table-table--default', 9004);
|
|
13
|
+
const relationsStoryUrl = storybookUrl('ui-react-ui-table-relations--default', 9004);
|
|
12
14
|
|
|
13
15
|
// NOTE(ZaymonFC): This test suite relies on the faker seed being set to 0 in the story.
|
|
14
16
|
test.describe('Table', () => {
|
|
@@ -183,4 +185,94 @@ test.describe('Table', () => {
|
|
|
183
185
|
|
|
184
186
|
await page.close();
|
|
185
187
|
});
|
|
188
|
+
|
|
189
|
+
test('extant relations work as expected', async ({ browser, browserName }) => {
|
|
190
|
+
test.skip(browserName === 'webkit');
|
|
191
|
+
const { page } = await setupPage(browser, { url: relationsStoryUrl });
|
|
192
|
+
|
|
193
|
+
// Wait for the page to load
|
|
194
|
+
await page.locator('dx-grid > .dx-grid').nth(1).waitFor({ state: 'visible' });
|
|
195
|
+
|
|
196
|
+
// Find the dx-grid element for the contactModel (second table)
|
|
197
|
+
// The contactModel is used in the second Table.Main component in the story
|
|
198
|
+
const dxGrid = page.locator('dx-grid').nth(1);
|
|
199
|
+
await dxGrid.waitFor({ state: 'visible' });
|
|
200
|
+
|
|
201
|
+
// Scroll to the last column (column 8)
|
|
202
|
+
await dxGrid.evaluate(async (dxGridElement: DxGrid) => {
|
|
203
|
+
dxGridElement.scrollToColumn(8);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Click on the cell at aria-rowindex=0 aria-colindex=8 to focus it
|
|
207
|
+
const targetCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="8"]');
|
|
208
|
+
await targetCell.click();
|
|
209
|
+
|
|
210
|
+
// Click again to engage edit mode
|
|
211
|
+
await page.keyboard.press('Enter');
|
|
212
|
+
await page.getByTestId('grid.cell-editor').waitFor({ state: 'visible' });
|
|
213
|
+
|
|
214
|
+
// Type the first few letters of an org name.
|
|
215
|
+
const orgName =
|
|
216
|
+
(await page
|
|
217
|
+
.locator('dx-grid')
|
|
218
|
+
.nth(0)
|
|
219
|
+
.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="0"] .dx-grid__cell__content')
|
|
220
|
+
.textContent()) ?? 'never';
|
|
221
|
+
await page.keyboard.type(orgName.substring(0, 4), { delay: 500 });
|
|
222
|
+
|
|
223
|
+
// Assert that there is an element with aria-selected on the page
|
|
224
|
+
await expect(page.locator('[role="option"][aria-selected]')).toBeVisible();
|
|
225
|
+
|
|
226
|
+
// Type the enter key
|
|
227
|
+
await page.keyboard.press('Enter');
|
|
228
|
+
|
|
229
|
+
// Assert that the cell element has the org name
|
|
230
|
+
await expect(targetCell).toHaveText(orgName);
|
|
231
|
+
|
|
232
|
+
await page.close();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('new relations work as expected', async ({ browser, browserName }) => {
|
|
236
|
+
test.skip(browserName === 'webkit');
|
|
237
|
+
const { page } = await setupPage(browser, { url: relationsStoryUrl });
|
|
238
|
+
|
|
239
|
+
// Wait for the page to load
|
|
240
|
+
await page.locator('dx-grid > .dx-grid').nth(1).waitFor({ state: 'visible' });
|
|
241
|
+
|
|
242
|
+
// Find the dx-grid element for the contactModel (second table)
|
|
243
|
+
// The contactModel is used in the second Table.Main component in the story
|
|
244
|
+
const dxGrid = page.locator('dx-grid').nth(1);
|
|
245
|
+
await dxGrid.waitFor({ state: 'visible' });
|
|
246
|
+
|
|
247
|
+
// Scroll to the last column (column 8)
|
|
248
|
+
await dxGrid.evaluate(async (dxGridElement: DxGrid) => {
|
|
249
|
+
dxGridElement.scrollToColumn(8);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Click on the cell at aria-rowindex=0 aria-colindex=8 to focus it
|
|
253
|
+
const targetCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="8"]');
|
|
254
|
+
await targetCell.click();
|
|
255
|
+
|
|
256
|
+
// Click again to engage edit mode
|
|
257
|
+
await page.keyboard.press('Enter');
|
|
258
|
+
await page.getByTestId('grid.cell-editor').waitFor({ state: 'visible' });
|
|
259
|
+
|
|
260
|
+
// Type the first few letters of an org name.
|
|
261
|
+
const orgName = 'Sally';
|
|
262
|
+
await page.keyboard.type(orgName, { delay: 500 });
|
|
263
|
+
|
|
264
|
+
// Assert that there is an element with aria-selected on the page
|
|
265
|
+
await expect(page.locator('[role="option"][aria-selected]')).toBeVisible();
|
|
266
|
+
|
|
267
|
+
// Type the enter key
|
|
268
|
+
await page.keyboard.press('Enter');
|
|
269
|
+
|
|
270
|
+
// Click the save button in the popover
|
|
271
|
+
await page.getByTestId('save-button').click();
|
|
272
|
+
|
|
273
|
+
// Assert that the cell element has the org name
|
|
274
|
+
await expect(targetCell).toHaveText(orgName);
|
|
275
|
+
|
|
276
|
+
await page.close();
|
|
277
|
+
});
|
|
186
278
|
});
|
|
@@ -13,7 +13,7 @@ import { useClientProvider } from '@dxos/react-client/testing';
|
|
|
13
13
|
import { DataType, ProjectionModel } from '@dxos/schema';
|
|
14
14
|
|
|
15
15
|
import { type TableController } from '../components';
|
|
16
|
-
import {
|
|
16
|
+
import { useAddRow, useTableModel } from '../hooks';
|
|
17
17
|
import { TablePresentation } from '../model';
|
|
18
18
|
|
|
19
19
|
faker.seed(0); // NOTE(ZaymonFC): Required for smoke tests.
|
|
@@ -93,7 +93,8 @@ export const useTestTableModel = () => {
|
|
|
93
93
|
|
|
94
94
|
const handleInsertRow = useCallback(() => {
|
|
95
95
|
model?.insertRow();
|
|
96
|
-
|
|
96
|
+
tableRef.current?.focusDraft?.();
|
|
97
|
+
}, [model, tableRef.current]);
|
|
97
98
|
|
|
98
99
|
const handleSaveView = useCallback(() => {
|
|
99
100
|
model?.saveView();
|
package/src/translations.ts
CHANGED
|
@@ -14,8 +14,8 @@ export const translations = [
|
|
|
14
14
|
'create object label': 'Create table',
|
|
15
15
|
'table name placeholder': 'Table name',
|
|
16
16
|
'settings title': 'Table settings',
|
|
17
|
-
'table schema label': '
|
|
18
|
-
'new schema': 'New
|
|
17
|
+
'table schema label': 'Record type',
|
|
18
|
+
'new schema': 'New record type',
|
|
19
19
|
'continue label': 'Continue',
|
|
20
20
|
'create stack section label': 'Create table',
|
|
21
21
|
'add row label': 'Add row',
|
|
@@ -8,11 +8,11 @@ import { Obj } from '@dxos/echo';
|
|
|
8
8
|
import { getTypename, toJsonSchema } from '@dxos/echo-schema';
|
|
9
9
|
import type { JsonSchemaType, SortDirectionType } from '@dxos/echo-schema';
|
|
10
10
|
import {
|
|
11
|
-
createView,
|
|
12
11
|
type DataType,
|
|
13
|
-
getSchemaFromPropertyDefinitions,
|
|
14
12
|
ProjectionModel,
|
|
15
13
|
type SchemaPropertyDefinition,
|
|
14
|
+
createView,
|
|
15
|
+
getSchemaFromPropertyDefinitions,
|
|
16
16
|
} from '@dxos/schema';
|
|
17
17
|
|
|
18
18
|
import { TableView } from '../types';
|
package/src/util/schema.ts
CHANGED
|
@@ -40,7 +40,7 @@ const createButton = ({
|
|
|
40
40
|
.join(' ');
|
|
41
41
|
|
|
42
42
|
const positionClass = type === 'primary' ? 'inline-end-2' : 'inline-end-9';
|
|
43
|
-
return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? 'disabled' : ''}><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
43
|
+
return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? 'disabled' : ''} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
const addColumnButton = {
|
|
@@ -130,6 +130,7 @@ const saveDraftRowButton = {
|
|
|
130
130
|
disabled,
|
|
131
131
|
data: {
|
|
132
132
|
'data-row-index': rowIndex.toString(),
|
|
133
|
+
'data-variant': 'primary',
|
|
133
134
|
},
|
|
134
135
|
testId: 'table-save-draft-row-button',
|
|
135
136
|
});
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
// Core types.
|
|
6
|
+
import { accessoryHandlesPointerdownAttrs } from '@dxos/lit-grid';
|
|
7
|
+
|
|
6
8
|
export type TableControl = 'checkbox' | 'switch';
|
|
7
9
|
|
|
8
10
|
export type ControlData =
|
|
@@ -41,7 +43,7 @@ const renderInput = (
|
|
|
41
43
|
preventToggle = false,
|
|
42
44
|
testId: string,
|
|
43
45
|
) => {
|
|
44
|
-
return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? 'checked' : ''} ${preventToggle ? 'onclick="return false"' : ''} ${disabled ? 'disabled' : ''} data-testid="${testId}"/>`;
|
|
46
|
+
return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? 'checked' : ''} ${preventToggle ? 'onclick="return false"' : ''} ${disabled ? 'disabled' : ''} data-testid="${testId}" data-dx-grid-action="accessory"/>`;
|
|
45
47
|
};
|
|
46
48
|
|
|
47
49
|
export const CheckboxStory = ({
|
|
@@ -64,6 +66,7 @@ export const SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = fa
|
|
|
64
66
|
[CONTROL_IDENTIFIERS.switch]: '',
|
|
65
67
|
'data-row-index': rowIndex.toString(),
|
|
66
68
|
'data-col-index': colIndex.toString(),
|
|
69
|
+
...accessoryHandlesPointerdownAttrs,
|
|
67
70
|
};
|
|
68
71
|
|
|
69
72
|
return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, 'table-switch');
|
package/src/util/table.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Match } from 'effect';
|
|
6
6
|
|
|
7
7
|
import { Obj } from '@dxos/echo';
|
|
8
|
-
import { type JsonPath,
|
|
8
|
+
import { type JsonPath, type JsonSchemaType, toEffectSchema } from '@dxos/echo-schema';
|
|
9
9
|
import { type SimpleType } from '@dxos/effect';
|
|
10
10
|
import { type CreateViewFromSpaceProps, type DataType, createViewFromSpace, getSchemaProperties } from '@dxos/schema';
|
|
11
11
|
|
|
@@ -18,7 +18,11 @@ type CreateTableProps = Omit<CreateViewFromSpaceProps, 'presentation'> & {
|
|
|
18
18
|
export const createTable = async ({
|
|
19
19
|
sizes,
|
|
20
20
|
...props
|
|
21
|
-
}: CreateTableProps): Promise<{
|
|
21
|
+
}: CreateTableProps): Promise<{
|
|
22
|
+
jsonSchema: JsonSchemaType;
|
|
23
|
+
view: DataType.View;
|
|
24
|
+
schema: ReturnType<typeof toEffectSchema>;
|
|
25
|
+
}> => {
|
|
22
26
|
const table = Obj.make(TableView, { sizes: {} });
|
|
23
27
|
const { jsonSchema, view } = await createViewFromSpace({ ...props, presentation: table });
|
|
24
28
|
|
|
@@ -45,5 +49,5 @@ export const createTable = async ({
|
|
|
45
49
|
)(property.type);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
return { jsonSchema, view };
|
|
52
|
+
return { jsonSchema, schema, view };
|
|
49
53
|
};
|