ywana-core8 0.0.843 → 0.0.845
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/dist/index.cjs +1614 -2661
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +28 -54
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +1612 -2659
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +1618 -2663
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/http/client.js +14 -8
- package/src/site/site.css +24 -0
- package/src/site/site.js +19 -21
- package/src/site/site.test.js +7 -5
- package/src/test.js +0 -67
- package/src_old/upload/UploadArea.js +0 -80
- package/src_old/upload/UploadDialog.js +0 -41
- package/src_old/upload/UploadFile.js +0 -29
- package/src_old/upload/index.js +0 -4
- package/src_old/upload/uploader.css +0 -58
- package/src_old/upload/uploader.js +0 -87
package/package.json
CHANGED
package/src/http/client.js
CHANGED
@@ -23,22 +23,28 @@ async function fetchAsync(method, URL, body = null, token, headers) {
|
|
23
23
|
}
|
24
24
|
throw response
|
25
25
|
} catch (error) {
|
26
|
-
if (error instanceof Error) { throw { error }}
|
26
|
+
if (error instanceof Error) { throw { error } }
|
27
27
|
const json = await error.json()
|
28
28
|
throw {
|
29
29
|
success: false,
|
30
|
-
message: json.message ||
|
30
|
+
message: json.message || json.err
|
31
31
|
}
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
35
|
-
|
35
|
+
/**
|
36
|
+
* HTTP Client
|
37
|
+
*
|
38
|
+
* @param {*} domain
|
39
|
+
* @param {*} securityCtx
|
40
|
+
* @returns
|
41
|
+
*/
|
36
42
|
export const HTTPClient = (domain, securityCtx) => {
|
37
43
|
return {
|
38
44
|
|
39
|
-
GET: (URL) => {
|
45
|
+
GET: (URL, headers) => {
|
40
46
|
const token = securityCtx ? securityCtx.token() : null;
|
41
|
-
return fetchAsync('GET', domain + URL, undefined, token);
|
47
|
+
return fetchAsync('GET', domain + URL, undefined, token, headers);
|
42
48
|
},
|
43
49
|
|
44
50
|
POST: (URL, body, headers) => {
|
@@ -48,17 +54,17 @@ export const HTTPClient = (domain, securityCtx) => {
|
|
48
54
|
|
49
55
|
PUT: (URL, body) => {
|
50
56
|
const token = securityCtx ? securityCtx.token() : null;
|
51
|
-
return fetchAsync('PUT', domain + URL, body, token);
|
57
|
+
return fetchAsync('PUT', domain + URL, body, token, headers);
|
52
58
|
},
|
53
59
|
|
54
60
|
PATCH: (URL, body) => {
|
55
61
|
const token = securityCtx ? securityCtx.token() : null;
|
56
|
-
return fetchAsync('PATCH', domain + URL, body, token);
|
62
|
+
return fetchAsync('PATCH', domain + URL, body, token, headers);
|
57
63
|
},
|
58
64
|
|
59
65
|
DELETE: (URL) => {
|
60
66
|
const token = securityCtx ? securityCtx.token() : null;
|
61
|
-
return fetchAsync('DELETE', domain + URL, undefined, token);
|
67
|
+
return fetchAsync('DELETE', domain + URL, undefined, token, headers);
|
62
68
|
}
|
63
69
|
}
|
64
70
|
}
|
package/src/site/site.css
CHANGED
@@ -159,4 +159,28 @@
|
|
159
159
|
flex-direction: column;
|
160
160
|
align-items: center;
|
161
161
|
justify-content: center;
|
162
|
+
}
|
163
|
+
|
164
|
+
|
165
|
+
.site-error-fallback {
|
166
|
+
display: flex;
|
167
|
+
flex-direction: column;
|
168
|
+
align-items: center;
|
169
|
+
justify-content: center;
|
170
|
+
height: 100vh;
|
171
|
+
width: 100vw;
|
172
|
+
background-color: var(--background-color);
|
173
|
+
}
|
174
|
+
|
175
|
+
.site-error-fallback > dialog {
|
176
|
+
display: flex;
|
177
|
+
flex-direction: column;
|
178
|
+
align-items: center;
|
179
|
+
justify-content: center;
|
180
|
+
width: 50%;
|
181
|
+
height: 50%;
|
182
|
+
background-color: var(--paper-color);
|
183
|
+
box-shadow: var(--shadow1);
|
184
|
+
|
185
|
+
border: solid 1px black;
|
162
186
|
}
|
package/src/site/site.js
CHANGED
@@ -2,18 +2,16 @@ import React, { Children, Fragment, useState, useContext, useEffect } from 'reac
|
|
2
2
|
import { Icon } from '../html/icon'
|
3
3
|
import { Tabs, Tab } from '../html/tab'
|
4
4
|
import { Header } from '../html/header'
|
5
|
-
import {
|
5
|
+
import { Tooltip } from '../html/tooltip'
|
6
6
|
import { Page } from './page'
|
7
7
|
import { SiteContext } from './siteContext'
|
8
|
-
import { ReactNotifications, Store } from 'react-notifications-component'
|
9
|
-
import 'react-notifications-component/dist/theme.css'
|
10
8
|
import './site.css'
|
11
9
|
|
12
10
|
/**
|
13
11
|
* Site Provider
|
14
12
|
*/
|
15
13
|
export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
|
16
|
-
|
14
|
+
|
17
15
|
const [lang, setLang] = useState(siteLang)
|
18
16
|
const [dictionary, setDictionary] = useState(siteDictionary)
|
19
17
|
const [sideNav, setSideNav] = useState('max')
|
@@ -27,15 +25,15 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
|
|
27
25
|
const [preview, setPreview] = useState()
|
28
26
|
const [breadcrumb, setBreadcrumb] = useState()
|
29
27
|
const [focused, setFocused] = useState()
|
30
|
-
|
28
|
+
|
31
29
|
const value = {
|
32
|
-
|
30
|
+
|
33
31
|
lang,
|
34
32
|
setLang,
|
35
|
-
|
33
|
+
|
36
34
|
dictionary,
|
37
35
|
setDictionary,
|
38
|
-
|
36
|
+
|
39
37
|
focused,
|
40
38
|
changeFocus: (next) => {
|
41
39
|
if (focused) focused.lose()
|
@@ -45,25 +43,25 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
|
|
45
43
|
if (focused) focused.lose()
|
46
44
|
setFocused(null)
|
47
45
|
},
|
48
|
-
|
46
|
+
|
49
47
|
sideNav,
|
50
48
|
setSideNav,
|
51
49
|
|
52
50
|
showNav,
|
53
51
|
setShowNav,
|
54
|
-
|
52
|
+
|
55
53
|
info,
|
56
54
|
openInfo: (info) => { setInfo(info) },
|
57
55
|
closeInfo: () => { setInfo(null) },
|
58
|
-
|
56
|
+
|
59
57
|
consoleLines,
|
60
58
|
showConsole,
|
61
59
|
toggleConsole: () => { setShowConsole(!showConsole) },
|
62
|
-
writeLog: (line) => {
|
60
|
+
writeLog: (line) => {
|
63
61
|
const next = consoleLines.concat(line)
|
64
62
|
setConsoleLines(next)
|
65
63
|
},
|
66
|
-
clearLog: () => { setConsoleLines([])},
|
64
|
+
clearLog: () => { setConsoleLines([]) },
|
67
65
|
|
68
66
|
breadcrumb,
|
69
67
|
setBreadcrumb,
|
@@ -83,10 +81,10 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
|
|
83
81
|
prompt: (message) => window.prompt(message),
|
84
82
|
|
85
83
|
promptDialog,
|
86
|
-
openPromptDialog: (dialog) => {setPromptDialog(dialog)},
|
87
|
-
closePromptDialog: () => { setPromptDialog(null)},
|
84
|
+
openPromptDialog: (dialog) => { setPromptDialog(dialog) },
|
85
|
+
closePromptDialog: () => { setPromptDialog(null) },
|
88
86
|
|
89
|
-
notify: ({ title, body, type = "success", duration=3000, onRemoval }) => {
|
87
|
+
notify: ({ title, body, type = "success", duration = 3000, onRemoval }) => {
|
90
88
|
Store.addNotification({
|
91
89
|
title,
|
92
90
|
message: body,
|
@@ -106,7 +104,7 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
|
|
106
104
|
|
107
105
|
return (
|
108
106
|
<SiteContext.Provider value={value}>
|
109
|
-
|
107
|
+
{children}
|
110
108
|
</SiteContext.Provider>
|
111
109
|
)
|
112
110
|
}
|
@@ -167,7 +165,7 @@ const SiteToolBar = ({ children }) => {
|
|
167
165
|
/**
|
168
166
|
* Site Footer
|
169
167
|
*/
|
170
|
-
|
168
|
+
const SiteFooter = ({ children }) => {
|
171
169
|
return (
|
172
170
|
<footer>
|
173
171
|
{children}
|
@@ -223,7 +221,7 @@ const SiteMenu = ({ logo, title, children, min }) => {
|
|
223
221
|
const menutTitle = sideNav === 'max' ? title : ''
|
224
222
|
return (
|
225
223
|
<menu className={`${style} ${showNav ? 'show' : ''}`}>
|
226
|
-
<Header title={menutTitle}/>
|
224
|
+
<Header title={menutTitle} />
|
227
225
|
<main >
|
228
226
|
{Object.keys(sections).map(title => (
|
229
227
|
<Fragment key={title}>
|
@@ -282,7 +280,7 @@ const SiteDialog = () => {
|
|
282
280
|
/**
|
283
281
|
* Site Promtp Dialog
|
284
282
|
*/
|
285
|
-
|
283
|
+
const SitePromptDialog = () => {
|
286
284
|
const context = useContext(SiteContext)
|
287
285
|
return context.promptDialog ? context.promptDialog : ''
|
288
286
|
}
|
@@ -321,7 +319,7 @@ const SiteConsole = () => {
|
|
321
319
|
<Icon icon="clear_all" size="small" clickable action={clear} />
|
322
320
|
</nav>
|
323
321
|
<main>
|
324
|
-
{context.consoleLines.map((line,index) => <div key={`log-${index}`}>{line}</div>)}
|
322
|
+
{context.consoleLines.map((line, index) => <div key={`log-${index}`}>{line}</div>)}
|
325
323
|
</main>
|
326
324
|
</div>
|
327
325
|
) : ''
|
package/src/site/site.test.js
CHANGED
@@ -2,10 +2,8 @@ import React, { Fragment, useContext, useEffect, useState } from 'react'
|
|
2
2
|
import { SiteContext } from './siteContext'
|
3
3
|
import { Site } from './site'
|
4
4
|
import { Page } from './page'
|
5
|
-
import './site.css'
|
6
|
-
import './page.css'
|
7
5
|
import { Dialog } from './dialog'
|
8
|
-
import { Button, DropDown, TextField, TextArea } from '../html'
|
6
|
+
import { Button, DropDown, TextField, TextArea, Icon } from '../html'
|
9
7
|
import { UploadDialog } from '../widgets/upload/UploadDialog'
|
10
8
|
import { Uploader } from '../widgets/upload/Uploader'
|
11
9
|
import { TabbedTablePage } from '../domain/TabbedTablePage'
|
@@ -15,6 +13,9 @@ import { CollectionPage } from '../domain/CollectionPage'
|
|
15
13
|
import { FORMATS, TYPES } from '../domain/ContentType'
|
16
14
|
import { TableTest } from '../html/table.test'
|
17
15
|
import { PasswordEditor } from '../incubator/password'
|
16
|
+
import './site.css'
|
17
|
+
import './page.css'
|
18
|
+
|
18
19
|
|
19
20
|
const SiteTest = (prop) => {
|
20
21
|
|
@@ -41,10 +42,11 @@ const SiteTest = (prop) => {
|
|
41
42
|
)
|
42
43
|
}
|
43
44
|
|
45
|
+
|
44
46
|
const Page1 = (props) => {
|
45
47
|
|
46
48
|
const site = useContext(SiteContext)
|
47
|
-
const [
|
49
|
+
const [formm, setForm] = useState({})
|
48
50
|
|
49
51
|
useEffect(() => {
|
50
52
|
site.notify({ title: "Notification 1", body: "Lorem ipsum dolor sit amet" })
|
@@ -84,7 +86,7 @@ const Page1 = (props) => {
|
|
84
86
|
)
|
85
87
|
}
|
86
88
|
|
87
|
-
const Page2 = (props) => {
|
89
|
+
const Page2 = (props) => {
|
88
90
|
|
89
91
|
const site = useContext(SiteContext)
|
90
92
|
|
package/src/test.js
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
|
3
|
-
const Test = (props) => {
|
4
|
-
|
5
|
-
return (
|
6
|
-
|
7
|
-
<div>
|
8
|
-
|
9
|
-
<table border="1">
|
10
|
-
<thead>
|
11
|
-
<tr>
|
12
|
-
<th rowspan="2" colspan="1"><div class="checkbox"><input type="checkbox" value=""/><span class="checkmark"></span><label></label></div></th>
|
13
|
-
<th rowspan="2" colspan="1"><span>Estado</span></th>
|
14
|
-
<th rowspan="2" colspan="1"><span>Fecha de Entrada</span></th>
|
15
|
-
<th rowspan="2" colspan="1"><span>Circuito</span></th>
|
16
|
-
<th rowspan="2" colspan="1"><span>Clase de Muestra</span></th>
|
17
|
-
<th colspan="3"><span>Referencia</span></th>
|
18
|
-
<th></th>
|
19
|
-
</tr>
|
20
|
-
<tr>
|
21
|
-
<th>Referencia</th>
|
22
|
-
<th>Referencia</th>
|
23
|
-
<th>Referencia</th>
|
24
|
-
</tr>
|
25
|
-
</thead>
|
26
|
-
<tbody>
|
27
|
-
</tbody>
|
28
|
-
</table>
|
29
|
-
|
30
|
-
<table border="1">
|
31
|
-
<thead>
|
32
|
-
<tr>
|
33
|
-
<th rowSpan={2}>Uno</th>
|
34
|
-
<th rowSpan={2}>Dos</th>
|
35
|
-
<th rowSpan={2}>Tres</th>
|
36
|
-
<th colspan="4">Cuatro</th>
|
37
|
-
<th rowSpan={2}>Ocho</th>
|
38
|
-
</tr>
|
39
|
-
|
40
|
-
<tr>
|
41
|
-
<th>a</th>
|
42
|
-
<th>b</th>
|
43
|
-
<th>c</th>
|
44
|
-
<th>d</th>
|
45
|
-
</tr>
|
46
|
-
|
47
|
-
</thead>
|
48
|
-
<tbody>
|
49
|
-
|
50
|
-
<tr>
|
51
|
-
<td>1</td>
|
52
|
-
<td>2</td>
|
53
|
-
<td>3</td>
|
54
|
-
<td>4</td>
|
55
|
-
<td>5</td>
|
56
|
-
<td>6</td>
|
57
|
-
<td>7</td>
|
58
|
-
<td>8</td>
|
59
|
-
</tr>
|
60
|
-
</tbody>
|
61
|
-
</table>
|
62
|
-
|
63
|
-
</div>
|
64
|
-
|
65
|
-
)
|
66
|
-
}
|
67
|
-
|
@@ -1,80 +0,0 @@
|
|
1
|
-
import React, { useState, useEffect, useRef } from 'react'
|
2
|
-
import { Icon, Text, CircularProgress } from '../html'
|
3
|
-
|
4
|
-
/**
|
5
|
-
* Component
|
6
|
-
*/
|
7
|
-
export const UploadArea = (props) => {
|
8
|
-
|
9
|
-
const STATES = { 'IDLE': 0, 'RUNNING': 1, 'SUCCESS': 2, 'ERROR': 3 }
|
10
|
-
|
11
|
-
const areaElement = useRef()
|
12
|
-
const [drag, setDrag] = useState(false)
|
13
|
-
|
14
|
-
useEffect(() => {
|
15
|
-
const { resumable } = props
|
16
|
-
if (resumable && areaElement) resumable.assignDrop(areaElement.current)
|
17
|
-
}, [])
|
18
|
-
|
19
|
-
const onDragOver = () => {
|
20
|
-
setDrag(true)
|
21
|
-
}
|
22
|
-
|
23
|
-
const onDragLeave = () => {
|
24
|
-
setDrag(false)
|
25
|
-
}
|
26
|
-
|
27
|
-
const { state = STATES.IDLE, label = 'Add file or drop file here...', error } = props
|
28
|
-
const dragging = drag === true ? 'drag-over' : ''
|
29
|
-
|
30
|
-
return (
|
31
|
-
<div className={`upload-area6 ${dragging}`}
|
32
|
-
onDragOver={onDragOver}
|
33
|
-
onDragLeave={onDragLeave}
|
34
|
-
ref={areaElement}
|
35
|
-
>
|
36
|
-
{state === STATES.IDLE ? <UploadIcon resumable={props.resumable} /> : ''}
|
37
|
-
{state === STATES.IDLE ? <label>{label}</label> : ''}
|
38
|
-
{state === STATES.RUNNING ? <CircularProgress size="xlarge" /> : ''}
|
39
|
-
{state === STATES.SUCCESS ? <Icon icon="done_all" /> : ''}
|
40
|
-
{state === STATES.ERROR ? <Text use="body1">{error}</Text> : ''}
|
41
|
-
{props.children}
|
42
|
-
</div>
|
43
|
-
)
|
44
|
-
}
|
45
|
-
|
46
|
-
/**
|
47
|
-
* Component
|
48
|
-
*/
|
49
|
-
const UploadIcon = ({ resumable }) => {
|
50
|
-
|
51
|
-
const iconElement = useRef()
|
52
|
-
|
53
|
-
useEffect(() => {
|
54
|
-
if (resumable && iconElement) resumable.assignBrowse(iconElement.current)
|
55
|
-
}, [])
|
56
|
-
|
57
|
-
return (
|
58
|
-
<div className="upload-icon" ref={iconElement}>
|
59
|
-
<Icon icon="folder_open" clickable/>
|
60
|
-
</div>
|
61
|
-
)
|
62
|
-
}
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Upload Button
|
66
|
-
*/
|
67
|
-
export function UploadButton({ resumable, icon="file_upload", label="Upload"}) {
|
68
|
-
|
69
|
-
const buttonElement = useRef();
|
70
|
-
|
71
|
-
useEffect(() => {
|
72
|
-
if (resumable && buttonElement) resumable.assignBrowse(buttonElement.current);
|
73
|
-
}, []);
|
74
|
-
|
75
|
-
return (
|
76
|
-
<div className="upload-button" ref={buttonElement}>
|
77
|
-
<Button icon={icon} label={label} outlined/>
|
78
|
-
</div>
|
79
|
-
)
|
80
|
-
}
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import React, { Fragment, useContext, useState } from 'react';
|
2
|
-
import { Uploader } from './uploader'
|
3
|
-
import { Button, Text } from '../html';
|
4
|
-
import { SiteContext, Dialog } from '../site';
|
5
|
-
import { UploadFile } from './UploadFile';
|
6
|
-
|
7
|
-
/**
|
8
|
-
* Upload Dialog
|
9
|
-
*/
|
10
|
-
export const UploadDialog = ({ label, target, accept, onSuccess, onOK, onError, onClose, onActionClose = true }) => {
|
11
|
-
|
12
|
-
const site = useContext(SiteContext);
|
13
|
-
const [file, setFile] = useState();
|
14
|
-
const [errors, setErrors] = useState([])
|
15
|
-
|
16
|
-
function onComplete(uploads) {
|
17
|
-
setFile(uploads[0]);
|
18
|
-
if (onSuccess) onSuccess(uploads[0])
|
19
|
-
}
|
20
|
-
|
21
|
-
function onAction(action) {
|
22
|
-
if (action === 'CLOSE' || onActionClose === true) {
|
23
|
-
site.closeDialog();
|
24
|
-
onClose()
|
25
|
-
}
|
26
|
-
}
|
27
|
-
|
28
|
-
const actions = (
|
29
|
-
<Fragment>
|
30
|
-
<Button label="CLOSE" action={() => onAction("CLOSE")} />
|
31
|
-
</Fragment>
|
32
|
-
)
|
33
|
-
|
34
|
-
const title = <Text use="headline6">{label}</Text>
|
35
|
-
return (
|
36
|
-
<Dialog title={title} open={true} onAction={onAction} actions={actions}>
|
37
|
-
{file ? <UploadFile file={file} /> : <Uploader label={label} accept={accept} target={target} onComplete={onComplete} />}
|
38
|
-
{errors.map(error => <Text use="overline" tag="div" className="error">{error}</Text>)}
|
39
|
-
</Dialog>
|
40
|
-
)
|
41
|
-
}
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import React, { Fragment } from 'react'
|
2
|
-
import { Icon, Text, LinearProgress } from '../html'
|
3
|
-
import './uploader.css'
|
4
|
-
|
5
|
-
/**
|
6
|
-
* Upload File
|
7
|
-
*/
|
8
|
-
export const UploadFile = ({ file, state, progress, error }) => {
|
9
|
-
|
10
|
-
const STATES = { 'IDLE': 0, 'RUNNING': 1, 'SUCCESS': 2, 'ERROR': 3 }
|
11
|
-
|
12
|
-
const icon = error ? <Icon icon="image" className="error"/> : <Icon icon="image" />
|
13
|
-
return state !== STATES.IDLE ? (
|
14
|
-
<Fragment>
|
15
|
-
|
16
|
-
<div className="upload-file">
|
17
|
-
{icon}
|
18
|
-
<Text use="body1" tag="label">{file.fileName}</Text>
|
19
|
-
{state === STATES.RUNNING ? <LinearProgress progress={progress} /> : ''}
|
20
|
-
{state === STATES.RUNNING ? <Icon icon="close" clickable /> : ''}
|
21
|
-
{state === STATES.SUCCESS ? <Icon icon="done" /> : ''}
|
22
|
-
{state === STATES.ERROR ? <Icon icon="error" /> : ''}
|
23
|
-
</div>
|
24
|
-
|
25
|
-
{ error ? <div className="error"><Text use="overline">{error}</Text></div> : ''}
|
26
|
-
|
27
|
-
</Fragment>
|
28
|
-
) : ''
|
29
|
-
}
|
package/src_old/upload/index.js
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
.uploader {
|
2
|
-
display: flex;
|
3
|
-
flex-direction: column;
|
4
|
-
flex: 1;
|
5
|
-
}
|
6
|
-
|
7
|
-
.demo-uploader {
|
8
|
-
width: 40rem;
|
9
|
-
height: 30rem;
|
10
|
-
margin: 5rem auto;
|
11
|
-
flex-direction: column;
|
12
|
-
}
|
13
|
-
|
14
|
-
/***************** Upload Area ***********************/
|
15
|
-
|
16
|
-
.upload-area6 {
|
17
|
-
flex: 1;
|
18
|
-
margin: 0 0 1rem 0;
|
19
|
-
border: dashed 2px var(--divider-color);
|
20
|
-
display: flex;
|
21
|
-
flex-direction: column;
|
22
|
-
align-items: center;
|
23
|
-
justify-content: center;
|
24
|
-
border-radius: 1rem;
|
25
|
-
min-height: 10rem;
|
26
|
-
}
|
27
|
-
|
28
|
-
.upload-area6>label {
|
29
|
-
font-size: 1.1rem;
|
30
|
-
font-weight: 500;
|
31
|
-
}
|
32
|
-
|
33
|
-
.upload-area6.drag-over {
|
34
|
-
background-color: rgba(200,200,200,.1);
|
35
|
-
}
|
36
|
-
|
37
|
-
/***************** Upload File ***********************/
|
38
|
-
|
39
|
-
.upload-file {
|
40
|
-
display: flex;
|
41
|
-
align-items: center;
|
42
|
-
min-height: 4rem;
|
43
|
-
padding: 0 1rem;
|
44
|
-
}
|
45
|
-
|
46
|
-
.upload-file>label {
|
47
|
-
padding: 0 1rem;
|
48
|
-
min-width: 40%;
|
49
|
-
flex: 1;
|
50
|
-
overflow: hidden;
|
51
|
-
text-overflow: ellipsis;
|
52
|
-
white-space: nowrap;
|
53
|
-
}
|
54
|
-
|
55
|
-
.error {
|
56
|
-
color: red;
|
57
|
-
text-align: center
|
58
|
-
}
|
@@ -1,87 +0,0 @@
|
|
1
|
-
import React, { useState, useMemo } from 'react'
|
2
|
-
import ResumableJS from 'resumablejs'
|
3
|
-
import { UploadArea } from "./UploadArea";
|
4
|
-
import { UploadFile } from "./UploadFile";
|
5
|
-
import './uploader.css'
|
6
|
-
|
7
|
-
const STATES = {
|
8
|
-
IDLE: 0, RUNNING: 1, SUCCESS: 2, ERROR: 3, COMPLETED: 4
|
9
|
-
}
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Uploader
|
13
|
-
*/
|
14
|
-
export const Uploader = ({ label, target, accept, simultaneousUploads = 1, className, onProgress, onSuccess, onError, onComplete, errors = [] }) => {
|
15
|
-
|
16
|
-
|
17
|
-
const resumable = useMemo(() => {
|
18
|
-
const config = {
|
19
|
-
target: target,
|
20
|
-
chunkSize: 1 * 1024 * 1024,
|
21
|
-
simultaneousUploads,
|
22
|
-
testChunks: false,
|
23
|
-
throttleProgressCallbacks: 1,
|
24
|
-
fileType: accept
|
25
|
-
}
|
26
|
-
const resumable = new ResumableJS(config)
|
27
|
-
resumable.on('fileAdded', onFileAdded)
|
28
|
-
resumable.on('fileProgress', onFileProgress)
|
29
|
-
resumable.on('fileSuccess', onFileSuccess)
|
30
|
-
resumable.on('fileError', onFileError)
|
31
|
-
resumable.on('complete', onAllComplete)
|
32
|
-
return resumable
|
33
|
-
}, [])
|
34
|
-
|
35
|
-
const [progress, setProgress] = useState(0)
|
36
|
-
const [state, setState] = useState(STATES.IDLE)
|
37
|
-
const [error, setError] = useState()
|
38
|
-
const [files, setFiles] = useState([])
|
39
|
-
|
40
|
-
function onFileAdded(file) {
|
41
|
-
files.push(file)
|
42
|
-
setFiles(files)
|
43
|
-
setState(STATES.RUNNING)
|
44
|
-
resumable.upload()
|
45
|
-
}
|
46
|
-
|
47
|
-
function onFileProgress(file) {
|
48
|
-
const progress = file.progress()
|
49
|
-
setProgress(progress)
|
50
|
-
if (onProgress) onProgress(files);
|
51
|
-
}
|
52
|
-
|
53
|
-
function onFileSuccess(file, message) {
|
54
|
-
setState(STATES.SUCCESS)
|
55
|
-
if (onSuccess) onSuccess(file, message)
|
56
|
-
}
|
57
|
-
|
58
|
-
function onFileError(file, message) {
|
59
|
-
setError(message)
|
60
|
-
setState(STATES.ERROR)
|
61
|
-
if (onError) onError(file, message)
|
62
|
-
}
|
63
|
-
|
64
|
-
function onAllComplete() {
|
65
|
-
setState(STATES.IDLE)
|
66
|
-
if (onComplete) onComplete(files)
|
67
|
-
}
|
68
|
-
|
69
|
-
return (
|
70
|
-
<div className={`uploader ${className}`}>
|
71
|
-
{state === STATES.IDLE ? <UploadArea resumable={resumable} state={state} label={label} error={error} progress={progress} /> : null}
|
72
|
-
{state === STATES.RUNNING || STATES.SUCCESS || STATES.ERROR ? <UploadProgress files={files} errors={errors} /> : null}
|
73
|
-
</div>
|
74
|
-
)
|
75
|
-
}
|
76
|
-
|
77
|
-
const UploadProgress = ({ files = [], errors }) => {
|
78
|
-
return (
|
79
|
-
<div>
|
80
|
-
{files.map((file) => {
|
81
|
-
const error2 = errors.some((e) => e === file.fileName) ? "Fichero Mal Nombrado" : "";
|
82
|
-
const progress = 1
|
83
|
-
return <UploadFile file={file} state={STATES.RUNNING} progress={file.progress()} />;
|
84
|
-
})}
|
85
|
-
</div>
|
86
|
-
);
|
87
|
-
};
|