@dxos/react-ui-table 0.8.4-main.67995b8 → 0.8.4-main.72ec0f3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/chunk-2PFAPQL4.mjs +66 -0
- package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-GS2UNGJK.mjs} +493 -469
- package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +610 -695
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +14 -9
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs +67 -0
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-TRR3C5NX.mjs} +493 -469
- package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +610 -695
- 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 +14 -9
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +2 -2
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +51 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +107 -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 +8 -4
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +42 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -6
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +12 -17
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
- package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +3 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +3 -2
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +4 -4
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +0 -7
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +11 -9
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +2 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +3 -4
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +3 -22
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +25 -5
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +5 -6
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +61 -59
- package/src/components/Table/ColumnActionsMenu.tsx +1 -1
- package/src/components/Table/ColumnSettings.tsx +1 -1
- package/src/components/Table/DynamicTable.stories.tsx +18 -14
- package/src/components/Table/DynamicTable.tsx +8 -10
- package/src/components/Table/Relations.stories.tsx +242 -0
- package/src/components/Table/RowActionsMenu.tsx +23 -15
- package/src/components/Table/Table.stories.tsx +72 -60
- package/src/components/Table/Table.tsx +140 -115
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +153 -42
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +26 -65
- package/src/components/TableCellEditor/TableCellEditor.tsx +74 -224
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +34 -24
- package/src/components/testing.ts +2 -2
- package/src/hooks/useAddRow.ts +7 -5
- package/src/hooks/useTableModel.ts +6 -6
- package/src/model/modal-controller.ts +1 -29
- package/src/model/selection-model.ts +3 -2
- package/src/model/table-model.test.ts +20 -11
- package/src/model/table-model.ts +46 -31
- package/src/model/table-presentation.test.ts +24 -22
- package/src/model/table-presentation.ts +74 -33
- package/src/model/table-sorting.ts +17 -8
- package/src/playwright/TableManager.ts +1 -1
- package/src/playwright/smoke.spec.ts +131 -37
- package/src/testing/useTestTableModel.ts +12 -8
- package/src/translations.ts +2 -2
- package/src/types/index.ts +1 -1
- package/src/types/schema.ts +63 -6
- package/src/util/dynamic-table.ts +16 -17
- package/src/util/index.ts +0 -1
- package/src/util/schema.ts +4 -4
- package/src/util/table-buttons.ts +4 -3
- package/src/util/table-controls.ts +4 -1
- 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.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/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/util/table.ts +0 -49
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
TableModel,
|
|
9
9
|
TablePresentation,
|
|
10
10
|
cellClassesForRowSelection,
|
|
11
|
-
createTable,
|
|
12
11
|
getBaseSchema,
|
|
13
12
|
makeDynamicTable,
|
|
14
13
|
narrowSchema,
|
|
@@ -17,8 +16,8 @@ import {
|
|
|
17
16
|
touch,
|
|
18
17
|
useAddRow,
|
|
19
18
|
useTableModel
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-TRR3C5NX.mjs";
|
|
20
|
+
import "./chunk-6POOFFYF.mjs";
|
|
22
21
|
|
|
23
22
|
// src/translations.ts
|
|
24
23
|
var translationKey = "react-ui-table";
|
|
@@ -30,8 +29,8 @@ var translations = [
|
|
|
30
29
|
"create object label": "Create table",
|
|
31
30
|
"table name placeholder": "Table name",
|
|
32
31
|
"settings title": "Table settings",
|
|
33
|
-
"table schema label": "
|
|
34
|
-
"new schema": "New
|
|
32
|
+
"table schema label": "Record type",
|
|
33
|
+
"new schema": "New record type",
|
|
35
34
|
"continue label": "Continue",
|
|
36
35
|
"create stack section label": "Create table",
|
|
37
36
|
"add row label": "Add row",
|
|
@@ -53,271 +52,37 @@ var translations = [
|
|
|
53
52
|
];
|
|
54
53
|
|
|
55
54
|
// src/components/Table/Table.tsx
|
|
56
|
-
import { useSignals as
|
|
57
|
-
import
|
|
58
|
-
import {
|
|
59
|
-
import { getValue } from "@dxos/echo-schema";
|
|
60
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
61
|
-
import { getSpace as getSpace2 } from "@dxos/react-client/echo";
|
|
62
|
-
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
55
|
+
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
56
|
+
import * as String2 from "effect/String";
|
|
57
|
+
import React7, { forwardRef, useCallback as useCallback4, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo4, useState as useState4 } from "react";
|
|
63
58
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
64
|
-
import { closestCell,
|
|
59
|
+
import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
|
|
60
|
+
import { DxEditRequest } from "@dxos/react-ui-grid";
|
|
65
61
|
import { mx } from "@dxos/react-ui-theme";
|
|
66
|
-
import { isNotFalsy, safeParseInt } from "@dxos/util";
|
|
67
|
-
|
|
68
|
-
// src/components/Table/ColumnActionsMenu.tsx
|
|
69
|
-
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
70
|
-
import React from "react";
|
|
71
|
-
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
72
|
-
var ColumnActionsMenu = ({ model, modals }) => {
|
|
73
|
-
var _effect = _useSignals();
|
|
74
|
-
try {
|
|
75
|
-
const { t } = useTranslation(translationKey);
|
|
76
|
-
const state = modals.state.value;
|
|
77
|
-
if (state?.type !== "column") {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
const currentSort = model.sorting?.sorting;
|
|
81
|
-
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
82
|
-
return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
83
|
-
modal: false,
|
|
84
|
-
open: true,
|
|
85
|
-
onOpenChange: modals.close
|
|
86
|
-
}, /* @__PURE__ */ React.createElement(DropdownMenu.VirtualTrigger, {
|
|
87
|
-
virtualRef: modals.trigger
|
|
88
|
-
}), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
89
|
-
"data-testid": "column-sort-descending",
|
|
90
|
-
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
91
|
-
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
92
|
-
"data-testid": "column-sort-ascending",
|
|
93
|
-
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
94
|
-
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
95
|
-
"data-testid": "column-clear-sort",
|
|
96
|
-
onClick: () => model.sorting?.clearSort()
|
|
97
|
-
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
98
|
-
"data-testid": "column-delete",
|
|
99
|
-
onClick: () => model.deleteColumn(state.fieldId)
|
|
100
|
-
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
101
|
-
"data-testid": "column-settings",
|
|
102
|
-
onClick: () => modals.openColumnSettings()
|
|
103
|
-
}, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
|
|
104
|
-
} finally {
|
|
105
|
-
_effect.f();
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// src/components/Table/ColumnSettings.tsx
|
|
110
|
-
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
111
|
-
import React2, { useCallback, useEffect, useMemo, useState } from "react";
|
|
112
|
-
import { Popover } from "@dxos/react-ui";
|
|
113
|
-
import { FieldEditor } from "@dxos/react-ui-form";
|
|
114
|
-
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
115
|
-
var _effect = _useSignals2();
|
|
116
|
-
try {
|
|
117
|
-
const [newField, setNewField] = useState();
|
|
118
|
-
const state = modals.state.value;
|
|
119
|
-
useEffect(() => {
|
|
120
|
-
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
121
|
-
setNewField(model.projection.createFieldProjection());
|
|
122
|
-
requestAnimationFrame(() => {
|
|
123
|
-
onNewColumn();
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
126
|
-
setNewField(void 0);
|
|
127
|
-
}
|
|
128
|
-
}, [
|
|
129
|
-
model?.projection,
|
|
130
|
-
state
|
|
131
|
-
]);
|
|
132
|
-
const existingField = useMemo(() => {
|
|
133
|
-
if (state?.type === "columnSettings") {
|
|
134
|
-
const { mode } = state;
|
|
135
|
-
if (mode.type === "edit") {
|
|
136
|
-
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return void 0;
|
|
140
|
-
}, [
|
|
141
|
-
model?.projection?.fields,
|
|
142
|
-
state
|
|
143
|
-
]);
|
|
144
|
-
const field = existingField ?? newField;
|
|
145
|
-
const handleSave = useCallback(() => {
|
|
146
|
-
modals.close();
|
|
147
|
-
}, [
|
|
148
|
-
modals
|
|
149
|
-
]);
|
|
150
|
-
const handleCancel = useCallback(() => {
|
|
151
|
-
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
152
|
-
model?.projection.deleteFieldProjection(newField.id);
|
|
153
|
-
}
|
|
154
|
-
}, [
|
|
155
|
-
model?.projection,
|
|
156
|
-
state,
|
|
157
|
-
newField
|
|
158
|
-
]);
|
|
159
|
-
if (!model?.projection || !field) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
163
|
-
modal: false,
|
|
164
|
-
open: state?.type === "columnSettings"
|
|
165
|
-
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
166
|
-
virtualRef: modals.trigger
|
|
167
|
-
}), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
168
|
-
classNames: "md:is-64"
|
|
169
|
-
}, /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
|
|
170
|
-
projection: model.projection,
|
|
171
|
-
field,
|
|
172
|
-
registry,
|
|
173
|
-
onSave: handleSave,
|
|
174
|
-
onCancel: handleCancel
|
|
175
|
-
})), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))));
|
|
176
|
-
} finally {
|
|
177
|
-
_effect.f();
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// src/components/Table/CreateRefPanel.tsx
|
|
182
|
-
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
183
|
-
import { Schema } from "effect";
|
|
184
|
-
import React3, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
185
|
-
import { live } from "@dxos/live-object";
|
|
186
|
-
import { getSpace } from "@dxos/react-client/echo";
|
|
187
|
-
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
188
|
-
import { Form } from "@dxos/react-ui-form";
|
|
189
|
-
import { useGridContext } from "@dxos/react-ui-grid";
|
|
190
|
-
var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
191
|
-
var _effect = _useSignals3();
|
|
192
|
-
try {
|
|
193
|
-
const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
|
|
194
|
-
const space = model && getSpace(model?.view);
|
|
195
|
-
const state = modals.state.value;
|
|
196
|
-
const schema = useMemo2(() => {
|
|
197
|
-
if (!space || state?.type !== "createRefPanel") {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
const [schema2] = space.db.schemaRegistry.query({
|
|
201
|
-
typename: state.typename
|
|
202
|
-
}).runSync();
|
|
203
|
-
if (schema2) {
|
|
204
|
-
const omit = Schema.omit("id");
|
|
205
|
-
return omit(schema2);
|
|
206
|
-
}
|
|
207
|
-
}, [
|
|
208
|
-
space,
|
|
209
|
-
state
|
|
210
|
-
]);
|
|
211
|
-
const handleSave = useCallback2((values) => {
|
|
212
|
-
if (!model || !space || state?.type !== "createRefPanel") {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const [schema2] = space.db.schemaRegistry.query({
|
|
216
|
-
typename: state.typename
|
|
217
|
-
}).runSync();
|
|
218
|
-
if (schema2) {
|
|
219
|
-
const obj = space.db.add(live(schema2, values));
|
|
220
|
-
state.onCreate?.(obj);
|
|
221
|
-
}
|
|
222
|
-
void modals.close();
|
|
223
|
-
}, [
|
|
224
|
-
modals,
|
|
225
|
-
space,
|
|
226
|
-
state
|
|
227
|
-
]);
|
|
228
|
-
const handleCancel = useCallback2(() => {
|
|
229
|
-
if (model) {
|
|
230
|
-
modals.close();
|
|
231
|
-
}
|
|
232
|
-
}, [
|
|
233
|
-
modals
|
|
234
|
-
]);
|
|
235
|
-
if (!model?.projection) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
return /* @__PURE__ */ React3.createElement(Popover2.Root, {
|
|
239
|
-
modal: false,
|
|
240
|
-
open: state?.type === "createRefPanel" && !!schema,
|
|
241
|
-
onOpenChange: (nextOpen) => {
|
|
242
|
-
if (model && !nextOpen) {
|
|
243
|
-
return modals.close();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}, /* @__PURE__ */ React3.createElement(Popover2.VirtualTrigger, {
|
|
247
|
-
virtualRef: modals.trigger
|
|
248
|
-
}), /* @__PURE__ */ React3.createElement(Popover2.Portal, null, /* @__PURE__ */ React3.createElement(Popover2.Content, {
|
|
249
|
-
classNames: "md:is-64",
|
|
250
|
-
"data-grid": gridId
|
|
251
|
-
}, /* @__PURE__ */ React3.createElement(Popover2.Viewport, null, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React3.createElement(Form, {
|
|
252
|
-
schema,
|
|
253
|
-
values: state.initialValues ?? {},
|
|
254
|
-
onSave: handleSave,
|
|
255
|
-
onCancel: handleCancel
|
|
256
|
-
})), /* @__PURE__ */ React3.createElement(Popover2.Arrow, null))));
|
|
257
|
-
} finally {
|
|
258
|
-
_effect.f();
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// src/components/Table/RowActionsMenu.tsx
|
|
263
|
-
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
264
|
-
import React4 from "react";
|
|
265
|
-
import { DropdownMenu as DropdownMenu2, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
266
|
-
var RowActionsMenu = ({ model, modals }) => {
|
|
267
|
-
var _effect = _useSignals4();
|
|
268
|
-
try {
|
|
269
|
-
const { t } = useTranslation2(translationKey);
|
|
270
|
-
const hasSelection = model.selection.hasSelection.value;
|
|
271
|
-
const state = modals.state.value;
|
|
272
|
-
if (state?.type !== "row") {
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
|
-
return /* @__PURE__ */ React4.createElement(DropdownMenu2.Root, {
|
|
276
|
-
modal: false,
|
|
277
|
-
open: true,
|
|
278
|
-
onOpenChange: modals.close
|
|
279
|
-
}, /* @__PURE__ */ React4.createElement(DropdownMenu2.VirtualTrigger, {
|
|
280
|
-
virtualRef: modals.trigger
|
|
281
|
-
}), /* @__PURE__ */ React4.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu2.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React4.createElement(DropdownMenu2.Item, {
|
|
282
|
-
"data-testid": "row-menu-delete",
|
|
283
|
-
onClick: () => model.deleteRow(state.rowIndex)
|
|
284
|
-
}, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React4.createElement(DropdownMenu2.Item, {
|
|
285
|
-
key: action.id,
|
|
286
|
-
"data-testid": `row-action-${action.id}`,
|
|
287
|
-
onClick: () => {
|
|
288
|
-
modals.close();
|
|
289
|
-
model.handleRowAction(action.id, state.rowIndex);
|
|
290
|
-
}
|
|
291
|
-
}, t(action.translationKey)))), /* @__PURE__ */ React4.createElement(DropdownMenu2.Arrow, null)));
|
|
292
|
-
} finally {
|
|
293
|
-
_effect.f();
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
62
|
|
|
297
63
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
298
|
-
import { useSignals as
|
|
299
|
-
import
|
|
300
|
-
import {
|
|
64
|
+
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
65
|
+
import { EditorView } from "@codemirror/view";
|
|
66
|
+
import React3, { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
67
|
+
import { debounce } from "@dxos/async";
|
|
68
|
+
import { FormatEnum as FormatEnum2, TypeEnum } from "@dxos/echo/internal";
|
|
301
69
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
302
|
-
import {
|
|
303
|
-
import { createMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
304
|
-
import { cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext4, GridCellEditor } from "@dxos/react-ui-grid";
|
|
305
|
-
import { tagPicker, createLinks } from "@dxos/react-ui-tag-picker";
|
|
70
|
+
import { GridCellEditor, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
|
|
306
71
|
|
|
307
72
|
// src/components/TableCellEditor/CellValidationMessage.tsx
|
|
308
|
-
import { useSignals as
|
|
309
|
-
import
|
|
310
|
-
import { useGridContext
|
|
73
|
+
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
74
|
+
import React from "react";
|
|
75
|
+
import { useGridContext } from "@dxos/react-ui-grid";
|
|
311
76
|
var CellValidationMessage = ({ validationError, variant = "error", __gridScope }) => {
|
|
312
|
-
var _effect =
|
|
77
|
+
var _effect = _useSignals();
|
|
313
78
|
try {
|
|
314
|
-
const { editing, editBox: box } =
|
|
79
|
+
const { editing, editBox: box } = useGridContext("GridSheetCellEditor", __gridScope);
|
|
315
80
|
if (!editing || !validationError) {
|
|
316
81
|
return null;
|
|
317
82
|
}
|
|
318
83
|
const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
|
|
319
84
|
const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
|
|
320
|
-
return /* @__PURE__ */
|
|
85
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
321
86
|
role: "none",
|
|
322
87
|
className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
|
|
323
88
|
style: {
|
|
@@ -336,71 +101,108 @@ var CellValidationMessage = ({ validationError, variant = "error", __gridScope }
|
|
|
336
101
|
};
|
|
337
102
|
|
|
338
103
|
// src/components/TableCellEditor/FormCellEditor.tsx
|
|
339
|
-
import { useSignals as
|
|
340
|
-
import
|
|
341
|
-
import {
|
|
104
|
+
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
105
|
+
import * as Schema from "effect/Schema";
|
|
106
|
+
import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
107
|
+
import { Filter, Obj } from "@dxos/echo";
|
|
108
|
+
import { FormatEnum, Ref, getValue } from "@dxos/echo/internal";
|
|
342
109
|
import { invariant } from "@dxos/invariant";
|
|
343
|
-
import {
|
|
344
|
-
import {
|
|
345
|
-
import {
|
|
346
|
-
import {
|
|
110
|
+
import { getSnapshot } from "@dxos/live-object";
|
|
111
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
112
|
+
import { Popover } from "@dxos/react-ui";
|
|
113
|
+
import { Form } from "@dxos/react-ui-form";
|
|
114
|
+
import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
|
|
115
|
+
import { getDeep, isTruthy, setDeep } from "@dxos/util";
|
|
347
116
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
|
|
348
|
-
var
|
|
349
|
-
|
|
117
|
+
var createOptionLabel = [
|
|
118
|
+
"create new object label",
|
|
119
|
+
{
|
|
120
|
+
ns: translationKey
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, onCreate, __gridScope, ...formProps }) => {
|
|
124
|
+
var _effect = _useSignals2();
|
|
350
125
|
try {
|
|
351
|
-
const { editing: contextEditing, setEditing } =
|
|
352
|
-
const [editing, setLocalEditing] =
|
|
126
|
+
const { editing: contextEditing, setEditing, id: gridId } = useGridContext2("ArrayEditor", __gridScope);
|
|
127
|
+
const [editing, setLocalEditing] = useState(false);
|
|
353
128
|
const anchorRef = useRef(null);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
129
|
+
const getSchema = useCallback((typeAnnotation) => {
|
|
130
|
+
const space = getSpace(model.view);
|
|
131
|
+
invariant(space, void 0, {
|
|
132
|
+
F: __dxlog_file,
|
|
133
|
+
L: 57,
|
|
134
|
+
S: void 0,
|
|
135
|
+
A: [
|
|
136
|
+
"space",
|
|
137
|
+
""
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
let schema2;
|
|
141
|
+
if (client) {
|
|
142
|
+
schema2 = client.graph.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
143
|
+
}
|
|
144
|
+
if (!schema2) {
|
|
145
|
+
schema2 = space.db.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
361
146
|
}
|
|
147
|
+
return {
|
|
148
|
+
space,
|
|
149
|
+
schema: schema2
|
|
150
|
+
};
|
|
362
151
|
}, [
|
|
363
|
-
|
|
152
|
+
client,
|
|
153
|
+
model
|
|
364
154
|
]);
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
155
|
+
const handleQueryRefOptions = useCallback(async (typeAnnotation) => {
|
|
156
|
+
const { schema: schema2, space } = getSchema(typeAnnotation);
|
|
157
|
+
if (model && schema2 && space) {
|
|
158
|
+
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
159
|
+
return objects.map((obj) => {
|
|
160
|
+
return {
|
|
161
|
+
dxn: Obj.getDXN(obj),
|
|
162
|
+
label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
|
|
163
|
+
};
|
|
164
|
+
}).filter(isTruthy);
|
|
368
165
|
}
|
|
369
|
-
return
|
|
370
|
-
fieldProjection.field.path
|
|
371
|
-
]);
|
|
166
|
+
return [];
|
|
372
167
|
}, [
|
|
373
|
-
|
|
374
|
-
|
|
168
|
+
client,
|
|
169
|
+
model
|
|
375
170
|
]);
|
|
376
|
-
const originalRow =
|
|
171
|
+
const originalRow = useMemo(() => {
|
|
377
172
|
if (model && contextEditing) {
|
|
378
173
|
const cell = parseCellIndex(contextEditing.index);
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
174
|
+
if (model.isDraftCell(cell)) {
|
|
175
|
+
const draftRow = model.draftRows.value[cell.row];
|
|
176
|
+
invariant(draftRow, void 0, {
|
|
177
|
+
F: __dxlog_file,
|
|
178
|
+
L: 98,
|
|
179
|
+
S: void 0,
|
|
180
|
+
A: [
|
|
181
|
+
"draftRow",
|
|
182
|
+
""
|
|
183
|
+
]
|
|
184
|
+
});
|
|
185
|
+
return draftRow.data;
|
|
186
|
+
} else {
|
|
187
|
+
const row = model.getRowAt(cell.row);
|
|
188
|
+
invariant(row, void 0, {
|
|
189
|
+
F: __dxlog_file,
|
|
190
|
+
L: 102,
|
|
191
|
+
S: void 0,
|
|
192
|
+
A: [
|
|
193
|
+
"row",
|
|
194
|
+
""
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
return row;
|
|
198
|
+
}
|
|
390
199
|
}
|
|
391
200
|
return void 0;
|
|
392
201
|
}, [
|
|
393
202
|
model,
|
|
394
203
|
contextEditing
|
|
395
204
|
]);
|
|
396
|
-
const
|
|
397
|
-
if (originalRow) {
|
|
398
|
-
return getSnapshot(originalRow);
|
|
399
|
-
}
|
|
400
|
-
}, [
|
|
401
|
-
originalRow
|
|
402
|
-
]);
|
|
403
|
-
const handleSave = useCallback3((values) => {
|
|
205
|
+
const handleSave = useCallback((values) => {
|
|
404
206
|
const path = fieldProjection.field.path;
|
|
405
207
|
const value = getDeep(values, [
|
|
406
208
|
path
|
|
@@ -408,93 +210,128 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
408
210
|
setDeep(originalRow, [
|
|
409
211
|
path
|
|
410
212
|
], value);
|
|
213
|
+
contextEditing?.cellElement?.focus();
|
|
411
214
|
setEditing(null);
|
|
412
215
|
setLocalEditing(false);
|
|
413
216
|
onSave?.();
|
|
414
217
|
}, [
|
|
415
218
|
fieldProjection.field.path,
|
|
219
|
+
onSave,
|
|
220
|
+
contextEditing,
|
|
221
|
+
originalRow
|
|
222
|
+
]);
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
if (contextEditing && contextEditing.cellElement) {
|
|
225
|
+
anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
|
|
226
|
+
setLocalEditing(true);
|
|
227
|
+
} else {
|
|
228
|
+
anchorRef.current = null;
|
|
229
|
+
setLocalEditing(false);
|
|
230
|
+
}
|
|
231
|
+
}, [
|
|
232
|
+
contextEditing
|
|
233
|
+
]);
|
|
234
|
+
const narrowedSchema = useMemo(() => {
|
|
235
|
+
if (!schema) {
|
|
236
|
+
return void 0;
|
|
237
|
+
}
|
|
238
|
+
return narrowSchema(schema, [
|
|
239
|
+
fieldProjection.field.path
|
|
240
|
+
]);
|
|
241
|
+
}, [
|
|
242
|
+
JSON.stringify(schema),
|
|
243
|
+
fieldProjection.field.path
|
|
244
|
+
]);
|
|
245
|
+
const formValues = useMemo(() => originalRow ? getSnapshot(originalRow) : {}, [
|
|
416
246
|
originalRow
|
|
417
247
|
]);
|
|
418
|
-
const handleOpenChange =
|
|
248
|
+
const handleOpenChange = useCallback((nextOpen) => {
|
|
419
249
|
if (nextOpen === false) {
|
|
420
250
|
setEditing(null);
|
|
421
251
|
onSave?.();
|
|
422
252
|
}
|
|
423
253
|
setLocalEditing(nextOpen);
|
|
424
254
|
}, []);
|
|
255
|
+
const refSchema = useMemo(() => {
|
|
256
|
+
if (fieldProjection.props.format === FormatEnum.Ref && fieldProjection.props.referenceSchema) {
|
|
257
|
+
const { schema: refSchema2 } = getSchema({
|
|
258
|
+
typename: fieldProjection.props.referenceSchema
|
|
259
|
+
});
|
|
260
|
+
return refSchema2;
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}, [
|
|
264
|
+
fieldProjection.props.format,
|
|
265
|
+
fieldProjection.props.referenceSchema,
|
|
266
|
+
getSchema
|
|
267
|
+
]);
|
|
268
|
+
const createSchema = useMemo(() => {
|
|
269
|
+
return refSchema ? Schema.omit("id")(refSchema) : null;
|
|
270
|
+
}, [
|
|
271
|
+
refSchema
|
|
272
|
+
]);
|
|
273
|
+
const handleCreate = useCallback((values) => {
|
|
274
|
+
if (refSchema && onCreate) {
|
|
275
|
+
const objectWithId = onCreate(refSchema, values);
|
|
276
|
+
if (objectWithId) {
|
|
277
|
+
const ref = Ref.make(objectWithId);
|
|
278
|
+
const path = fieldProjection.field.path;
|
|
279
|
+
setDeep(originalRow, [
|
|
280
|
+
path
|
|
281
|
+
], ref);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
contextEditing?.cellElement?.focus();
|
|
285
|
+
setEditing(null);
|
|
286
|
+
setLocalEditing(false);
|
|
287
|
+
onSave?.();
|
|
288
|
+
}, [
|
|
289
|
+
fieldProjection.field.path,
|
|
290
|
+
onSave,
|
|
291
|
+
contextEditing,
|
|
292
|
+
originalRow,
|
|
293
|
+
refSchema,
|
|
294
|
+
onCreate
|
|
295
|
+
]);
|
|
425
296
|
if (!editing) {
|
|
426
297
|
return null;
|
|
427
298
|
}
|
|
428
|
-
return /* @__PURE__ */
|
|
299
|
+
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
429
300
|
open: editing,
|
|
430
301
|
onOpenChange: handleOpenChange
|
|
431
|
-
}, /* @__PURE__ */
|
|
302
|
+
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
432
303
|
virtualRef: anchorRef
|
|
433
|
-
}), /* @__PURE__ */
|
|
304
|
+
}), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
434
305
|
tabIndex: -1,
|
|
435
306
|
classNames: "popover-card-width density-fine"
|
|
436
|
-
}, /* @__PURE__ */
|
|
307
|
+
}, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form, {
|
|
308
|
+
autoFocus: true,
|
|
437
309
|
values: formValues,
|
|
438
310
|
schema: narrowedSchema,
|
|
439
|
-
onSave: handleSave
|
|
440
|
-
|
|
311
|
+
onSave: handleSave,
|
|
312
|
+
...formProps,
|
|
313
|
+
onQueryRefOptions: handleQueryRefOptions,
|
|
314
|
+
...createSchema && {
|
|
315
|
+
onCreate: handleCreate,
|
|
316
|
+
createSchema,
|
|
317
|
+
createInitialValuePath: fieldProjection.field.referencePath,
|
|
318
|
+
createOptionIcon: "ph--plus--regular",
|
|
319
|
+
createOptionLabel
|
|
320
|
+
}
|
|
321
|
+
})))));
|
|
441
322
|
} finally {
|
|
442
323
|
_effect.f();
|
|
443
324
|
}
|
|
444
325
|
};
|
|
445
326
|
|
|
446
|
-
// src/components/TableCellEditor/extension.ts
|
|
447
|
-
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
|
|
448
|
-
import { EditorView } from "@codemirror/view";
|
|
449
|
-
var completion = ({ debug, onQuery, onMatch }) => {
|
|
450
|
-
return [
|
|
451
|
-
EditorView.theme({
|
|
452
|
-
".cm-completionDialog": {
|
|
453
|
-
width: "var(--dx-gridCellWidth)"
|
|
454
|
-
}
|
|
455
|
-
}),
|
|
456
|
-
autocompletion({
|
|
457
|
-
icons: false,
|
|
458
|
-
activateOnTyping: true,
|
|
459
|
-
closeOnBlur: !debug,
|
|
460
|
-
override: [
|
|
461
|
-
async (context) => {
|
|
462
|
-
const text = context.state.doc.toString();
|
|
463
|
-
return {
|
|
464
|
-
from: 0,
|
|
465
|
-
options: await onQuery(text)
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
],
|
|
469
|
-
// TODO(burdon): Consts from grid (to line-up with grid).
|
|
470
|
-
tooltipClass: () => "cm-completionDialog !mt-[8px] !-ml-[4px] [&>ul]:!max-h-[264px]",
|
|
471
|
-
optionClass: () => "flex h-[33px] items-center"
|
|
472
|
-
}),
|
|
473
|
-
// Check for accepted completion metadata in the transaction.
|
|
474
|
-
EditorView.updateListener.of((update) => {
|
|
475
|
-
update.transactions.forEach((tr) => {
|
|
476
|
-
const completion2 = tr.annotation(pickedCompletion);
|
|
477
|
-
if (completion2) {
|
|
478
|
-
onMatch(completion2.data);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
})
|
|
482
|
-
];
|
|
483
|
-
};
|
|
484
|
-
|
|
485
327
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
486
328
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
487
|
-
var
|
|
488
|
-
var
|
|
489
|
-
|
|
490
|
-
text
|
|
491
|
-
});
|
|
492
|
-
var isCreateOption = (data) => typeof data === "object" && data[newValue];
|
|
493
|
-
var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQuery, __gridScope }) => {
|
|
494
|
-
var _effect = _useSignals7();
|
|
329
|
+
var adaptValidationMessage = (message) => message ? message.endsWith("is missing") ? "Can\u2019t be blank" : message : null;
|
|
330
|
+
var TableValueEditor = ({ model, modals, schema, onFocus, onSave, onCreate, client, __gridScope }) => {
|
|
331
|
+
var _effect = _useSignals3();
|
|
495
332
|
try {
|
|
496
|
-
const { editing } =
|
|
497
|
-
const fieldProjection =
|
|
333
|
+
const { editing } = useGridContext3("TableValueEditor", __gridScope);
|
|
334
|
+
const fieldProjection = useMemo2(() => {
|
|
498
335
|
if (!model || !editing) {
|
|
499
336
|
return;
|
|
500
337
|
}
|
|
@@ -503,7 +340,7 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
503
340
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
504
341
|
invariant2(fieldProjection2, void 0, {
|
|
505
342
|
F: __dxlog_file2,
|
|
506
|
-
L:
|
|
343
|
+
L: 71,
|
|
507
344
|
S: void 0,
|
|
508
345
|
A: [
|
|
509
346
|
"fieldProjection",
|
|
@@ -515,21 +352,22 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
515
352
|
model,
|
|
516
353
|
editing
|
|
517
354
|
]);
|
|
518
|
-
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format ===
|
|
519
|
-
return /* @__PURE__ */
|
|
355
|
+
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum2.SingleSelect || fieldProjection?.props.format === FormatEnum2.Ref) {
|
|
356
|
+
return /* @__PURE__ */ React3.createElement(FormCellEditor, {
|
|
520
357
|
fieldProjection,
|
|
521
358
|
model,
|
|
522
359
|
schema,
|
|
523
360
|
__gridScope,
|
|
524
|
-
onSave
|
|
361
|
+
onSave,
|
|
362
|
+
onCreate,
|
|
363
|
+
client,
|
|
364
|
+
modals
|
|
525
365
|
});
|
|
526
366
|
}
|
|
527
|
-
return /* @__PURE__ */
|
|
367
|
+
return /* @__PURE__ */ React3.createElement(TableCellEditor, {
|
|
528
368
|
model,
|
|
529
369
|
modals,
|
|
530
|
-
onEnter,
|
|
531
370
|
onFocus,
|
|
532
|
-
onQuery,
|
|
533
371
|
onSave,
|
|
534
372
|
__gridScope
|
|
535
373
|
});
|
|
@@ -538,19 +376,18 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
538
376
|
}
|
|
539
377
|
};
|
|
540
378
|
var editorSlots = {
|
|
541
|
-
|
|
379
|
+
scroll: {
|
|
542
380
|
className: "!plb-[--dx-grid-cell-editor-padding-block]"
|
|
543
381
|
}
|
|
544
382
|
};
|
|
545
|
-
var TableCellEditor = ({ model, modals,
|
|
546
|
-
var _effect =
|
|
383
|
+
var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
|
|
384
|
+
var _effect = _useSignals3();
|
|
547
385
|
try {
|
|
548
|
-
const {
|
|
386
|
+
const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
|
|
549
387
|
const suppressNextBlur = useRef2(false);
|
|
550
|
-
const
|
|
551
|
-
const [
|
|
552
|
-
const
|
|
553
|
-
const fieldProjection = useMemo4(() => {
|
|
388
|
+
const [validationError, setValidationError] = useState2(null);
|
|
389
|
+
const [validationVariant, setValidationVariant] = useState2("error");
|
|
390
|
+
const fieldProjection = useMemo2(() => {
|
|
554
391
|
if (!model || !editing) {
|
|
555
392
|
return;
|
|
556
393
|
}
|
|
@@ -559,7 +396,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
559
396
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
560
397
|
invariant2(fieldProjection2, void 0, {
|
|
561
398
|
F: __dxlog_file2,
|
|
562
|
-
L:
|
|
399
|
+
L: 121,
|
|
563
400
|
S: void 0,
|
|
564
401
|
A: [
|
|
565
402
|
"fieldProjection",
|
|
@@ -569,40 +406,9 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
569
406
|
return fieldProjection2;
|
|
570
407
|
}, [
|
|
571
408
|
model,
|
|
572
|
-
editing
|
|
573
|
-
]);
|
|
574
|
-
useEffect3(() => {
|
|
575
|
-
if (!model || !editing || !fieldProjection) {
|
|
576
|
-
setValidationError(null);
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
const cell = parseCellIndex2(editing.index);
|
|
580
|
-
const { row, col } = cell;
|
|
581
|
-
if (model.isDraftCell(cell)) {
|
|
582
|
-
const field = model.projection.fields[col];
|
|
583
|
-
const hasValidationError = model.hasDraftRowValidationError(row, field.path);
|
|
584
|
-
if (hasValidationError) {
|
|
585
|
-
const draftRows = model.draftRows.value;
|
|
586
|
-
if (row >= 0 && row < draftRows.length) {
|
|
587
|
-
const draftRow = draftRows[row];
|
|
588
|
-
const validationError = draftRow.validationErrors?.find((error) => error.path === field.path);
|
|
589
|
-
if (validationError) {
|
|
590
|
-
setValidationError(validationError.message);
|
|
591
|
-
setValidationVariant("warning");
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
} else {
|
|
595
|
-
setValidationError(null);
|
|
596
|
-
}
|
|
597
|
-
} else {
|
|
598
|
-
setValidationError(null);
|
|
599
|
-
}
|
|
600
|
-
}, [
|
|
601
|
-
model,
|
|
602
|
-
editing,
|
|
603
|
-
fieldProjection
|
|
409
|
+
editing
|
|
604
410
|
]);
|
|
605
|
-
const handleEnter =
|
|
411
|
+
const handleEnter = useCallback2(async (value) => {
|
|
606
412
|
if (!model || !editing) {
|
|
607
413
|
return;
|
|
608
414
|
}
|
|
@@ -611,33 +417,39 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
611
417
|
if (validationResult.valid) {
|
|
612
418
|
setValidationError(null);
|
|
613
419
|
model.setCellData(cell, value);
|
|
614
|
-
onEnter?.(cell);
|
|
615
420
|
onFocus?.();
|
|
616
421
|
setEditing(null);
|
|
617
422
|
onSave?.();
|
|
618
423
|
} else {
|
|
619
|
-
setValidationError(validationResult.error);
|
|
424
|
+
setValidationError(adaptValidationMessage(validationResult.error));
|
|
620
425
|
setValidationVariant("error");
|
|
621
426
|
}
|
|
622
427
|
}, [
|
|
623
428
|
model,
|
|
624
429
|
editing,
|
|
625
|
-
onEnter,
|
|
626
430
|
onFocus,
|
|
627
431
|
setEditing
|
|
628
432
|
]);
|
|
629
|
-
const handleBlur =
|
|
630
|
-
if (!model || !editing) {
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
433
|
+
const handleBlur = useCallback2(async (value) => {
|
|
633
434
|
if (suppressNextBlur.current) {
|
|
634
435
|
suppressNextBlur.current = false;
|
|
436
|
+
} else if (model && editing) {
|
|
437
|
+
const cell = parseCellIndex2(editing.index);
|
|
438
|
+
if (value !== void 0) {
|
|
439
|
+
const result = await model.validateCellData(cell, value);
|
|
440
|
+
if (result.valid) {
|
|
441
|
+
setValidationError(null);
|
|
442
|
+
model.setCellData(cell, value);
|
|
443
|
+
setEditing(null);
|
|
444
|
+
onSave?.();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
635
447
|
}
|
|
636
448
|
}, [
|
|
637
449
|
model,
|
|
638
450
|
editing
|
|
639
451
|
]);
|
|
640
|
-
const handleClose =
|
|
452
|
+
const handleClose = useCallback2(async (value, event) => {
|
|
641
453
|
if (!model || !editing || !fieldProjection) {
|
|
642
454
|
return;
|
|
643
455
|
}
|
|
@@ -645,19 +457,20 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
645
457
|
if (value !== void 0) {
|
|
646
458
|
const result = await model.validateCellData(cell, value);
|
|
647
459
|
if (result.valid) {
|
|
460
|
+
suppressNextBlur.current = true;
|
|
648
461
|
setValidationError(null);
|
|
649
462
|
model.setCellData(cell, value);
|
|
650
463
|
setEditing(null);
|
|
651
464
|
onSave?.();
|
|
652
|
-
onEnter?.(cell);
|
|
653
465
|
if (event && onFocus) {
|
|
654
|
-
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
466
|
+
onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
|
|
655
467
|
}
|
|
656
468
|
} else {
|
|
657
469
|
setValidationError(result.error);
|
|
658
470
|
setValidationVariant("error");
|
|
659
471
|
}
|
|
660
472
|
} else {
|
|
473
|
+
suppressNextBlur.current = true;
|
|
661
474
|
setValidationError(null);
|
|
662
475
|
setEditing(null);
|
|
663
476
|
onSave?.();
|
|
@@ -669,16 +482,15 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
669
482
|
model,
|
|
670
483
|
editing,
|
|
671
484
|
onFocus,
|
|
672
|
-
onEnter,
|
|
673
485
|
fieldProjection,
|
|
674
486
|
setEditing,
|
|
675
487
|
onSave
|
|
676
488
|
]);
|
|
677
|
-
const
|
|
489
|
+
const extensions = useMemo2(() => {
|
|
678
490
|
if (!fieldProjection) {
|
|
679
491
|
return [];
|
|
680
492
|
}
|
|
681
|
-
const
|
|
493
|
+
const extensions2 = [
|
|
682
494
|
editorKeys({
|
|
683
495
|
onClose: handleClose,
|
|
684
496
|
...editing?.initialContent && {
|
|
@@ -686,114 +498,31 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
686
498
|
}
|
|
687
499
|
})
|
|
688
500
|
];
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
onSearch: (text, selectedIds) => {
|
|
700
|
-
return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
|
|
701
|
-
id: option.id,
|
|
702
|
-
label: option.title,
|
|
703
|
-
hue: option.color
|
|
704
|
-
}));
|
|
705
|
-
},
|
|
706
|
-
onUpdate: (ids) => {
|
|
707
|
-
if (model && editing) {
|
|
708
|
-
if (ids.length === 0) {
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
if (mode === "single-select") {
|
|
712
|
-
void handleEnter(ids[0]);
|
|
713
|
-
} else {
|
|
714
|
-
void handleEnter(ids);
|
|
715
|
-
}
|
|
501
|
+
if (model && editing) {
|
|
502
|
+
extensions2.push(EditorView.updateListener.of(debounce((update) => {
|
|
503
|
+
const content = update.state.doc.toString();
|
|
504
|
+
const cell = parseCellIndex2(editing.index);
|
|
505
|
+
void model.validateCellData(cell, content).then((result) => {
|
|
506
|
+
if (result.valid) {
|
|
507
|
+
setValidationError(null);
|
|
508
|
+
} else {
|
|
509
|
+
setValidationError(result.error);
|
|
510
|
+
setValidationVariant("error");
|
|
716
511
|
}
|
|
717
|
-
}
|
|
718
|
-
}));
|
|
719
|
-
}
|
|
720
|
-
if (onQuery) {
|
|
721
|
-
switch (fieldProjection.props.format) {
|
|
722
|
-
case FormatEnum.Ref: {
|
|
723
|
-
extension2.push([
|
|
724
|
-
completion({
|
|
725
|
-
onQuery: (text) => onQuery(fieldProjection, text),
|
|
726
|
-
onMatch: (data) => {
|
|
727
|
-
if (model && editing && modals) {
|
|
728
|
-
if (isCreateOption(data)) {
|
|
729
|
-
const { field, props } = fieldProjection;
|
|
730
|
-
if (props.referenceSchema) {
|
|
731
|
-
suppressNextBlur.current = true;
|
|
732
|
-
modals.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
|
|
733
|
-
[field.referencePath]: data.text
|
|
734
|
-
}, (data2) => {
|
|
735
|
-
void handleEnter(data2);
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
} else {
|
|
739
|
-
void handleEnter(data);
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
})
|
|
744
|
-
]);
|
|
745
|
-
break;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
512
|
+
});
|
|
513
|
+
}, 10)));
|
|
748
514
|
}
|
|
749
|
-
return
|
|
515
|
+
return extensions2;
|
|
750
516
|
}, [
|
|
751
517
|
model,
|
|
752
518
|
modals,
|
|
753
519
|
editing,
|
|
754
520
|
fieldProjection,
|
|
755
|
-
handleClose
|
|
756
|
-
themeMode
|
|
521
|
+
handleClose
|
|
757
522
|
]);
|
|
758
|
-
const getCellContent =
|
|
523
|
+
const getCellContent = useCallback2(() => {
|
|
759
524
|
if (model && editing) {
|
|
760
525
|
const cell = parseCellIndex2(editing.index);
|
|
761
|
-
const { col } = cell;
|
|
762
|
-
const field = model.projection.fields[col];
|
|
763
|
-
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
764
|
-
if (fieldProjection2?.props.format === FormatEnum.SingleSelect || fieldProjection2?.props.format === FormatEnum.MultiSelect) {
|
|
765
|
-
const value2 = model.getCellData(cell);
|
|
766
|
-
if (value2 !== void 0) {
|
|
767
|
-
const options = fieldProjection2.props.options || [];
|
|
768
|
-
if (fieldProjection2.props.format === FormatEnum.MultiSelect) {
|
|
769
|
-
const tagItems = value2.split(",").map((id) => {
|
|
770
|
-
const option = options.find((o) => o.id === id);
|
|
771
|
-
if (option) {
|
|
772
|
-
return {
|
|
773
|
-
id,
|
|
774
|
-
label: option.title,
|
|
775
|
-
hue: option.color
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
return void 0;
|
|
779
|
-
}).filter((item) => item !== void 0);
|
|
780
|
-
return createLinks(tagItems);
|
|
781
|
-
} else {
|
|
782
|
-
const option = options.find((o) => o.id === value2);
|
|
783
|
-
if (option) {
|
|
784
|
-
const tagItem = {
|
|
785
|
-
id: value2,
|
|
786
|
-
label: option.title,
|
|
787
|
-
hue: option.color
|
|
788
|
-
};
|
|
789
|
-
return createLinks([
|
|
790
|
-
tagItem
|
|
791
|
-
]);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
return "";
|
|
796
|
-
}
|
|
797
526
|
const value = model.getCellData(cell);
|
|
798
527
|
return value !== void 0 ? String(value) : "";
|
|
799
528
|
}
|
|
@@ -801,12 +530,12 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
801
530
|
model,
|
|
802
531
|
editing
|
|
803
532
|
]);
|
|
804
|
-
return /* @__PURE__ */
|
|
805
|
-
validationError
|
|
806
|
-
variant:
|
|
533
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
|
|
534
|
+
validationError,
|
|
535
|
+
variant: validationVariant,
|
|
807
536
|
__gridScope
|
|
808
|
-
}), /* @__PURE__ */
|
|
809
|
-
|
|
537
|
+
}), /* @__PURE__ */ React3.createElement(GridCellEditor, {
|
|
538
|
+
extensions,
|
|
810
539
|
getCellContent,
|
|
811
540
|
onBlur: handleBlur,
|
|
812
541
|
slots: editorSlots
|
|
@@ -840,12 +569,171 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
840
569
|
return shift ? -1 : 1;
|
|
841
570
|
};
|
|
842
571
|
|
|
572
|
+
// src/components/Table/ColumnActionsMenu.tsx
|
|
573
|
+
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
574
|
+
import React4 from "react";
|
|
575
|
+
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
576
|
+
var ColumnActionsMenu = ({ model, modals }) => {
|
|
577
|
+
var _effect = _useSignals4();
|
|
578
|
+
try {
|
|
579
|
+
const { t } = useTranslation(translationKey);
|
|
580
|
+
const state = modals.state.value;
|
|
581
|
+
if (state?.type !== "column") {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
const currentSort = model.sorting?.sorting;
|
|
585
|
+
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
586
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
|
|
587
|
+
modal: false,
|
|
588
|
+
open: true,
|
|
589
|
+
onOpenChange: modals.close
|
|
590
|
+
}, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
|
|
591
|
+
virtualRef: modals.trigger
|
|
592
|
+
}), /* @__PURE__ */ React4.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
593
|
+
"data-testid": "column-sort-descending",
|
|
594
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
595
|
+
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
596
|
+
"data-testid": "column-sort-ascending",
|
|
597
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
598
|
+
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
599
|
+
"data-testid": "column-clear-sort",
|
|
600
|
+
onClick: () => model.sorting?.clearSort()
|
|
601
|
+
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
602
|
+
"data-testid": "column-delete",
|
|
603
|
+
onClick: () => model.deleteColumn(state.fieldId)
|
|
604
|
+
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
605
|
+
"data-testid": "column-settings",
|
|
606
|
+
onClick: () => modals.openColumnSettings()
|
|
607
|
+
}, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
|
|
608
|
+
} finally {
|
|
609
|
+
_effect.f();
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// src/components/Table/ColumnSettings.tsx
|
|
614
|
+
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
615
|
+
import React5, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useState as useState3 } from "react";
|
|
616
|
+
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
617
|
+
import { FieldEditor } from "@dxos/react-ui-form";
|
|
618
|
+
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
619
|
+
var _effect = _useSignals5();
|
|
620
|
+
try {
|
|
621
|
+
const [newField, setNewField] = useState3();
|
|
622
|
+
const state = modals.state.value;
|
|
623
|
+
useEffect2(() => {
|
|
624
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
625
|
+
setNewField(model.projection.createFieldProjection());
|
|
626
|
+
requestAnimationFrame(() => {
|
|
627
|
+
onNewColumn();
|
|
628
|
+
});
|
|
629
|
+
} else {
|
|
630
|
+
setNewField(void 0);
|
|
631
|
+
}
|
|
632
|
+
}, [
|
|
633
|
+
model?.projection,
|
|
634
|
+
state
|
|
635
|
+
]);
|
|
636
|
+
const existingField = useMemo3(() => {
|
|
637
|
+
if (state?.type === "columnSettings") {
|
|
638
|
+
const { mode } = state;
|
|
639
|
+
if (mode.type === "edit") {
|
|
640
|
+
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return void 0;
|
|
644
|
+
}, [
|
|
645
|
+
model?.projection?.fields,
|
|
646
|
+
state
|
|
647
|
+
]);
|
|
648
|
+
const field = existingField ?? newField;
|
|
649
|
+
const handleSave = useCallback3(() => {
|
|
650
|
+
modals.close();
|
|
651
|
+
}, [
|
|
652
|
+
modals
|
|
653
|
+
]);
|
|
654
|
+
const handleCancel = useCallback3(() => {
|
|
655
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
656
|
+
model?.projection.deleteFieldProjection(newField.id);
|
|
657
|
+
}
|
|
658
|
+
}, [
|
|
659
|
+
model?.projection,
|
|
660
|
+
state,
|
|
661
|
+
newField
|
|
662
|
+
]);
|
|
663
|
+
if (!model?.projection || !field) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
return /* @__PURE__ */ React5.createElement(Popover2.Root, {
|
|
667
|
+
modal: false,
|
|
668
|
+
open: state?.type === "columnSettings"
|
|
669
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
|
|
670
|
+
virtualRef: modals.trigger
|
|
671
|
+
}), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
|
|
672
|
+
classNames: "md:is-64"
|
|
673
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
|
|
674
|
+
projection: model.projection,
|
|
675
|
+
field,
|
|
676
|
+
registry,
|
|
677
|
+
onSave: handleSave,
|
|
678
|
+
onCancel: handleCancel
|
|
679
|
+
})), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
|
|
680
|
+
} finally {
|
|
681
|
+
_effect.f();
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/components/Table/RowActionsMenu.tsx
|
|
686
|
+
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
687
|
+
import React6 from "react";
|
|
688
|
+
import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
689
|
+
var RowActionsMenu = ({ model, modals }) => {
|
|
690
|
+
var _effect = _useSignals6();
|
|
691
|
+
try {
|
|
692
|
+
const { t } = useTranslation2(translationKey);
|
|
693
|
+
const hasSelection = model.selection.hasSelection.value;
|
|
694
|
+
const state = modals.state.value;
|
|
695
|
+
if (state?.type !== "row") {
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
return /* @__PURE__ */ React6.createElement(DropdownMenu2.Root, {
|
|
699
|
+
modal: false,
|
|
700
|
+
open: true,
|
|
701
|
+
onOpenChange: modals.close
|
|
702
|
+
}, /* @__PURE__ */ React6.createElement(DropdownMenu2.VirtualTrigger, {
|
|
703
|
+
virtualRef: modals.trigger
|
|
704
|
+
}), /* @__PURE__ */ React6.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Viewport, null, model.rowActions?.length > 0 && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Group, null, model.rowActions?.map((action) => /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
|
|
705
|
+
key: action.id,
|
|
706
|
+
"data-testid": `row-action-${action.id}`,
|
|
707
|
+
onClick: () => {
|
|
708
|
+
modals.close();
|
|
709
|
+
model.handleRowAction(action.id, state.rowIndex);
|
|
710
|
+
}
|
|
711
|
+
}, toLocalizedString(action.label, t)))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Separator, null)), model.features.dataEditable !== false && /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
|
|
712
|
+
"data-testid": "row-menu-delete",
|
|
713
|
+
onClick: () => model.deleteRow(state.rowIndex)
|
|
714
|
+
}, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Arrow, null)));
|
|
715
|
+
} finally {
|
|
716
|
+
_effect.f();
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
|
|
843
720
|
// src/components/Table/Table.tsx
|
|
844
|
-
var
|
|
721
|
+
var columnDefault = {
|
|
722
|
+
grid: {
|
|
723
|
+
minSize: 80,
|
|
724
|
+
maxSize: 640
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
var rowDefault = {
|
|
728
|
+
frozenRowsStart: {
|
|
729
|
+
readonly: true,
|
|
730
|
+
focusUnfurl: false
|
|
731
|
+
}
|
|
732
|
+
};
|
|
845
733
|
var TableRoot = ({ children, role = "article" }) => {
|
|
846
|
-
var _effect =
|
|
734
|
+
var _effect = _useSignals7();
|
|
847
735
|
try {
|
|
848
|
-
return /* @__PURE__ */
|
|
736
|
+
return /* @__PURE__ */ React7.createElement("div", {
|
|
849
737
|
role: "none",
|
|
850
738
|
className: mx("relative !border-separator [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]", role === "card--popover" && "popover-card-height", role === "section" && "attention-surface", role === "card--intrinsic" && "[&_.dx-grid]:bs-[--dx-grid-content-block-size]", [
|
|
851
739
|
"card--popover",
|
|
@@ -860,19 +748,24 @@ var TableRoot = ({ children, role = "article" }) => {
|
|
|
860
748
|
_effect.f();
|
|
861
749
|
}
|
|
862
750
|
};
|
|
863
|
-
var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onRowClick }, forwardedRef) => {
|
|
864
|
-
var _effect =
|
|
751
|
+
var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onCreate, onRowClick, testId }, forwardedRef) => {
|
|
752
|
+
var _effect = _useSignals7();
|
|
865
753
|
try {
|
|
866
754
|
const [dxGrid, setDxGrid] = useState4(null);
|
|
867
755
|
const { hasAttention } = useAttention(model?.id ?? "table");
|
|
868
|
-
const
|
|
869
|
-
const modals = useMemo5(() => new ModalController(), []);
|
|
756
|
+
const modals = useMemo4(() => new ModalController(), []);
|
|
870
757
|
const draftRowCount = model?.getDraftRowCount() ?? 0;
|
|
871
|
-
const
|
|
758
|
+
const handleSave = useCallback4(() => {
|
|
759
|
+
dxGrid?.updateCells(true);
|
|
760
|
+
dxGrid?.requestUpdate();
|
|
761
|
+
}, [
|
|
762
|
+
dxGrid
|
|
763
|
+
]);
|
|
764
|
+
const frozen = useMemo4(() => {
|
|
872
765
|
const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
|
|
873
766
|
return {
|
|
874
767
|
frozenRowsStart: 1,
|
|
875
|
-
frozenRowsEnd: draftRowCount,
|
|
768
|
+
frozenRowsEnd: Math.max(1, draftRowCount),
|
|
876
769
|
frozenColsStart: model?.features.selection.enabled ? 1 : 0,
|
|
877
770
|
frozenColsEnd: noActionColumn ? 0 : 1
|
|
878
771
|
};
|
|
@@ -880,10 +773,10 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
880
773
|
model,
|
|
881
774
|
draftRowCount
|
|
882
775
|
]);
|
|
883
|
-
const getCells =
|
|
776
|
+
const getCells = useCallback4((range, plane) => presentation?.getCells(range, plane) ?? {}, [
|
|
884
777
|
presentation
|
|
885
778
|
]);
|
|
886
|
-
|
|
779
|
+
useEffect3(() => {
|
|
887
780
|
if (!presentation || !dxGrid) {
|
|
888
781
|
return;
|
|
889
782
|
}
|
|
@@ -893,6 +786,30 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
893
786
|
dxGrid,
|
|
894
787
|
getCells
|
|
895
788
|
]);
|
|
789
|
+
const handleInsertRowResult = useCallback4((insertResult) => {
|
|
790
|
+
if (insertResult === "draft") {
|
|
791
|
+
requestAnimationFrame(() => {
|
|
792
|
+
dxGrid?.setFocus({
|
|
793
|
+
plane: "frozenRowsEnd",
|
|
794
|
+
col: 0,
|
|
795
|
+
row: 0
|
|
796
|
+
});
|
|
797
|
+
dxGrid?.refocus();
|
|
798
|
+
});
|
|
799
|
+
} else {
|
|
800
|
+
requestAnimationFrame(() => {
|
|
801
|
+
dxGrid?.setFocus({
|
|
802
|
+
plane: "grid",
|
|
803
|
+
col: 0,
|
|
804
|
+
row: model ? model.getRowCount() - 1 : 0
|
|
805
|
+
});
|
|
806
|
+
dxGrid?.refocus();
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
}, [
|
|
810
|
+
model,
|
|
811
|
+
dxGrid
|
|
812
|
+
]);
|
|
896
813
|
useImperativeHandle(forwardedRef, () => {
|
|
897
814
|
if (!presentation || !dxGrid) {
|
|
898
815
|
return {};
|
|
@@ -905,18 +822,38 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
905
822
|
dxGrid.updateCells(true);
|
|
906
823
|
dxGrid.requestUpdate();
|
|
907
824
|
}
|
|
908
|
-
}
|
|
825
|
+
},
|
|
826
|
+
handleInsertRowResult
|
|
909
827
|
};
|
|
910
828
|
}, [
|
|
911
829
|
presentation,
|
|
830
|
+
dxGrid,
|
|
831
|
+
model
|
|
832
|
+
]);
|
|
833
|
+
const handleSaveDraftRow = useCallback4((rowIndex = 0) => {
|
|
834
|
+
if (model && dxGrid) {
|
|
835
|
+
const didCommitSuccessfully = model.commitDraftRow(rowIndex);
|
|
836
|
+
if (didCommitSuccessfully) {
|
|
837
|
+
requestAnimationFrame(() => {
|
|
838
|
+
dxGrid.scrollToEndRow();
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}, [
|
|
843
|
+
model,
|
|
912
844
|
dxGrid
|
|
913
845
|
]);
|
|
914
|
-
const handleGridClick =
|
|
915
|
-
const
|
|
916
|
-
if (
|
|
846
|
+
const handleGridClick = useCallback4((event) => {
|
|
847
|
+
const cell = closestCell(event.target);
|
|
848
|
+
if (cell) {
|
|
849
|
+
const { row: rowIndex, plane } = cell;
|
|
917
850
|
if (onRowClick) {
|
|
918
|
-
|
|
919
|
-
|
|
851
|
+
if (plane === "grid") {
|
|
852
|
+
const row = model?.getRowAt(rowIndex);
|
|
853
|
+
row && onRowClick(row);
|
|
854
|
+
} else {
|
|
855
|
+
onRowClick(cell);
|
|
856
|
+
}
|
|
920
857
|
}
|
|
921
858
|
if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
|
|
922
859
|
model.selection.toggleSelectionForRowIndex(rowIndex);
|
|
@@ -952,14 +889,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
952
889
|
break;
|
|
953
890
|
}
|
|
954
891
|
case "saveDraftRow": {
|
|
955
|
-
|
|
956
|
-
const didCommitSuccessfully = model.commitDraftRow(data.rowIndex);
|
|
957
|
-
if (dxGrid && didCommitSuccessfully) {
|
|
958
|
-
requestAnimationFrame(() => {
|
|
959
|
-
dxGrid.scrollToEndRow();
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
}
|
|
892
|
+
handleSaveDraftRow();
|
|
963
893
|
break;
|
|
964
894
|
}
|
|
965
895
|
}
|
|
@@ -998,31 +928,22 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
998
928
|
modals,
|
|
999
929
|
dxGrid
|
|
1000
930
|
]);
|
|
1001
|
-
const handleFocus =
|
|
1002
|
-
if (dxGrid) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
return;
|
|
1011
|
-
}
|
|
1012
|
-
if (model && cell.row === model.getRowCount() - 1) {
|
|
1013
|
-
model.insertRow();
|
|
1014
|
-
if (dxGrid) {
|
|
1015
|
-
requestAnimationFrame(() => {
|
|
1016
|
-
dxGrid?.scrollToRow(cell.row + 1);
|
|
1017
|
-
dxGrid?.refocus("row", 1);
|
|
1018
|
-
});
|
|
931
|
+
const handleFocus = useCallback4((increment, delta, cell) => {
|
|
932
|
+
if (dxGrid && model) {
|
|
933
|
+
if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1 && increment !== "col") {
|
|
934
|
+
handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
|
|
935
|
+
} else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
|
|
936
|
+
handleSaveDraftRow(cell.row);
|
|
937
|
+
handleInsertRowResult(model.insertRow());
|
|
938
|
+
} else {
|
|
939
|
+
dxGrid.refocus(increment, delta);
|
|
1019
940
|
}
|
|
1020
941
|
}
|
|
1021
942
|
}, [
|
|
1022
|
-
|
|
1023
|
-
|
|
943
|
+
dxGrid,
|
|
944
|
+
model
|
|
1024
945
|
]);
|
|
1025
|
-
const handleKeyDown =
|
|
946
|
+
const handleKeyDown = useCallback4((event) => {
|
|
1026
947
|
if (!model?.features.dataEditable) {
|
|
1027
948
|
return;
|
|
1028
949
|
}
|
|
@@ -1030,21 +951,66 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1030
951
|
if (!model || !cell) {
|
|
1031
952
|
return;
|
|
1032
953
|
}
|
|
954
|
+
if (event.metaKey || event.ctrlKey) {
|
|
955
|
+
switch (event.key) {
|
|
956
|
+
case "c": {
|
|
957
|
+
try {
|
|
958
|
+
const cellData = model.getCellData(cell);
|
|
959
|
+
const textContent = cellData?.toString() ?? "";
|
|
960
|
+
void navigator.clipboard.writeText(textContent);
|
|
961
|
+
event.preventDefault();
|
|
962
|
+
} catch (error) {
|
|
963
|
+
console.warn("Failed to copy cell content:", error);
|
|
964
|
+
}
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
case "v": {
|
|
968
|
+
event.preventDefault();
|
|
969
|
+
void navigator.clipboard.readText().then((clipboardText) => {
|
|
970
|
+
try {
|
|
971
|
+
model.setCellData(cell, String2.trim(clipboardText).replace(/[\n\r]+/, " "));
|
|
972
|
+
handleSave();
|
|
973
|
+
} catch {
|
|
974
|
+
const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
|
|
975
|
+
if (cellElement) {
|
|
976
|
+
const rect = cellElement.getBoundingClientRect();
|
|
977
|
+
const editRequest = new DxEditRequest({
|
|
978
|
+
cellIndex: `${cell.plane},${cell.col},${cell.row}`,
|
|
979
|
+
cellBox: {
|
|
980
|
+
insetInlineStart: rect.left,
|
|
981
|
+
insetBlockStart: rect.top,
|
|
982
|
+
inlineSize: rect.width,
|
|
983
|
+
blockSize: rect.height
|
|
984
|
+
},
|
|
985
|
+
cellElement,
|
|
986
|
+
initialContent: clipboardText
|
|
987
|
+
});
|
|
988
|
+
cellElement.dispatchEvent(editRequest);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
1033
996
|
switch (event.key) {
|
|
1034
997
|
case "Backspace":
|
|
1035
998
|
case "Delete": {
|
|
1036
999
|
try {
|
|
1037
1000
|
model.setCellData(cell, void 0);
|
|
1038
1001
|
event.preventDefault();
|
|
1002
|
+
handleSave();
|
|
1039
1003
|
} catch {
|
|
1040
1004
|
}
|
|
1041
1005
|
break;
|
|
1042
1006
|
}
|
|
1043
1007
|
}
|
|
1044
1008
|
}, [
|
|
1045
|
-
model
|
|
1009
|
+
model,
|
|
1010
|
+
dxGrid,
|
|
1011
|
+
handleSave
|
|
1046
1012
|
]);
|
|
1047
|
-
const handleAxisResize =
|
|
1013
|
+
const handleAxisResize = useCallback4((event) => {
|
|
1048
1014
|
if (event.axis === "col") {
|
|
1049
1015
|
const columnIndex = parseInt(event.index, 10);
|
|
1050
1016
|
model?.setColumnWidth(columnIndex, event.size);
|
|
@@ -1052,7 +1018,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1052
1018
|
}, [
|
|
1053
1019
|
model
|
|
1054
1020
|
]);
|
|
1055
|
-
const handleWheel =
|
|
1021
|
+
const handleWheel = useCallback4((event) => {
|
|
1056
1022
|
if (!ignoreAttention && !hasAttention) {
|
|
1057
1023
|
event.stopPropagation();
|
|
1058
1024
|
}
|
|
@@ -1060,7 +1026,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1060
1026
|
hasAttention,
|
|
1061
1027
|
ignoreAttention
|
|
1062
1028
|
]);
|
|
1063
|
-
const handleNewColumn =
|
|
1029
|
+
const handleNewColumn = useCallback4(() => {
|
|
1064
1030
|
const columns = model?.getColumnCount();
|
|
1065
1031
|
if (dxGrid && columns) {
|
|
1066
1032
|
dxGrid.scrollToColumn(columns - 1);
|
|
@@ -1069,79 +1035,28 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1069
1035
|
model,
|
|
1070
1036
|
dxGrid
|
|
1071
1037
|
]);
|
|
1072
|
-
const handleQuery = useCallback5(async ({ field, props }, text) => {
|
|
1073
|
-
if (model && props.referenceSchema && field.referencePath) {
|
|
1074
|
-
const space = getSpace2(model.view);
|
|
1075
|
-
invariant3(space, void 0, {
|
|
1076
|
-
F: __dxlog_file3,
|
|
1077
|
-
L: 330,
|
|
1078
|
-
S: void 0,
|
|
1079
|
-
A: [
|
|
1080
|
-
"space",
|
|
1081
|
-
""
|
|
1082
|
-
]
|
|
1083
|
-
});
|
|
1084
|
-
let schema2;
|
|
1085
|
-
if (client) {
|
|
1086
|
-
schema2 = client.graph.schemaRegistry.getSchema(props.referenceSchema);
|
|
1087
|
-
}
|
|
1088
|
-
if (!schema2) {
|
|
1089
|
-
schema2 = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
1090
|
-
}
|
|
1091
|
-
if (schema2) {
|
|
1092
|
-
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
1093
|
-
const options = objects.map((obj) => {
|
|
1094
|
-
const value = getValue(obj, field.referencePath);
|
|
1095
|
-
if (!value || typeof value !== "string") {
|
|
1096
|
-
return void 0;
|
|
1097
|
-
}
|
|
1098
|
-
return {
|
|
1099
|
-
label: value,
|
|
1100
|
-
data: obj
|
|
1101
|
-
};
|
|
1102
|
-
}).filter(isNotFalsy);
|
|
1103
|
-
return [
|
|
1104
|
-
...options,
|
|
1105
|
-
{
|
|
1106
|
-
label: t("create new object label", {
|
|
1107
|
-
text
|
|
1108
|
-
}),
|
|
1109
|
-
data: createOption(text)
|
|
1110
|
-
}
|
|
1111
|
-
];
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
return [];
|
|
1115
|
-
}, [
|
|
1116
|
-
model,
|
|
1117
|
-
client,
|
|
1118
|
-
t
|
|
1119
|
-
]);
|
|
1120
|
-
const handleSave = useCallback5(() => {
|
|
1121
|
-
dxGrid?.updateCells(true);
|
|
1122
|
-
}, [
|
|
1123
|
-
dxGrid
|
|
1124
|
-
]);
|
|
1125
1038
|
if (!model || !modals) {
|
|
1126
|
-
return /* @__PURE__ */
|
|
1039
|
+
return /* @__PURE__ */ React7.createElement("span", {
|
|
1127
1040
|
role: "none",
|
|
1128
1041
|
className: "attention-surface"
|
|
1129
1042
|
});
|
|
1130
1043
|
}
|
|
1131
|
-
return /* @__PURE__ */
|
|
1044
|
+
return /* @__PURE__ */ React7.createElement(Grid.Root, {
|
|
1132
1045
|
id: model.id ?? "table-grid"
|
|
1133
|
-
}, /* @__PURE__ */
|
|
1046
|
+
}, /* @__PURE__ */ React7.createElement(TableValueEditor, {
|
|
1134
1047
|
model,
|
|
1135
1048
|
modals,
|
|
1136
1049
|
schema,
|
|
1137
|
-
onEnter: handleEnter,
|
|
1138
1050
|
onFocus: handleFocus,
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1051
|
+
onSave: handleSave,
|
|
1052
|
+
onCreate,
|
|
1053
|
+
client
|
|
1054
|
+
}), /* @__PURE__ */ React7.createElement(Grid.Content, {
|
|
1142
1055
|
className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
|
|
1143
1056
|
frozen,
|
|
1144
1057
|
columns: model.columnMeta.value,
|
|
1058
|
+
columnDefault,
|
|
1059
|
+
rowDefault,
|
|
1145
1060
|
limitRows: model.getRowCount() ?? 0,
|
|
1146
1061
|
limitColumns: model.projection.fields.length,
|
|
1147
1062
|
overscroll: "trap",
|
|
@@ -1149,20 +1064,20 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1149
1064
|
onClick: handleGridClick,
|
|
1150
1065
|
onKeyDownCapture: handleKeyDown,
|
|
1151
1066
|
onWheelCapture: handleWheel,
|
|
1067
|
+
...testId && {
|
|
1068
|
+
"data-testid": testId
|
|
1069
|
+
},
|
|
1152
1070
|
ref: setDxGrid
|
|
1153
|
-
}), /* @__PURE__ */
|
|
1071
|
+
}), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
|
|
1154
1072
|
model,
|
|
1155
1073
|
modals
|
|
1156
|
-
}), /* @__PURE__ */
|
|
1074
|
+
}), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
|
|
1157
1075
|
model,
|
|
1158
1076
|
modals
|
|
1159
|
-
}), /* @__PURE__ */
|
|
1077
|
+
}), /* @__PURE__ */ React7.createElement(ColumnSettings, {
|
|
1160
1078
|
model,
|
|
1161
1079
|
modals,
|
|
1162
1080
|
onNewColumn: handleNewColumn
|
|
1163
|
-
}), /* @__PURE__ */ React8.createElement(CreateRefPanel, {
|
|
1164
|
-
model,
|
|
1165
|
-
modals
|
|
1166
1081
|
}));
|
|
1167
1082
|
} finally {
|
|
1168
1083
|
_effect.f();
|
|
@@ -1174,14 +1089,14 @@ var Table = {
|
|
|
1174
1089
|
};
|
|
1175
1090
|
|
|
1176
1091
|
// src/components/Table/DynamicTable.tsx
|
|
1177
|
-
import { useSignals as
|
|
1178
|
-
import
|
|
1092
|
+
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
1093
|
+
import React8, { useCallback as useCallback5, useMemo as useMemo5, useRef as useRef3 } from "react";
|
|
1179
1094
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
1180
1095
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1181
1096
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
1182
|
-
var _effect =
|
|
1097
|
+
var _effect = _useSignals8();
|
|
1183
1098
|
try {
|
|
1184
|
-
const {
|
|
1099
|
+
const { jsonSchema } = useMemo5(() => getBaseSchema({
|
|
1185
1100
|
typename: name,
|
|
1186
1101
|
properties,
|
|
1187
1102
|
jsonSchema: _jsonSchema,
|
|
@@ -1192,20 +1107,18 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1192
1107
|
_jsonSchema,
|
|
1193
1108
|
schema
|
|
1194
1109
|
]);
|
|
1195
|
-
const { projection, view } =
|
|
1196
|
-
typename,
|
|
1110
|
+
const { projection, view } = useMemo5(() => makeDynamicTable({
|
|
1197
1111
|
jsonSchema,
|
|
1198
1112
|
properties
|
|
1199
1113
|
}), [
|
|
1200
|
-
typename,
|
|
1201
1114
|
jsonSchema,
|
|
1202
1115
|
properties
|
|
1203
1116
|
]);
|
|
1204
1117
|
const tableRef = useRef3(null);
|
|
1205
|
-
const handleCellUpdate =
|
|
1118
|
+
const handleCellUpdate = useCallback5((cell) => {
|
|
1206
1119
|
tableRef.current?.update?.(cell);
|
|
1207
1120
|
}, []);
|
|
1208
|
-
const handleRowOrderChange =
|
|
1121
|
+
const handleRowOrderChange = useCallback5(() => {
|
|
1209
1122
|
tableRef.current?.update?.();
|
|
1210
1123
|
}, []);
|
|
1211
1124
|
const features = useDefaultValue(props.features, () => ({
|
|
@@ -1225,20 +1138,20 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1225
1138
|
onRowOrderChange: handleRowOrderChange,
|
|
1226
1139
|
onRowAction
|
|
1227
1140
|
});
|
|
1228
|
-
const presentation =
|
|
1141
|
+
const presentation = useMemo5(() => {
|
|
1229
1142
|
if (model) {
|
|
1230
1143
|
return new TablePresentation(model);
|
|
1231
1144
|
}
|
|
1232
1145
|
}, [
|
|
1233
1146
|
model
|
|
1234
1147
|
]);
|
|
1235
|
-
return /* @__PURE__ */
|
|
1148
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
1236
1149
|
role: "none",
|
|
1237
1150
|
className: mx2("is-full bs-full grow grid", classNames)
|
|
1238
|
-
}, /* @__PURE__ */
|
|
1151
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
1239
1152
|
role: "none",
|
|
1240
1153
|
className: "grid min-bs-0 overflow-hidden"
|
|
1241
|
-
}, /* @__PURE__ */
|
|
1154
|
+
}, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
|
|
1242
1155
|
ref: tableRef,
|
|
1243
1156
|
model,
|
|
1244
1157
|
presentation,
|
|
@@ -1251,43 +1164,46 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1251
1164
|
};
|
|
1252
1165
|
|
|
1253
1166
|
// src/components/TableToolbar/TableToolbar.tsx
|
|
1254
|
-
import { useSignals as
|
|
1255
|
-
import {
|
|
1256
|
-
import
|
|
1257
|
-
import { live
|
|
1258
|
-
import {
|
|
1259
|
-
import {
|
|
1260
|
-
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) =>
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1167
|
+
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1168
|
+
import { Atom } from "@effect-atom/atom-react";
|
|
1169
|
+
import React9, { useMemo as useMemo6 } from "react";
|
|
1170
|
+
import { live } from "@dxos/live-object";
|
|
1171
|
+
import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
|
|
1172
|
+
import { atomFromSignal } from "@dxos/react-ui-menu";
|
|
1173
|
+
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Atom.make((get) => {
|
|
1174
|
+
const nodes = [];
|
|
1175
|
+
if (onAdd) {
|
|
1176
|
+
const add = createMenuAction("add-row", onAdd, {
|
|
1177
|
+
type: "add-row",
|
|
1178
|
+
icon: "ph--plus--regular",
|
|
1179
|
+
label: [
|
|
1180
|
+
"add row",
|
|
1181
|
+
{
|
|
1182
|
+
ns: translationKey
|
|
1183
|
+
}
|
|
1184
|
+
],
|
|
1185
|
+
testId: "table.toolbar.add-row"
|
|
1186
|
+
});
|
|
1187
|
+
nodes.push(add);
|
|
1188
|
+
}
|
|
1189
|
+
if (onSave) {
|
|
1190
|
+
const save = createMenuAction("save-view", onSave, {
|
|
1191
|
+
type: "save-view",
|
|
1192
|
+
icon: "ph--floppy-disk--regular",
|
|
1193
|
+
label: [
|
|
1194
|
+
"save view label",
|
|
1195
|
+
{
|
|
1196
|
+
ns: translationKey
|
|
1197
|
+
}
|
|
1198
|
+
],
|
|
1199
|
+
testId: "table.toolbar.save-view",
|
|
1200
|
+
iconOnly: false,
|
|
1201
|
+
hidden: get(atomFromSignal(() => !state.viewDirty))
|
|
1202
|
+
});
|
|
1203
|
+
nodes.push(save);
|
|
1204
|
+
}
|
|
1285
1205
|
const gap = createGapSeparator();
|
|
1286
|
-
|
|
1287
|
-
add,
|
|
1288
|
-
save,
|
|
1289
|
-
...gap.nodes
|
|
1290
|
-
];
|
|
1206
|
+
nodes.push(...gap.nodes);
|
|
1291
1207
|
const edges = nodes.map(({ id: target }) => ({
|
|
1292
1208
|
source: "root",
|
|
1293
1209
|
target
|
|
@@ -1303,12 +1219,12 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.
|
|
|
1303
1219
|
};
|
|
1304
1220
|
});
|
|
1305
1221
|
var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, customActions }) => {
|
|
1306
|
-
var _effect =
|
|
1222
|
+
var _effect = _useSignals9();
|
|
1307
1223
|
try {
|
|
1308
|
-
const state =
|
|
1224
|
+
const state = useMemo6(() => live({
|
|
1309
1225
|
viewDirty
|
|
1310
1226
|
}), []);
|
|
1311
|
-
const actionsCreator =
|
|
1227
|
+
const actionsCreator = useMemo6(() => createTableToolbarActions({
|
|
1312
1228
|
state,
|
|
1313
1229
|
onAdd,
|
|
1314
1230
|
onSave,
|
|
@@ -1320,10 +1236,10 @@ var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, custom
|
|
|
1320
1236
|
customActions
|
|
1321
1237
|
]);
|
|
1322
1238
|
const menu = useMenuActions(actionsCreator);
|
|
1323
|
-
return /* @__PURE__ */
|
|
1239
|
+
return /* @__PURE__ */ React9.createElement(MenuProvider, {
|
|
1324
1240
|
...menu,
|
|
1325
1241
|
attendableId
|
|
1326
|
-
}, /* @__PURE__ */
|
|
1242
|
+
}, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
|
|
1327
1243
|
classNames
|
|
1328
1244
|
}));
|
|
1329
1245
|
} finally {
|
|
@@ -1342,7 +1258,6 @@ export {
|
|
|
1342
1258
|
TablePresentation,
|
|
1343
1259
|
TableToolbar,
|
|
1344
1260
|
cellClassesForRowSelection,
|
|
1345
|
-
createTable,
|
|
1346
1261
|
getBaseSchema,
|
|
1347
1262
|
makeDynamicTable,
|
|
1348
1263
|
narrowSchema,
|