@onehat/ui 0.4.88 → 0.4.91
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 +7 -7
- package/src/Components/Form/Form.js +3 -3
- package/src/Components/Grid/Grid.js +4 -3
- package/src/Components/Hoc/withModal.js +1 -6
- package/src/Components/Hoc/withPdfButtons.js +48 -4
- package/src/Components/Messages/WaitMessage.js +45 -11
- package/src/Components/Viewer/Viewer.js +7 -1
- package/src/PlatformImports/Web/Attachments.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onehat/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.91",
|
|
4
4
|
"description": "Base UI for OneHat apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
"@hookform/resolvers": "^5.0.0",
|
|
58
58
|
"@k-renwick/colour-mixer": "^1.2.1",
|
|
59
59
|
"@legendapp/motion": "^2.4.0",
|
|
60
|
-
"@onehat/data": "^1.22.
|
|
61
|
-
"@react-native-community/slider": "^
|
|
62
|
-
"@reduxjs/toolkit": "^2.
|
|
60
|
+
"@onehat/data": "^1.22.31",
|
|
61
|
+
"@react-native-community/slider": "^5.1.1",
|
|
62
|
+
"@reduxjs/toolkit": "^2.11.2",
|
|
63
63
|
"clsx": "^2.1.1",
|
|
64
|
-
"decimal.js": "^10.
|
|
65
|
-
"inflector-js": "^
|
|
64
|
+
"decimal.js": "^10.6.0",
|
|
65
|
+
"inflector-js": "^2.0.1",
|
|
66
66
|
"js-cookie": "^3.0.5",
|
|
67
67
|
"nativewind": "4.1.23",
|
|
68
68
|
"normalize-css-color": "^1.0.2",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"react-redux": "^9.2.0",
|
|
72
72
|
"tailwind-scrollbar": "^3.1.0",
|
|
73
73
|
"tailwindcss": "^3.4.17",
|
|
74
|
-
"yup": "^1.
|
|
74
|
+
"yup": "^1.7.1"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"@ckeditor/ckeditor5-react": "^6.3.0",
|
|
@@ -339,13 +339,13 @@ function Form(props) {
|
|
|
339
339
|
if (renderer) {
|
|
340
340
|
value = renderer(record);
|
|
341
341
|
} else {
|
|
342
|
-
if (record?.properties
|
|
342
|
+
if (record?.properties?.hasOwnProperty(fieldName)) {
|
|
343
343
|
value = record.properties[fieldName].displayValue;
|
|
344
344
|
}
|
|
345
|
-
if (_.isNil(value) && record
|
|
345
|
+
if (_.isNil(value) && record?.hasOwnProperty(fieldName)) {
|
|
346
346
|
value = record[fieldName];
|
|
347
347
|
}
|
|
348
|
-
if (_.isNil(value) && startingValues
|
|
348
|
+
if (_.isNil(value) && startingValues?.hasOwnProperty(fieldName)) {
|
|
349
349
|
value = startingValues[fieldName];
|
|
350
350
|
}
|
|
351
351
|
}
|
|
@@ -1569,9 +1569,6 @@ function GridComponent(props) {
|
|
|
1569
1569
|
console.log(`${getMeasurementPhase()}, placeholder onLayout, call setIsInited(true)`);
|
|
1570
1570
|
}
|
|
1571
1571
|
setIsInited(true);
|
|
1572
|
-
if (onLayout) {
|
|
1573
|
-
onLayout(e);
|
|
1574
|
-
}
|
|
1575
1572
|
}}
|
|
1576
1573
|
className="w-full flex-1"
|
|
1577
1574
|
/>;
|
|
@@ -1716,6 +1713,10 @@ function GridComponent(props) {
|
|
|
1716
1713
|
onLayout={(e) => {
|
|
1717
1714
|
const containerHeight = e.nativeEvent.layout.height;
|
|
1718
1715
|
debouncedAdjustPageSizeToHeight(containerHeight);
|
|
1716
|
+
|
|
1717
|
+
if (onLayout) {
|
|
1718
|
+
onLayout(e);
|
|
1719
|
+
}
|
|
1719
1720
|
}}
|
|
1720
1721
|
className={className}
|
|
1721
1722
|
style={style}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useState
|
|
1
|
+
import { forwardRef, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Icon,
|
|
4
4
|
Modal, ModalBackdrop, ModalHeader, ModalContent, ModalCloseButton, ModalBody, ModalFooter,
|
|
@@ -44,8 +44,6 @@ export default function withModal(WrappedComponent) {
|
|
|
44
44
|
[body, setBody] = useState(),
|
|
45
45
|
[whichModal, setWhichModal] = useState(),
|
|
46
46
|
[testID, setTestID] = useState('Modal'),
|
|
47
|
-
autoFocusRef = useRef(null),
|
|
48
|
-
cancelRef = useRef(null),
|
|
49
47
|
[windowWidth, windowHeight] = useAdjustedWindowSize(w, h),
|
|
50
48
|
hideModal = () => {
|
|
51
49
|
setIsModalShown(false);
|
|
@@ -113,7 +111,6 @@ export default function withModal(WrappedComponent) {
|
|
|
113
111
|
key="cancelBtn"
|
|
114
112
|
onPress={onCancel || hideModal}
|
|
115
113
|
colorScheme="coolGray"
|
|
116
|
-
ref={cancelRef}
|
|
117
114
|
className="mr-2"
|
|
118
115
|
text="Cancel"
|
|
119
116
|
variant="outline" // or unstyled
|
|
@@ -133,7 +130,6 @@ export default function withModal(WrappedComponent) {
|
|
|
133
130
|
buttons.push(<Button
|
|
134
131
|
{...testProps('okBtn')}
|
|
135
132
|
key="okBtn"
|
|
136
|
-
ref={autoFocusRef}
|
|
137
133
|
onPress={onOk}
|
|
138
134
|
text={okBtnLabel}
|
|
139
135
|
className="text-white"
|
|
@@ -143,7 +139,6 @@ export default function withModal(WrappedComponent) {
|
|
|
143
139
|
buttons.push(<Button
|
|
144
140
|
{...testProps('yesBtn')}
|
|
145
141
|
key="yesBtn"
|
|
146
|
-
ref={autoFocusRef}
|
|
147
142
|
onPress={onYes}
|
|
148
143
|
text="Yes"
|
|
149
144
|
className="text-white"
|
|
@@ -319,14 +319,58 @@ export default function withPdfButtons(WrappedComponent) {
|
|
|
319
319
|
/>,
|
|
320
320
|
});
|
|
321
321
|
},
|
|
322
|
-
getPdf = (data) => {
|
|
322
|
+
getPdf = async (data) => {
|
|
323
|
+
// NOTE: we previously used a simple window.open() with the URL to view the PDF,
|
|
324
|
+
// but this doesn't work when authentication headers are required.
|
|
325
|
+
// So now we fetch the PDF ourselves, then open it in a new window.
|
|
326
|
+
|
|
323
327
|
data.id = selection[0].id;
|
|
324
328
|
|
|
325
329
|
const
|
|
326
|
-
url = UiGlobals.baseURL + model + '/viewModelPdf
|
|
327
|
-
queryString = qs.stringify(data)
|
|
330
|
+
url = UiGlobals.baseURL + model + '/viewModelPdf',
|
|
331
|
+
queryString = qs.stringify(data),
|
|
332
|
+
fullUrl = url + '?' + queryString;
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
// Show loading indicator
|
|
336
|
+
const
|
|
337
|
+
dispatch = UiGlobals.redux.dispatch,
|
|
338
|
+
setIsWaitModalShownAction = UiGlobals.systemReducer.setIsWaitModalShownAction;
|
|
339
|
+
dispatch(setIsWaitModalShownAction(true));
|
|
340
|
+
|
|
341
|
+
// Fetch with auth headers
|
|
342
|
+
const response = await fetch(fullUrl, {
|
|
343
|
+
method: 'GET',
|
|
344
|
+
headers: {
|
|
345
|
+
...Repository.headers,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
328
348
|
|
|
329
|
-
|
|
349
|
+
dispatch(setIsWaitModalShownAction(false));
|
|
350
|
+
|
|
351
|
+
if (!response.ok) {
|
|
352
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Get the PDF blob
|
|
356
|
+
const blob = await response.blob();
|
|
357
|
+
|
|
358
|
+
// Create a blob URL
|
|
359
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
360
|
+
|
|
361
|
+
// Open in new window
|
|
362
|
+
window.open(blobUrl, '_blank');
|
|
363
|
+
|
|
364
|
+
// Clean up the blob URL after a delay
|
|
365
|
+
// (give it time to load in the new window)
|
|
366
|
+
setTimeout(() => {
|
|
367
|
+
URL.revokeObjectURL(blobUrl);
|
|
368
|
+
}, 1000);
|
|
369
|
+
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.error('Failed to fetch PDF:', error);
|
|
372
|
+
alert('Failed to load PDF. Please try again.');
|
|
373
|
+
}
|
|
330
374
|
},
|
|
331
375
|
sendEmail = async (data) => {
|
|
332
376
|
|
|
@@ -27,18 +27,52 @@ export default function WaitMessage(props) {
|
|
|
27
27
|
if (CURRENT_MODE === UI_MODE_NATIVE) {
|
|
28
28
|
// Gluestack's ModalBackdrop was not working on Native,
|
|
29
29
|
// so workaround is to do it manually for now
|
|
30
|
-
|
|
30
|
+
return <Modal
|
|
31
|
+
{...testProps('WaitMessage')}
|
|
32
|
+
isOpen={true}
|
|
33
|
+
className="Modal"
|
|
34
|
+
aria-disabled={true}
|
|
35
|
+
>
|
|
36
|
+
<Box
|
|
37
|
+
className={clsx(
|
|
38
|
+
'WaitMessage-ModalBackdrop-replacment',
|
|
39
|
+
'h-full',
|
|
40
|
+
'w-full',
|
|
41
|
+
'absolute',
|
|
42
|
+
'top-0',
|
|
43
|
+
'left-0',
|
|
44
|
+
'bg-[#000]',
|
|
45
|
+
'opacity-50',
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
{/* <ModalContent
|
|
49
|
+
className={clsx(
|
|
50
|
+
'ModalContent',
|
|
51
|
+
'w-[200px]',
|
|
52
|
+
CURRENT_MODE === UI_MODE_WEB ? 'h-[50px]' : '',
|
|
53
|
+
'shadow-lg',
|
|
54
|
+
)}
|
|
55
|
+
> */}
|
|
56
|
+
<HStack
|
|
31
57
|
className={clsx(
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'bg-[#000]',
|
|
39
|
-
'opacity-50',
|
|
58
|
+
'HStack',
|
|
59
|
+
'items-center',
|
|
60
|
+
'justify-center',
|
|
61
|
+
'bg-white',
|
|
62
|
+
'p-4',
|
|
63
|
+
'rounded-md',
|
|
40
64
|
)}
|
|
41
|
-
|
|
65
|
+
>
|
|
66
|
+
<Spinner
|
|
67
|
+
className={clsx(
|
|
68
|
+
'mr-2',
|
|
69
|
+
'focus:outline-none',
|
|
70
|
+
)}
|
|
71
|
+
/>
|
|
72
|
+
<Text className="text-black">{text}</Text>
|
|
73
|
+
</HStack>
|
|
74
|
+
{/* </ModalContent> */}
|
|
75
|
+
</Modal>;
|
|
42
76
|
}
|
|
43
77
|
|
|
44
78
|
return <Modal
|
|
@@ -47,7 +81,7 @@ export default function WaitMessage(props) {
|
|
|
47
81
|
className="Modal"
|
|
48
82
|
aria-disabled={true}
|
|
49
83
|
>
|
|
50
|
-
|
|
84
|
+
<ModalBackdrop className="WaitMessage-ModalBackdrop" />
|
|
51
85
|
<ModalContent
|
|
52
86
|
className={clsx(
|
|
53
87
|
'ModalContent',
|
|
@@ -257,7 +257,13 @@ function Viewer(props) {
|
|
|
257
257
|
label = propertyDef.title;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
let value =
|
|
260
|
+
let value = null;
|
|
261
|
+
if (record?.properties?.hasOwnProperty(name)) {
|
|
262
|
+
value = record.properties[name].displayValue;
|
|
263
|
+
}
|
|
264
|
+
if (_.isNil(value) && record?.hasOwnProperty(name)) {
|
|
265
|
+
value = record[name];
|
|
266
|
+
}
|
|
261
267
|
const
|
|
262
268
|
schema = record?.repository?.getSchema(),
|
|
263
269
|
propertyDefinition = schema?.getPropertyDefinition(name);
|
|
@@ -385,7 +385,7 @@ function AttachmentsElement(props) {
|
|
|
385
385
|
|
|
386
386
|
alert('Files cannot be downloaded and viewed within an iOS PWA. Please use the Safari browser instead.');
|
|
387
387
|
} else {
|
|
388
|
-
downloadInBackground(url);
|
|
388
|
+
downloadInBackground(url, {}, Attachments.headers);
|
|
389
389
|
}
|
|
390
390
|
},
|
|
391
391
|
|