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