@dxos/react-ui-table 0.8.4-main.1da679c → 0.8.4-main.21d9917
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-MNZKOFMA.mjs +1746 -0
- package/dist/lib/browser/chunk-MNZKOFMA.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 +1134 -1150
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +29 -39
- 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-2ATAIIAO.mjs +1748 -0
- package/dist/lib/node-esm/chunk-2ATAIIAO.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 +1134 -1150
- 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 +29 -39
- 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 +1 -2
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
- 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 +6 -20
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +77 -10
- 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 +11 -8
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +76 -11
- 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/FormCellEditor.d.ts +12 -12
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +7 -7
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +5 -6
- 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 +5 -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 +8 -8
- 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 +103 -24
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +3 -1
- 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 -15
- 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 -0
- 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/tsconfig.tsbuildinfo +1 -1
- package/package.json +56 -56
- package/src/components/Table/ColumnActionsMenu.tsx +10 -6
- package/src/components/Table/ColumnSettings.tsx +6 -6
- package/src/components/Table/DynamicTable.stories.tsx +18 -18
- package/src/components/Table/DynamicTable.tsx +23 -19
- package/src/components/Table/Relations.stories.tsx +143 -39
- package/src/components/Table/RowActionsMenu.tsx +24 -15
- package/src/components/Table/Table.stories.tsx +92 -95
- package/src/components/Table/Table.tsx +339 -307
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +116 -129
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +23 -47
- package/src/components/TableCellEditor/TableCellEditor.tsx +35 -122
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +47 -31
- package/src/components/testing.ts +39 -13
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAddRow.ts +8 -10
- package/src/hooks/useProjectionModel.ts +40 -0
- package/src/hooks/useTableModel.ts +35 -33
- package/src/model/modal-controller.ts +23 -40
- package/src/model/selection-model.ts +75 -44
- package/src/model/table-model.test.ts +91 -58
- package/src/model/table-model.ts +429 -163
- package/src/model/table-presentation.test.ts +64 -57
- package/src/model/table-presentation.ts +34 -30
- package/src/playwright/TableManager.ts +5 -5
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +11 -8
- package/src/testing/useTestTableModel.ts +44 -35
- 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 +41 -30
- package/src/util/index.ts +2 -0
- package/src/util/query-ast.ts +19 -0
- package/src/util/schema.ts +4 -4
- package/src/util/sort.ts +90 -0
- package/dist/lib/browser/chunk-63UUF4IG.mjs +0 -66
- package/dist/lib/browser/chunk-63UUF4IG.mjs.map +0 -7
- package/dist/lib/browser/chunk-BBXDTWCX.mjs +0 -1822
- package/dist/lib/browser/chunk-BBXDTWCX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-K734DJB7.mjs +0 -67
- package/dist/lib/node-esm/chunk-K734DJB7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RNQDU7IQ.mjs +0 -1823
- package/dist/lib/node-esm/chunk-RNQDU7IQ.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/model/table-sorting.d.ts +0 -52
- package/dist/types/src/model/table-sorting.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -28
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -103
- package/src/model/table-sorting.ts +0 -225
- package/src/types/schema.ts +0 -73
|
@@ -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,95 +2,75 @@
|
|
|
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 {
|
|
9
|
-
import { Ref,
|
|
8
|
+
import { Entity, type Type } from '@dxos/echo';
|
|
9
|
+
import { Ref, getValue } from '@dxos/echo/internal';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import {
|
|
12
|
-
import { type
|
|
13
|
-
import {
|
|
14
|
-
import { Popover } from '@dxos/react-ui';
|
|
15
|
-
import { Form, type FormProps } from '@dxos/react-ui-form';
|
|
16
|
-
import { cellQuery, parseCellIndex, useGridContext } from '@dxos/react-ui-grid';
|
|
11
|
+
import { type Label, Popover } from '@dxos/react-ui';
|
|
12
|
+
import { Form, type FormRootProps, type RefFieldProps } from '@dxos/react-ui-form';
|
|
13
|
+
import { parseCellIndex, useGridContext } from '@dxos/react-ui-grid';
|
|
17
14
|
import { type FieldProjection } from '@dxos/schema';
|
|
18
|
-
import { getDeep,
|
|
15
|
+
import { getDeep, isTruthy, setDeep } from '@dxos/util';
|
|
19
16
|
|
|
20
|
-
import { type ModalController, type TableModel } from '../../model';
|
|
17
|
+
import { type ModalController, type TableModel, type TableRow } from '../../model';
|
|
21
18
|
import { translationKey } from '../../translations';
|
|
22
19
|
import { narrowSchema } from '../../util';
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
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;
|
|
26
28
|
model?: TableModel;
|
|
27
|
-
|
|
29
|
+
fieldProjection: FieldProjection;
|
|
30
|
+
modals?: ModalController; // TODO(burdon): Not used. Remove?
|
|
28
31
|
onSave?: () => void;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
__gridScope: any;
|
|
32
|
-
} & Omit<FormProps<any>, 'values' | 'schema'>;
|
|
32
|
+
onCreate?: OnCreateHandler;
|
|
33
|
+
} & Omit<FormRootProps<any>, 'values' | 'schema' | 'onCreate'>;
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
export const FormCellEditor = ({
|
|
37
|
-
fieldProjection,
|
|
38
|
-
model,
|
|
35
|
+
export const FormCellEditor = <T extends Type.Entity.Any = Type.Entity.Any>({
|
|
36
|
+
__gridScope,
|
|
39
37
|
schema,
|
|
38
|
+
model,
|
|
39
|
+
fieldProjection,
|
|
40
40
|
onSave,
|
|
41
|
-
|
|
42
|
-
modals,
|
|
43
|
-
__gridScope,
|
|
41
|
+
onCreate,
|
|
44
42
|
...formProps
|
|
45
|
-
}: FormCellEditorProps) => {
|
|
46
|
-
const { editing: contextEditing, setEditing, id: gridId } = useGridContext('ArrayEditor', __gridScope);
|
|
47
|
-
const [editing, setLocalEditing] = useState(false);
|
|
43
|
+
}: FormCellEditorProps<T>) => {
|
|
48
44
|
const anchorRef = useRef<HTMLButtonElement | null>(null);
|
|
45
|
+
const { id: _gridId, editing: contextEditing, setEditing } = useGridContext('ArrayEditor', __gridScope);
|
|
46
|
+
const [editing, setLocalEditing] = useState(false);
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return { space, schema };
|
|
63
|
-
},
|
|
64
|
-
[client, model],
|
|
65
|
-
);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (contextEditing && contextEditing.cellElement) {
|
|
50
|
+
anchorRef.current = (contextEditing.cellElement as HTMLElement).querySelector(
|
|
51
|
+
'.dx-grid__cell__content',
|
|
52
|
+
) as HTMLButtonElement;
|
|
53
|
+
setLocalEditing(true);
|
|
54
|
+
} else {
|
|
55
|
+
anchorRef.current = null;
|
|
56
|
+
setLocalEditing(false);
|
|
57
|
+
}
|
|
58
|
+
}, [contextEditing]);
|
|
66
59
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const { objects } = await space.db.query(Filter.type(schema)).run();
|
|
72
|
-
return objects
|
|
73
|
-
.map((obj) => {
|
|
74
|
-
return {
|
|
75
|
-
dxn: Obj.getDXN(obj),
|
|
76
|
-
label: getValue(obj, fieldProjection.field.referencePath!) || obj.id.toString(),
|
|
77
|
-
};
|
|
78
|
-
})
|
|
79
|
-
.filter(isNotFalsy);
|
|
80
|
-
}
|
|
60
|
+
const narrowedSchema = useMemo<Schema.Schema.AnyNoContext | undefined>(() => {
|
|
61
|
+
if (!schema) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
[client, model],
|
|
85
|
-
);
|
|
65
|
+
return narrowSchema(schema, [fieldProjection.field.path]);
|
|
66
|
+
}, [JSON.stringify(schema), fieldProjection.field.path]); // TODO(burdon): Avoid stringify.
|
|
86
67
|
|
|
87
|
-
const originalRow = useMemo(() => {
|
|
68
|
+
const originalRow = useMemo<TableRow | undefined>(() => {
|
|
88
69
|
if (model && contextEditing) {
|
|
89
|
-
const cell = parseCellIndex(contextEditing.index);
|
|
90
|
-
|
|
91
70
|
// Check if this is a draft cell and get the appropriate row data
|
|
71
|
+
const cell = parseCellIndex(contextEditing.index);
|
|
92
72
|
if (model.isDraftCell(cell)) {
|
|
93
|
-
const draftRow = model.
|
|
73
|
+
const draftRow = model.getDraftRows()[cell.row];
|
|
94
74
|
invariant(draftRow);
|
|
95
75
|
return draftRow.data;
|
|
96
76
|
} else {
|
|
@@ -103,79 +83,77 @@ export const FormCellEditor = ({
|
|
|
103
83
|
return undefined;
|
|
104
84
|
}, [model, contextEditing]);
|
|
105
85
|
|
|
106
|
-
|
|
107
|
-
|
|
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?.();
|
|
94
|
+
}
|
|
95
|
+
setLocalEditing(nextOpen);
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
const handleSave = useCallback<NonNullable<FormRootProps<any>['onSave']>>(
|
|
99
|
+
(values) => {
|
|
100
|
+
if (!originalRow) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
108
103
|
const path = fieldProjection.field.path;
|
|
109
104
|
const value = getDeep(values, [path]);
|
|
110
|
-
|
|
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
|
+
}
|
|
111
113
|
contextEditing?.cellElement?.focus();
|
|
112
114
|
setEditing(null);
|
|
113
115
|
setLocalEditing(false);
|
|
114
116
|
onSave?.();
|
|
115
117
|
},
|
|
116
|
-
[fieldProjection.field.path, onSave, contextEditing, originalRow],
|
|
118
|
+
[fieldProjection.field.path, onSave, contextEditing, originalRow, model],
|
|
117
119
|
);
|
|
118
120
|
|
|
119
|
-
const handleCreate = useCallback(
|
|
120
|
-
(
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
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
|
+
}
|
|
124
136
|
contextEditing?.cellElement?.focus();
|
|
125
137
|
setEditing(null);
|
|
126
138
|
setLocalEditing(false);
|
|
127
139
|
onSave?.();
|
|
128
140
|
},
|
|
129
|
-
[fieldProjection.field.path, onSave, contextEditing, originalRow],
|
|
141
|
+
[fieldProjection.field.path, onSave, contextEditing, originalRow, onCreate, model],
|
|
130
142
|
);
|
|
131
143
|
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
[model, modals, client, contextEditing?.index, gridId, fieldProjection, handleSave],
|
|
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],
|
|
147
155
|
);
|
|
148
156
|
|
|
149
|
-
useEffect(() => {
|
|
150
|
-
if (contextEditing && contextEditing.cellElement) {
|
|
151
|
-
anchorRef.current = (contextEditing.cellElement as HTMLElement).querySelector(
|
|
152
|
-
'.dx-grid__cell__content',
|
|
153
|
-
) as HTMLButtonElement;
|
|
154
|
-
setLocalEditing(true);
|
|
155
|
-
} else {
|
|
156
|
-
anchorRef.current = null;
|
|
157
|
-
setLocalEditing(false);
|
|
158
|
-
}
|
|
159
|
-
}, [contextEditing]);
|
|
160
|
-
|
|
161
|
-
const narrowedSchema = useMemo(() => {
|
|
162
|
-
if (!schema) {
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
return narrowSchema(schema, [fieldProjection.field.path]);
|
|
166
|
-
}, [JSON.stringify(schema), fieldProjection.field.path]); // TODO(burdon): Avoid stringify.
|
|
167
|
-
|
|
168
|
-
// NOTE: Important to get a snapshot to eject from the live object.
|
|
169
|
-
const formValues = useMemo(() => (originalRow ? getSnapshot(originalRow) : {}), [originalRow]);
|
|
170
|
-
|
|
171
|
-
const handleOpenChange = useCallback((nextOpen: boolean) => {
|
|
172
|
-
if (nextOpen === false) {
|
|
173
|
-
setEditing(null);
|
|
174
|
-
onSave?.();
|
|
175
|
-
}
|
|
176
|
-
setLocalEditing(nextOpen);
|
|
177
|
-
}, []);
|
|
178
|
-
|
|
179
157
|
if (!editing) {
|
|
180
158
|
return null;
|
|
181
159
|
}
|
|
@@ -187,17 +165,26 @@ export const FormCellEditor = ({
|
|
|
187
165
|
<Popover.Content tabIndex={-1} classNames='popover-card-width density-fine'>
|
|
188
166
|
<Popover.Arrow />
|
|
189
167
|
<Popover.Viewport>
|
|
190
|
-
<Form
|
|
168
|
+
<Form.Root
|
|
169
|
+
{...formProps}
|
|
191
170
|
autoFocus
|
|
171
|
+
schema={narrowedSchema}
|
|
192
172
|
values={formValues}
|
|
193
|
-
|
|
194
|
-
onSave={handleSave}
|
|
195
|
-
{...formProps}
|
|
196
|
-
onQueryRefOptions={handleQueryRefOptions}
|
|
197
|
-
onCreateFromQuery={handleCreateFromQuery}
|
|
173
|
+
createInitialValuePath={fieldProjection.field.referencePath}
|
|
198
174
|
createOptionIcon='ph--plus--regular'
|
|
199
175
|
createOptionLabel={createOptionLabel}
|
|
200
|
-
|
|
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>
|
|
201
188
|
</Popover.Viewport>
|
|
202
189
|
</Popover.Content>
|
|
203
190
|
</Popover.Portal>
|
|
@@ -2,23 +2,18 @@
|
|
|
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 {
|
|
10
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
11
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
16
12
|
import { Grid, type GridEditing, defaultRowSize } from '@dxos/react-ui-grid';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
13
|
+
import { View } from '@dxos/schema';
|
|
14
|
+
import { Task } from '@dxos/types';
|
|
19
15
|
|
|
20
|
-
import {
|
|
21
|
-
import { type TableFeatures } from '../../model';
|
|
16
|
+
import { useTestTableModel } from '../../testing';
|
|
22
17
|
import { translations } from '../../translations';
|
|
23
18
|
import { Table } from '../../types';
|
|
24
19
|
|
|
@@ -28,40 +23,18 @@ 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(typenameFromQuery(view.query)!));
|
|
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
|
-
if (!model || !schema || !view) {
|
|
30
|
+
if (!model || !table) {
|
|
58
31
|
return <div />;
|
|
59
32
|
}
|
|
60
33
|
|
|
61
34
|
return (
|
|
62
|
-
<div className='
|
|
35
|
+
<div className='border border-separator' style={{ height: defaultRowSize }}>
|
|
63
36
|
<Grid.Root id='test' editing={editing}>
|
|
64
|
-
<TableCellEditor model={model} schema={
|
|
37
|
+
<TableCellEditor model={model} schema={Task.Task} />
|
|
65
38
|
</Grid.Root>
|
|
66
39
|
</div>
|
|
67
40
|
);
|
|
@@ -71,19 +44,20 @@ const meta = {
|
|
|
71
44
|
title: 'ui/react-ui-table/TableCellEditor',
|
|
72
45
|
component: DefaultStory,
|
|
73
46
|
render: DefaultStory,
|
|
74
|
-
parameters: { translations, layout: 'centered' },
|
|
75
47
|
decorators: [
|
|
48
|
+
withTheme,
|
|
49
|
+
withLayout({ layout: 'column' }),
|
|
76
50
|
withClientProvider({
|
|
77
|
-
types: [
|
|
51
|
+
types: [View.View, Task.Task, Table.Table],
|
|
78
52
|
createIdentity: true,
|
|
79
53
|
createSpace: true,
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
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);
|
|
84
58
|
Array.from({ length: 10 }).forEach(() => {
|
|
85
59
|
space.db.add(
|
|
86
|
-
Obj.make(
|
|
60
|
+
Obj.make(Task.Task, {
|
|
87
61
|
title: faker.person.fullName(),
|
|
88
62
|
status: faker.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
|
|
89
63
|
description: faker.lorem.sentence(),
|
|
@@ -92,9 +66,11 @@ const meta = {
|
|
|
92
66
|
});
|
|
93
67
|
},
|
|
94
68
|
}),
|
|
95
|
-
withTheme,
|
|
96
|
-
withLayout(),
|
|
97
69
|
],
|
|
70
|
+
parameters: {
|
|
71
|
+
layout: 'fullscreen',
|
|
72
|
+
translations,
|
|
73
|
+
},
|
|
98
74
|
} satisfies Meta<typeof DefaultStory>;
|
|
99
75
|
|
|
100
76
|
export default meta;
|