@onehat/ui 0.4.39 → 0.4.41
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 +6 -13
- package/src/Components/Filter/DateRange.js +3 -1
- package/src/Components/Filter/NumberRange.js +4 -1
- package/src/Components/Form/Field/Combo/Combo.js +27 -20
- package/src/Components/Form/Field/Combo/MeterTypesCombo.js +2 -2
- package/src/Components/Form/Field/Combo/PageSizeCombo.js +1 -0
- package/src/Components/Form/Field/Date.js +15 -2
- package/src/Components/Form/Field/Number.js +4 -6
- package/src/Components/Form/Field/Select/PageSizeSelect.js +1 -0
- package/src/Components/Form/Field/Slider.js +186 -191
- package/src/Components/Form/Field/TextArea.js +96 -98
- package/src/Components/Form/Form.js +9 -6
- package/src/Components/Grid/Grid.js +6 -3
- package/src/Components/Hoc/Secondary/withSecondarySelection.js +22 -7
- package/src/Components/Hoc/withMultiSelection.js +1 -2
- package/src/Components/Hoc/withSelection.js +23 -8
- package/src/Components/Hoc/withTooltip.js +7 -1
- package/src/Components/Toolbar/Pagination.js +1 -0
- package/src/Components/Tooltip/Tooltip.js +13 -10
- package/src/Components/Viewer/MeterTypeText.js +3 -3
package/package.json
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ButtonSpinner,
|
|
6
6
|
ButtonIcon,
|
|
7
7
|
ButtonGroup,
|
|
8
|
-
Tooltip,
|
|
9
8
|
} from '@project-components/Gluestack';
|
|
10
9
|
import withComponent from '../Hoc/withComponent.js';
|
|
11
10
|
import withTooltip from '../Hoc/withTooltip.js';
|
|
@@ -22,7 +21,6 @@ const ButtonComponent = forwardRef((props, ref) => {
|
|
|
22
21
|
_icon, // props for icon
|
|
23
22
|
_rightIcon, // props for rightIcon
|
|
24
23
|
_text = {}, // props for ButtonText
|
|
25
|
-
tooltip,
|
|
26
24
|
...propsToPass
|
|
27
25
|
} = props;
|
|
28
26
|
|
|
@@ -61,17 +59,12 @@ const ButtonComponent = forwardRef((props, ref) => {
|
|
|
61
59
|
className += ' ' + propsToPass.className;
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (tooltip) {
|
|
71
|
-
button = <Tooltip text={tooltip}>{button}</Tooltip>;
|
|
72
|
-
}
|
|
73
|
-
return button;
|
|
74
|
-
|
|
62
|
+
return <Button {...propsToPass} className={className} ref={ref}>
|
|
63
|
+
{isLoading && <ButtonSpinner className="ButtonSpinner" {..._spinner} />}
|
|
64
|
+
{icon}
|
|
65
|
+
{text && <ButtonText className="ButtonText" {..._text}>{text}</ButtonText>}
|
|
66
|
+
{rightIcon}
|
|
67
|
+
</Button>;
|
|
75
68
|
});
|
|
76
69
|
|
|
77
70
|
export default withComponent(withTooltip(ButtonComponent));
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
} from '@project-components/Gluestack';
|
|
7
7
|
import Date from '../Form/Field/Date.js';
|
|
8
8
|
import testProps from '../../Functions/testProps.js';
|
|
9
|
-
import withTooltip from '../Hoc/withTooltip.js';
|
|
10
9
|
import withValue from '../Hoc/withValue.js';
|
|
11
10
|
import _ from 'lodash';
|
|
12
11
|
|
|
@@ -22,6 +21,7 @@ const
|
|
|
22
21
|
minValue,
|
|
23
22
|
maxValue,
|
|
24
23
|
tooltip,
|
|
24
|
+
tooltipPlacement,
|
|
25
25
|
|
|
26
26
|
// withComponent
|
|
27
27
|
self,
|
|
@@ -100,6 +100,7 @@ const
|
|
|
100
100
|
minValue={minValue}
|
|
101
101
|
maxValue={maxValue}
|
|
102
102
|
tooltip={(tooltip ? tooltip + ' ' : '') + 'Low'}
|
|
103
|
+
tooltipPlacement={tooltipPlacement}
|
|
103
104
|
limitWidth={true}
|
|
104
105
|
parent={self}
|
|
105
106
|
reference="low"
|
|
@@ -113,6 +114,7 @@ const
|
|
|
113
114
|
minValue={minValue}
|
|
114
115
|
maxValue={maxValue}
|
|
115
116
|
tooltip={(tooltip ? tooltip + ' ' : '') + 'High'}
|
|
117
|
+
tooltipPlacement={tooltipPlacement}
|
|
116
118
|
limitWidth={true}
|
|
117
119
|
parent={self}
|
|
118
120
|
reference="high"
|
|
@@ -17,7 +17,8 @@ const
|
|
|
17
17
|
high: null,
|
|
18
18
|
},
|
|
19
19
|
setValue,
|
|
20
|
-
tooltip
|
|
20
|
+
tooltip,
|
|
21
|
+
tooltipPlacement,
|
|
21
22
|
|
|
22
23
|
minValue = 0,
|
|
23
24
|
maxValue,
|
|
@@ -82,6 +83,7 @@ const
|
|
|
82
83
|
minValue={minValue}
|
|
83
84
|
maxValue={maxValue}
|
|
84
85
|
tooltip={(tooltip ? tooltip + ' ' : '') + 'Low'}
|
|
86
|
+
tooltipPlacement={tooltipPlacement}
|
|
85
87
|
className="max-w-[150px]"
|
|
86
88
|
/>
|
|
87
89
|
<Text className="px-2 select-none">to</Text>
|
|
@@ -93,6 +95,7 @@ const
|
|
|
93
95
|
minValue={minValue}
|
|
94
96
|
maxValue={maxValue}
|
|
95
97
|
tooltip={(tooltip ? tooltip + ' ' : '') + 'High'}
|
|
98
|
+
tooltipPlacement={tooltipPlacement}
|
|
96
99
|
className="max-w-[150px]"
|
|
97
100
|
/>
|
|
98
101
|
</HStack>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef, useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
HStack,
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
Pressable,
|
|
10
10
|
Text,
|
|
11
11
|
TextNative,
|
|
12
|
-
Tooltip,
|
|
13
12
|
VStackNative,
|
|
14
13
|
} from '@project-components/Gluestack';
|
|
15
14
|
import {
|
|
@@ -37,13 +36,11 @@ import _ from 'lodash';
|
|
|
37
36
|
|
|
38
37
|
const FILTER_NAME = 'q';
|
|
39
38
|
|
|
40
|
-
export
|
|
39
|
+
export const ComboComponent = forwardRef((props, ref) => {
|
|
41
40
|
|
|
42
41
|
const {
|
|
43
42
|
additionalButtons,
|
|
44
43
|
autoFocus = false,
|
|
45
|
-
tooltipRef = null,
|
|
46
|
-
tooltip = null,
|
|
47
44
|
menuMinWidth,
|
|
48
45
|
disableDirectEntry = false,
|
|
49
46
|
hideMenuOnSelection = true,
|
|
@@ -58,7 +55,6 @@ export function ComboComponent(props) {
|
|
|
58
55
|
minimizeForRow = false,
|
|
59
56
|
reloadOnTrigger = false,
|
|
60
57
|
menuHeight,
|
|
61
|
-
tooltipPlacement = 'bottom',
|
|
62
58
|
placeholder,
|
|
63
59
|
onRowPress,
|
|
64
60
|
icon,
|
|
@@ -68,6 +64,8 @@ export function ComboComponent(props) {
|
|
|
68
64
|
onGridDelete, // to hook into when menu deletes (ComboEditor only)
|
|
69
65
|
onSubmit, // when Combo is used in a Tag, call this when the user submits the Combo value (i.e. presses Enter or clicks a row)
|
|
70
66
|
newEntityDisplayProperty,
|
|
67
|
+
tooltip = null,
|
|
68
|
+
tooltipPlacement = 'bottom',
|
|
71
69
|
testID,
|
|
72
70
|
|
|
73
71
|
// withComponent
|
|
@@ -630,6 +628,14 @@ export function ComboComponent(props) {
|
|
|
630
628
|
InputLeftElement={inputIconElement}
|
|
631
629
|
autoSubmitDelay={500}
|
|
632
630
|
placeholder={placeholder}
|
|
631
|
+
tooltip={tooltip}
|
|
632
|
+
tooltipPlacement={tooltipPlacement}
|
|
633
|
+
tooltipClassName={`
|
|
634
|
+
grow
|
|
635
|
+
h-auto
|
|
636
|
+
self-stretch
|
|
637
|
+
flex-1
|
|
638
|
+
`}
|
|
633
639
|
className={`
|
|
634
640
|
Combo-Input
|
|
635
641
|
grow
|
|
@@ -858,6 +864,13 @@ export function ComboComponent(props) {
|
|
|
858
864
|
InputLeftElement={inputIconElement}
|
|
859
865
|
autoSubmitDelay={500}
|
|
860
866
|
placeholder={placeholder}
|
|
867
|
+
tooltip={tooltip}
|
|
868
|
+
tooltipPlacement={tooltipPlacement}
|
|
869
|
+
tooltipClassName={`
|
|
870
|
+
grow
|
|
871
|
+
h-full
|
|
872
|
+
flex-1
|
|
873
|
+
`}
|
|
861
874
|
className={`
|
|
862
875
|
Combo-inputClone-Input
|
|
863
876
|
grow
|
|
@@ -964,6 +977,12 @@ export function ComboComponent(props) {
|
|
|
964
977
|
InputLeftElement={inputIconElement}
|
|
965
978
|
autoSubmitDelay={500}
|
|
966
979
|
placeholder={placeholder}
|
|
980
|
+
tooltip={tooltip}
|
|
981
|
+
tooltipPlacement={tooltipPlacement}
|
|
982
|
+
tooltipClassName={`
|
|
983
|
+
h-full
|
|
984
|
+
flex-1
|
|
985
|
+
`}
|
|
967
986
|
className={`
|
|
968
987
|
h-full
|
|
969
988
|
flex-1
|
|
@@ -1014,10 +1033,6 @@ export function ComboComponent(props) {
|
|
|
1014
1033
|
</Modal>;
|
|
1015
1034
|
}
|
|
1016
1035
|
}
|
|
1017
|
-
const refProps = {};
|
|
1018
|
-
if (tooltipRef) {
|
|
1019
|
-
refProps.ref = tooltipRef;
|
|
1020
|
-
}
|
|
1021
1036
|
|
|
1022
1037
|
let className = `
|
|
1023
1038
|
Combo-HStack
|
|
@@ -1043,7 +1058,6 @@ export function ComboComponent(props) {
|
|
|
1043
1058
|
className="Combo-VStack"
|
|
1044
1059
|
>
|
|
1045
1060
|
<HStack
|
|
1046
|
-
{...refProps}
|
|
1047
1061
|
className={className}
|
|
1048
1062
|
>
|
|
1049
1063
|
{xButton}
|
|
@@ -1059,7 +1073,6 @@ export function ComboComponent(props) {
|
|
|
1059
1073
|
} else {
|
|
1060
1074
|
assembledComponents =
|
|
1061
1075
|
<HStackNative
|
|
1062
|
-
{...refProps}
|
|
1063
1076
|
testID={testID}
|
|
1064
1077
|
onLayout={onLayout}
|
|
1065
1078
|
className={className}
|
|
@@ -1115,15 +1128,9 @@ export function ComboComponent(props) {
|
|
|
1115
1128
|
</>;
|
|
1116
1129
|
}
|
|
1117
1130
|
|
|
1118
|
-
if (tooltip) {
|
|
1119
|
-
// TODO: implement withTooltip for Combo
|
|
1120
|
-
// assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement} className="h-full">
|
|
1121
|
-
// {assembledComponents}
|
|
1122
|
-
// </Tooltip>;
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
1131
|
return assembledComponents;
|
|
1126
|
-
|
|
1132
|
+
|
|
1133
|
+
});
|
|
1127
1134
|
|
|
1128
1135
|
export const Combo = withComponent(
|
|
1129
1136
|
withAlert(
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
} from '../../../../Constants/MeterTypes.js';
|
|
13
13
|
|
|
14
14
|
const data = [
|
|
15
|
-
[METER_TYPES__HOURS, '
|
|
16
|
-
[METER_TYPES__MILES, '
|
|
15
|
+
[METER_TYPES__HOURS, 'Time (hrs)'],
|
|
16
|
+
[METER_TYPES__MILES, 'Distance (mi/km)'],
|
|
17
17
|
];
|
|
18
18
|
function MeterTypesCombo(props) {
|
|
19
19
|
return <ArrayCombo
|
|
@@ -24,7 +24,6 @@ import Input from '../Field/Input.js';
|
|
|
24
24
|
import IconButton from '../../Buttons/IconButton.js';
|
|
25
25
|
import Xmark from '../../Icons/Xmark.js';
|
|
26
26
|
import withComponent from '../../Hoc/withComponent.js';
|
|
27
|
-
import withTooltip from '../../Hoc/withTooltip.js';
|
|
28
27
|
import withValue from '../../Hoc/withValue.js';
|
|
29
28
|
import emptyFn from '../../../Functions/emptyFn.js';
|
|
30
29
|
import testProps from '../../../Functions/testProps.js';
|
|
@@ -51,6 +50,8 @@ export const DateElement = forwardRef((props, ref) => {
|
|
|
51
50
|
minimizeForRow = false,
|
|
52
51
|
minValue,
|
|
53
52
|
maxValue,
|
|
53
|
+
tooltip = null,
|
|
54
|
+
tooltipPlacement = 'bottom',
|
|
54
55
|
testID,
|
|
55
56
|
|
|
56
57
|
// withComponent
|
|
@@ -359,6 +360,12 @@ export const DateElement = forwardRef((props, ref) => {
|
|
|
359
360
|
onFocus={onInputFocus}
|
|
360
361
|
autoSubmit={true}
|
|
361
362
|
isDisabled={isDisabled}
|
|
363
|
+
tooltip={tooltip}
|
|
364
|
+
tooltipPlacement={tooltipPlacement}
|
|
365
|
+
tooltipClassName={`
|
|
366
|
+
flex-1
|
|
367
|
+
h-full
|
|
368
|
+
`}
|
|
362
369
|
// onLayout={(e) => {
|
|
363
370
|
// const {
|
|
364
371
|
// height,
|
|
@@ -510,6 +517,12 @@ export const DateElement = forwardRef((props, ref) => {
|
|
|
510
517
|
onBlur={onInputBlur}
|
|
511
518
|
autoSubmitDelay={1000}
|
|
512
519
|
placeholder={placeholder}
|
|
520
|
+
tooltip={tooltip}
|
|
521
|
+
tooltipPlacement={tooltipPlacement}
|
|
522
|
+
tooltipClassName={`
|
|
523
|
+
flex-1
|
|
524
|
+
h-full
|
|
525
|
+
`}
|
|
513
526
|
className={`
|
|
514
527
|
flex-1
|
|
515
528
|
h-full
|
|
@@ -602,4 +615,4 @@ export const DateElement = forwardRef((props, ref) => {
|
|
|
602
615
|
|
|
603
616
|
});
|
|
604
617
|
|
|
605
|
-
export default withComponent(withValue(
|
|
618
|
+
export default withComponent(withValue(DateElement));
|
|
@@ -9,14 +9,11 @@ import IconButton from '../../Buttons/IconButton.js';
|
|
|
9
9
|
import Input from './Input.js';
|
|
10
10
|
import testProps from '../../../Functions/testProps.js';
|
|
11
11
|
import withComponent from '../../Hoc/withComponent.js';
|
|
12
|
-
import withTooltip from '../../Hoc/withTooltip.js';
|
|
13
12
|
import withValue from '../../Hoc/withValue.js';
|
|
14
13
|
import Plus from '../../Icons/Plus.js';
|
|
15
14
|
import Minus from '../../Icons/Minus.js';
|
|
16
15
|
import _ from 'lodash';
|
|
17
16
|
|
|
18
|
-
const InputWithTooltip = withTooltip(Input);
|
|
19
|
-
|
|
20
17
|
function NumberElement(props) {
|
|
21
18
|
let {
|
|
22
19
|
value,
|
|
@@ -24,7 +21,8 @@ function NumberElement(props) {
|
|
|
24
21
|
minValue,
|
|
25
22
|
maxValue,
|
|
26
23
|
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
27
|
-
tooltip
|
|
24
|
+
tooltip,
|
|
25
|
+
tooltipPlacement,
|
|
28
26
|
isDisabled = false,
|
|
29
27
|
testID,
|
|
30
28
|
} = props,
|
|
@@ -158,15 +156,15 @@ function NumberElement(props) {
|
|
|
158
156
|
width: 40,
|
|
159
157
|
}}
|
|
160
158
|
/>
|
|
161
|
-
<
|
|
159
|
+
<Input
|
|
162
160
|
testID={testID}
|
|
163
161
|
value={inputValue}
|
|
164
162
|
onChangeText={onChangeText}
|
|
165
163
|
onKeyPress={onInputKeyPress}
|
|
166
164
|
isDisabled={isDisabled}
|
|
167
165
|
tooltip={tooltip}
|
|
166
|
+
tooltipPlacement={tooltipPlacement}
|
|
168
167
|
className={`
|
|
169
|
-
InputWithTooltip
|
|
170
168
|
h-full
|
|
171
169
|
text-center
|
|
172
170
|
rounded-none
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
HStack,
|
|
4
4
|
Text,
|
|
@@ -13,211 +13,206 @@ import Slider from '@react-native-community/slider'; // https://www.npmjs.com/pa
|
|
|
13
13
|
import UiGlobals from '../../../UiGlobals.js';
|
|
14
14
|
import testProps from '../../../Functions/testProps.js';
|
|
15
15
|
import withComponent from '../../Hoc/withComponent.js';
|
|
16
|
-
import withTooltip from '../../Hoc/withTooltip.js';
|
|
17
16
|
import withValue from '../../Hoc/withValue.js';
|
|
18
17
|
import _ from 'lodash';
|
|
19
18
|
|
|
20
19
|
const FAKE_ZERO = 0.0000000001; // Slider doesn't like zero
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
case 'Tab':
|
|
57
|
-
case 'Backspace':
|
|
58
|
-
return;
|
|
59
|
-
default:
|
|
60
|
-
}
|
|
61
|
-
if (!key.match(/^[\-\d\.]*$/)) {
|
|
62
|
-
e.preventDefault(); // kill anything that's not a number
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
onChangeText = (value) => {
|
|
66
|
-
if (!value || value === '') {
|
|
67
|
-
value = 0; // empty string makes value null
|
|
68
|
-
} else if (value.match(/\.$/)) { // value ends with a decimal point
|
|
69
|
-
// don't parseFloat, otherwise we'll lose the decimal point
|
|
70
|
-
} else if (value.match(/0$/)) { // value ends with a zero
|
|
71
|
-
// don't parseFloat, otherwise we'll lose the ability to do things like 1.03
|
|
72
|
-
} else {
|
|
73
|
-
value = parseFloat(value, 10);
|
|
74
|
-
}
|
|
75
|
-
if (value < minValue) {
|
|
76
|
-
value = minValue;
|
|
77
|
-
} else if (value > maxValue) {
|
|
78
|
-
value = maxValue;
|
|
79
|
-
}
|
|
80
|
-
setLocalValue(value);
|
|
81
|
-
debouncedSetValueRef.current(value);
|
|
82
|
-
},
|
|
83
|
-
onDecrement = () => {
|
|
84
|
-
let localValue = value;
|
|
85
|
-
if (minValue && localValue === minValue) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (!localValue) {
|
|
89
|
-
localValue = 0;
|
|
90
|
-
}
|
|
91
|
-
localValue = new Decimal(localValue).minus(step).toNumber();
|
|
92
|
-
if (minValue > localValue) {
|
|
93
|
-
localValue = minValue;
|
|
94
|
-
}
|
|
95
|
-
setValue(localValue);
|
|
96
|
-
},
|
|
97
|
-
onIncrement = () => {
|
|
98
|
-
let localValue = value;
|
|
99
|
-
if (maxValue && localValue === maxValue) {
|
|
21
|
+
function SliderElement(props) {
|
|
22
|
+
let {
|
|
23
|
+
value = 0,
|
|
24
|
+
setValue,
|
|
25
|
+
minValue = 0,
|
|
26
|
+
maxValue = 100,
|
|
27
|
+
step = 10,
|
|
28
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
29
|
+
minimizeForRow = false,
|
|
30
|
+
tooltip,
|
|
31
|
+
tooltipPlacement,
|
|
32
|
+
isDisabled = false,
|
|
33
|
+
testID,
|
|
34
|
+
} = props,
|
|
35
|
+
styles = UiGlobals.styles,
|
|
36
|
+
debouncedSetValueRef = useRef(),
|
|
37
|
+
[localValue, setLocalValue] = useState(value),
|
|
38
|
+
onInputKeyPress = (e) => {
|
|
39
|
+
const key = e.nativeEvent.key; // e.key works on web, but not mobile; so use e.nativeEvent.key which works on both
|
|
40
|
+
switch(key) {
|
|
41
|
+
case 'ArrowDown':
|
|
42
|
+
onDecrement();
|
|
43
|
+
break;
|
|
44
|
+
case 'ArrowUp':
|
|
45
|
+
onIncrement();
|
|
46
|
+
break;
|
|
47
|
+
case 'Enter':
|
|
48
|
+
debouncedSetValueRef.current?.cancel();
|
|
49
|
+
setValue(value);
|
|
50
|
+
break;
|
|
51
|
+
case 'ArrowLeft':
|
|
52
|
+
case 'ArrowRight':
|
|
53
|
+
case 'Tab':
|
|
54
|
+
case 'Backspace':
|
|
100
55
|
return;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
56
|
+
default:
|
|
57
|
+
}
|
|
58
|
+
if (!key.match(/^[\-\d\.]*$/)) {
|
|
59
|
+
e.preventDefault(); // kill anything that's not a number
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
onChangeText = (value) => {
|
|
63
|
+
if (!value || value === '') {
|
|
64
|
+
value = 0; // empty string makes value null
|
|
65
|
+
} else if (value.match(/\.$/)) { // value ends with a decimal point
|
|
66
|
+
// don't parseFloat, otherwise we'll lose the decimal point
|
|
67
|
+
} else if (value.match(/0$/)) { // value ends with a zero
|
|
68
|
+
// don't parseFloat, otherwise we'll lose the ability to do things like 1.03
|
|
69
|
+
} else {
|
|
70
|
+
value = parseFloat(value, 10);
|
|
71
|
+
}
|
|
72
|
+
if (value < minValue) {
|
|
73
|
+
value = minValue;
|
|
74
|
+
} else if (value > maxValue) {
|
|
75
|
+
value = maxValue;
|
|
76
|
+
}
|
|
77
|
+
setLocalValue(value);
|
|
78
|
+
debouncedSetValueRef.current(value);
|
|
79
|
+
},
|
|
80
|
+
onDecrement = () => {
|
|
81
|
+
let localValue = value;
|
|
82
|
+
if (minValue && localValue === minValue) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!localValue) {
|
|
86
|
+
localValue = 0;
|
|
87
|
+
}
|
|
88
|
+
localValue = new Decimal(localValue).minus(step).toNumber();
|
|
89
|
+
if (minValue > localValue) {
|
|
90
|
+
localValue = minValue;
|
|
91
|
+
}
|
|
92
|
+
setValue(localValue);
|
|
93
|
+
},
|
|
94
|
+
onIncrement = () => {
|
|
95
|
+
let localValue = value;
|
|
96
|
+
if (maxValue && localValue === maxValue) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!localValue) {
|
|
100
|
+
localValue = 0;
|
|
124
101
|
}
|
|
102
|
+
localValue = new Decimal(localValue).plus(step).toNumber();
|
|
103
|
+
if (maxValue < localValue) {
|
|
104
|
+
localValue = maxValue;
|
|
105
|
+
}
|
|
106
|
+
setValue(localValue);
|
|
107
|
+
};
|
|
125
108
|
|
|
126
|
-
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
// Set up debounce fn
|
|
111
|
+
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
112
|
+
debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
|
|
113
|
+
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
114
|
+
}, [setValue]);
|
|
127
115
|
|
|
128
|
-
|
|
116
|
+
useEffect(() => {
|
|
129
117
|
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
// Make local value conform to externally changed value
|
|
119
|
+
if (value !== localValue) {
|
|
120
|
+
setLocalValue(value);
|
|
132
121
|
}
|
|
133
122
|
|
|
134
|
-
|
|
135
|
-
sliderValue = 0; // If the value is null or undefined, force slider to use zero
|
|
136
|
-
}
|
|
123
|
+
}, [value]);
|
|
137
124
|
|
|
138
|
-
|
|
139
|
-
let inputValue = localValue;
|
|
140
|
-
if (_.isNumber(inputValue)) {
|
|
141
|
-
inputValue = '' + inputValue;
|
|
142
|
-
}
|
|
125
|
+
let sliderValue = value;
|
|
143
126
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
127
|
+
if (localValue === null || typeof localValue === 'undefined') {
|
|
128
|
+
localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
|
|
129
|
+
}
|
|
148
130
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
131
|
+
if (sliderValue === null || typeof sliderValue === 'undefined') {
|
|
132
|
+
sliderValue = 0; // If the value is null or undefined, force slider to use zero
|
|
133
|
+
}
|
|
152
134
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
135
|
+
// convert localValue to string if necessary, because numbers work on web but not mobile; while strings work in both places
|
|
136
|
+
let inputValue = localValue;
|
|
137
|
+
if (_.isNumber(inputValue)) {
|
|
138
|
+
inputValue = '' + inputValue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const style = props.style || {};
|
|
142
|
+
if (!hasWidth(props) && !hasFlex(props)) {
|
|
143
|
+
style.flex = 1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (sliderValue === 0) {
|
|
147
|
+
sliderValue = FAKE_ZERO; // Slider doesn't like zero
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let className = `
|
|
151
|
+
w-full
|
|
152
|
+
items-center
|
|
153
|
+
`,
|
|
154
|
+
inputClassName = `
|
|
155
|
+
Input
|
|
156
|
+
h-full
|
|
157
|
+
w-[60px]
|
|
158
|
+
mr-4
|
|
159
|
+
text-center
|
|
160
|
+
rounded-md
|
|
161
|
+
${styles.SLIDER_READOUT_FONTSIZE}
|
|
162
|
+
`;
|
|
163
|
+
if (props.className) {
|
|
164
|
+
className += ' ' + props.className;
|
|
165
|
+
}
|
|
166
|
+
if (minimizeForRow) {
|
|
167
|
+
inputClassName += ' h-auto min-h-0 max-h-[50px] mr-1';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return <HStack
|
|
171
|
+
className={className}
|
|
172
|
+
style={props.style}
|
|
173
|
+
>
|
|
174
|
+
<Input
|
|
175
|
+
{...testProps('readout')}
|
|
176
|
+
value={inputValue}
|
|
177
|
+
onChangeText={onChangeText}
|
|
178
|
+
onKeyPress={onInputKeyPress}
|
|
179
|
+
isDisabled={isDisabled}
|
|
180
|
+
disableAutoFlex={true}
|
|
181
|
+
className={inputClassName}
|
|
182
|
+
textAlignIsCenter={true}
|
|
183
|
+
tooltip={tooltip}
|
|
184
|
+
tooltipPlacement={tooltipPlacement}
|
|
185
|
+
{...props._input}
|
|
186
|
+
/>
|
|
187
|
+
<HStack className="flex-1">
|
|
188
|
+
<Slider
|
|
189
|
+
{...testProps('slider')}
|
|
190
|
+
ref={props.outerRef}
|
|
191
|
+
style={{
|
|
192
|
+
width: '100%',
|
|
193
|
+
height: 40,
|
|
194
|
+
}}
|
|
195
|
+
minimumTrackTintColor={styles.SLIDER_MIN_TRACK_COLOR}
|
|
196
|
+
maximumTrackTintColor={styles.SLIDER_MAX_TRACK_COLOR}
|
|
197
|
+
thumbTintColor={styles.SLIDER_THUMB_COLOR}
|
|
198
|
+
minimumValue={minValue}
|
|
199
|
+
maximumValue={maxValue}
|
|
200
|
+
step={step}
|
|
201
|
+
value={sliderValue}
|
|
202
|
+
onValueChange={(value) => {
|
|
203
|
+
// This sets the localValue, only for display purposes
|
|
204
|
+
setLocalValue(value);
|
|
205
|
+
}}
|
|
206
|
+
onSlidingComplete={(value) => {
|
|
207
|
+
// This sets the actual value
|
|
208
|
+
if (value === FAKE_ZERO) {
|
|
209
|
+
value = 0;
|
|
210
|
+
}
|
|
211
|
+
setValue(value);
|
|
212
|
+
}}
|
|
187
213
|
/>
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
ref={props.outerRef}
|
|
192
|
-
style={{
|
|
193
|
-
width: '100%',
|
|
194
|
-
height: 40,
|
|
195
|
-
}}
|
|
196
|
-
minimumTrackTintColor={styles.SLIDER_MIN_TRACK_COLOR}
|
|
197
|
-
maximumTrackTintColor={styles.SLIDER_MAX_TRACK_COLOR}
|
|
198
|
-
thumbTintColor={styles.SLIDER_THUMB_COLOR}
|
|
199
|
-
minimumValue={minValue}
|
|
200
|
-
maximumValue={maxValue}
|
|
201
|
-
step={step}
|
|
202
|
-
value={sliderValue}
|
|
203
|
-
onValueChange={(value) => {
|
|
204
|
-
// This sets the localValue, only for display purposes
|
|
205
|
-
setLocalValue(value);
|
|
206
|
-
}}
|
|
207
|
-
onSlidingComplete={(value) => {
|
|
208
|
-
// This sets the actual value
|
|
209
|
-
if (value === FAKE_ZERO) {
|
|
210
|
-
value = 0;
|
|
211
|
-
}
|
|
212
|
-
setValue(value);
|
|
213
|
-
}}
|
|
214
|
-
/>
|
|
215
|
-
</HStack>
|
|
216
|
-
</HStack>;
|
|
217
|
-
},
|
|
218
|
-
SliderField = withComponent(withValue(SliderElement));
|
|
214
|
+
</HStack>
|
|
215
|
+
</HStack>;
|
|
216
|
+
};
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
export default withTooltip(React.forwardRef((props, ref) => {
|
|
222
|
-
return <SliderField {...props} outerRef={ref} />;
|
|
223
|
-
}));
|
|
218
|
+
export default withComponent(withValue(SliderElement));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef, useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Textarea, TextareaInput,
|
|
4
4
|
} from '@project-components/Gluestack';
|
|
@@ -8,106 +8,104 @@ import withTooltip from '../../Hoc/withTooltip.js';
|
|
|
8
8
|
import withValue from '../../Hoc/withValue.js';
|
|
9
9
|
import _ from 'lodash';
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
// Set up debounce fn
|
|
64
|
-
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
65
|
-
debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
|
|
66
|
-
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
67
|
-
}, [setValue]);
|
|
68
|
-
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
|
|
71
|
-
if (!isTyping() && value !== localValue) {
|
|
72
|
-
// Make local value conform to externally changed value
|
|
73
|
-
setLocalValue(value);
|
|
11
|
+
const TextAreaElement = forwardRef((props, ref) => {
|
|
12
|
+
let { // so localValue can be changed, if needed
|
|
13
|
+
setValue,
|
|
14
|
+
autoSubmit = true, // automatically setValue after user stops typing for autoSubmitDelay
|
|
15
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
16
|
+
onChangeText,
|
|
17
|
+
placeholder,
|
|
18
|
+
minimizeForRow = false,
|
|
19
|
+
testID,
|
|
20
|
+
className,
|
|
21
|
+
...propsToPass
|
|
22
|
+
} = props,
|
|
23
|
+
value = _.isNil(props.value) ? '' : props.value, // null value may not actually reset this TextArea, so set it explicitly to empty string
|
|
24
|
+
styles = UiGlobals.styles,
|
|
25
|
+
debouncedSetValueRef = useRef(),
|
|
26
|
+
[localValue, setLocalValue] = useState(value),
|
|
27
|
+
isTypingRef = useRef(),
|
|
28
|
+
isTypingTimeoutRef = useRef(),
|
|
29
|
+
isTyping = () => {
|
|
30
|
+
return isTypingRef.current;
|
|
31
|
+
},
|
|
32
|
+
setIsTyping = (isTyping) => {
|
|
33
|
+
isTypingRef.current = isTyping;
|
|
34
|
+
if (isTyping) {
|
|
35
|
+
startIsTypingTimeout();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
startIsTypingTimeout = () => {
|
|
39
|
+
clearIsTypingTimeout();
|
|
40
|
+
isTypingTimeoutRef.current = setTimeout(() => {
|
|
41
|
+
setIsTyping(false);
|
|
42
|
+
}, autoSubmitDelay + 1000);
|
|
43
|
+
},
|
|
44
|
+
clearIsTypingTimeout = () => {
|
|
45
|
+
if (isTypingTimeoutRef.current) {
|
|
46
|
+
clearTimeout(isTypingTimeoutRef.current);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
onChangeTextLocal = (value) => {
|
|
50
|
+
setIsTyping(true);
|
|
51
|
+
if (value === '') {
|
|
52
|
+
value = null; // empty string makes value null
|
|
53
|
+
}
|
|
54
|
+
setLocalValue(value);
|
|
55
|
+
if (autoSubmit) {
|
|
56
|
+
debouncedSetValueRef.current(value);
|
|
57
|
+
}
|
|
58
|
+
if (onChangeText) {
|
|
59
|
+
onChangeText(value);
|
|
74
60
|
}
|
|
61
|
+
};
|
|
75
62
|
|
|
76
|
-
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
// Set up debounce fn
|
|
65
|
+
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
66
|
+
debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
|
|
67
|
+
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
68
|
+
}, [setValue]);
|
|
77
69
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
`,
|
|
84
|
-
inputClassName = `
|
|
85
|
-
TextAreaInput
|
|
86
|
-
flex-1
|
|
87
|
-
${styles.FORM_TEXTAREA_CLASSNAME}
|
|
88
|
-
`;
|
|
89
|
-
if (props.className) {
|
|
90
|
-
inputClassName += ' ' + props.className;
|
|
91
|
-
}
|
|
92
|
-
if (minimizeForRow) {
|
|
93
|
-
textareaClassName += ' h-auto min-h-0 max-h-[40px] overflow-auto';
|
|
94
|
-
inputClassName += ' py-0';
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
|
|
72
|
+
if (!isTyping() && value !== localValue) {
|
|
73
|
+
// Make local value conform to externally changed value
|
|
74
|
+
setLocalValue(value);
|
|
95
75
|
}
|
|
96
76
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
77
|
+
}, [value]);
|
|
78
|
+
|
|
79
|
+
if (localValue === null || typeof localValue === 'undefined') {
|
|
80
|
+
localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
|
|
81
|
+
}
|
|
82
|
+
let textareaClassName = `
|
|
83
|
+
Textarea
|
|
84
|
+
`,
|
|
85
|
+
inputClassName = `
|
|
86
|
+
TextAreaInput
|
|
87
|
+
flex-1
|
|
88
|
+
${styles.FORM_TEXTAREA_CLASSNAME}
|
|
89
|
+
`;
|
|
90
|
+
if (className) {
|
|
91
|
+
inputClassName += ' ' + className;
|
|
92
|
+
}
|
|
93
|
+
if (minimizeForRow) {
|
|
94
|
+
textareaClassName += ' h-auto min-h-0 max-h-[40px] overflow-auto';
|
|
95
|
+
inputClassName += ' py-0';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return <Textarea className={textareaClassName}>
|
|
99
|
+
<TextareaInput
|
|
100
|
+
{...propsToPass}
|
|
101
|
+
testID={testID}
|
|
102
|
+
ref={ref}
|
|
103
|
+
onChangeText={onChangeTextLocal}
|
|
104
|
+
value={localValue}
|
|
105
|
+
className={inputClassName}
|
|
106
|
+
placeholder={placeholder}
|
|
107
|
+
/>
|
|
108
|
+
</Textarea>;
|
|
109
|
+
});
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
export default withTooltip(React.forwardRef((props, ref) => {
|
|
112
|
-
return <TextAreaField {...props} outerRef={ref} />;
|
|
113
|
-
}));
|
|
111
|
+
export default withComponent(withValue(withTooltip(TextAreaElement)));
|
|
@@ -608,12 +608,15 @@ function Form(props) {
|
|
|
608
608
|
}
|
|
609
609
|
|
|
610
610
|
if (isEditorViewOnly || !isEditable) {
|
|
611
|
-
let value =
|
|
612
|
-
if (
|
|
613
|
-
value = record[name];
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
611
|
+
let value = null;
|
|
612
|
+
if (isSingle) {
|
|
613
|
+
value = record?.properties[name]?.displayValue || null;
|
|
614
|
+
if (_.isNil(value) && record && record[name]) {
|
|
615
|
+
value = record[name];
|
|
616
|
+
}
|
|
617
|
+
if (_.isNil(value) && startingValues && startingValues[name]) {
|
|
618
|
+
value = startingValues[name];
|
|
619
|
+
}
|
|
617
620
|
}
|
|
618
621
|
|
|
619
622
|
let elementClassName = 'field-' + name;
|
|
@@ -455,17 +455,20 @@ function GridComponent(props) {
|
|
|
455
455
|
if (isHeaderRow || isReorderMode) {
|
|
456
456
|
return
|
|
457
457
|
}
|
|
458
|
+
if (selection && selection[0] && selection[0].isRemotePhantom) {
|
|
459
|
+
return; // block context menu or changing selection when a remote phantom is already selected
|
|
460
|
+
}
|
|
458
461
|
|
|
459
462
|
// context menu
|
|
460
|
-
const
|
|
463
|
+
const newSelection = [item];
|
|
461
464
|
if (!disableWithSelection) {
|
|
462
|
-
setSelection(
|
|
465
|
+
setSelection(newSelection);
|
|
463
466
|
}
|
|
464
467
|
if (onEditorRowClick) { // e.g. inline editor
|
|
465
468
|
onEditorRowClick(item, index, e);
|
|
466
469
|
}
|
|
467
470
|
if (onContextMenu) {
|
|
468
|
-
onContextMenu(item, e,
|
|
471
|
+
onContextMenu(item, e, newSelection);
|
|
469
472
|
}
|
|
470
473
|
}}
|
|
471
474
|
className="Pressable Row flex-row grow">
|
|
@@ -50,6 +50,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
50
50
|
initialSelection = secondarySelection || secondaryDefaultSelection || [],
|
|
51
51
|
forceUpdate = useForceUpdate(),
|
|
52
52
|
secondarySelectionRef = useRef(initialSelection),
|
|
53
|
+
SecondaryRepositoryRef = useRef(SecondaryRepository),
|
|
53
54
|
[isReady, setIsReady] = useState(secondarySelection || false), // if secondarySelection is already defined, or secondaryValue is not null and we don't need to load repository, it's ready
|
|
54
55
|
secondarySetSelection = (secondarySelection) => {
|
|
55
56
|
if (_.isEqual(secondarySelection, secondaryGetSelection())) {
|
|
@@ -68,6 +69,9 @@ export default function withSelection(WrappedComponent) {
|
|
|
68
69
|
secondaryGetSelection = () => {
|
|
69
70
|
return secondarySelectionRef.current;
|
|
70
71
|
},
|
|
72
|
+
secondaryGetRepository = () => {
|
|
73
|
+
return SecondaryRepositoryRef.current;
|
|
74
|
+
},
|
|
71
75
|
secondarySelectPrev = () => {
|
|
72
76
|
secondarySelectDirection(SELECT_UP);
|
|
73
77
|
},
|
|
@@ -112,6 +116,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
112
116
|
secondarySetSelection(newSelection);
|
|
113
117
|
},
|
|
114
118
|
secondaryRemoveFromSelection = (item) => {
|
|
119
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
115
120
|
let newSelection = [];
|
|
116
121
|
if (SecondaryRepository) {
|
|
117
122
|
newSelection = _.remove(secondaryGetSelection(), (sel) => sel !== item);
|
|
@@ -132,7 +137,8 @@ export default function withSelection(WrappedComponent) {
|
|
|
132
137
|
// That way, after a load event, we'll keep the same selection, if possible.
|
|
133
138
|
const
|
|
134
139
|
newSelection = [],
|
|
135
|
-
ids = _.map(secondaryGetSelection(), (item) => item.id)
|
|
140
|
+
ids = _.map(secondaryGetSelection(), (item) => item.id),
|
|
141
|
+
SecondaryRepository = secondaryGetRepository();
|
|
136
142
|
_.each(ids, (id) => {
|
|
137
143
|
const found = SecondaryRepository.getById(id);
|
|
138
144
|
if (found) {
|
|
@@ -144,6 +150,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
144
150
|
getMaxMinSelectionIndices = () => {
|
|
145
151
|
let items,
|
|
146
152
|
currentlySelectedRowIndices = [];
|
|
153
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
147
154
|
if (SecondaryRepository) {
|
|
148
155
|
items = SecondaryRepository.getEntitiesOnPage();
|
|
149
156
|
} else {
|
|
@@ -194,6 +201,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
194
201
|
secondarySetSelection(newSelection);
|
|
195
202
|
},
|
|
196
203
|
secondaryIsInSelection = (item) => {
|
|
204
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
197
205
|
if (SecondaryRepository) {
|
|
198
206
|
return inArray(item, secondaryGetSelection());
|
|
199
207
|
}
|
|
@@ -204,6 +212,8 @@ export default function withSelection(WrappedComponent) {
|
|
|
204
212
|
return !!found;
|
|
205
213
|
},
|
|
206
214
|
getIndexOfSelectedItem = (item) => {
|
|
215
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
216
|
+
|
|
207
217
|
// Gets ix of entity on page, or element in secondaryData array
|
|
208
218
|
if (SecondaryRepository) {
|
|
209
219
|
const entities = SecondaryRepository.getEntitiesOnPage();
|
|
@@ -223,12 +233,14 @@ export default function withSelection(WrappedComponent) {
|
|
|
223
233
|
if (!secondaryGetSelection()[0]) {
|
|
224
234
|
return null;
|
|
225
235
|
}
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
236
|
+
const
|
|
237
|
+
SecondaryRepository = secondaryGetRepository(),
|
|
238
|
+
secondaryValues = _.map(secondaryGetSelection(), (item) => {
|
|
239
|
+
if (SecondaryRepository) {
|
|
240
|
+
return item.id;
|
|
241
|
+
}
|
|
242
|
+
return item[secondaryIdIx];
|
|
243
|
+
});
|
|
232
244
|
if (secondaryValues.length === 1) {
|
|
233
245
|
return secondaryValues[0];
|
|
234
246
|
}
|
|
@@ -239,6 +251,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
239
251
|
return '';
|
|
240
252
|
}
|
|
241
253
|
|
|
254
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
242
255
|
return _.map(secondarySelection, (item) => {
|
|
243
256
|
if (SecondaryRepository) {
|
|
244
257
|
return item.displayValue;
|
|
@@ -258,6 +271,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
258
271
|
}
|
|
259
272
|
},
|
|
260
273
|
conformSelectionToValue = async () => {
|
|
274
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
261
275
|
let newSelection = [];
|
|
262
276
|
if (SecondaryRepository) {
|
|
263
277
|
if (SecondaryRepository.isLoading) {
|
|
@@ -325,6 +339,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
325
339
|
|
|
326
340
|
(async () => {
|
|
327
341
|
|
|
342
|
+
const SecondaryRepository = secondaryGetRepository();
|
|
328
343
|
if (usesWithValue && SecondaryRepository?.isRemote
|
|
329
344
|
&& !SecondaryRepository.isAutoLoad && !SecondaryRepository.isLoaded && !SecondaryRepository.isLoading && (!_.isNil(secondaryValue) || !_.isEmpty(secondarySelection)) || secondaryAutoSelectFirstItem) {
|
|
330
345
|
// on initialization, we can't conformSelectionToValue if the repository is not yet loaded,
|
|
@@ -48,6 +48,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
48
48
|
initialSelection = selection || defaultSelection || [],
|
|
49
49
|
forceUpdate = useForceUpdate(),
|
|
50
50
|
selectionRef = useRef(initialSelection),
|
|
51
|
+
RepositoryRef = useRef(Repository),
|
|
51
52
|
[isReady, setIsReady] = useState(selection || false), // if selection is already defined, or value is not null and we don't need to load repository, it's ready
|
|
52
53
|
setSelection = (selection) => {
|
|
53
54
|
if (_.isEqual(selection, getSelection())) {
|
|
@@ -65,7 +66,10 @@ export default function withSelection(WrappedComponent) {
|
|
|
65
66
|
},
|
|
66
67
|
getSelection = () => {
|
|
67
68
|
return selectionRef.current;
|
|
68
|
-
}
|
|
69
|
+
},
|
|
70
|
+
getRepository = () => {
|
|
71
|
+
return RepositoryRef.current;
|
|
72
|
+
},
|
|
69
73
|
selectPrev = () => {
|
|
70
74
|
selectDirection(SELECT_UP);
|
|
71
75
|
},
|
|
@@ -110,6 +114,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
110
114
|
setSelection(newSelection);
|
|
111
115
|
},
|
|
112
116
|
removeFromSelection = (item) => {
|
|
117
|
+
const Repository = getRepository();
|
|
113
118
|
let newSelection = [];
|
|
114
119
|
if (Repository) {
|
|
115
120
|
newSelection = _.remove(getSelection(), (sel) => sel !== item);
|
|
@@ -130,7 +135,8 @@ export default function withSelection(WrappedComponent) {
|
|
|
130
135
|
// That way, after a load event, we'll keep the same selection, if possible.
|
|
131
136
|
const
|
|
132
137
|
newSelection = [],
|
|
133
|
-
ids = _.map(getSelection(), (item) => item.id)
|
|
138
|
+
ids = _.map(getSelection(), (item) => item.id),
|
|
139
|
+
Repository = getRepository();
|
|
134
140
|
_.each(ids, (id) => {
|
|
135
141
|
const found = Repository.getById(id);
|
|
136
142
|
if (found) {
|
|
@@ -142,6 +148,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
142
148
|
getMaxMinSelectionIndices = () => {
|
|
143
149
|
let items,
|
|
144
150
|
currentlySelectedRowIndices = [];
|
|
151
|
+
const Repository = getRepository();
|
|
145
152
|
if (Repository) {
|
|
146
153
|
items = Repository.getEntitiesOnPage();
|
|
147
154
|
} else {
|
|
@@ -192,6 +199,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
192
199
|
setSelection(newSelection);
|
|
193
200
|
},
|
|
194
201
|
isInSelection = (item) => {
|
|
202
|
+
const Repository = getRepository();
|
|
195
203
|
if (Repository) {
|
|
196
204
|
return inArray(item, getSelection());
|
|
197
205
|
}
|
|
@@ -202,6 +210,8 @@ export default function withSelection(WrappedComponent) {
|
|
|
202
210
|
return !!found;
|
|
203
211
|
},
|
|
204
212
|
getIndexOfSelectedItem = (item) => {
|
|
213
|
+
const Repository = getRepository();
|
|
214
|
+
|
|
205
215
|
// Gets ix of entity on page, or element in data array
|
|
206
216
|
if (Repository) {
|
|
207
217
|
const entities = Repository.getEntitiesOnPage();
|
|
@@ -221,12 +231,14 @@ export default function withSelection(WrappedComponent) {
|
|
|
221
231
|
if (!getSelection()[0]) {
|
|
222
232
|
return null;
|
|
223
233
|
}
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
234
|
+
const
|
|
235
|
+
Repository = getRepository(),
|
|
236
|
+
values = _.map(getSelection(), (item) => {
|
|
237
|
+
if (Repository) {
|
|
238
|
+
return item.id;
|
|
239
|
+
}
|
|
240
|
+
return item[idIx];
|
|
241
|
+
});
|
|
230
242
|
if (values.length === 1) {
|
|
231
243
|
return values[0];
|
|
232
244
|
}
|
|
@@ -237,6 +249,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
237
249
|
return '';
|
|
238
250
|
}
|
|
239
251
|
|
|
252
|
+
const Repository = getRepository();
|
|
240
253
|
return _.map(selection, (item) => {
|
|
241
254
|
if (Repository) {
|
|
242
255
|
return item.displayValue;
|
|
@@ -256,6 +269,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
256
269
|
}
|
|
257
270
|
},
|
|
258
271
|
conformSelectionToValue = async () => {
|
|
272
|
+
const Repository = getRepository();
|
|
259
273
|
let newSelection = [];
|
|
260
274
|
if (Repository) {
|
|
261
275
|
if (Repository.isLoading) {
|
|
@@ -323,6 +337,7 @@ export default function withSelection(WrappedComponent) {
|
|
|
323
337
|
|
|
324
338
|
(async () => {
|
|
325
339
|
|
|
340
|
+
const Repository = getRepository();
|
|
326
341
|
if (usesWithValue && Repository?.isRemote
|
|
327
342
|
&& !Repository.isAutoLoad && !Repository.isLoaded && !Repository.isLoading && (!_.isNil(value) || !_.isEmpty(selection)) || autoSelectFirstItem) {
|
|
328
343
|
// on initialization, we can't conformSelectionToValue if the repository is not yet loaded,
|
|
@@ -10,6 +10,7 @@ export default function withTooltip(WrappedComponent) {
|
|
|
10
10
|
const {
|
|
11
11
|
tooltip,
|
|
12
12
|
tooltipPlacement = 'bottom',
|
|
13
|
+
tooltipClassName,
|
|
13
14
|
_tooltip = {},
|
|
14
15
|
...propsToPass
|
|
15
16
|
} = props;
|
|
@@ -17,7 +18,12 @@ export default function withTooltip(WrappedComponent) {
|
|
|
17
18
|
let component = <WrappedComponent {...propsToPass} ref={ref} />;
|
|
18
19
|
|
|
19
20
|
if (tooltip || !_.isEmpty(_tooltip)) {
|
|
20
|
-
component = <Tooltip
|
|
21
|
+
component = <Tooltip
|
|
22
|
+
label={tooltip}
|
|
23
|
+
placement={tooltipPlacement}
|
|
24
|
+
className={tooltipClassName}
|
|
25
|
+
{..._tooltip}
|
|
26
|
+
>
|
|
21
27
|
{component}
|
|
22
28
|
</Tooltip>;
|
|
23
29
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { forwardRef
|
|
2
|
-
import {
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
BoxNative as Box,
|
|
4
|
+
Tooltip, TooltipContent, TooltipText,
|
|
5
|
+
} from '@project-components/Gluestack';
|
|
3
6
|
|
|
4
7
|
const TooltipElement = forwardRef((props, ref) => {
|
|
5
8
|
const {
|
|
@@ -12,18 +15,18 @@ const TooltipElement = forwardRef((props, ref) => {
|
|
|
12
15
|
if (props.className) {
|
|
13
16
|
className += ' ' + props.className;
|
|
14
17
|
}
|
|
18
|
+
|
|
19
|
+
let triggerClassName = 'Tooltip-trigger';
|
|
20
|
+
if (props.className) {
|
|
21
|
+
triggerClassName += ' ' + props.className;
|
|
22
|
+
}
|
|
15
23
|
|
|
16
24
|
return <Tooltip
|
|
17
25
|
placement={placement}
|
|
18
26
|
trigger={(triggerProps) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
if (ref) {
|
|
24
|
-
propsToPass.ref = ref;
|
|
25
|
-
}
|
|
26
|
-
return cloneElement(children, propsToPass);
|
|
27
|
+
return <Box className={triggerClassName} {...triggerProps}>
|
|
28
|
+
{children}
|
|
29
|
+
</Box>;
|
|
27
30
|
}}
|
|
28
31
|
>
|
|
29
32
|
<TooltipContent className={className}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
TextNative,
|
|
3
3
|
} from '@project-components/Gluestack';
|
|
4
4
|
import UiGlobals from '../../UiGlobals';
|
|
5
5
|
|
|
@@ -16,8 +16,8 @@ export default function MeterTypeText(props) {
|
|
|
16
16
|
if (props.className) {
|
|
17
17
|
className += ' ' + props.className;
|
|
18
18
|
}
|
|
19
|
-
return <
|
|
19
|
+
return <TextNative
|
|
20
20
|
{...props}
|
|
21
21
|
className={className}
|
|
22
|
-
>{props.value ? '
|
|
22
|
+
>{props.value ? 'Time (hrs)' : 'Distance (mi/km)'}</TextNative>;
|
|
23
23
|
};
|