@onehat/ui 0.4.71 → 0.4.73
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 +2 -1
- package/src/Components/Buttons/Button.js +20 -6
- package/src/Components/Container/ScreenContainer.js +1 -0
- package/src/Components/Editor/InlineEditor.js +2 -1
- package/src/Components/Form/Field/Color.js +2 -1
- package/src/Components/Form/Field/Combo/Combo.js +55 -37
- package/src/Components/Form/Field/Combo/MeterTypesCombo.js +4 -2
- package/src/Components/Form/Field/Date.js +9 -8
- package/src/Components/Form/Field/Input.js +5 -4
- package/src/Components/Form/Field/Json.js +3 -2
- package/src/Components/Form/Field/TextArea.js +1 -1
- package/src/Components/Form/FieldSet.js +1 -1
- package/src/Components/Form/Form.js +4 -1
- package/src/Components/Gluestack/accordion/index.tsx +5 -1
- package/src/Components/Gluestack/actionsheet/index.tsx +5 -1
- package/src/Components/Gluestack/alert/index.tsx +5 -1
- package/src/Components/Gluestack/badge/index.tsx +5 -1
- package/src/Components/Gluestack/button/index.tsx +5 -1
- package/src/Components/Gluestack/checkbox/index.tsx +5 -1
- package/src/Components/Gluestack/fab/index.tsx +5 -1
- package/src/Components/Gluestack/form-control/index.tsx +5 -1
- package/src/Components/Gluestack/icon/createIcon.js +74 -0
- package/src/Components/Gluestack/icon/index.tsx +46 -88
- package/src/Components/Gluestack/input/index.tsx +5 -1
- package/src/Components/Gluestack/select/index.tsx +5 -1
- package/src/Components/Grid/Grid.js +24 -11
- package/src/Components/Grid/GridHeaderRow.js +4 -3
- 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 +21 -11
- 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 +52 -40
- 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 +70 -0
- package/src/Components/Messages/Loading.js +2 -2
- package/src/Components/Messages/ProgressModal.js +63 -0
- package/src/Components/Messages/WaitMessage.js +7 -2
- package/src/Components/Report/Report.js +15 -5
- package/src/Components/Toolbar/Pagination.js +1 -1
- package/src/Components/Toolbar/Toolbar.js +26 -6
- 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/Components/Viewer/TextWithLinks.js +2 -1
- package/src/Constants/Dates.js +5 -2
- package/src/Constants/MeterTypes.js +2 -0
- package/src/Functions/addIconProps.js +46 -0
- package/src/Functions/downloadInBackground.js +47 -7
- package/src/Functions/getReport.js +5 -2
- package/src/Functions/testProps.js +1 -1
- package/src/Functions/trackEngagementHit.js +2 -1
- package/src/Hooks/useWhyDidYouUpdate.js +33 -0
- package/src/PlatformImports/Web/Attachments.js +1 -1
- package/src/Components/Hoc/withBlank.js +0 -10
|
@@ -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,70 @@
|
|
|
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
|
+
selectProgressMessage,
|
|
13
|
+
selectProgressPercentage,
|
|
14
|
+
} from '@src/models/Slices/DebugSlice';
|
|
15
|
+
import WaitMessage from './WaitMessage';
|
|
16
|
+
import ErrorMessage from './ErrorMessage';
|
|
17
|
+
import ProgressModal from './ProgressModal';
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export default function GlobalModals(props) {
|
|
22
|
+
const {
|
|
23
|
+
progressColor = '#666',
|
|
24
|
+
} = props,
|
|
25
|
+
dispatch = useDispatch(),
|
|
26
|
+
isWaitModalShown = useSelector(selectIsWaitModalShown),
|
|
27
|
+
alertMessage = useSelector(selectAlertMessage),
|
|
28
|
+
debugMessage = useSelector(selectDebugMessage),
|
|
29
|
+
infoMessage = useSelector(selectInfoMessage),
|
|
30
|
+
waitMessage = useSelector(selectWaitMessage),
|
|
31
|
+
progressMessage = useSelector(selectProgressMessage),
|
|
32
|
+
progressPercentage = useSelector(selectProgressPercentage);
|
|
33
|
+
|
|
34
|
+
let moduleToShow = null;
|
|
35
|
+
|
|
36
|
+
if (debugMessage) {
|
|
37
|
+
moduleToShow =
|
|
38
|
+
<ErrorMessage
|
|
39
|
+
text={debugMessage}
|
|
40
|
+
onOk={() => dispatch(setDebugMessage(null))}
|
|
41
|
+
color="green"
|
|
42
|
+
/>;
|
|
43
|
+
} else if (alertMessage) {
|
|
44
|
+
moduleToShow =
|
|
45
|
+
<ErrorMessage
|
|
46
|
+
text={alertMessage}
|
|
47
|
+
onOk={() => dispatch(setAlertMessage(null))}
|
|
48
|
+
/>;
|
|
49
|
+
} else if (infoMessage) {
|
|
50
|
+
moduleToShow =
|
|
51
|
+
<ErrorMessage
|
|
52
|
+
text={infoMessage}
|
|
53
|
+
onOk={() => dispatch(setInfoMessage(null))}
|
|
54
|
+
color="#000"
|
|
55
|
+
/>;
|
|
56
|
+
}
|
|
57
|
+
if (isWaitModalShown) {
|
|
58
|
+
moduleToShow = <WaitMessage text={waitMessage} />;
|
|
59
|
+
}
|
|
60
|
+
if (progressMessage && progressPercentage < 100) {
|
|
61
|
+
moduleToShow = <ProgressModal
|
|
62
|
+
progressMessage={progressMessage}
|
|
63
|
+
progressPercentage={progressPercentage}
|
|
64
|
+
color={progressColor}
|
|
65
|
+
/>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return moduleToShow;
|
|
69
|
+
}
|
|
70
|
+
|
|
@@ -10,14 +10,14 @@ import ScreenContainer from '../Container/ScreenContainer.js';
|
|
|
10
10
|
export default function Loading(props) {
|
|
11
11
|
|
|
12
12
|
if (props.isScreen) {
|
|
13
|
-
return <ScreenContainer {...props}>
|
|
13
|
+
return <ScreenContainer className="h-full w-full" {...props}>
|
|
14
14
|
<HStack className="flex-1 justify-center items-center">
|
|
15
15
|
<Spinner className="text-primary-500 mr-1" />
|
|
16
16
|
<Text>Loading</Text>
|
|
17
17
|
</HStack>
|
|
18
18
|
</ScreenContainer>;
|
|
19
19
|
}
|
|
20
|
-
return <HStackNative {...props} className="justify-center min-h-[100px]">
|
|
20
|
+
return <HStackNative {...props} className="justify-center min-h-[100px] h-full w-full">
|
|
21
21
|
<Spinner className="flex-1 text-primary-500" />
|
|
22
22
|
</HStackNative>;
|
|
23
23
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useState, useEffect, } from 'react';import {
|
|
2
|
+
HStack,
|
|
3
|
+
Modal, ModalBackdrop, ModalHeader, ModalContent, ModalCloseButton, ModalBody, ModalFooter,
|
|
4
|
+
Spinner,
|
|
5
|
+
Text,
|
|
6
|
+
VStack,
|
|
7
|
+
} from '@project-components/Gluestack';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import { useSelector } from 'react-redux';
|
|
10
|
+
import * as Progress from 'react-native-progress';
|
|
11
|
+
import testProps from '../../Functions/testProps';
|
|
12
|
+
|
|
13
|
+
let progressTimeout = null;
|
|
14
|
+
|
|
15
|
+
export default function ProgressModal(props) {
|
|
16
|
+
const {
|
|
17
|
+
progressMessage,
|
|
18
|
+
progressPercentage,
|
|
19
|
+
color = '#666',
|
|
20
|
+
} = props,
|
|
21
|
+
[progressBarWidth, setProgressBarWidth] = useState(175),
|
|
22
|
+
[isInited, setIsInited] = useState(false);
|
|
23
|
+
|
|
24
|
+
return <Modal
|
|
25
|
+
{...testProps('ProgressModal')}
|
|
26
|
+
isOpen={true}
|
|
27
|
+
className="Modal"
|
|
28
|
+
aria-disabled={true}
|
|
29
|
+
>
|
|
30
|
+
<ModalBackdrop />
|
|
31
|
+
<ModalContent
|
|
32
|
+
className={clsx(
|
|
33
|
+
'ModalContent',
|
|
34
|
+
'max-w-[400px]',
|
|
35
|
+
'shadow-lg',
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
<VStack
|
|
39
|
+
className={clsx(
|
|
40
|
+
'VStack',
|
|
41
|
+
'w-[90%]',
|
|
42
|
+
'items-center',
|
|
43
|
+
'justify-center',
|
|
44
|
+
'self-center',
|
|
45
|
+
)}
|
|
46
|
+
onLayout={(e) => {
|
|
47
|
+
setProgressBarWidth(e.nativeEvent.layout.width);
|
|
48
|
+
setIsInited(true);
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<Text className="text-black mb-2">{progressMessage}</Text>
|
|
52
|
+
{isInited &&
|
|
53
|
+
<Progress.Bar
|
|
54
|
+
animated={false}
|
|
55
|
+
progress={progressPercentage / 100}
|
|
56
|
+
width={progressBarWidth}
|
|
57
|
+
height={20}
|
|
58
|
+
color={color}
|
|
59
|
+
/>}
|
|
60
|
+
</VStack>
|
|
61
|
+
</ModalContent>
|
|
62
|
+
</Modal>;
|
|
63
|
+
}
|
|
@@ -5,6 +5,11 @@ import {
|
|
|
5
5
|
Text,
|
|
6
6
|
} from '@project-components/Gluestack';
|
|
7
7
|
import clsx from 'clsx';
|
|
8
|
+
import {
|
|
9
|
+
CURRENT_MODE,
|
|
10
|
+
UI_MODE_WEB,
|
|
11
|
+
UI_MODE_NATIVE,
|
|
12
|
+
} from '../../Constants/UiModes.js';
|
|
8
13
|
import testProps from '../../Functions/testProps.js';
|
|
9
14
|
|
|
10
15
|
export default function WaitMessage(props) {
|
|
@@ -19,14 +24,14 @@ export default function WaitMessage(props) {
|
|
|
19
24
|
{...testProps('WaitMessage')}
|
|
20
25
|
isOpen={true}
|
|
21
26
|
className="Modal"
|
|
22
|
-
aria-disabled=
|
|
27
|
+
aria-disabled={true}
|
|
23
28
|
>
|
|
24
29
|
<ModalBackdrop />
|
|
25
30
|
<ModalContent
|
|
26
31
|
className={clsx(
|
|
27
32
|
'ModalContent',
|
|
28
33
|
'w-[200px]',
|
|
29
|
-
'h-[50px]',
|
|
34
|
+
CURRENT_MODE === UI_MODE_WEB ? 'h-[50px]' : '',
|
|
30
35
|
'shadow-lg',
|
|
31
36
|
)}
|
|
32
37
|
>
|
|
@@ -41,6 +41,7 @@ function Report(props) {
|
|
|
41
41
|
disableExcel = false,
|
|
42
42
|
showReportHeaders = true,
|
|
43
43
|
isQuickReport = false,
|
|
44
|
+
additionalData = {},
|
|
44
45
|
quickReportData = {},
|
|
45
46
|
alert,
|
|
46
47
|
} = props,
|
|
@@ -50,7 +51,10 @@ function Report(props) {
|
|
|
50
51
|
reportId,
|
|
51
52
|
reportType: REPORT_TYPES__EXCEL,
|
|
52
53
|
showReportHeaders,
|
|
53
|
-
data:
|
|
54
|
+
data: {
|
|
55
|
+
...additionalData,
|
|
56
|
+
...quickReportData,
|
|
57
|
+
},
|
|
54
58
|
});
|
|
55
59
|
},
|
|
56
60
|
downloadReport = (args) => {
|
|
@@ -74,8 +78,8 @@ function Report(props) {
|
|
|
74
78
|
|
|
75
79
|
if (isQuickReport) {
|
|
76
80
|
let className = clsx(
|
|
77
|
-
'
|
|
78
|
-
'
|
|
81
|
+
'QuickReport',
|
|
82
|
+
'flex-1',
|
|
79
83
|
'm-2',
|
|
80
84
|
);
|
|
81
85
|
if (props.className) {
|
|
@@ -122,7 +126,10 @@ function Report(props) {
|
|
|
122
126
|
icon: Excel,
|
|
123
127
|
onPress: (data) => downloadReport({
|
|
124
128
|
reportId,
|
|
125
|
-
data
|
|
129
|
+
data: {
|
|
130
|
+
...data,
|
|
131
|
+
...additionalData,
|
|
132
|
+
},
|
|
126
133
|
reportType: REPORT_TYPES__EXCEL,
|
|
127
134
|
showReportHeaders,
|
|
128
135
|
}),
|
|
@@ -137,7 +144,10 @@ function Report(props) {
|
|
|
137
144
|
icon: Pdf,
|
|
138
145
|
onPress: (data) => downloadReport({
|
|
139
146
|
reportId,
|
|
140
|
-
data
|
|
147
|
+
data: {
|
|
148
|
+
...data,
|
|
149
|
+
...additionalData,
|
|
150
|
+
},
|
|
141
151
|
reportType: REPORT_TYPES__PDF,
|
|
142
152
|
showReportHeaders,
|
|
143
153
|
}),
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HStackNative,
|
|
3
|
+
ScrollView,
|
|
3
4
|
} from '@project-components/Gluestack';
|
|
4
5
|
import clsx from 'clsx';
|
|
6
|
+
import {
|
|
7
|
+
CURRENT_MODE,
|
|
8
|
+
UI_MODE_NATIVE,
|
|
9
|
+
} from '../../Constants/UiModes.js';
|
|
5
10
|
import UiGlobals from '../../UiGlobals.js';
|
|
6
11
|
|
|
7
12
|
export default function Toolbar(props) {
|
|
@@ -20,13 +25,28 @@ export default function Toolbar(props) {
|
|
|
20
25
|
'border-b-grey-400',
|
|
21
26
|
styles.TOOLBAR_CLASSNAME,
|
|
22
27
|
);
|
|
28
|
+
if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
29
|
+
className += ' min-w-[100%]';
|
|
30
|
+
}
|
|
23
31
|
if (props.className) {
|
|
24
32
|
className += ' ' + props.className
|
|
25
33
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
let toolbar = <HStackNative
|
|
35
|
+
className={className}
|
|
36
|
+
style={props.style || {}}
|
|
37
|
+
>
|
|
38
|
+
{props.children}
|
|
39
|
+
</HStackNative>;
|
|
40
|
+
|
|
41
|
+
if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
42
|
+
toolbar = <ScrollView
|
|
43
|
+
horizontal={true}
|
|
44
|
+
className={clsx(
|
|
45
|
+
'min-w-[100%]',
|
|
46
|
+
'max-h-[50px]',
|
|
47
|
+
)}
|
|
48
|
+
>{toolbar}</ScrollView>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return toolbar;
|
|
32
52
|
};
|
|
@@ -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
|
};
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from '@project-components/Gluestack';
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import {
|
|
11
|
+
CURRENT_MODE,
|
|
11
12
|
UI_MODE_WEB,
|
|
12
13
|
} from '../../Constants/UiModes.js';
|
|
13
14
|
import UiGlobals from '../../UiGlobals.js';
|
|
@@ -78,7 +79,7 @@ function TextWithLinksElement(props) {
|
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
const elementProps = {};
|
|
81
|
-
if (
|
|
82
|
+
if (CURRENT_MODE === UI_MODE_WEB) {
|
|
82
83
|
elementProps.textOverflow = 'ellipsis';
|
|
83
84
|
}
|
|
84
85
|
let className = clsx(
|
package/src/Constants/Dates.js
CHANGED
|
@@ -10,8 +10,11 @@ export const ONE_MONTH_AGO = moment().add(-1, 'months');
|
|
|
10
10
|
export const TWO_MONTHS_AGO = moment().add(-2, 'months');
|
|
11
11
|
export const SIX_MONTHS_AGO = moment().add(-6, 'months');
|
|
12
12
|
export const ONE_MONTH_FROM_NOW = moment().add(1, 'months');
|
|
13
|
+
export const START_OF_THIS_MONTH = moment().startOf('months');
|
|
14
|
+
export const END_OF_LAST_MONTH = moment().subtract(1, 'months').endOf('month');
|
|
13
15
|
export const ONE_YEAR_AGO = moment().add(-1, 'years');
|
|
14
16
|
export const MOMENT_DATE_FORMAT_1 = 'YYYY-MM-DD HH:mm:ss';
|
|
15
|
-
export const MOMENT_DATE_FORMAT_2 = 'MMMM Do YYYY, h:mm:ss a';
|
|
16
|
-
export const MOMENT_DATE_FORMAT_3 = 'h:mm A';
|
|
17
|
+
export const MOMENT_DATE_FORMAT_2 = 'MMMM Do YYYY, h:mm:ss a'; // pretty datetime
|
|
18
|
+
export const MOMENT_DATE_FORMAT_3 = 'h:mm A'; // pretty time
|
|
17
19
|
export const MOMENT_DATE_FORMAT_4 = 'YYYY-MM-DD';
|
|
20
|
+
export const MOMENT_DATE_FORMAT_5 = 'HH:mm:ss';
|
|
@@ -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
|
+
}
|