@teselagen/ui 0.3.77 → 0.3.79
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/index.cjs.js +5362 -50834
- package/index.es.js +5359 -50831
- package/package.json +9 -4
- package/src/DataTable/dataTableEnhancer.js +2 -4
- package/src/DataTable/editCellHelper.js +10 -306
- package/src/DataTable/getCellVal.js +1 -4
- package/src/DataTable/index.js +192 -622
- package/src/FormComponents/tryToMatchSchemas.js +3 -9
- package/src/MatchHeaders.js +1 -1
- package/src/external_styles.js +3 -0
- package/src/index.js +0 -3
- package/src/showConfirmationDialog/index.js +2 -6
- package/src/toastr.js +3 -0
- package/style.css +1 -8819
- package/src/ExcelCell.js +0 -38
package/src/DataTable/index.js
CHANGED
|
@@ -29,8 +29,7 @@ import {
|
|
|
29
29
|
times,
|
|
30
30
|
some,
|
|
31
31
|
isFunction,
|
|
32
|
-
every
|
|
33
|
-
uniq
|
|
32
|
+
every
|
|
34
33
|
} from "lodash";
|
|
35
34
|
import joinUrl from "url-join";
|
|
36
35
|
|
|
@@ -45,8 +44,7 @@ import {
|
|
|
45
44
|
Popover,
|
|
46
45
|
Intent,
|
|
47
46
|
Callout,
|
|
48
|
-
Tooltip
|
|
49
|
-
Divider
|
|
47
|
+
Tooltip
|
|
50
48
|
} from "@blueprintjs/core";
|
|
51
49
|
import classNames from "classnames";
|
|
52
50
|
import scrollIntoView from "dom-scroll-into-view";
|
|
@@ -59,6 +57,7 @@ import ReactMarkdown from "react-markdown";
|
|
|
59
57
|
import immer, { produceWithPatches, enablePatches, applyPatches } from "immer";
|
|
60
58
|
import papaparse from "papaparse";
|
|
61
59
|
import remarkGfm from "remark-gfm";
|
|
60
|
+
|
|
62
61
|
import TgSelect from "../TgSelect";
|
|
63
62
|
import { withHotkeys } from "../utils/hotkeyUtils";
|
|
64
63
|
import InfoHelper from "../InfoHelper";
|
|
@@ -75,6 +74,7 @@ import SearchBar from "./SearchBar";
|
|
|
75
74
|
import DisplayOptions from "./DisplayOptions";
|
|
76
75
|
import DisabledLoadingComponent from "./DisabledLoadingComponent";
|
|
77
76
|
import SortableColumns from "./SortableColumns";
|
|
77
|
+
import computePresets from "./utils/computePresets";
|
|
78
78
|
import dataTableEnhancer from "./dataTableEnhancer";
|
|
79
79
|
import defaultProps from "./defaultProps";
|
|
80
80
|
|
|
@@ -86,16 +86,10 @@ import { CellDragHandle } from "./CellDragHandle";
|
|
|
86
86
|
import { nanoid } from "nanoid";
|
|
87
87
|
import { SwitchField } from "../FormComponents";
|
|
88
88
|
import { validateTableWideErrors } from "./validateTableWideErrors";
|
|
89
|
-
import {
|
|
90
|
-
editCellHelper,
|
|
91
|
-
getCellAlphaNumHelper,
|
|
92
|
-
getColLetFromIndex,
|
|
93
|
-
replaceFormulaRanges
|
|
94
|
-
} from "./editCellHelper";
|
|
89
|
+
import { editCellHelper } from "./editCellHelper";
|
|
95
90
|
import { getCellVal } from "./getCellVal";
|
|
96
91
|
import { getVals } from "./getVals";
|
|
97
92
|
import { throwFormError } from "../throwFormError";
|
|
98
|
-
import showConfirmationDialog from "../showConfirmationDialog";
|
|
99
93
|
enablePatches();
|
|
100
94
|
|
|
101
95
|
const PRIMARY_SELECTED_VAL = "main_cell";
|
|
@@ -227,10 +221,8 @@ class DataTable extends React.Component {
|
|
|
227
221
|
reduxFormEntitiesUndoRedoStack.currentVersion
|
|
228
222
|
].inversePatches
|
|
229
223
|
);
|
|
230
|
-
this.buildDepGraph(nextState);
|
|
231
224
|
const { newEnts, validationErrors } =
|
|
232
225
|
this.formatAndValidateEntities(nextState);
|
|
233
|
-
|
|
234
226
|
change("reduxFormEntities", newEnts);
|
|
235
227
|
this.updateValidation(newEnts, validationErrors);
|
|
236
228
|
change("reduxFormEntitiesUndoRedoStack", {
|
|
@@ -253,10 +245,8 @@ class DataTable extends React.Component {
|
|
|
253
245
|
entities,
|
|
254
246
|
reduxFormEntitiesUndoRedoStack[nextV].patches
|
|
255
247
|
);
|
|
256
|
-
this.buildDepGraph(nextState);
|
|
257
248
|
const { newEnts, validationErrors } =
|
|
258
249
|
this.formatAndValidateEntities(nextState);
|
|
259
|
-
|
|
260
250
|
change("reduxFormEntities", newEnts);
|
|
261
251
|
this.updateValidation(newEnts, validationErrors);
|
|
262
252
|
change("reduxFormEntitiesUndoRedoStack", {
|
|
@@ -409,16 +399,15 @@ class DataTable extends React.Component {
|
|
|
409
399
|
};
|
|
410
400
|
formatAndValidateEntities = (
|
|
411
401
|
entities,
|
|
412
|
-
{ useDefaultValues, indexToStartAt
|
|
402
|
+
{ useDefaultValues, indexToStartAt } = {}
|
|
413
403
|
) => {
|
|
414
|
-
const { schema
|
|
404
|
+
const { schema } = this.props;
|
|
415
405
|
const editableFields = schema.fields.filter(f => !f.isNotEditable);
|
|
416
406
|
const validationErrors = {};
|
|
417
|
-
|
|
418
|
-
const depGraph = depGraphToUse || this.depGraph;
|
|
407
|
+
|
|
419
408
|
const newEnts = immer(entities, entities => {
|
|
420
409
|
entities.forEach((e, index) => {
|
|
421
|
-
editableFields.forEach(
|
|
410
|
+
editableFields.forEach(columnSchema => {
|
|
422
411
|
if (useDefaultValues) {
|
|
423
412
|
if (e[columnSchema.path] === undefined) {
|
|
424
413
|
if (isFunction(columnSchema.defaultValue)) {
|
|
@@ -430,18 +419,15 @@ class DataTable extends React.Component {
|
|
|
430
419
|
}
|
|
431
420
|
}
|
|
432
421
|
//mutative
|
|
433
|
-
const {
|
|
434
|
-
_cellAlphaNum: getCellAlphaNumHelper(colIndex, index),
|
|
435
|
-
allowFormulas,
|
|
436
|
-
updateGroup,
|
|
437
|
-
depGraph,
|
|
438
|
-
entities,
|
|
422
|
+
const { error } = editCellHelper({
|
|
439
423
|
entity: e,
|
|
440
|
-
schema,
|
|
441
424
|
columnSchema,
|
|
442
425
|
newVal: e[columnSchema.path]
|
|
443
426
|
});
|
|
444
|
-
|
|
427
|
+
if (error) {
|
|
428
|
+
const rowId = getIdOrCodeOrIndex(e, index);
|
|
429
|
+
validationErrors[`${rowId}:${columnSchema.path}`] = error;
|
|
430
|
+
}
|
|
445
431
|
});
|
|
446
432
|
});
|
|
447
433
|
});
|
|
@@ -450,43 +436,6 @@ class DataTable extends React.Component {
|
|
|
450
436
|
validationErrors
|
|
451
437
|
};
|
|
452
438
|
};
|
|
453
|
-
buildDepGraph = ents => {
|
|
454
|
-
const { schema, allowFormulas } = this.props;
|
|
455
|
-
if (!allowFormulas) return;
|
|
456
|
-
const depGraph = {};
|
|
457
|
-
schema.fields.forEach((field, fi) => {
|
|
458
|
-
if (field.allowFormulas) {
|
|
459
|
-
ents.forEach((ent, i) => {
|
|
460
|
-
const val = ent[field.path];
|
|
461
|
-
const formula =
|
|
462
|
-
val &&
|
|
463
|
-
(val.formula || (typeof val === "string" && val[0] === "=" && val));
|
|
464
|
-
if (formula) {
|
|
465
|
-
const { replacedFormula } = replaceFormulaRanges({
|
|
466
|
-
formula,
|
|
467
|
-
entities: ents,
|
|
468
|
-
schema
|
|
469
|
-
});
|
|
470
|
-
const deps = replacedFormula.match(/[A-Z]+[0-9]+/gi);
|
|
471
|
-
if (deps) {
|
|
472
|
-
deps.forEach(_dep => {
|
|
473
|
-
const dep = _dep.toUpperCase();
|
|
474
|
-
|
|
475
|
-
if (!depGraph[dep]) {
|
|
476
|
-
depGraph[dep] = [];
|
|
477
|
-
}
|
|
478
|
-
// convert the field index to a letter
|
|
479
|
-
const fieldLetter = getColLetFromIndex(fi);
|
|
480
|
-
depGraph[dep].push(`${fieldLetter}${i + 1}`);
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
this.depGraph = depGraph;
|
|
488
|
-
};
|
|
489
|
-
|
|
490
439
|
formatAndValidateTableInitial = () => {
|
|
491
440
|
const {
|
|
492
441
|
_origEntities,
|
|
@@ -495,11 +444,10 @@ class DataTable extends React.Component {
|
|
|
495
444
|
change,
|
|
496
445
|
reduxFormCellValidation
|
|
497
446
|
} = this.props;
|
|
498
|
-
const
|
|
447
|
+
const { newEnts, validationErrors } = this.formatAndValidateEntities(
|
|
499
448
|
initialEntities ||
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
const { newEnts, validationErrors } = this.formatAndValidateEntities(ents);
|
|
449
|
+
(entities && entities.length ? entities : _origEntities)
|
|
450
|
+
);
|
|
503
451
|
change("reduxFormEntities", newEnts);
|
|
504
452
|
const toKeep = {};
|
|
505
453
|
//on the initial load we want to keep any async table wide errors
|
|
@@ -523,7 +471,7 @@ class DataTable extends React.Component {
|
|
|
523
471
|
setShowForcedHidden
|
|
524
472
|
} = this.props;
|
|
525
473
|
isCellEditable && this.formatAndValidateTableInitial();
|
|
526
|
-
this.updateFromProps({}, this.props);
|
|
474
|
+
this.updateFromProps({}, computePresets(this.props));
|
|
527
475
|
document.addEventListener("paste", this.handlePaste);
|
|
528
476
|
|
|
529
477
|
if (!entities.length && !isLoading && !showForcedHiddenColumns) {
|
|
@@ -551,7 +499,7 @@ class DataTable extends React.Component {
|
|
|
551
499
|
// }
|
|
552
500
|
// }
|
|
553
501
|
|
|
554
|
-
this.updateFromProps(oldProps, this.props);
|
|
502
|
+
this.updateFromProps(computePresets(oldProps), computePresets(this.props));
|
|
555
503
|
|
|
556
504
|
// comment in to test what is causing re-render
|
|
557
505
|
// Object.entries(this.props).forEach(
|
|
@@ -567,7 +515,7 @@ class DataTable extends React.Component {
|
|
|
567
515
|
handleRowMove = (type, shiftHeld) => e => {
|
|
568
516
|
e.preventDefault();
|
|
569
517
|
e.stopPropagation();
|
|
570
|
-
const props = this.props;
|
|
518
|
+
const props = computePresets(this.props);
|
|
571
519
|
const {
|
|
572
520
|
noSelect,
|
|
573
521
|
entities,
|
|
@@ -637,7 +585,9 @@ class DataTable extends React.Component {
|
|
|
637
585
|
});
|
|
638
586
|
};
|
|
639
587
|
handleCopyHotkey = e => {
|
|
640
|
-
const { isCellEditable, reduxFormSelectedEntityIdMap } =
|
|
588
|
+
const { isCellEditable, reduxFormSelectedEntityIdMap } = computePresets(
|
|
589
|
+
this.props
|
|
590
|
+
);
|
|
641
591
|
|
|
642
592
|
if (isCellEditable) {
|
|
643
593
|
this.handleCopySelectedCells(e);
|
|
@@ -665,10 +615,9 @@ class DataTable extends React.Component {
|
|
|
665
615
|
reduxFormCellValidation,
|
|
666
616
|
change,
|
|
667
617
|
schema,
|
|
668
|
-
entities
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
const updateGroup = {};
|
|
618
|
+
entities
|
|
619
|
+
} = computePresets(this.props);
|
|
620
|
+
|
|
672
621
|
if (isCellEditable) {
|
|
673
622
|
if (isEmpty(reduxFormSelectedCells)) return;
|
|
674
623
|
try {
|
|
@@ -681,8 +630,6 @@ class DataTable extends React.Component {
|
|
|
681
630
|
toPaste = e.clipboardData.getData("text/plain");
|
|
682
631
|
}
|
|
683
632
|
const jsonToPaste = e.clipboardData.getData("application/json");
|
|
684
|
-
let hasReplace = false;
|
|
685
|
-
|
|
686
633
|
try {
|
|
687
634
|
const pastedJson = [];
|
|
688
635
|
JSON.parse(jsonToPaste).forEach(row => {
|
|
@@ -703,14 +650,6 @@ class DataTable extends React.Component {
|
|
|
703
650
|
pasteData = pasteData.slice(1);
|
|
704
651
|
}
|
|
705
652
|
} catch (e) {
|
|
706
|
-
if (toPaste.includes("=") && allowFormulas) {
|
|
707
|
-
// replace any commas inside brackets with %%comma%% so that we can parse it out later
|
|
708
|
-
toPaste = toPaste.replace(/\(([^)]+)\)/g, match => {
|
|
709
|
-
hasReplace = true;
|
|
710
|
-
const toRet = match.replace(/,/g, "%%comma%%");
|
|
711
|
-
return toRet;
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
653
|
if (toPaste.includes(",")) {
|
|
715
654
|
//try papaparsing it out as a csv if it contains commas
|
|
716
655
|
try {
|
|
@@ -726,19 +665,11 @@ class DataTable extends React.Component {
|
|
|
726
665
|
}
|
|
727
666
|
}
|
|
728
667
|
pasteData = pasteData.length ? pasteData : defaultParsePaste(toPaste);
|
|
729
|
-
if (hasReplace) {
|
|
730
|
-
// put the commas back in
|
|
731
668
|
|
|
732
|
-
pasteData = pasteData.map(row => {
|
|
733
|
-
return row.map(cell => {
|
|
734
|
-
return cell.replace(/%%comma%%/g, ",");
|
|
735
|
-
});
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
669
|
if (!pasteData || !pasteData.length) return;
|
|
739
670
|
|
|
740
671
|
if (pasteData.length === 1 && pasteData[0].length === 1) {
|
|
741
|
-
|
|
672
|
+
const newCellValidate = {
|
|
742
673
|
...reduxFormCellValidation
|
|
743
674
|
};
|
|
744
675
|
// single paste value, fill all cells with value
|
|
@@ -750,29 +681,25 @@ class DataTable extends React.Component {
|
|
|
750
681
|
|
|
751
682
|
const entity = entityIdToEntity[rowId].e;
|
|
752
683
|
delete entity._isClean;
|
|
753
|
-
const {
|
|
754
|
-
allowFormulas,
|
|
755
|
-
updateGroup,
|
|
756
|
-
depGraph: this.depGraph,
|
|
757
|
-
entities,
|
|
684
|
+
const { error } = editCellHelper({
|
|
758
685
|
entity,
|
|
759
686
|
path,
|
|
760
687
|
schema,
|
|
761
688
|
newVal: formatPasteData({ newVal, path, schema })
|
|
762
689
|
});
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
690
|
+
if (error) {
|
|
691
|
+
newCellValidate[cellId] = error;
|
|
692
|
+
} else {
|
|
693
|
+
delete newCellValidate[cellId];
|
|
694
|
+
}
|
|
767
695
|
});
|
|
768
|
-
this.buildDepGraph(entities);
|
|
769
696
|
this.updateValidation(entities, newCellValidate);
|
|
770
697
|
});
|
|
771
698
|
} else {
|
|
772
699
|
// handle paste in same format
|
|
773
700
|
const primarySelectedCell = this.getPrimarySelectedCellId();
|
|
774
701
|
if (primarySelectedCell) {
|
|
775
|
-
|
|
702
|
+
const newCellValidate = {
|
|
776
703
|
...reduxFormCellValidation
|
|
777
704
|
};
|
|
778
705
|
|
|
@@ -801,11 +728,7 @@ class DataTable extends React.Component {
|
|
|
801
728
|
delete entity._isClean;
|
|
802
729
|
const path = indexToPath[cellIndexToChange];
|
|
803
730
|
if (path) {
|
|
804
|
-
const {
|
|
805
|
-
allowFormulas,
|
|
806
|
-
updateGroup,
|
|
807
|
-
depGraph: this.depGraph,
|
|
808
|
-
entities,
|
|
731
|
+
const { error } = editCellHelper({
|
|
809
732
|
entity,
|
|
810
733
|
path,
|
|
811
734
|
schema,
|
|
@@ -819,16 +742,16 @@ class DataTable extends React.Component {
|
|
|
819
742
|
if (!newSelectedCells[cellId]) {
|
|
820
743
|
newSelectedCells[cellId] = true;
|
|
821
744
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
745
|
+
if (error) {
|
|
746
|
+
newCellValidate[cellId] = error;
|
|
747
|
+
} else {
|
|
748
|
+
delete newCellValidate[cellId];
|
|
749
|
+
}
|
|
826
750
|
}
|
|
827
751
|
}
|
|
828
752
|
}
|
|
829
753
|
});
|
|
830
754
|
});
|
|
831
|
-
this.buildDepGraph(entities);
|
|
832
755
|
this.updateValidation(entities, newCellValidate);
|
|
833
756
|
});
|
|
834
757
|
change("reduxFormSelectedCells", newSelectedCells);
|
|
@@ -847,7 +770,7 @@ class DataTable extends React.Component {
|
|
|
847
770
|
isSingleSelect,
|
|
848
771
|
isCellEditable,
|
|
849
772
|
schema
|
|
850
|
-
} = this.props;
|
|
773
|
+
} = computePresets(this.props);
|
|
851
774
|
if (isSingleSelect) return;
|
|
852
775
|
e.preventDefault();
|
|
853
776
|
|
|
@@ -873,17 +796,17 @@ class DataTable extends React.Component {
|
|
|
873
796
|
finalizeSelection({
|
|
874
797
|
idMap: newIdMap,
|
|
875
798
|
entities,
|
|
876
|
-
props: this.props
|
|
799
|
+
props: computePresets(this.props)
|
|
877
800
|
});
|
|
878
801
|
}
|
|
879
802
|
};
|
|
880
803
|
updateValidationHelper = () => {
|
|
881
|
-
const { entities, reduxFormCellValidation } = this.props;
|
|
804
|
+
const { entities, reduxFormCellValidation } = computePresets(this.props);
|
|
882
805
|
this.updateValidation(entities, reduxFormCellValidation);
|
|
883
806
|
};
|
|
884
807
|
|
|
885
808
|
updateValidation = (entities, newCellValidate) => {
|
|
886
|
-
const { change, schema } = this.props;
|
|
809
|
+
const { change, schema } = computePresets(this.props);
|
|
887
810
|
const tableWideErr = validateTableWideErrors({
|
|
888
811
|
entities,
|
|
889
812
|
schema,
|
|
@@ -898,15 +821,12 @@ class DataTable extends React.Component {
|
|
|
898
821
|
reduxFormSelectedCells,
|
|
899
822
|
reduxFormCellValidation,
|
|
900
823
|
schema,
|
|
901
|
-
entities
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
let newCellValidate = {
|
|
824
|
+
entities
|
|
825
|
+
} = computePresets(this.props);
|
|
826
|
+
const newCellValidate = {
|
|
905
827
|
...reduxFormCellValidation
|
|
906
828
|
};
|
|
907
829
|
if (isEmpty(reduxFormSelectedCells)) return;
|
|
908
|
-
const updateGroup = {};
|
|
909
|
-
|
|
910
830
|
const rowIds = [];
|
|
911
831
|
this.updateEntitiesHelper(entities, entities => {
|
|
912
832
|
const entityIdToEntity = getEntityIdToEntity(entities);
|
|
@@ -915,22 +835,18 @@ class DataTable extends React.Component {
|
|
|
915
835
|
rowIds.push(rowId);
|
|
916
836
|
const entity = entityIdToEntity[rowId].e;
|
|
917
837
|
delete entity._isClean;
|
|
918
|
-
const {
|
|
919
|
-
allowFormulas,
|
|
920
|
-
updateGroup,
|
|
921
|
-
depGraph: this.depGraph,
|
|
922
|
-
entities,
|
|
838
|
+
const { error } = editCellHelper({
|
|
923
839
|
entity,
|
|
924
840
|
path,
|
|
925
841
|
schema,
|
|
926
842
|
newVal: ""
|
|
927
843
|
});
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
844
|
+
if (error) {
|
|
845
|
+
newCellValidate[cellId] = error;
|
|
846
|
+
} else {
|
|
847
|
+
delete newCellValidate[cellId];
|
|
848
|
+
}
|
|
932
849
|
});
|
|
933
|
-
this.buildDepGraph(entities);
|
|
934
850
|
this.updateValidation(entities, newCellValidate);
|
|
935
851
|
});
|
|
936
852
|
};
|
|
@@ -940,17 +856,16 @@ class DataTable extends React.Component {
|
|
|
940
856
|
this.handleCopyHotkey(e);
|
|
941
857
|
};
|
|
942
858
|
|
|
943
|
-
getCellCopyText =
|
|
944
|
-
// note - all copy/download functions use this helper to get the text to copy
|
|
859
|
+
getCellCopyText = cellWrapper => {
|
|
945
860
|
const text = cellWrapper && cellWrapper.getAttribute("data-copy-text");
|
|
946
|
-
const formula = cellWrapper && cellWrapper.getAttribute("data-formula");
|
|
947
861
|
const jsonText = cellWrapper && cellWrapper.getAttribute("data-copy-json");
|
|
862
|
+
|
|
948
863
|
const textContent = text || cellWrapper.textContent || "";
|
|
949
|
-
return [
|
|
864
|
+
return [textContent, jsonText];
|
|
950
865
|
};
|
|
951
866
|
|
|
952
|
-
handleCopyColumn = (
|
|
953
|
-
const specificColumn = cellWrapper.getAttribute("data-
|
|
867
|
+
handleCopyColumn = (e, cellWrapper, selectedRecords) => {
|
|
868
|
+
const specificColumn = cellWrapper.getAttribute("data-test");
|
|
954
869
|
let rowElsToCopy = getAllRows(e);
|
|
955
870
|
if (!rowElsToCopy) return;
|
|
956
871
|
if (selectedRecords) {
|
|
@@ -963,21 +878,17 @@ class DataTable extends React.Component {
|
|
|
963
878
|
if (!rowElsToCopy) return;
|
|
964
879
|
this.handleCopyRows(rowElsToCopy, {
|
|
965
880
|
specificColumn,
|
|
966
|
-
onFinishMsg: "Column Copied"
|
|
967
|
-
...opts
|
|
881
|
+
onFinishMsg: "Column Copied"
|
|
968
882
|
});
|
|
969
883
|
};
|
|
970
884
|
handleCopyRows = (
|
|
971
885
|
rowElsToCopy,
|
|
972
|
-
{ specificColumn, onFinishMsg, isDownload
|
|
886
|
+
{ specificColumn, onFinishMsg, isDownload } = {}
|
|
973
887
|
) => {
|
|
974
888
|
let textToCopy = [];
|
|
975
889
|
const jsonToCopy = [];
|
|
976
890
|
forEach(rowElsToCopy, rowEl => {
|
|
977
|
-
const [t, j] = this.getRowCopyText(rowEl, {
|
|
978
|
-
specificColumn,
|
|
979
|
-
isFormulaCopy
|
|
980
|
-
});
|
|
891
|
+
const [t, j] = this.getRowCopyText(rowEl, { specificColumn });
|
|
981
892
|
textToCopy.push(t);
|
|
982
893
|
jsonToCopy.push(j);
|
|
983
894
|
});
|
|
@@ -998,7 +909,6 @@ class DataTable extends React.Component {
|
|
|
998
909
|
this.props;
|
|
999
910
|
const [nextState, patches, inversePatches] = produceWithPatches(ents, fn);
|
|
1000
911
|
if (!inversePatches.length) return;
|
|
1001
|
-
|
|
1002
912
|
const thatNewNew = [...nextState];
|
|
1003
913
|
thatNewNew.isDirty = true;
|
|
1004
914
|
change("reduxFormEntities", thatNewNew);
|
|
@@ -1014,7 +924,7 @@ class DataTable extends React.Component {
|
|
|
1014
924
|
});
|
|
1015
925
|
};
|
|
1016
926
|
|
|
1017
|
-
getRowCopyText = (rowEl, { specificColumn
|
|
927
|
+
getRowCopyText = (rowEl, { specificColumn } = {}) => {
|
|
1018
928
|
//takes in a row element
|
|
1019
929
|
if (!rowEl) return [];
|
|
1020
930
|
const textContent = [];
|
|
@@ -1028,11 +938,11 @@ class DataTable extends React.Component {
|
|
|
1028
938
|
}
|
|
1029
939
|
if (
|
|
1030
940
|
specificColumn &&
|
|
1031
|
-
cellChild.getAttribute("data-
|
|
941
|
+
cellChild.getAttribute("data-test") !== specificColumn
|
|
1032
942
|
) {
|
|
1033
943
|
return [];
|
|
1034
944
|
}
|
|
1035
|
-
const [t, j] = this.getCellCopyText(cellChild
|
|
945
|
+
const [t, j] = this.getCellCopyText(cellChild);
|
|
1036
946
|
textContent.push(t);
|
|
1037
947
|
jsonText.push(j);
|
|
1038
948
|
});
|
|
@@ -1041,15 +951,10 @@ class DataTable extends React.Component {
|
|
|
1041
951
|
};
|
|
1042
952
|
|
|
1043
953
|
handleCopyHelper = (stringToCopy, jsonToCopy, message) => {
|
|
1044
|
-
const jToC = JSON.stringify(jsonToCopy);
|
|
1045
|
-
if (window.Cypress) {
|
|
1046
|
-
window.Cypress.__savedClipboardData = stringToCopy;
|
|
1047
|
-
window.Cypress.__savedClipboardDataJson = jToC;
|
|
1048
|
-
}
|
|
1049
954
|
!window.Cypress &&
|
|
1050
955
|
copy(stringToCopy, {
|
|
1051
956
|
onCopy: clipboardData => {
|
|
1052
|
-
clipboardData.setData("application/json",
|
|
957
|
+
clipboardData.setData("application/json", JSON.stringify(jsonToCopy));
|
|
1053
958
|
},
|
|
1054
959
|
// keep this so that pasting into spreadsheets works.
|
|
1055
960
|
format: "text/plain"
|
|
@@ -1059,10 +964,9 @@ class DataTable extends React.Component {
|
|
|
1059
964
|
}
|
|
1060
965
|
};
|
|
1061
966
|
|
|
1062
|
-
handleCopyTable = (e, opts
|
|
967
|
+
handleCopyTable = (e, opts) => {
|
|
1063
968
|
try {
|
|
1064
|
-
|
|
1065
|
-
if (opts.noHeader) allRowEls = [...allRowEls].slice(1);
|
|
969
|
+
const allRowEls = getAllRows(e);
|
|
1066
970
|
if (!allRowEls) return;
|
|
1067
971
|
this.handleCopyRows(allRowEls, {
|
|
1068
972
|
...opts,
|
|
@@ -1073,12 +977,15 @@ class DataTable extends React.Component {
|
|
|
1073
977
|
window.toastr.error("Error copying rows.");
|
|
1074
978
|
}
|
|
1075
979
|
};
|
|
1076
|
-
handleCopySelectedCells =
|
|
1077
|
-
const {
|
|
980
|
+
handleCopySelectedCells = e => {
|
|
981
|
+
const {
|
|
982
|
+
entities = [],
|
|
983
|
+
reduxFormSelectedCells,
|
|
984
|
+
schema
|
|
985
|
+
} = computePresets(this.props);
|
|
1078
986
|
// if the current selection is consecutive cells then copy with
|
|
1079
987
|
// tabs between. if not then just select primary selected cell
|
|
1080
|
-
|
|
1081
|
-
if (isEmpty(reduxFormSelectedCells)) return getEmptyMsg();
|
|
988
|
+
if (isEmpty(reduxFormSelectedCells)) return;
|
|
1082
989
|
const pathToIndex = getFieldPathToIndex(schema);
|
|
1083
990
|
const entityIdToEntity = getEntityIdToEntity(entities);
|
|
1084
991
|
const selectionGrid = [];
|
|
@@ -1101,7 +1008,7 @@ class DataTable extends React.Component {
|
|
|
1101
1008
|
selectionGrid[eInfo.i][cellIndex] = true;
|
|
1102
1009
|
}
|
|
1103
1010
|
});
|
|
1104
|
-
if (firstRowIndex === undefined) return
|
|
1011
|
+
if (firstRowIndex === undefined) return;
|
|
1105
1012
|
const allRows = getAllRows(e);
|
|
1106
1013
|
let fullCellText = "";
|
|
1107
1014
|
const fullJson = [];
|
|
@@ -1115,7 +1022,7 @@ class DataTable extends React.Component {
|
|
|
1115
1022
|
} else {
|
|
1116
1023
|
const jsonRow = [];
|
|
1117
1024
|
// ignore header
|
|
1118
|
-
let [rowCopyText, json] = this.getRowCopyText(allRows[i + 1]
|
|
1025
|
+
let [rowCopyText, json] = this.getRowCopyText(allRows[i + 1]);
|
|
1119
1026
|
rowCopyText = rowCopyText.split("\t");
|
|
1120
1027
|
times(row.length, i => {
|
|
1121
1028
|
const cell = row[i];
|
|
@@ -1128,17 +1035,13 @@ class DataTable extends React.Component {
|
|
|
1128
1035
|
fullJson.push(jsonRow);
|
|
1129
1036
|
}
|
|
1130
1037
|
});
|
|
1131
|
-
if (!fullCellText) return
|
|
1038
|
+
if (!fullCellText) return window.toastr.warning("No text to copy");
|
|
1132
1039
|
|
|
1133
|
-
this.handleCopyHelper(
|
|
1134
|
-
fullCellText,
|
|
1135
|
-
fullJson,
|
|
1136
|
-
`Selected cell${Object.values(reduxFormSelectedCells).length === 1 ? "" : "s"} copied`
|
|
1137
|
-
);
|
|
1040
|
+
this.handleCopyHelper(fullCellText, fullJson, "Selected cells copied");
|
|
1138
1041
|
};
|
|
1139
1042
|
|
|
1140
|
-
handleCopySelectedRows = (selectedRecords, e
|
|
1141
|
-
const { entities = [] } = this.props;
|
|
1043
|
+
handleCopySelectedRows = (selectedRecords, e) => {
|
|
1044
|
+
const { entities = [] } = computePresets(this.props);
|
|
1142
1045
|
const idToIndex = entities.reduce((acc, e, i) => {
|
|
1143
1046
|
acc[e.id || e.code] = i;
|
|
1144
1047
|
return acc;
|
|
@@ -1158,8 +1061,7 @@ class DataTable extends React.Component {
|
|
|
1158
1061
|
const rowEls = rowNumbersToCopy.map(i => allRowEls[i]);
|
|
1159
1062
|
|
|
1160
1063
|
this.handleCopyRows(rowEls, {
|
|
1161
|
-
onFinishMsg: "Selected rows copied"
|
|
1162
|
-
...opts
|
|
1064
|
+
onFinishMsg: "Selected rows copied"
|
|
1163
1065
|
});
|
|
1164
1066
|
} catch (error) {
|
|
1165
1067
|
console.error(`error:`, error);
|
|
@@ -1198,7 +1100,7 @@ class DataTable extends React.Component {
|
|
|
1198
1100
|
moveColumnPersist,
|
|
1199
1101
|
syncDisplayOptionsToDb,
|
|
1200
1102
|
change
|
|
1201
|
-
} = this.props;
|
|
1103
|
+
} = computePresets(this.props);
|
|
1202
1104
|
let moveColumnPersistToUse = moveColumnPersist;
|
|
1203
1105
|
if (moveColumnPersist && withDisplayOptions && !syncDisplayOptionsToDb) {
|
|
1204
1106
|
//little hack to make localstorage changes get reflected in UI (we force an update to get the enhancers to run again :)
|
|
@@ -1236,7 +1138,7 @@ class DataTable extends React.Component {
|
|
|
1236
1138
|
));
|
|
1237
1139
|
|
|
1238
1140
|
addEntitiesToSelection = entities => {
|
|
1239
|
-
const propPresets = this.props;
|
|
1141
|
+
const propPresets = computePresets(this.props);
|
|
1240
1142
|
const { isEntityDisabled, reduxFormSelectedEntityIdMap } = propPresets;
|
|
1241
1143
|
const idMap = reduxFormSelectedEntityIdMap || {};
|
|
1242
1144
|
const newIdMap = cloneDeep(idMap) || {};
|
|
@@ -1254,7 +1156,7 @@ class DataTable extends React.Component {
|
|
|
1254
1156
|
|
|
1255
1157
|
render() {
|
|
1256
1158
|
const { fullscreen } = this.state;
|
|
1257
|
-
const propPresets = this.props;
|
|
1159
|
+
const propPresets = computePresets(this.props);
|
|
1258
1160
|
const {
|
|
1259
1161
|
extraClasses,
|
|
1260
1162
|
className,
|
|
@@ -1577,13 +1479,16 @@ class DataTable extends React.Component {
|
|
|
1577
1479
|
// if (isArrowKey && e.target?.tagName !== "INPUT") {
|
|
1578
1480
|
const isTabKey = e.keyCode === 9;
|
|
1579
1481
|
// const isEnter = e.keyCode === 13;
|
|
1482
|
+
// console.log(`onKeydown datatable inner`);
|
|
1483
|
+
// console.log(`isEnter:`, isEnter)
|
|
1580
1484
|
const isArrowKey = e.keyCode >= 37 && e.keyCode <= 40;
|
|
1485
|
+
// console.log(`e.target?.tagName:`,e.target?.tagName)
|
|
1581
1486
|
if (
|
|
1582
1487
|
(isArrowKey && e.target?.tagName !== "INPUT") ||
|
|
1583
1488
|
isTabKey
|
|
1584
1489
|
// || (isEnter && e.target?.tagName === "INPUT")
|
|
1585
1490
|
) {
|
|
1586
|
-
const { schema, entities } = this.props;
|
|
1491
|
+
const { schema, entities } = computePresets(this.props);
|
|
1587
1492
|
const left = e.keyCode === 37;
|
|
1588
1493
|
const up = e.keyCode === 38;
|
|
1589
1494
|
const down = e.keyCode === 40 || e.keyCode === 13;
|
|
@@ -1681,8 +1586,7 @@ class DataTable extends React.Component {
|
|
|
1681
1586
|
const rowDisabled = isEntityDisabled(entity);
|
|
1682
1587
|
const isNum = e.keyCode >= 48 && e.keyCode <= 57;
|
|
1683
1588
|
const isLetter = e.keyCode >= 65 && e.keyCode <= 90;
|
|
1684
|
-
|
|
1685
|
-
if (!isNum && !isLetter && !isEqlSign) return;
|
|
1589
|
+
if (!isNum && !isLetter) return;
|
|
1686
1590
|
if (rowDisabled) return;
|
|
1687
1591
|
this.startCellEdit(cellId, { shouldSelectAll: true });
|
|
1688
1592
|
e.stopPropagation();
|
|
@@ -1818,7 +1722,7 @@ class DataTable extends React.Component {
|
|
|
1818
1722
|
finalizeSelection({
|
|
1819
1723
|
idMap: {},
|
|
1820
1724
|
entities,
|
|
1821
|
-
props: this.props
|
|
1725
|
+
props: computePresets(this.props)
|
|
1822
1726
|
});
|
|
1823
1727
|
}}
|
|
1824
1728
|
/>
|
|
@@ -1977,7 +1881,7 @@ class DataTable extends React.Component {
|
|
|
1977
1881
|
change,
|
|
1978
1882
|
getRowClassName,
|
|
1979
1883
|
isCellEditable
|
|
1980
|
-
} = this.props;
|
|
1884
|
+
} = computePresets(this.props);
|
|
1981
1885
|
if (!rowInfo) {
|
|
1982
1886
|
return {
|
|
1983
1887
|
className: "no-row-data"
|
|
@@ -2009,7 +1913,7 @@ class DataTable extends React.Component {
|
|
|
2009
1913
|
if (e.detail > 1) {
|
|
2010
1914
|
return; //cancel multiple quick clicks
|
|
2011
1915
|
}
|
|
2012
|
-
rowClick(e, rowInfo, entities, this.props);
|
|
1916
|
+
rowClick(e, rowInfo, entities, computePresets(this.props));
|
|
2013
1917
|
},
|
|
2014
1918
|
//row right click
|
|
2015
1919
|
onContextMenu: e => {
|
|
@@ -2036,7 +1940,7 @@ class DataTable extends React.Component {
|
|
|
2036
1940
|
finalizeSelection({
|
|
2037
1941
|
idMap: newIdMap,
|
|
2038
1942
|
entities,
|
|
2039
|
-
props: this.props
|
|
1943
|
+
props: computePresets(this.props)
|
|
2040
1944
|
});
|
|
2041
1945
|
}
|
|
2042
1946
|
this.showContextMenu(e, newIdMap);
|
|
@@ -2066,7 +1970,7 @@ class DataTable extends React.Component {
|
|
|
2066
1970
|
change,
|
|
2067
1971
|
reduxFormSelectedCells = {},
|
|
2068
1972
|
reduxFormEditingCell
|
|
2069
|
-
} = this.props;
|
|
1973
|
+
} = computePresets(this.props);
|
|
2070
1974
|
const newSelectedCells = { ...reduxFormSelectedCells };
|
|
2071
1975
|
newSelectedCells[cellId] = PRIMARY_SELECTED_VAL;
|
|
2072
1976
|
//check if the cell is already selected and editing and if so, don't change it
|
|
@@ -2090,7 +1994,7 @@ class DataTable extends React.Component {
|
|
|
2090
1994
|
reduxFormSelectedCells = {},
|
|
2091
1995
|
isEntityDisabled,
|
|
2092
1996
|
change
|
|
2093
|
-
} = this.props;
|
|
1997
|
+
} = computePresets(this.props);
|
|
2094
1998
|
if (!isCellEditable) return {}; //only allow cell selection to do stuff here
|
|
2095
1999
|
if (!rowInfo) return {};
|
|
2096
2000
|
const entity = rowInfo.original;
|
|
@@ -2102,7 +2006,8 @@ class DataTable extends React.Component {
|
|
|
2102
2006
|
cellIdToRight,
|
|
2103
2007
|
cellIdBelow,
|
|
2104
2008
|
cellIdToLeft,
|
|
2105
|
-
rowDisabled
|
|
2009
|
+
rowDisabled,
|
|
2010
|
+
columnIndex
|
|
2106
2011
|
} = getCellInfo({
|
|
2107
2012
|
columnIndex: column.index,
|
|
2108
2013
|
columnPath: column.path,
|
|
@@ -2122,18 +2027,18 @@ class DataTable extends React.Component {
|
|
|
2122
2027
|
selectedRightBorder,
|
|
2123
2028
|
selectedBottomBorder,
|
|
2124
2029
|
selectedLeftBorder;
|
|
2125
|
-
|
|
2126
|
-
if (isSelected) {
|
|
2030
|
+
if (reduxFormSelectedCells[cellId]) {
|
|
2127
2031
|
selectedTopBorder = !reduxFormSelectedCells[cellIdAbove];
|
|
2128
2032
|
selectedRightBorder = !reduxFormSelectedCells[cellIdToRight];
|
|
2129
2033
|
selectedBottomBorder = !reduxFormSelectedCells[cellIdBelow];
|
|
2130
2034
|
selectedLeftBorder = !reduxFormSelectedCells[cellIdToLeft];
|
|
2131
2035
|
}
|
|
2132
|
-
const isPrimarySelected =
|
|
2036
|
+
const isPrimarySelected =
|
|
2037
|
+
reduxFormSelectedCells[cellId] === PRIMARY_SELECTED_VAL;
|
|
2133
2038
|
const className = classNames({
|
|
2134
|
-
isSelectedCell:
|
|
2039
|
+
isSelectedCell: reduxFormSelectedCells[cellId],
|
|
2135
2040
|
isPrimarySelected,
|
|
2136
|
-
isSecondarySelected:
|
|
2041
|
+
isSecondarySelected: reduxFormSelectedCells[cellId] === true,
|
|
2137
2042
|
noSelectedTopBorder: !selectedTopBorder,
|
|
2138
2043
|
isCleanRow: _isClean,
|
|
2139
2044
|
noSelectedRightBorder: !selectedRightBorder,
|
|
@@ -2142,12 +2047,8 @@ class DataTable extends React.Component {
|
|
|
2142
2047
|
isDropdownCell: column.type === "dropdown",
|
|
2143
2048
|
isEditingCell: reduxFormEditingCell === cellId,
|
|
2144
2049
|
hasCellError: !!err,
|
|
2145
|
-
"no-data-tip":
|
|
2050
|
+
"no-data-tip": reduxFormSelectedCells[cellId]
|
|
2146
2051
|
});
|
|
2147
|
-
const clickProps = {
|
|
2148
|
-
isRowIndexColumn: column.isRowIndexColumn,
|
|
2149
|
-
cellId
|
|
2150
|
-
};
|
|
2151
2052
|
return {
|
|
2152
2053
|
onDoubleClick: () => {
|
|
2153
2054
|
// cell double click
|
|
@@ -2159,12 +2060,7 @@ class DataTable extends React.Component {
|
|
|
2159
2060
|
"data-no-child-data-tip": true
|
|
2160
2061
|
}),
|
|
2161
2062
|
onContextMenu: e => {
|
|
2162
|
-
if (!
|
|
2163
|
-
this.handleCellClick({
|
|
2164
|
-
event: e,
|
|
2165
|
-
...clickProps
|
|
2166
|
-
});
|
|
2167
|
-
} else if (!isPrimarySelected) {
|
|
2063
|
+
if (!isPrimarySelected) {
|
|
2168
2064
|
const primaryCellId = this.getPrimarySelectedCellId();
|
|
2169
2065
|
const newSelectedCells = { ...reduxFormSelectedCells };
|
|
2170
2066
|
if (primaryCellId) {
|
|
@@ -2181,14 +2077,17 @@ class DataTable extends React.Component {
|
|
|
2181
2077
|
onClick: event => {
|
|
2182
2078
|
this.handleCellClick({
|
|
2183
2079
|
event,
|
|
2184
|
-
|
|
2080
|
+
cellId,
|
|
2081
|
+
rowDisabled,
|
|
2082
|
+
rowIndex,
|
|
2083
|
+
columnIndex
|
|
2185
2084
|
});
|
|
2186
2085
|
},
|
|
2187
2086
|
className
|
|
2188
2087
|
};
|
|
2189
2088
|
};
|
|
2190
2089
|
|
|
2191
|
-
handleCellClick = ({ event, cellId
|
|
2090
|
+
handleCellClick = ({ event, cellId }) => {
|
|
2192
2091
|
if (!cellId) return;
|
|
2193
2092
|
// cell click, cellclick
|
|
2194
2093
|
const {
|
|
@@ -2198,7 +2097,7 @@ class DataTable extends React.Component {
|
|
|
2198
2097
|
reduxFormEditingCell,
|
|
2199
2098
|
reduxFormSelectedCells = {},
|
|
2200
2099
|
isEntityDisabled
|
|
2201
|
-
} = this.props;
|
|
2100
|
+
} = computePresets(this.props);
|
|
2202
2101
|
const [rowId, cellPath] = cellId.split(":");
|
|
2203
2102
|
const entityMap = getEntityIdToEntity(entities);
|
|
2204
2103
|
const { e: entity, i: rowIndex } = entityMap[rowId];
|
|
@@ -2207,36 +2106,10 @@ class DataTable extends React.Component {
|
|
|
2207
2106
|
const rowDisabled = isEntityDisabled(entity);
|
|
2208
2107
|
|
|
2209
2108
|
if (rowDisabled) return;
|
|
2210
|
-
|
|
2211
2109
|
let newSelectedCells = {
|
|
2212
2110
|
...reduxFormSelectedCells
|
|
2213
2111
|
};
|
|
2214
|
-
if (
|
|
2215
|
-
// it's like the whole row is being selected
|
|
2216
|
-
let isThereAnUnselectedCell = false;
|
|
2217
|
-
const allCellsInRow = {};
|
|
2218
|
-
schema.fields.forEach(f => {
|
|
2219
|
-
const toSelectId = `${rowId}:${f.path}`;
|
|
2220
|
-
if (!reduxFormSelectedCells[toSelectId]) {
|
|
2221
|
-
isThereAnUnselectedCell = true;
|
|
2222
|
-
}
|
|
2223
|
-
allCellsInRow[toSelectId] = true;
|
|
2224
|
-
});
|
|
2225
|
-
if (event.metaKey || event.shiftKey) {
|
|
2226
|
-
if (isThereAnUnselectedCell) {
|
|
2227
|
-
newSelectedCells = {
|
|
2228
|
-
...newSelectedCells,
|
|
2229
|
-
...allCellsInRow
|
|
2230
|
-
};
|
|
2231
|
-
} else {
|
|
2232
|
-
forEach(allCellsInRow, (c, key) => {
|
|
2233
|
-
delete newSelectedCells[key];
|
|
2234
|
-
});
|
|
2235
|
-
}
|
|
2236
|
-
} else {
|
|
2237
|
-
newSelectedCells = allCellsInRow;
|
|
2238
|
-
}
|
|
2239
|
-
} else if (newSelectedCells[cellId] && !event.shiftKey) {
|
|
2112
|
+
if (newSelectedCells[cellId] && !event.shiftKey) {
|
|
2240
2113
|
// don't deselect if editing
|
|
2241
2114
|
if (reduxFormEditingCell === cellId) return;
|
|
2242
2115
|
if (event.metaKey) {
|
|
@@ -2313,7 +2186,7 @@ class DataTable extends React.Component {
|
|
|
2313
2186
|
noUserSelect,
|
|
2314
2187
|
entities,
|
|
2315
2188
|
isEntityDisabled
|
|
2316
|
-
} = this.props;
|
|
2189
|
+
} = computePresets(this.props);
|
|
2317
2190
|
const checkedRows = getSelectedRowsFromEntities(
|
|
2318
2191
|
entities,
|
|
2319
2192
|
reduxFormSelectedEntityIdMap
|
|
@@ -2353,7 +2226,7 @@ class DataTable extends React.Component {
|
|
|
2353
2226
|
finalizeSelection({
|
|
2354
2227
|
idMap: newIdMap,
|
|
2355
2228
|
entities,
|
|
2356
|
-
props: this.props
|
|
2229
|
+
props: computePresets(this.props)
|
|
2357
2230
|
});
|
|
2358
2231
|
}}
|
|
2359
2232
|
/* eslint-enable react/jsx-no-bind */
|
|
@@ -2370,7 +2243,7 @@ class DataTable extends React.Component {
|
|
|
2370
2243
|
noUserSelect,
|
|
2371
2244
|
entities,
|
|
2372
2245
|
isEntityDisabled
|
|
2373
|
-
} = this.props;
|
|
2246
|
+
} = computePresets(this.props);
|
|
2374
2247
|
const checkedRows = getSelectedRowsFromEntities(
|
|
2375
2248
|
entities,
|
|
2376
2249
|
reduxFormSelectedEntityIdMap
|
|
@@ -2387,7 +2260,7 @@ class DataTable extends React.Component {
|
|
|
2387
2260
|
<Checkbox
|
|
2388
2261
|
disabled={noSelect || noUserSelect || isEntityDisabled(entity)}
|
|
2389
2262
|
onClick={e => {
|
|
2390
|
-
rowClick(e, row, entities, this.props);
|
|
2263
|
+
rowClick(e, row, entities, computePresets(this.props));
|
|
2391
2264
|
}}
|
|
2392
2265
|
checked={isSelected}
|
|
2393
2266
|
/>
|
|
@@ -2399,11 +2272,8 @@ class DataTable extends React.Component {
|
|
|
2399
2272
|
entities = [],
|
|
2400
2273
|
change,
|
|
2401
2274
|
schema,
|
|
2402
|
-
reduxFormCellValidation
|
|
2403
|
-
|
|
2404
|
-
} = this.props;
|
|
2405
|
-
const updateGroup = {};
|
|
2406
|
-
|
|
2275
|
+
reduxFormCellValidation
|
|
2276
|
+
} = computePresets(this.props);
|
|
2407
2277
|
const [rowId, path] = cellId.split(":");
|
|
2408
2278
|
!doNotStopEditing && change("reduxFormEditingCell", null);
|
|
2409
2279
|
this.updateEntitiesHelper(entities, entities => {
|
|
@@ -2411,33 +2281,22 @@ class DataTable extends React.Component {
|
|
|
2411
2281
|
return getIdOrCodeOrIndex(e, i) === rowId;
|
|
2412
2282
|
});
|
|
2413
2283
|
delete entity._isClean;
|
|
2414
|
-
const {
|
|
2415
|
-
allowFormulas,
|
|
2416
|
-
updateGroup,
|
|
2417
|
-
depGraph: this.depGraph,
|
|
2418
|
-
entities,
|
|
2284
|
+
const { error } = editCellHelper({
|
|
2419
2285
|
entity,
|
|
2420
2286
|
path,
|
|
2421
2287
|
schema,
|
|
2422
2288
|
newVal
|
|
2423
2289
|
});
|
|
2424
|
-
this.buildDepGraph(entities);
|
|
2425
2290
|
this.updateValidation(entities, {
|
|
2426
2291
|
...reduxFormCellValidation,
|
|
2427
|
-
|
|
2292
|
+
[cellId]: error
|
|
2428
2293
|
});
|
|
2429
2294
|
});
|
|
2430
|
-
|
|
2431
|
-
// do not try to refocus the table if another cell has already been selected
|
|
2432
|
-
const isCellIdStillSelected = this.props.reduxFormSelectedCells[cellId];
|
|
2433
|
-
if (isCellIdStillSelected) {
|
|
2434
|
-
!doNotStopEditing && this.refocusTable();
|
|
2435
|
-
}
|
|
2436
|
-
}, 0);
|
|
2295
|
+
!doNotStopEditing && this.refocusTable();
|
|
2437
2296
|
};
|
|
2438
2297
|
|
|
2439
2298
|
cancelCellEdit = () => {
|
|
2440
|
-
const { change } = this.props;
|
|
2299
|
+
const { change } = computePresets(this.props);
|
|
2441
2300
|
change("reduxFormEditingCell", null);
|
|
2442
2301
|
this.refocusTable();
|
|
2443
2302
|
};
|
|
@@ -2451,7 +2310,9 @@ class DataTable extends React.Component {
|
|
|
2451
2310
|
};
|
|
2452
2311
|
|
|
2453
2312
|
isSelectionARectangle = () => {
|
|
2454
|
-
const { entities, reduxFormSelectedCells, schema } =
|
|
2313
|
+
const { entities, reduxFormSelectedCells, schema } = computePresets(
|
|
2314
|
+
this.props
|
|
2315
|
+
);
|
|
2455
2316
|
if (
|
|
2456
2317
|
reduxFormSelectedCells &&
|
|
2457
2318
|
Object.keys(reduxFormSelectedCells).length > 1
|
|
@@ -2531,7 +2392,6 @@ class DataTable extends React.Component {
|
|
|
2531
2392
|
isCellEditable,
|
|
2532
2393
|
cellRenderer,
|
|
2533
2394
|
withCheckboxes,
|
|
2534
|
-
allowFormulas,
|
|
2535
2395
|
SubComponent,
|
|
2536
2396
|
shouldShowSubComponent,
|
|
2537
2397
|
entities,
|
|
@@ -2543,7 +2403,7 @@ class DataTable extends React.Component {
|
|
|
2543
2403
|
change,
|
|
2544
2404
|
reduxFormSelectedCells,
|
|
2545
2405
|
reduxFormEditingCell
|
|
2546
|
-
} = this.props;
|
|
2406
|
+
} = computePresets(this.props);
|
|
2547
2407
|
const { columns } = this.state;
|
|
2548
2408
|
if (!columns.length) {
|
|
2549
2409
|
return columns;
|
|
@@ -2606,88 +2466,6 @@ class DataTable extends React.Component {
|
|
|
2606
2466
|
}
|
|
2607
2467
|
});
|
|
2608
2468
|
}
|
|
2609
|
-
if (allowFormulas) {
|
|
2610
|
-
columnsToRender.push({
|
|
2611
|
-
isRowIndexColumn: true,
|
|
2612
|
-
Header: () => {
|
|
2613
|
-
return (
|
|
2614
|
-
<InfoHelper
|
|
2615
|
-
content="Formulas"
|
|
2616
|
-
isButton
|
|
2617
|
-
minimal
|
|
2618
|
-
small
|
|
2619
|
-
style={{ padding: 2 }}
|
|
2620
|
-
popoverProps={{
|
|
2621
|
-
modifiers: {
|
|
2622
|
-
preventOverflow: { enabled: false },
|
|
2623
|
-
hide: { enabled: false }
|
|
2624
|
-
}
|
|
2625
|
-
}}
|
|
2626
|
-
onClick={() => {
|
|
2627
|
-
showConfirmationDialog({
|
|
2628
|
-
text: (
|
|
2629
|
-
<div
|
|
2630
|
-
style={{
|
|
2631
|
-
padding: 10,
|
|
2632
|
-
width: 500,
|
|
2633
|
-
overflow: "auto"
|
|
2634
|
-
}}
|
|
2635
|
-
>
|
|
2636
|
-
<h3>Formulas</h3>
|
|
2637
|
-
<div>
|
|
2638
|
-
<p>
|
|
2639
|
-
Formulas are supported in the following columns:
|
|
2640
|
-
<ul>
|
|
2641
|
-
{columns.map((c, i) => {
|
|
2642
|
-
if (c.allowFormulas) {
|
|
2643
|
-
return <li>{this.renderColumnHeader(c, i)}</li>;
|
|
2644
|
-
}
|
|
2645
|
-
return null;
|
|
2646
|
-
})}
|
|
2647
|
-
</ul>
|
|
2648
|
-
</p>
|
|
2649
|
-
</div>
|
|
2650
|
-
</div>
|
|
2651
|
-
),
|
|
2652
|
-
confirmButtonText: "Ok",
|
|
2653
|
-
noCancelButton: true,
|
|
2654
|
-
canOutsideClickClose: true,
|
|
2655
|
-
canEscapeKeyClose: true
|
|
2656
|
-
});
|
|
2657
|
-
}}
|
|
2658
|
-
// className={classNames("tg-expander-all")}
|
|
2659
|
-
icon="help"
|
|
2660
|
-
/>
|
|
2661
|
-
);
|
|
2662
|
-
},
|
|
2663
|
-
Cell: props => {
|
|
2664
|
-
return (
|
|
2665
|
-
<div
|
|
2666
|
-
style={{
|
|
2667
|
-
display: "flex",
|
|
2668
|
-
justifyContent: "center",
|
|
2669
|
-
width: "100%"
|
|
2670
|
-
}}
|
|
2671
|
-
>
|
|
2672
|
-
{props.index + 1}
|
|
2673
|
-
</div>
|
|
2674
|
-
);
|
|
2675
|
-
},
|
|
2676
|
-
width: 35,
|
|
2677
|
-
resizable: false,
|
|
2678
|
-
getHeaderProps: () => {
|
|
2679
|
-
return {
|
|
2680
|
-
className: "tg-react-table-checkbox-header-container",
|
|
2681
|
-
immovable: "true"
|
|
2682
|
-
};
|
|
2683
|
-
},
|
|
2684
|
-
getProps: (p, b) => {
|
|
2685
|
-
return {
|
|
2686
|
-
className: `tg-row-index-${b.index}`
|
|
2687
|
-
};
|
|
2688
|
-
}
|
|
2689
|
-
});
|
|
2690
|
-
}
|
|
2691
2469
|
|
|
2692
2470
|
if (withCheckboxes) {
|
|
2693
2471
|
columnsToRender.push({
|
|
@@ -2709,10 +2487,10 @@ class DataTable extends React.Component {
|
|
|
2709
2487
|
});
|
|
2710
2488
|
}
|
|
2711
2489
|
|
|
2712
|
-
columns.forEach(
|
|
2490
|
+
columns.forEach(column => {
|
|
2713
2491
|
const tableColumn = {
|
|
2714
2492
|
...column,
|
|
2715
|
-
Header: this.renderColumnHeader(column
|
|
2493
|
+
Header: this.renderColumnHeader(column),
|
|
2716
2494
|
accessor: column.path,
|
|
2717
2495
|
getHeaderProps: () => ({
|
|
2718
2496
|
// needs to be a string because it is getting passed
|
|
@@ -2735,17 +2513,6 @@ class DataTable extends React.Component {
|
|
|
2735
2513
|
);
|
|
2736
2514
|
return val;
|
|
2737
2515
|
};
|
|
2738
|
-
} else if (column.allowFormulas) {
|
|
2739
|
-
tableColumn.Cell = row => {
|
|
2740
|
-
const val = row.value;
|
|
2741
|
-
|
|
2742
|
-
if (!val) return "";
|
|
2743
|
-
if (typeof val === "number") return val;
|
|
2744
|
-
if (val.formula) {
|
|
2745
|
-
return val.value;
|
|
2746
|
-
}
|
|
2747
|
-
return val;
|
|
2748
|
-
};
|
|
2749
2516
|
} else if (column.render) {
|
|
2750
2517
|
tableColumn.Cell = row => {
|
|
2751
2518
|
const val = column.render(row.value, row.original, row, this.props);
|
|
@@ -2799,20 +2566,14 @@ class DataTable extends React.Component {
|
|
|
2799
2566
|
const [row] = args;
|
|
2800
2567
|
const rowId = getIdOrCodeOrIndex(row.original, row.index);
|
|
2801
2568
|
const cellId = `${rowId}:${row.column.path}`;
|
|
2802
|
-
const alphaNum = getCellAlphaNumHelper(i, row.index);
|
|
2803
2569
|
let val = oldFunc(...args);
|
|
2804
2570
|
const oldVal = val;
|
|
2805
2571
|
const text = this.getCopyTextForCell(val, row, column);
|
|
2806
2572
|
const isBool = column.type === "boolean";
|
|
2807
|
-
const fullValue = row.original?.[row.column.path];
|
|
2808
2573
|
const dataTest = {
|
|
2809
|
-
"data-
|
|
2810
|
-
"data-test": "tgCell_" + column.path,
|
|
2811
|
-
"data-cell-alpha": alphaNum,
|
|
2812
|
-
...(fullValue?.formula && {
|
|
2813
|
-
"data-formula": fullValue.formula
|
|
2814
|
-
})
|
|
2574
|
+
"data-test": "tgCell_" + column.path
|
|
2815
2575
|
};
|
|
2576
|
+
const fullValue = row.original?.[row.column.path];
|
|
2816
2577
|
if (isCellEditable && isBool) {
|
|
2817
2578
|
val = (
|
|
2818
2579
|
<Checkbox
|
|
@@ -2873,7 +2634,7 @@ class DataTable extends React.Component {
|
|
|
2873
2634
|
shouldSelectAll={reduxFormEditingCellSelectAll}
|
|
2874
2635
|
cancelEdit={this.cancelCellEdit}
|
|
2875
2636
|
isNumeric={column.type === "number"}
|
|
2876
|
-
initialValue={
|
|
2637
|
+
initialValue={text}
|
|
2877
2638
|
finishEdit={newVal => {
|
|
2878
2639
|
this.finishCellEdit(cellId, newVal);
|
|
2879
2640
|
}}
|
|
@@ -2923,9 +2684,7 @@ class DataTable extends React.Component {
|
|
|
2923
2684
|
__strVal: fullValue,
|
|
2924
2685
|
__genSelCol: column.path
|
|
2925
2686
|
}
|
|
2926
|
-
:
|
|
2927
|
-
? { __strVal: fullValue }
|
|
2928
|
-
: { __strVal: text }
|
|
2687
|
+
: { __strVal: text }
|
|
2929
2688
|
)}
|
|
2930
2689
|
title={title || undefined}
|
|
2931
2690
|
>
|
|
@@ -3003,8 +2762,7 @@ class DataTable extends React.Component {
|
|
|
3003
2762
|
schema,
|
|
3004
2763
|
reduxFormCellValidation,
|
|
3005
2764
|
change,
|
|
3006
|
-
reduxFormSelectedCells
|
|
3007
|
-
allowFormulas
|
|
2765
|
+
reduxFormSelectedCells
|
|
3008
2766
|
} = this.props;
|
|
3009
2767
|
const primaryCellId = this.getPrimarySelectedCellId();
|
|
3010
2768
|
const [primaryRowId, primaryCellPath] = primaryCellId.split(":");
|
|
@@ -3014,8 +2772,7 @@ class DataTable extends React.Component {
|
|
|
3014
2772
|
if (!allSelectedPaths) {
|
|
3015
2773
|
allSelectedPaths = [primaryCellPath];
|
|
3016
2774
|
}
|
|
3017
|
-
|
|
3018
|
-
const prevEnts = entities;
|
|
2775
|
+
|
|
3019
2776
|
this.updateEntitiesHelper(entities, entities => {
|
|
3020
2777
|
let newReduxFormSelectedCells;
|
|
3021
2778
|
if (selectedPaths) {
|
|
@@ -3028,11 +2785,10 @@ class DataTable extends React.Component {
|
|
|
3028
2785
|
};
|
|
3029
2786
|
}
|
|
3030
2787
|
|
|
3031
|
-
|
|
2788
|
+
const newCellValidate = {
|
|
3032
2789
|
...reduxFormCellValidation
|
|
3033
2790
|
};
|
|
3034
|
-
const entityMap = getEntityIdToEntity(
|
|
3035
|
-
const updateAbleEntityMap = getEntityIdToEntity(entities);
|
|
2791
|
+
const entityMap = getEntityIdToEntity(entities);
|
|
3036
2792
|
const { e: selectedEnt } = entityMap[primaryRowId];
|
|
3037
2793
|
const firstCellToSelectRowIndex =
|
|
3038
2794
|
entityMap[cellsToSelect[0]?.split(":")[0]]?.i;
|
|
@@ -3081,8 +2837,7 @@ class DataTable extends React.Component {
|
|
|
3081
2837
|
}
|
|
3082
2838
|
if (incrementStart === undefined) {
|
|
3083
2839
|
const draggingDown =
|
|
3084
|
-
firstCellToSelectRowIndex >
|
|
3085
|
-
selectionGrid?.[0]?.[cellIndexOfSelectedPath]?.rowIndex;
|
|
2840
|
+
firstCellToSelectRowIndex > selectionGrid?.[0][0].rowIndex;
|
|
3086
2841
|
if (selectedPaths && draggingDown) {
|
|
3087
2842
|
let checkIncrement;
|
|
3088
2843
|
let prefix;
|
|
@@ -3148,8 +2903,7 @@ class DataTable extends React.Component {
|
|
|
3148
2903
|
const [rowId, cellPath] = cellId.split(":");
|
|
3149
2904
|
if (cellPath !== selectedPath) return;
|
|
3150
2905
|
newReduxFormSelectedCells[cellId] = true;
|
|
3151
|
-
const { e: entityToUpdate, i: rowIndex } =
|
|
3152
|
-
updateAbleEntityMap[rowId] || {};
|
|
2906
|
+
const { e: entityToUpdate, i: rowIndex } = entityMap[rowId] || {};
|
|
3153
2907
|
if (entityToUpdate) {
|
|
3154
2908
|
delete entityToUpdate._isClean;
|
|
3155
2909
|
let newVal;
|
|
@@ -3189,31 +2943,24 @@ class DataTable extends React.Component {
|
|
|
3189
2943
|
newVal = selectedCellVal;
|
|
3190
2944
|
}
|
|
3191
2945
|
}
|
|
3192
|
-
const {
|
|
3193
|
-
allowFormulas,
|
|
3194
|
-
updateGroup,
|
|
3195
|
-
depGraph: this.depGraph,
|
|
3196
|
-
entities,
|
|
2946
|
+
const { error } = editCellHelper({
|
|
3197
2947
|
entity: entityToUpdate,
|
|
3198
2948
|
path: cellPath,
|
|
3199
2949
|
schema,
|
|
3200
2950
|
newVal
|
|
3201
2951
|
});
|
|
3202
|
-
newCellValidate =
|
|
3203
|
-
...newCellValidate,
|
|
3204
|
-
...errors
|
|
3205
|
-
};
|
|
2952
|
+
newCellValidate[cellId] = error;
|
|
3206
2953
|
}
|
|
3207
2954
|
});
|
|
3208
2955
|
});
|
|
3209
|
-
|
|
2956
|
+
|
|
3210
2957
|
// select the new cells
|
|
3211
2958
|
this.updateValidation(entities, newCellValidate);
|
|
3212
2959
|
change("reduxFormSelectedCells", newReduxFormSelectedCells);
|
|
3213
2960
|
});
|
|
3214
2961
|
};
|
|
3215
2962
|
getCopyTextForCell = (val, row = {}, column = {}) => {
|
|
3216
|
-
const { cellRenderer } = this.props;
|
|
2963
|
+
const { cellRenderer } = computePresets(this.props);
|
|
3217
2964
|
// TODOCOPY we need a way to potentially omit certain columns from being added as a \t element (talk to taoh about this)
|
|
3218
2965
|
let text = typeof val !== "string" ? row.value : val;
|
|
3219
2966
|
|
|
@@ -3265,7 +3012,9 @@ class DataTable extends React.Component {
|
|
|
3265
3012
|
};
|
|
3266
3013
|
|
|
3267
3014
|
addEditableTableEntities = incomingEnts => {
|
|
3268
|
-
const { entities = [], reduxFormCellValidation } =
|
|
3015
|
+
const { entities = [], reduxFormCellValidation } = computePresets(
|
|
3016
|
+
this.props
|
|
3017
|
+
);
|
|
3269
3018
|
|
|
3270
3019
|
this.updateEntitiesHelper(entities, entities => {
|
|
3271
3020
|
const newEntities = incomingEnts.map(e => ({
|
|
@@ -3288,7 +3037,7 @@ class DataTable extends React.Component {
|
|
|
3288
3037
|
} else {
|
|
3289
3038
|
entities.splice(entities.length, 0, ...newEnts);
|
|
3290
3039
|
}
|
|
3291
|
-
|
|
3040
|
+
|
|
3292
3041
|
this.updateValidation(entities, {
|
|
3293
3042
|
...reduxFormCellValidation,
|
|
3294
3043
|
...validationErrors
|
|
@@ -3296,7 +3045,8 @@ class DataTable extends React.Component {
|
|
|
3296
3045
|
});
|
|
3297
3046
|
};
|
|
3298
3047
|
getEditableTableInfoAndThrowFormError = () => {
|
|
3299
|
-
const { schema, reduxFormEntities, reduxFormCellValidation } =
|
|
3048
|
+
const { schema, reduxFormEntities, reduxFormCellValidation } =
|
|
3049
|
+
computePresets(this.props);
|
|
3300
3050
|
const { entsToUse, validationToUse } = removeCleanRows(
|
|
3301
3051
|
reduxFormEntities,
|
|
3302
3052
|
reduxFormCellValidation
|
|
@@ -3325,11 +3075,9 @@ class DataTable extends React.Component {
|
|
|
3325
3075
|
};
|
|
3326
3076
|
|
|
3327
3077
|
insertRows = ({ above, numRows = 1, appendToBottom } = {}) => {
|
|
3328
|
-
const {
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
allowFormulas
|
|
3332
|
-
} = this.props;
|
|
3078
|
+
const { entities = [], reduxFormCellValidation } = computePresets(
|
|
3079
|
+
this.props
|
|
3080
|
+
);
|
|
3333
3081
|
|
|
3334
3082
|
const primaryCellId = this.getPrimarySelectedCellId();
|
|
3335
3083
|
const [rowId] = primaryCellId?.split(":") || [];
|
|
@@ -3341,50 +3089,6 @@ class DataTable extends React.Component {
|
|
|
3341
3089
|
});
|
|
3342
3090
|
const insertIndex = above ? indexToInsert : indexToInsert + 1;
|
|
3343
3091
|
const insertIndexToUse = appendToBottom ? entities.length : insertIndex;
|
|
3344
|
-
let { newEnts, validationErrors } = this.formatAndValidateEntities(
|
|
3345
|
-
newEntities,
|
|
3346
|
-
{
|
|
3347
|
-
useDefaultValues: true,
|
|
3348
|
-
indexToStartAt: insertIndexToUse,
|
|
3349
|
-
depGraphToUse: {}
|
|
3350
|
-
}
|
|
3351
|
-
);
|
|
3352
|
-
|
|
3353
|
-
newEnts = newEnts.map(e => ({
|
|
3354
|
-
...e,
|
|
3355
|
-
_isClean: true
|
|
3356
|
-
}));
|
|
3357
|
-
allowFormulas &&
|
|
3358
|
-
updateEntityFormulasToInsertDelete({
|
|
3359
|
-
entities,
|
|
3360
|
-
insertIndex: insertIndexToUse,
|
|
3361
|
-
numEnts: newEnts.length
|
|
3362
|
-
});
|
|
3363
|
-
|
|
3364
|
-
this.updateValidation(entities, {
|
|
3365
|
-
...reduxFormCellValidation,
|
|
3366
|
-
...validationErrors
|
|
3367
|
-
});
|
|
3368
|
-
// we need to make sure any entities with formulas are updated
|
|
3369
|
-
|
|
3370
|
-
entities.splice(insertIndexToUse, 0, ...newEnts);
|
|
3371
|
-
this.buildDepGraph(entities);
|
|
3372
|
-
});
|
|
3373
|
-
this.refocusTable();
|
|
3374
|
-
};
|
|
3375
|
-
insertColumns = ({ toTheLeft, numColumns = 1, appendToEnd } = {}) => {
|
|
3376
|
-
const { entities = [], reduxFormCellValidation } = this.props;
|
|
3377
|
-
|
|
3378
|
-
const primaryCellId = this.getPrimarySelectedCellId();
|
|
3379
|
-
const [rowId] = primaryCellId?.split(":") || [];
|
|
3380
|
-
this.updateEntitiesHelper(entities, entities => {
|
|
3381
|
-
const newEntities = times(numColumns).map(() => ({ id: nanoid() }));
|
|
3382
|
-
|
|
3383
|
-
const indexToInsert = entities.findIndex((e, i) => {
|
|
3384
|
-
return getIdOrCodeOrIndex(e, i) === rowId;
|
|
3385
|
-
});
|
|
3386
|
-
const insertIndex = toTheLeft ? indexToInsert : indexToInsert + 1;
|
|
3387
|
-
const insertIndexToUse = appendToEnd ? entities.length : insertIndex;
|
|
3388
3092
|
let { newEnts, validationErrors } = this.formatAndValidateEntities(
|
|
3389
3093
|
newEntities,
|
|
3390
3094
|
{
|
|
@@ -3412,11 +3116,10 @@ class DataTable extends React.Component {
|
|
|
3412
3116
|
history,
|
|
3413
3117
|
contextMenu,
|
|
3414
3118
|
isCopyable,
|
|
3415
|
-
allowFormulas,
|
|
3416
3119
|
isCellEditable,
|
|
3417
3120
|
entities = [],
|
|
3418
3121
|
reduxFormSelectedCells = {}
|
|
3419
|
-
} = this.props;
|
|
3122
|
+
} = computePresets(this.props);
|
|
3420
3123
|
let selectedRecords;
|
|
3421
3124
|
if (isCellEditable) {
|
|
3422
3125
|
const rowIds = {};
|
|
@@ -3443,44 +3146,43 @@ class DataTable extends React.Component {
|
|
|
3443
3146
|
e.target.querySelector(".tg-cell-wrapper") ||
|
|
3444
3147
|
e.target.closest(".tg-cell-wrapper");
|
|
3445
3148
|
if (cellWrapper) {
|
|
3446
|
-
copyMenuItems.push(
|
|
3149
|
+
copyMenuItems.push(
|
|
3447
3150
|
<MenuItem
|
|
3448
3151
|
key="copyCell"
|
|
3449
3152
|
onClick={() => {
|
|
3450
3153
|
//TODOCOPY: we need to make sure that the cell copy is being used by the row copy.. right now we have 2 different things going on
|
|
3451
3154
|
//do we need to be able to copy hidden cells? It seems like it should just copy what's on the page..?
|
|
3452
|
-
|
|
3155
|
+
const specificColumn = cellWrapper.getAttribute("data-test");
|
|
3156
|
+
this.handleCopyRows([cellWrapper.closest(".rt-tr")], {
|
|
3157
|
+
specificColumn,
|
|
3158
|
+
onFinishMsg: "Cell copied"
|
|
3159
|
+
});
|
|
3160
|
+
const [text, jsonText] = this.getCellCopyText(cellWrapper);
|
|
3161
|
+
this.handleCopyHelper(text, jsonText);
|
|
3453
3162
|
}}
|
|
3454
|
-
text=
|
|
3455
|
-
Object.keys(reduxFormSelectedCells).length > 1 ? "s" : ""
|
|
3456
|
-
}`}
|
|
3163
|
+
text="Cell"
|
|
3457
3164
|
/>
|
|
3458
|
-
)
|
|
3165
|
+
);
|
|
3459
3166
|
|
|
3460
|
-
copyMenuItems.push(
|
|
3167
|
+
copyMenuItems.push(
|
|
3461
3168
|
<MenuItem
|
|
3462
3169
|
key="copyColumn"
|
|
3463
3170
|
onClick={() => {
|
|
3464
|
-
this.handleCopyColumn(
|
|
3171
|
+
this.handleCopyColumn(e, cellWrapper);
|
|
3465
3172
|
}}
|
|
3466
|
-
text=
|
|
3173
|
+
text="Column"
|
|
3467
3174
|
/>
|
|
3468
|
-
)
|
|
3175
|
+
);
|
|
3469
3176
|
if (selectedRecords.length > 1) {
|
|
3470
|
-
copyMenuItems.push(
|
|
3177
|
+
copyMenuItems.push(
|
|
3471
3178
|
<MenuItem
|
|
3472
3179
|
key="copyColumnSelected"
|
|
3473
3180
|
onClick={() => {
|
|
3474
|
-
this.handleCopyColumn(
|
|
3475
|
-
e,
|
|
3476
|
-
cellWrapper,
|
|
3477
|
-
selectedRecords,
|
|
3478
|
-
opts
|
|
3479
|
-
});
|
|
3181
|
+
this.handleCopyColumn(e, cellWrapper, selectedRecords);
|
|
3480
3182
|
}}
|
|
3481
|
-
text="Selected
|
|
3183
|
+
text="Column (Selected)"
|
|
3482
3184
|
/>
|
|
3483
|
-
)
|
|
3185
|
+
);
|
|
3484
3186
|
}
|
|
3485
3187
|
}
|
|
3486
3188
|
if (selectedRecords.length === 0 || selectedRecords.length === 1) {
|
|
@@ -3490,48 +3192,38 @@ class DataTable extends React.Component {
|
|
|
3490
3192
|
e.target.closest(".tg-cell-wrapper") ||
|
|
3491
3193
|
e.target.closest(".rt-td");
|
|
3492
3194
|
const row = cell.closest(".rt-tr");
|
|
3493
|
-
copyMenuItems.push(
|
|
3195
|
+
copyMenuItems.push(
|
|
3494
3196
|
<MenuItem
|
|
3495
3197
|
key="copySelectedRows"
|
|
3496
3198
|
onClick={() => {
|
|
3497
|
-
this.handleCopyRows([row]
|
|
3199
|
+
this.handleCopyRows([row]);
|
|
3498
3200
|
// loop through each cell in the row
|
|
3499
3201
|
}}
|
|
3500
3202
|
text="Row"
|
|
3501
3203
|
/>
|
|
3502
|
-
)
|
|
3204
|
+
);
|
|
3503
3205
|
} else if (selectedRecords.length > 1) {
|
|
3504
|
-
copyMenuItems.push(
|
|
3206
|
+
copyMenuItems.push(
|
|
3505
3207
|
<MenuItem
|
|
3506
3208
|
key="copySelectedRows"
|
|
3507
3209
|
onClick={() => {
|
|
3508
|
-
this.handleCopySelectedRows(selectedRecords, e
|
|
3210
|
+
this.handleCopySelectedRows(selectedRecords, e);
|
|
3509
3211
|
// loop through each cell in the row
|
|
3510
3212
|
}}
|
|
3511
3213
|
text="Rows"
|
|
3512
3214
|
/>
|
|
3513
|
-
)
|
|
3215
|
+
);
|
|
3514
3216
|
}
|
|
3515
|
-
copyMenuItems.push(
|
|
3217
|
+
copyMenuItems.push(
|
|
3516
3218
|
<MenuItem
|
|
3517
3219
|
key="copyFullTableRows"
|
|
3518
3220
|
onClick={() => {
|
|
3519
|
-
this.handleCopyTable(e
|
|
3221
|
+
this.handleCopyTable(e);
|
|
3520
3222
|
// loop through each cell in the row
|
|
3521
3223
|
}}
|
|
3522
3224
|
text="Table"
|
|
3523
3225
|
/>
|
|
3524
|
-
)
|
|
3525
|
-
copyMenuItems.push(opts => (
|
|
3526
|
-
<MenuItem
|
|
3527
|
-
key="copyFullTableRowsNoHeader"
|
|
3528
|
-
onClick={() => {
|
|
3529
|
-
this.handleCopyTable(e, { ...opts, noHeader: true });
|
|
3530
|
-
// loop through each cell in the row
|
|
3531
|
-
}}
|
|
3532
|
-
text="Table Without Header"
|
|
3533
|
-
/>
|
|
3534
|
-
));
|
|
3226
|
+
);
|
|
3535
3227
|
}
|
|
3536
3228
|
const selectedRowIds = Object.keys(reduxFormSelectedCells).map(cellId => {
|
|
3537
3229
|
const [rowId] = cellId.split(":");
|
|
@@ -3543,39 +3235,11 @@ class DataTable extends React.Component {
|
|
|
3543
3235
|
{itemsToRender}
|
|
3544
3236
|
{copyMenuItems.length && (
|
|
3545
3237
|
<MenuItem icon="clipboard" key="copyOpts" text="Copy">
|
|
3546
|
-
{copyMenuItems
|
|
3238
|
+
{copyMenuItems}
|
|
3547
3239
|
</MenuItem>
|
|
3548
3240
|
)}
|
|
3549
|
-
{copyMenuItems.length && allowFormulas && (
|
|
3550
|
-
<MenuItem
|
|
3551
|
-
data-tip="This will copy the underlying formula (if there are any) instead of the evaluated value"
|
|
3552
|
-
icon="clipboard"
|
|
3553
|
-
key="copyOptsFormulas"
|
|
3554
|
-
text="Copy Formula"
|
|
3555
|
-
>
|
|
3556
|
-
{copyMenuItems.map(f => f({ isFormulaCopy: true }))}
|
|
3557
|
-
</MenuItem>
|
|
3558
|
-
)}
|
|
3559
|
-
<Divider></Divider>
|
|
3560
3241
|
{isCellEditable && (
|
|
3561
3242
|
<>
|
|
3562
|
-
<MenuItem
|
|
3563
|
-
icon="add-column-left"
|
|
3564
|
-
text="Add Column Left"
|
|
3565
|
-
key="addColumnLeft"
|
|
3566
|
-
onClick={() => {
|
|
3567
|
-
this.insertColumns({ toTheLeft: true });
|
|
3568
|
-
}}
|
|
3569
|
-
></MenuItem>
|
|
3570
|
-
<MenuItem
|
|
3571
|
-
icon="add-column-right"
|
|
3572
|
-
text="Add Column Right"
|
|
3573
|
-
key="addColumnRight"
|
|
3574
|
-
onClick={() => {
|
|
3575
|
-
this.insertColumns({});
|
|
3576
|
-
}}
|
|
3577
|
-
></MenuItem>
|
|
3578
|
-
<Divider></Divider>
|
|
3579
3243
|
<MenuItem
|
|
3580
3244
|
icon="add-row-top"
|
|
3581
3245
|
text="Add Row Above"
|
|
@@ -3594,15 +3258,14 @@ class DataTable extends React.Component {
|
|
|
3594
3258
|
></MenuItem>
|
|
3595
3259
|
<MenuItem
|
|
3596
3260
|
icon="remove"
|
|
3597
|
-
text={`Remove Row${
|
|
3261
|
+
text={`Remove Row${selectedRowIds.length > 1 ? "s" : ""}`}
|
|
3598
3262
|
key="removeRow"
|
|
3599
3263
|
onClick={() => {
|
|
3600
3264
|
const {
|
|
3601
3265
|
entities = [],
|
|
3602
3266
|
reduxFormCellValidation,
|
|
3603
|
-
reduxFormSelectedCells = {}
|
|
3604
|
-
|
|
3605
|
-
} = this.props;
|
|
3267
|
+
reduxFormSelectedCells = {}
|
|
3268
|
+
} = computePresets(this.props);
|
|
3606
3269
|
const selectedRowIds = Object.keys(reduxFormSelectedCells).map(
|
|
3607
3270
|
cellId => {
|
|
3608
3271
|
const [rowId] = cellId.split(":");
|
|
@@ -3610,33 +3273,16 @@ class DataTable extends React.Component {
|
|
|
3610
3273
|
}
|
|
3611
3274
|
);
|
|
3612
3275
|
this.updateEntitiesHelper(entities, entities => {
|
|
3613
|
-
const
|
|
3614
|
-
selectedRowIds
|
|
3615
|
-
.map(
|
|
3616
|
-
id =>
|
|
3617
|
-
entities.findIndex(
|
|
3618
|
-
(e, i) => getIdOrCodeOrIndex(e, i) === id
|
|
3619
|
-
) + 1
|
|
3620
|
-
)
|
|
3621
|
-
.sort((a, b) => a - b)
|
|
3276
|
+
const ents = entities.filter(
|
|
3277
|
+
(e, i) => !selectedRowIds.includes(getIdOrCodeOrIndex(e, i))
|
|
3622
3278
|
);
|
|
3623
|
-
allowFormulas &&
|
|
3624
|
-
updateEntityFormulasToInsertDelete({
|
|
3625
|
-
entities,
|
|
3626
|
-
deleteIndices
|
|
3627
|
-
});
|
|
3628
|
-
|
|
3629
|
-
deleteIndices.reverse().forEach(indexToRemove => {
|
|
3630
|
-
entities.splice(indexToRemove - 1, 1);
|
|
3631
|
-
});
|
|
3632
|
-
this.buildDepGraph(entities);
|
|
3633
3279
|
this.updateValidation(
|
|
3634
|
-
|
|
3280
|
+
ents,
|
|
3635
3281
|
omitBy(reduxFormCellValidation, (v, cellId) =>
|
|
3636
3282
|
selectedRowIds.includes(cellId.split(":")[0])
|
|
3637
3283
|
)
|
|
3638
3284
|
);
|
|
3639
|
-
|
|
3285
|
+
return ents;
|
|
3640
3286
|
});
|
|
3641
3287
|
this.refocusTable();
|
|
3642
3288
|
}}
|
|
@@ -3648,7 +3294,7 @@ class DataTable extends React.Component {
|
|
|
3648
3294
|
ContextMenu.show(menu, { left: e.clientX, top: e.clientY });
|
|
3649
3295
|
};
|
|
3650
3296
|
|
|
3651
|
-
renderColumnHeader =
|
|
3297
|
+
renderColumnHeader = column => {
|
|
3652
3298
|
const {
|
|
3653
3299
|
addFilters,
|
|
3654
3300
|
setOrder,
|
|
@@ -3663,9 +3309,8 @@ class DataTable extends React.Component {
|
|
|
3663
3309
|
compact,
|
|
3664
3310
|
isCellEditable,
|
|
3665
3311
|
extraCompact,
|
|
3666
|
-
entities
|
|
3667
|
-
|
|
3668
|
-
} = this.props;
|
|
3312
|
+
entities
|
|
3313
|
+
} = computePresets(this.props);
|
|
3669
3314
|
const {
|
|
3670
3315
|
displayName,
|
|
3671
3316
|
description,
|
|
@@ -3805,15 +3450,7 @@ class DataTable extends React.Component {
|
|
|
3805
3450
|
}
|
|
3806
3451
|
|
|
3807
3452
|
const columnTitleTextified = getTextFromEl(columnTitle);
|
|
3808
|
-
|
|
3809
|
-
const getLetterifiedColumnTitle = () => {
|
|
3810
|
-
const letter = getColLetFromIndex(index);
|
|
3811
|
-
if (inner?.toUpperCase() === letter) {
|
|
3812
|
-
inner = letter;
|
|
3813
|
-
return null;
|
|
3814
|
-
}
|
|
3815
|
-
return <div>{getColLetFromIndex(index)}:</div>;
|
|
3816
|
-
};
|
|
3453
|
+
|
|
3817
3454
|
return (
|
|
3818
3455
|
<div
|
|
3819
3456
|
{...(description && {
|
|
@@ -3821,7 +3458,6 @@ class DataTable extends React.Component {
|
|
|
3821
3458
|
<strong>${columnTitle}:</strong> <br>
|
|
3822
3459
|
${description} ${isUnique ? "<br>Must be unique" : ""}</div>`
|
|
3823
3460
|
})}
|
|
3824
|
-
data-column={column.path}
|
|
3825
3461
|
data-test={columnTitleTextified}
|
|
3826
3462
|
data-path={path}
|
|
3827
3463
|
data-copy-text={columnTitleTextified}
|
|
@@ -3836,7 +3472,6 @@ class DataTable extends React.Component {
|
|
|
3836
3472
|
{columnTitleTextified && !noTitle && (
|
|
3837
3473
|
<React.Fragment>
|
|
3838
3474
|
{maybeCheckbox}
|
|
3839
|
-
{allowFormulas && getLetterifiedColumnTitle()}
|
|
3840
3475
|
<span
|
|
3841
3476
|
title={columnTitleTextified}
|
|
3842
3477
|
className={classNames({
|
|
@@ -3848,7 +3483,7 @@ class DataTable extends React.Component {
|
|
|
3848
3483
|
display: "inline-block"
|
|
3849
3484
|
}}
|
|
3850
3485
|
>
|
|
3851
|
-
{
|
|
3486
|
+
{renderTitleInner ? renderTitleInner : columnTitle}{" "}
|
|
3852
3487
|
</span>
|
|
3853
3488
|
</React.Fragment>
|
|
3854
3489
|
)}
|
|
@@ -4144,7 +3779,6 @@ function endsWithNumber(str) {
|
|
|
4144
3779
|
}
|
|
4145
3780
|
|
|
4146
3781
|
function getNumberStrAtEnd(str) {
|
|
4147
|
-
if (typeof str !== "string") str = str.toString();
|
|
4148
3782
|
if (endsWithNumber(str)) {
|
|
4149
3783
|
return str.match(/[0-9]+$/)[0];
|
|
4150
3784
|
}
|
|
@@ -4179,13 +3813,7 @@ const formatPasteData = ({ schema, newVal, path }) => {
|
|
|
4179
3813
|
newVal = undefined;
|
|
4180
3814
|
}
|
|
4181
3815
|
} else {
|
|
4182
|
-
newVal = Object.hasOwn(newVal, "__strVal")
|
|
4183
|
-
? newVal.__strVal?.formula
|
|
4184
|
-
? newVal.__strVal.formula
|
|
4185
|
-
: newVal.__strVal
|
|
4186
|
-
: isEmpty(newVal)
|
|
4187
|
-
? undefined
|
|
4188
|
-
: newVal;
|
|
3816
|
+
newVal = Object.hasOwn(newVal, "__strVal") ? newVal.__strVal : newVal;
|
|
4189
3817
|
}
|
|
4190
3818
|
return newVal;
|
|
4191
3819
|
};
|
|
@@ -4209,61 +3837,3 @@ export function removeCleanRows(reduxFormEntities, reduxFormCellValidation) {
|
|
|
4209
3837
|
});
|
|
4210
3838
|
return { entsToUse, validationToUse };
|
|
4211
3839
|
}
|
|
4212
|
-
|
|
4213
|
-
const updateEntityFormulasToInsertDelete = ({
|
|
4214
|
-
entities,
|
|
4215
|
-
deleteIndices,
|
|
4216
|
-
insertIndex,
|
|
4217
|
-
numEnts = 1
|
|
4218
|
-
}) => {
|
|
4219
|
-
const isInsert = !deleteIndices;
|
|
4220
|
-
entities.forEach(e => {
|
|
4221
|
-
Object.values(e).forEach(v => {
|
|
4222
|
-
if (v?.formula) {
|
|
4223
|
-
// update the formula to shift the row numbers up or down as needed
|
|
4224
|
-
v.formula = v.formula.replace(/([A-Z]+[0-9]+)/gi, match => {
|
|
4225
|
-
const letter = match.replace(/[0-9]+/gi, "");
|
|
4226
|
-
// update the match number
|
|
4227
|
-
const num = Number(match.replace(/[A-Z]+/gi, ""));
|
|
4228
|
-
if (isInsert) {
|
|
4229
|
-
if (num > insertIndex) {
|
|
4230
|
-
// if the insert index is above the match number then we need to add 1 to the row number
|
|
4231
|
-
const newNum = num + numEnts;
|
|
4232
|
-
return `${letter}${newNum}`;
|
|
4233
|
-
}
|
|
4234
|
-
} else {
|
|
4235
|
-
let newNum = num;
|
|
4236
|
-
deleteIndices.forEach(i => {
|
|
4237
|
-
if (num > i) {
|
|
4238
|
-
newNum = num - 1;
|
|
4239
|
-
}
|
|
4240
|
-
});
|
|
4241
|
-
return `${letter}${newNum}`;
|
|
4242
|
-
}
|
|
4243
|
-
return match;
|
|
4244
|
-
});
|
|
4245
|
-
v.formula = v.formula.replace(/([0-9]+:[0-9]+)/gi, match => {
|
|
4246
|
-
const [num1, num2] = match.split(":");
|
|
4247
|
-
if (num1 === num2) {
|
|
4248
|
-
const num = Number(num1);
|
|
4249
|
-
if (isInsert) {
|
|
4250
|
-
if (num > insertIndex) {
|
|
4251
|
-
const newNum = num + numEnts;
|
|
4252
|
-
return `${newNum}:${newNum}`;
|
|
4253
|
-
}
|
|
4254
|
-
} else {
|
|
4255
|
-
let newNum = num;
|
|
4256
|
-
deleteIndices.forEach(i => {
|
|
4257
|
-
if (num > i) {
|
|
4258
|
-
newNum = num - 1;
|
|
4259
|
-
}
|
|
4260
|
-
});
|
|
4261
|
-
return `${newNum}:${newNum}`;
|
|
4262
|
-
}
|
|
4263
|
-
}
|
|
4264
|
-
return match;
|
|
4265
|
-
});
|
|
4266
|
-
}
|
|
4267
|
-
});
|
|
4268
|
-
});
|
|
4269
|
-
};
|