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