@onehat/ui 0.4.71 → 0.4.72
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 +1 -1
- package/src/Components/Buttons/Button.js +13 -6
- package/src/Components/Container/ScreenContainer.js +1 -0
- package/src/Components/Form/Field/Combo/MeterTypesCombo.js +4 -2
- package/src/Components/Form/Field/Input.js +5 -4
- package/src/Components/Grid/Grid.js +16 -7
- package/src/Components/Grid/GridHeaderRow.js +1 -1
- package/src/Components/Grid/GridRow.js +35 -34
- package/src/Components/Grid/RowDragHandle.js +25 -10
- package/src/Components/Grid/RowHandle.js +55 -0
- package/src/{Hooks → Components/Grid}/useAsyncRenderers.js +1 -1
- package/src/Components/Hoc/Secondary/withSecondaryData.js +2 -1
- package/src/Components/Hoc/Secondary/withSecondaryEditor.js +3 -2
- package/src/Components/Hoc/Secondary/withSecondarySelection.js +3 -2
- package/src/Components/Hoc/Secondary/withSecondaryValue.js +2 -1
- package/src/Components/Hoc/withAlert.js +3 -1
- package/src/Components/Hoc/withCollapsible.js +9 -4
- package/src/Components/Hoc/withComponent.js +6 -0
- package/src/Components/Hoc/withContextMenu.js +6 -0
- package/src/Components/Hoc/withData.js +3 -2
- package/src/Components/Hoc/withDnd.js +16 -8
- package/src/Components/Hoc/withDraggable.js +21 -5
- package/src/Components/Hoc/withEditor.js +2 -1
- package/src/Components/Hoc/withEvents.js +11 -1
- package/src/Components/Hoc/withFilters.js +7 -2
- package/src/Components/Hoc/withModal.js +3 -2
- package/src/Components/Hoc/withPdfButtons.js +3 -2
- package/src/Components/Hoc/withPermissions.js +3 -2
- package/src/Components/Hoc/withPresetButtons.js +3 -2
- package/src/Components/Hoc/withSelection.js +2 -8
- package/src/Components/Hoc/withToast.js +4 -2
- package/src/Components/Hoc/withTooltip.js +10 -1
- package/src/Components/Hoc/withValue.js +3 -9
- package/src/Components/Messages/GlobalModals.js +47 -0
- package/src/Components/Tree/Tree.js +22 -6
- package/src/Components/Tree/TreeNode.js +11 -11
- package/src/Components/Tree/TreeNodeDragHandle.js +8 -4
- package/src/Components/Viewer/MeterTypeText.js +21 -1
- package/src/Constants/MeterTypes.js +2 -0
- package/src/Functions/addIconProps.js +46 -0
- package/src/Functions/testProps.js +1 -1
- package/src/Hooks/useWhyDidYouUpdate.js +33 -0
- package/src/PlatformImports/Web/Attachments.js +1 -1
- package/src/Components/Hoc/withBlank.js +0 -10
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
|
|
19
19
|
export function withDragSource(WrappedComponent) {
|
|
20
20
|
return forwardRef((props, ref) => {
|
|
21
|
-
|
|
22
|
-
if (!props.isDragSource) {
|
|
21
|
+
|
|
22
|
+
if (!props.isDragSource || props.alreadyHasDragSource) {
|
|
23
23
|
return <WrappedComponent {...props} ref={ref} />;
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -37,6 +37,7 @@ export function withDragSource(WrappedComponent) {
|
|
|
37
37
|
dragOptions = null,
|
|
38
38
|
dropEffect = null,
|
|
39
39
|
// onDrag,
|
|
40
|
+
onDragStart = null,
|
|
40
41
|
onDragEnd = null,
|
|
41
42
|
canDrag = null,
|
|
42
43
|
isDragging = null,
|
|
@@ -63,10 +64,15 @@ export function withDragSource(WrappedComponent) {
|
|
|
63
64
|
|
|
64
65
|
return {
|
|
65
66
|
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.
|
|
66
|
-
item: {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
item: () => { // Required (object or function). If a function, it runs only once at the start of a drag.
|
|
68
|
+
if (dragSourceItem.onDragStart) {
|
|
69
|
+
dragSourceItem.onDragStart();
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
...dragSourceItem,
|
|
73
|
+
getDragProxy,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
70
76
|
// 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 }.
|
|
71
77
|
// 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.
|
|
72
78
|
previewOptions: dragPreviewOptions, // Optional. A plain JavaScript object describing drag preview options.
|
|
@@ -119,6 +125,7 @@ export function withDragSource(WrappedComponent) {
|
|
|
119
125
|
|
|
120
126
|
return <WrappedComponent
|
|
121
127
|
{...props}
|
|
128
|
+
alreadyHasDragSource={true}
|
|
122
129
|
ref={ref}
|
|
123
130
|
canDrag={stateCanDrag}
|
|
124
131
|
isDragging={stateIsDragging}
|
|
@@ -133,7 +140,7 @@ export function withDragSource(WrappedComponent) {
|
|
|
133
140
|
export function withDropTarget(WrappedComponent) {
|
|
134
141
|
return forwardRef((props, ref) => {
|
|
135
142
|
|
|
136
|
-
if (!props.isDropTarget) {
|
|
143
|
+
if (!props.isDropTarget || props.alreadyHasDropTarget) {
|
|
137
144
|
return <WrappedComponent {...props} ref={ref} />;
|
|
138
145
|
}
|
|
139
146
|
|
|
@@ -197,8 +204,9 @@ export function withDropTarget(WrappedComponent) {
|
|
|
197
204
|
dropTargetRef(localTargetRef); // register DOM node with react-dnd
|
|
198
205
|
|
|
199
206
|
return <WrappedComponent
|
|
200
|
-
|
|
207
|
+
alreadyHasDropTarget={true}
|
|
201
208
|
ref={ref}
|
|
209
|
+
canDrop={stateCanDrop}
|
|
202
210
|
isOver={isOver}
|
|
203
211
|
dropTargetRef={localTargetRef}
|
|
204
212
|
draggedItem={draggedItem} // Pass the dragged item
|
|
@@ -23,7 +23,7 @@ import getComponentFromType from '../../Functions/getComponentFromType.js';
|
|
|
23
23
|
export default function withDraggable(WrappedComponent) {
|
|
24
24
|
return forwardRef((props, ref) => {
|
|
25
25
|
|
|
26
|
-
if (!props.isDraggable) {
|
|
26
|
+
if (!props.isDraggable || props.alreadyHasDraggable) {
|
|
27
27
|
return <WrappedComponent {...props} ref={ref} />;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -237,7 +237,11 @@ export default function withDraggable(WrappedComponent) {
|
|
|
237
237
|
{...draggableProps}
|
|
238
238
|
>
|
|
239
239
|
<div ref={nodeRef} className="nsResize">
|
|
240
|
-
<WrappedComponent
|
|
240
|
+
<WrappedComponent
|
|
241
|
+
{...propsToPass}
|
|
242
|
+
alreadyHasDraggable={true}
|
|
243
|
+
ref={ref}
|
|
244
|
+
/>
|
|
241
245
|
</div>
|
|
242
246
|
</Draggable>;
|
|
243
247
|
} else if (mode === HORIZONTAL) {
|
|
@@ -252,7 +256,11 @@ export default function withDraggable(WrappedComponent) {
|
|
|
252
256
|
{...draggableProps}
|
|
253
257
|
>
|
|
254
258
|
<div ref={nodeRef} className="ewResize" style={{ height: '100%', }}>
|
|
255
|
-
<WrappedComponent
|
|
259
|
+
<WrappedComponent
|
|
260
|
+
{...propsToPass}
|
|
261
|
+
alreadyHasDraggable={true}
|
|
262
|
+
ref={ref}
|
|
263
|
+
/>
|
|
256
264
|
</div>
|
|
257
265
|
</Draggable>;
|
|
258
266
|
}
|
|
@@ -268,14 +276,22 @@ export default function withDraggable(WrappedComponent) {
|
|
|
268
276
|
nodeRef={nodeRef}
|
|
269
277
|
{...draggableProps}
|
|
270
278
|
>
|
|
271
|
-
<WrappedComponent
|
|
279
|
+
<WrappedComponent
|
|
280
|
+
{...propsToPass}
|
|
281
|
+
alreadyHasDraggable={true}
|
|
282
|
+
ref={nodeRef}
|
|
283
|
+
/>
|
|
272
284
|
</Draggable>;
|
|
273
285
|
} else if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
274
286
|
|
|
275
287
|
// NOT YET IMPLEMENTED
|
|
276
288
|
// Really need to replace most of this, as much of it is web-centric.
|
|
277
289
|
|
|
278
|
-
return <WrappedComponent
|
|
290
|
+
return <WrappedComponent
|
|
291
|
+
{...propsToPass}
|
|
292
|
+
alreadyHasDraggable={true}
|
|
293
|
+
ref={ref}
|
|
294
|
+
/>;
|
|
279
295
|
|
|
280
296
|
}
|
|
281
297
|
});
|
|
@@ -21,7 +21,7 @@ import _ from 'lodash';
|
|
|
21
21
|
export default function withEditor(WrappedComponent, isTree = false) {
|
|
22
22
|
return forwardRef((props, ref) => {
|
|
23
23
|
|
|
24
|
-
if (props.disableWithEditor) {
|
|
24
|
+
if (props.disableWithEditor || props.alreadyHasWithEditor) {
|
|
25
25
|
return <WrappedComponent {...props} ref={ref} isTree={isTree} />;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -702,6 +702,7 @@ export default function withEditor(WrappedComponent, isTree = false) {
|
|
|
702
702
|
{...props}
|
|
703
703
|
ref={ref}
|
|
704
704
|
disableWithEditor={false}
|
|
705
|
+
alreadyHasWithEditor={true}
|
|
705
706
|
currentRecord={currentRecord}
|
|
706
707
|
setCurrentRecord={setCurrentRecord}
|
|
707
708
|
isEditorShown={isEditorShown}
|
|
@@ -2,9 +2,19 @@ import { forwardRef } from 'react';
|
|
|
2
2
|
|
|
3
3
|
export default function withEvents(WrappedComponent) {
|
|
4
4
|
return forwardRef((props, ref) => {
|
|
5
|
+
|
|
6
|
+
if (props.alreadyHasWithEvents) {
|
|
7
|
+
return <WrappedComponent {...props} ref={ref} />;
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
const {
|
|
6
11
|
onEvent,
|
|
7
12
|
} = props;
|
|
8
|
-
return <WrappedComponent
|
|
13
|
+
return <WrappedComponent
|
|
14
|
+
{...props}
|
|
15
|
+
alreadyHasWithEvents={true}
|
|
16
|
+
ref={ref}
|
|
17
|
+
fireEvent={onEvent}
|
|
18
|
+
/>;
|
|
9
19
|
});
|
|
10
20
|
}
|
|
@@ -42,7 +42,7 @@ const isWindows = Platform.OS === 'windows';
|
|
|
42
42
|
export default function withFilters(WrappedComponent) {
|
|
43
43
|
return forwardRef((props, ref) => {
|
|
44
44
|
|
|
45
|
-
if (!props.useFilters) {
|
|
45
|
+
if (!props.useFilters || props.alreadyHasWithFilters) {
|
|
46
46
|
return <WrappedComponent {...props} ref={ref} />;
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -695,7 +695,12 @@ export default function withFilters(WrappedComponent) {
|
|
|
695
695
|
</HStack>}
|
|
696
696
|
</Toolbar>;
|
|
697
697
|
|
|
698
|
-
return <WrappedComponent
|
|
698
|
+
return <WrappedComponent
|
|
699
|
+
{...props}
|
|
700
|
+
ref={ref}
|
|
701
|
+
alreadyHasWithFilters={true}
|
|
702
|
+
topToolbar={toolbar}
|
|
703
|
+
/>;
|
|
699
704
|
|
|
700
705
|
});
|
|
701
706
|
}
|
|
@@ -19,7 +19,7 @@ import _ from 'lodash';
|
|
|
19
19
|
export default function withModal(WrappedComponent) {
|
|
20
20
|
return forwardRef((props, ref) => {
|
|
21
21
|
|
|
22
|
-
if (props.disableWithModal || props.
|
|
22
|
+
if (props.disableWithModal || props.alreadyHasWithModal) {
|
|
23
23
|
return <WrappedComponent {...props} ref={ref} />;
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -180,12 +180,13 @@ export default function withModal(WrappedComponent) {
|
|
|
180
180
|
<WrappedComponent
|
|
181
181
|
{...props}
|
|
182
182
|
disableWithModal={false}
|
|
183
|
+
alreadyHasWithModal={true}
|
|
184
|
+
ref={ref}
|
|
183
185
|
showModal={showModal}
|
|
184
186
|
hideModal={onCancel || hideModal}
|
|
185
187
|
updateModalBody={updateModalBody}
|
|
186
188
|
isModalShown={isModalShown}
|
|
187
189
|
whichModal={whichModal}
|
|
188
|
-
ref={ref}
|
|
189
190
|
/>
|
|
190
191
|
{isModalShown &&
|
|
191
192
|
<Modal
|
|
@@ -22,7 +22,7 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
22
22
|
if (props.canUser && !props.canUser(VIEW)) { // permissions
|
|
23
23
|
showButtons = false;
|
|
24
24
|
}
|
|
25
|
-
if (!showButtons) {
|
|
25
|
+
if (!showButtons || props.alreadyHasWithPdfButtons) {
|
|
26
26
|
// bypass everything.
|
|
27
27
|
// If we don't do this, we get an infinite recursion with Form
|
|
28
28
|
// because this HOC wraps Form and uses Form itself.
|
|
@@ -384,9 +384,10 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
384
384
|
|
|
385
385
|
return <WrappedComponent
|
|
386
386
|
{...props}
|
|
387
|
+
ref={ref}
|
|
388
|
+
alreadyHasWithPdfButtons={true}
|
|
387
389
|
additionalEditButtons={additionalEditButtons}
|
|
388
390
|
additionalViewButtons={additionalViewButtons}
|
|
389
|
-
ref={ref}
|
|
390
391
|
/>;
|
|
391
392
|
}));
|
|
392
393
|
}
|
|
@@ -97,7 +97,7 @@ export function canUser(permission, modelToCheck = null) {
|
|
|
97
97
|
export default function withPermissions(WrappedComponent, forceUsePermissions = false) {
|
|
98
98
|
return forwardRef((props, ref) => {
|
|
99
99
|
|
|
100
|
-
if (!props.usePermissions && !forceUsePermissions) {
|
|
100
|
+
if ((!props.usePermissions && !forceUsePermissions) || props.alreadyHasWithPermissions) {
|
|
101
101
|
return <WrappedComponent {...props} ref={ref} />;
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -126,9 +126,10 @@ export default function withPermissions(WrappedComponent, forceUsePermissions =
|
|
|
126
126
|
|
|
127
127
|
return <WrappedComponent
|
|
128
128
|
{...props}
|
|
129
|
+
alreadyHasWithPermissions={true}
|
|
130
|
+
ref={ref}
|
|
129
131
|
canUser={canUserDecorator}
|
|
130
132
|
showPermissionsError={showPermissionsError}
|
|
131
|
-
ref={ref}
|
|
132
133
|
/>;
|
|
133
134
|
});
|
|
134
135
|
}
|
|
@@ -41,7 +41,7 @@ const presetButtons = [
|
|
|
41
41
|
export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
42
42
|
return forwardRef((props, ref) => {
|
|
43
43
|
|
|
44
|
-
if (props.disablePresetButtons) {
|
|
44
|
+
if (props.disablePresetButtons || props.alreadyHasWithPresetButtons) {
|
|
45
45
|
// bypass everything
|
|
46
46
|
return <WrappedComponent {...props} ref={ref} />;
|
|
47
47
|
}
|
|
@@ -433,8 +433,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
433
433
|
|
|
434
434
|
return <WrappedComponent
|
|
435
435
|
{...propsToPass}
|
|
436
|
-
ref={ref}
|
|
437
436
|
disablePresetButtons={false}
|
|
437
|
+
alreadyHasWithPresetButtons={true}
|
|
438
|
+
ref={ref}
|
|
438
439
|
contextMenuItems={[
|
|
439
440
|
...localContextMenuItems,
|
|
440
441
|
...contextMenuItems,
|
|
@@ -12,14 +12,7 @@ import _ from 'lodash';
|
|
|
12
12
|
export default function withSelection(WrappedComponent) {
|
|
13
13
|
return forwardRef((props, ref) => {
|
|
14
14
|
|
|
15
|
-
if (props.disableWithSelection) {
|
|
16
|
-
return <WrappedComponent {...props} ref={ref} />;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (props.setSelection) {
|
|
20
|
-
// bypass everything, since we're already using withSelection() in hierarchy.
|
|
21
|
-
// For example, Combo has withSelection(), and intenally it uses Grid which also has withSelection(),
|
|
22
|
-
// but we only need it defined once for the whole thing.
|
|
15
|
+
if (props.disableWithSelection || props.alreadyHasWithSelection) {
|
|
23
16
|
return <WrappedComponent {...props} ref={ref} />;
|
|
24
17
|
}
|
|
25
18
|
|
|
@@ -427,6 +420,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
427
420
|
{...props}
|
|
428
421
|
ref={ref}
|
|
429
422
|
disableWithSelection={false}
|
|
423
|
+
alreadyHasWithSelection={true}
|
|
430
424
|
selection={getSelection()}
|
|
431
425
|
getSelection={getSelection}
|
|
432
426
|
setSelection={setSelection}
|
|
@@ -13,7 +13,7 @@ import _ from 'lodash';
|
|
|
13
13
|
export default function withToast(WrappedComponent) {
|
|
14
14
|
return forwardRef((props, ref) => {
|
|
15
15
|
|
|
16
|
-
if (props.disableWithToast || props.
|
|
16
|
+
if (props.disableWithToast || props.alreadyHasWithToast) {
|
|
17
17
|
return <WrappedComponent {...props} ref={ref} />;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -80,8 +80,10 @@ export default function withToast(WrappedComponent) {
|
|
|
80
80
|
|
|
81
81
|
return <WrappedComponent
|
|
82
82
|
{...props}
|
|
83
|
-
|
|
83
|
+
alreadyHasWithToast={true}
|
|
84
|
+
disableWithToast={false}
|
|
84
85
|
ref={ref}
|
|
86
|
+
showToast={showToast}
|
|
85
87
|
/>;
|
|
86
88
|
});
|
|
87
89
|
}
|
|
@@ -7,6 +7,11 @@ import _ from 'lodash';
|
|
|
7
7
|
|
|
8
8
|
export default function withTooltip(WrappedComponent) {
|
|
9
9
|
return forwardRef((props, ref) => {
|
|
10
|
+
|
|
11
|
+
if (props.alreadyHasWithTooltip) {
|
|
12
|
+
return <WrappedComponent {...props} ref={ref} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
const {
|
|
11
16
|
tooltip,
|
|
12
17
|
tooltipPlacement = 'bottom',
|
|
@@ -16,7 +21,11 @@ export default function withTooltip(WrappedComponent) {
|
|
|
16
21
|
...propsToPass
|
|
17
22
|
} = props;
|
|
18
23
|
|
|
19
|
-
let component = <WrappedComponent
|
|
24
|
+
let component = <WrappedComponent
|
|
25
|
+
{...propsToPass}
|
|
26
|
+
alreadyHasWithTooltip={true}
|
|
27
|
+
ref={ref}
|
|
28
|
+
/>;
|
|
20
29
|
|
|
21
30
|
if (tooltip || !_.isEmpty(_tooltip)) {
|
|
22
31
|
component = <Tooltip
|
|
@@ -9,14 +9,7 @@ import _ from 'lodash';
|
|
|
9
9
|
export default function withValue(WrappedComponent) {
|
|
10
10
|
return forwardRef((props, ref) => {
|
|
11
11
|
|
|
12
|
-
if (props.disableWithValue) {
|
|
13
|
-
return <WrappedComponent {...props} ref={ref} />;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (props.setValue) {
|
|
17
|
-
// bypass everything, since we're already using withValue() in hierarchy.
|
|
18
|
-
// For example, Combo has withValue(), and intenally it uses Input which also has withValue(),
|
|
19
|
-
// but we only need it defined once for the whole thing.
|
|
12
|
+
if (props.disableWithValue || props.alreadyHasWithValue) {
|
|
20
13
|
return <WrappedComponent {...props} ref={ref} />;
|
|
21
14
|
}
|
|
22
15
|
|
|
@@ -143,8 +136,9 @@ export default function withValue(WrappedComponent) {
|
|
|
143
136
|
|
|
144
137
|
return <WrappedComponent
|
|
145
138
|
{...props}
|
|
146
|
-
ref={ref}
|
|
147
139
|
disableWithValue={false}
|
|
140
|
+
alreadyHasWithValue={true}
|
|
141
|
+
ref={ref}
|
|
148
142
|
value={convertedValue}
|
|
149
143
|
setValue={setValueRef.current}
|
|
150
144
|
onChangeSelection={onChangeSelection}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
import { useSelector, useDispatch, } from 'react-redux';
|
|
3
|
+
import {
|
|
4
|
+
selectIsWaitModalShown,
|
|
5
|
+
selectAlertMessage,
|
|
6
|
+
selectDebugMessage,
|
|
7
|
+
selectInfoMessage,
|
|
8
|
+
selectWaitMessage,
|
|
9
|
+
setAlertMessage,
|
|
10
|
+
setDebugMessage,
|
|
11
|
+
setInfoMessage,
|
|
12
|
+
} from '@src/models/Slices/DebugSlice';
|
|
13
|
+
import WaitMessage from './WaitMessage';
|
|
14
|
+
import ErrorMessage from './ErrorMessage';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export default function GlobalModals() {
|
|
19
|
+
const
|
|
20
|
+
dispatch = useDispatch(),
|
|
21
|
+
isWaitModalShown = useSelector(selectIsWaitModalShown),
|
|
22
|
+
alertMessage = useSelector(selectAlertMessage),
|
|
23
|
+
debugMessage = useSelector(selectDebugMessage),
|
|
24
|
+
infoMessage = useSelector(selectInfoMessage),
|
|
25
|
+
waitMessage = useSelector(selectWaitMessage);
|
|
26
|
+
|
|
27
|
+
return <>
|
|
28
|
+
{isWaitModalShown && <WaitMessage text={waitMessage} />}
|
|
29
|
+
{!isWaitModalShown && alertMessage &&
|
|
30
|
+
<ErrorMessage
|
|
31
|
+
text={alertMessage}
|
|
32
|
+
onOk={() => dispatch(setAlertMessage(null))}
|
|
33
|
+
/>}
|
|
34
|
+
{!isWaitModalShown && debugMessage &&
|
|
35
|
+
<ErrorMessage
|
|
36
|
+
text={debugMessage}
|
|
37
|
+
color="green"
|
|
38
|
+
onOk={() => dispatch(setDebugMessage(null))}
|
|
39
|
+
/>}
|
|
40
|
+
{!isWaitModalShown && infoMessage &&
|
|
41
|
+
<ErrorMessage
|
|
42
|
+
text={infoMessage}
|
|
43
|
+
color="#000"
|
|
44
|
+
onOk={() => dispatch(setInfoMessage(null))}
|
|
45
|
+
/>}
|
|
46
|
+
</>;
|
|
47
|
+
}
|
|
@@ -1088,17 +1088,26 @@ function TreeComponent(props) {
|
|
|
1088
1088
|
id: item.id,
|
|
1089
1089
|
item,
|
|
1090
1090
|
getSelection,
|
|
1091
|
+
isInSelection,
|
|
1091
1092
|
type: nodeDragSourceType,
|
|
1093
|
+
onDragStart: () => {
|
|
1094
|
+
if (!isInSelection(item)) { // get updated isSelected (will be stale if using one in closure)
|
|
1095
|
+
// reset the selection to just this one node if it's not already selected
|
|
1096
|
+
setSelection([item]);
|
|
1097
|
+
}
|
|
1098
|
+
},
|
|
1092
1099
|
};
|
|
1093
1100
|
|
|
1094
1101
|
// Prevent root nodes from being dragged, and use custom logic if provided
|
|
1095
1102
|
nodeDragProps.canDrag = (monitor) => {
|
|
1096
1103
|
const currentSelection = getSelection();
|
|
1097
1104
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1105
|
+
if (isInSelection(item)) {
|
|
1106
|
+
// make sure root node is not selected (can't drag root nodes)
|
|
1107
|
+
const hasRootNode = currentSelection.some(node => node.isRoot);
|
|
1108
|
+
if (hasRootNode) {
|
|
1109
|
+
return false;
|
|
1110
|
+
}
|
|
1102
1111
|
}
|
|
1103
1112
|
|
|
1104
1113
|
// Use custom drag validation if provided
|
|
@@ -1118,7 +1127,7 @@ function TreeComponent(props) {
|
|
|
1118
1127
|
// Add drag preview rendering
|
|
1119
1128
|
nodeDragProps.getDragProxy = getCustomDragProxy ?
|
|
1120
1129
|
(dragItem) => getCustomDragProxy(item, getSelection()) :
|
|
1121
|
-
null; //
|
|
1130
|
+
null; // let GlobalDragProxy handle the default case
|
|
1122
1131
|
|
|
1123
1132
|
const dropTargetAccept = 'internal';
|
|
1124
1133
|
nodeDragProps.isDropTarget = true;
|
|
@@ -1178,15 +1187,22 @@ function TreeComponent(props) {
|
|
|
1178
1187
|
nodeDragProps.isDragSource = !item.isRoot; // Root nodes cannot be dragged
|
|
1179
1188
|
nodeDragProps.dragSourceType = nodeDragSourceType;
|
|
1180
1189
|
if (getNodeDragSourceItem) {
|
|
1181
|
-
nodeDragProps.dragSourceItem = getNodeDragSourceItem(item, getSelection, nodeDragSourceType);
|
|
1190
|
+
nodeDragProps.dragSourceItem = getNodeDragSourceItem(item, getSelection, isInSelection, nodeDragSourceType);
|
|
1182
1191
|
} else {
|
|
1183
1192
|
nodeDragProps.dragSourceItem = {
|
|
1184
1193
|
id: item.id,
|
|
1185
1194
|
item,
|
|
1186
1195
|
getSelection,
|
|
1196
|
+
isInSelection,
|
|
1187
1197
|
type: nodeDragSourceType,
|
|
1188
1198
|
};
|
|
1189
1199
|
}
|
|
1200
|
+
nodeDragProps.dragSourceItem.onDragStart = () => {
|
|
1201
|
+
if (!isInSelection(item)) { // get updated isSelected (will be stale if using one in closure)
|
|
1202
|
+
// reset the selection to just this one node if it's not already selected
|
|
1203
|
+
setSelection([item]);
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1190
1206
|
if (canNodeMoveExternally) {
|
|
1191
1207
|
nodeDragProps.canDrag = canNodeMoveExternally;
|
|
1192
1208
|
}
|
|
@@ -16,7 +16,7 @@ import UiGlobals from '../../UiGlobals.js';
|
|
|
16
16
|
import withDraggable from '../Hoc/withDraggable.js';
|
|
17
17
|
import IconButton from '../Buttons/IconButton.js';
|
|
18
18
|
import { withDragSource, withDropTarget } from '../Hoc/withDnd.js';
|
|
19
|
-
import
|
|
19
|
+
import RowHandle from '../Grid/RowHandle.js';
|
|
20
20
|
import testProps from '../../Functions/testProps.js';
|
|
21
21
|
import ChevronRight from '../Icons/ChevronRight.js';
|
|
22
22
|
import ChevronDown from '../Icons/ChevronDown.js';
|
|
@@ -40,11 +40,13 @@ export default function TreeNode(props) {
|
|
|
40
40
|
nodeProps = {},
|
|
41
41
|
onToggle,
|
|
42
42
|
bg,
|
|
43
|
+
isDraggable,
|
|
43
44
|
isDragSource,
|
|
44
45
|
isHovered,
|
|
45
46
|
isHighlighted,
|
|
46
47
|
isOver,
|
|
47
48
|
isSelected,
|
|
49
|
+
showSelectHandle,
|
|
48
50
|
canDrop,
|
|
49
51
|
draggedItem,
|
|
50
52
|
validateDrop, // same as canDrop (for visual feedback)
|
|
@@ -144,19 +146,21 @@ export default function TreeNode(props) {
|
|
|
144
146
|
backgroundColor: bg,
|
|
145
147
|
}}
|
|
146
148
|
ref={(element) => {
|
|
147
|
-
// Attach both drag and drop refs to the same element
|
|
148
|
-
if (dragSourceRef && typeof dragSourceRef === 'function') {
|
|
149
|
-
dragSourceRef(element);
|
|
150
|
-
}
|
|
151
149
|
if (dropTargetRef && dropTargetRef.current !== undefined) {
|
|
152
150
|
// dropTargetRef is a ref object, not a callback
|
|
153
151
|
dropTargetRef.current = element;
|
|
154
152
|
}
|
|
155
153
|
}}
|
|
156
154
|
>
|
|
157
|
-
{isPhantom && <Box t
|
|
155
|
+
{isPhantom && <Box className="absolute t-0 l-0 bg-[#f00] h-[2px] w-[2px]" />}
|
|
158
156
|
|
|
159
|
-
{isDragSource
|
|
157
|
+
{(isDragSource || showSelectHandle) &&
|
|
158
|
+
<RowHandle
|
|
159
|
+
ref={dragSourceRef}
|
|
160
|
+
isDragSource={isDragSource}
|
|
161
|
+
isDraggable={isDraggable}
|
|
162
|
+
showSelectHandle={showSelectHandle}
|
|
163
|
+
/>}
|
|
160
164
|
|
|
161
165
|
{hasChildren && <IconButton
|
|
162
166
|
{...testProps('expandBtn')}
|
|
@@ -180,12 +184,8 @@ export default function TreeNode(props) {
|
|
|
180
184
|
'flex',
|
|
181
185
|
'flex-1',
|
|
182
186
|
'text-ellipsis',
|
|
183
|
-
'select-none',
|
|
184
187
|
styles.TREE_NODE_CLASSNAME,
|
|
185
188
|
)}
|
|
186
|
-
style={{
|
|
187
|
-
userSelect: 'none',
|
|
188
|
-
}}
|
|
189
189
|
>{text}</TextNative>}
|
|
190
190
|
|
|
191
191
|
{content}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
1
2
|
import {
|
|
2
3
|
Icon,
|
|
3
4
|
VStack,
|
|
@@ -6,11 +7,11 @@ import clsx from 'clsx';
|
|
|
6
7
|
import styles from '../../Styles/StyleSheets.js';
|
|
7
8
|
import GripVertical from '../Icons/GripVertical.js';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const TreeNodeDragHandle = forwardRef(function(props, ref) {
|
|
10
11
|
let className = clsx(
|
|
11
12
|
'TreeNodeDragHandle',
|
|
12
13
|
'h-full',
|
|
13
|
-
'w-[
|
|
14
|
+
'w-[17px]',
|
|
14
15
|
'px-[2px]',
|
|
15
16
|
'border-l-2',
|
|
16
17
|
'items-center',
|
|
@@ -21,14 +22,17 @@ function TreeNodeDragHandle(props) {
|
|
|
21
22
|
className += ' ' + props.className;
|
|
22
23
|
}
|
|
23
24
|
return <VStack
|
|
25
|
+
{...props}
|
|
26
|
+
ref={ref}
|
|
24
27
|
style={styles.ewResize}
|
|
25
28
|
className={className}
|
|
26
29
|
>
|
|
27
30
|
<Icon
|
|
28
31
|
as={GripVertical}
|
|
29
32
|
size="xs"
|
|
30
|
-
className="handle w-full h-full text-[#ccc]"
|
|
33
|
+
className="handle w-full h-full text-[#ccc]"
|
|
34
|
+
/>
|
|
31
35
|
</VStack>;
|
|
32
|
-
}
|
|
36
|
+
});
|
|
33
37
|
|
|
34
38
|
export default TreeNodeDragHandle;
|
|
@@ -2,6 +2,13 @@ import {
|
|
|
2
2
|
TextNative,
|
|
3
3
|
} from '@project-components/Gluestack';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
+
import {
|
|
6
|
+
METER_TYPES__HOURS,
|
|
7
|
+
METER_TYPES__MILES,
|
|
8
|
+
METER_TYPES__HOURS_TEXT,
|
|
9
|
+
METER_TYPES__MILES_TEXT,
|
|
10
|
+
} from '../../Constants/MeterTypes';
|
|
11
|
+
|
|
5
12
|
import UiGlobals from '../../UiGlobals';
|
|
6
13
|
|
|
7
14
|
export default function MeterTypeText(props) {
|
|
@@ -17,8 +24,21 @@ export default function MeterTypeText(props) {
|
|
|
17
24
|
if (props.className) {
|
|
18
25
|
className += ' ' + props.className;
|
|
19
26
|
}
|
|
27
|
+
let meterType = '';
|
|
28
|
+
switch(props.value) {
|
|
29
|
+
case METER_TYPES__HOURS:
|
|
30
|
+
meterType = METER_TYPES__HOURS_TEXT;
|
|
31
|
+
break;
|
|
32
|
+
case METER_TYPES__MILES:
|
|
33
|
+
meterType = METER_TYPES__MILES_TEXT;
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
meterType = 'unknown';
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
|
|
20
40
|
return <TextNative
|
|
21
41
|
{...props}
|
|
22
42
|
className={className}
|
|
23
|
-
>{
|
|
43
|
+
>{meterType}</TextNative>;
|
|
24
44
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import {
|
|
4
|
+
UI_MODE_WEB,
|
|
5
|
+
UI_MODE_NATIVE,
|
|
6
|
+
CURRENT_MODE,
|
|
7
|
+
} from '../Constants/UiModes.js';
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
|
|
10
|
+
export default function addIconProps(iconProps = {}) {
|
|
11
|
+
|
|
12
|
+
iconProps = _.cloneDeep(iconProps); // avoid mutating the original props, as they may be submitted to multiple components
|
|
13
|
+
|
|
14
|
+
iconProps.className = clsx(
|
|
15
|
+
'Icon',
|
|
16
|
+
iconProps.className,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (CURRENT_MODE === UI_MODE_WEB) {
|
|
20
|
+
return iconProps;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// native only
|
|
24
|
+
|
|
25
|
+
// marginx
|
|
26
|
+
iconProps.style = {
|
|
27
|
+
marginHorizontal: 8,
|
|
28
|
+
...iconProps.style,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// On native, react-native-svg ignores className and will only size the icon based on
|
|
32
|
+
// explicit width / height props (or size if the wrapper supports it).
|
|
33
|
+
// If no size set, it falls back to the full intrinsic viewBox size, so we need to ensure we set a default size.
|
|
34
|
+
// If you want to override the size, pass width and height props to the icon.
|
|
35
|
+
if (iconProps.width || iconProps.height) {
|
|
36
|
+
return iconProps;
|
|
37
|
+
}
|
|
38
|
+
const nativeDefaults = {
|
|
39
|
+
width: 24,
|
|
40
|
+
height: 24,
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
...nativeDefaults,
|
|
44
|
+
...iconProps,
|
|
45
|
+
};
|
|
46
|
+
}
|