ywana-core8 0.0.843 → 0.0.844

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": "ywana-core8",
3
- "version": "0.0.843",
3
+ "version": "0.0.844",
4
4
  "description": "ywana-core8",
5
5
  "homepage": "https://ywana.github.io/workspace",
6
6
  "author": "Ernesto Roldan Garcia",
@@ -37,6 +37,7 @@
37
37
  "moment": "^2.29.1",
38
38
  "moment-range": "^4.0.2",
39
39
  "react-datepicker": "^4.6.0",
40
+ "react-error-boundary": "^4.0.3",
40
41
  "react-error-overlay": "^6.0.10",
41
42
  "react-image-pan-zoom-rotate": "^1.6.0",
42
43
  "react-notifications-component": "^3.4.1",
@@ -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 || json.err
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,19 @@ 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 { Tooltip } from '../html/tooltip'
5
+ import { Tooltip } from '../html/tooltip'
6
6
  import { Page } from './page'
7
7
  import { SiteContext } from './siteContext'
8
8
  import { ReactNotifications, Store } from 'react-notifications-component'
9
9
  import 'react-notifications-component/dist/theme.css'
10
10
  import './site.css'
11
+ import { ErrorBoundary } from 'react-error-boundary'
11
12
 
12
13
  /**
13
14
  * Site Provider
14
15
  */
15
16
  export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
16
-
17
+
17
18
  const [lang, setLang] = useState(siteLang)
18
19
  const [dictionary, setDictionary] = useState(siteDictionary)
19
20
  const [sideNav, setSideNav] = useState('max')
@@ -27,15 +28,15 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
27
28
  const [preview, setPreview] = useState()
28
29
  const [breadcrumb, setBreadcrumb] = useState()
29
30
  const [focused, setFocused] = useState()
30
-
31
+
31
32
  const value = {
32
-
33
+
33
34
  lang,
34
35
  setLang,
35
-
36
+
36
37
  dictionary,
37
38
  setDictionary,
38
-
39
+
39
40
  focused,
40
41
  changeFocus: (next) => {
41
42
  if (focused) focused.lose()
@@ -45,25 +46,25 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
45
46
  if (focused) focused.lose()
46
47
  setFocused(null)
47
48
  },
48
-
49
+
49
50
  sideNav,
50
51
  setSideNav,
51
52
 
52
53
  showNav,
53
54
  setShowNav,
54
-
55
+
55
56
  info,
56
57
  openInfo: (info) => { setInfo(info) },
57
58
  closeInfo: () => { setInfo(null) },
58
-
59
+
59
60
  consoleLines,
60
61
  showConsole,
61
62
  toggleConsole: () => { setShowConsole(!showConsole) },
62
- writeLog: (line) => {
63
+ writeLog: (line) => {
63
64
  const next = consoleLines.concat(line)
64
65
  setConsoleLines(next)
65
66
  },
66
- clearLog: () => { setConsoleLines([])},
67
+ clearLog: () => { setConsoleLines([]) },
67
68
 
68
69
  breadcrumb,
69
70
  setBreadcrumb,
@@ -83,10 +84,10 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
83
84
  prompt: (message) => window.prompt(message),
84
85
 
85
86
  promptDialog,
86
- openPromptDialog: (dialog) => {setPromptDialog(dialog)},
87
- closePromptDialog: () => { setPromptDialog(null)},
87
+ openPromptDialog: (dialog) => { setPromptDialog(dialog) },
88
+ closePromptDialog: () => { setPromptDialog(null) },
88
89
 
89
- notify: ({ title, body, type = "success", duration=3000, onRemoval }) => {
90
+ notify: ({ title, body, type = "success", duration = 3000, onRemoval }) => {
90
91
  Store.addNotification({
91
92
  title,
92
93
  message: body,
@@ -104,9 +105,23 @@ export const SiteProvider = ({ children, siteLang, siteDictionary }) => {
104
105
  }
105
106
  }
106
107
 
108
+ function fallbackRenderer({ error, resetErrorBoundary }) {
109
+ return (
110
+ <div className="site-error-fallback" role="alert">
111
+ <dialog>
112
+ <h3>Ywana Core 8</h3>
113
+ <p>Something went wrong:</p>
114
+ <pre>{error.message}</pre>
115
+ </dialog>
116
+ </div>
117
+ )
118
+ }
119
+
107
120
  return (
108
121
  <SiteContext.Provider value={value}>
109
- {children}
122
+ <ErrorBoundary fallbackRender={fallbackRenderer}>
123
+ {children}
124
+ </ErrorBoundary>
110
125
  </SiteContext.Provider>
111
126
  )
112
127
  }
@@ -167,7 +182,7 @@ const SiteToolBar = ({ children }) => {
167
182
  /**
168
183
  * Site Footer
169
184
  */
170
- const SiteFooter = ({ children }) => {
185
+ const SiteFooter = ({ children }) => {
171
186
  return (
172
187
  <footer>
173
188
  {children}
@@ -223,7 +238,7 @@ const SiteMenu = ({ logo, title, children, min }) => {
223
238
  const menutTitle = sideNav === 'max' ? title : ''
224
239
  return (
225
240
  <menu className={`${style} ${showNav ? 'show' : ''}`}>
226
- <Header title={menutTitle}/>
241
+ <Header title={menutTitle} />
227
242
  <main >
228
243
  {Object.keys(sections).map(title => (
229
244
  <Fragment key={title}>
@@ -282,7 +297,7 @@ const SiteDialog = () => {
282
297
  /**
283
298
  * Site Promtp Dialog
284
299
  */
285
- const SitePromptDialog = () => {
300
+ const SitePromptDialog = () => {
286
301
  const context = useContext(SiteContext)
287
302
  return context.promptDialog ? context.promptDialog : ''
288
303
  }
@@ -321,7 +336,7 @@ const SiteConsole = () => {
321
336
  <Icon icon="clear_all" size="small" clickable action={clear} />
322
337
  </nav>
323
338
  <main>
324
- {context.consoleLines.map((line,index) => <div key={`log-${index}`}>{line}</div>)}
339
+ {context.consoleLines.map((line, index) => <div key={`log-${index}`}>{line}</div>)}
325
340
  </main>
326
341
  </div>
327
342
  ) : ''
@@ -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 [form, setForm] = useState({})
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
- }
@@ -1,4 +0,0 @@
1
- export * from './uploader'
2
- export * from './UploadDialog'
3
- export * from './UploadArea'
4
- export * from './UploadFile'
@@ -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
- };