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