@dxos/react-ui-table 0.7.5-labs.a279d8c → 0.7.5-labs.a8b535d
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/index.mjs +47 -5
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +47 -5
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +47 -5
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/_deprecated/components/Cell/Cell.d.ts +2 -2
- package/dist/types/src/_deprecated/components/Cell/Cell.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts +1 -2
- package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts +2 -3
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts +6 -7
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts +1 -2
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts +6 -7
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Table/Table.d.ts +5 -5
- package/dist/types/src/_deprecated/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts +8 -9
- package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Table/TableBody.d.ts +1 -2
- package/dist/types/src/_deprecated/components/Table/TableBody.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Table/TableContext.d.ts +1 -1
- package/dist/types/src/_deprecated/components/Table/TableContext.d.ts.map +1 -1
- package/dist/types/src/_deprecated/components/Table/TableHead.d.ts +1 -2
- package/dist/types/src/_deprecated/components/Table/TableHead.d.ts.map +1 -1
- package/dist/types/src/_deprecated/schema/Schema.stories.d.ts +2 -3
- package/dist/types/src/_deprecated/schema/Schema.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -2
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +1 -2
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +1 -2
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/RefPanel.d.ts +1 -2
- package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -2
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +1 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +1 -2
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +1 -2
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +11 -10
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +17 -14
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +36 -35
- package/src/_deprecated/schema/Schema.stories.tsx +1 -1
- package/src/components/Table/Table.stories.tsx +22 -23
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +1 -1
- package/src/hooks/useTableModel.ts +21 -0
- package/src/model/table-model.ts +1 -1
- package/src/model/table-presentation.ts +13 -1
- package/src/model/table-sorting.ts +14 -0
- package/src/playwright/smoke.spec.ts +3 -3
- package/src/util/table-buttons.ts +1 -1
- package/src/util/table-controls.ts +2 -2
- package/src/util/table.ts +1 -1
- package/dist/types/src/playwright/playwright.config.d.ts +0 -3
- package/dist/types/src/playwright/playwright.config.d.ts.map +0 -1
- /package/src/playwright/{playwright.config.ts → playwright.config.cts} +0 -0
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import { type EchoSchema } from '@dxos/echo-schema';
|
|
11
10
|
import { invariant } from '@dxos/invariant';
|
|
12
11
|
import { useGlobalFilteredObjects } from '@dxos/plugin-search';
|
|
13
12
|
import { faker } from '@dxos/random';
|
|
14
|
-
import { Filter, useQuery, create } from '@dxos/react-client/echo';
|
|
13
|
+
import { Filter, useQuery, useSchema, create } from '@dxos/react-client/echo';
|
|
15
14
|
import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
|
|
16
15
|
import { useDefaultValue } from '@dxos/react-ui';
|
|
17
16
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
@@ -41,13 +40,13 @@ const DefaultStory = () => {
|
|
|
41
40
|
|
|
42
41
|
const tables = useQuery(space, Filter.schema(TableType));
|
|
43
42
|
const [table, setTable] = useState<TableType>();
|
|
44
|
-
const
|
|
43
|
+
const schema = useSchema(space, table?.view?.target?.query.type);
|
|
44
|
+
|
|
45
45
|
useEffect(() => {
|
|
46
46
|
if (space && tables.length && !table) {
|
|
47
47
|
const table = tables[0];
|
|
48
48
|
invariant(table.view);
|
|
49
49
|
setTable(table);
|
|
50
|
-
setSchema(space.db.schemaRegistry.getSchema(table.view.target!.query.type));
|
|
51
50
|
}
|
|
52
51
|
}, [space, tables]);
|
|
53
52
|
|
|
@@ -175,7 +174,7 @@ type StoryProps = {
|
|
|
175
174
|
rows?: number;
|
|
176
175
|
} & Pick<SimulatorProps, 'insertInterval' | 'updateInterval'>;
|
|
177
176
|
|
|
178
|
-
const
|
|
177
|
+
const _TablePerformanceStory = (props: StoryProps) => {
|
|
179
178
|
const getDefaultRows = useCallback(() => 10, []);
|
|
180
179
|
const rows = useDefaultValue(props.rows, getDefaultRows);
|
|
181
180
|
const table = useMemo(() => createTable(), []);
|
|
@@ -248,22 +247,22 @@ const meta: Meta<StoryProps> = {
|
|
|
248
247
|
|
|
249
248
|
export default meta;
|
|
250
249
|
|
|
251
|
-
type Story = StoryObj<StoryProps>;
|
|
252
|
-
|
|
253
250
|
export const Default = {};
|
|
254
251
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
252
|
+
// TODO(ZaymonFC): Restore the performance stories.
|
|
253
|
+
// type Story = StoryObj<StoryProps>;
|
|
254
|
+
// export const Mutations: Story = {
|
|
255
|
+
// render: TablePerformanceStory,
|
|
256
|
+
// args: {
|
|
257
|
+
// rows: 1000,
|
|
258
|
+
// updateInterval: 1,
|
|
259
|
+
// },
|
|
260
|
+
// };
|
|
261
|
+
|
|
262
|
+
// export const RapidInsertions: Story = {
|
|
263
|
+
// render: TablePerformanceStory,
|
|
264
|
+
// args: {
|
|
265
|
+
// rows: 0,
|
|
266
|
+
// insertInterval: 100,
|
|
267
|
+
// },
|
|
268
|
+
// };
|
|
@@ -38,7 +38,7 @@ const DefaultStory = ({ editing }: StoryProps) => {
|
|
|
38
38
|
const table = tables[0];
|
|
39
39
|
invariant(table.view);
|
|
40
40
|
setTable(table);
|
|
41
|
-
setSchema(space.db.schemaRegistry.getSchema(table.view.target!.query.type));
|
|
41
|
+
setSchema(space.db.schemaRegistry.getSchema(table.view.target!.query.type!));
|
|
42
42
|
}
|
|
43
43
|
}, [space, tables]);
|
|
44
44
|
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { effect } from '@preact/signals-core';
|
|
5
6
|
import { useEffect, useState } from 'react';
|
|
6
7
|
|
|
7
8
|
import { type ReactiveObject } from '@dxos/react-client/echo';
|
|
9
|
+
import { useSelectionActions } from '@dxos/react-ui-attention';
|
|
8
10
|
import { type ViewProjection } from '@dxos/schema';
|
|
11
|
+
import { isNonNullable } from '@dxos/util';
|
|
9
12
|
|
|
10
13
|
import { type BaseTableRow, TableModel, type TableModelProps } from '../model';
|
|
11
14
|
import { type TableType } from '../types';
|
|
@@ -48,5 +51,23 @@ export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
|
48
51
|
}
|
|
49
52
|
}, [model, objects]);
|
|
50
53
|
|
|
54
|
+
const { select, clear } = useSelectionActions([table?.id, table?.view?.target?.query.type].filter(isNonNullable));
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!model) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const unsubscribe = effect(() => {
|
|
62
|
+
select([...model.selection.selection.value]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Maybe clear the selection here?
|
|
66
|
+
return () => {
|
|
67
|
+
clear();
|
|
68
|
+
unsubscribe();
|
|
69
|
+
};
|
|
70
|
+
}, [model]);
|
|
71
|
+
|
|
51
72
|
return model;
|
|
52
73
|
};
|
package/src/model/table-model.ts
CHANGED
|
@@ -68,7 +68,8 @@ export class TablePresentation<T extends BaseTableRow = { id: string }> {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
switch (props.format) {
|
|
71
|
-
case FormatEnum.Boolean:
|
|
71
|
+
case FormatEnum.Boolean:
|
|
72
|
+
case FormatEnum.SingleSelect: {
|
|
72
73
|
return '';
|
|
73
74
|
}
|
|
74
75
|
case FormatEnum.Ref: {
|
|
@@ -119,6 +120,17 @@ export class TablePresentation<T extends BaseTableRow = { id: string }> {
|
|
|
119
120
|
cell.readonly = true;
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
if (props.format === FormatEnum.SingleSelect) {
|
|
124
|
+
const value = getValue(obj, field.path);
|
|
125
|
+
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
126
|
+
if (options) {
|
|
127
|
+
const option = options.find((o) => o.id === value);
|
|
128
|
+
if (option) {
|
|
129
|
+
cell.accessoryHtml = `<span class="dx-tag" data-hue="${option.color}">${option.title}</span>`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
122
134
|
const idx = toPlaneCellIndex({ col: colIndex, row: displayIndex });
|
|
123
135
|
cells[idx] = cell;
|
|
124
136
|
};
|
|
@@ -188,6 +188,20 @@ export class TableSorting<T extends BaseTableRow> {
|
|
|
188
188
|
return value;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* For single select fields, the sort value is determined by the index of the option in the
|
|
193
|
+
* options array. This ensures sort order matches the configured option order.
|
|
194
|
+
*/
|
|
195
|
+
if (format === FormatEnum.SingleSelect) {
|
|
196
|
+
const options = props.options;
|
|
197
|
+
if (!options) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const option = options.find((option) => option.id === value);
|
|
202
|
+
return option ? options.indexOf(option) : undefined;
|
|
203
|
+
}
|
|
204
|
+
|
|
191
205
|
// TODO(ZaymonFC): Should we format this returned value for display based on the referenced prop format?
|
|
192
206
|
// Right now we're going to be sorting based on the raw values.
|
|
193
207
|
// Maybe we need to recurse this function with the referenced prop format and field?
|
|
@@ -145,7 +145,7 @@ test.describe('Table', () => {
|
|
|
145
145
|
await page.getByRole('option', { name: 'Anita Mayer' }).click();
|
|
146
146
|
|
|
147
147
|
// Assert that the value is shown in the cell.
|
|
148
|
-
await expect(page.getByRole('gridcell', { name: 'Anita Mayer' })).toBeVisible();
|
|
148
|
+
await expect(page.getByRole('gridcell', { name: 'Anita Mayer' }).first()).toBeVisible();
|
|
149
149
|
|
|
150
150
|
// Create new object.
|
|
151
151
|
await table.grid.cell(4, 1, 'grid').click();
|
|
@@ -157,7 +157,7 @@ test.describe('Table', () => {
|
|
|
157
157
|
await page.getByTestId('save-button').click();
|
|
158
158
|
|
|
159
159
|
// Scroll to the left.
|
|
160
|
-
await page.getByRole('gridcell', { name: 'test' }).click();
|
|
160
|
+
await page.getByRole('gridcell', { name: 'test' }).first().click();
|
|
161
161
|
|
|
162
162
|
await page.close();
|
|
163
163
|
});
|
|
@@ -173,7 +173,7 @@ test.describe('Table', () => {
|
|
|
173
173
|
await page.getByTestId('table-switch').nth(7).click();
|
|
174
174
|
|
|
175
175
|
// Test that checks are durable in the data model by sorting.
|
|
176
|
-
await table.sortColumn(
|
|
176
|
+
await table.sortColumn(3, 'descending');
|
|
177
177
|
|
|
178
178
|
// Assert the first two switch checkboxes are checked.
|
|
179
179
|
await expect(page.getByTestId('table-switch').first()).toBeChecked();
|
|
@@ -39,7 +39,7 @@ const createButton = ({
|
|
|
39
39
|
.join(' ');
|
|
40
40
|
|
|
41
41
|
const positionClass = type === 'primary' ? 'inline-end-2' : 'inline-end-9';
|
|
42
|
-
return `<button ${attr} data-testid="${testId}" class="
|
|
42
|
+
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><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const addColumnButton = {
|
|
@@ -23,8 +23,8 @@ export const CONTROL_IDENTIFIERS = {
|
|
|
23
23
|
} as const;
|
|
24
24
|
|
|
25
25
|
const BASE_CLASSES = {
|
|
26
|
-
checkbox: 'absolute inset-block-[.375rem] inline-end-[.375rem]
|
|
27
|
-
switch: 'absolute inset-block-[.25rem] inline-end-[.25rem]
|
|
26
|
+
checkbox: 'absolute inset-block-[.375rem] inline-end-[.375rem] dx-checkbox',
|
|
27
|
+
switch: 'absolute inset-block-[.25rem] inline-end-[.25rem] dx-checkbox--switch',
|
|
28
28
|
} as const;
|
|
29
29
|
|
|
30
30
|
const renderAttributes = (data: Record<string, string>) => {
|
package/src/util/table.ts
CHANGED
|
@@ -46,7 +46,7 @@ export const initializeTable = async ({
|
|
|
46
46
|
// We need to get the schema properties here. For now, only simple types and refs, not compound types
|
|
47
47
|
// are going to be supported.
|
|
48
48
|
const fields = getSchemaProperties(schema.ast)
|
|
49
|
-
.filter((prop) => prop.
|
|
49
|
+
.filter((prop) => prop.format !== FormatEnum.Ref)
|
|
50
50
|
.map((prop) => prop.name);
|
|
51
51
|
|
|
52
52
|
table.view = makeRef(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["../../../../src/playwright/playwright.config.ts"],"names":[],"mappings":";AASA,wBAQG"}
|
|
File without changes
|