@onehat/ui 0.4.101 → 0.4.103
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/Accordion/Accordion.js +65 -6
- package/src/Components/Container/Container.js +10 -4
- package/src/Components/Form/Field/Combo/Combo.js +10 -4
- package/src/Components/Form/Field/Tag/Tag.js +6 -0
- package/src/Components/Form/Form.js +8 -3
- package/src/Components/Grid/Grid.js +232 -154
- package/src/Components/Grid/GridRow.js +7 -3
- package/src/Components/Hoc/withPresetButtons.js +18 -6
- package/src/Components/Icons/ArrowsLeftRight.js +10 -0
- package/src/Components/Icons/Bar.js +10 -0
- package/src/Components/Icons/Box.js +11 -0
- package/src/Components/Icons/BoxOpen.js +11 -0
- package/src/Components/Icons/Bucket.js +10 -0
- package/src/Components/Icons/Bump.js +21 -0
- package/src/Components/Icons/Calculator.js +12 -0
- package/src/Components/Icons/Dots.js +20 -0
- package/src/Components/Icons/Fleets.js +26 -0
- package/src/Components/Icons/Lock.js +11 -0
- package/src/Components/Icons/Microchip.js +12 -0
- package/src/Components/Icons/Num1.js +10 -0
- package/src/Components/Icons/Num2.js +10 -0
- package/src/Components/Icons/Num3.js +10 -0
- package/src/Components/Icons/Num4.js +10 -0
- package/src/Components/Icons/OilCan.js +11 -0
- package/src/Components/Icons/Operations.js +10 -0
- package/src/Components/Icons/OverduePms.js +10 -0
- package/src/Components/Icons/SackDollar.js +11 -0
- package/src/Components/Icons/ShortBar.js +15 -0
- package/src/Components/Icons/Tower.js +10 -0
- package/src/Components/Icons/UpcomingPms.js +10 -0
- package/src/Components/Layout/ScreenHeader.js +35 -3
- package/src/Components/Layout/SetupButton.js +31 -0
- package/src/Components/Layout/UserIndicator.js +35 -0
- package/src/Components/Pms/Editor/BumpPmsEditor.js +9 -0
- package/src/Components/Pms/Editor/MetersEditor.js +173 -0
- package/src/Components/Pms/Editor/PmEventsEditor.js +291 -0
- package/src/Components/Pms/Grid/UpcomingPmsGrid.js +569 -0
- package/src/Components/Pms/Layout/TreeSpecific/MakeTreeSelection.js +11 -0
- package/src/Components/Pms/Layout/TreeSpecific/TreeSpecific.js +30 -0
- package/src/Components/Pms/Modals/BulkAssignTechnician.js +104 -0
- package/src/Components/Pms/Screens/PmsManager.js +136 -0
- package/src/Components/Pms/Window/BumpPmsEditorWindow.js +25 -0
- package/src/Components/Screens/Manager.js +3 -0
- package/src/Components/Screens/ReportsManager.js +51 -26
- package/src/Components/Tree/Tree.js +15 -6
- package/src/Components/Viewer/PmCalcDebugViewer.js +164 -146
- package/src/Components/Viewer/TextWithLinks.js +9 -1
- package/src/Components/Viewer/Viewer.js +38 -30
- package/src/Functions/flatten.js +39 -0
- package/src/Functions/verifyCanCrudPmEvents.js +33 -0
package/package.json
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
Box,
|
|
3
4
|
HStack,
|
|
4
|
-
|
|
5
|
+
Icon,
|
|
5
6
|
Pressable,
|
|
7
|
+
ScrollView,
|
|
8
|
+
Text,
|
|
9
|
+
TextNative,
|
|
6
10
|
VStack,
|
|
7
11
|
VStackNative,
|
|
8
12
|
} from '@project-components/Gluestack';
|
|
9
13
|
import clsx from 'clsx';
|
|
14
|
+
import Plus from '../Icons/Plus.js';
|
|
15
|
+
import Minus from '../Icons/Minus.js';
|
|
10
16
|
import inArray from '../../Functions/inArray.js';
|
|
11
17
|
import emptyFn from '../../Functions/emptyFn.js';
|
|
18
|
+
import UiGlobals from '../../UiGlobals.js';
|
|
12
19
|
import _ from 'lodash';
|
|
13
20
|
|
|
14
21
|
// The Accordion has two modes.
|
|
@@ -25,11 +32,61 @@ import _ from 'lodash';
|
|
|
25
32
|
|
|
26
33
|
export default function Accordion(props) {
|
|
27
34
|
const {
|
|
35
|
+
styles = UiGlobals.styles,
|
|
28
36
|
sections = [],
|
|
29
37
|
activeSections = [],
|
|
30
38
|
setActiveSections = emptyFn,
|
|
31
|
-
renderHeader =
|
|
32
|
-
|
|
39
|
+
renderHeader = (section, ix, isActive) => {
|
|
40
|
+
return <HStack
|
|
41
|
+
className={clsx(
|
|
42
|
+
'Header',
|
|
43
|
+
'bg-grey-300',
|
|
44
|
+
'items-center',
|
|
45
|
+
'justify-start',
|
|
46
|
+
'py-1',
|
|
47
|
+
'px-2',
|
|
48
|
+
'border-b-grey-400',
|
|
49
|
+
'border-b-1',
|
|
50
|
+
styles.PANEL_HEADER_BG,
|
|
51
|
+
)}
|
|
52
|
+
>
|
|
53
|
+
{/* <Text className="text-white flex-1">{section.header}</Text> */}
|
|
54
|
+
|
|
55
|
+
<TextNative
|
|
56
|
+
numberOfLines={1}
|
|
57
|
+
ellipsizeMode="head"
|
|
58
|
+
className={clsx(
|
|
59
|
+
'Header-TextNative1',
|
|
60
|
+
'flex-1',
|
|
61
|
+
'font-bold',
|
|
62
|
+
styles.PANEL_HEADER_TEXT_CLASSNAME,
|
|
63
|
+
)}>{section.header}</TextNative>
|
|
64
|
+
<Icon
|
|
65
|
+
as={isActive ? Minus : Plus}
|
|
66
|
+
className={clsx(
|
|
67
|
+
'text-black',
|
|
68
|
+
)}
|
|
69
|
+
/>
|
|
70
|
+
</HStack>;
|
|
71
|
+
},
|
|
72
|
+
unmountInactiveContent = true,
|
|
73
|
+
renderContent = (section, ix, isActive, ref) => {
|
|
74
|
+
if (unmountInactiveContent) {
|
|
75
|
+
if (!isActive) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return section.content;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// This keeps all content rendered, just hidden (zero height) if it's inActive
|
|
82
|
+
let className = 'w-full overflow-hidden';
|
|
83
|
+
if (!isActive) {
|
|
84
|
+
className += ' h-[0px]';
|
|
85
|
+
}
|
|
86
|
+
return <Box className={className}>
|
|
87
|
+
{section.content}
|
|
88
|
+
</Box>;
|
|
89
|
+
},
|
|
33
90
|
onAnimationEnd = emptyFn,
|
|
34
91
|
onLayout,
|
|
35
92
|
onlyOne = true,
|
|
@@ -67,7 +124,9 @@ export default function Accordion(props) {
|
|
|
67
124
|
|
|
68
125
|
// TODO: Animate height. Possible help here: https://stackoverflow.com/a/57333550 and https://stackoverflow.com/a/64797961
|
|
69
126
|
if (isActive) {
|
|
70
|
-
|
|
127
|
+
if (onlyOne) {
|
|
128
|
+
rowProps.flex = 1;
|
|
129
|
+
}
|
|
71
130
|
} else {
|
|
72
131
|
rowProps.h = 0;
|
|
73
132
|
rowProps.overflow = 'hidden'; // otherwise some elements mistakenly show
|
|
@@ -94,7 +153,7 @@ export default function Accordion(props) {
|
|
|
94
153
|
>
|
|
95
154
|
{header}
|
|
96
155
|
</Pressable>
|
|
97
|
-
<HStack {...rowProps}
|
|
156
|
+
<HStack {...rowProps}>
|
|
98
157
|
{content}
|
|
99
158
|
</HStack>
|
|
100
159
|
</VStack>;
|
|
@@ -129,7 +188,7 @@ export default function Accordion(props) {
|
|
|
129
188
|
keyboardShouldPersistTaps="always"
|
|
130
189
|
className="Accordion-ScrollView flex-1 w-full"
|
|
131
190
|
contentContainerStyle={{
|
|
132
|
-
height: '100%',
|
|
191
|
+
height: onlyOne ? '100%' : undefined,
|
|
133
192
|
}}
|
|
134
193
|
>
|
|
135
194
|
<VStackNative
|
|
@@ -125,16 +125,20 @@ function Container(props) {
|
|
|
125
125
|
localSouthIsCollapsedRef = useRef(southInitialIsCollapsed),
|
|
126
126
|
localEastIsCollapsedRef = useRef(eastInitialIsCollapsed),
|
|
127
127
|
localWestIsCollapsedRef = useRef(westInitialIsCollapsed),
|
|
128
|
+
isSplitterDraggingRef = useRef(false),
|
|
128
129
|
onLayout = async (e) => {
|
|
129
|
-
|
|
130
|
+
if (isSplitterDraggingRef.current) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
130
133
|
if (id) {
|
|
131
134
|
// save prevScreenSize if changed
|
|
132
135
|
const
|
|
133
|
-
height = parseFloat(e.nativeEvent.layout.height),
|
|
134
|
-
width = parseFloat(e.nativeEvent.layout.width),
|
|
136
|
+
height = windowSize?.height ?? parseFloat(e.nativeEvent.layout.height),
|
|
137
|
+
width = windowSize?.width ?? parseFloat(e.nativeEvent.layout.width),
|
|
135
138
|
key = id + '-prevScreenSize',
|
|
136
139
|
prevScreenSize = await getSaved(key);
|
|
137
|
-
|
|
140
|
+
const hasChanged = !prevScreenSize || Math.abs((prevScreenSize.width ?? 0) - width) > 1 || Math.abs((prevScreenSize.height ?? 0) - height) > 1;
|
|
141
|
+
if (hasChanged) {
|
|
138
142
|
await setSaved(key, {
|
|
139
143
|
height,
|
|
140
144
|
width,
|
|
@@ -300,10 +304,12 @@ function Container(props) {
|
|
|
300
304
|
}
|
|
301
305
|
},
|
|
302
306
|
onSplitterDragStart = () => {
|
|
307
|
+
isSplitterDraggingRef.current = true;
|
|
303
308
|
setIsComponentsDisabled(true);
|
|
304
309
|
},
|
|
305
310
|
onSplitterDragStop = (delta, which) => {
|
|
306
311
|
setIsComponentsDisabled(false);
|
|
312
|
+
isSplitterDraggingRef.current = false;
|
|
307
313
|
switch(which) {
|
|
308
314
|
case 'north':
|
|
309
315
|
onNorthResize(delta);
|
|
@@ -100,6 +100,8 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
100
100
|
onGridSave, // to hook into when menu saves (ComboEditor only)
|
|
101
101
|
onGridDelete, // to hook into when menu deletes (ComboEditor only)
|
|
102
102
|
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)
|
|
103
|
+
displayProperty, // override for Repository.schema.model.displayProperty
|
|
104
|
+
valueProperty, // override for Repository.schema.model.idProperty
|
|
103
105
|
newEntityDisplayProperty,
|
|
104
106
|
testID,
|
|
105
107
|
|
|
@@ -242,7 +244,7 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
242
244
|
displayValue = _.each(value, (id) => {
|
|
243
245
|
const entity = Repository.getById(id);
|
|
244
246
|
if (entity) {
|
|
245
|
-
displayValue.push(entity
|
|
247
|
+
displayValue.push((displayProperty ? entity?.[displayProperty] : entity?.displayValue) || '');
|
|
246
248
|
}
|
|
247
249
|
});
|
|
248
250
|
}
|
|
@@ -272,7 +274,7 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
|
-
displayValue = entity?.displayValue || '';
|
|
277
|
+
displayValue = (displayProperty ? entity?.[displayProperty] : entity?.displayValue) || '';
|
|
276
278
|
}
|
|
277
279
|
} else {
|
|
278
280
|
const item = _.find(data, (datum) => datum[idIx] === value);
|
|
@@ -318,7 +320,11 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
318
320
|
|
|
319
321
|
let id = null;
|
|
320
322
|
if (gridSelection.length) {
|
|
321
|
-
|
|
323
|
+
if (Repository) {
|
|
324
|
+
id = valueProperty ? gridSelection[0][valueProperty] : gridSelection[0].id;
|
|
325
|
+
} else {
|
|
326
|
+
id = gridSelection[0][idIx];
|
|
327
|
+
}
|
|
322
328
|
}
|
|
323
329
|
if (id !== value) {
|
|
324
330
|
setValue(id);
|
|
@@ -863,7 +869,7 @@ export const ComboComponent = forwardRef((props, ref) => {
|
|
|
863
869
|
return;
|
|
864
870
|
}
|
|
865
871
|
|
|
866
|
-
setValue(selection[0] ? selection[0].id : null);
|
|
872
|
+
setValue(selection[0] ? (valueProperty ? selection[0][valueProperty] : selection[0].id) : null);
|
|
867
873
|
|
|
868
874
|
} else {
|
|
869
875
|
|
|
@@ -545,10 +545,16 @@ function TagComponent(props) {
|
|
|
545
545
|
|
|
546
546
|
function withAdditionalProps(WrappedComponent) {
|
|
547
547
|
return (props) => {
|
|
548
|
+
const tooltipTriggerClassName = clsx(
|
|
549
|
+
'w-full',
|
|
550
|
+
'flex-1',
|
|
551
|
+
props.tooltipTriggerClassName,
|
|
552
|
+
);
|
|
548
553
|
return <WrappedComponent
|
|
549
554
|
isValueAlwaysArray={true}
|
|
550
555
|
isValueAsStringifiedJson={true}
|
|
551
556
|
{...props}
|
|
557
|
+
tooltipTriggerClassName={tooltipTriggerClassName}
|
|
552
558
|
/>;
|
|
553
559
|
};
|
|
554
560
|
}
|
|
@@ -1213,6 +1213,10 @@ function Form(props) {
|
|
|
1213
1213
|
style.maxHeight = maxHeight;
|
|
1214
1214
|
}
|
|
1215
1215
|
|
|
1216
|
+
const
|
|
1217
|
+
// allow horizontal layouts only if there are top-level columns, and screen is wide enough
|
|
1218
|
+
hasTopLevelColumns = _.some(items, (item) => item?.type === 'Column'),
|
|
1219
|
+
shouldUseHorizontalFormLayout = !isItemsCustomLayout && hasTopLevelColumns && containerWidth >= styles.FORM_ONE_COLUMN_THRESHOLD;
|
|
1216
1220
|
let modeHeader = null,
|
|
1217
1221
|
formButtons = null,
|
|
1218
1222
|
scrollButtons = null,
|
|
@@ -1246,8 +1250,8 @@ function Form(props) {
|
|
|
1246
1250
|
formComponents = buildFromItems();
|
|
1247
1251
|
const formAncillaryComponents = buildAncillary();
|
|
1248
1252
|
editor = <>
|
|
1249
|
-
{
|
|
1250
|
-
{
|
|
1253
|
+
{shouldUseHorizontalFormLayout ? <HStack className="Form-formComponents-HStack w-full min-w-0 p-4 gap-4 justify-start items-stretch">{formComponents}</HStack> : null}
|
|
1254
|
+
{!shouldUseHorizontalFormLayout ? <VStack className="Form-formComponents-VStack p-4">{formComponents}</VStack> : null}
|
|
1251
1255
|
{formAncillaryComponents.length ? <VStack className="Form-AncillaryComponents m-2 pt-4 px-2">{formAncillaryComponents}</VStack> : null}
|
|
1252
1256
|
</>;
|
|
1253
1257
|
|
|
@@ -1532,7 +1536,8 @@ function Form(props) {
|
|
|
1532
1536
|
onScroll={onScroll}
|
|
1533
1537
|
scrollEventThrottle={16 /* ms */}
|
|
1534
1538
|
contentContainerStyle={{
|
|
1535
|
-
|
|
1539
|
+
width: '100%',
|
|
1540
|
+
minWidth: '100%',
|
|
1536
1541
|
}}
|
|
1537
1542
|
>
|
|
1538
1543
|
{scrollToTopAnchor}
|