@dxos/react-ui-table 0.8.4-main.67995b8 → 0.8.4-main.69d29f4
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-I5IFW7UF.mjs +1746 -0
- package/dist/lib/browser/chunk-I5IFW7UF.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 +1163 -1120
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +30 -37
- 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-DDJKYJFY.mjs +1748 -0
- package/dist/lib/node-esm/chunk-DDJKYJFY.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 +1163 -1120
- 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 +30 -37
- 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/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 +3 -3
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +5 -6
- 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 +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +13 -9
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +11 -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 +23 -16
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +6 -6
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- 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 +9 -9
- package/dist/types/src/hooks/useTableModel.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 -8
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +109 -28
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +5 -2
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +1 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +18 -34
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +4 -4
- 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 +13 -12
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- 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.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 +65 -64
- package/src/components/Table/ColumnActionsMenu.tsx +11 -7
- package/src/components/Table/ColumnSettings.tsx +7 -7
- package/src/components/Table/DynamicTable.stories.tsx +25 -22
- package/src/components/Table/DynamicTable.tsx +26 -21
- package/src/components/Table/Relations.stories.tsx +237 -0
- package/src/components/Table/RowActionsMenu.tsx +26 -17
- package/src/components/Table/Table.stories.tsx +110 -102
- package/src/components/Table/Table.tsx +353 -298
- package/src/components/TableCellEditor/CellValidationMessage.tsx +2 -2
- package/src/components/TableCellEditor/FormCellEditor.tsx +128 -40
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +30 -66
- package/src/components/TableCellEditor/TableCellEditor.tsx +88 -238
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +49 -33
- package/src/components/testing.ts +39 -13
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAddRow.ts +14 -14
- package/src/hooks/useProjectionModel.ts +39 -0
- package/src/hooks/useTableModel.ts +35 -33
- package/src/model/modal-controller.ts +24 -41
- package/src/model/selection-model.ts +75 -43
- package/src/model/table-model.test.ts +92 -55
- package/src/model/table-model.ts +445 -168
- package/src/model/table-presentation.test.ts +70 -58
- package/src/model/table-presentation.ts +103 -57
- package/src/playwright/TableManager.ts +5 -5
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +135 -40
- package/src/testing/useTestTableModel.ts +45 -34
- package/src/translations.ts +3 -3
- package/src/types/Table.ts +90 -0
- package/src/types/index.ts +1 -1
- package/src/util/dynamic-table.ts +44 -32
- 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 +4 -3
- package/src/util/table-controls.ts +4 -1
- package/dist/lib/browser/chunk-5XLSHLOG.mjs +0 -1751
- package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
- package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
- package/dist/lib/browser/chunk-L2LSB6KV.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-Y66YLSTC.mjs +0 -1752
- package/dist/lib/node-esm/chunk-Y66YLSTC.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/schema.d.ts +0 -8
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -11
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -86
- package/src/components/Table/relations.stories.tsx +0 -116
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/model/table-sorting.ts +0 -216
- package/src/types/schema.ts +0 -16
- package/src/util/table.ts +0 -49
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { type GridScopedProps, useGridContext } from '@dxos/react-ui-grid';
|
|
8
8
|
|
|
9
9
|
export type CellValidationMessageProps = {
|
|
10
10
|
validationError: string | null;
|
|
@@ -12,9 +12,9 @@ export type CellValidationMessageProps = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export const CellValidationMessage = ({
|
|
15
|
+
__gridScope,
|
|
15
16
|
validationError,
|
|
16
17
|
variant = 'error',
|
|
17
|
-
__gridScope,
|
|
18
18
|
}: GridScopedProps<CellValidationMessageProps>) => {
|
|
19
19
|
const { editing, editBox: box } = useGridContext('GridSheetCellEditor', __gridScope);
|
|
20
20
|
|
|
@@ -2,32 +2,48 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Entity, type Type } from '@dxos/echo';
|
|
9
|
+
import { Ref, getValue } from '@dxos/echo/internal';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
10
|
-
import { Popover } from '@dxos/react-ui';
|
|
11
|
-
import { Form } from '@dxos/react-ui-form';
|
|
11
|
+
import { type Label, Popover } from '@dxos/react-ui';
|
|
12
|
+
import { Form, type FormRootProps, type RefFieldProps } from '@dxos/react-ui-form';
|
|
12
13
|
import { parseCellIndex, useGridContext } from '@dxos/react-ui-grid';
|
|
13
14
|
import { type FieldProjection } from '@dxos/schema';
|
|
14
|
-
import { getDeep, setDeep } from '@dxos/util';
|
|
15
|
+
import { getDeep, isTruthy, setDeep } from '@dxos/util';
|
|
15
16
|
|
|
16
|
-
import { type TableModel } from '../../model';
|
|
17
|
+
import { type ModalController, type TableModel, type TableRow } from '../../model';
|
|
18
|
+
import { translationKey } from '../../translations';
|
|
17
19
|
import { narrowSchema } from '../../util';
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const createOptionLabel: Label = ['create new object label', { ns: translationKey }];
|
|
22
|
+
|
|
23
|
+
export type OnCreateHandler = (schema: Type.Entity.Any, values: any) => Parameters<typeof Ref.make>[0];
|
|
24
|
+
|
|
25
|
+
export type FormCellEditorProps<T extends Type.Entity.Any = Type.Entity.Any> = {
|
|
26
|
+
__gridScope: any;
|
|
27
|
+
schema?: T;
|
|
21
28
|
model?: TableModel;
|
|
22
|
-
|
|
29
|
+
fieldProjection: FieldProjection;
|
|
30
|
+
modals?: ModalController; // TODO(burdon): Not used. Remove?
|
|
23
31
|
onSave?: () => void;
|
|
24
|
-
|
|
25
|
-
}
|
|
32
|
+
onCreate?: OnCreateHandler;
|
|
33
|
+
} & Omit<FormRootProps<any>, 'values' | 'schema' | 'onCreate'>;
|
|
26
34
|
|
|
27
|
-
export const FormCellEditor =
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
export const FormCellEditor = <T extends Type.Entity.Any = Type.Entity.Any>({
|
|
36
|
+
__gridScope,
|
|
37
|
+
schema,
|
|
38
|
+
model,
|
|
39
|
+
fieldProjection,
|
|
40
|
+
onSave,
|
|
41
|
+
onCreate,
|
|
42
|
+
...formProps
|
|
43
|
+
}: FormCellEditorProps<T>) => {
|
|
30
44
|
const anchorRef = useRef<HTMLButtonElement | null>(null);
|
|
45
|
+
const { id: _gridId, editing: contextEditing, setEditing } = useGridContext('ArrayEditor', __gridScope);
|
|
46
|
+
const [editing, setLocalEditing] = useState(false);
|
|
31
47
|
|
|
32
48
|
useEffect(() => {
|
|
33
49
|
if (contextEditing && contextEditing.cellElement) {
|
|
@@ -41,51 +57,102 @@ export const FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridS
|
|
|
41
57
|
}
|
|
42
58
|
}, [contextEditing]);
|
|
43
59
|
|
|
44
|
-
const narrowedSchema = useMemo(() => {
|
|
60
|
+
const narrowedSchema = useMemo<Schema.Schema.AnyNoContext | undefined>(() => {
|
|
45
61
|
if (!schema) {
|
|
46
62
|
return undefined;
|
|
47
63
|
}
|
|
64
|
+
|
|
48
65
|
return narrowSchema(schema, [fieldProjection.field.path]);
|
|
49
66
|
}, [JSON.stringify(schema), fieldProjection.field.path]); // TODO(burdon): Avoid stringify.
|
|
50
67
|
|
|
51
|
-
const originalRow = useMemo(() => {
|
|
68
|
+
const originalRow = useMemo<TableRow | undefined>(() => {
|
|
52
69
|
if (model && contextEditing) {
|
|
70
|
+
// Check if this is a draft cell and get the appropriate row data
|
|
53
71
|
const cell = parseCellIndex(contextEditing.index);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
if (model.isDraftCell(cell)) {
|
|
73
|
+
const draftRow = model.getDraftRows()[cell.row];
|
|
74
|
+
invariant(draftRow);
|
|
75
|
+
return draftRow.data;
|
|
76
|
+
} else {
|
|
77
|
+
const row = model.getRowAt(cell.row);
|
|
78
|
+
invariant(row);
|
|
79
|
+
return row;
|
|
80
|
+
}
|
|
58
81
|
}
|
|
59
82
|
|
|
60
83
|
return undefined;
|
|
61
84
|
}, [model, contextEditing]);
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
86
|
+
// NOTE: Important to get a mutable deep clone to eject from the echo object.
|
|
87
|
+
// TODO(wittjosiah): Consider using something like Obj.clone for this use case.
|
|
88
|
+
const formValues = useMemo(() => (originalRow ? JSON.parse(JSON.stringify(originalRow)) : {}), [originalRow]);
|
|
89
|
+
|
|
90
|
+
const handleOpenChange = useCallback((nextOpen: boolean) => {
|
|
91
|
+
if (nextOpen === false) {
|
|
92
|
+
setEditing(null);
|
|
93
|
+
onSave?.();
|
|
67
94
|
}
|
|
68
|
-
|
|
95
|
+
setLocalEditing(nextOpen);
|
|
96
|
+
}, []);
|
|
69
97
|
|
|
70
|
-
const handleSave = useCallback(
|
|
71
|
-
(values
|
|
98
|
+
const handleSave = useCallback<NonNullable<FormRootProps<any>['onSave']>>(
|
|
99
|
+
(values) => {
|
|
100
|
+
if (!originalRow) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
72
103
|
const path = fieldProjection.field.path;
|
|
73
104
|
const value = getDeep(values, [path]);
|
|
74
|
-
|
|
105
|
+
// Use model's changeRow for consistent mutation handling.
|
|
106
|
+
if (model) {
|
|
107
|
+
model.changeRow(originalRow, (mutableRow) => {
|
|
108
|
+
setDeep(mutableRow, [path], value);
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
setDeep(originalRow, [path], value);
|
|
112
|
+
}
|
|
113
|
+
contextEditing?.cellElement?.focus();
|
|
75
114
|
setEditing(null);
|
|
76
115
|
setLocalEditing(false);
|
|
77
116
|
onSave?.();
|
|
78
117
|
},
|
|
79
|
-
[fieldProjection.field.path, originalRow],
|
|
118
|
+
[fieldProjection.field.path, onSave, contextEditing, originalRow, model],
|
|
80
119
|
);
|
|
81
120
|
|
|
82
|
-
const
|
|
83
|
-
|
|
121
|
+
const handleCreate = useCallback<NonNullable<FormRootProps<any>['onCreate']>>(
|
|
122
|
+
(schema, values) => {
|
|
123
|
+
const objectWithId = onCreate?.(schema, values);
|
|
124
|
+
if (objectWithId && originalRow) {
|
|
125
|
+
const ref = Ref.make(objectWithId);
|
|
126
|
+
const path = fieldProjection.field.path;
|
|
127
|
+
// Use model's changeRow for consistent mutation handling.
|
|
128
|
+
if (model) {
|
|
129
|
+
model.changeRow(originalRow, (mutableRow) => {
|
|
130
|
+
setDeep(mutableRow, [path], ref);
|
|
131
|
+
});
|
|
132
|
+
} else {
|
|
133
|
+
setDeep(originalRow, [path], ref);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
contextEditing?.cellElement?.focus();
|
|
84
137
|
setEditing(null);
|
|
138
|
+
setLocalEditing(false);
|
|
85
139
|
onSave?.();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
140
|
+
},
|
|
141
|
+
[fieldProjection.field.path, onSave, contextEditing, originalRow, onCreate, model],
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const getOptions = useCallback<NonNullable<RefFieldProps['getOptions']>>(
|
|
145
|
+
(results) =>
|
|
146
|
+
results
|
|
147
|
+
.map((obj) => {
|
|
148
|
+
return {
|
|
149
|
+
id: Entity.getDXN(obj).toString(),
|
|
150
|
+
label: getValue(obj, fieldProjection.field.referencePath!) || obj.id.toString(),
|
|
151
|
+
};
|
|
152
|
+
})
|
|
153
|
+
.filter(isTruthy),
|
|
154
|
+
[fieldProjection],
|
|
155
|
+
);
|
|
89
156
|
|
|
90
157
|
if (!editing) {
|
|
91
158
|
return null;
|
|
@@ -94,12 +161,33 @@ export const FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridS
|
|
|
94
161
|
return (
|
|
95
162
|
<Popover.Root open={editing} onOpenChange={handleOpenChange}>
|
|
96
163
|
<Popover.VirtualTrigger virtualRef={anchorRef} />
|
|
97
|
-
<Popover.
|
|
98
|
-
<Popover.
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
164
|
+
<Popover.Portal>
|
|
165
|
+
<Popover.Content tabIndex={-1} classNames='popover-card-width density-fine'>
|
|
166
|
+
<Popover.Arrow />
|
|
167
|
+
<Popover.Viewport>
|
|
168
|
+
<Form.Root
|
|
169
|
+
{...formProps}
|
|
170
|
+
autoFocus
|
|
171
|
+
schema={narrowedSchema}
|
|
172
|
+
values={formValues}
|
|
173
|
+
createInitialValuePath={fieldProjection.field.referencePath}
|
|
174
|
+
createOptionIcon='ph--plus--regular'
|
|
175
|
+
createOptionLabel={createOptionLabel}
|
|
176
|
+
db={model?.db}
|
|
177
|
+
getOptions={getOptions}
|
|
178
|
+
onCreate={handleCreate}
|
|
179
|
+
onSave={handleSave}
|
|
180
|
+
>
|
|
181
|
+
<Form.Viewport>
|
|
182
|
+
<Form.Content>
|
|
183
|
+
<Form.FieldSet />
|
|
184
|
+
<Form.Actions />
|
|
185
|
+
</Form.Content>
|
|
186
|
+
</Form.Viewport>
|
|
187
|
+
</Form.Root>
|
|
188
|
+
</Popover.Viewport>
|
|
189
|
+
</Popover.Content>
|
|
190
|
+
</Popover.Portal>
|
|
103
191
|
</Popover.Root>
|
|
104
192
|
);
|
|
105
193
|
};
|
|
@@ -2,100 +2,62 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
|
-
import React
|
|
6
|
+
import React from 'react';
|
|
9
7
|
|
|
10
8
|
import { Obj } from '@dxos/echo';
|
|
11
|
-
import { type EchoSchema, isMutable } from '@dxos/echo-schema';
|
|
12
|
-
import { invariant } from '@dxos/invariant';
|
|
13
9
|
import { faker } from '@dxos/random';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
10
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
11
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
12
|
+
import { Grid, type GridEditing, defaultRowSize } from '@dxos/react-ui-grid';
|
|
13
|
+
import { View } from '@dxos/schema';
|
|
14
|
+
import { Task } from '@dxos/types';
|
|
19
15
|
|
|
20
|
-
import {
|
|
21
|
-
import { useTableModel } from '../../hooks';
|
|
22
|
-
import { type TableFeatures } from '../../model';
|
|
16
|
+
import { useTestTableModel } from '../../testing';
|
|
23
17
|
import { translations } from '../../translations';
|
|
24
|
-
import {
|
|
25
|
-
|
|
18
|
+
import { Table } from '../../types';
|
|
19
|
+
|
|
20
|
+
import { TableCellEditor } from './TableCellEditor';
|
|
26
21
|
|
|
27
22
|
type StoryProps = {
|
|
28
23
|
editing: GridEditing;
|
|
29
24
|
};
|
|
30
25
|
|
|
26
|
+
// TODO(burdon): Broken layout.
|
|
31
27
|
const DefaultStory = ({ editing }: StoryProps) => {
|
|
32
|
-
const {
|
|
33
|
-
invariant(space);
|
|
34
|
-
|
|
35
|
-
const views = useQuery(space, Filter.type(DataType.View));
|
|
36
|
-
const [view, setView] = useState<DataType.View>();
|
|
37
|
-
const [schema, setSchema] = useState<EchoSchema>();
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (space && views.length && !view) {
|
|
40
|
-
const view = views[0];
|
|
41
|
-
setView(view);
|
|
42
|
-
setSchema(space.db.schemaRegistry.getSchema(view.query.typename!));
|
|
43
|
-
}
|
|
44
|
-
}, [space, views, view]);
|
|
45
|
-
|
|
46
|
-
const features: Partial<TableFeatures> = useMemo(
|
|
47
|
-
() => ({
|
|
48
|
-
selection: { enabled: true, mode: 'multiple' },
|
|
49
|
-
dataEditable: true,
|
|
50
|
-
schemaEditable: schema && isMutable(schema),
|
|
51
|
-
}),
|
|
52
|
-
[schema],
|
|
53
|
-
);
|
|
28
|
+
const { model, table } = useTestTableModel();
|
|
54
29
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const handleQuery: TableCellEditorProps['onQuery'] = async ({ field }) => {
|
|
58
|
-
// TODO(dmaretskyi): If no schema query nothing
|
|
59
|
-
const { objects } = await space.db.query(schema ? Filter.type(schema) : Filter.everything()).run();
|
|
60
|
-
return objects.map((obj) => {
|
|
61
|
-
const label = obj[field.referencePath ?? 'id'];
|
|
62
|
-
return {
|
|
63
|
-
label,
|
|
64
|
-
data: obj,
|
|
65
|
-
};
|
|
66
|
-
});
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
if (!model || !schema || !view) {
|
|
30
|
+
if (!model || !table) {
|
|
70
31
|
return <div />;
|
|
71
32
|
}
|
|
72
33
|
|
|
73
34
|
return (
|
|
74
|
-
<div className='
|
|
35
|
+
<div className='border border-separator' style={{ height: defaultRowSize }}>
|
|
75
36
|
<Grid.Root id='test' editing={editing}>
|
|
76
|
-
<TableCellEditor model={model}
|
|
37
|
+
<TableCellEditor model={model} schema={Task.Task} />
|
|
77
38
|
</Grid.Root>
|
|
78
39
|
</div>
|
|
79
40
|
);
|
|
80
41
|
};
|
|
81
42
|
|
|
82
|
-
const meta
|
|
43
|
+
const meta = {
|
|
83
44
|
title: 'ui/react-ui-table/TableCellEditor',
|
|
84
45
|
component: DefaultStory,
|
|
85
46
|
render: DefaultStory,
|
|
86
|
-
parameters: { translations, layout: 'centered' },
|
|
87
47
|
decorators: [
|
|
48
|
+
withTheme,
|
|
49
|
+
withLayout({ layout: 'column' }),
|
|
88
50
|
withClientProvider({
|
|
89
|
-
types: [
|
|
51
|
+
types: [View.View, Task.Task, Table.Table],
|
|
90
52
|
createIdentity: true,
|
|
91
53
|
createSpace: true,
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
space.db.add(
|
|
54
|
+
onCreateSpace: async ({ space }) => {
|
|
55
|
+
const { view, jsonSchema } = await View.makeFromDatabase({ db: space.db, typename: Task.Task.typename });
|
|
56
|
+
const table = Table.make({ view, jsonSchema });
|
|
57
|
+
space.db.add(table);
|
|
96
58
|
Array.from({ length: 10 }).forEach(() => {
|
|
97
59
|
space.db.add(
|
|
98
|
-
Obj.make(
|
|
60
|
+
Obj.make(Task.Task, {
|
|
99
61
|
title: faker.person.fullName(),
|
|
100
62
|
status: faker.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
|
|
101
63
|
description: faker.lorem.sentence(),
|
|
@@ -104,14 +66,16 @@ const meta: Meta<StoryProps> = {
|
|
|
104
66
|
});
|
|
105
67
|
},
|
|
106
68
|
}),
|
|
107
|
-
withTheme,
|
|
108
|
-
withLayout(),
|
|
109
69
|
],
|
|
110
|
-
|
|
70
|
+
parameters: {
|
|
71
|
+
layout: 'fullscreen',
|
|
72
|
+
translations,
|
|
73
|
+
},
|
|
74
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
111
75
|
|
|
112
76
|
export default meta;
|
|
113
77
|
|
|
114
|
-
type Story = StoryObj<
|
|
78
|
+
type Story = StoryObj<typeof meta>;
|
|
115
79
|
|
|
116
80
|
export const Default: Story = {
|
|
117
81
|
args: {
|