@dxos/react-ui-table 0.8.4-main.28f8d3d → 0.8.4-main.2c6827d
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-2PFAPQL4.mjs +66 -0
- package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ZAOSIG3L.mjs → chunk-GS2UNGJK.mjs} +174 -213
- package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +411 -515
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +12 -9
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs +67 -0
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ZOFFI3JJ.mjs → chunk-TRR3C5NX.mjs} +174 -213
- package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +411 -515
- 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 +12 -9
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/components/Table/DynamicTable.d.ts +2 -2
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +51 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +103 -5
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +8 -5
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +41 -3
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -6
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +8 -13
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
- package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +3 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +3 -2
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +3 -3
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +0 -7
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +9 -8
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +1 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +2 -3
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +3 -22
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +25 -5
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +5 -6
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +53 -51
- package/src/components/Table/DynamicTable.stories.tsx +15 -12
- package/src/components/Table/DynamicTable.tsx +4 -7
- package/src/components/Table/Relations.stories.tsx +160 -42
- package/src/components/Table/RowActionsMenu.tsx +21 -13
- package/src/components/Table/Table.stories.tsx +63 -56
- package/src/components/Table/Table.tsx +109 -90
- package/src/components/TableCellEditor/FormCellEditor.tsx +153 -42
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +24 -64
- package/src/components/TableCellEditor/TableCellEditor.tsx +62 -208
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +32 -22
- package/src/components/testing.ts +2 -2
- package/src/hooks/useAddRow.ts +7 -5
- package/src/hooks/useTableModel.ts +5 -5
- package/src/model/modal-controller.ts +0 -28
- package/src/model/table-model.test.ts +19 -11
- package/src/model/table-model.ts +36 -24
- package/src/model/table-presentation.test.ts +22 -21
- package/src/model/table-presentation.ts +58 -39
- package/src/model/table-sorting.ts +16 -7
- package/src/playwright/TableManager.ts +1 -1
- package/src/playwright/smoke.spec.ts +51 -49
- package/src/testing/useTestTableModel.ts +10 -7
- package/src/types/index.ts +1 -1
- package/src/types/schema.ts +63 -6
- package/src/util/dynamic-table.ts +15 -16
- package/src/util/index.ts +0 -1
- package/src/util/schema.ts +4 -4
- package/src/util/table-buttons.ts +3 -3
- package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
- package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +0 -7
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -12
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -86
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/util/table.ts +0 -53
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { expect, test } from '@playwright/test';
|
|
6
6
|
|
|
7
7
|
import { type DxGrid } from '@dxos/lit-grid';
|
|
8
|
+
import { faker } from '@dxos/random';
|
|
8
9
|
import { setupPage, storybookUrl } from '@dxos/test-utils/playwright';
|
|
9
10
|
|
|
10
11
|
import { TableManager } from './TableManager';
|
|
@@ -16,6 +17,7 @@ const relationsStoryUrl = storybookUrl('ui-react-ui-table-relations--default', 9
|
|
|
16
17
|
test.describe('Table', () => {
|
|
17
18
|
test('Loads', async ({ browser, browserName }) => {
|
|
18
19
|
test.skip(browserName === 'webkit');
|
|
20
|
+
test.skip(browserName === 'firefox');
|
|
19
21
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
20
22
|
const table = new TableManager(page);
|
|
21
23
|
|
|
@@ -25,6 +27,7 @@ test.describe('Table', () => {
|
|
|
25
27
|
|
|
26
28
|
test('sort', async ({ browser, browserName }) => {
|
|
27
29
|
test.skip(browserName === 'webkit');
|
|
30
|
+
test.skip(browserName === 'firefox');
|
|
28
31
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
29
32
|
const table = new TableManager(page);
|
|
30
33
|
|
|
@@ -41,6 +44,7 @@ test.describe('Table', () => {
|
|
|
41
44
|
|
|
42
45
|
test('selection', async ({ browser, browserName }) => {
|
|
43
46
|
test.skip(browserName === 'webkit');
|
|
47
|
+
test.skip(browserName === 'firefox');
|
|
44
48
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
45
49
|
const table = new TableManager(page);
|
|
46
50
|
|
|
@@ -62,6 +66,7 @@ test.describe('Table', () => {
|
|
|
62
66
|
|
|
63
67
|
test('delete row', async ({ browser, browserName }) => {
|
|
64
68
|
test.skip(browserName === 'webkit');
|
|
69
|
+
test.skip(browserName === 'firefox');
|
|
65
70
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
66
71
|
const table = new TableManager(page);
|
|
67
72
|
|
|
@@ -73,6 +78,7 @@ test.describe('Table', () => {
|
|
|
73
78
|
|
|
74
79
|
test('delete row--select all', async ({ browser, browserName }) => {
|
|
75
80
|
test.skip(browserName === 'webkit');
|
|
81
|
+
test.skip(browserName === 'firefox');
|
|
76
82
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
77
83
|
const table = new TableManager(page);
|
|
78
84
|
|
|
@@ -90,6 +96,7 @@ test.describe('Table', () => {
|
|
|
90
96
|
|
|
91
97
|
test('delete column', async ({ browser, browserName }) => {
|
|
92
98
|
test.skip(browserName === 'webkit');
|
|
99
|
+
test.skip(browserName === 'firefox');
|
|
93
100
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
94
101
|
const table = new TableManager(page);
|
|
95
102
|
|
|
@@ -116,6 +123,7 @@ test.describe('Table', () => {
|
|
|
116
123
|
// Rest of add column test remains the same as it's a more complex flow.
|
|
117
124
|
test('add column', async ({ browser, browserName }) => {
|
|
118
125
|
test.skip(browserName === 'webkit');
|
|
126
|
+
test.skip(browserName === 'firefox');
|
|
119
127
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
120
128
|
const table = new TableManager(page);
|
|
121
129
|
|
|
@@ -128,44 +136,9 @@ test.describe('Table', () => {
|
|
|
128
136
|
await page.close();
|
|
129
137
|
});
|
|
130
138
|
|
|
131
|
-
test('
|
|
132
|
-
test.skip(browserName === 'webkit');
|
|
133
|
-
const { page } = await setupPage(browser, { url: storyUrl });
|
|
134
|
-
const table = new TableManager(page);
|
|
135
|
-
|
|
136
|
-
await table.grid.ready();
|
|
137
|
-
|
|
138
|
-
// Reference existing object.
|
|
139
|
-
// Scroll over to the manager column.
|
|
140
|
-
await table.grid.panByWheel(10000, 0);
|
|
141
|
-
|
|
142
|
-
await table.grid.cell(4, 0, 'grid').click();
|
|
143
|
-
// TODO(wittjosiah): Surprisingly long delay needed here.
|
|
144
|
-
await page.keyboard.press('A', { delay: 1_000 });
|
|
145
|
-
await page.keyboard.press('u', { delay: 1_000 });
|
|
146
|
-
await page.getByRole('option', { name: 'Aut.' }).click();
|
|
147
|
-
|
|
148
|
-
// Assert that the value is shown in the cell.
|
|
149
|
-
await expect(page.getByRole('gridcell', { name: 'Aut.' }).first()).toBeVisible();
|
|
150
|
-
|
|
151
|
-
// Create new object.
|
|
152
|
-
await table.grid.cell(4, 1, 'grid').click();
|
|
153
|
-
// TODO(wittjosiah): Surprisingly long delay needed here.
|
|
154
|
-
await page.keyboard.type('t', { delay: 1_000 });
|
|
155
|
-
await page.keyboard.type('e', { delay: 1_000 });
|
|
156
|
-
await page.keyboard.type('s', { delay: 1_000 });
|
|
157
|
-
await page.keyboard.type('t', { delay: 1_000 });
|
|
158
|
-
await page.getByText('Create new object', { exact: false }).click();
|
|
159
|
-
await page.getByTestId('save-button').click();
|
|
160
|
-
|
|
161
|
-
// Scroll to the left.
|
|
162
|
-
await page.getByRole('gridcell', { name: 'test' }).first().click();
|
|
163
|
-
|
|
164
|
-
await page.close();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test('test toggles', async ({ browser, browserName }) => {
|
|
139
|
+
test.skip('test toggles', async ({ browser, browserName }) => {
|
|
168
140
|
test.skip(browserName === 'webkit');
|
|
141
|
+
test.skip(browserName === 'firefox');
|
|
169
142
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
170
143
|
const table = new TableManager(page);
|
|
171
144
|
|
|
@@ -186,8 +159,10 @@ test.describe('Table', () => {
|
|
|
186
159
|
await page.close();
|
|
187
160
|
});
|
|
188
161
|
|
|
189
|
-
|
|
162
|
+
// TODO(wittjosiah): Remove? Conflicts with story play function which is run as a unit test anyways.
|
|
163
|
+
test.skip('extant relations work as expected', async ({ browser, browserName }) => {
|
|
190
164
|
test.skip(browserName === 'webkit');
|
|
165
|
+
test.skip(browserName === 'firefox');
|
|
191
166
|
const { page } = await setupPage(browser, { url: relationsStoryUrl });
|
|
192
167
|
|
|
193
168
|
// Wait for the page to load
|
|
@@ -198,18 +173,22 @@ test.describe('Table', () => {
|
|
|
198
173
|
const dxGrid = page.locator('dx-grid').nth(1);
|
|
199
174
|
await dxGrid.waitFor({ state: 'visible' });
|
|
200
175
|
|
|
201
|
-
// Scroll to the last column (column
|
|
176
|
+
// Scroll to the last column (column 4)
|
|
202
177
|
await dxGrid.evaluate(async (dxGridElement: DxGrid) => {
|
|
203
|
-
dxGridElement.scrollToColumn(
|
|
178
|
+
dxGridElement.scrollToColumn(4);
|
|
204
179
|
});
|
|
205
180
|
|
|
206
|
-
// Click on the cell at aria-rowindex=0 aria-colindex=
|
|
207
|
-
const targetCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="
|
|
181
|
+
// Click on the cell at aria-rowindex=0 aria-colindex=4 to focus it
|
|
182
|
+
const targetCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="4"]');
|
|
208
183
|
await targetCell.click();
|
|
209
184
|
|
|
210
185
|
// Click again to engage edit mode
|
|
211
186
|
await page.keyboard.press('Enter');
|
|
212
|
-
|
|
187
|
+
|
|
188
|
+
// Click on the combobox to open options
|
|
189
|
+
await page.getByRole('combobox').click();
|
|
190
|
+
await page.pause();
|
|
191
|
+
await page.getByPlaceholder('Search…').focus();
|
|
213
192
|
|
|
214
193
|
// Type the first few letters of an org name.
|
|
215
194
|
const orgName =
|
|
@@ -226,14 +205,19 @@ test.describe('Table', () => {
|
|
|
226
205
|
// Type the enter key
|
|
227
206
|
await page.keyboard.press('Enter');
|
|
228
207
|
|
|
208
|
+
// Save the result
|
|
209
|
+
await page.getByTestId('save-button').click();
|
|
210
|
+
|
|
229
211
|
// Assert that the cell element has the org name
|
|
230
212
|
await expect(targetCell).toHaveText(orgName);
|
|
231
213
|
|
|
232
214
|
await page.close();
|
|
233
215
|
});
|
|
234
216
|
|
|
235
|
-
|
|
217
|
+
// TODO(wittjosiah): Remove? Conflicts with story play function which is run as a unit test anyways.
|
|
218
|
+
test.skip('new relations work as expected', async ({ browser, browserName }) => {
|
|
236
219
|
test.skip(browserName === 'webkit');
|
|
220
|
+
test.skip(browserName === 'firefox');
|
|
237
221
|
const { page } = await setupPage(browser, { url: relationsStoryUrl });
|
|
238
222
|
|
|
239
223
|
// Wait for the page to load
|
|
@@ -244,18 +228,21 @@ test.describe('Table', () => {
|
|
|
244
228
|
const dxGrid = page.locator('dx-grid').nth(1);
|
|
245
229
|
await dxGrid.waitFor({ state: 'visible' });
|
|
246
230
|
|
|
247
|
-
// Scroll to the last column (column
|
|
231
|
+
// Scroll to the last column (column 4)
|
|
248
232
|
await dxGrid.evaluate(async (dxGridElement: DxGrid) => {
|
|
249
|
-
dxGridElement.scrollToColumn(
|
|
233
|
+
dxGridElement.scrollToColumn(4);
|
|
250
234
|
});
|
|
251
235
|
|
|
252
236
|
// 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="
|
|
237
|
+
const targetCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="4"]');
|
|
254
238
|
await targetCell.click();
|
|
255
239
|
|
|
256
240
|
// Click again to engage edit mode
|
|
257
241
|
await page.keyboard.press('Enter');
|
|
258
|
-
|
|
242
|
+
|
|
243
|
+
// Click on the combobox to open options
|
|
244
|
+
await page.getByRole('combobox').click();
|
|
245
|
+
await page.getByPlaceholder('Search…').focus();
|
|
259
246
|
|
|
260
247
|
// Type the first few letters of an org name.
|
|
261
248
|
const orgName = 'Sally';
|
|
@@ -266,13 +253,28 @@ test.describe('Table', () => {
|
|
|
266
253
|
|
|
267
254
|
// Type the enter key
|
|
268
255
|
await page.keyboard.press('Enter');
|
|
256
|
+
await page.pause();
|
|
269
257
|
|
|
270
258
|
// Click the save button in the popover
|
|
271
|
-
await page.getByTestId('save-button').click();
|
|
259
|
+
await page.getByTestId('create-referenced-object-form').getByTestId('save-button').click();
|
|
272
260
|
|
|
273
261
|
// Assert that the cell element has the org name
|
|
274
262
|
await expect(targetCell).toHaveText(orgName);
|
|
275
263
|
|
|
264
|
+
// Make a change to a non-ref cell to check that populated refs don’t cause problems with snapshots or schemas.
|
|
265
|
+
await dxGrid.evaluate(async (dxGridElement: DxGrid) => {
|
|
266
|
+
dxGridElement.scrollToColumn(6);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const nonRefContent = faker.lorem.words(3);
|
|
270
|
+
const nonRefCell = dxGrid.locator('[data-dx-grid-plane="grid"] [aria-rowindex="0"][aria-colindex="6"]');
|
|
271
|
+
await nonRefCell.click();
|
|
272
|
+
await page.keyboard.press('Enter');
|
|
273
|
+
await page.getByTestId('grid.cell-editor').waitFor({ state: 'visible' });
|
|
274
|
+
await page.keyboard.type(nonRefContent, { delay: 500 });
|
|
275
|
+
await page.keyboard.press('Enter');
|
|
276
|
+
await expect(nonRefCell).toHaveText(nonRefContent);
|
|
277
|
+
|
|
276
278
|
await page.close();
|
|
277
279
|
});
|
|
278
280
|
});
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import { useCallback, useMemo, useRef } from 'react';
|
|
6
6
|
|
|
7
|
-
import { isMutable, toJsonSchema } from '@dxos/echo
|
|
7
|
+
import { isMutable, toJsonSchema } from '@dxos/echo/internal';
|
|
8
8
|
import { useGlobalFilteredObjects } from '@dxos/plugin-search';
|
|
9
9
|
import { faker } from '@dxos/random';
|
|
10
10
|
import { useClient } from '@dxos/react-client';
|
|
11
11
|
import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
|
|
12
12
|
import { useClientProvider } from '@dxos/react-client/testing';
|
|
13
|
-
import {
|
|
13
|
+
import { ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
|
|
14
14
|
|
|
15
15
|
import { type TableController } from '../components';
|
|
16
16
|
import { useAddRow, useTableModel } from '../hooks';
|
|
@@ -26,14 +26,17 @@ export const useTestTableModel = () => {
|
|
|
26
26
|
const client = useClient();
|
|
27
27
|
const { space } = useClientProvider();
|
|
28
28
|
|
|
29
|
-
const views = useQuery(space, Filter.type(
|
|
29
|
+
const views = useQuery(space, Filter.type(View.View));
|
|
30
30
|
const view = useMemo(() => views.at(0), [views]);
|
|
31
|
-
const
|
|
31
|
+
const typename = view?.query ? getTypenameFromQuery(view.query.ast) : undefined;
|
|
32
|
+
const schema = useSchema(client, space, typename);
|
|
32
33
|
const jsonSchema = useMemo(() => (schema ? toJsonSchema(schema) : undefined), [schema]);
|
|
33
34
|
|
|
34
35
|
const projection = useMemo(() => {
|
|
35
36
|
if (schema && view?.projection) {
|
|
36
|
-
|
|
37
|
+
const projection = new ProjectionModel(toJsonSchema(schema), view.projection);
|
|
38
|
+
projection.normalizeView();
|
|
39
|
+
return projection;
|
|
37
40
|
}
|
|
38
41
|
}, [schema, view?.projection]);
|
|
39
42
|
|
|
@@ -92,8 +95,8 @@ export const useTestTableModel = () => {
|
|
|
92
95
|
});
|
|
93
96
|
|
|
94
97
|
const handleInsertRow = useCallback(() => {
|
|
95
|
-
model?.insertRow();
|
|
96
|
-
tableRef.current?.
|
|
98
|
+
const insertResult = model?.insertRow();
|
|
99
|
+
tableRef.current?.handleInsertRowResult?.(insertResult);
|
|
97
100
|
}, [model, tableRef.current]);
|
|
98
101
|
|
|
99
102
|
const handleSaveView = useCallback(() => {
|
package/src/types/index.ts
CHANGED
package/src/types/schema.ts
CHANGED
|
@@ -2,15 +2,72 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Match from 'effect/Match';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
6
7
|
|
|
7
|
-
import { Type } from '@dxos/echo';
|
|
8
|
-
import { JsonPath } from '@dxos/
|
|
8
|
+
import { Obj, Type } from '@dxos/echo';
|
|
9
|
+
import { JsonPath, type JsonSchemaType, toEffectSchema } from '@dxos/echo/internal';
|
|
10
|
+
import { ViewAnnotation } from '@dxos/echo/internal';
|
|
11
|
+
import { type SimpleType } from '@dxos/effect';
|
|
12
|
+
import { View, getSchemaProperties } from '@dxos/schema';
|
|
9
13
|
|
|
10
|
-
export const
|
|
14
|
+
export const Table = Schema.Struct({
|
|
11
15
|
sizes: Schema.Record({
|
|
12
16
|
key: JsonPath,
|
|
13
17
|
value: Schema.Number,
|
|
14
18
|
}).pipe(Schema.mutable),
|
|
15
|
-
}).pipe(
|
|
16
|
-
|
|
19
|
+
}).pipe(
|
|
20
|
+
Type.Obj({
|
|
21
|
+
typename: 'dxos.org/type/Table',
|
|
22
|
+
version: '0.1.0',
|
|
23
|
+
}),
|
|
24
|
+
ViewAnnotation.set(true),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export type Table = Schema.Schema.Type<typeof Table>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Make a table view.
|
|
31
|
+
*/
|
|
32
|
+
export const make = (props: Partial<Obj.MakeProps<typeof Table>> = {}) => Obj.make(Table, { sizes: {}, ...props });
|
|
33
|
+
|
|
34
|
+
type MakeViewProps = Omit<View.MakeFromSpaceProps, 'presentation'> & {
|
|
35
|
+
sizes?: Record<string, number>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const makeView = async ({
|
|
39
|
+
sizes,
|
|
40
|
+
...props
|
|
41
|
+
}: MakeViewProps): Promise<{
|
|
42
|
+
jsonSchema: JsonSchemaType;
|
|
43
|
+
view: View.View;
|
|
44
|
+
schema: ReturnType<typeof toEffectSchema>;
|
|
45
|
+
}> => {
|
|
46
|
+
const table = Obj.make(Table, { sizes: {} });
|
|
47
|
+
const { jsonSchema, view } = await View.makeFromSpace({ ...props, presentation: table });
|
|
48
|
+
|
|
49
|
+
// Preset sizes.
|
|
50
|
+
const schema = toEffectSchema(jsonSchema);
|
|
51
|
+
const shouldIncludeId = props.fields?.find((field) => field === 'id') !== undefined;
|
|
52
|
+
const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
|
|
53
|
+
for (const property of properties) {
|
|
54
|
+
if (sizes?.[property.name]) {
|
|
55
|
+
table.sizes[property.name as JsonPath] = sizes[property.name];
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Match.type<SimpleType>().pipe(
|
|
60
|
+
Match.when('boolean', () => {
|
|
61
|
+
table.sizes[property.name as JsonPath] = 100;
|
|
62
|
+
}),
|
|
63
|
+
Match.when('number', () => {
|
|
64
|
+
table.sizes[property.name as JsonPath] = 100;
|
|
65
|
+
}),
|
|
66
|
+
Match.orElse(() => {
|
|
67
|
+
// Noop.
|
|
68
|
+
}),
|
|
69
|
+
)(property.type);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { jsonSchema, schema, view };
|
|
73
|
+
};
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
import { Obj } from '@dxos/echo';
|
|
8
|
-
import { getTypename, toJsonSchema } from '@dxos/echo
|
|
9
|
-
import type { JsonSchemaType
|
|
7
|
+
import { Filter, Obj, Query } from '@dxos/echo';
|
|
8
|
+
import { getTypename, toJsonSchema } from '@dxos/echo/internal';
|
|
9
|
+
import type { JsonSchemaType } from '@dxos/echo/internal';
|
|
10
10
|
import {
|
|
11
|
-
type DataType,
|
|
12
11
|
ProjectionModel,
|
|
13
12
|
type SchemaPropertyDefinition,
|
|
14
|
-
|
|
13
|
+
type SortDirectionType,
|
|
14
|
+
View,
|
|
15
15
|
getSchemaFromPropertyDefinitions,
|
|
16
16
|
} from '@dxos/schema';
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { Table } from '../types';
|
|
19
19
|
|
|
20
20
|
// TODO(ZaymonFC): Upstream these extra fields to SchemaPropertyDefinition to enhance schema-tools schema creation.
|
|
21
21
|
type PropertyDisplayProps = {
|
|
@@ -54,23 +54,22 @@ export const getBaseSchema = ({
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
export const makeDynamicTable = ({
|
|
57
|
-
typename,
|
|
58
57
|
jsonSchema,
|
|
59
58
|
properties,
|
|
60
59
|
}: {
|
|
61
|
-
typename: string;
|
|
62
60
|
jsonSchema: JsonSchemaType;
|
|
63
61
|
properties?: TablePropertyDefinition[];
|
|
64
|
-
}): { projection: ProjectionModel; view:
|
|
65
|
-
const table = Obj.make(
|
|
66
|
-
const view =
|
|
67
|
-
|
|
62
|
+
}): { projection: ProjectionModel; view: View.View } => {
|
|
63
|
+
const table = Obj.make(Table.Table, { sizes: {} });
|
|
64
|
+
const view = View.make({
|
|
65
|
+
query: Query.select(Filter.everything()),
|
|
68
66
|
jsonSchema,
|
|
69
67
|
presentation: table,
|
|
70
68
|
...(properties && { fields: properties.map((property) => property.name) }),
|
|
71
69
|
});
|
|
72
70
|
|
|
73
71
|
const projection = new ProjectionModel(jsonSchema, view.projection);
|
|
72
|
+
projection.normalizeView();
|
|
74
73
|
if (properties && projection.fields) {
|
|
75
74
|
setProperties(view, projection, table, properties);
|
|
76
75
|
}
|
|
@@ -79,9 +78,9 @@ export const makeDynamicTable = ({
|
|
|
79
78
|
};
|
|
80
79
|
|
|
81
80
|
const setProperties = (
|
|
82
|
-
view:
|
|
81
|
+
view: View.View,
|
|
83
82
|
projection: ProjectionModel,
|
|
84
|
-
table:
|
|
83
|
+
table: Table.Table,
|
|
85
84
|
properties: TablePropertyDefinition[],
|
|
86
85
|
) => {
|
|
87
86
|
for (const property of properties) {
|
|
@@ -101,7 +100,7 @@ const setProperties = (
|
|
|
101
100
|
|
|
102
101
|
if (property.sort) {
|
|
103
102
|
const fieldId = field.id;
|
|
104
|
-
view.
|
|
103
|
+
view.sort = [{ fieldId, direction: property.sort }];
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
}
|
package/src/util/index.ts
CHANGED
package/src/util/schema.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates a narrowed schema from an original schema that only includes
|
|
@@ -20,14 +20,14 @@ export const narrowSchema = <S extends Schema.Schema.AnyNoContext>(
|
|
|
20
20
|
): Schema.Schema<unknown, unknown> | undefined => {
|
|
21
21
|
const ast = (schema as any)?.ast;
|
|
22
22
|
|
|
23
|
-
if (isTypeLiteral(ast)) {
|
|
23
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
24
24
|
// Filter property signatures that match any of the provided paths
|
|
25
25
|
const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
|
|
26
26
|
|
|
27
27
|
// If we found at least one matching property
|
|
28
28
|
if (propertySignatures.length > 0) {
|
|
29
29
|
// Create a new TypeLiteral with only the matching properties
|
|
30
|
-
const narrowType = new TypeLiteral(propertySignatures, []);
|
|
30
|
+
const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
|
|
31
31
|
return Schema.make(narrowType);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -26,7 +26,7 @@ const createButton = ({
|
|
|
26
26
|
disabled = false,
|
|
27
27
|
icon,
|
|
28
28
|
testId,
|
|
29
|
-
type = 'primary',
|
|
29
|
+
type: _type = 'primary',
|
|
30
30
|
}: {
|
|
31
31
|
attr: string;
|
|
32
32
|
data: Record<string, string>;
|
|
@@ -39,8 +39,7 @@ const createButton = ({
|
|
|
39
39
|
.map(([k, v]) => `${k}="${v}"`)
|
|
40
40
|
.join(' ');
|
|
41
41
|
|
|
42
|
-
|
|
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>`;
|
|
42
|
+
return `<button ${attr} data-testid="${testId}" class="dx-button is-6 aspect-square pli-0.5 min-bs-0" ${dataAttrs} ${disabled ? 'disabled' : ''} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
44
43
|
};
|
|
45
44
|
|
|
46
45
|
const addColumnButton = {
|
|
@@ -67,6 +66,7 @@ const columnSettingsButton = {
|
|
|
67
66
|
icon: columnSettingsButton.icon,
|
|
68
67
|
data: {
|
|
69
68
|
'data-field-id': fieldId,
|
|
69
|
+
'data-variant': 'ghost',
|
|
70
70
|
},
|
|
71
71
|
testId: 'table-column-settings-button',
|
|
72
72
|
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// src/types/schema.ts
|
|
2
|
-
import { Schema } from "effect";
|
|
3
|
-
import { Type } from "@dxos/echo";
|
|
4
|
-
import { JsonPath } from "@dxos/effect";
|
|
5
|
-
var TableView = Schema.Struct({
|
|
6
|
-
sizes: Schema.Record({
|
|
7
|
-
key: JsonPath,
|
|
8
|
-
value: Schema.Number
|
|
9
|
-
}).pipe(Schema.mutable)
|
|
10
|
-
}).pipe(Type.Obj({
|
|
11
|
-
typename: "dxos.org/type/TableView",
|
|
12
|
-
version: "0.1.0"
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
TableView
|
|
17
|
-
};
|
|
18
|
-
//# sourceMappingURL=chunk-L2LSB6KV.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/types/schema.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { Type } from '@dxos/echo';\nimport { JsonPath } from '@dxos/effect';\n\nexport const TableView = Schema.Struct({\n sizes: Schema.Record({\n key: JsonPath,\n value: Schema.Number,\n }).pipe(Schema.mutable),\n}).pipe(Type.Obj({ typename: 'dxos.org/type/TableView', version: '0.1.0' }));\nexport type TableView = Schema.Schema.Type<typeof TableView>;\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,cAAc;AAEvB,SAASC,YAAY;AACrB,SAASC,gBAAgB;AAElB,IAAMC,YAAYC,OAAOC,OAAO;EACrCC,OAAOF,OAAOG,OAAO;IACnBC,KAAKC;IACLC,OAAON,OAAOO;EAChB,CAAA,EAAGC,KAAKR,OAAOS,OAAO;AACxB,CAAA,EAAGD,KAAKE,KAAKC,IAAI;EAAEC,UAAU;EAA2BC,SAAS;AAAQ,CAAA,CAAA;",
|
|
6
|
-
"names": ["Schema", "Type", "JsonPath", "TableView", "Schema", "Struct", "sizes", "Record", "key", "JsonPath", "value", "Number", "pipe", "mutable", "Type", "Obj", "typename", "version"]
|
|
7
|
-
}
|