@dxos/react-ui-table 0.8.3 → 0.8.4-main.1068cf700f
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-GTGYBRJA.mjs +1748 -0
- package/dist/lib/browser/chunk-GTGYBRJA.mjs.map +7 -0
- package/dist/lib/browser/chunk-OZBLY7XM.mjs +76 -0
- package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1156 -2508
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +114 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +3 -5
- package/dist/lib/node-esm/chunk-DPNSZHU5.mjs +1750 -0
- package/dist/lib/node-esm/chunk-DPNSZHU5.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-WNZSKIRF.mjs +77 -0
- package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1156 -2508
- 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 +115 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +3 -5
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +2 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +4 -2
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +7 -7
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +37 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +111 -0
- 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 +13 -9
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +108 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +2 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +14 -9
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +12 -18
- 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 +4 -4
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +26 -56
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +13 -0
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts +6 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +11 -10
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +5 -8
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts +17 -7
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +149 -32
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +13 -2
- 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/playwright/playwright.config.d.ts +3 -0
- package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/useTestTableModel.d.ts +25 -0
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +5 -6
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +31 -0
- package/dist/types/src/types/Table.d.ts.map +1 -0
- 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/util/dynamic-table.d.ts +15 -14
- 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/index.d.ts +2 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/query-ast.d.ts +7 -0
- package/dist/types/src/util/query-ast.d.ts.map +1 -0
- 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/sort.d.ts +12 -0
- package/dist/types/src/util/sort.d.ts.map +1 -0
- package/dist/types/src/util/table-buttons.d.ts +15 -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/tsconfig.tsbuildinfo +1 -1
- package/package.json +69 -56
- package/src/components/Table/ColumnActionsMenu.tsx +11 -7
- package/src/components/Table/ColumnSettings.tsx +16 -12
- package/src/components/Table/DynamicTable.stories.tsx +29 -25
- package/src/components/Table/DynamicTable.tsx +34 -22
- package/src/components/Table/Relations.stories.tsx +237 -0
- package/src/components/Table/RowActionsMenu.tsx +26 -17
- package/src/components/Table/Table.stories.tsx +171 -194
- package/src/components/Table/Table.tsx +364 -286
- package/src/components/TableCellEditor/CellValidationMessage.tsx +8 -3
- package/src/components/TableCellEditor/FormCellEditor.tsx +146 -49
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +36 -76
- package/src/components/TableCellEditor/TableCellEditor.tsx +106 -198
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +49 -33
- package/src/components/testing.ts +41 -32
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useAddRow.ts +36 -0
- package/src/hooks/useProjectionModel.ts +39 -0
- package/src/hooks/useTableModel.ts +41 -35
- package/src/index.ts +1 -2
- package/src/model/modal-controller.ts +24 -41
- package/src/model/selection-model.ts +75 -41
- package/src/model/table-model.test.ts +92 -56
- package/src/model/table-model.ts +628 -162
- package/src/model/table-presentation.test.ts +70 -59
- package/src/model/table-presentation.ts +278 -149
- package/src/playwright/TableManager.ts +13 -6
- package/src/playwright/playwright.config.ts +17 -0
- package/src/playwright/smoke.spec.ts +180 -41
- package/src/testing/index.ts +5 -0
- package/src/testing/useTestTableModel.ts +133 -0
- package/src/translations.ts +7 -5
- package/src/types/Table.ts +90 -0
- package/src/types/index.ts +2 -2
- package/src/util/dynamic-table.test.ts +70 -0
- package/src/util/dynamic-table.ts +50 -36
- package/src/util/index.ts +2 -1
- package/src/util/query-ast.ts +19 -0
- package/src/util/schema.ts +4 -4
- package/src/util/sort.ts +90 -0
- package/src/util/table-buttons.ts +28 -4
- package/src/util/table-controls.ts +4 -1
- package/dist/lib/browser/chunk-TL7CKQQV.mjs +0 -27
- package/dist/lib/browser/chunk-TL7CKQQV.mjs.map +0 -7
- package/dist/lib/node/chunk-O2VPBNS5.cjs +0 -50
- package/dist/lib/node/chunk-O2VPBNS5.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -2739
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/types/index.cjs +0 -31
- package/dist/lib/node/types/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-GBT6GD4G.mjs +0 -29
- package/dist/lib/node-esm/chunk-GBT6GD4G.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/Table/relations.stories.d.ts +0 -9
- package/dist/types/src/components/Table/relations.stories.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/model/table-sorting.d.ts +0 -53
- package/dist/types/src/model/table-sorting.d.ts.map +0 -1
- package/dist/types/src/types/table.d.ts +0 -56
- package/dist/types/src/types/table.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -14
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -84
- package/src/components/Table/relations.stories.tsx +0 -124
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/model/table-sorting.ts +0 -216
- package/src/playwright/playwright.config.cts +0 -18
- package/src/types/table.ts +0 -27
- package/src/util/table.ts +0 -127
|
@@ -2,26 +2,25 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type
|
|
5
|
+
import { type Registry } from '@effect-atom/atom-react';
|
|
6
|
+
import type * as Types from 'effect/Types';
|
|
6
7
|
|
|
7
|
-
import { Obj, Ref } from '@dxos/echo';
|
|
8
|
-
import { getTypename, toJsonSchema } from '@dxos/echo-schema';
|
|
9
|
-
import type { JsonSchemaType, SortDirectionType } from '@dxos/echo-schema';
|
|
8
|
+
import { Filter, type JsonSchema, Obj, Order, Query, type QueryAST, Ref, Type } from '@dxos/echo';
|
|
10
9
|
import {
|
|
11
|
-
|
|
12
|
-
getSchemaFromPropertyDefinitions,
|
|
13
|
-
ViewProjection,
|
|
14
|
-
type ViewType,
|
|
10
|
+
ProjectionModel,
|
|
15
11
|
type SchemaPropertyDefinition,
|
|
12
|
+
View,
|
|
13
|
+
createEchoChangeCallback,
|
|
14
|
+
getSchemaFromPropertyDefinitions,
|
|
16
15
|
} from '@dxos/schema';
|
|
17
16
|
|
|
18
|
-
import {
|
|
17
|
+
import { Table } from '../types';
|
|
19
18
|
|
|
20
19
|
// TODO(ZaymonFC): Upstream these extra fields to SchemaPropertyDefinition to enhance schema-tools schema creation.
|
|
21
20
|
type PropertyDisplayProps = {
|
|
22
21
|
size: number;
|
|
23
22
|
title: string;
|
|
24
|
-
sort:
|
|
23
|
+
sort: QueryAST.OrderDirection;
|
|
25
24
|
};
|
|
26
25
|
|
|
27
26
|
export type TablePropertyDefinition = SchemaPropertyDefinition & Partial<PropertyDisplayProps>;
|
|
@@ -31,21 +30,21 @@ export type TablePropertyDefinition = SchemaPropertyDefinition & Partial<Propert
|
|
|
31
30
|
*/
|
|
32
31
|
// TODO(burdon): Remove variance.
|
|
33
32
|
export const getBaseSchema = ({
|
|
33
|
+
schema,
|
|
34
34
|
typename,
|
|
35
35
|
properties,
|
|
36
36
|
jsonSchema,
|
|
37
|
-
schema,
|
|
38
37
|
}: {
|
|
38
|
+
schema?: Type.Entity.Any;
|
|
39
39
|
typename?: string;
|
|
40
40
|
properties?: TablePropertyDefinition[];
|
|
41
|
-
jsonSchema?:
|
|
42
|
-
|
|
43
|
-
}): { typename: string; jsonSchema: JsonSchemaType } => {
|
|
41
|
+
jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
|
|
42
|
+
}): { typename: string; jsonSchema: Types.DeepMutable<JsonSchema.JsonSchema> } => {
|
|
44
43
|
if (typename && properties) {
|
|
45
44
|
const schema = getSchemaFromPropertyDefinitions(typename, properties);
|
|
46
|
-
return { typename: schema.typename, jsonSchema: schema
|
|
45
|
+
return { typename: schema.typename, jsonSchema: Type.toJsonSchema(schema) };
|
|
47
46
|
} else if (schema) {
|
|
48
|
-
return { typename: getTypename(schema)!, jsonSchema: toJsonSchema(schema) };
|
|
47
|
+
return { typename: Type.getTypename(schema)!, jsonSchema: Type.toJsonSchema(schema) };
|
|
49
48
|
} else if (typename && jsonSchema) {
|
|
50
49
|
return { typename, jsonSchema };
|
|
51
50
|
} else {
|
|
@@ -54,39 +53,48 @@ export const getBaseSchema = ({
|
|
|
54
53
|
};
|
|
55
54
|
|
|
56
55
|
export const makeDynamicTable = ({
|
|
57
|
-
|
|
56
|
+
registry,
|
|
58
57
|
jsonSchema,
|
|
59
58
|
properties,
|
|
60
59
|
}: {
|
|
61
|
-
|
|
62
|
-
jsonSchema:
|
|
60
|
+
registry: Registry.Registry;
|
|
61
|
+
jsonSchema: Types.DeepMutable<JsonSchema.JsonSchema>;
|
|
63
62
|
properties?: TablePropertyDefinition[];
|
|
64
|
-
}): {
|
|
65
|
-
const view =
|
|
66
|
-
|
|
67
|
-
typename,
|
|
63
|
+
}): { projection: ProjectionModel; object: Table.Table } => {
|
|
64
|
+
const view = View.make({
|
|
65
|
+
query: Query.select(Filter.everything()),
|
|
68
66
|
jsonSchema,
|
|
69
67
|
...(properties && { fields: properties.map((property) => property.name) }),
|
|
70
68
|
});
|
|
69
|
+
const object = Obj.make(Table.Table, { view: Ref.make(view), sizes: {} });
|
|
71
70
|
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
const projection = new ProjectionModel({
|
|
72
|
+
registry,
|
|
73
|
+
view,
|
|
74
|
+
baseSchema: jsonSchema,
|
|
75
|
+
change: createEchoChangeCallback(view, jsonSchema),
|
|
76
|
+
});
|
|
77
|
+
projection.normalizeView();
|
|
78
|
+
if (properties && projection.getFields()) {
|
|
79
|
+
setProperties(view, projection, object, properties);
|
|
76
80
|
}
|
|
77
81
|
|
|
78
|
-
return {
|
|
79
|
-
table,
|
|
80
|
-
projection,
|
|
81
|
-
};
|
|
82
|
+
return { projection, object };
|
|
82
83
|
};
|
|
83
84
|
|
|
84
|
-
const setProperties = (
|
|
85
|
+
const setProperties = (
|
|
86
|
+
view: View.View,
|
|
87
|
+
projection: ProjectionModel,
|
|
88
|
+
table: Table.Table,
|
|
89
|
+
properties: TablePropertyDefinition[],
|
|
90
|
+
) => {
|
|
85
91
|
for (const property of properties) {
|
|
86
|
-
const field =
|
|
92
|
+
const field = projection.getFields().find((field) => field.path === property.name);
|
|
87
93
|
if (field) {
|
|
88
94
|
if (property.size !== undefined) {
|
|
89
|
-
|
|
95
|
+
Obj.change(table, (t) => {
|
|
96
|
+
t.sizes[field.path] = property.size!;
|
|
97
|
+
});
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
if (property.title !== undefined) {
|
|
@@ -98,8 +106,14 @@ const setProperties = (view: ViewType, projection: ViewProjection, properties: T
|
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
if (property.sort) {
|
|
101
|
-
|
|
102
|
-
view.query.
|
|
109
|
+
// Apply sort to query instead of deprecated view.sort
|
|
110
|
+
const currentQuery = Query.fromAst(Obj.getSnapshot(view).query.ast);
|
|
111
|
+
// Use any type parameter since we're working with dynamic field paths
|
|
112
|
+
const newQuery = currentQuery.orderBy(Order.property<any>(field.path as string, property.sort));
|
|
113
|
+
Obj.change(view, (v) => {
|
|
114
|
+
// Type assertion needed because Query AST types have some variance issues.
|
|
115
|
+
v.query.ast = newQuery.ast as typeof v.query.ast;
|
|
116
|
+
});
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
119
|
}
|
package/src/util/index.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type QueryAST } from '@dxos/echo';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extracts order clauses from a query AST.
|
|
9
|
+
* Handles nested structures (options, order, etc.).
|
|
10
|
+
*/
|
|
11
|
+
export const extractOrder = (queryAst: QueryAST.Query): readonly QueryAST.Order[] | undefined => {
|
|
12
|
+
if (queryAst.type === 'order') {
|
|
13
|
+
return queryAst.order;
|
|
14
|
+
}
|
|
15
|
+
if (queryAst.type === 'options') {
|
|
16
|
+
return extractOrder(queryAst.query);
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
};
|
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
|
}
|
package/src/util/sort.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Format, type QueryAST } from '@dxos/echo';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Gets a normalized sort value for a given value and format.
|
|
9
|
+
* This ensures consistent sorting behavior across different data types.
|
|
10
|
+
*/
|
|
11
|
+
export const getSortValue = (value: any, format: Format.TypeFormat): any => {
|
|
12
|
+
// Handle null/undefined
|
|
13
|
+
if (value === undefined || value === null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Handle dates chronologically if schema indicates date format
|
|
18
|
+
const isDateFormat = format === Format.TypeFormat.DateTime || format === Format.TypeFormat.Date;
|
|
19
|
+
if (isDateFormat) {
|
|
20
|
+
const date = new Date(value);
|
|
21
|
+
if (!isNaN(date.getTime())) {
|
|
22
|
+
return date.getTime();
|
|
23
|
+
}
|
|
24
|
+
// Fallback to string if date parsing fails
|
|
25
|
+
return String(value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Handle numbers if schema indicates number format
|
|
29
|
+
if (
|
|
30
|
+
format === Format.TypeFormat.Number ||
|
|
31
|
+
format === Format.TypeFormat.Integer ||
|
|
32
|
+
format === Format.TypeFormat.Currency ||
|
|
33
|
+
format === Format.TypeFormat.Percent ||
|
|
34
|
+
format === Format.TypeFormat.Duration
|
|
35
|
+
) {
|
|
36
|
+
const num = typeof value === 'number' ? value : Number(value);
|
|
37
|
+
if (!isNaN(num)) {
|
|
38
|
+
return num;
|
|
39
|
+
}
|
|
40
|
+
// Fallback to string if number parsing fails
|
|
41
|
+
return String(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Default to string comparison
|
|
45
|
+
if (typeof value === 'string') {
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value === 'number') {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Fallback to string representation
|
|
53
|
+
return String(value);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Compares two values for sorting based on the field format.
|
|
58
|
+
* Handles dates, numbers, and strings appropriately.
|
|
59
|
+
*/
|
|
60
|
+
export const compareValues = (
|
|
61
|
+
aValue: any,
|
|
62
|
+
bValue: any,
|
|
63
|
+
format: Format.TypeFormat,
|
|
64
|
+
direction: QueryAST.OrderDirection,
|
|
65
|
+
): number => {
|
|
66
|
+
// Handle null/undefined values - nulls sort to the end
|
|
67
|
+
if (aValue === undefined || aValue === null) {
|
|
68
|
+
return bValue === undefined || bValue === null ? 0 : 1;
|
|
69
|
+
}
|
|
70
|
+
if (bValue === undefined || bValue === null) {
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Get normalized sort values
|
|
75
|
+
const aSortValue = getSortValue(aValue, format);
|
|
76
|
+
const bSortValue = getSortValue(bValue, format);
|
|
77
|
+
|
|
78
|
+
// Compare based on type
|
|
79
|
+
let comparison = 0;
|
|
80
|
+
if (typeof aSortValue === 'number' && typeof bSortValue === 'number') {
|
|
81
|
+
comparison = aSortValue - bSortValue;
|
|
82
|
+
} else if (typeof aSortValue === 'string' && typeof bSortValue === 'string') {
|
|
83
|
+
comparison = aSortValue.localeCompare(bSortValue);
|
|
84
|
+
} else {
|
|
85
|
+
// Mixed types - convert both to strings
|
|
86
|
+
comparison = String(aSortValue).localeCompare(String(bSortValue));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return direction === 'desc' ? -comparison : comparison;
|
|
90
|
+
};
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export type TableButton = 'columnSettings' | 'rowMenu' | 'newColumn' | 'referencedCell' | 'sort';
|
|
5
|
+
export type TableButton = 'columnSettings' | 'rowMenu' | 'newColumn' | 'referencedCell' | 'sort' | 'saveDraftRow';
|
|
6
6
|
|
|
7
7
|
export const BUTTON_IDENTIFIERS: { [K in TableButton]: string } = {
|
|
8
8
|
columnSettings: 'data-table-column-settings-button',
|
|
9
9
|
newColumn: 'data-table-new-column-button',
|
|
10
10
|
referencedCell: 'data-table-ref-cell-button',
|
|
11
11
|
rowMenu: 'data-table-row-menu-button',
|
|
12
|
+
saveDraftRow: 'data-table-save-draft-row-button',
|
|
12
13
|
sort: 'data-table-sort-button',
|
|
13
14
|
} as const;
|
|
14
15
|
|
|
@@ -16,6 +17,7 @@ type ButtonData =
|
|
|
16
17
|
| { type: 'columnSettings'; fieldId: string }
|
|
17
18
|
| { type: 'newColumn'; disabled?: boolean }
|
|
18
19
|
| { type: 'rowMenu'; rowIndex: number }
|
|
20
|
+
| { type: 'saveDraftRow'; rowIndex: number; disabled?: boolean }
|
|
19
21
|
| { type: 'sort'; fieldId: string; direction?: 'asc' | 'desc' };
|
|
20
22
|
|
|
21
23
|
const createButton = ({
|
|
@@ -24,7 +26,7 @@ const createButton = ({
|
|
|
24
26
|
disabled = false,
|
|
25
27
|
icon,
|
|
26
28
|
testId,
|
|
27
|
-
type = 'primary',
|
|
29
|
+
type: _type = 'primary',
|
|
28
30
|
}: {
|
|
29
31
|
attr: string;
|
|
30
32
|
data: Record<string, string>;
|
|
@@ -37,8 +39,7 @@ const createButton = ({
|
|
|
37
39
|
.map(([k, v]) => `${k}="${v}"`)
|
|
38
40
|
.join(' ');
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
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>`;
|
|
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>`;
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
const addColumnButton = {
|
|
@@ -65,6 +66,7 @@ const columnSettingsButton = {
|
|
|
65
66
|
icon: columnSettingsButton.icon,
|
|
66
67
|
data: {
|
|
67
68
|
'data-field-id': fieldId,
|
|
69
|
+
'data-variant': 'ghost',
|
|
68
70
|
},
|
|
69
71
|
testId: 'table-column-settings-button',
|
|
70
72
|
});
|
|
@@ -118,9 +120,31 @@ const sortButton = {
|
|
|
118
120
|
}),
|
|
119
121
|
} as const;
|
|
120
122
|
|
|
123
|
+
const saveDraftRowButton = {
|
|
124
|
+
attr: BUTTON_IDENTIFIERS.saveDraftRow,
|
|
125
|
+
icon: 'ph--floppy-disk--regular',
|
|
126
|
+
render: ({ rowIndex, disabled }: Omit<Extract<ButtonData, { type: 'saveDraftRow' }>, 'type'>) => {
|
|
127
|
+
return createButton({
|
|
128
|
+
attr: BUTTON_IDENTIFIERS.saveDraftRow,
|
|
129
|
+
icon: saveDraftRowButton.icon,
|
|
130
|
+
disabled,
|
|
131
|
+
data: {
|
|
132
|
+
'data-row-index': rowIndex.toString(),
|
|
133
|
+
'data-variant': 'primary',
|
|
134
|
+
},
|
|
135
|
+
testId: 'table-save-draft-row-button',
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
getData: (el: HTMLElement): Extract<ButtonData, { type: 'saveDraftRow' }> => ({
|
|
139
|
+
type: 'saveDraftRow',
|
|
140
|
+
rowIndex: Number(el.getAttribute('data-row-index')!),
|
|
141
|
+
}),
|
|
142
|
+
} as const;
|
|
143
|
+
|
|
121
144
|
export const tableButtons = {
|
|
122
145
|
addColumn: addColumnButton,
|
|
123
146
|
columnSettings: columnSettingsButton,
|
|
124
147
|
rowMenu: rowMenuButton,
|
|
148
|
+
saveDraftRow: saveDraftRowButton,
|
|
125
149
|
sort: sortButton,
|
|
126
150
|
} as const;
|
|
@@ -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');
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// packages/ui/react-ui-table/src/types/table.ts
|
|
2
|
-
import { Schema } from "effect";
|
|
3
|
-
import { Type } from "@dxos/echo";
|
|
4
|
-
import { ObjectId, Ref, Expando, LabelAnnotation } from "@dxos/echo-schema";
|
|
5
|
-
import { ViewType } from "@dxos/schema";
|
|
6
|
-
var TableSchema = Schema.Struct({
|
|
7
|
-
id: ObjectId,
|
|
8
|
-
name: Schema.optional(Schema.String),
|
|
9
|
-
view: Schema.optional(Ref(ViewType)),
|
|
10
|
-
// TODO(burdon): Document why threads is included here?
|
|
11
|
-
threads: Schema.optional(Schema.Array(Ref(
|
|
12
|
-
Expando
|
|
13
|
-
/* ThreadType */
|
|
14
|
-
)))
|
|
15
|
-
}).pipe(LabelAnnotation.set([
|
|
16
|
-
"name"
|
|
17
|
-
]));
|
|
18
|
-
var TableType = TableSchema.pipe(Type.Obj({
|
|
19
|
-
typename: "dxos.org/type/Table",
|
|
20
|
-
version: "0.1.0"
|
|
21
|
-
}));
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
TableSchema,
|
|
25
|
-
TableType
|
|
26
|
-
};
|
|
27
|
-
//# sourceMappingURL=chunk-TL7CKQQV.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/types/table.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\n// import { ThreadType } from '@dxos/plugin-space/types';\nimport { Type } from '@dxos/echo';\nimport { ObjectId, Ref, Expando, LabelAnnotation } from '@dxos/echo-schema';\nimport { ViewType } from '@dxos/schema';\n\nexport const TableSchema = Schema.Struct({\n id: ObjectId,\n name: Schema.optional(Schema.String),\n view: Schema.optional(Ref(ViewType)),\n // TODO(burdon): Document why threads is included here?\n threads: Schema.optional(Schema.Array(Ref(Expando /* ThreadType */))),\n}).pipe(LabelAnnotation.set(['name']));\n\n// TODO(burdon): Move out of react-ui-xxx.\nexport const TableType = TableSchema.pipe(\n Type.Obj({\n typename: 'dxos.org/type/Table',\n version: '0.1.0',\n }),\n);\nexport interface TableType extends Schema.Schema.Type<typeof TableType> {}\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,cAAc;AAGvB,SAASC,YAAY;AACrB,SAASC,UAAUC,KAAKC,SAASC,uBAAuB;AACxD,SAASC,gBAAgB;AAElB,IAAMC,cAAcC,OAAOC,OAAO;EACvCC,IAAIC;EACJC,MAAMJ,OAAOK,SAASL,OAAOM,MAAM;EACnCC,MAAMP,OAAOK,SAASG,IAAIC,QAAAA,CAAAA;;EAE1BC,SAASV,OAAOK,SAASL,OAAOW,MAAMH;IAAII;;EAAsB,CAAA,CAAA;AAClE,CAAA,EAAGC,KAAKC,gBAAgBC,IAAI;EAAC;CAAO,CAAA;AAG7B,IAAMC,YAAYjB,YAAYc,KACnCI,KAAKC,IAAI;EACPC,UAAU;EACVC,SAAS;AACX,CAAA,CAAA;",
|
|
6
|
-
"names": ["Schema", "Type", "ObjectId", "Ref", "Expando", "LabelAnnotation", "ViewType", "TableSchema", "Schema", "Struct", "id", "ObjectId", "name", "optional", "String", "view", "Ref", "ViewType", "threads", "Array", "Expando", "pipe", "LabelAnnotation", "set", "TableType", "Type", "Obj", "typename", "version"]
|
|
7
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var chunk_O2VPBNS5_exports = {};
|
|
20
|
-
__export(chunk_O2VPBNS5_exports, {
|
|
21
|
-
TableSchema: () => TableSchema,
|
|
22
|
-
TableType: () => TableType
|
|
23
|
-
});
|
|
24
|
-
module.exports = __toCommonJS(chunk_O2VPBNS5_exports);
|
|
25
|
-
var import_effect = require("effect");
|
|
26
|
-
var import_echo = require("@dxos/echo");
|
|
27
|
-
var import_echo_schema = require("@dxos/echo-schema");
|
|
28
|
-
var import_schema = require("@dxos/schema");
|
|
29
|
-
var TableSchema = import_effect.Schema.Struct({
|
|
30
|
-
id: import_echo_schema.ObjectId,
|
|
31
|
-
name: import_effect.Schema.optional(import_effect.Schema.String),
|
|
32
|
-
view: import_effect.Schema.optional((0, import_echo_schema.Ref)(import_schema.ViewType)),
|
|
33
|
-
// TODO(burdon): Document why threads is included here?
|
|
34
|
-
threads: import_effect.Schema.optional(import_effect.Schema.Array((0, import_echo_schema.Ref)(
|
|
35
|
-
import_echo_schema.Expando
|
|
36
|
-
/* ThreadType */
|
|
37
|
-
)))
|
|
38
|
-
}).pipe(import_echo_schema.LabelAnnotation.set([
|
|
39
|
-
"name"
|
|
40
|
-
]));
|
|
41
|
-
var TableType = TableSchema.pipe(import_echo.Type.Obj({
|
|
42
|
-
typename: "dxos.org/type/Table",
|
|
43
|
-
version: "0.1.0"
|
|
44
|
-
}));
|
|
45
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
-
0 && (module.exports = {
|
|
47
|
-
TableSchema,
|
|
48
|
-
TableType
|
|
49
|
-
});
|
|
50
|
-
//# sourceMappingURL=chunk-O2VPBNS5.cjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/types/table.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\n// import { ThreadType } from '@dxos/plugin-space/types';\nimport { Type } from '@dxos/echo';\nimport { ObjectId, Ref, Expando, LabelAnnotation } from '@dxos/echo-schema';\nimport { ViewType } from '@dxos/schema';\n\nexport const TableSchema = Schema.Struct({\n id: ObjectId,\n name: Schema.optional(Schema.String),\n view: Schema.optional(Ref(ViewType)),\n // TODO(burdon): Document why threads is included here?\n threads: Schema.optional(Schema.Array(Ref(Expando /* ThreadType */))),\n}).pipe(LabelAnnotation.set(['name']));\n\n// TODO(burdon): Move out of react-ui-xxx.\nexport const TableType = TableSchema.pipe(\n Type.Obj({\n typename: 'dxos.org/type/Table',\n version: '0.1.0',\n }),\n);\nexport interface TableType extends Schema.Schema.Type<typeof TableType> {}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAIA,oBAAuB;AAGvB,kBAAqB;AACrB,yBAAwD;AACxD,oBAAyB;AAElB,IAAMA,cAAcC,qBAAOC,OAAO;EACvCC,IAAIC;EACJC,MAAMJ,qBAAOK,SAASL,qBAAOM,MAAM;EACnCC,MAAMP,qBAAOK,aAASG,wBAAIC,sBAAAA,CAAAA;;EAE1BC,SAASV,qBAAOK,SAASL,qBAAOW,UAAMH;IAAII;;EAAsB,CAAA,CAAA;AAClE,CAAA,EAAGC,KAAKC,mCAAgBC,IAAI;EAAC;CAAO,CAAA;AAG7B,IAAMC,YAAYjB,YAAYc,KACnCI,iBAAKC,IAAI;EACPC,UAAU;EACVC,SAAS;AACX,CAAA,CAAA;",
|
|
6
|
-
"names": ["TableSchema", "Schema", "Struct", "id", "ObjectId", "name", "optional", "String", "view", "Ref", "ViewType", "threads", "Array", "Expando", "pipe", "LabelAnnotation", "set", "TableType", "Type", "Obj", "typename", "version"]
|
|
7
|
-
}
|