@dxos/react-ui-table 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8
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-OZBLY7XM.mjs → chunk-BF54SSNL.mjs} +12 -18
- package/dist/lib/browser/chunk-BF54SSNL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-I5IFW7UF.mjs → chunk-PTHMYAAM.mjs} +33 -28
- package/dist/lib/browser/chunk-PTHMYAAM.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +178 -176
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -3
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-DDJKYJFY.mjs → chunk-GI72MQSG.mjs} +33 -28
- package/dist/lib/node-esm/chunk-GI72MQSG.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WNZSKIRF.mjs → chunk-SIRDIPHZ.mjs} +12 -18
- package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +178 -176
- 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 +3 -3
- package/dist/lib/node-esm/testing/index.mjs.map +2 -2
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +5 -4
- 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.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +6 -6
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +3 -3
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +2 -2
- 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/TableToolbar/TableToolbar.d.ts +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +1 -1
- package/dist/types/src/model/table-model.d.ts +5 -4
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +2 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +2 -2
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +1 -6
- package/dist/types/src/types/Table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +6 -5
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
- package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
- package/dist/types/src/util/query-ast.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -42
- package/src/components/Table/ColumnSettings.tsx +3 -4
- package/src/components/Table/DynamicTable.stories.tsx +6 -5
- package/src/components/Table/DynamicTable.tsx +11 -10
- package/src/components/Table/Relations.stories.tsx +13 -10
- package/src/components/Table/Table.stories.tsx +54 -32
- package/src/components/Table/Table.tsx +51 -56
- package/src/components/TableCellEditor/CellValidationMessage.tsx +4 -4
- package/src/components/TableCellEditor/FormCellEditor.tsx +11 -5
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +4 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +3 -3
- package/src/components/TableToolbar/TableToolbar.tsx +6 -6
- package/src/components/testing.ts +1 -1
- package/src/hooks/useAddRow.ts +1 -1
- package/src/hooks/useProjectionModel.ts +3 -3
- package/src/hooks/useTableModel.ts +1 -1
- package/src/model/table-model.test.ts +5 -5
- package/src/model/table-model.ts +9 -8
- package/src/model/table-presentation.test.ts +5 -5
- package/src/model/table-presentation.ts +12 -11
- package/src/playwright/TableManager.ts +10 -3
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +45 -2
- package/src/testing/useTestTableModel.ts +3 -3
- package/src/types/Table.ts +11 -22
- package/src/util/dynamic-table.test.ts +70 -0
- package/src/util/dynamic-table.ts +13 -12
- package/src/util/query-ast.ts +3 -0
- package/src/util/table-buttons.ts +1 -1
- package/src/util/table-controls.ts +2 -2
- package/dist/lib/browser/chunk-I5IFW7UF.mjs.map +0 -7
- package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-DDJKYJFY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +0 -7
|
@@ -17,6 +17,7 @@ const TABLE_SELECTORS = {
|
|
|
17
17
|
},
|
|
18
18
|
columnDelete: 'column-delete',
|
|
19
19
|
rowDelete: 'row-menu-delete',
|
|
20
|
+
addRow: 'table.toolbar.add-row',
|
|
20
21
|
} as const;
|
|
21
22
|
|
|
22
23
|
export class TableManager {
|
|
@@ -53,10 +54,16 @@ export class TableManager {
|
|
|
53
54
|
await this.page.getByTestId(TABLE_SELECTORS.columnSort[direction]).click();
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
public async
|
|
57
|
+
public async addRow(): Promise<void> {
|
|
58
|
+
await this.page.getByTestId(TABLE_SELECTORS.addRow).click();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public async addColumn({ label, format }: { label: string; format?: string }): Promise<void> {
|
|
57
62
|
await this.page.getByTestId(TABLE_SELECTORS.newColumnButton).click();
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
if (format) {
|
|
64
|
+
await this.page.getByRole('combobox').click();
|
|
65
|
+
await this.page.getByLabel(format).click();
|
|
66
|
+
}
|
|
60
67
|
await this.page.getByPlaceholder('Property label').click();
|
|
61
68
|
await this.page.getByPlaceholder('Property label').fill(label);
|
|
62
69
|
await this.page.getByRole('button', { name: 'Save' }).click();
|
|
@@ -10,7 +10,7 @@ export default defineConfig({
|
|
|
10
10
|
...e2ePreset(import.meta.dirname),
|
|
11
11
|
// TODO(wittjosiah): Avoid hard-coding ports.
|
|
12
12
|
webServer: {
|
|
13
|
-
command: '
|
|
13
|
+
command: 'pnpm storybook dev --ci --quiet --port=9004 --config-dir=.storybook',
|
|
14
14
|
port: 9004,
|
|
15
15
|
reuseExistingServer: false,
|
|
16
16
|
},
|
|
@@ -121,8 +121,22 @@ test.describe('Table', () => {
|
|
|
121
121
|
await page.close();
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
test('add column without changing format', async ({ browser, browserName }) => {
|
|
125
|
+
test.skip(browserName === 'webkit');
|
|
126
|
+
test.skip(browserName === 'firefox');
|
|
127
|
+
const { page } = await setupPage(browser, { url: storyUrl });
|
|
128
|
+
const table = new TableManager(page);
|
|
129
|
+
|
|
130
|
+
await table.grid.ready();
|
|
131
|
+
const newColumnLabel = 'DEFAULT FORMAT COL';
|
|
132
|
+
|
|
133
|
+
await table.addColumn({ label: newColumnLabel });
|
|
134
|
+
|
|
135
|
+
await expect(page.getByRole('gridcell', { name: newColumnLabel })).toBeVisible();
|
|
136
|
+
await page.close();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('add column with format', async ({ browser, browserName }) => {
|
|
126
140
|
test.skip(browserName === 'webkit');
|
|
127
141
|
test.skip(browserName === 'firefox');
|
|
128
142
|
const { page } = await setupPage(browser, { url: storyUrl });
|
|
@@ -160,6 +174,35 @@ test.describe('Table', () => {
|
|
|
160
174
|
await page.close();
|
|
161
175
|
});
|
|
162
176
|
|
|
177
|
+
test('add row and edit cell', async ({ browser, browserName }) => {
|
|
178
|
+
test.skip(browserName === 'webkit');
|
|
179
|
+
test.skip(browserName === 'firefox');
|
|
180
|
+
const { page } = await setupPage(browser, { url: storyUrl });
|
|
181
|
+
const table = new TableManager(page);
|
|
182
|
+
|
|
183
|
+
await table.grid.ready();
|
|
184
|
+
|
|
185
|
+
// Click the CTA row at the bottom to add a new row.
|
|
186
|
+
await table.grid.cell(0, 0, 'frozenRowsEnd').click();
|
|
187
|
+
|
|
188
|
+
// All schema fields are optional so the row is added directly to the grid (not as a draft).
|
|
189
|
+
const newCell = table.grid.cell(0, 10, 'grid');
|
|
190
|
+
await newCell.waitFor({ state: 'visible' });
|
|
191
|
+
|
|
192
|
+
// Focus should already be on the new row; engage edit mode.
|
|
193
|
+
await page.keyboard.press('Enter');
|
|
194
|
+
await page.getByTestId('grid.cell-editor').waitFor({ state: 'visible' });
|
|
195
|
+
|
|
196
|
+
// Type text and confirm.
|
|
197
|
+
const cellContent = 'New row content';
|
|
198
|
+
await page.keyboard.type(cellContent);
|
|
199
|
+
await page.keyboard.press('Enter');
|
|
200
|
+
|
|
201
|
+
// Assert the cell content is saved.
|
|
202
|
+
await expect(newCell).toHaveText(cellContent);
|
|
203
|
+
await page.close();
|
|
204
|
+
});
|
|
205
|
+
|
|
163
206
|
// TODO(wittjosiah): Remove? Conflicts with story play function which is run as a unit test anyways.
|
|
164
207
|
test.skip('extant relations work as expected', async ({ browser, browserName }) => {
|
|
165
208
|
test.skip(browserName === 'webkit');
|
|
@@ -20,7 +20,7 @@ import { Table } from '../types';
|
|
|
20
20
|
|
|
21
21
|
faker.seed(0); // NOTE(ZaymonFC): Required for smoke tests.
|
|
22
22
|
|
|
23
|
-
export type TestTableModel<T extends Type.
|
|
23
|
+
export type TestTableModel<T extends Type.AnyObj = Type.AnyObj> = {
|
|
24
24
|
schema: T | undefined;
|
|
25
25
|
table: Table.Table | undefined;
|
|
26
26
|
projection: ProjectionModel | undefined;
|
|
@@ -38,7 +38,7 @@ export type TestTableModel<T extends Type.Obj.Any = Type.Obj.Any> = {
|
|
|
38
38
|
* Custom hook to create and manage a test table model for storybook demonstrations.
|
|
39
39
|
* Provides table data, schema, and handlers for table operations.
|
|
40
40
|
*/
|
|
41
|
-
export const useTestTableModel = <T extends Type.
|
|
41
|
+
export const useTestTableModel = <T extends Type.AnyObj = Type.AnyObj>(): TestTableModel<T> => {
|
|
42
42
|
const registry = useContext(RegistryContext);
|
|
43
43
|
const { space } = useClientStory();
|
|
44
44
|
const db = space?.db;
|
|
@@ -97,7 +97,7 @@ export const useTestTableModel = <T extends Type.Obj.Any = Type.Obj.Any>(): Test
|
|
|
97
97
|
rows: filteredObjects,
|
|
98
98
|
onInsertRow: addRow,
|
|
99
99
|
onDeleteRows: handleDeleteRows,
|
|
100
|
-
|
|
100
|
+
onColumnDelete: handleDeleteColumn,
|
|
101
101
|
onCellUpdate: handleCellUpdate,
|
|
102
102
|
onRowOrderChange: handleRowOrderChange,
|
|
103
103
|
});
|
package/src/types/Table.ts
CHANGED
|
@@ -6,14 +6,15 @@ import * as Match from 'effect/Match';
|
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
8
8
|
|
|
9
|
-
import { Obj, Ref, Type } from '@dxos/echo';
|
|
9
|
+
import { Annotation, JsonSchema, Obj, Ref, Type } from '@dxos/echo';
|
|
10
|
+
import { View } from '@dxos/echo';
|
|
10
11
|
import { FormInputAnnotation, type JsonPath, type JsonSchemaType, LabelAnnotation } from '@dxos/echo/internal';
|
|
11
|
-
import {
|
|
12
|
+
import { ViewAnnotation } from '@dxos/schema';
|
|
12
13
|
|
|
13
14
|
export const Table = Schema.Struct({
|
|
14
15
|
name: Schema.String.pipe(Schema.optional),
|
|
15
16
|
|
|
16
|
-
view:
|
|
17
|
+
view: Ref.Ref(View.View).pipe(FormInputAnnotation.set(false)),
|
|
17
18
|
|
|
18
19
|
sizes: Schema.Record({
|
|
19
20
|
// TODO(wittjosiah): Should be JsonPath.
|
|
@@ -22,11 +23,15 @@ export const Table = Schema.Struct({
|
|
|
22
23
|
}).pipe(Schema.mutable, FormInputAnnotation.set(false)),
|
|
23
24
|
}).pipe(
|
|
24
25
|
Type.object({
|
|
25
|
-
typename: 'dxos.
|
|
26
|
-
version: '0.
|
|
26
|
+
typename: 'org.dxos.type.table',
|
|
27
|
+
version: '0.1.0',
|
|
27
28
|
}),
|
|
28
29
|
LabelAnnotation.set(['name']),
|
|
29
30
|
ViewAnnotation.set(true),
|
|
31
|
+
Annotation.IconAnnotation.set({
|
|
32
|
+
icon: 'ph--table--regular',
|
|
33
|
+
hue: 'green',
|
|
34
|
+
}),
|
|
30
35
|
);
|
|
31
36
|
|
|
32
37
|
export interface Table extends Schema.Schema.Type<typeof Table> {}
|
|
@@ -47,7 +52,7 @@ export const make = ({ name, sizes = {}, view, jsonSchema }: MakeProps): Table =
|
|
|
47
52
|
|
|
48
53
|
// Preset sizes.
|
|
49
54
|
if (jsonSchema) {
|
|
50
|
-
const schema =
|
|
55
|
+
const schema = JsonSchema.toEffectSchema(jsonSchema);
|
|
51
56
|
const properties = SchemaAST.getPropertySignatures(schema.ast);
|
|
52
57
|
for (const property of properties) {
|
|
53
58
|
const name = property.name.toString() as JsonPath;
|
|
@@ -72,19 +77,3 @@ export const make = ({ name, sizes = {}, view, jsonSchema }: MakeProps): Table =
|
|
|
72
77
|
|
|
73
78
|
return table;
|
|
74
79
|
};
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
// V1
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
export const TableV1 = Schema.Struct({
|
|
81
|
-
sizes: Schema.Record({
|
|
82
|
-
key: Schema.String,
|
|
83
|
-
value: Schema.Number,
|
|
84
|
-
}).pipe(Schema.mutable),
|
|
85
|
-
}).pipe(
|
|
86
|
-
Type.object({
|
|
87
|
-
typename: 'dxos.org/type/Table',
|
|
88
|
-
version: '0.1.0',
|
|
89
|
-
}),
|
|
90
|
-
);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Registry } from '@effect-atom/atom-react';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { Format } from '@dxos/echo';
|
|
9
|
+
|
|
10
|
+
import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from './dynamic-table';
|
|
11
|
+
|
|
12
|
+
describe('makeDynamicTable', () => {
|
|
13
|
+
/**
|
|
14
|
+
* Base case: plain jsonSchema (not from Echo / JsonSchema.toJsonSchema). Does not exercise the path
|
|
15
|
+
* where projection or schema are reactive, so this does not reproduce the Obj.change regression.
|
|
16
|
+
* Confirms makeDynamicTable + setProperties (title) works with plain objects.
|
|
17
|
+
*/
|
|
18
|
+
test('makeDynamicTable with plain jsonSchema and properties with title does not throw', () => {
|
|
19
|
+
const registry = Registry.make();
|
|
20
|
+
const jsonSchema = {
|
|
21
|
+
type: 'object' as const,
|
|
22
|
+
properties: {
|
|
23
|
+
id: { type: 'string' as const },
|
|
24
|
+
name: { type: 'string' as const },
|
|
25
|
+
},
|
|
26
|
+
required: ['id'],
|
|
27
|
+
};
|
|
28
|
+
const properties: TablePropertyDefinition[] = [
|
|
29
|
+
{ name: 'id', format: Format.TypeFormat.String },
|
|
30
|
+
{ name: 'name', format: Format.TypeFormat.String, title: 'Name' },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
expect(() => {
|
|
34
|
+
const { projection, object } = makeDynamicTable({
|
|
35
|
+
registry,
|
|
36
|
+
jsonSchema,
|
|
37
|
+
properties,
|
|
38
|
+
});
|
|
39
|
+
expect(projection).toBeDefined();
|
|
40
|
+
expect(object).toBeDefined();
|
|
41
|
+
expect(projection.getFields().length).toBeGreaterThan(0);
|
|
42
|
+
}).not.toThrow();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Regression test for the path where jsonSchema comes from getBaseSchema(typename, properties).
|
|
47
|
+
* That path uses Echo (ViewModel.make, JsonSchema.toJsonSchema); mutations must run inside Obj.change and on a
|
|
48
|
+
* cloned schema. This test ensures that flow does not throw.
|
|
49
|
+
*/
|
|
50
|
+
test('makeDynamicTable with jsonSchema from getBaseSchema(typename, properties) and properties with title does not throw', () => {
|
|
51
|
+
const registry = Registry.make();
|
|
52
|
+
const typename = 'com.example.type.dynamic-table-test';
|
|
53
|
+
const properties: TablePropertyDefinition[] = [
|
|
54
|
+
{ name: 'id', format: Format.TypeFormat.String },
|
|
55
|
+
{ name: 'name', format: Format.TypeFormat.String, title: 'Name' },
|
|
56
|
+
];
|
|
57
|
+
const { jsonSchema } = getBaseSchema({ typename, properties });
|
|
58
|
+
|
|
59
|
+
expect(() => {
|
|
60
|
+
const { projection, object } = makeDynamicTable({
|
|
61
|
+
registry,
|
|
62
|
+
jsonSchema,
|
|
63
|
+
properties,
|
|
64
|
+
});
|
|
65
|
+
expect(projection).toBeDefined();
|
|
66
|
+
expect(object).toBeDefined();
|
|
67
|
+
expect(projection.getFields().length).toBeGreaterThan(0);
|
|
68
|
+
}).not.toThrow();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Registry } from '@effect-atom/atom-react';
|
|
6
|
+
import type * as Types from 'effect/Types';
|
|
6
7
|
|
|
7
|
-
import { Filter,
|
|
8
|
+
import { Filter, JsonSchema, Obj, Order, Query, type QueryAST, Ref, Type } from '@dxos/echo';
|
|
9
|
+
import { type View } from '@dxos/echo';
|
|
8
10
|
import {
|
|
9
11
|
ProjectionModel,
|
|
10
12
|
type SchemaPropertyDefinition,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
ViewModel,
|
|
14
|
+
createEchoChangeCallback,
|
|
13
15
|
getSchemaFromPropertyDefinitions,
|
|
14
16
|
} from '@dxos/schema';
|
|
15
17
|
|
|
@@ -34,16 +36,16 @@ export const getBaseSchema = ({
|
|
|
34
36
|
properties,
|
|
35
37
|
jsonSchema,
|
|
36
38
|
}: {
|
|
37
|
-
schema?: Type.
|
|
39
|
+
schema?: Type.AnyEntity;
|
|
38
40
|
typename?: string;
|
|
39
41
|
properties?: TablePropertyDefinition[];
|
|
40
|
-
jsonSchema?: JsonSchema.JsonSchema
|
|
41
|
-
}): { typename: string; jsonSchema: JsonSchema.JsonSchema } => {
|
|
42
|
+
jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
|
|
43
|
+
}): { typename: string; jsonSchema: Types.DeepMutable<JsonSchema.JsonSchema> } => {
|
|
42
44
|
if (typename && properties) {
|
|
43
45
|
const schema = getSchemaFromPropertyDefinitions(typename, properties);
|
|
44
|
-
return { typename: schema.typename, jsonSchema: schema
|
|
46
|
+
return { typename: schema.typename, jsonSchema: JsonSchema.toJsonSchema(schema) };
|
|
45
47
|
} else if (schema) {
|
|
46
|
-
return { typename: Type.getTypename(schema)!, jsonSchema:
|
|
48
|
+
return { typename: Type.getTypename(schema)!, jsonSchema: JsonSchema.toJsonSchema(schema) };
|
|
47
49
|
} else if (typename && jsonSchema) {
|
|
48
50
|
return { typename, jsonSchema };
|
|
49
51
|
} else {
|
|
@@ -57,22 +59,21 @@ export const makeDynamicTable = ({
|
|
|
57
59
|
properties,
|
|
58
60
|
}: {
|
|
59
61
|
registry: Registry.Registry;
|
|
60
|
-
jsonSchema: JsonSchema.JsonSchema
|
|
62
|
+
jsonSchema: Types.DeepMutable<JsonSchema.JsonSchema>;
|
|
61
63
|
properties?: TablePropertyDefinition[];
|
|
62
64
|
}): { projection: ProjectionModel; object: Table.Table } => {
|
|
63
|
-
const view =
|
|
65
|
+
const view = ViewModel.make({
|
|
64
66
|
query: Query.select(Filter.everything()),
|
|
65
67
|
jsonSchema,
|
|
66
68
|
...(properties && { fields: properties.map((property) => property.name) }),
|
|
67
69
|
});
|
|
68
70
|
const object = Obj.make(Table.Table, { view: Ref.make(view), sizes: {} });
|
|
69
71
|
|
|
70
|
-
// Use direct change callback for in-memory objects (non-ECHO backed).
|
|
71
72
|
const projection = new ProjectionModel({
|
|
72
73
|
registry,
|
|
73
74
|
view,
|
|
74
75
|
baseSchema: jsonSchema,
|
|
75
|
-
change:
|
|
76
|
+
change: createEchoChangeCallback(view, jsonSchema),
|
|
76
77
|
});
|
|
77
78
|
projection.normalizeView();
|
|
78
79
|
if (properties && projection.getFields()) {
|
package/src/util/query-ast.ts
CHANGED
|
@@ -15,5 +15,8 @@ export const extractOrder = (queryAst: QueryAST.Query): readonly QueryAST.Order[
|
|
|
15
15
|
if (queryAst.type === 'options') {
|
|
16
16
|
return extractOrder(queryAst.query);
|
|
17
17
|
}
|
|
18
|
+
if (queryAst.type === 'from') {
|
|
19
|
+
return extractOrder(queryAst.query);
|
|
20
|
+
}
|
|
18
21
|
return undefined;
|
|
19
22
|
};
|
|
@@ -39,7 +39,7 @@ const createButton = ({
|
|
|
39
39
|
.map(([k, v]) => `${k}="${v}"`)
|
|
40
40
|
.join(' ');
|
|
41
41
|
|
|
42
|
-
return `<button ${attr} data-testid="${testId}" class="dx-button
|
|
42
|
+
return `<button ${attr} data-testid="${testId}" class="dx-button w-6 aspect-square px-0.5 min-h-0" ${dataAttrs} ${disabled ? 'disabled' : ''} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const addColumnButton = {
|
|
@@ -25,8 +25,8 @@ export const CONTROL_IDENTIFIERS = {
|
|
|
25
25
|
} as const;
|
|
26
26
|
|
|
27
27
|
const BASE_CLASSES = {
|
|
28
|
-
checkbox: 'absolute inset-
|
|
29
|
-
switch: 'absolute inset-
|
|
28
|
+
checkbox: 'absolute inset-y-[.375rem] end-[.375rem] dx-checkbox',
|
|
29
|
+
switch: 'absolute inset-y-[.25rem] end-[.25rem] dx-checkbox--switch',
|
|
30
30
|
} as const;
|
|
31
31
|
|
|
32
32
|
const renderAttributes = (data: Record<string, string>) => {
|