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