@onehat/ui 0.3.5 → 0.3.7
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onehat/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Base UI for OneHat apps",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"yup": "^1.2.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
+
"@files-ui/react": "^1.0.8",
|
|
40
41
|
"ckeditor5-custom-build": "file:ckeditor5",
|
|
41
42
|
"react": "*",
|
|
42
43
|
"react-color": "^2.19.3",
|
|
@@ -44,8 +45,7 @@
|
|
|
44
45
|
"react-draggable": "^4.4.5",
|
|
45
46
|
"react-native-draggable": "^3.3.0",
|
|
46
47
|
"react-dom": "*",
|
|
47
|
-
"react-native": "*"
|
|
48
|
-
"react-uploader": "^3.41.0"
|
|
48
|
+
"react-native": "*"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@babel/core": "^7.22.1",
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import UiGlobals from '../UiGlobals.js';
|
|
2
|
+
import Attachments from '../PlatformImports/Web/Attachments.js';
|
|
2
3
|
// import CKEditor from '../Components/Form/Field/CKEditor/CKEditor.js';
|
|
3
4
|
import Datetime from '../PlatformImports/Web/Datetime.js';
|
|
4
5
|
import Draggable from '../PlatformImports/Web/Draggable.js';
|
|
5
|
-
import File from '../PlatformImports/Web/
|
|
6
|
+
// import File from '../PlatformImports/Web/Attachments.js';
|
|
6
7
|
import _ from 'lodash';
|
|
7
8
|
|
|
8
9
|
export default function registerWebComponents() {
|
|
9
10
|
_.merge(UiGlobals.components, {
|
|
11
|
+
Attachments,
|
|
10
12
|
// CKEditor, // The CKEditor was giving me CSS import errors, so had to disable it until I can fix those
|
|
11
13
|
Datetime,
|
|
12
14
|
Draggable,
|
|
13
|
-
File,
|
|
15
|
+
// File,
|
|
14
16
|
});
|
|
15
17
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
Icon,
|
|
5
|
+
Row,
|
|
6
|
+
Text,
|
|
7
|
+
Tooltip,
|
|
8
|
+
} from 'native-base';
|
|
9
|
+
import {
|
|
10
|
+
CURRENT_MODE,
|
|
11
|
+
UI_MODE_WEB,
|
|
12
|
+
UI_MODE_REACT_NATIVE,
|
|
13
|
+
} from '../../../Constants/UiModes.js';
|
|
14
|
+
import UiGlobals from '../../../UiGlobals.js';
|
|
15
|
+
import {
|
|
16
|
+
FILE_MODE_IMAGE,
|
|
17
|
+
FILE_MODE_FILE,
|
|
18
|
+
} from '../../../Constants/File.js';
|
|
19
|
+
import { Avatar, Dropzone, FileMosaic, FileCard, FileInputButton, } from "@files-ui/react";
|
|
20
|
+
import withData from '../../Components/Hoc/withData.js';
|
|
21
|
+
import _ from 'lodash';
|
|
22
|
+
|
|
23
|
+
function AttachmentsElement(props) {
|
|
24
|
+
|
|
25
|
+
if (CURRENT_MODE !== UI_MODE_WEB) {
|
|
26
|
+
throw new Error('Not yet implemented except for web.');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const {
|
|
30
|
+
canCrud = true,
|
|
31
|
+
_dropZone = {},
|
|
32
|
+
_fileMosaic = {},
|
|
33
|
+
accept = '*', // 'image/*'
|
|
34
|
+
maxFiles = null,
|
|
35
|
+
maxFileSize = 28 * 1024,
|
|
36
|
+
disabled = false,
|
|
37
|
+
clickable = true,
|
|
38
|
+
isImageOnly = false,
|
|
39
|
+
|
|
40
|
+
// withData
|
|
41
|
+
Repository,
|
|
42
|
+
|
|
43
|
+
} = props,
|
|
44
|
+
styles = UiGlobals.styles,
|
|
45
|
+
WhichFile = isImageOnly ? Avatar : FileMosaic,
|
|
46
|
+
onDelete = (a,b,c,d,e) => {
|
|
47
|
+
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (canCrud) {
|
|
51
|
+
return <Dropzone
|
|
52
|
+
value={files}
|
|
53
|
+
onChange={updateFiles}
|
|
54
|
+
accept={accept}
|
|
55
|
+
maxFiles={maxFiles}
|
|
56
|
+
maxFileSize={maxFileSize}
|
|
57
|
+
validator={() => {}}
|
|
58
|
+
autoClean={true}
|
|
59
|
+
uploadConfig={{
|
|
60
|
+
url: Repository.api.baseURL + Repository.name + '/uploadAttachments',
|
|
61
|
+
method: 'POST',
|
|
62
|
+
headers: Repository.headers,
|
|
63
|
+
autoUpload: true,
|
|
64
|
+
}}
|
|
65
|
+
onUploadFinish={handleFinishUpload}
|
|
66
|
+
background={styles.ATTACHMENTS_BG}
|
|
67
|
+
color={styles.ATTACHMENTS_COLOR}
|
|
68
|
+
minHeight={150}
|
|
69
|
+
clickable={clickable}
|
|
70
|
+
{..._dropZone}
|
|
71
|
+
>
|
|
72
|
+
{files.map((file) => {
|
|
73
|
+
// const ExtFile = {
|
|
74
|
+
// id string | number The identifier of the file
|
|
75
|
+
// file File The file object obtained from client drop or selection
|
|
76
|
+
// name string The name of the file
|
|
77
|
+
// type string The file mime type.
|
|
78
|
+
// size number The size of the file in bytes.
|
|
79
|
+
// valid boolean If present, it will show a valid or rejected message ("valid", "denied"). By default valid is undefined.
|
|
80
|
+
// errors string[] The list of errors according to the validation criteria or the result of the given custom validation function.
|
|
81
|
+
// uploadStatus UPLOADSTATUS The current upload status. (e.g. "uploading").
|
|
82
|
+
// uploadMessage string A message that shows the result of the upload process.
|
|
83
|
+
// imageUrl string A string representation or web url of the image that will be set to the "src" prop of an <img/> tag. If given, the component will use this image source instead of reading the image file.
|
|
84
|
+
// downloadUrl string The url to be used to perform a GET request in order to download the file. If defined, the download icon will be shown.
|
|
85
|
+
// progress number The current percentage of upload progress. This value will have a higher priority over the upload progress value calculated inside the component.
|
|
86
|
+
// extraUploadData Record<string, any> The additional data that will be sent to the server when files are uploaded individually
|
|
87
|
+
// extraData Object Any kind of extra data that could be needed.
|
|
88
|
+
// serverResponse ServerResponse The upload response from server.
|
|
89
|
+
// xhr XMLHttpRequest A reference to the XHR object that allows the upload, progress and abort events.
|
|
90
|
+
// };
|
|
91
|
+
return <WhichFile
|
|
92
|
+
key={file.id}
|
|
93
|
+
{...file}
|
|
94
|
+
backgroundBlurImage={false}
|
|
95
|
+
onDelete={onDelete}
|
|
96
|
+
info
|
|
97
|
+
{..._fileMosaic}
|
|
98
|
+
/>;
|
|
99
|
+
})}
|
|
100
|
+
</Dropzone>;
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return <Row
|
|
105
|
+
flex={1}
|
|
106
|
+
minHeight={150}
|
|
107
|
+
background={styles.ATTACHMENTS_BG}
|
|
108
|
+
color={styles.ATTACHMENTS_COLOR}
|
|
109
|
+
>
|
|
110
|
+
{files.map((file) => {
|
|
111
|
+
return <WhichFile
|
|
112
|
+
key={file.id}
|
|
113
|
+
{...file}
|
|
114
|
+
onDelete={removeFile}
|
|
115
|
+
info
|
|
116
|
+
{..._fileMosaic}
|
|
117
|
+
/>;
|
|
118
|
+
})}
|
|
119
|
+
</Row>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export default withData(AttachmentsElement);
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef, } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Icon,
|
|
5
|
-
Row,
|
|
6
|
-
Text,
|
|
7
|
-
Tooltip,
|
|
8
|
-
} from 'native-base';
|
|
9
|
-
import {
|
|
10
|
-
CURRENT_MODE,
|
|
11
|
-
UI_MODE_WEB,
|
|
12
|
-
UI_MODE_REACT_NATIVE,
|
|
13
|
-
} from '../../../Constants/UiModes.js';
|
|
14
|
-
import UiGlobals from '../../../UiGlobals.js';
|
|
15
|
-
import {
|
|
16
|
-
FILE_MODE_IMAGE,
|
|
17
|
-
FILE_MODE_FILE,
|
|
18
|
-
} from '../../../Constants/File.js';
|
|
19
|
-
import { Uploader } from 'uploader'; // Installed by "react-uploader".
|
|
20
|
-
import { UploadButton } from 'react-uploader';
|
|
21
|
-
import IconButton from '../../Buttons/IconButton.js';
|
|
22
|
-
import withValue from '../../Hoc/withValue.js';
|
|
23
|
-
import File from '../../Icons/File.js';
|
|
24
|
-
import Trash from '../../Icons/Trash.js';
|
|
25
|
-
import _ from 'lodash';
|
|
26
|
-
|
|
27
|
-
function FileElement(props) {
|
|
28
|
-
|
|
29
|
-
if (CURRENT_MODE !== UI_MODE_WEB) {
|
|
30
|
-
throw new Error('Not yet implemented except for web.');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const {
|
|
34
|
-
name,
|
|
35
|
-
value = {
|
|
36
|
-
dataUri: null,
|
|
37
|
-
control: null,
|
|
38
|
-
filename: null,
|
|
39
|
-
},
|
|
40
|
-
setValue,
|
|
41
|
-
|
|
42
|
-
mode = FILE_MODE_IMAGE, // FILE_MODE_IMAGE, FILE_MODE_FILE
|
|
43
|
-
imagePath = '',
|
|
44
|
-
tooltip = 'Choose or drag a file on top of this control.',
|
|
45
|
-
tooltipPlacement = 'bottom',
|
|
46
|
-
} = props,
|
|
47
|
-
styles = UiGlobals.styles,
|
|
48
|
-
dragRef = useRef(),
|
|
49
|
-
fileInputRef = useRef(),
|
|
50
|
-
[isDropping, setIsDropping] = useState(false),
|
|
51
|
-
onSelect = () => {
|
|
52
|
-
fileInputRef.current.click();
|
|
53
|
-
|
|
54
|
-
setValue({
|
|
55
|
-
dataUri: null,
|
|
56
|
-
control: null,
|
|
57
|
-
filename: null,
|
|
58
|
-
version,
|
|
59
|
-
});
|
|
60
|
-
},
|
|
61
|
-
setBase64 = (file, readerResult) => {
|
|
62
|
-
const
|
|
63
|
-
base64 = btoa(readerResult), // 'btoa' is deprecated in Node.js, but not browsers, so use it! // https://developer.mozilla.org/en-US/docs/Web/API/btoa
|
|
64
|
-
dataUri = `data:${file.type};base64,${base64}`,
|
|
65
|
-
control = '',
|
|
66
|
-
filename = file.name;
|
|
67
|
-
|
|
68
|
-
},
|
|
69
|
-
onDrop = (e) => {
|
|
70
|
-
e.preventDefault();
|
|
71
|
-
const
|
|
72
|
-
files = e.dataTransfer && e.dataTransfer.files,
|
|
73
|
-
file = files[0],
|
|
74
|
-
reader = new FileReader();
|
|
75
|
-
|
|
76
|
-
reader.readAsDataURL(file);
|
|
77
|
-
reader.onload = (e) => {
|
|
78
|
-
setBase64(file, e.target.result);
|
|
79
|
-
};
|
|
80
|
-
setIsDropping(false);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
return <div ref={dragRef} style={{ flex: 1, height: '100%', }} onDragEnter={onDragEnter} onDragLeave={onDragLeave} onDragOver={onDragOver} onDrop={onDrop}>
|
|
84
|
-
<Tooltip label={tooltip} placement={tooltipPlacement}>
|
|
85
|
-
<Row flex={1} h={10} alignItems="center">
|
|
86
|
-
{isDropping && <Box position="absolute" borderWidth={isDropping ? 2 : 0} borderColor="primary.800" top={0} left={0} w="100%" h="100%" bg="trueGray.200" zIndex={10000} justifyContent="center" alignItems="center">
|
|
87
|
-
<Text>Set File</Text>
|
|
88
|
-
</Box>}
|
|
89
|
-
<IconButton
|
|
90
|
-
icon={<Icon as={File} color={styles.FORM_FILE_ICON_COLOR} />}
|
|
91
|
-
onPress={onSelect}
|
|
92
|
-
h={10}
|
|
93
|
-
w={10}
|
|
94
|
-
bg={styles.FORM_FILE_ICON_BG}
|
|
95
|
-
_hover={{
|
|
96
|
-
bg: styles.FORM_FILE_ICON_BG_HOVER,
|
|
97
|
-
}}
|
|
98
|
-
/>
|
|
99
|
-
<IconButton
|
|
100
|
-
icon={<Icon as={Trash} color={styles.FORM_FILE_ICON_COLOR} />}
|
|
101
|
-
onPress={onClear}
|
|
102
|
-
h={10}
|
|
103
|
-
w={10}
|
|
104
|
-
ml={1}
|
|
105
|
-
isDisabled={!value?.dataUri}
|
|
106
|
-
bg={value?.dataUri ? styles.FORM_FILE_ICON_BG : 'disabled'}
|
|
107
|
-
_hover={{
|
|
108
|
-
bg: value?.dataUri ? styles.FORM_FILE_ICON_BG_HOVER : 'disabled',
|
|
109
|
-
}}
|
|
110
|
-
/>
|
|
111
|
-
{mode === FILE_MODE_FILE && <Text
|
|
112
|
-
flex={1}
|
|
113
|
-
ml={3}
|
|
114
|
-
fontSize={styles.FORM_FILE_READOUT_FONTSIZE}
|
|
115
|
-
fontStyle="italic"
|
|
116
|
-
numberOfLines={1}
|
|
117
|
-
ellipsizeMode="head"
|
|
118
|
-
bg={styles.FORM_FILE_READOUT_BG}
|
|
119
|
-
>{value.filename || 'No file'}</Text>}
|
|
120
|
-
{mode === FILE_MODE_IMAGE && <Box
|
|
121
|
-
flex={1}
|
|
122
|
-
h="100%"
|
|
123
|
-
ml={1}
|
|
124
|
-
bg={styles.FORM_FILE_READOUT_BG}
|
|
125
|
-
backgroundImage={value?.dataUri ? 'url(' + imagePath + encodeURIComponent(value.dataUri) + ')' : 'none'}
|
|
126
|
-
backgroundSize="contain"
|
|
127
|
-
backgroundRepeat="no-repeat"
|
|
128
|
-
borderRadius={4}
|
|
129
|
-
borderWidth={1}
|
|
130
|
-
/>}
|
|
131
|
-
<input type="file" ref={fileInputRef} name={name} onChange={onChangeFile} style={{ position: 'absolute', opacity: 0, height: 0, width: 0, }} />
|
|
132
|
-
</Row>
|
|
133
|
-
</Tooltip>
|
|
134
|
-
</div>;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export default withValue(FileElement);
|