@dxos/react-ui-table 0.8.3-staging.0fa589b → 0.8.4-main.f9ba587
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-TL7CKQQV.mjs → chunk-Q5QQXJUO.mjs} +2 -2
- package/dist/lib/browser/index.mjs +552 -227
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-GBT6GD4G.mjs → chunk-ZNOU6LHG.mjs} +2 -2
- package/dist/lib/node-esm/index.mjs +552 -227
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/relations.stories.d.ts +1 -1
- package/dist/types/src/components/Table/relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +2 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +2 -2
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +13 -0
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +42 -6
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +8 -0
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/playwright/playwright.config.d.ts +3 -0
- package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +3 -4
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +4 -4
- package/dist/types/src/util/table-buttons.d.ts +15 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +38 -40
- package/src/components/Table/DynamicTable.stories.tsx +2 -2
- package/src/components/Table/Table.stories.tsx +18 -12
- package/src/components/Table/Table.tsx +17 -4
- package/src/components/Table/relations.stories.tsx +4 -5
- package/src/components/TableCellEditor/CellValidationMessage.tsx +6 -1
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +3 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +54 -15
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAddRow.ts +36 -0
- package/src/index.ts +1 -1
- package/src/model/table-model.ts +220 -34
- package/src/model/table-presentation.ts +213 -130
- package/src/playwright/playwright.config.ts +17 -0
- package/src/playwright/smoke.spec.ts +9 -7
- package/src/translations.ts +5 -3
- package/src/util/table-buttons.ts +24 -1
- package/dist/lib/node/chunk-O2VPBNS5.cjs +0 -50
- package/dist/lib/node/chunk-O2VPBNS5.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -2739
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/types/index.cjs +0 -31
- package/dist/lib/node/types/index.cjs.map +0 -7
- package/src/playwright/playwright.config.cts +0 -18
- /package/dist/lib/browser/{chunk-TL7CKQQV.mjs.map → chunk-Q5QQXJUO.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-GBT6GD4G.mjs.map → chunk-ZNOU6LHG.mjs.map} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TableSchema,
|
|
3
3
|
TableType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q5QQXJUO.mjs";
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
var translationKey = "table";
|
|
8
|
-
var
|
|
6
|
+
// src/translations.ts
|
|
7
|
+
var translationKey = "react-ui-table";
|
|
8
|
+
var translations = [
|
|
9
9
|
{
|
|
10
10
|
"en-US": {
|
|
11
11
|
[translationKey]: {
|
|
@@ -35,9 +35,9 @@ var translations_default = [
|
|
|
35
35
|
}
|
|
36
36
|
];
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// src/components/Table/Table.tsx
|
|
39
39
|
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
40
|
-
import React8, { forwardRef, useCallback as useCallback5, useImperativeHandle, useState as useState3, useMemo as useMemo5, useEffect as
|
|
40
|
+
import React8, { forwardRef, useCallback as useCallback5, useImperativeHandle, useState as useState3, useMemo as useMemo5, useEffect as useEffect4 } from "react";
|
|
41
41
|
import { getValue as getValue4 } from "@dxos/echo-schema";
|
|
42
42
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
43
43
|
import { Filter } from "@dxos/react-client/echo";
|
|
@@ -47,7 +47,7 @@ import { closestCell, Grid, gridSeparatorInlineEnd, gridSeparatorBlockEnd } from
|
|
|
47
47
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
48
48
|
import { isNotFalsy, safeParseInt } from "@dxos/util";
|
|
49
49
|
|
|
50
|
-
//
|
|
50
|
+
// src/components/Table/ColumnActionsMenu.tsx
|
|
51
51
|
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
52
52
|
import React from "react";
|
|
53
53
|
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
@@ -88,7 +88,7 @@ var ColumnActionsMenu = ({ model, modals }) => {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
//
|
|
91
|
+
// src/components/Table/ColumnSettings.tsx
|
|
92
92
|
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
93
93
|
import React2, { useCallback, useEffect, useMemo, useState } from "react";
|
|
94
94
|
import { Popover } from "@dxos/react-ui";
|
|
@@ -162,7 +162,7 @@ var ColumnSettings = ({ model, modals, onNewColumn }) => {
|
|
|
162
162
|
}
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
-
//
|
|
165
|
+
// src/components/Table/CreateRefPanel.tsx
|
|
166
166
|
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
167
167
|
import { Schema } from "effect";
|
|
168
168
|
import React3, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
@@ -242,7 +242,7 @@ var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
|
242
242
|
}
|
|
243
243
|
};
|
|
244
244
|
|
|
245
|
-
//
|
|
245
|
+
// src/components/Table/RowActionsMenu.tsx
|
|
246
246
|
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
247
247
|
import React4 from "react";
|
|
248
248
|
import { DropdownMenu as DropdownMenu2, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
@@ -277,20 +277,22 @@ var RowActionsMenu = ({ model, modals }) => {
|
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
279
|
|
|
280
|
-
//
|
|
280
|
+
// src/model/table-model.ts
|
|
281
281
|
import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
|
|
282
282
|
import { Resource as Resource2 } from "@dxos/context";
|
|
283
|
-
import {
|
|
283
|
+
import { Ref as Ref3 } from "@dxos/echo";
|
|
284
|
+
import { FormatEnum as FormatEnum3, getValue as getValue2, setValue, getSnapshot, getSchema, toEffectSchema } from "@dxos/echo-schema";
|
|
284
285
|
import { invariant } from "@dxos/invariant";
|
|
285
|
-
import {
|
|
286
|
+
import { ObjectId } from "@dxos/keys";
|
|
287
|
+
import { isLiveObject } from "@dxos/live-object";
|
|
286
288
|
import { formatForEditing, parseValue } from "@dxos/react-ui-form";
|
|
287
289
|
import { validateSchema } from "@dxos/schema";
|
|
288
290
|
|
|
289
|
-
//
|
|
291
|
+
// src/model/selection-model.ts
|
|
290
292
|
import { computed, effect, signal } from "@preact/signals-core";
|
|
291
293
|
import { Resource } from "@dxos/context";
|
|
292
294
|
|
|
293
|
-
//
|
|
295
|
+
// src/util/dynamic-table.ts
|
|
294
296
|
import { Obj, Ref } from "@dxos/echo";
|
|
295
297
|
import { getTypename, toJsonSchema } from "@dxos/echo-schema";
|
|
296
298
|
import { createView, getSchemaFromPropertyDefinitions, ViewProjection } from "@dxos/schema";
|
|
@@ -367,10 +369,10 @@ var setProperties = (view, projection, properties) => {
|
|
|
367
369
|
}
|
|
368
370
|
};
|
|
369
371
|
|
|
370
|
-
//
|
|
372
|
+
// src/util/signals.ts
|
|
371
373
|
var touch = (value) => value;
|
|
372
374
|
|
|
373
|
-
//
|
|
375
|
+
// src/util/table.ts
|
|
374
376
|
import { Schema as Schema2 } from "effect";
|
|
375
377
|
import { Format, FormatEnum, Ref as Ref2, TypedObject, TypeEnum } from "@dxos/echo-schema";
|
|
376
378
|
import { PublicKey } from "@dxos/react-client";
|
|
@@ -463,12 +465,13 @@ var createProjection = (schema, view) => {
|
|
|
463
465
|
return projection;
|
|
464
466
|
};
|
|
465
467
|
|
|
466
|
-
//
|
|
468
|
+
// src/util/table-buttons.ts
|
|
467
469
|
var BUTTON_IDENTIFIERS = {
|
|
468
470
|
columnSettings: "data-table-column-settings-button",
|
|
469
471
|
newColumn: "data-table-new-column-button",
|
|
470
472
|
referencedCell: "data-table-ref-cell-button",
|
|
471
473
|
rowMenu: "data-table-row-menu-button",
|
|
474
|
+
saveDraftRow: "data-table-save-draft-row-button",
|
|
472
475
|
sort: "data-table-sort-button"
|
|
473
476
|
};
|
|
474
477
|
var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
|
|
@@ -551,14 +554,34 @@ var sortButton = {
|
|
|
551
554
|
direction: el.getAttribute("data-direction")
|
|
552
555
|
})
|
|
553
556
|
};
|
|
557
|
+
var saveDraftRowButton = {
|
|
558
|
+
attr: BUTTON_IDENTIFIERS.saveDraftRow,
|
|
559
|
+
icon: "ph--floppy-disk--regular",
|
|
560
|
+
render: ({ rowIndex, disabled }) => {
|
|
561
|
+
return createButton({
|
|
562
|
+
attr: BUTTON_IDENTIFIERS.saveDraftRow,
|
|
563
|
+
icon: saveDraftRowButton.icon,
|
|
564
|
+
disabled,
|
|
565
|
+
data: {
|
|
566
|
+
"data-row-index": rowIndex.toString()
|
|
567
|
+
},
|
|
568
|
+
testId: "table-save-draft-row-button"
|
|
569
|
+
});
|
|
570
|
+
},
|
|
571
|
+
getData: (el) => ({
|
|
572
|
+
type: "saveDraftRow",
|
|
573
|
+
rowIndex: Number(el.getAttribute("data-row-index"))
|
|
574
|
+
})
|
|
575
|
+
};
|
|
554
576
|
var tableButtons = {
|
|
555
577
|
addColumn: addColumnButton,
|
|
556
578
|
columnSettings: columnSettingsButton,
|
|
557
579
|
rowMenu: rowMenuButton,
|
|
580
|
+
saveDraftRow: saveDraftRowButton,
|
|
558
581
|
sort: sortButton
|
|
559
582
|
};
|
|
560
583
|
|
|
561
|
-
//
|
|
584
|
+
// src/util/table-controls.ts
|
|
562
585
|
var CONTROL_IDENTIFIERS = {
|
|
563
586
|
checkbox: "data-table-checkbox",
|
|
564
587
|
switch: "data-table-switch"
|
|
@@ -612,7 +635,7 @@ var tableControls = {
|
|
|
612
635
|
}
|
|
613
636
|
};
|
|
614
637
|
|
|
615
|
-
//
|
|
638
|
+
// src/util/schema.ts
|
|
616
639
|
import { Schema as Schema3 } from "effect";
|
|
617
640
|
import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
|
|
618
641
|
var narrowSchema = (schema, paths) => {
|
|
@@ -627,7 +650,7 @@ var narrowSchema = (schema, paths) => {
|
|
|
627
650
|
return void 0;
|
|
628
651
|
};
|
|
629
652
|
|
|
630
|
-
//
|
|
653
|
+
// src/model/selection-model.ts
|
|
631
654
|
var SelectionModel = class extends Resource {
|
|
632
655
|
constructor(_rows, _selectionMode, _onSelectionChanged) {
|
|
633
656
|
super(), this._rows = _rows, this._selectionMode = _selectionMode, this._onSelectionChanged = _onSelectionChanged, this._selection = signal(/* @__PURE__ */ new Set()), this._validSelectedIds = computed(() => {
|
|
@@ -702,7 +725,7 @@ var SelectionModel = class extends Resource {
|
|
|
702
725
|
}
|
|
703
726
|
};
|
|
704
727
|
|
|
705
|
-
//
|
|
728
|
+
// src/model/table-sorting.ts
|
|
706
729
|
import { computed as computed2, signal as signal2 } from "@preact/signals-core";
|
|
707
730
|
import orderBy from "lodash.orderby";
|
|
708
731
|
import { getValue, FormatEnum as FormatEnum2, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
@@ -867,7 +890,7 @@ var TableSorting = class {
|
|
|
867
890
|
}
|
|
868
891
|
};
|
|
869
892
|
|
|
870
|
-
//
|
|
893
|
+
// src/util/tag.ts
|
|
871
894
|
var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
872
895
|
var extractTagIds = (value) => {
|
|
873
896
|
if (typeof value !== "string") {
|
|
@@ -883,8 +906,8 @@ var extractTagIds = (value) => {
|
|
|
883
906
|
return ids.length > 0 ? ids : void 0;
|
|
884
907
|
};
|
|
885
908
|
|
|
886
|
-
//
|
|
887
|
-
var __dxlog_file = "/
|
|
909
|
+
// src/model/table-model.ts
|
|
910
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
888
911
|
var defaultFeatures = {
|
|
889
912
|
selection: {
|
|
890
913
|
enabled: true,
|
|
@@ -910,6 +933,7 @@ var TableModel = class extends Resource2 {
|
|
|
910
933
|
}
|
|
911
934
|
});
|
|
912
935
|
this._rows = signal3([]);
|
|
936
|
+
this._draftRows = signal3([]);
|
|
913
937
|
//
|
|
914
938
|
// Data
|
|
915
939
|
//
|
|
@@ -917,10 +941,31 @@ var TableModel = class extends Resource2 {
|
|
|
917
941
|
this._rows.value = obj;
|
|
918
942
|
};
|
|
919
943
|
this.getRowCount = () => this._rows.value.length;
|
|
944
|
+
/**
|
|
945
|
+
* @reactive
|
|
946
|
+
*/
|
|
947
|
+
this.getDraftRowCount = () => this._draftRows.value.length;
|
|
920
948
|
this.getColumnCount = () => this._view?.fields.length ?? 0;
|
|
921
|
-
this.insertRow = (
|
|
922
|
-
const
|
|
923
|
-
this.
|
|
949
|
+
this.insertRow = () => {
|
|
950
|
+
const result = this._onInsertRow?.();
|
|
951
|
+
if (result === false && this._draftRows.value.length === 0) {
|
|
952
|
+
this.createDraftRow();
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
this.commitDraftRow = (draftRowIndex) => {
|
|
956
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
const draftRow = this._draftRows.value[draftRowIndex];
|
|
960
|
+
if (!draftRow.valid) {
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
const success = this._onInsertRow?.(draftRow.data);
|
|
964
|
+
if (success) {
|
|
965
|
+
const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
|
|
966
|
+
this._draftRows.value = newDraftRows;
|
|
967
|
+
}
|
|
968
|
+
return success ?? false;
|
|
924
969
|
};
|
|
925
970
|
this.deleteRow = (rowIndex) => {
|
|
926
971
|
const row = this._sorting.getDataIndex(rowIndex);
|
|
@@ -944,14 +989,24 @@ var TableModel = class extends Resource2 {
|
|
|
944
989
|
this._onRowAction(actionId, data);
|
|
945
990
|
}
|
|
946
991
|
};
|
|
947
|
-
this.getCellData = (
|
|
992
|
+
this.getCellData = (cell) => {
|
|
993
|
+
const { col, row, plane } = cell;
|
|
948
994
|
const fields = this._view?.fields ?? [];
|
|
949
995
|
if (col < 0 || col >= fields.length) {
|
|
950
996
|
return void 0;
|
|
951
997
|
}
|
|
952
998
|
const field = fields[col];
|
|
953
|
-
|
|
954
|
-
|
|
999
|
+
let value;
|
|
1000
|
+
if (plane === "frozenRowsEnd") {
|
|
1001
|
+
if (row >= 0 && row < this._draftRows.value.length) {
|
|
1002
|
+
value = getValue2(this._draftRows.value[row].data, field.path);
|
|
1003
|
+
} else {
|
|
1004
|
+
return void 0;
|
|
1005
|
+
}
|
|
1006
|
+
} else {
|
|
1007
|
+
const dataIndex = this._sorting.getDataIndex(row);
|
|
1008
|
+
value = getValue2(this._rows.value[dataIndex], field.path);
|
|
1009
|
+
}
|
|
955
1010
|
if (value == null) {
|
|
956
1011
|
return "";
|
|
957
1012
|
}
|
|
@@ -972,8 +1027,7 @@ var TableModel = class extends Resource2 {
|
|
|
972
1027
|
}
|
|
973
1028
|
}
|
|
974
1029
|
};
|
|
975
|
-
this.validateCellData = async ({ col, row }, value) => {
|
|
976
|
-
const rowIdx = this._sorting.getDataIndex(row);
|
|
1030
|
+
this.validateCellData = async ({ col, row, plane }, value) => {
|
|
977
1031
|
const fields = this._view?.fields ?? [];
|
|
978
1032
|
if (col < 0 || col >= fields.length) {
|
|
979
1033
|
return {
|
|
@@ -983,52 +1037,82 @@ var TableModel = class extends Resource2 {
|
|
|
983
1037
|
}
|
|
984
1038
|
const field = fields[col];
|
|
985
1039
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
986
|
-
const currentRow = this._rows.value[rowIdx];
|
|
987
|
-
invariant(currentRow, "Invalid row index", {
|
|
988
|
-
F: __dxlog_file,
|
|
989
|
-
L: 355,
|
|
990
|
-
S: this,
|
|
991
|
-
A: [
|
|
992
|
-
"currentRow",
|
|
993
|
-
"'Invalid row index'"
|
|
994
|
-
]
|
|
995
|
-
});
|
|
996
|
-
const snapshot = getSnapshot(currentRow);
|
|
997
1040
|
const transformedValue = editorTextToCellValue(props, value);
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
]
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1041
|
+
const isDraftRow = plane === "frozenRowsEnd";
|
|
1042
|
+
if (isDraftRow) {
|
|
1043
|
+
const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
|
|
1044
|
+
if (isInvalidDraftRowIndex) {
|
|
1045
|
+
return {
|
|
1046
|
+
valid: false,
|
|
1047
|
+
error: "Invalid draft row index"
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
const draftRow = this._draftRows.value[row];
|
|
1051
|
+
const snapshot = {
|
|
1052
|
+
...draftRow.data
|
|
1053
|
+
};
|
|
1054
|
+
setValue(snapshot, field.path, transformedValue);
|
|
1055
|
+
const validationErrors = this.validateDraftRowData(snapshot);
|
|
1056
|
+
if (validationErrors.length > 0) {
|
|
1057
|
+
const error = validationErrors.find((err) => err.path === field.path);
|
|
1058
|
+
if (error) {
|
|
1059
|
+
return {
|
|
1060
|
+
valid: false,
|
|
1061
|
+
error: error.message
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
valid: true
|
|
1067
|
+
};
|
|
1068
|
+
} else {
|
|
1069
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
1070
|
+
const currentRow = this._rows.value[rowIdx];
|
|
1071
|
+
invariant(currentRow, "Invalid row index", {
|
|
1013
1072
|
F: __dxlog_file,
|
|
1014
|
-
L:
|
|
1073
|
+
L: 507,
|
|
1015
1074
|
S: this,
|
|
1016
1075
|
A: [
|
|
1017
|
-
"
|
|
1076
|
+
"currentRow",
|
|
1077
|
+
"'Invalid row index'"
|
|
1078
|
+
]
|
|
1079
|
+
});
|
|
1080
|
+
const snapshot = getSnapshot(currentRow);
|
|
1081
|
+
setValue(snapshot, field.path, transformedValue);
|
|
1082
|
+
const schema = getSchema(currentRow);
|
|
1083
|
+
invariant(schema, void 0, {
|
|
1084
|
+
F: __dxlog_file,
|
|
1085
|
+
L: 513,
|
|
1086
|
+
S: this,
|
|
1087
|
+
A: [
|
|
1088
|
+
"schema",
|
|
1018
1089
|
""
|
|
1019
1090
|
]
|
|
1020
1091
|
});
|
|
1092
|
+
const validationResult = validateSchema(schema, snapshot);
|
|
1093
|
+
if (validationResult && validationResult.length > 0) {
|
|
1094
|
+
const error = validationResult[0];
|
|
1095
|
+
invariant(error.path === field.path, void 0, {
|
|
1096
|
+
F: __dxlog_file,
|
|
1097
|
+
L: 518,
|
|
1098
|
+
S: this,
|
|
1099
|
+
A: [
|
|
1100
|
+
"error.path === field.path",
|
|
1101
|
+
""
|
|
1102
|
+
]
|
|
1103
|
+
});
|
|
1104
|
+
return {
|
|
1105
|
+
valid: false,
|
|
1106
|
+
error: error.message
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1021
1109
|
return {
|
|
1022
|
-
valid:
|
|
1023
|
-
error: error.message
|
|
1110
|
+
valid: true
|
|
1024
1111
|
};
|
|
1025
1112
|
}
|
|
1026
|
-
return {
|
|
1027
|
-
valid: true
|
|
1028
|
-
};
|
|
1029
1113
|
};
|
|
1030
|
-
this.setCellData = (
|
|
1031
|
-
const
|
|
1114
|
+
this.setCellData = (cell, value) => {
|
|
1115
|
+
const { col, row, plane } = cell;
|
|
1032
1116
|
const fields = this._view?.fields ?? [];
|
|
1033
1117
|
if (col < 0 || col >= fields.length) {
|
|
1034
1118
|
return;
|
|
@@ -1039,7 +1123,15 @@ var TableModel = class extends Resource2 {
|
|
|
1039
1123
|
if (props.format === FormatEnum3.Ref && !isLiveObject(value)) {
|
|
1040
1124
|
return;
|
|
1041
1125
|
}
|
|
1042
|
-
|
|
1126
|
+
if (plane === "frozenRowsEnd") {
|
|
1127
|
+
if (row >= 0 && row < this._draftRows.value.length) {
|
|
1128
|
+
setValue(this._draftRows.value[row].data, field.path, transformedValue);
|
|
1129
|
+
this.validateDraftRow(row);
|
|
1130
|
+
}
|
|
1131
|
+
} else {
|
|
1132
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
1133
|
+
setValue(this._rows.value[rowIdx], field.path, transformedValue);
|
|
1134
|
+
}
|
|
1043
1135
|
};
|
|
1044
1136
|
this._id = id;
|
|
1045
1137
|
this._space = space;
|
|
@@ -1051,7 +1143,7 @@ var TableModel = class extends Resource2 {
|
|
|
1051
1143
|
};
|
|
1052
1144
|
invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
|
|
1053
1145
|
F: __dxlog_file,
|
|
1054
|
-
L:
|
|
1146
|
+
L: 145,
|
|
1055
1147
|
S: this,
|
|
1056
1148
|
A: [
|
|
1057
1149
|
"!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
|
|
@@ -1111,7 +1203,7 @@ var TableModel = class extends Resource2 {
|
|
|
1111
1203
|
get columnMeta() {
|
|
1112
1204
|
invariant(this._columnMeta, void 0, {
|
|
1113
1205
|
F: __dxlog_file,
|
|
1114
|
-
L:
|
|
1206
|
+
L: 214,
|
|
1115
1207
|
S: this,
|
|
1116
1208
|
A: [
|
|
1117
1209
|
"this._columnMeta",
|
|
@@ -1189,6 +1281,68 @@ var TableModel = class extends Resource2 {
|
|
|
1189
1281
|
return () => rowEffects.forEach((cleanup) => cleanup());
|
|
1190
1282
|
});
|
|
1191
1283
|
this._ctx.onDispose(rowEffectManager);
|
|
1284
|
+
const draftRowsWatcher = effect2(() => {
|
|
1285
|
+
touch(this._draftRows.value);
|
|
1286
|
+
this._onRowOrderChange?.();
|
|
1287
|
+
});
|
|
1288
|
+
this._ctx.onDispose(draftRowsWatcher);
|
|
1289
|
+
}
|
|
1290
|
+
// TODO(ZaymonFC): Return .value instead of exposing the signal.
|
|
1291
|
+
get draftRows() {
|
|
1292
|
+
return this._draftRows;
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Checks if a specific field path has validation errors for a given draft row.
|
|
1296
|
+
* @param draftRowIndex - The index of the draft row to check
|
|
1297
|
+
* @param fieldPath - The path of the field to check for validation errors
|
|
1298
|
+
* @returns true if the field has validation errors, false otherwise
|
|
1299
|
+
*/
|
|
1300
|
+
hasDraftRowValidationError(draftRowIndex, fieldPath) {
|
|
1301
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
const draftRow = this._draftRows.value[draftRowIndex];
|
|
1305
|
+
const validationErrors = draftRow.validationErrors || [];
|
|
1306
|
+
return validationErrors.some((error) => error.path === fieldPath);
|
|
1307
|
+
}
|
|
1308
|
+
createDraftRow() {
|
|
1309
|
+
if (!this._view) {
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
const draftData = {
|
|
1313
|
+
id: ObjectId.random()
|
|
1314
|
+
};
|
|
1315
|
+
const validationErrors = this.validateDraftRowData(draftData);
|
|
1316
|
+
const draftRow = {
|
|
1317
|
+
data: draftData,
|
|
1318
|
+
valid: validationErrors.length === 0,
|
|
1319
|
+
validationErrors
|
|
1320
|
+
};
|
|
1321
|
+
this._draftRows.value = [
|
|
1322
|
+
...this._draftRows.value,
|
|
1323
|
+
draftRow
|
|
1324
|
+
];
|
|
1325
|
+
}
|
|
1326
|
+
validateDraftRow(draftRowIndex) {
|
|
1327
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
const draftRow = this._draftRows.value[draftRowIndex];
|
|
1331
|
+
const validationErrors = this.validateDraftRowData(draftRow.data);
|
|
1332
|
+
const updatedDraftRow = {
|
|
1333
|
+
...draftRow,
|
|
1334
|
+
valid: validationErrors.length === 0,
|
|
1335
|
+
validationErrors
|
|
1336
|
+
};
|
|
1337
|
+
const newDraftRows = [
|
|
1338
|
+
...this._draftRows.value
|
|
1339
|
+
];
|
|
1340
|
+
newDraftRows[draftRowIndex] = updatedDraftRow;
|
|
1341
|
+
this._draftRows.value = newDraftRows;
|
|
1342
|
+
}
|
|
1343
|
+
validateDraftRowData(data) {
|
|
1344
|
+
const schema = toEffectSchema(this._projection.schema);
|
|
1345
|
+
return validateSchema(schema, data) || [];
|
|
1192
1346
|
}
|
|
1193
1347
|
/**
|
|
1194
1348
|
* Updates a cell's value using a transform function.
|
|
@@ -1203,6 +1357,31 @@ var TableModel = class extends Resource2 {
|
|
|
1203
1357
|
const updatedValue = update(value);
|
|
1204
1358
|
setValue(this._rows.value[dataRow], field.path, updatedValue);
|
|
1205
1359
|
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Gets the domain-appropriate cell type for a given cell position.
|
|
1362
|
+
* This abstracts away the low-level grid plane concepts and provides domain-specific types.
|
|
1363
|
+
* @param cell - The cell position to classify
|
|
1364
|
+
* @returns The domain-appropriate cell type
|
|
1365
|
+
*/
|
|
1366
|
+
getCellType(cell) {
|
|
1367
|
+
switch (cell.plane) {
|
|
1368
|
+
case "frozenRowsEnd":
|
|
1369
|
+
return "draft";
|
|
1370
|
+
case "frozenRowsStart":
|
|
1371
|
+
return "header";
|
|
1372
|
+
case "grid":
|
|
1373
|
+
default:
|
|
1374
|
+
return "standard";
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Convenience method to check if a cell is a draft cell.
|
|
1379
|
+
* @param cell - The cell position to check
|
|
1380
|
+
* @returns true if the cell is a draft cell, false otherwise
|
|
1381
|
+
*/
|
|
1382
|
+
isDraftCell(cell) {
|
|
1383
|
+
return this.getCellType(cell) === "draft";
|
|
1384
|
+
}
|
|
1206
1385
|
//
|
|
1207
1386
|
// Column Operations
|
|
1208
1387
|
//
|
|
@@ -1250,7 +1429,7 @@ var editorTextToCellValue = (props, value) => {
|
|
|
1250
1429
|
switch (props.format) {
|
|
1251
1430
|
case FormatEnum3.Ref: {
|
|
1252
1431
|
if (isLiveObject(value)) {
|
|
1253
|
-
return
|
|
1432
|
+
return Ref3.make(value);
|
|
1254
1433
|
} else {
|
|
1255
1434
|
return value;
|
|
1256
1435
|
}
|
|
@@ -1277,10 +1456,10 @@ var editorTextToCellValue = (props, value) => {
|
|
|
1277
1456
|
}
|
|
1278
1457
|
};
|
|
1279
1458
|
|
|
1280
|
-
//
|
|
1459
|
+
// src/model/modal-controller.ts
|
|
1281
1460
|
import { signal as signal4 } from "@preact/signals-core";
|
|
1282
1461
|
import { log } from "@dxos/log";
|
|
1283
|
-
var __dxlog_file2 = "/
|
|
1462
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
|
|
1284
1463
|
var ModalController = class {
|
|
1285
1464
|
constructor() {
|
|
1286
1465
|
this._state = signal4({
|
|
@@ -1365,10 +1544,11 @@ var ModalController = class {
|
|
|
1365
1544
|
}
|
|
1366
1545
|
};
|
|
1367
1546
|
|
|
1368
|
-
//
|
|
1547
|
+
// src/model/table-presentation.ts
|
|
1369
1548
|
import { signal as signal5 } from "@preact/signals-core";
|
|
1370
1549
|
import { isNotNullable } from "effect/Predicate";
|
|
1371
|
-
import {
|
|
1550
|
+
import { Obj as Obj2 } from "@dxos/echo";
|
|
1551
|
+
import { FormatEnum as FormatEnum4, getValue as getValue3, TypeEnum as TypeEnum3 } from "@dxos/echo-schema";
|
|
1372
1552
|
import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
|
|
1373
1553
|
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1374
1554
|
import { mx } from "@dxos/react-ui-theme";
|
|
@@ -1386,8 +1566,10 @@ var TablePresentation = class {
|
|
|
1386
1566
|
})) {
|
|
1387
1567
|
this.model = model;
|
|
1388
1568
|
this._visibleRange = _visibleRange;
|
|
1569
|
+
this.fieldProjectionCache = /* @__PURE__ */ new Map();
|
|
1389
1570
|
}
|
|
1390
1571
|
getCells(range, plane) {
|
|
1572
|
+
this.fieldProjectionCache.clear();
|
|
1391
1573
|
let cells;
|
|
1392
1574
|
switch (plane) {
|
|
1393
1575
|
case "grid":
|
|
@@ -1409,6 +1591,12 @@ var TablePresentation = class {
|
|
|
1409
1591
|
case "fixedStartEnd":
|
|
1410
1592
|
cells = this.getNewColumnCell();
|
|
1411
1593
|
break;
|
|
1594
|
+
case "frozenRowsEnd":
|
|
1595
|
+
cells = this.getDraftRowCells(range);
|
|
1596
|
+
break;
|
|
1597
|
+
case "fixedEndEnd":
|
|
1598
|
+
cells = this.getDraftActionCells(range);
|
|
1599
|
+
break;
|
|
1412
1600
|
default:
|
|
1413
1601
|
cells = {};
|
|
1414
1602
|
}
|
|
@@ -1419,139 +1607,178 @@ var TablePresentation = class {
|
|
|
1419
1607
|
}
|
|
1420
1608
|
return cells;
|
|
1421
1609
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1610
|
+
/**
|
|
1611
|
+
* Gets a field projection, using cache if available within the current render pass.
|
|
1612
|
+
*/
|
|
1613
|
+
getFieldProjection(fieldId) {
|
|
1614
|
+
let projection = this.fieldProjectionCache.get(fieldId);
|
|
1615
|
+
if (!projection) {
|
|
1616
|
+
projection = this.model.projection.getFieldProjection(fieldId);
|
|
1617
|
+
this.fieldProjectionCache.set(fieldId, projection);
|
|
1618
|
+
}
|
|
1619
|
+
return projection;
|
|
1620
|
+
}
|
|
1621
|
+
createDataCell(cells, obj, field, colIndex, displayIndex) {
|
|
1622
|
+
const { props } = this.getFieldProjection(field.id);
|
|
1623
|
+
const cell = {
|
|
1624
|
+
get value() {
|
|
1625
|
+
const value = getValue3(obj, field.path);
|
|
1626
|
+
if (value == null) {
|
|
1627
|
+
return "";
|
|
1628
|
+
}
|
|
1629
|
+
if (props.type === "array") {
|
|
1630
|
+
return "";
|
|
1631
|
+
}
|
|
1632
|
+
switch (props.format) {
|
|
1633
|
+
case FormatEnum4.Boolean:
|
|
1634
|
+
case FormatEnum4.SingleSelect:
|
|
1635
|
+
case FormatEnum4.MultiSelect: {
|
|
1434
1636
|
return "";
|
|
1435
1637
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
case FormatEnum4.SingleSelect:
|
|
1439
|
-
case FormatEnum4.MultiSelect: {
|
|
1638
|
+
case FormatEnum4.Ref: {
|
|
1639
|
+
if (!field.referencePath) {
|
|
1440
1640
|
return "";
|
|
1441
1641
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
type: props.type,
|
|
1451
|
-
format: props.format,
|
|
1452
|
-
value
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1642
|
+
return getValue3(value.target, field.referencePath);
|
|
1643
|
+
}
|
|
1644
|
+
default: {
|
|
1645
|
+
return formatForDisplay2({
|
|
1646
|
+
type: props.type,
|
|
1647
|
+
format: props.format,
|
|
1648
|
+
value
|
|
1649
|
+
});
|
|
1455
1650
|
}
|
|
1456
1651
|
}
|
|
1457
|
-
};
|
|
1458
|
-
const classes = [];
|
|
1459
|
-
const formatClasses = cellClassesForFieldType({
|
|
1460
|
-
type: props.type,
|
|
1461
|
-
format: props.format
|
|
1462
|
-
});
|
|
1463
|
-
if (formatClasses) {
|
|
1464
|
-
classes.push(formatClasses);
|
|
1465
1652
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1653
|
+
};
|
|
1654
|
+
const classes = [];
|
|
1655
|
+
const formatClasses = cellClassesForFieldType({
|
|
1656
|
+
type: props.type,
|
|
1657
|
+
format: props.format
|
|
1658
|
+
});
|
|
1659
|
+
if (formatClasses) {
|
|
1660
|
+
classes.push(formatClasses);
|
|
1661
|
+
}
|
|
1662
|
+
const rowSelectionClasses = cellClassesForRowSelection(this.model.selection.isObjectSelected(obj), this.model.selection.selectionMode);
|
|
1663
|
+
if (rowSelectionClasses) {
|
|
1664
|
+
classes.push(rowSelectionClasses);
|
|
1665
|
+
}
|
|
1666
|
+
if (classes.length > 0) {
|
|
1667
|
+
cell.className = mx(classes.flat());
|
|
1668
|
+
}
|
|
1669
|
+
if (props.type === TypeEnum3.Array) {
|
|
1670
|
+
const targetArray = getValue3(obj, field.path);
|
|
1671
|
+
if (targetArray && Array.isArray(targetArray)) {
|
|
1672
|
+
const getLabel = (value) => {
|
|
1673
|
+
if (!value) {
|
|
1674
|
+
return void 0;
|
|
1675
|
+
}
|
|
1676
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1677
|
+
return String(value);
|
|
1678
|
+
}
|
|
1679
|
+
if (Array.isArray(value)) {
|
|
1680
|
+
return "Array";
|
|
1681
|
+
}
|
|
1682
|
+
if (typeof value === "object" && value.name) {
|
|
1683
|
+
return value.name;
|
|
1684
|
+
}
|
|
1685
|
+
if (typeof value === "object" && value.value) {
|
|
1686
|
+
return `${value.value}`;
|
|
1687
|
+
}
|
|
1688
|
+
return "Object";
|
|
1689
|
+
};
|
|
1690
|
+
const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
|
|
1691
|
+
return `<span class="dx-tag rounded-xl" data-hue="neutral">${title}</span>`;
|
|
1692
|
+
}).join("");
|
|
1693
|
+
cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
|
|
1472
1694
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
}
|
|
1480
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1481
|
-
return String(value);
|
|
1482
|
-
}
|
|
1483
|
-
if (Array.isArray(value)) {
|
|
1484
|
-
return "Array";
|
|
1485
|
-
}
|
|
1486
|
-
if (typeof value === "object" && value.name) {
|
|
1487
|
-
return value.name;
|
|
1488
|
-
}
|
|
1489
|
-
if (typeof value === "object" && value.value) {
|
|
1490
|
-
return `${value.value}`;
|
|
1491
|
-
}
|
|
1492
|
-
return "Object";
|
|
1493
|
-
};
|
|
1494
|
-
const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
|
|
1495
|
-
return `<span class="dx-tag rounded-xl" data-hue="neutral">${title}</span>`;
|
|
1496
|
-
}).join("");
|
|
1497
|
-
cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
|
|
1498
|
-
}
|
|
1695
|
+
}
|
|
1696
|
+
if (props.format === FormatEnum4.Ref && props.referenceSchema) {
|
|
1697
|
+
const targetObj = getValue3(obj, field.path)?.target;
|
|
1698
|
+
if (targetObj) {
|
|
1699
|
+
const dxn = Obj2.getDXN(targetObj)?.toString();
|
|
1700
|
+
cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-1"><dx-icon icon="ph--link-simple--regular"/></dx-ref-tag>`;
|
|
1499
1701
|
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1702
|
+
}
|
|
1703
|
+
if (props.format === FormatEnum4.Boolean) {
|
|
1704
|
+
const value = getValue3(obj, field.path);
|
|
1705
|
+
cell.accessoryHtml = tableControls.switch.render({
|
|
1706
|
+
colIndex,
|
|
1707
|
+
rowIndex: displayIndex,
|
|
1708
|
+
checked: value ?? false
|
|
1709
|
+
});
|
|
1710
|
+
cell.readonly = "no-text-select";
|
|
1711
|
+
}
|
|
1712
|
+
if (props.format === FormatEnum4.SingleSelect) {
|
|
1713
|
+
const value = getValue3(obj, field.path);
|
|
1714
|
+
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1715
|
+
if (options) {
|
|
1716
|
+
const option = options.find((o) => o.id === value);
|
|
1717
|
+
if (option) {
|
|
1718
|
+
cell.accessoryHtml = `<span class="dx-tag" data-hue="${option.color}">${option.title}</span>`;
|
|
1505
1719
|
}
|
|
1506
1720
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
});
|
|
1514
|
-
cell.readonly = "no-text-select";
|
|
1515
|
-
}
|
|
1516
|
-
if (props.format === FormatEnum4.SingleSelect) {
|
|
1517
|
-
const value = getValue3(obj, field.path);
|
|
1518
|
-
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1519
|
-
if (options) {
|
|
1721
|
+
}
|
|
1722
|
+
if (props.format === FormatEnum4.MultiSelect) {
|
|
1723
|
+
const values = getValue3(obj, field.path);
|
|
1724
|
+
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1725
|
+
if (options && values && values.length > 0) {
|
|
1726
|
+
const tags = values.map((value) => {
|
|
1520
1727
|
const option = options.find((o) => o.id === value);
|
|
1521
1728
|
if (option) {
|
|
1522
|
-
|
|
1729
|
+
return `<span class="dx-tag" data-hue="${option.color}">${option.title}</span>`;
|
|
1523
1730
|
}
|
|
1731
|
+
return null;
|
|
1732
|
+
}).filter(Boolean).join("");
|
|
1733
|
+
if (tags) {
|
|
1734
|
+
cell.accessoryHtml = tags;
|
|
1524
1735
|
}
|
|
1525
1736
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1737
|
+
}
|
|
1738
|
+
const idx = toPlaneCellIndex({
|
|
1739
|
+
col: colIndex,
|
|
1740
|
+
row: displayIndex
|
|
1741
|
+
});
|
|
1742
|
+
cells[idx] = cell;
|
|
1743
|
+
}
|
|
1744
|
+
getMainGridCells(range) {
|
|
1745
|
+
const cells = {};
|
|
1746
|
+
const fields = this.model.view?.fields ?? [];
|
|
1747
|
+
for (let row = range.start.row; row <= range.end.row && row < this.model.getRowCount(); row++) {
|
|
1748
|
+
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1749
|
+
const field = fields[col];
|
|
1750
|
+
if (!field) {
|
|
1751
|
+
continue;
|
|
1540
1752
|
}
|
|
1753
|
+
this.createDataCell(cells, this.model.rows.value[row], field, col, row);
|
|
1541
1754
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1755
|
+
}
|
|
1756
|
+
return cells;
|
|
1757
|
+
}
|
|
1758
|
+
getDraftRowCells(range) {
|
|
1759
|
+
const cells = {};
|
|
1760
|
+
const fields = this.model.view?.fields ?? [];
|
|
1761
|
+
const draftRows = this.model.draftRows.value;
|
|
1762
|
+
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
1763
|
+
const draftRow = draftRows[row];
|
|
1549
1764
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1550
1765
|
const field = fields[col];
|
|
1551
1766
|
if (!field) {
|
|
1552
1767
|
continue;
|
|
1553
1768
|
}
|
|
1554
|
-
|
|
1769
|
+
this.createDataCell(cells, draftRow.data, field, col, row);
|
|
1770
|
+
if (this.model.hasDraftRowValidationError(row, field.path)) {
|
|
1771
|
+
const cellIndex = toPlaneCellIndex({
|
|
1772
|
+
col,
|
|
1773
|
+
row
|
|
1774
|
+
});
|
|
1775
|
+
const cellValue = cells[cellIndex];
|
|
1776
|
+
if (cellValue) {
|
|
1777
|
+
const existingClasses = cellValue.className || "";
|
|
1778
|
+
const draftClasses = "dx-grid__cell--flagged";
|
|
1779
|
+
cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1555
1782
|
}
|
|
1556
1783
|
}
|
|
1557
1784
|
return cells;
|
|
@@ -1560,7 +1787,7 @@ var TablePresentation = class {
|
|
|
1560
1787
|
const cells = {};
|
|
1561
1788
|
const fields = this.model.view?.fields ?? [];
|
|
1562
1789
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1563
|
-
const { field, props } = this.
|
|
1790
|
+
const { field, props } = this.getFieldProjection(fields[col].id);
|
|
1564
1791
|
const sorting = this.model.sorting?.sorting;
|
|
1565
1792
|
const direction = sorting?.fieldId === field.id ? sorting.direction : void 0;
|
|
1566
1793
|
cells[toPlaneCellIndex({
|
|
@@ -1668,6 +1895,26 @@ var TablePresentation = class {
|
|
|
1668
1895
|
}
|
|
1669
1896
|
};
|
|
1670
1897
|
}
|
|
1898
|
+
getDraftActionCells(range) {
|
|
1899
|
+
const cells = {};
|
|
1900
|
+
const draftRows = this.model.draftRows.value;
|
|
1901
|
+
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
1902
|
+
const draftRow = draftRows[row];
|
|
1903
|
+
const disabled = !draftRow.valid;
|
|
1904
|
+
cells[toPlaneCellIndex({
|
|
1905
|
+
col: 0,
|
|
1906
|
+
row
|
|
1907
|
+
})] = {
|
|
1908
|
+
value: "",
|
|
1909
|
+
readonly: true,
|
|
1910
|
+
accessoryHtml: tableButtons.saveDraftRow.render({
|
|
1911
|
+
rowIndex: row,
|
|
1912
|
+
disabled
|
|
1913
|
+
})
|
|
1914
|
+
};
|
|
1915
|
+
}
|
|
1916
|
+
return cells;
|
|
1917
|
+
}
|
|
1671
1918
|
};
|
|
1672
1919
|
var cellClassesForRowSelection = (selected, selectionMode) => {
|
|
1673
1920
|
if (!selected) {
|
|
@@ -1692,30 +1939,32 @@ var cellClassesForRowSelection = (selected, selectionMode) => {
|
|
|
1692
1939
|
}
|
|
1693
1940
|
};
|
|
1694
1941
|
|
|
1695
|
-
//
|
|
1942
|
+
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
1696
1943
|
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
1697
|
-
import React7, { useCallback as useCallback4, useMemo as useMemo4, useRef as useRef2, useState as useState2 } from "react";
|
|
1944
|
+
import React7, { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef2, useState as useState2 } from "react";
|
|
1698
1945
|
import { FormatEnum as FormatEnum5, TypeEnum as TypeEnum4 } from "@dxos/echo-schema";
|
|
1699
1946
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1700
1947
|
import { useThemeContext } from "@dxos/react-ui";
|
|
1701
1948
|
import { createMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
1702
1949
|
import { cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext4, GridCellEditor } from "@dxos/react-ui-grid";
|
|
1703
|
-
import {
|
|
1950
|
+
import { tagPicker, createLinks } from "@dxos/react-ui-tag-picker";
|
|
1704
1951
|
|
|
1705
|
-
//
|
|
1952
|
+
// src/components/TableCellEditor/CellValidationMessage.tsx
|
|
1706
1953
|
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
1707
1954
|
import React5 from "react";
|
|
1708
1955
|
import { useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
|
|
1709
|
-
var CellValidationMessage = ({ validationError, __gridScope }) => {
|
|
1956
|
+
var CellValidationMessage = ({ validationError, variant = "error", __gridScope }) => {
|
|
1710
1957
|
var _effect = _useSignals5();
|
|
1711
1958
|
try {
|
|
1712
1959
|
const { editing, editBox: box } = useGridContext2("GridSheetCellEditor", __gridScope);
|
|
1713
1960
|
if (!editing || !validationError) {
|
|
1714
1961
|
return null;
|
|
1715
1962
|
}
|
|
1963
|
+
const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
|
|
1964
|
+
const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
|
|
1716
1965
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1717
1966
|
role: "none",
|
|
1718
|
-
className:
|
|
1967
|
+
className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
|
|
1719
1968
|
style: {
|
|
1720
1969
|
...{
|
|
1721
1970
|
"--dx-gridCellWidth": `${box?.inlineSize ?? 200}px`
|
|
@@ -1731,7 +1980,7 @@ var CellValidationMessage = ({ validationError, __gridScope }) => {
|
|
|
1731
1980
|
}
|
|
1732
1981
|
};
|
|
1733
1982
|
|
|
1734
|
-
//
|
|
1983
|
+
// src/components/TableCellEditor/FormCellEditor.tsx
|
|
1735
1984
|
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
1736
1985
|
import React6, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useRef } from "react";
|
|
1737
1986
|
import { getSnapshot as getSnapshot2 } from "@dxos/echo-schema";
|
|
@@ -1740,7 +1989,7 @@ import { Popover as Popover3 } from "@dxos/react-ui";
|
|
|
1740
1989
|
import { Form as Form2 } from "@dxos/react-ui-form";
|
|
1741
1990
|
import { parseCellIndex, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
|
|
1742
1991
|
import { getDeep, setDeep } from "@dxos/util";
|
|
1743
|
-
var __dxlog_file3 = "/
|
|
1992
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
|
|
1744
1993
|
var FormCellEditor = ({ fieldProjection, model, schema, __gridScope }) => {
|
|
1745
1994
|
var _effect = _useSignals6();
|
|
1746
1995
|
try {
|
|
@@ -1832,7 +2081,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, __gridScope }) => {
|
|
|
1832
2081
|
}
|
|
1833
2082
|
};
|
|
1834
2083
|
|
|
1835
|
-
//
|
|
2084
|
+
// src/components/TableCellEditor/extension.ts
|
|
1836
2085
|
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
|
|
1837
2086
|
import { EditorView } from "@codemirror/view";
|
|
1838
2087
|
var completion = ({ debug, onQuery, onMatch }) => {
|
|
@@ -1871,8 +2120,8 @@ var completion = ({ debug, onQuery, onMatch }) => {
|
|
|
1871
2120
|
];
|
|
1872
2121
|
};
|
|
1873
2122
|
|
|
1874
|
-
//
|
|
1875
|
-
var __dxlog_file4 = "/
|
|
2123
|
+
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
2124
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
1876
2125
|
var newValue = Symbol.for("newValue");
|
|
1877
2126
|
var createOption = (text) => ({
|
|
1878
2127
|
[newValue]: true,
|
|
@@ -1924,6 +2173,11 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onQuery, __gr
|
|
|
1924
2173
|
_effect.f();
|
|
1925
2174
|
}
|
|
1926
2175
|
};
|
|
2176
|
+
var editorSlots = {
|
|
2177
|
+
scroller: {
|
|
2178
|
+
className: "!plb-[--dx-grid-cell-editor-padding-block]"
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
1927
2181
|
var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }) => {
|
|
1928
2182
|
var _effect = _useSignals7();
|
|
1929
2183
|
try {
|
|
@@ -1931,6 +2185,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1931
2185
|
const suppressNextBlur = useRef2(false);
|
|
1932
2186
|
const { themeMode } = useThemeContext();
|
|
1933
2187
|
const [_validationError, setValidationError] = useState2(null);
|
|
2188
|
+
const [_validationVariant, setValidationVariant] = useState2("error");
|
|
1934
2189
|
const fieldProjection = useMemo4(() => {
|
|
1935
2190
|
if (!model || !editing) {
|
|
1936
2191
|
return;
|
|
@@ -1940,7 +2195,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1940
2195
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
1941
2196
|
invariant3(fieldProjection2, void 0, {
|
|
1942
2197
|
F: __dxlog_file4,
|
|
1943
|
-
L:
|
|
2198
|
+
L: 119,
|
|
1944
2199
|
S: void 0,
|
|
1945
2200
|
A: [
|
|
1946
2201
|
"fieldProjection",
|
|
@@ -1952,20 +2207,52 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1952
2207
|
model,
|
|
1953
2208
|
editing
|
|
1954
2209
|
]);
|
|
2210
|
+
useEffect3(() => {
|
|
2211
|
+
if (!model || !editing || !fieldProjection) {
|
|
2212
|
+
setValidationError(null);
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
const cell = parseCellIndex2(editing.index);
|
|
2216
|
+
const { row, col } = cell;
|
|
2217
|
+
if (model.isDraftCell(cell)) {
|
|
2218
|
+
const field = model.projection.view.fields[col];
|
|
2219
|
+
const hasValidationError = model.hasDraftRowValidationError(row, field.path);
|
|
2220
|
+
if (hasValidationError) {
|
|
2221
|
+
const draftRows = model.draftRows.value;
|
|
2222
|
+
if (row >= 0 && row < draftRows.length) {
|
|
2223
|
+
const draftRow = draftRows[row];
|
|
2224
|
+
const validationError = draftRow.validationErrors?.find((error) => error.path === field.path);
|
|
2225
|
+
if (validationError) {
|
|
2226
|
+
setValidationError(validationError.message);
|
|
2227
|
+
setValidationVariant("warning");
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
} else {
|
|
2231
|
+
setValidationError(null);
|
|
2232
|
+
}
|
|
2233
|
+
} else {
|
|
2234
|
+
setValidationError(null);
|
|
2235
|
+
}
|
|
2236
|
+
}, [
|
|
2237
|
+
model,
|
|
2238
|
+
editing,
|
|
2239
|
+
fieldProjection
|
|
2240
|
+
]);
|
|
1955
2241
|
const handleEnter = useCallback4(async (value) => {
|
|
1956
2242
|
if (!model || !editing) {
|
|
1957
2243
|
return;
|
|
1958
2244
|
}
|
|
1959
2245
|
const cell = parseCellIndex2(editing.index);
|
|
1960
|
-
const
|
|
1961
|
-
if (
|
|
2246
|
+
const validationResult = await model.validateCellData(cell, value);
|
|
2247
|
+
if (validationResult.valid) {
|
|
1962
2248
|
setValidationError(null);
|
|
1963
2249
|
model.setCellData(cell, value);
|
|
1964
2250
|
onEnter?.(cell);
|
|
1965
2251
|
onFocus?.();
|
|
1966
2252
|
setEditing(null);
|
|
1967
2253
|
} else {
|
|
1968
|
-
setValidationError(
|
|
2254
|
+
setValidationError(validationResult.error);
|
|
2255
|
+
setValidationVariant("error");
|
|
1969
2256
|
}
|
|
1970
2257
|
}, [
|
|
1971
2258
|
model,
|
|
@@ -2002,6 +2289,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
2002
2289
|
}
|
|
2003
2290
|
} else {
|
|
2004
2291
|
setValidationError(result.error);
|
|
2292
|
+
setValidationVariant("error");
|
|
2005
2293
|
}
|
|
2006
2294
|
} else {
|
|
2007
2295
|
setValidationError(null);
|
|
@@ -2037,9 +2325,9 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
2037
2325
|
}));
|
|
2038
2326
|
const options = fieldProjection.props.options || [];
|
|
2039
2327
|
const mode = format === FormatEnum5.SingleSelect ? "single-select" : "multi-select";
|
|
2040
|
-
extension2.push(
|
|
2328
|
+
extension2.push(tagPicker({
|
|
2041
2329
|
mode,
|
|
2042
|
-
|
|
2330
|
+
keymap: false,
|
|
2043
2331
|
onSearch: (text, selectedIds) => {
|
|
2044
2332
|
return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
|
|
2045
2333
|
id: option.id,
|
|
@@ -2109,8 +2397,8 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
2109
2397
|
const value2 = model.getCellData(cell);
|
|
2110
2398
|
if (value2 !== void 0) {
|
|
2111
2399
|
const options = fieldProjection2.props.options || [];
|
|
2112
|
-
if (fieldProjection2.props.format === FormatEnum5.MultiSelect
|
|
2113
|
-
const tagItems = value2.map((id) => {
|
|
2400
|
+
if (fieldProjection2.props.format === FormatEnum5.MultiSelect) {
|
|
2401
|
+
const tagItems = value2.split(",").map((id) => {
|
|
2114
2402
|
const option = options.find((o) => o.id === id);
|
|
2115
2403
|
if (option) {
|
|
2116
2404
|
return {
|
|
@@ -2147,11 +2435,13 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
2147
2435
|
]);
|
|
2148
2436
|
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(CellValidationMessage, {
|
|
2149
2437
|
validationError: _validationError,
|
|
2438
|
+
variant: _validationVariant,
|
|
2150
2439
|
__gridScope
|
|
2151
2440
|
}), /* @__PURE__ */ React7.createElement(GridCellEditor, {
|
|
2152
2441
|
extension,
|
|
2153
2442
|
getCellContent,
|
|
2154
|
-
onBlur: handleBlur
|
|
2443
|
+
onBlur: handleBlur,
|
|
2444
|
+
slots: editorSlots
|
|
2155
2445
|
}));
|
|
2156
2446
|
} finally {
|
|
2157
2447
|
_effect.f();
|
|
@@ -2182,8 +2472,8 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
2182
2472
|
return shift ? -1 : 1;
|
|
2183
2473
|
};
|
|
2184
2474
|
|
|
2185
|
-
//
|
|
2186
|
-
var __dxlog_file5 = "/
|
|
2475
|
+
// src/components/Table/Table.tsx
|
|
2476
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
|
|
2187
2477
|
var TableRoot = ({ children, role }) => {
|
|
2188
2478
|
var _effect = _useSignals8();
|
|
2189
2479
|
try {
|
|
@@ -2202,20 +2492,23 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2202
2492
|
const { hasAttention } = useAttention(model?.id ?? "table");
|
|
2203
2493
|
const { t } = useTranslation3(translationKey);
|
|
2204
2494
|
const modals = useMemo5(() => new ModalController(), []);
|
|
2495
|
+
const draftRowCount = model?.getDraftRowCount() ?? 0;
|
|
2205
2496
|
const frozen = useMemo5(() => {
|
|
2206
2497
|
const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
|
|
2207
2498
|
return {
|
|
2208
2499
|
frozenRowsStart: 1,
|
|
2500
|
+
frozenRowsEnd: draftRowCount,
|
|
2209
2501
|
frozenColsStart: model?.features.selection.enabled ? 1 : 0,
|
|
2210
2502
|
frozenColsEnd: noActionColumn ? 0 : 1
|
|
2211
2503
|
};
|
|
2212
2504
|
}, [
|
|
2213
|
-
model
|
|
2505
|
+
model,
|
|
2506
|
+
draftRowCount
|
|
2214
2507
|
]);
|
|
2215
2508
|
const getCells = useCallback5((range, plane) => presentation?.getCells(range, plane) ?? {}, [
|
|
2216
2509
|
presentation
|
|
2217
2510
|
]);
|
|
2218
|
-
|
|
2511
|
+
useEffect4(() => {
|
|
2219
2512
|
if (!presentation || !dxGrid) {
|
|
2220
2513
|
return;
|
|
2221
2514
|
}
|
|
@@ -2283,6 +2576,17 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2283
2576
|
model?.sorting?.toggleSort(data.fieldId);
|
|
2284
2577
|
break;
|
|
2285
2578
|
}
|
|
2579
|
+
case "saveDraftRow": {
|
|
2580
|
+
if (model) {
|
|
2581
|
+
const didCommitSuccessfully = model.commitDraftRow(data.rowIndex);
|
|
2582
|
+
if (dxGrid && didCommitSuccessfully) {
|
|
2583
|
+
requestAnimationFrame(() => {
|
|
2584
|
+
dxGrid.scrollToEndRow();
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
break;
|
|
2589
|
+
}
|
|
2286
2590
|
}
|
|
2287
2591
|
return;
|
|
2288
2592
|
}
|
|
@@ -2316,7 +2620,8 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2316
2620
|
}
|
|
2317
2621
|
}, [
|
|
2318
2622
|
model,
|
|
2319
|
-
modals
|
|
2623
|
+
modals,
|
|
2624
|
+
dxGrid
|
|
2320
2625
|
]);
|
|
2321
2626
|
const handleFocus = useCallback5((increment, delta) => {
|
|
2322
2627
|
if (dxGrid) {
|
|
@@ -2330,7 +2635,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2330
2635
|
return;
|
|
2331
2636
|
}
|
|
2332
2637
|
if (model && cell.row === model.getRowCount() - 1) {
|
|
2333
|
-
model.insertRow(
|
|
2638
|
+
model.insertRow();
|
|
2334
2639
|
if (dxGrid) {
|
|
2335
2640
|
requestAnimationFrame(() => {
|
|
2336
2641
|
dxGrid?.scrollToRow(cell.row + 1);
|
|
@@ -2390,7 +2695,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2390
2695
|
const space = model.space;
|
|
2391
2696
|
invariant4(space, void 0, {
|
|
2392
2697
|
F: __dxlog_file5,
|
|
2393
|
-
L:
|
|
2698
|
+
L: 325,
|
|
2394
2699
|
S: void 0,
|
|
2395
2700
|
A: [
|
|
2396
2701
|
"space",
|
|
@@ -2451,7 +2756,6 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
2451
2756
|
}), /* @__PURE__ */ React8.createElement(Grid.Content, {
|
|
2452
2757
|
className: mx2("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
|
|
2453
2758
|
frozen,
|
|
2454
|
-
// getCells={getCells}
|
|
2455
2759
|
columns: model.columnMeta.value,
|
|
2456
2760
|
limitRows: model.getRowCount() ?? 0,
|
|
2457
2761
|
limitColumns: model.view?.fields?.length ?? 0,
|
|
@@ -2484,17 +2788,17 @@ var Table = {
|
|
|
2484
2788
|
Main: TableMain
|
|
2485
2789
|
};
|
|
2486
2790
|
|
|
2487
|
-
//
|
|
2791
|
+
// src/components/Table/DynamicTable.tsx
|
|
2488
2792
|
import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
|
|
2489
|
-
import React9, { useRef as useRef3, useMemo as useMemo6, useCallback as
|
|
2793
|
+
import React9, { useRef as useRef3, useMemo as useMemo6, useCallback as useCallback7 } from "react";
|
|
2490
2794
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
2491
2795
|
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
2492
2796
|
|
|
2493
|
-
//
|
|
2797
|
+
// src/hooks/useTableModel.ts
|
|
2494
2798
|
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
2495
2799
|
import { effect as effect3 } from "@preact/signals-core";
|
|
2496
2800
|
import orderBy2 from "lodash.orderby";
|
|
2497
|
-
import { useEffect as
|
|
2801
|
+
import { useEffect as useEffect5, useState as useState4 } from "react";
|
|
2498
2802
|
import { fullyQualifiedId, getSpace } from "@dxos/react-client/echo";
|
|
2499
2803
|
import { useSelectionActions } from "@dxos/react-ui-attention";
|
|
2500
2804
|
import { isNonNullable } from "@dxos/util";
|
|
@@ -2502,7 +2806,7 @@ var useTableModel = ({ table, projection, rows, rowActions, features, onSelectio
|
|
|
2502
2806
|
var _effect = _useSignals9();
|
|
2503
2807
|
try {
|
|
2504
2808
|
const [model, setModel] = useState4();
|
|
2505
|
-
|
|
2809
|
+
useEffect5(() => {
|
|
2506
2810
|
if (!table || !projection) {
|
|
2507
2811
|
return;
|
|
2508
2812
|
}
|
|
@@ -2532,7 +2836,7 @@ var useTableModel = ({ table, projection, rows, rowActions, features, onSelectio
|
|
|
2532
2836
|
features,
|
|
2533
2837
|
rowActions
|
|
2534
2838
|
]);
|
|
2535
|
-
|
|
2839
|
+
useEffect5(() => {
|
|
2536
2840
|
if (rows) {
|
|
2537
2841
|
const sortedRows = orderBy2(rows, [
|
|
2538
2842
|
(row) => String(row.id)
|
|
@@ -2549,7 +2853,7 @@ var useTableModel = ({ table, projection, rows, rowActions, features, onSelectio
|
|
|
2549
2853
|
table?.id,
|
|
2550
2854
|
table?.view?.target?.query.typename
|
|
2551
2855
|
].filter(isNonNullable));
|
|
2552
|
-
|
|
2856
|
+
useEffect5(() => {
|
|
2553
2857
|
if (!model) {
|
|
2554
2858
|
return;
|
|
2555
2859
|
}
|
|
@@ -2574,7 +2878,27 @@ var useTableModel = ({ table, projection, rows, rowActions, features, onSelectio
|
|
|
2574
2878
|
}
|
|
2575
2879
|
};
|
|
2576
2880
|
|
|
2577
|
-
//
|
|
2881
|
+
// src/hooks/useAddRow.ts
|
|
2882
|
+
import { useCallback as useCallback6 } from "react";
|
|
2883
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
2884
|
+
var useAddRow = ({ space, schema }) => {
|
|
2885
|
+
return useCallback6((data) => {
|
|
2886
|
+
if (space && schema) {
|
|
2887
|
+
try {
|
|
2888
|
+
space.db.add(Obj3.make(schema, data ?? {}));
|
|
2889
|
+
return true;
|
|
2890
|
+
} catch (error) {
|
|
2891
|
+
return false;
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
return false;
|
|
2895
|
+
}, [
|
|
2896
|
+
space,
|
|
2897
|
+
schema
|
|
2898
|
+
]);
|
|
2899
|
+
};
|
|
2900
|
+
|
|
2901
|
+
// src/components/Table/DynamicTable.tsx
|
|
2578
2902
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
2579
2903
|
var _effect = _useSignals10();
|
|
2580
2904
|
try {
|
|
@@ -2596,10 +2920,10 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
2596
2920
|
jsonSchema
|
|
2597
2921
|
]);
|
|
2598
2922
|
const tableRef = useRef3(null);
|
|
2599
|
-
const handleCellUpdate =
|
|
2923
|
+
const handleCellUpdate = useCallback7((cell) => {
|
|
2600
2924
|
tableRef.current?.update?.(cell);
|
|
2601
2925
|
}, []);
|
|
2602
|
-
const handleRowOrderChange =
|
|
2926
|
+
const handleRowOrderChange = useCallback7(() => {
|
|
2603
2927
|
tableRef.current?.update?.();
|
|
2604
2928
|
}, []);
|
|
2605
2929
|
const features = useDefaultValue(props.features, () => ({
|
|
@@ -2643,7 +2967,7 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
2643
2967
|
}
|
|
2644
2968
|
};
|
|
2645
2969
|
|
|
2646
|
-
//
|
|
2970
|
+
// src/components/TableToolbar/TableToolbar.tsx
|
|
2647
2971
|
import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
|
|
2648
2972
|
import { Rx } from "@effect-rx/rx-react";
|
|
2649
2973
|
import React10, { useMemo as useMemo7 } from "react";
|
|
@@ -2744,7 +3068,8 @@ export {
|
|
|
2744
3068
|
tableButtons,
|
|
2745
3069
|
tableControls,
|
|
2746
3070
|
touch,
|
|
2747
|
-
|
|
3071
|
+
translations,
|
|
3072
|
+
useAddRow,
|
|
2748
3073
|
useTableModel
|
|
2749
3074
|
};
|
|
2750
3075
|
//# sourceMappingURL=index.mjs.map
|