@onehat/ui 0.2.56 → 0.2.58
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/cypress/plugins/index.js +2 -0
- package/cypress/support/commands.js +2 -0
- package/cypress/support/e2e.js +2 -0
- package/cypress.config.js +41 -0
- package/package.json +34 -25
- package/src/Components/Form/Form.js +1 -1
- package/src/Components/Grid/Grid.js +12 -5
- package/src/Components/Grid/GridHeaderRow.js +5 -2
- package/src/Components/Grid/GridRow.js +2 -0
- package/src/Components/Hoc/withContextMenu.js +1 -1
- package/src/Components/Messages/WaitMessage.js +19 -7
- package/src/Components/Tree/Tree.js +813 -0
- package/src/Components/Tree/TreeNode.js +95 -0
- package/src/Constants/Styles.js +4 -0
- package/src/Functions/BankersRound.js +1 -1
- package/src/Functions/getTokenHeaders.js +2 -2
- package/src/UiGlobals.js +6 -1
- package/src/Components/Icons/AddressBook.js +0 -14
- package/src/Components/Icons/Alt.js +0 -17
- package/src/Components/Icons/AngleLeft.js +0 -18
- package/src/Components/Icons/AngleRight.js +0 -18
- package/src/Components/Icons/AnglesLeft.js +0 -18
- package/src/Components/Icons/AnglesRight.js +0 -18
- package/src/Components/Icons/Asterisk.js +0 -14
- package/src/Components/Icons/Ban.js +0 -18
- package/src/Components/Icons/Bars.js +0 -14
- package/src/Components/Icons/BigCircle.js +0 -17
- package/src/Components/Icons/Book.js +0 -14
- package/src/Components/Icons/BookOpen.js +0 -14
- package/src/Components/Icons/Bug.js +0 -14
- package/src/Components/Icons/Building.js +0 -14
- package/src/Components/Icons/Calendar.js +0 -18
- package/src/Components/Icons/Calendar2.js +0 -18
- package/src/Components/Icons/CalendarDays.js +0 -18
- package/src/Components/Icons/Camera.js +0 -18
- package/src/Components/Icons/CaretDown.js +0 -18
- package/src/Components/Icons/CaretUp.js +0 -18
- package/src/Components/Icons/CartPlus.js +0 -14
- package/src/Components/Icons/CartShopping.js +0 -14
- package/src/Components/Icons/CashRegister.js +0 -14
- package/src/Components/Icons/ChartLine.js +0 -14
- package/src/Components/Icons/Check.js +0 -14
- package/src/Components/Icons/CheckDouble.js +0 -14
- package/src/Components/Icons/ChevronDown.js +0 -14
- package/src/Components/Icons/ChevronLeft.js +0 -14
- package/src/Components/Icons/ChevronRight.js +0 -14
- package/src/Components/Icons/ChevronUp.js +0 -14
- package/src/Components/Icons/CircleArrowRight.js +0 -14
- package/src/Components/Icons/CircleExclamation.js +0 -18
- package/src/Components/Icons/CircleInfo.js +0 -14
- package/src/Components/Icons/CircleQuestion.js +0 -14
- package/src/Components/Icons/CircleXmark.js +0 -14
- package/src/Components/Icons/CircleXmarkRegular.js +0 -14
- package/src/Components/Icons/Clipboard.js +0 -18
- package/src/Components/Icons/Clock.js +0 -14
- package/src/Components/Icons/ClockRegular.js +0 -14
- package/src/Components/Icons/ClockRotateLeft.js +0 -14
- package/src/Components/Icons/Clone.js +0 -14
- package/src/Components/Icons/Comment.js +0 -14
- package/src/Components/Icons/CommentRegular.js +0 -14
- package/src/Components/Icons/Comments.js +0 -14
- package/src/Components/Icons/CommentsRegular.js +0 -14
- package/src/Components/Icons/Copyright.js +0 -14
- package/src/Components/Icons/Duplicate.js +0 -18
- package/src/Components/Icons/Edit.js +0 -18
- package/src/Components/Icons/EllipsisVertical.js +0 -18
- package/src/Components/Icons/Envelope.js +0 -14
- package/src/Components/Icons/EnvelopeRegular.js +0 -14
- package/src/Components/Icons/Exclamation.js +0 -14
- package/src/Components/Icons/Expand.js +0 -14
- package/src/Components/Icons/Eye.js +0 -18
- package/src/Components/Icons/EyeSlash.js +0 -14
- package/src/Components/Icons/File.js +0 -18
- package/src/Components/Icons/FloppyDiskRegular.js +0 -14
- package/src/Components/Icons/Gear.js +0 -18
- package/src/Components/Icons/Gift.js +0 -14
- package/src/Components/Icons/Grip.js +0 -18
- package/src/Components/Icons/GripLines.js +0 -18
- package/src/Components/Icons/GripLinesVertical.js +0 -18
- package/src/Components/Icons/GripVertical.js +0 -18
- package/src/Components/Icons/Hammer.js +0 -14
- package/src/Components/Icons/Hand.js +0 -14
- package/src/Components/Icons/House.js +0 -14
- package/src/Components/Icons/Info.js +0 -14
- package/src/Components/Icons/ItunesNote.js +0 -14
- package/src/Components/Icons/List.js +0 -14
- package/src/Components/Icons/ListCheck.js +0 -14
- package/src/Components/Icons/LocationDot.js +0 -14
- package/src/Components/Icons/Loop.js +0 -17
- package/src/Components/Icons/Loop1.js +0 -18
- package/src/Components/Icons/LoopAll.js +0 -18
- package/src/Components/Icons/Maximize.js +0 -14
- package/src/Components/Icons/Microphone.js +0 -14
- package/src/Components/Icons/Minimize.js +0 -14
- package/src/Components/Icons/Minus.js +0 -18
- package/src/Components/Icons/MobileScreenButton.js +0 -14
- package/src/Components/Icons/MoneyBill.js +0 -14
- package/src/Components/Icons/MoneyBillWave.js +0 -14
- package/src/Components/Icons/Mouth.js +0 -24
- package/src/Components/Icons/Music.js +0 -14
- package/src/Components/Icons/Na.js +0 -17
- package/src/Components/Icons/NoLoop.js +0 -24
- package/src/Components/Icons/NoReorderRows.js +0 -25
- package/src/Components/Icons/ObjectGroupRegular.js +0 -14
- package/src/Components/Icons/Pause.js +0 -14
- package/src/Components/Icons/Pencil.js +0 -18
- package/src/Components/Icons/Phone.js +0 -14
- package/src/Components/Icons/Play.js +0 -14
- package/src/Components/Icons/Plus.js +0 -18
- package/src/Components/Icons/Presentation.js +0 -19
- package/src/Components/Icons/Print.js +0 -18
- package/src/Components/Icons/Question.js +0 -14
- package/src/Components/Icons/Rate-.25x.js +0 -20
- package/src/Components/Icons/Rate-.5x.js +0 -19
- package/src/Components/Icons/Rate-.75x.js +0 -19
- package/src/Components/Icons/Rate-1.25x.js +0 -20
- package/src/Components/Icons/Rate-1.5x.js +0 -19
- package/src/Components/Icons/Rate-1.75x.js +0 -19
- package/src/Components/Icons/Rate-1x.js +0 -19
- package/src/Components/Icons/Rate-2x.js +0 -19
- package/src/Components/Icons/RateIcon-.25x.js +0 -20
- package/src/Components/Icons/RateIcon-.5x.js +0 -19
- package/src/Components/Icons/RateIcon-.75x.js +0 -19
- package/src/Components/Icons/RateIcon-1.25x.js +0 -20
- package/src/Components/Icons/RateIcon-1.5x.js +0 -19
- package/src/Components/Icons/RateIcon-1.75x.js +0 -19
- package/src/Components/Icons/RateIcon-1x.js +0 -19
- package/src/Components/Icons/RateIcon-2x.js +0 -19
- package/src/Components/Icons/RectangleXmark.js +0 -14
- package/src/Components/Icons/RectangleXmarkRegular.js +0 -14
- package/src/Components/Icons/ReorderRows.js +0 -21
- package/src/Components/Icons/RightFromBracket.js +0 -14
- package/src/Components/Icons/RightToBracket.js +0 -14
- package/src/Components/Icons/Rotate.js +0 -18
- package/src/Components/Icons/RotateLeft.js +0 -14
- package/src/Components/Icons/RotateRight.js +0 -18
- package/src/Components/Icons/ScrewdriverWrench.js +0 -14
- package/src/Components/Icons/Scroll.js +0 -14
- package/src/Components/Icons/Share.js +0 -14
- package/src/Components/Icons/Shop.js +0 -14
- package/src/Components/Icons/SortDown.js +0 -14
- package/src/Components/Icons/SortUp.js +0 -18
- package/src/Components/Icons/Square.js +0 -14
- package/src/Components/Icons/SquareCheck.js +0 -14
- package/src/Components/Icons/SquareCheckRegular.js +0 -14
- package/src/Components/Icons/SquareMinus.js +0 -18
- package/src/Components/Icons/SquareRegular.js +0 -14
- package/src/Components/Icons/Store.js +0 -14
- package/src/Components/Icons/ThumbsDown.js +0 -14
- package/src/Components/Icons/ThumbsDownRegular.js +0 -14
- package/src/Components/Icons/ThumbsUp.js +0 -14
- package/src/Components/Icons/ThumbsUpRegular.js +0 -14
- package/src/Components/Icons/Trash.js +0 -18
- package/src/Components/Icons/TrashCan.js +0 -18
- package/src/Components/Icons/TriangleExclamation.js +0 -18
- package/src/Components/Icons/Truck.js +0 -14
- package/src/Components/Icons/TruckFast.js +0 -14
- package/src/Components/Icons/User.js +0 -14
- package/src/Components/Icons/UserGroup.js +0 -14
- package/src/Components/Icons/UserPlus.js +0 -14
- package/src/Components/Icons/UserSecret.js +0 -14
- package/src/Components/Icons/X.js +0 -14
- package/src/Components/Icons/Xmark.js +0 -14
|
@@ -0,0 +1,813 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, useMemo, } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Column,
|
|
4
|
+
FlatList,
|
|
5
|
+
Pressable,
|
|
6
|
+
Icon,
|
|
7
|
+
Row,
|
|
8
|
+
Text,
|
|
9
|
+
} from 'native-base';
|
|
10
|
+
import {
|
|
11
|
+
SELECTION_MODE_SINGLE,
|
|
12
|
+
SELECTION_MODE_MULTI,
|
|
13
|
+
} from '../../Constants/Selection.js';
|
|
14
|
+
import {
|
|
15
|
+
VERTICAL,
|
|
16
|
+
} from '../../Constants/Directions.js';
|
|
17
|
+
import {
|
|
18
|
+
DROP_POSITION_BEFORE,
|
|
19
|
+
DROP_POSITION_AFTER,
|
|
20
|
+
} from '../../Constants/Tree.js';
|
|
21
|
+
import * as colourMixer from '@k-renwick/colour-mixer'
|
|
22
|
+
import UiGlobals from '../../UiGlobals.js';
|
|
23
|
+
import useForceUpdate from '../../Hooks/useForceUpdate.js';
|
|
24
|
+
import withContextMenu from '../Hoc/withContextMenu.js';
|
|
25
|
+
import withAlert from '../Hoc/withAlert.js';
|
|
26
|
+
import withData from '../Hoc/withData.js';
|
|
27
|
+
import withEvents from '../Hoc/withEvents.js';
|
|
28
|
+
import withSideEditor from '../Hoc/withSideEditor.js';
|
|
29
|
+
import withFilters from '../Hoc/withFilters.js';
|
|
30
|
+
import withPresetButtons from '../Hoc/withPresetButtons.js';
|
|
31
|
+
import withMultiSelection from '../Hoc/withMultiSelection.js';
|
|
32
|
+
import withSelection from '../Hoc/withSelection.js';
|
|
33
|
+
import withWindowedEditor from '../Hoc/withWindowedEditor.js';
|
|
34
|
+
import withInlineEditor from '../Hoc/withInlineEditor.js';
|
|
35
|
+
import testProps from '../../Functions/testProps.js';
|
|
36
|
+
import nbToRgb from '../../Functions/nbToRgb.js';
|
|
37
|
+
import TreeHeaderRow from './TreeHeaderRow.js';
|
|
38
|
+
import TreeNode, { ReorderableTreeNode } from './TreeNode.js';
|
|
39
|
+
import IconButton from '../Buttons/IconButton.js';
|
|
40
|
+
import PaginationToolbar from '../Toolbar/PaginationToolbar.js';
|
|
41
|
+
import NoRecordsFound from './NoRecordsFound.js';
|
|
42
|
+
import Toolbar from '../Toolbar/Toolbar.js';
|
|
43
|
+
import NoReorderRows from '../Icons/NoReorderRows.js';
|
|
44
|
+
import ReorderRows from '../Icons/ReorderRows.js';
|
|
45
|
+
import _ from 'lodash';
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// Tree requires the use of HOC withSelection() whenever it's used.
|
|
49
|
+
// The default export is *with* the HOC. A separate *raw* component is
|
|
50
|
+
// exported which can be combined with many HOCs for various functionality.
|
|
51
|
+
|
|
52
|
+
export function Tree(props) {
|
|
53
|
+
const {
|
|
54
|
+
isRootVisible = true,
|
|
55
|
+
getChildParams = () => { // returns params needed to get child nodes from server (getEquipment, getRentalEquipment, etc). This is primarily to limit results, as different kinds of views are only interested in certain types of nodes in the returned data.
|
|
56
|
+
return {};
|
|
57
|
+
},
|
|
58
|
+
getNodeText = (item) => { // extracts model/data and decides what the row text should be
|
|
59
|
+
return item.displayValue;
|
|
60
|
+
},
|
|
61
|
+
getNodeType, // extracts model/data and decides what kind of node this should be. Helper for getNodeIcon
|
|
62
|
+
getNodeIcon,
|
|
63
|
+
nodeProps = (item) => {
|
|
64
|
+
return {};
|
|
65
|
+
},
|
|
66
|
+
noneFoundText,
|
|
67
|
+
disableLoadingIndicator = false,
|
|
68
|
+
disableSelectorSelected = false,
|
|
69
|
+
showHovers = true,
|
|
70
|
+
canNodesReorder = false,
|
|
71
|
+
allowToggleSelection = true, // i.e. single click with no shift key toggles the selection of the node clicked on
|
|
72
|
+
disableBottomToolbar = false,
|
|
73
|
+
bottomToolbar = null,
|
|
74
|
+
topToolbar = null,
|
|
75
|
+
additionalToolbarButtons = [],
|
|
76
|
+
|
|
77
|
+
// withEditor
|
|
78
|
+
onAdd,
|
|
79
|
+
onEdit,
|
|
80
|
+
onDelete,
|
|
81
|
+
onView,
|
|
82
|
+
onDuplicate,
|
|
83
|
+
onReset,
|
|
84
|
+
onContextMenu,
|
|
85
|
+
|
|
86
|
+
// withData
|
|
87
|
+
Repository,
|
|
88
|
+
data,
|
|
89
|
+
fields,
|
|
90
|
+
idField,
|
|
91
|
+
displayField,
|
|
92
|
+
idIx,
|
|
93
|
+
displayIx,
|
|
94
|
+
|
|
95
|
+
// withSelection
|
|
96
|
+
selection,
|
|
97
|
+
setSelection,
|
|
98
|
+
selectionMode,
|
|
99
|
+
removeFromSelection,
|
|
100
|
+
addToSelection,
|
|
101
|
+
deselectAll,
|
|
102
|
+
selectRangeTo,
|
|
103
|
+
isInSelection,
|
|
104
|
+
noSelectorMeansNoResults = false,
|
|
105
|
+
|
|
106
|
+
// DataMgt
|
|
107
|
+
selectorId,
|
|
108
|
+
selectorSelected,
|
|
109
|
+
|
|
110
|
+
} = props,
|
|
111
|
+
styles = UiGlobals.styles,
|
|
112
|
+
forceUpdate = useForceUpdate(),
|
|
113
|
+
treeRef = useRef(),
|
|
114
|
+
[isReady, setIsReady] = useState(false),
|
|
115
|
+
[isLoading, setIsLoading] = useState(false),
|
|
116
|
+
[isReorderMode, setIsReorderMode] = useState(false),
|
|
117
|
+
[treeNodeData, setTreeNodeData] = useState({}),
|
|
118
|
+
[dragNodeSlot, setDragNodeSlot] = useState(null),
|
|
119
|
+
[dragNodeIx, setDragNodeIx] = useState(),
|
|
120
|
+
onNodeClick = (item, e) => {
|
|
121
|
+
const
|
|
122
|
+
{
|
|
123
|
+
shiftKey,
|
|
124
|
+
metaKey,
|
|
125
|
+
} = e;
|
|
126
|
+
|
|
127
|
+
if (selectionMode === SELECTION_MODE_MULTI) {
|
|
128
|
+
if (shiftKey) {
|
|
129
|
+
if (isInSelection(item)) {
|
|
130
|
+
removeFromSelection(item);
|
|
131
|
+
} else {
|
|
132
|
+
selectRangeTo(item);
|
|
133
|
+
}
|
|
134
|
+
} else if (metaKey) {
|
|
135
|
+
if (isInSelection(item)) {
|
|
136
|
+
// Already selected
|
|
137
|
+
if (allowToggleSelection) {
|
|
138
|
+
removeFromSelection(item);
|
|
139
|
+
} else {
|
|
140
|
+
// Do nothing.
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
addToSelection(item);
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
if (isInSelection(item)) {
|
|
147
|
+
// Already selected
|
|
148
|
+
if (allowToggleSelection) {
|
|
149
|
+
removeFromSelection(item);
|
|
150
|
+
} else {
|
|
151
|
+
// Do nothing.
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
// select just this one
|
|
155
|
+
setSelection([item]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
// selectionMode is SELECTION_MODE_SINGLE
|
|
160
|
+
let newSelection = selection;
|
|
161
|
+
if (isInSelection(item)) {
|
|
162
|
+
// Already selected
|
|
163
|
+
if (allowToggleSelection) {
|
|
164
|
+
// Create empty selection
|
|
165
|
+
newSelection = [];
|
|
166
|
+
} else {
|
|
167
|
+
// Do nothing.
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
// Select it alone
|
|
171
|
+
newSelection = [item];
|
|
172
|
+
}
|
|
173
|
+
if (newSelection) {
|
|
174
|
+
setSelection(newSelection);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
onRefresh = () => {
|
|
179
|
+
if (!Repository) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const promise = Repository.reload();
|
|
183
|
+
if (promise) { // Some repository types don't use promises
|
|
184
|
+
promise.then(() => {
|
|
185
|
+
setIsLoading(false);
|
|
186
|
+
forceUpdate();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
getFooterToolbarItems = () => {
|
|
191
|
+
const
|
|
192
|
+
iconButtonProps = {
|
|
193
|
+
_hover: {
|
|
194
|
+
bg: 'trueGray.400',
|
|
195
|
+
},
|
|
196
|
+
mx: 1,
|
|
197
|
+
px: 3,
|
|
198
|
+
},
|
|
199
|
+
iconProps = {
|
|
200
|
+
alignSelf: 'center',
|
|
201
|
+
size: styles.TREE_TOOLBAR_ITEMS_ICON_SIZE,
|
|
202
|
+
h: 20,
|
|
203
|
+
w: 20,
|
|
204
|
+
},
|
|
205
|
+
items = _.map(additionalToolbarButtons, (config, ix) => {
|
|
206
|
+
let {
|
|
207
|
+
text,
|
|
208
|
+
handler,
|
|
209
|
+
icon = null,
|
|
210
|
+
isDisabled = false,
|
|
211
|
+
} = config;
|
|
212
|
+
if (icon) {
|
|
213
|
+
const thisIconProps = {
|
|
214
|
+
color: isDisabled ? styles.TREE_TOOLBAR_ITEMS_DISABLED_COLOR : styles.TREE_TOOLBAR_ITEMS_COLOR,
|
|
215
|
+
};
|
|
216
|
+
icon = React.cloneElement(icon, {...iconProps, ...thisIconProps});
|
|
217
|
+
}
|
|
218
|
+
return <IconButton
|
|
219
|
+
key={ix}
|
|
220
|
+
{...iconButtonProps}
|
|
221
|
+
onPress={handler}
|
|
222
|
+
icon={icon}
|
|
223
|
+
isDisabled={isDisabled}
|
|
224
|
+
tooltip={text}
|
|
225
|
+
/>;
|
|
226
|
+
});
|
|
227
|
+
if (canNodesReorder) {
|
|
228
|
+
items.unshift(<IconButton
|
|
229
|
+
key="reorderBtn"
|
|
230
|
+
{...iconButtonProps}
|
|
231
|
+
onPress={() => setIsReorderMode(!isReorderMode)}
|
|
232
|
+
icon={<Icon as={isReorderMode ? NoReorderRows : ReorderRows} color={styles.TREE_TOOLBAR_ITEMS_COLOR} />}
|
|
233
|
+
/>);
|
|
234
|
+
}
|
|
235
|
+
return items;
|
|
236
|
+
},
|
|
237
|
+
renderNode = (itemData) => {
|
|
238
|
+
const item = itemData.item;
|
|
239
|
+
if (item.isDestroyed) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
// TODO: Figure out these vars
|
|
245
|
+
// icon (optional)
|
|
246
|
+
// onToggle (handler for if expand/collapse icon is clicked)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
let nodeProps = getNodeProps && !isHeaderNode ? getNodeProps(item) : {},
|
|
251
|
+
isSelected = !isHeaderNode && isInSelection(item);
|
|
252
|
+
|
|
253
|
+
return <Pressable
|
|
254
|
+
// {...testProps(Repository ? Repository.schema.name + '-' + item.id : item.id)}
|
|
255
|
+
onPress={(e) => {
|
|
256
|
+
if (e.preventDefault && e.cancelable) {
|
|
257
|
+
e.preventDefault();
|
|
258
|
+
}
|
|
259
|
+
if (isReorderMode) {
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
switch (e.detail) {
|
|
263
|
+
case 1: // single click
|
|
264
|
+
onNodeClick(item, e); // sets selection
|
|
265
|
+
break;
|
|
266
|
+
case 2: // double click
|
|
267
|
+
if (!isSelected) { // If a row was already selected when double-clicked, the first click will deselect it,
|
|
268
|
+
onNodeClick(item, e); // so reselect it
|
|
269
|
+
}
|
|
270
|
+
if (onEdit) {
|
|
271
|
+
onEdit();
|
|
272
|
+
}
|
|
273
|
+
break;
|
|
274
|
+
case 3: // triple click
|
|
275
|
+
break;
|
|
276
|
+
default:
|
|
277
|
+
}
|
|
278
|
+
}}
|
|
279
|
+
onLongPress={(e) => {
|
|
280
|
+
if (e.preventDefault && e.cancelable) {
|
|
281
|
+
e.preventDefault();
|
|
282
|
+
}
|
|
283
|
+
if (isReorderMode) {
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// context menu
|
|
288
|
+
const selection = [item];
|
|
289
|
+
setSelection(selection);
|
|
290
|
+
if (onContextMenu) {
|
|
291
|
+
onContextMenu(item, e, selection, setSelection);
|
|
292
|
+
}
|
|
293
|
+
}}
|
|
294
|
+
flexDirection="row"
|
|
295
|
+
flexGrow={1}
|
|
296
|
+
>
|
|
297
|
+
{({
|
|
298
|
+
isHovered,
|
|
299
|
+
isFocused,
|
|
300
|
+
isPressed,
|
|
301
|
+
}) => {
|
|
302
|
+
let bg = nodeProps.bg || styles.TREE_NODE_BG,
|
|
303
|
+
mixWith;
|
|
304
|
+
if (isSelected) {
|
|
305
|
+
if (showHovers && isHovered) {
|
|
306
|
+
mixWith = styles.TREE_NODE_SELECTED_HOVER_BG;
|
|
307
|
+
} else {
|
|
308
|
+
mixWith = styles.TREE_NODE_SELECTED_BG;
|
|
309
|
+
}
|
|
310
|
+
} else if (showHovers && isHovered) {
|
|
311
|
+
mixWith = styles.TREE_NODE_HOVER_BG;
|
|
312
|
+
}
|
|
313
|
+
if (mixWith) {
|
|
314
|
+
const
|
|
315
|
+
mixWithObj = nbToRgb(mixWith),
|
|
316
|
+
ratio = mixWithObj.alpha ? 1 - mixWithObj.alpha : 0.5;
|
|
317
|
+
bg = colourMixer.blend(bg, ratio, mixWithObj.color);
|
|
318
|
+
}
|
|
319
|
+
let WhichTreeNode = TreeNode,
|
|
320
|
+
rowReorderProps = {};
|
|
321
|
+
if (canNodesReorder && isReorderMode) {
|
|
322
|
+
WhichTreeNode = ReorderableTreeNode;
|
|
323
|
+
rowReorderProps = {
|
|
324
|
+
mode: VERTICAL,
|
|
325
|
+
onDragStart: onNodeReorderDragStart,
|
|
326
|
+
onDrag: onNodeReorderDrag,
|
|
327
|
+
onDragStop: onNodeReorderDragStop,
|
|
328
|
+
proxyParent: treeRef.current?.getScrollableNode().children[0],
|
|
329
|
+
proxyPositionRelativeToParent: true,
|
|
330
|
+
getParentNode: (node) => node.parentElement.parentElement.parentElement,
|
|
331
|
+
getProxy: getReorderProxy,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return <WhichTreeNode
|
|
336
|
+
nodeProps={nodeProps}
|
|
337
|
+
bg={bg}
|
|
338
|
+
itemData={itemData}
|
|
339
|
+
|
|
340
|
+
icon={icon}
|
|
341
|
+
onToggle={onToggle}
|
|
342
|
+
|
|
343
|
+
// fields={fields}
|
|
344
|
+
// hideNavColumn={hideNavColumn}
|
|
345
|
+
{...rowReorderProps}
|
|
346
|
+
/>;
|
|
347
|
+
}}
|
|
348
|
+
</Pressable>;
|
|
349
|
+
},
|
|
350
|
+
buildTreeNode = (itemData) => {
|
|
351
|
+
// this one is to be used recursively on children
|
|
352
|
+
|
|
353
|
+
// isVisible // skip if not visible, just return keyed array
|
|
354
|
+
|
|
355
|
+
// renderNode(itemData);
|
|
356
|
+
|
|
357
|
+
},
|
|
358
|
+
buildTreeNodes = () => {
|
|
359
|
+
|
|
360
|
+
// const entities = Repository ? (Repository.isRemote ? Repository.entities : Repository.getEntitiesOnPage()) : data;
|
|
361
|
+
// let rowData = _.clone(entities); // don't use the original array, make a new one so alterations to it are temporary
|
|
362
|
+
|
|
363
|
+
const
|
|
364
|
+
rootEntity = Repository.getRootEntity(),
|
|
365
|
+
rootNode = buildTreeNode(rootEntity);
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
return rootNode;
|
|
371
|
+
},
|
|
372
|
+
getChildren = (node_id, depth) => {
|
|
373
|
+
// Calls getChildParams(), then submits to server
|
|
374
|
+
// Server returns this for each node:
|
|
375
|
+
// hasChildren (so view can show/hide caret)
|
|
376
|
+
// model (e.g. "Fleet", "Equipment)
|
|
377
|
+
// data (json encoded representation of entity)
|
|
378
|
+
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
// Button handlers
|
|
382
|
+
expandPath = (path) => {} // - drills down the tree based on path (usually given by server). Path would be a list of sequential IDs (3/35/263/1024)
|
|
383
|
+
collapseOne = (node_id) => {},
|
|
384
|
+
collapseAll = () => {},
|
|
385
|
+
expandOne = (node_id) => {},
|
|
386
|
+
expandAll = () => {},
|
|
387
|
+
|
|
388
|
+
// Drag/Drop
|
|
389
|
+
getReorderProxy = (node) => {
|
|
390
|
+
const
|
|
391
|
+
row = node.parentElement.parentElement,
|
|
392
|
+
rowRect = row.getBoundingClientRect(),
|
|
393
|
+
parent = row.parentElement,
|
|
394
|
+
parentRect = parent.getBoundingClientRect(),
|
|
395
|
+
proxy = row.cloneNode(true),
|
|
396
|
+
top = rowRect.top - parentRect.top,
|
|
397
|
+
dragNodeIx = Array.from(parent.children).indexOf(row)
|
|
398
|
+
|
|
399
|
+
setDragNodeIx(dragNodeIx); // the ix of which record is being dragged
|
|
400
|
+
|
|
401
|
+
proxy.style.top = top + 'px';
|
|
402
|
+
proxy.style.left = '20px';
|
|
403
|
+
proxy.style.height = rowRect.height + 'px';
|
|
404
|
+
proxy.style.width = rowRect.width + 'px';
|
|
405
|
+
proxy.style.display = 'flex';
|
|
406
|
+
// proxy.style.backgroundColor = '#ccc';
|
|
407
|
+
proxy.style.position = 'absolute';
|
|
408
|
+
proxy.style.border = '1px solid #000';
|
|
409
|
+
return proxy;
|
|
410
|
+
},
|
|
411
|
+
onNodeReorderDragStart = (info, e, proxy, node) => {
|
|
412
|
+
// console.log('onNodeReorderDragStart', info, e, proxy, node);
|
|
413
|
+
const
|
|
414
|
+
proxyRect = proxy.getBoundingClientRect(),
|
|
415
|
+
row = node.parentElement.parentElement,
|
|
416
|
+
parent = row.parentElement,
|
|
417
|
+
parentRect = parent.getBoundingClientRect(),
|
|
418
|
+
rows = _.filter(row.parentElement.children, (childNode) => {
|
|
419
|
+
return childNode.getBoundingClientRect().height !== 0; // Skip zero-height children
|
|
420
|
+
}),
|
|
421
|
+
currentY = proxyRect.top - parentRect.top, // top position of pointer, relative to page
|
|
422
|
+
headerNodeIx = showHeaders ? 0 : null,
|
|
423
|
+
firstActualNodeIx = showHeaders ? 1 : 0;
|
|
424
|
+
|
|
425
|
+
// Figure out which index the user wants
|
|
426
|
+
let newIx = 0;
|
|
427
|
+
_.each(rows, (child, ix, all) => {
|
|
428
|
+
const
|
|
429
|
+
rect = child.getBoundingClientRect(), // rect of the row of this iteration
|
|
430
|
+
{
|
|
431
|
+
top,
|
|
432
|
+
bottom,
|
|
433
|
+
height,
|
|
434
|
+
} = rect,
|
|
435
|
+
compensatedTop = top - parentRect.top,
|
|
436
|
+
compensatedBottom = bottom - parentRect.top,
|
|
437
|
+
halfHeight = height / 2;
|
|
438
|
+
|
|
439
|
+
if (ix === headerNodeIx || child === proxy) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (ix === firstActualNodeIx) {
|
|
443
|
+
// first row
|
|
444
|
+
if (currentY < compensatedTop + halfHeight) {
|
|
445
|
+
newIx = firstActualNodeIx;
|
|
446
|
+
return false;
|
|
447
|
+
} else if (currentY < compensatedBottom) {
|
|
448
|
+
newIx = firstActualNodeIx + 1;
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
return;
|
|
452
|
+
} else if (ix === all.length -1) {
|
|
453
|
+
// last row
|
|
454
|
+
if (currentY < compensatedTop + halfHeight) {
|
|
455
|
+
newIx = ix;
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
newIx = ix +1;
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// all other rows
|
|
463
|
+
if (compensatedTop <= currentY && currentY < compensatedTop + halfHeight) {
|
|
464
|
+
newIx = ix;
|
|
465
|
+
return false;
|
|
466
|
+
} else if (currentY < compensatedBottom) {
|
|
467
|
+
newIx = ix +1;
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
let useBottom = false;
|
|
473
|
+
if (!rows[newIx] || rows[newIx] === proxy) {
|
|
474
|
+
newIx--;
|
|
475
|
+
useBottom = true;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Render marker showing destination location
|
|
479
|
+
const
|
|
480
|
+
rowContainerRect = rows[newIx].getBoundingClientRect(),
|
|
481
|
+
top = (useBottom ? rowContainerRect.bottom : rowContainerRect.top) - parentRect.top - parseInt(parent.style.borderWidth), // get relative Y position
|
|
482
|
+
treeNodesContainer = treeRef.current._listRef._scrollRef.childNodes[0],
|
|
483
|
+
treeNodesContainerRect = treeNodesContainer.getBoundingClientRect(),
|
|
484
|
+
marker = document.createElement('div');
|
|
485
|
+
|
|
486
|
+
marker.style.position = 'absolute';
|
|
487
|
+
marker.style.top = top -4 + 'px'; // -4 so it's always visible
|
|
488
|
+
marker.style.height = '4px';
|
|
489
|
+
marker.style.width = treeNodesContainerRect.width + 'px';
|
|
490
|
+
marker.style.backgroundColor = '#f00';
|
|
491
|
+
|
|
492
|
+
treeNodesContainer.appendChild(marker);
|
|
493
|
+
|
|
494
|
+
setDragNodeSlot({ ix: newIx, marker, useBottom, });
|
|
495
|
+
},
|
|
496
|
+
onNodeReorderDrag = (info, e, proxy, node) => {
|
|
497
|
+
// console.log('onNodeReorderDrag', info, e, proxy, node);
|
|
498
|
+
const
|
|
499
|
+
proxyRect = proxy.getBoundingClientRect(),
|
|
500
|
+
row = node.parentElement.parentElement,
|
|
501
|
+
parent = row.parentElement,
|
|
502
|
+
parentRect = parent.getBoundingClientRect(),
|
|
503
|
+
rows = _.filter(row.parentElement.children, (childNode) => {
|
|
504
|
+
return childNode.getBoundingClientRect().height !== 0; // Skip zero-height children
|
|
505
|
+
}),
|
|
506
|
+
currentY = proxyRect.top - parentRect.top, // top position of pointer, relative to page
|
|
507
|
+
headerNodeIx = showHeaders ? 0 : null,
|
|
508
|
+
firstActualNodeIx = showHeaders ? 1 : 0;
|
|
509
|
+
|
|
510
|
+
// Figure out which index the user wants
|
|
511
|
+
let newIx = 0;
|
|
512
|
+
_.each(rows, (child, ix, all) => {
|
|
513
|
+
const
|
|
514
|
+
rect = child.getBoundingClientRect(), // rect of the row of this iteration
|
|
515
|
+
{
|
|
516
|
+
top,
|
|
517
|
+
bottom,
|
|
518
|
+
height,
|
|
519
|
+
} = rect,
|
|
520
|
+
compensatedTop = top - parentRect.top,
|
|
521
|
+
compensatedBottom = bottom - parentRect.top,
|
|
522
|
+
halfHeight = height / 2;
|
|
523
|
+
|
|
524
|
+
if (ix === headerNodeIx || child === proxy) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (ix === firstActualNodeIx) {
|
|
528
|
+
// first row
|
|
529
|
+
if (currentY < compensatedTop + halfHeight) {
|
|
530
|
+
newIx = firstActualNodeIx;
|
|
531
|
+
return false;
|
|
532
|
+
} else if (currentY < compensatedBottom) {
|
|
533
|
+
newIx = firstActualNodeIx + 1;
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
return;
|
|
537
|
+
} else if (ix === all.length -1) {
|
|
538
|
+
// last row
|
|
539
|
+
if (currentY < compensatedTop + halfHeight) {
|
|
540
|
+
newIx = ix;
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
newIx = ix +1;
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// all other rows
|
|
548
|
+
if (compensatedTop <= currentY && currentY < compensatedTop + halfHeight) {
|
|
549
|
+
newIx = ix;
|
|
550
|
+
return false;
|
|
551
|
+
} else if (currentY < compensatedBottom) {
|
|
552
|
+
newIx = ix +1;
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
let useBottom = false;
|
|
558
|
+
if (!rows[newIx] || rows[newIx] === proxy) {
|
|
559
|
+
newIx--;
|
|
560
|
+
useBottom = true;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Render marker showing destination location (can't use regular render cycle because this div is absolutely positioned on page)
|
|
564
|
+
const
|
|
565
|
+
rowContainerRect = rows[newIx].getBoundingClientRect(),
|
|
566
|
+
top = (useBottom ? rowContainerRect.bottom : rowContainerRect.top) - parentRect.top - parseInt(parent.style.borderWidth); // get relative Y position
|
|
567
|
+
let marker = dragNodeSlot && dragNodeSlot.marker;
|
|
568
|
+
if (marker) {
|
|
569
|
+
marker.style.top = top -4 + 'px'; // -4 so it's always visible
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
setDragNodeSlot({ ix: newIx, marker, useBottom, });
|
|
573
|
+
// console.log('onNodeReorderDrag', newIx);
|
|
574
|
+
|
|
575
|
+
},
|
|
576
|
+
onNodeReorderDragStop = (delta, e, config) => {
|
|
577
|
+
// console.log('onNodeReorderDragStop', delta, e, config);
|
|
578
|
+
const
|
|
579
|
+
dropIx = dragNodeSlot.ix,
|
|
580
|
+
compensatedDragIx = showHeaders ? dragNodeIx -1 : dragNodeIx, // ix, without taking header row into account
|
|
581
|
+
compensatedDropIx = showHeaders ? dropIx -1 : dropIx, // // ix, without taking header row into account
|
|
582
|
+
dropPosition = dragNodeSlot.useBottom ? DROP_POSITION_AFTER : DROP_POSITION_BEFORE;
|
|
583
|
+
|
|
584
|
+
let shouldMove = true,
|
|
585
|
+
finalDropIx = compensatedDropIx;
|
|
586
|
+
|
|
587
|
+
if (dropPosition === DROP_POSITION_BEFORE) {
|
|
588
|
+
if (dragNodeIx === dropIx || dragNodeIx === dropIx -1) { // basically before or after the drag row's origin
|
|
589
|
+
// Same as origin; don't do anything
|
|
590
|
+
shouldMove = false;
|
|
591
|
+
} else {
|
|
592
|
+
// Actually move it
|
|
593
|
+
if (!Repository) { // If we're just going to be switching rows, rather than telling server to reorder rows, so maybe adjust finalDropIx...
|
|
594
|
+
if (finalDropIx > compensatedDragIx) { // if we're dropping *before* the origin ix
|
|
595
|
+
finalDropIx = finalDropIx -1; // Because we're using BEFORE, we want to switch with the row *prior to* the ix we're dropping before
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
} else if (dropPosition === DROP_POSITION_AFTER) {
|
|
600
|
+
// Only happens on the very last row. Everything else is BEFORE...
|
|
601
|
+
if (dragNodeIx === dropIx) {
|
|
602
|
+
// Same as origin; don't do anything
|
|
603
|
+
shouldMove = false;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (shouldMove) {
|
|
608
|
+
// Update the row with the new ix
|
|
609
|
+
let dragRecord,
|
|
610
|
+
dropRecord;
|
|
611
|
+
if (Repository) {
|
|
612
|
+
dragRecord = Repository.getByIx(compensatedDragIx);
|
|
613
|
+
dropRecord = Repository.getByIx(finalDropIx);
|
|
614
|
+
|
|
615
|
+
Repository.reorder(dragRecord, dropRecord, dropPosition);
|
|
616
|
+
|
|
617
|
+
} else {
|
|
618
|
+
function arrayMove(arr, fromIndex, toIndex) {
|
|
619
|
+
var element = arr[fromIndex];
|
|
620
|
+
arr.splice(fromIndex, 1);
|
|
621
|
+
arr.splice(toIndex, 0, element);
|
|
622
|
+
}
|
|
623
|
+
arrayMove(data, compensatedDragIx, finalDropIx);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (dragNodeSlot) {
|
|
628
|
+
dragNodeSlot.marker.remove();
|
|
629
|
+
}
|
|
630
|
+
setDragNodeSlot(null);
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
useEffect(() => {
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
function buildTreeNodeData() {
|
|
637
|
+
// Take the Repository and build up the tree node data from its entities
|
|
638
|
+
const
|
|
639
|
+
entities = Repository.entities,
|
|
640
|
+
treeNodes = {};
|
|
641
|
+
|
|
642
|
+
// TODO: Get root node?
|
|
643
|
+
// I'm thinking if a repository senses that it's a tree, then at initial load
|
|
644
|
+
// it should get the root node +1 level of children.
|
|
645
|
+
//
|
|
646
|
+
// How would it then subsequently get the proper children?
|
|
647
|
+
// i.e. When a node gets its children, how will it do this
|
|
648
|
+
// while maintaining the nodes that already exist there?
|
|
649
|
+
// We don't want it to *replace* all exisitng nodes!
|
|
650
|
+
//
|
|
651
|
+
// And if the repository does a reload, should it just get root+1 again?
|
|
652
|
+
// Changing filters would potentially change the tree structure.
|
|
653
|
+
// Changing sorting would only change the ordering, not what is expanded/collapsed or visible/invisible.
|
|
654
|
+
|
|
655
|
+
// include the following on each node
|
|
656
|
+
// - item
|
|
657
|
+
// - isExpanded,
|
|
658
|
+
// - isVisible,
|
|
659
|
+
// - hasChildren,
|
|
660
|
+
// - children
|
|
661
|
+
// - depth,
|
|
662
|
+
// - text,
|
|
663
|
+
|
|
664
|
+
// Need to take into account whether using Repository or data.
|
|
665
|
+
// If using data, everything exists at once. What format will data be in?
|
|
666
|
+
// How does this interface with Repository?
|
|
667
|
+
// Maybe if Repository is not AjaxRepository, everything needs to be present at once!
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
return treeNodes;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function buildAndSetTreeNodeData() {
|
|
674
|
+
setTreeNodeData(buildTreeNodeData());
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (!isReady) {
|
|
678
|
+
buildAndSetTreeNodeData();
|
|
679
|
+
setIsReady(true);
|
|
680
|
+
}
|
|
681
|
+
if (!Repository) {
|
|
682
|
+
return () => {};
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// set up @onehat/data repository
|
|
686
|
+
const
|
|
687
|
+
setTrue = () => setIsLoading(true),
|
|
688
|
+
setFalse = () => setIsLoading(false),
|
|
689
|
+
onChangeFilters = () => {
|
|
690
|
+
if (!Repository.isAutoLoad) {
|
|
691
|
+
Repository.reload();
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
onChangeSorters = () => {
|
|
695
|
+
if (!Repository.isAutoLoad) {
|
|
696
|
+
Repository.reload();
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
Repository.on('beforeLoad', setTrue);
|
|
701
|
+
Repository.on('load', setFalse);
|
|
702
|
+
Repository.ons(['changePage', 'changePageSize',], deselectAll);
|
|
703
|
+
Repository.ons(['changeData', 'change'], buildAndSetTreeNodeData);
|
|
704
|
+
Repository.on('changeFilters', onChangeFilters);
|
|
705
|
+
Repository.on('changeSorters', onChangeSorters);
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
return () => {
|
|
709
|
+
Repository.off('beforeLoad', setTrue);
|
|
710
|
+
Repository.off('load', setFalse);
|
|
711
|
+
Repository.offs(['changePage', 'changePageSize',], deselectAll);
|
|
712
|
+
Repository.offs(['changeData', 'change'], buildAndSetTreeNodeData);
|
|
713
|
+
Repository.off('changeFilters', onChangeFilters);
|
|
714
|
+
Repository.off('changeSorters', onChangeSorters);
|
|
715
|
+
};
|
|
716
|
+
}, []);
|
|
717
|
+
|
|
718
|
+
useEffect(() => {
|
|
719
|
+
if (!Repository) {
|
|
720
|
+
return () => {};
|
|
721
|
+
}
|
|
722
|
+
if (!disableSelectorSelected && selectorId) {
|
|
723
|
+
let id = selectorSelected?.id;
|
|
724
|
+
if (_.isEmpty(selectorSelected)) {
|
|
725
|
+
id = noSelectorMeansNoResults ? 'NO_MATCHES' : null;
|
|
726
|
+
}
|
|
727
|
+
Repository.filter(selectorId, id, false); // so it doesn't clear existing filters
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
}, [selectorId, selectorSelected]);
|
|
731
|
+
|
|
732
|
+
const footerToolbarItemComponents = useMemo(() => getFooterToolbarItems(), [additionalToolbarButtons, isReorderMode]);
|
|
733
|
+
|
|
734
|
+
if (!isReady) {
|
|
735
|
+
return null;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// Actual TreeNodes
|
|
739
|
+
const treeNodes = buildTreeNodes();
|
|
740
|
+
|
|
741
|
+
// headers & footers
|
|
742
|
+
let treeFooterComponent = null;
|
|
743
|
+
if (!disableBottomToolbar) {
|
|
744
|
+
if (Repository && bottomToolbar === 'pagination' && !disablePagination && Repository.isPaginated) {
|
|
745
|
+
treeFooterComponent = <PaginationToolbar Repository={Repository} toolbarItems={footerToolbarItemComponents} />;
|
|
746
|
+
} else if (footerToolbarItemComponents.length) {
|
|
747
|
+
treeFooterComponent = <Toolbar>{footerToolbarItemComponents}</Toolbar>;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
return <Column
|
|
752
|
+
{...testProps('Tree')}
|
|
753
|
+
flex={1}
|
|
754
|
+
w="100%"
|
|
755
|
+
>
|
|
756
|
+
{topToolbar}
|
|
757
|
+
|
|
758
|
+
<Column w="100%" flex={1} borderTopWidth={isLoading ? 2 : 1} borderTopColor={isLoading ? '#f00' : 'trueGray.300'} onClick={() => {
|
|
759
|
+
if (!isReorderMode) {
|
|
760
|
+
deselectAll();
|
|
761
|
+
}
|
|
762
|
+
}}>
|
|
763
|
+
{!treeNodes.length ? <NoRecordsFound text={noneFoundText} onRefresh={onRefresh} /> :
|
|
764
|
+
treeNodes}
|
|
765
|
+
</Column>
|
|
766
|
+
|
|
767
|
+
{treeFooterComponent}
|
|
768
|
+
|
|
769
|
+
</Column>;
|
|
770
|
+
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
export const SideTreeEditor = withAlert(
|
|
774
|
+
withEvents(
|
|
775
|
+
withData(
|
|
776
|
+
// withMultiSelection(
|
|
777
|
+
withSelection(
|
|
778
|
+
withSideEditor(
|
|
779
|
+
withFilters(
|
|
780
|
+
withPresetButtons(
|
|
781
|
+
withContextMenu(
|
|
782
|
+
Tree
|
|
783
|
+
)
|
|
784
|
+
)
|
|
785
|
+
)
|
|
786
|
+
)
|
|
787
|
+
)
|
|
788
|
+
// )
|
|
789
|
+
)
|
|
790
|
+
)
|
|
791
|
+
);
|
|
792
|
+
|
|
793
|
+
export const WindowedTreeEditor = withAlert(
|
|
794
|
+
withEvents(
|
|
795
|
+
withData(
|
|
796
|
+
// withMultiSelection(
|
|
797
|
+
withSelection(
|
|
798
|
+
withWindowedEditor(
|
|
799
|
+
withFilters(
|
|
800
|
+
withPresetButtons(
|
|
801
|
+
withContextMenu(
|
|
802
|
+
Tree
|
|
803
|
+
)
|
|
804
|
+
)
|
|
805
|
+
)
|
|
806
|
+
)
|
|
807
|
+
)
|
|
808
|
+
// )
|
|
809
|
+
)
|
|
810
|
+
)
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
export default WindowedTreeEditor;
|