@onehat/ui 0.3.213 → 0.3.216
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/package.json +4 -1
- package/src/Components/Buttons/ExpandButton.js +17 -0
- package/src/Components/Grid/Grid.js +133 -56
- package/src/Components/Grid/GridRow.js +174 -168
- package/src/Components/Grid/RowDragHandle.js +24 -0
- package/src/Components/Hoc/withContextMenu.js +5 -1
- package/src/Components/Hoc/withDnd.js +137 -0
- package/src/Components/Hoc/withDraggable.js +4 -0
- package/src/Components/Hoc/withPresetButtons.js +2 -2
- package/src/Components/index.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onehat/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.216",
|
|
4
4
|
"description": "Base UI for OneHat apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -46,6 +46,9 @@
|
|
|
46
46
|
"react-color": "^2.19.3",
|
|
47
47
|
"react-datetime": "^3.2.0",
|
|
48
48
|
"react-dom": "*",
|
|
49
|
+
"react-dnd": "^16.0.1",
|
|
50
|
+
"react-dnd-html5-backend": "^16.0.1",
|
|
51
|
+
"react-dnd-touch-backend":"16.0.1",
|
|
49
52
|
"react-draggable": "^4.4.5",
|
|
50
53
|
"react-native": "*",
|
|
51
54
|
"react-native-draggable": "^3.3.0",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import IconButton from './IconButton.js';
|
|
2
|
+
import Plus from '../Icons/Plus.js';
|
|
3
|
+
import Minus from '../Icons/Minus.js';
|
|
4
|
+
import _ from 'lodash';
|
|
5
|
+
|
|
6
|
+
export default function ExpandButton(props) {
|
|
7
|
+
const {
|
|
8
|
+
isExpanded = false,
|
|
9
|
+
onToggle,
|
|
10
|
+
} = props;
|
|
11
|
+
|
|
12
|
+
return <IconButton
|
|
13
|
+
icon={isExpanded ? Minus : Plus}
|
|
14
|
+
onPress={onToggle}
|
|
15
|
+
{...props}
|
|
16
|
+
/>;
|
|
17
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef, useMemo, useCallback, } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
Box,
|
|
3
4
|
Column,
|
|
4
5
|
FlatList,
|
|
5
6
|
Pressable,
|
|
@@ -34,6 +35,7 @@ import withContextMenu from '../Hoc/withContextMenu.js';
|
|
|
34
35
|
import withAlert from '../Hoc/withAlert.js';
|
|
35
36
|
import withComponent from '../Hoc/withComponent.js';
|
|
36
37
|
import withData from '../Hoc/withData.js';
|
|
38
|
+
import { withDropTarget } from '../Hoc/withDnd.js';
|
|
37
39
|
import withEvents from '../Hoc/withEvents.js';
|
|
38
40
|
import withSideEditor from '../Hoc/withSideEditor.js';
|
|
39
41
|
import withFilters from '../Hoc/withFilters.js';
|
|
@@ -49,8 +51,9 @@ import testProps from '../../Functions/testProps.js';
|
|
|
49
51
|
import nbToRgb from '../../Functions/nbToRgb.js';
|
|
50
52
|
import Loading from '../Messages/Loading.js';
|
|
51
53
|
import GridHeaderRow from './GridHeaderRow.js';
|
|
52
|
-
import GridRow
|
|
54
|
+
import GridRow from './GridRow.js';
|
|
53
55
|
import IconButton from '../Buttons/IconButton.js';
|
|
56
|
+
import ExpandButton from '../Buttons/ExpandButton.js';
|
|
54
57
|
import PaginationToolbar from '../Toolbar/PaginationToolbar.js';
|
|
55
58
|
import NoRecordsFound from './NoRecordsFound.js';
|
|
56
59
|
import Toolbar from '../Toolbar/Toolbar.js';
|
|
@@ -95,22 +98,26 @@ function GridComponent(props) {
|
|
|
95
98
|
},
|
|
96
99
|
flatListProps = {},
|
|
97
100
|
onRowPress,
|
|
98
|
-
|
|
101
|
+
onRender,
|
|
99
102
|
forceLoadOnRender = false,
|
|
100
103
|
pullToRefresh = true,
|
|
101
104
|
hideNavColumn = true,
|
|
102
105
|
noneFoundText,
|
|
103
106
|
autoAdjustPageSizeToHeight = true,
|
|
104
|
-
disableLoadingIndicator = false,
|
|
105
107
|
disableSelectorSelected = false,
|
|
106
108
|
showRowExpander = false,
|
|
107
|
-
|
|
109
|
+
getExpandedRowContent,
|
|
108
110
|
showHeaders = true,
|
|
109
111
|
showHovers = true,
|
|
110
112
|
canColumnsSort = true,
|
|
111
113
|
canColumnsReorder = true,
|
|
112
114
|
canColumnsResize = true,
|
|
113
115
|
canRowsReorder = false,
|
|
116
|
+
areRowsDragSource = false,
|
|
117
|
+
rowDragSourceType,
|
|
118
|
+
areRowsDropTarget = false,
|
|
119
|
+
dropTargetAccept,
|
|
120
|
+
onRowDrop,
|
|
114
121
|
allowToggleSelection = false, // i.e. single click with no shift key toggles the selection of the item clicked on
|
|
115
122
|
disableBottomToolbar = false,
|
|
116
123
|
disablePagination = false,
|
|
@@ -133,8 +140,6 @@ function GridComponent(props) {
|
|
|
133
140
|
onEdit,
|
|
134
141
|
onDelete,
|
|
135
142
|
onView,
|
|
136
|
-
onDuplicate,
|
|
137
|
-
onReset,
|
|
138
143
|
onContextMenu,
|
|
139
144
|
isAdding,
|
|
140
145
|
|
|
@@ -147,6 +152,12 @@ function GridComponent(props) {
|
|
|
147
152
|
idIx,
|
|
148
153
|
displayIx,
|
|
149
154
|
|
|
155
|
+
// withDnd
|
|
156
|
+
isDropTarget,
|
|
157
|
+
canDrop,
|
|
158
|
+
isOver,
|
|
159
|
+
dropTargetRef,
|
|
160
|
+
|
|
150
161
|
// withPresetButtons
|
|
151
162
|
onChangeColumnsConfig,
|
|
152
163
|
|
|
@@ -191,6 +202,7 @@ function GridComponent(props) {
|
|
|
191
202
|
gridRef = useRef(),
|
|
192
203
|
gridContainerRef = useRef(),
|
|
193
204
|
isAddingRef = useRef(),
|
|
205
|
+
expandedRowsRef = useRef({}),
|
|
194
206
|
[isInited, setIsInited] = useState(false),
|
|
195
207
|
[isReady, setIsReady] = useState(false),
|
|
196
208
|
[isLoading, setIsLoading] = useState(false),
|
|
@@ -198,6 +210,13 @@ function GridComponent(props) {
|
|
|
198
210
|
[isDragMode, setIsDragMode] = useState(false),
|
|
199
211
|
[dragRowSlot, setDragRowSlot] = useState(null),
|
|
200
212
|
[dragRowIx, setDragRowIx] = useState(),
|
|
213
|
+
getIsExpanded = (index) => {
|
|
214
|
+
return !!expandedRowsRef.current[index];
|
|
215
|
+
},
|
|
216
|
+
setIsExpanded = (index, isExpanded) => {
|
|
217
|
+
expandedRowsRef.current[index] = isExpanded;
|
|
218
|
+
forceUpdate();
|
|
219
|
+
},
|
|
201
220
|
setLocalColumnsConfig = (config) => {
|
|
202
221
|
if (localColumnsConfigKey && !hasFunctionColumn) {
|
|
203
222
|
setSaved(localColumnsConfigKey, config);
|
|
@@ -312,7 +331,7 @@ function GridComponent(props) {
|
|
|
312
331
|
rowProps = getRowProps && !isHeaderRow ? getRowProps(item) : {},
|
|
313
332
|
isSelected = !isHeaderRow && !disableWithSelection && isInSelection(item);
|
|
314
333
|
|
|
315
|
-
|
|
334
|
+
let rowComponent = <Pressable
|
|
316
335
|
// {...testProps(Repository ? Repository.schema.name + '-' + item.id : item.id)}
|
|
317
336
|
onPress={(e) => {
|
|
318
337
|
if (e.preventDefault && e.cancelable) {
|
|
@@ -421,23 +440,33 @@ function GridComponent(props) {
|
|
|
421
440
|
ratio = mixWithObj.alpha ? 1 - mixWithObj.alpha : 0.5;
|
|
422
441
|
bg = colourMixer.blend(bg, ratio, mixWithObj.color);
|
|
423
442
|
}
|
|
424
|
-
|
|
425
|
-
rowReorderProps = {}
|
|
443
|
+
const
|
|
444
|
+
rowReorderProps = {},
|
|
445
|
+
rowDragProps = {};
|
|
426
446
|
if (canRowsReorder && isDragMode) {
|
|
427
|
-
|
|
428
|
-
rowReorderProps =
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
447
|
+
rowReorderProps.isDraggable = true;
|
|
448
|
+
rowReorderProps.mode = VERTICAL;
|
|
449
|
+
rowReorderProps.onDragStart = onRowReorderDragStart;
|
|
450
|
+
rowReorderProps.onDrag = onRowReorderDrag;
|
|
451
|
+
rowReorderProps.onDragStop = onRowReorderDragStop;
|
|
452
|
+
rowReorderProps.proxyParent = gridRef.current?.getScrollableNode().children[0];
|
|
453
|
+
rowReorderProps.proxyPositionRelativeToParent = true;
|
|
454
|
+
rowReorderProps.getParentNode = (node) => node.parentElement.parentElement.parentElement;
|
|
455
|
+
rowReorderProps.getProxy = getReorderProxy;
|
|
456
|
+
}
|
|
457
|
+
if (areRowsDragSource) {
|
|
458
|
+
rowDragProps.isDragSource = true;
|
|
459
|
+
rowDragProps.dragSourceType = rowDragSourceType;
|
|
460
|
+
rowDragProps.dragSourceItem = { id: item.id };
|
|
461
|
+
}
|
|
462
|
+
if (areRowsDropTarget) {
|
|
463
|
+
rowDragProps.isDropTarget = true;
|
|
464
|
+
rowDragProps.dropTargetAccept = dropTargetAccept;
|
|
465
|
+
rowDragProps.onDrop = (droppedItem) => {
|
|
466
|
+
onRowDrop(item, droppedItem);
|
|
437
467
|
};
|
|
438
468
|
}
|
|
439
|
-
|
|
440
|
-
return <WhichGridRow
|
|
469
|
+
return <GridRow
|
|
441
470
|
columnsConfig={localColumnsConfig}
|
|
442
471
|
columnProps={columnProps}
|
|
443
472
|
fields={fields}
|
|
@@ -447,9 +476,29 @@ function GridComponent(props) {
|
|
|
447
476
|
item={item}
|
|
448
477
|
isInlineEditorShown={isInlineEditorShown}
|
|
449
478
|
{...rowReorderProps}
|
|
479
|
+
{...rowDragProps}
|
|
450
480
|
/>;
|
|
451
481
|
}}
|
|
452
482
|
</Pressable>;
|
|
483
|
+
|
|
484
|
+
if (showRowExpander && !isHeaderRow) {
|
|
485
|
+
const isExpanded = getIsExpanded(index);
|
|
486
|
+
rowComponent = <Column>
|
|
487
|
+
<Row>
|
|
488
|
+
<ExpandButton
|
|
489
|
+
isExpanded={isExpanded}
|
|
490
|
+
onToggle={() => setIsExpanded(index, !isExpanded)}
|
|
491
|
+
_icon={{
|
|
492
|
+
size: 'sm',
|
|
493
|
+
}}
|
|
494
|
+
py={0}
|
|
495
|
+
/>
|
|
496
|
+
{rowComponent}
|
|
497
|
+
</Row>
|
|
498
|
+
{isExpanded ? getExpandedRowContent(row) : null}
|
|
499
|
+
</Column>
|
|
500
|
+
}
|
|
501
|
+
return rowComponent;
|
|
453
502
|
},
|
|
454
503
|
getReorderProxy = (node) => {
|
|
455
504
|
const
|
|
@@ -750,6 +799,9 @@ function GridComponent(props) {
|
|
|
750
799
|
}
|
|
751
800
|
Repository.pauseEvents();
|
|
752
801
|
}
|
|
802
|
+
if (onRender) {
|
|
803
|
+
onRender(self)
|
|
804
|
+
}
|
|
753
805
|
return () => {};
|
|
754
806
|
}
|
|
755
807
|
|
|
@@ -857,6 +909,11 @@ function GridComponent(props) {
|
|
|
857
909
|
if (!Repository.isAutoLoad) {
|
|
858
910
|
Repository.reload();
|
|
859
911
|
}
|
|
912
|
+
},
|
|
913
|
+
onChangePage = () => {
|
|
914
|
+
if (showRowExpander) {
|
|
915
|
+
expandedRowsRef.current = {}; // clear expanded rows
|
|
916
|
+
}
|
|
860
917
|
};
|
|
861
918
|
|
|
862
919
|
Repository.on('beforeLoad', setTrue);
|
|
@@ -867,7 +924,7 @@ function GridComponent(props) {
|
|
|
867
924
|
Repository.ons(['changeData', 'change'], forceUpdate);
|
|
868
925
|
Repository.on('changeFilters', onChangeFilters);
|
|
869
926
|
Repository.on('changeSorters', onChangeSorters);
|
|
870
|
-
|
|
927
|
+
Repository.on('changePage', onChangePage);
|
|
871
928
|
|
|
872
929
|
applySelectorSelected();
|
|
873
930
|
Repository.resumeEvents();
|
|
@@ -885,6 +942,7 @@ function GridComponent(props) {
|
|
|
885
942
|
Repository.offs(['changeData', 'change'], forceUpdate);
|
|
886
943
|
Repository.off('changeFilters', onChangeFilters);
|
|
887
944
|
Repository.off('changeSorters', onChangeSorters);
|
|
945
|
+
Repository.off('changePage', onChangePage);
|
|
888
946
|
};
|
|
889
947
|
}, [isInited]);
|
|
890
948
|
|
|
@@ -1006,7 +1064,7 @@ function GridComponent(props) {
|
|
|
1006
1064
|
}
|
|
1007
1065
|
}
|
|
1008
1066
|
|
|
1009
|
-
|
|
1067
|
+
grid = <Column
|
|
1010
1068
|
{...testProps('Grid')}
|
|
1011
1069
|
ref={containerRef}
|
|
1012
1070
|
w="100%"
|
|
@@ -1028,7 +1086,18 @@ function GridComponent(props) {
|
|
|
1028
1086
|
|
|
1029
1087
|
{listFooterComponent}
|
|
1030
1088
|
|
|
1031
|
-
</Column
|
|
1089
|
+
</Column>
|
|
1090
|
+
|
|
1091
|
+
if (isDropTarget) {
|
|
1092
|
+
grid = <Box
|
|
1093
|
+
ref={dropTargetRef}
|
|
1094
|
+
borderWidth={canDrop && isOver ? 4 : 0}
|
|
1095
|
+
borderColor="#0ff"
|
|
1096
|
+
w="100%"
|
|
1097
|
+
{...sizeProps}
|
|
1098
|
+
>{grid}</Box>
|
|
1099
|
+
}
|
|
1100
|
+
return grid;
|
|
1032
1101
|
|
|
1033
1102
|
}
|
|
1034
1103
|
|
|
@@ -1036,12 +1105,14 @@ export const Grid = withComponent(
|
|
|
1036
1105
|
withAlert(
|
|
1037
1106
|
withEvents(
|
|
1038
1107
|
withData(
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1108
|
+
withDropTarget(
|
|
1109
|
+
withMultiSelection(
|
|
1110
|
+
withSelection(
|
|
1111
|
+
withFilters(
|
|
1112
|
+
withPresetButtons(
|
|
1113
|
+
withContextMenu(
|
|
1114
|
+
GridComponent
|
|
1115
|
+
)
|
|
1045
1116
|
),
|
|
1046
1117
|
true // isGrid
|
|
1047
1118
|
)
|
|
@@ -1057,13 +1128,15 @@ export const SideGridEditor = withComponent(
|
|
|
1057
1128
|
withAlert(
|
|
1058
1129
|
withEvents(
|
|
1059
1130
|
withData(
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1131
|
+
withDropTarget(
|
|
1132
|
+
withMultiSelection(
|
|
1133
|
+
withSelection(
|
|
1134
|
+
withSideEditor(
|
|
1135
|
+
withFilters(
|
|
1136
|
+
withPresetButtons(
|
|
1137
|
+
withContextMenu(
|
|
1138
|
+
GridComponent
|
|
1139
|
+
)
|
|
1067
1140
|
),
|
|
1068
1141
|
true // isGrid
|
|
1069
1142
|
)
|
|
@@ -1080,15 +1153,17 @@ export const WindowedGridEditor = withComponent(
|
|
|
1080
1153
|
withAlert(
|
|
1081
1154
|
withEvents(
|
|
1082
1155
|
withData(
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1156
|
+
withDropTarget(
|
|
1157
|
+
withMultiSelection(
|
|
1158
|
+
withSelection(
|
|
1159
|
+
withWindowedEditor(
|
|
1160
|
+
withFilters(
|
|
1161
|
+
withPresetButtons(
|
|
1162
|
+
withContextMenu(
|
|
1163
|
+
GridComponent
|
|
1164
|
+
),
|
|
1165
|
+
true // isGrid
|
|
1166
|
+
)
|
|
1092
1167
|
)
|
|
1093
1168
|
)
|
|
1094
1169
|
)
|
|
@@ -1103,16 +1178,18 @@ export const InlineGridEditor = withComponent(
|
|
|
1103
1178
|
withAlert(
|
|
1104
1179
|
withEvents(
|
|
1105
1180
|
withData(
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1181
|
+
withDropTarget(
|
|
1182
|
+
withMultiSelection(
|
|
1183
|
+
withSelection(
|
|
1184
|
+
withInlineEditor(
|
|
1185
|
+
withFilters(
|
|
1186
|
+
withPresetButtons(
|
|
1187
|
+
withContextMenu(
|
|
1188
|
+
GridComponent
|
|
1189
|
+
)
|
|
1190
|
+
),
|
|
1191
|
+
true // isGrid
|
|
1192
|
+
)
|
|
1116
1193
|
)
|
|
1117
1194
|
)
|
|
1118
1195
|
)
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Row,
|
|
5
5
|
Text,
|
|
6
6
|
} from 'native-base';
|
|
7
|
-
import {
|
|
8
|
-
VERTICAL,
|
|
9
|
-
} from '../../Constants/Directions.js';
|
|
10
7
|
import {
|
|
11
8
|
UI_MODE_WEB,
|
|
12
9
|
} from '../../Constants/UiModes.js';
|
|
13
10
|
import getComponentFromType from '../../Functions/getComponentFromType.js';
|
|
14
11
|
import UiGlobals from '../../UiGlobals.js';
|
|
12
|
+
import { withDragSource, withDropTarget } from '../Hoc/withDnd.js';
|
|
15
13
|
import withDraggable from '../Hoc/withDraggable.js';
|
|
16
14
|
import AngleRight from '../Icons/AngleRight.js';
|
|
15
|
+
import RowDragHandle from './RowDragHandle.js';
|
|
17
16
|
import _ from 'lodash';
|
|
18
17
|
|
|
19
18
|
// This was broken out from Grid simply so we can memoize it
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
function GridRow(props) {
|
|
22
21
|
const {
|
|
23
22
|
columnsConfig,
|
|
24
23
|
columnProps,
|
|
@@ -28,6 +27,8 @@ export default function GridRow(props) {
|
|
|
28
27
|
bg,
|
|
29
28
|
item,
|
|
30
29
|
isInlineEditorShown,
|
|
30
|
+
isDragSource = false,
|
|
31
|
+
isOver = false,
|
|
31
32
|
} = props,
|
|
32
33
|
styles = UiGlobals.styles;
|
|
33
34
|
|
|
@@ -39,182 +40,187 @@ export default function GridRow(props) {
|
|
|
39
40
|
isPhantom = item.isPhantom,
|
|
40
41
|
hash = item?.hash || item;
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
if (props.dragSourceRef) {
|
|
44
|
+
rowProps.ref = props.dragSourceRef;
|
|
45
|
+
}
|
|
46
|
+
if (props.dropTargetRef) {
|
|
47
|
+
rowProps.ref = props.dropTargetRef;
|
|
48
|
+
}
|
|
49
|
+
return useMemo(() => {
|
|
50
|
+
const renderColumns = (item) => {
|
|
51
|
+
if (_.isArray(columnsConfig)) {
|
|
52
|
+
return _.map(columnsConfig, (config, key, all) => {
|
|
53
|
+
const propsToPass = columnProps[key] || {};
|
|
54
|
+
if (all.length === 1) {
|
|
55
|
+
propsToPass.w = '100%';
|
|
56
|
+
} else {
|
|
57
|
+
if (config.w) {
|
|
58
|
+
propsToPass.w = config.w;
|
|
59
|
+
} else if (config.flex) {
|
|
60
|
+
propsToPass.flex = config.flex;
|
|
61
|
+
propsToPass.minWidth = 100;
|
|
50
62
|
} else {
|
|
51
|
-
|
|
52
|
-
propsToPass.w = config.w;
|
|
53
|
-
} else if (config.flex) {
|
|
54
|
-
propsToPass.flex = config.flex;
|
|
55
|
-
propsToPass.minWidth = 100;
|
|
56
|
-
} else {
|
|
57
|
-
propsToPass.flex = 1;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
propsToPass.p = 1;
|
|
61
|
-
propsToPass.justifyContent = 'center';
|
|
62
|
-
|
|
63
|
-
if (isInlineEditorShown) {
|
|
64
|
-
propsToPass.minWidth = styles.INLINE_EDITOR_MIN_WIDTH;
|
|
63
|
+
propsToPass.flex = 1;
|
|
65
64
|
}
|
|
65
|
+
}
|
|
66
|
+
propsToPass.p = 1;
|
|
67
|
+
propsToPass.justifyContent = 'center';
|
|
66
68
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
if (_.isPlainObject(config)) {
|
|
72
|
-
if (config.renderer) {
|
|
73
|
-
const extraProps = _.omit(config, [
|
|
74
|
-
'columnId',
|
|
75
|
-
'header',
|
|
76
|
-
'fieldName',
|
|
77
|
-
'type',
|
|
78
|
-
'isEditable',
|
|
79
|
-
'editor',
|
|
80
|
-
'format',
|
|
81
|
-
'renderer',
|
|
82
|
-
'reorderable',
|
|
83
|
-
'resizable',
|
|
84
|
-
'sortable',
|
|
85
|
-
'w',
|
|
86
|
-
'flex',
|
|
87
|
-
'showDragHandles',
|
|
88
|
-
]);
|
|
69
|
+
if (isInlineEditorShown) {
|
|
70
|
+
propsToPass.minWidth = styles.INLINE_EDITOR_MIN_WIDTH;
|
|
71
|
+
}
|
|
89
72
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
73
|
+
let value;
|
|
74
|
+
if (_.isFunction(config)) {
|
|
75
|
+
return config(item, key);
|
|
76
|
+
}
|
|
77
|
+
if (_.isPlainObject(config)) {
|
|
78
|
+
if (config.renderer) {
|
|
79
|
+
const extraProps = _.omit(config, [
|
|
80
|
+
'columnId',
|
|
81
|
+
'header',
|
|
82
|
+
'fieldName',
|
|
83
|
+
'type',
|
|
84
|
+
'isEditable',
|
|
85
|
+
'editor',
|
|
86
|
+
'format',
|
|
87
|
+
'renderer',
|
|
88
|
+
'reorderable',
|
|
89
|
+
'resizable',
|
|
90
|
+
'sortable',
|
|
91
|
+
'w',
|
|
92
|
+
'flex',
|
|
93
|
+
'showDragHandles',
|
|
94
|
+
]);
|
|
99
95
|
|
|
100
|
-
|
|
96
|
+
if (!extraProps._web) {
|
|
97
|
+
extraProps._web = {};
|
|
98
|
+
}
|
|
99
|
+
if (!extraProps._web.style) {
|
|
100
|
+
extraProps._web.style = {};
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
value = property.displayValue;
|
|
106
|
-
const type = property?.viewerType?.type;
|
|
102
|
+
extraProps._web.style = {
|
|
103
|
+
userSelect: 'none',
|
|
104
|
+
};
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
alignSelf="center"
|
|
122
|
-
style={{
|
|
123
|
-
userSelect: 'none',
|
|
124
|
-
}}
|
|
125
|
-
fontSize={styles.GRID_CELL_FONTSIZE}
|
|
126
|
-
px={styles.GRID_CELL_PX}
|
|
127
|
-
py={styles.GRID_CELL_PY}
|
|
128
|
-
numberOfLines={1}
|
|
129
|
-
ellipsizeMode="head"
|
|
130
|
-
{...propsToPass}
|
|
131
|
-
{...elementProps}
|
|
132
|
-
/>;
|
|
106
|
+
return <Row key={key} {...propsToPass} {...extraProps}>{config.renderer(item)}</Row>;
|
|
107
|
+
}
|
|
108
|
+
if (config.fieldName) {
|
|
109
|
+
if (item?.properties && item.properties[config.fieldName]) {
|
|
110
|
+
const property = item.properties[config.fieldName];
|
|
111
|
+
value = property.displayValue;
|
|
112
|
+
const type = property?.viewerType?.type;
|
|
113
|
+
|
|
114
|
+
if (type) {
|
|
115
|
+
const Element = getComponentFromType(type);
|
|
116
|
+
const elementProps = {};
|
|
117
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
118
|
+
elementProps.textOverflow = 'ellipsis';
|
|
133
119
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
if (type.match(/(Tag|TagEditor)$/)) {
|
|
121
|
+
elementProps.isViewOnly = true; // TODO: this won't work for InlineGridEditor, bc that Grid can't use isViewOnly when actually editing
|
|
122
|
+
}
|
|
123
|
+
return <Element
|
|
124
|
+
value={value}
|
|
125
|
+
key={key}
|
|
126
|
+
overflow="hidden"
|
|
127
|
+
alignSelf="center"
|
|
128
|
+
style={{
|
|
129
|
+
userSelect: 'none',
|
|
130
|
+
}}
|
|
131
|
+
fontSize={styles.GRID_CELL_FONTSIZE}
|
|
132
|
+
px={styles.GRID_CELL_PX}
|
|
133
|
+
py={styles.GRID_CELL_PY}
|
|
134
|
+
numberOfLines={1}
|
|
135
|
+
ellipsizeMode="head"
|
|
136
|
+
{...propsToPass}
|
|
137
|
+
{...elementProps}
|
|
138
|
+
/>;
|
|
139
139
|
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const ix = fields.indexOf(config);
|
|
140
|
+
} else if (item[config.fieldName]) {
|
|
141
|
+
value = item[config.fieldName];
|
|
142
|
+
} else if (fields) {
|
|
143
|
+
const ix = fields.indexOf(config.fieldName);
|
|
145
144
|
value = item[ix];
|
|
146
|
-
} else {
|
|
147
|
-
value = item[config];
|
|
148
145
|
}
|
|
149
146
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
147
|
+
}
|
|
148
|
+
if (_.isString(config)) {
|
|
149
|
+
if (fields) {
|
|
150
|
+
const ix = fields.indexOf(config);
|
|
151
|
+
value = item[ix];
|
|
152
|
+
} else {
|
|
153
|
+
value = item[config];
|
|
156
154
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
item,
|
|
205
|
-
isPhantom,
|
|
206
|
-
hash, // this is an easy way to determine if the data has changed and the item needs to be rerendered
|
|
207
|
-
isInlineEditorShown,
|
|
208
|
-
]);
|
|
209
|
-
}
|
|
155
|
+
}
|
|
156
|
+
if (_.isFunction(value)) {
|
|
157
|
+
return value(key);
|
|
158
|
+
}
|
|
159
|
+
const elementProps = {};
|
|
160
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
161
|
+
elementProps.textOverflow = 'ellipsis';
|
|
162
|
+
}
|
|
163
|
+
return <Text
|
|
164
|
+
key={key}
|
|
165
|
+
overflow="hidden"
|
|
166
|
+
alignSelf="center"
|
|
167
|
+
style={{
|
|
168
|
+
userSelect: 'none',
|
|
169
|
+
}}
|
|
170
|
+
fontSize={styles.GRID_CELL_FONTSIZE}
|
|
171
|
+
px={styles.GRID_CELL_PX}
|
|
172
|
+
py={styles.GRID_CELL_PY}
|
|
173
|
+
numberOfLines={1}
|
|
174
|
+
ellipsizeMode="head"
|
|
175
|
+
{...elementProps}
|
|
176
|
+
{...propsToPass}
|
|
177
|
+
>{value}</Text>;
|
|
178
|
+
});
|
|
179
|
+
} else {
|
|
180
|
+
// TODO: if 'columnsConfig' is an object, parse its contents
|
|
181
|
+
throw new Error('Non-array columnsConfig not yet supported');
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
if (isOver) {
|
|
185
|
+
rowProps.borderWidth = 4;
|
|
186
|
+
rowProps.borderColor = '#0ff';
|
|
187
|
+
} else {
|
|
188
|
+
rowProps.borderWidth = 0;
|
|
189
|
+
rowProps.borderColor = null;
|
|
190
|
+
}
|
|
191
|
+
return <Row
|
|
192
|
+
alignItems="center"
|
|
193
|
+
flexGrow={1}
|
|
194
|
+
{...rowProps}
|
|
195
|
+
bg={bg}
|
|
196
|
+
key={hash}
|
|
197
|
+
>
|
|
198
|
+
{isDragSource && <RowDragHandle />}
|
|
199
|
+
{isPhantom && <Box position="absolute" bg="#f00" h={2} w={2} t={0} l={0} />}
|
|
200
|
+
|
|
201
|
+
{renderColumns(item)}
|
|
210
202
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
203
|
+
{!hideNavColumn && <AngleRight
|
|
204
|
+
color={styles.GRID_NAV_COLUMN_COLOR}
|
|
205
|
+
variant="ghost"
|
|
206
|
+
w={30}
|
|
207
|
+
alignSelf="center"
|
|
208
|
+
mx={3}
|
|
209
|
+
/>}
|
|
210
|
+
</Row>;
|
|
211
|
+
}, [
|
|
212
|
+
columnsConfig,
|
|
213
|
+
columnProps,
|
|
214
|
+
fields,
|
|
215
|
+
rowProps,
|
|
216
|
+
hideNavColumn,
|
|
217
|
+
bg,
|
|
218
|
+
item,
|
|
219
|
+
isPhantom,
|
|
220
|
+
hash, // this is an easy way to determine if the data has changed and the item needs to be rerendered
|
|
221
|
+
isInlineEditorShown,
|
|
222
|
+
isOver,
|
|
223
|
+
]);
|
|
218
224
|
}
|
|
219
225
|
|
|
220
|
-
export
|
|
226
|
+
export default withDraggable(withDragSource(withDropTarget(GridRow)));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Column,
|
|
3
|
+
Icon,
|
|
4
|
+
Row,
|
|
5
|
+
Text,
|
|
6
|
+
} from 'native-base';
|
|
7
|
+
import styles from '../../Styles/StyleSheets.js';
|
|
8
|
+
import GripVertical from '../Icons/GripVertical.js';
|
|
9
|
+
|
|
10
|
+
function RowDragHandle(props) {
|
|
11
|
+
return <Column
|
|
12
|
+
testID="HeaderReorderHandle"
|
|
13
|
+
bg="trueGray.100"
|
|
14
|
+
h="100%"
|
|
15
|
+
w={3}
|
|
16
|
+
alignItems="center"
|
|
17
|
+
justifyContent="center"
|
|
18
|
+
style={styles.ewResize}
|
|
19
|
+
>
|
|
20
|
+
<Icon as={GripVertical} testID="handle" size="xs" w="100%" h="100%" color="#ccc" />
|
|
21
|
+
</Column>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default RowDragHandle;
|
|
@@ -91,7 +91,11 @@ export default function withContextMenu(WrappedComponent) {
|
|
|
91
91
|
w: 20,
|
|
92
92
|
mr: 2,
|
|
93
93
|
};
|
|
94
|
-
|
|
94
|
+
if (React.isValidElement(icon)) {
|
|
95
|
+
icon = React.cloneElement(icon, {...iconProps});
|
|
96
|
+
} else {
|
|
97
|
+
icon = <Icon as={icon} {...iconProps} />;
|
|
98
|
+
}
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
// <div style={{
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { useDrag, useDrop } from 'react-dnd'; // https://react-dnd.github.io/react-dnd/about don't forget the wrapping <DndProvider /> as shown here: https://react-dnd.github.io/react-dnd/docs/api/dnd-provider
|
|
2
|
+
|
|
3
|
+
// This HOC allows components to be dragged and dropped onto another component.
|
|
4
|
+
// It doesn't contraint the moment of the preview item.
|
|
5
|
+
|
|
6
|
+
export function withDragSource(WrappedComponent) {
|
|
7
|
+
return (props) => {
|
|
8
|
+
|
|
9
|
+
if (!props.isDragSource) {
|
|
10
|
+
return <WrappedComponent {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!props.dragSourceType) {
|
|
14
|
+
throw Error('dragSourceType not defined');
|
|
15
|
+
}
|
|
16
|
+
if (!props.dragSourceItem) {
|
|
17
|
+
throw Error('dragSourceItem not defined');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
dragSourceType,
|
|
22
|
+
dragSourceItem,
|
|
23
|
+
} = props,
|
|
24
|
+
[dragState, dragSourceRef, dragPreviewRef] = useDrag(() => { // A specification object or a function that creates a specification object.
|
|
25
|
+
// The useDrag hook provides a way to wire your component into the DnD system as a drag source. By passing in a specification into useDrag, you declaratively describe the typeof draggable being generated, the itemobject representing the drag source, what props to collect, and more. The useDraghooks returns a few key items: a set of collected props, and refs that may be attached to drag source and drag preview elements
|
|
26
|
+
return {
|
|
27
|
+
type: dragSourceType, // Required. This must be either a string or a symbol. Only the drop targets registered for the same type will react to this item.
|
|
28
|
+
item: dragSourceItem, // Required (object or function).
|
|
29
|
+
// When an object, it is a plain JavaScript object describing the data being dragged. This is the only information available to the drop targets about the drag source so it's important to pick the minimal data they need to know. You may be tempted to put a complex reference here, but you should try very hard to avoid doing this because it couples the drag sources and drop targets. It's a good idea to use something like { id }.
|
|
30
|
+
// When a function, it is fired at the beginning of the drag operation and returns an object representing the drag operation (see first bullet). If null is returned, the drag operation is cancelled.
|
|
31
|
+
previewOptions: null, // Optional. A plain JavaScript object describing drag preview options.
|
|
32
|
+
options: null, // Optional. A plain object optionally containing any of the following properties:
|
|
33
|
+
// dropEffect: Optional: The type of drop effect to use on this drag. ("move" or "copy" are valid values.)
|
|
34
|
+
end: null, // (item, monitor) Optional. When the dragging stops, endis called. For every begin call, a corresponding end call is guaranteed. You may call monitor.didDrop() to check whether or not the drop was handled by a compatible drop target. If it was handled, and the drop target specified a drop result by returning a plain object from its drop()method, it will be available as monitor.getDropResult(). This method is a good place to fire a Flux action. Note: If the component is unmounted while dragging, componentparameter is set to be null.
|
|
35
|
+
canDrag: null, // (monitor): Optional. Use it to specify whether the dragging is currently allowed. If you want to always allow it, just omit this method. Specifying it is handy if you'd like to disable dragging based on some predicate over props. Note: You may not call monitor.canDrag()inside this method.
|
|
36
|
+
isDragging: null, // (monitor): Optional. By default, only the drag source that initiated the drag operation is considered to be dragging. You can override this behavior by defining a custom isDraggingmethod. It might return something like props.id === monitor.getItem().id. Do this if the original component may be unmounted during the dragging and later “resurrected” with a different parent. For example, when moving a card across the lists in a Kanban board, you want it to retain the dragged appearance—even though technically, the component gets unmounted and a different one gets mounted every time you move it to another list. Note: You may not call monitor.isDragging()inside this method.
|
|
37
|
+
collect: (monitor, props) => { // Optional. The collecting function. It should return a plain object of the props to return for injection into your component. It receives two parameters, monitor and props. Read the overview for an introduction to the monitors and the collecting function. See the collecting function described in detail in the next section.
|
|
38
|
+
// monitor fn determines which props from dnd state get passed
|
|
39
|
+
return {
|
|
40
|
+
canDrag: !!monitor.canDrag(), // Returns trueif no drag operation is in progress, and the owner's canDrag() returns true or is not defined.
|
|
41
|
+
isDragging: !!monitor.isDragging(), // Returns trueif a drag operation is in progress, and either the owner initiated the drag, or its isDragging() is defined and returns true.
|
|
42
|
+
// type: monitor.getItemType(), // Returns a string or a symbol identifying the type of the current dragged item. Returns null if no item is being dragged.
|
|
43
|
+
// item: monitor.getItem(), // Returns a plain object representing the currently dragged item. Every drag source must specify it by returning an object from its beginDrag()method. Returns nullif no item is being dragged.
|
|
44
|
+
// dropResult: monitor.getDropResult(), // Returns a plain object representing the last recorded drop result. The drop targets may optionally specify it by returning an object from their drop()methods. When a chain of drop()is dispatched for the nested targets, bottom up, any parent that explicitly returns its own result from drop()overrides the child drop result previously set by the child. Returns nullif called outside endDrag().
|
|
45
|
+
// didDrop: !!monitor.didDrop(), // Returns trueif some drop target has handled the drop event, falseotherwise. Even if a target did not return a drop result, didDrop()returns true. Use it inside endDrag()to test whether any drop target has handled the drop. Returns falseif called outside endDrag().
|
|
46
|
+
// initialClientOffset: monitor.getInitialClientOffset(), // Returns the { x, y }client offset of the pointer at the time when the current drag operation has started. Returns nullif no item is being dragged.
|
|
47
|
+
// initialSourceClientOffset: monitor.getInitialSourceClientOffset(), // Returns the { x, y }client offset of the drag source component's root DOM node at the time when the current drag operation has started. Returns nullif no item is being dragged.
|
|
48
|
+
// clientOffset: monitor.getClientOffset(), // Returns the last recorded { x, y }client offset of the pointer while a drag operation is in progress. Returns nullif no item is being dragged.
|
|
49
|
+
// differenceFromInitialOffset: monitor.getDifferenceFromInitialOffset(), // Returns the { x, y }difference between the last recorded client offset of the pointer and the client offset when the current drag operation has started. Returns nullif no item is being dragged.
|
|
50
|
+
// sourceClientOffset: monitor.getSourceClientOffset(), // Returns the projected { x, y }client offset of the drag source component's root DOM node, based on its position at the time when the current drag operation has started, and the movement difference. Returns nullif no item is being dragged.
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
{
|
|
56
|
+
canDrag,
|
|
57
|
+
isDragging,
|
|
58
|
+
// type,
|
|
59
|
+
// item,
|
|
60
|
+
// dropResult,
|
|
61
|
+
// didDrop,
|
|
62
|
+
// initialClientOffset,
|
|
63
|
+
// initialSourceClientOffset,
|
|
64
|
+
// clientOffset,
|
|
65
|
+
// differenceFromInitialOffset,
|
|
66
|
+
// sourceClientOffset,
|
|
67
|
+
} = dragState;
|
|
68
|
+
|
|
69
|
+
return <WrappedComponent
|
|
70
|
+
canDrag={canDrag}
|
|
71
|
+
isDragging={isDragging}
|
|
72
|
+
dragSourceRef={dragSourceRef}
|
|
73
|
+
{...props}
|
|
74
|
+
/>;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
export function withDropTarget(WrappedComponent) {
|
|
80
|
+
return (props) => {
|
|
81
|
+
if (!props.isDropTarget) {
|
|
82
|
+
return <WrappedComponent {...props} />;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!props.dropTargetAccept) {
|
|
86
|
+
throw Error('dropTargetAccept not defined');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const {
|
|
90
|
+
dropTargetAccept,
|
|
91
|
+
onDrop = null,
|
|
92
|
+
} = props,
|
|
93
|
+
[dropState, dropTargetRef] = useDrop(() => { // A specification object or a function that creates a specification object.
|
|
94
|
+
// The useDrophook provides a way for you to wire in your component into the DnD system as a drop target. By passing in a specification into the useDrophook, you can specify including what types of data items the drop-target will accept, what props to collect, and more. This function returns an array containing a ref to attach to the Drop Target node and the collected props.
|
|
95
|
+
return {
|
|
96
|
+
accept: dropTargetAccept, // Required. A string, a symbol, or an array of either. This drop target will only react to the items produced by the drag sources of the specified type or types. Read the overview to learn more about the items and types.
|
|
97
|
+
// options: null, // Optional. A plain object. If some of the props to your component are not scalar (that is, are not primitive values or functions), specifying a custom arePropsEqual(props, otherProps) function inside the options object can improve the performance. Unless you have performance problems, don't worry about it.
|
|
98
|
+
drop: onDrop, // (item, monitor): Optional. Called when a compatible item is dropped on the target. You may either return undefined, or a plain object. If you return an object, it is going to become the drop result and will be available to the drag source in its endDragmethod as monitor.getDropResult(). This is useful in case you want to perform different actions depending on which target received the drop. If you have nested drop targets, you can test whether a nested target has already handled dropby checking monitor.didDrop()and monitor.getDropResult(). Both this method and the source's endDragmethod are good places to fire Flux actions. This method will not be called if canDrop()is defined and returns false.
|
|
99
|
+
// hover: null, // (item, monitor): Optional. Called when an item is hovered over the component. You can check monitor.isOver({ shallow: true })to test whether the hover happens over only the current target, or over a nested one. Unlike drop(), this method will be called even if canDrop()is defined and returns false. You can check monitor.canDrop()to test whether this is the case.
|
|
100
|
+
// canDrop: null, // (item, monitor): Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
|
|
101
|
+
collect: (monitor, props) => { // Optional. The collecting function. It should return a plain object of the props to return for injection into your component. It receives two parameters, monitorand props. Read the overview for an introduction to the monitors and the collecting function. See the collecting function described in detail in the next section.
|
|
102
|
+
return {
|
|
103
|
+
canDrop: !!monitor.canDrop(),
|
|
104
|
+
isOver: !!monitor.isOver(),
|
|
105
|
+
// didDrop: !!monitor.didDrop(),
|
|
106
|
+
// clientOffset: monitor.getClientOffset(),
|
|
107
|
+
// differenceFromInitialOffset: monitor.getDifferenceFromInitialOffset(),
|
|
108
|
+
// dropResult: monitor.getDropResult(),
|
|
109
|
+
// handlerId: monitor.getHandlerId(),
|
|
110
|
+
// initialClientOffset: monitor.getInitialClientOffset(),
|
|
111
|
+
// initialSourceClientOffset: monitor.getInitialSourceClientOffset(),
|
|
112
|
+
// receiveHandlerId
|
|
113
|
+
// subscribeToStateChange
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}),
|
|
118
|
+
{
|
|
119
|
+
canDrop,
|
|
120
|
+
isOver,
|
|
121
|
+
// didDrop,
|
|
122
|
+
// clientOffset,
|
|
123
|
+
// differenceFromInitialOffset,
|
|
124
|
+
// dropResult,
|
|
125
|
+
// handlerId,
|
|
126
|
+
// initialClientOffset,
|
|
127
|
+
// initialSourceClientOffset,
|
|
128
|
+
} = dropState;
|
|
129
|
+
|
|
130
|
+
return <WrappedComponent
|
|
131
|
+
canDrop={canDrop}
|
|
132
|
+
isOver={isOver}
|
|
133
|
+
dropTargetRef={dropTargetRef}
|
|
134
|
+
{...props}
|
|
135
|
+
/>;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -23,6 +23,10 @@ import getComponentFromType from '../../Functions/getComponentFromType.js';
|
|
|
23
23
|
export default function withDraggable(WrappedComponent) {
|
|
24
24
|
return (props) => {
|
|
25
25
|
|
|
26
|
+
if (!props.isDraggable) {
|
|
27
|
+
return <WrappedComponent {...props} />;
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
const {
|
|
27
31
|
// extract and pass
|
|
28
32
|
onDragStart,
|
|
@@ -327,12 +327,12 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
327
327
|
{...propsToPass}
|
|
328
328
|
disablePresetButtons={false}
|
|
329
329
|
contextMenuItems={[
|
|
330
|
-
...contextMenuItems,
|
|
331
330
|
...localContextMenuItems,
|
|
331
|
+
...contextMenuItems,
|
|
332
332
|
]}
|
|
333
333
|
additionalToolbarButtons={[
|
|
334
|
-
...additionalToolbarButtons,
|
|
335
334
|
...localAdditionalToolbarButtons,
|
|
335
|
+
...additionalToolbarButtons,
|
|
336
336
|
]}
|
|
337
337
|
onChangeColumnsConfig={onChangeColumnsConfigDecorator}
|
|
338
338
|
/>
|
package/src/Components/index.js
CHANGED
|
@@ -203,6 +203,7 @@ import DataMgt from './Screens/DataMgt.js';
|
|
|
203
203
|
import Date from './Form/Field/Date.js';
|
|
204
204
|
import DateRange from './Filter/DateRange.js';
|
|
205
205
|
import DisplayField from './Form/Field/DisplayField.js';
|
|
206
|
+
import ExpandButton from './Buttons/ExpandButton.js';
|
|
206
207
|
import FieldSet from './Form/FieldSet.js';
|
|
207
208
|
import FiltersForm from './Form/FiltersForm.js';
|
|
208
209
|
// import FiltersToolbar from '../Components/Toolbar/FiltersToolbar.js';
|
|
@@ -436,6 +437,7 @@ const components = {
|
|
|
436
437
|
Date,
|
|
437
438
|
DateRange,
|
|
438
439
|
DisplayField,
|
|
440
|
+
ExpandButton,
|
|
439
441
|
FieldSet,
|
|
440
442
|
FiltersForm,
|
|
441
443
|
// FiltersToolbar,
|