5htp-core 0.2.1 → 0.2.2-1
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 +10 -3
- package/src/client/app/index.ts +2 -2
- package/src/client/assets/css/components/card.less +0 -3
- package/src/client/assets/css/components/other.less +2 -4
- package/src/client/assets/css/components/table.less +1 -2
- package/src/client/assets/css/components.less +4 -0
- package/src/client/assets/css/core.less +0 -1
- package/src/client/assets/css/theme.less +2 -2
- package/src/client/assets/css/utils/medias.less +21 -0
- package/src/client/components/Card/index.tsx +8 -5
- package/src/client/components/Dialog/index.less +3 -3
- package/src/client/components/Row/index.less +2 -0
- package/src/client/components/Row/index.tsx +44 -10
- package/src/client/components/Video/index.less +39 -0
- package/src/client/components/Video/index.tsx +69 -0
- package/src/client/components/containers/Popover/index.tsx +2 -2
- package/src/client/components/data/Time.tsx +1 -1
- package/src/client/components/data/progressbar/circular/index.tsx +1 -1
- package/src/client/components/index.ts +24 -8
- package/src/client/components/input/BaseV2/index.tsx +0 -1
- package/src/client/components/{input/BaseV2/index.less → inputv3/base.less} +1 -1
- package/src/client/components/inputv3/base.tsx +73 -0
- package/src/client/components/{input/UploadImage → inputv3/file}/Bouton.tsx +0 -0
- package/src/client/components/inputv3/file/FileToUpload.ts +34 -0
- package/src/client/components/inputv3/file/index.less +59 -0
- package/src/client/components/inputv3/file/index.tsx +157 -0
- package/src/client/components/{input → inputv3/string}/index.tsx +41 -27
- package/src/client/pages/bug.tsx +3 -4
- package/src/client/services/router/index.tsx +0 -1
- package/src/client/services/router/request/api.ts +20 -12
- package/src/client/services/router/request/multipart.ts +27 -0
- package/src/common/data/chaines/greetings.ts +1 -1
- package/src/common/data/dates.ts +1 -1
- package/src/common/data/input/validate.ts +0 -9
- package/src/common/data/markdown.ts +1 -1
- package/src/common/errors/index.ts +16 -12
- package/src/common/router/request/api.ts +11 -3
- package/src/common/validation/schema.ts +21 -20
- package/src/common/validation/validators.ts +3 -6
- package/src/server/app/commands.ts +149 -0
- package/src/server/app/index.ts +25 -5
- package/src/server/app/service.ts +4 -0
- package/src/server/services/cache/commands.ts +41 -0
- package/src/server/services/cache/index.ts +102 -34
- package/src/server/services/console/index.ts +1 -1
- package/src/server/services/database/connection.ts +38 -22
- package/src/server/services/database/datatypes.ts +51 -12
- package/src/server/services/database/index.ts +133 -40
- package/src/server/services/database/metas.ts +63 -37
- package/src/server/services/database/repository.ts +26 -0
- package/src/server/services/email/index.ts +102 -42
- package/src/server/services/fetch/index.ts +110 -0
- package/src/server/services/router/http/multipart.ts +70 -41
- package/src/server/services/router/index.ts +35 -4
- package/src/server/services/router/request/index.ts +8 -6
- package/src/server/services/schema/index.ts +4 -11
- package/src/server/services/schema/request.ts +16 -7
- package/src/server/services/schema/router.ts +6 -2
- package/src/server/{services_old → services/security/encrypt}/aes.ts +33 -14
- package/src/server/services/users/index.ts +3 -3
- package/src/server/services/users/router/index.ts +0 -2
- package/src/types/global/utils.d.ts +11 -1
- package/tsconfig.common.json +3 -0
- package/src/client/components/input/Textarea.tsx +0 -57
- package/src/client/components/input/Upload.tsx +0 -5
- package/src/client/components/input/UploadImage/index.less +0 -93
- package/src/client/components/input/UploadImage/index.tsx +0 -220
- package/src/common/data/file.ts +0 -25
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.2.1",
|
|
4
|
+
"version": "0.2.2-1",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"express-fileupload": "^1.2.1",
|
|
36
36
|
"express-static-gzip": "^2.1.1",
|
|
37
37
|
"fast-safe-stringify": "^2.1.1",
|
|
38
|
+
"formattor": "^0.0.2",
|
|
38
39
|
"fs-extra": "^10.1.0",
|
|
39
40
|
"google-auth-library": "^7.11.0",
|
|
40
41
|
"got": "^11.8.3",
|
|
@@ -52,10 +53,12 @@
|
|
|
52
53
|
"locale": "^0.1.0",
|
|
53
54
|
"markdown-it": "^13.0.1",
|
|
54
55
|
"md5": "^2.3.0",
|
|
56
|
+
"mime-types": "^2.1.35",
|
|
55
57
|
"module-alias": "^2.2.2",
|
|
56
58
|
"morgan": "^1.10.0",
|
|
57
59
|
"mysql2": "^2.3.0",
|
|
58
60
|
"nodemailer": "^6.6.3",
|
|
61
|
+
"object-sizeof": "^1.6.3",
|
|
59
62
|
"path-to-regexp": "^6.2.0",
|
|
60
63
|
"picomatch": "^2.3.1",
|
|
61
64
|
"preact": "^10.5.15",
|
|
@@ -73,17 +76,21 @@
|
|
|
73
76
|
"uuid-by-string": "^3.0.4",
|
|
74
77
|
"validator": "^13.7.0",
|
|
75
78
|
"ws": "^8.2.2",
|
|
76
|
-
"yaml": "^1.10.2"
|
|
79
|
+
"yaml": "^1.10.2",
|
|
80
|
+
"yargs-parser": "^21.1.1"
|
|
77
81
|
},
|
|
78
82
|
"devDependencies": {
|
|
79
83
|
"@types/cookie": "^0.4.1",
|
|
80
84
|
"@types/express": "^4.17.13",
|
|
81
85
|
"@types/fs-extra": "^9.0.12",
|
|
86
|
+
"@types/markdown-it": "^12.2.3",
|
|
87
|
+
"@types/mime-types": "^2.1.1",
|
|
82
88
|
"@types/node": "^16.9.1",
|
|
83
89
|
"@types/nodemailer": "^6.4.4",
|
|
84
90
|
"@types/universal-analytics": "^0.4.5",
|
|
85
91
|
"@types/webpack-env": "^1.16.2",
|
|
86
92
|
"@types/ws": "^7.4.7",
|
|
87
|
-
"
|
|
93
|
+
"@types/yargs-parser": "^21.0.0",
|
|
94
|
+
"babel-plugin-glob-import": "^0.0.6-2"
|
|
88
95
|
}
|
|
89
96
|
}
|
package/src/client/app/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ if (typeof window === 'undefined')
|
|
|
8
8
|
window.dev && require('preact/debug');
|
|
9
9
|
|
|
10
10
|
// Core
|
|
11
|
-
import {
|
|
11
|
+
import { CoreError } from '@common/errors';
|
|
12
12
|
import type { Layout } from '@common/router';
|
|
13
13
|
import { createDialog } from '@client/components/Dialog/Manager';
|
|
14
14
|
|
|
@@ -102,7 +102,7 @@ export default abstract class Application {
|
|
|
102
102
|
})
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
public handleError( error:
|
|
105
|
+
public handleError( error: CoreError | Error, httpCode?: number ) {
|
|
106
106
|
|
|
107
107
|
/*console.error(`[api] Network error:`, e);
|
|
108
108
|
context.toast.error("Please check your internet connection and try again.", undefined, null, { autohide: false });*/
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
@import './text/icons.less';
|
|
5
5
|
@import './text/titres.less';
|
|
6
6
|
|
|
7
|
+
// TODO: move all less files to component folder
|
|
8
|
+
|
|
7
9
|
// Components
|
|
10
|
+
@import '@client/components/Video/index.less';
|
|
8
11
|
@import './components/input.less';
|
|
9
12
|
@import './components/button.less';
|
|
10
13
|
@import './components/lists.less';
|
|
@@ -18,6 +21,7 @@
|
|
|
18
21
|
// Les classes utilitaires override les classes de composant
|
|
19
22
|
@import './utils/borders.less';
|
|
20
23
|
@import './utils/layouts.less';
|
|
24
|
+
@import './utils/medias.less';
|
|
21
25
|
|
|
22
26
|
.white-card() {
|
|
23
27
|
background: white;
|
|
@@ -41,6 +41,27 @@ img {
|
|
|
41
41
|
background-size: cover;
|
|
42
42
|
background-repeat: no-repeat;
|
|
43
43
|
background-position: center;
|
|
44
|
+
|
|
45
|
+
&.colorize {
|
|
46
|
+
position: relative;
|
|
47
|
+
|
|
48
|
+
&::after {
|
|
49
|
+
content: ' ';
|
|
50
|
+
display: block;
|
|
51
|
+
background-color: inherit;
|
|
52
|
+
opacity: 0.5;
|
|
53
|
+
border-radius: inherit;
|
|
54
|
+
|
|
55
|
+
position: absolute;
|
|
56
|
+
top: 0; right: 0; bottom: 0; left: 0;
|
|
57
|
+
z-index: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
> * {
|
|
61
|
+
z-index: 2;
|
|
62
|
+
position: relative;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
44
65
|
}
|
|
45
66
|
|
|
46
67
|
img.img {
|
|
@@ -24,7 +24,7 @@ type TMeta = {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export type Props = {
|
|
27
|
-
title:
|
|
27
|
+
title: ComponentChild,
|
|
28
28
|
link?: string,
|
|
29
29
|
cover?: {
|
|
30
30
|
color?: string,
|
|
@@ -32,14 +32,15 @@ export type Props = {
|
|
|
32
32
|
title?: string,
|
|
33
33
|
logo?: ComponentChild
|
|
34
34
|
},
|
|
35
|
-
metas
|
|
35
|
+
metas?: TMeta[],
|
|
36
36
|
class?: string,
|
|
37
|
+
footer?: ComponentChild
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/*----------------------------------
|
|
40
41
|
- COMPONENT
|
|
41
42
|
----------------------------------*/
|
|
42
|
-
export default ({ title, link, cover, metas, class: className = '' }: Props) => {
|
|
43
|
+
export default ({ title, link, cover, metas, class: className = '', footer }: Props) => {
|
|
43
44
|
|
|
44
45
|
if (link)
|
|
45
46
|
className += ' clickable';
|
|
@@ -49,8 +50,8 @@ export default ({ title, link, cover, metas, class: className = '' }: Props) =>
|
|
|
49
50
|
<article class={"card col " + className}>
|
|
50
51
|
|
|
51
52
|
{cover && (
|
|
52
|
-
<header class="bg img row al-left cover pdb-1" style={{
|
|
53
|
-
backgroundColor: cover.color,
|
|
53
|
+
<header class="bg img colorize row al-left cover pdb-1" style={{
|
|
54
|
+
backgroundColor: '#' + cover.color,
|
|
54
55
|
backgroundImage: cover.image
|
|
55
56
|
? 'url(' + cover.image + ')'
|
|
56
57
|
: undefined
|
|
@@ -87,6 +88,8 @@ export default ({ title, link, cover, metas, class: className = '' }: Props) =>
|
|
|
87
88
|
))}
|
|
88
89
|
</ul>
|
|
89
90
|
)}
|
|
91
|
+
|
|
92
|
+
{footer}
|
|
90
93
|
|
|
91
94
|
</article>
|
|
92
95
|
)
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
&,
|
|
15
15
|
> .modal {
|
|
16
|
-
position:
|
|
16
|
+
position: fixed;
|
|
17
17
|
top: 0px;
|
|
18
18
|
left: 0px;
|
|
19
19
|
right: 0px;
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
gap: @spacing;
|
|
83
83
|
z-index: @modal-zindex;
|
|
84
84
|
|
|
85
|
-
background: fade(#
|
|
86
|
-
backdrop-filter: blur(
|
|
85
|
+
background: fade(#fff, 20%);
|
|
86
|
+
backdrop-filter: blur(30px) saturate(2);
|
|
87
87
|
border-radius: @radius;
|
|
88
88
|
|
|
89
89
|
// Desktop = vertically center the modal
|
|
@@ -17,18 +17,24 @@ import './index.less';
|
|
|
17
17
|
----------------------------------*/
|
|
18
18
|
|
|
19
19
|
export type Props = {
|
|
20
|
-
children: ComponentChild
|
|
20
|
+
children: ComponentChild,
|
|
21
|
+
elevator?: React.HTMLAttributes<HTMLDivElement>
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/*----------------------------------
|
|
24
25
|
- COMPONENT
|
|
25
26
|
----------------------------------*/
|
|
26
|
-
export default ({
|
|
27
|
+
export default ({ children, elevator = {} }: Props) => {
|
|
27
28
|
|
|
28
29
|
const containerRef = React.useRef<HTMLDivElement>();
|
|
29
|
-
const [
|
|
30
|
+
const [containerHeight, setContainerHeight] = React.useState<number>(undefined);
|
|
31
|
+
const [scroll, setScroll] = React.useState({
|
|
32
|
+
pos: 0,
|
|
33
|
+
left: false,
|
|
34
|
+
right: true
|
|
35
|
+
});
|
|
30
36
|
|
|
31
|
-
const moveTo = (
|
|
37
|
+
const moveTo = (direction: number) => {
|
|
32
38
|
|
|
33
39
|
const container = containerRef.current;
|
|
34
40
|
if (container === null)
|
|
@@ -41,25 +47,53 @@ export default ({ children }: Props) => {
|
|
|
41
47
|
const containerWidth = container.getBoundingClientRect().width;
|
|
42
48
|
const rowWidth = row.getBoundingClientRect().width;
|
|
43
49
|
|
|
44
|
-
|
|
50
|
+
setScroll( curPos => {
|
|
51
|
+
|
|
52
|
+
const newPos = {
|
|
53
|
+
pos: curPos.pos + (-1 * direction * containerWidth),
|
|
54
|
+
left: true,
|
|
55
|
+
right: true
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Scroll Left limit
|
|
59
|
+
const leftPosLim = 0 - rowWidth + containerWidth;
|
|
60
|
+
if (newPos.pos < leftPosLim) {
|
|
61
|
+
newPos.pos = leftPosLim;
|
|
62
|
+
newPos.right = false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Scroll Left limit
|
|
66
|
+
if (newPos.pos > 0) {
|
|
67
|
+
newPos.pos = 0;
|
|
68
|
+
newPos.left = false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return newPos;
|
|
72
|
+
});
|
|
45
73
|
|
|
46
74
|
}
|
|
47
75
|
|
|
48
76
|
React.useEffect(() => {
|
|
49
77
|
|
|
50
78
|
// If row oveflow, show horizontal arroxs
|
|
51
|
-
|
|
52
|
-
|
|
79
|
+
setContainerHeight( containerRef.current.getBoundingClientRect().height );
|
|
53
80
|
|
|
54
81
|
}, []);
|
|
55
82
|
|
|
56
83
|
return (
|
|
57
|
-
<div class="scrollable-row stopLeft
|
|
84
|
+
<div class={"scrollable-row" + (scroll.left ? '' : ' stopLeft') + (scroll.right ? '' : ' stopRight')}>
|
|
58
85
|
|
|
59
86
|
<Button class="left" shape="pill" icon="arrow-left" onClick={() => moveTo(-1)} />
|
|
60
87
|
|
|
61
|
-
<div class="container" ref={containerRef}
|
|
62
|
-
|
|
88
|
+
<div class="container" ref={containerRef} style={{
|
|
89
|
+
height: containerHeight ? containerHeight + 'px' : undefined
|
|
90
|
+
}}>
|
|
91
|
+
<div {...elevator} class={"row " + (elevator.class || '')} style={{
|
|
92
|
+
left: scroll.pos + 'px',
|
|
93
|
+
position: containerHeight === undefined
|
|
94
|
+
? 'relative'
|
|
95
|
+
: 'absolute'
|
|
96
|
+
}}>
|
|
63
97
|
{children}
|
|
64
98
|
</div>
|
|
65
99
|
</div>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
.video {
|
|
2
|
+
.build-theme-bg(#000, #fff);
|
|
3
|
+
|
|
4
|
+
position: relative;
|
|
5
|
+
text-shadow: 0 0 10px fade(#000, 20%);
|
|
6
|
+
border-radius: @radius;
|
|
7
|
+
|
|
8
|
+
--cTxtDiscret: fade(#fff, 40%)
|
|
9
|
+
--cTxtDesc: fade(#fff, 60%);
|
|
10
|
+
--cTxtBase: fade(#fff, 80%);
|
|
11
|
+
--cTxtImportant: fade(#fff, 100%);
|
|
12
|
+
--cTxtAccent: fade(#fff, 20%);
|
|
13
|
+
|
|
14
|
+
&.light {
|
|
15
|
+
--cTxtDiscret: fade(#000, 40%)
|
|
16
|
+
--cTxtDesc: fade(#000, 60%);
|
|
17
|
+
--cTxtBase: fade(#000, 80%);
|
|
18
|
+
--cTxtImportant: fade(#000, 100%);
|
|
19
|
+
--cTxtAccent: fade(#000, 20%);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
> img.preview,
|
|
23
|
+
> .actions {
|
|
24
|
+
position: absolute;
|
|
25
|
+
top: 0;
|
|
26
|
+
left: 0;
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
border-radius: inherit;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
> img.preview {
|
|
33
|
+
object-fit: cover;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
> .actions {
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPS
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
// Core
|
|
10
|
+
import Button from '../button';
|
|
11
|
+
|
|
12
|
+
/*----------------------------------
|
|
13
|
+
- TYPES
|
|
14
|
+
----------------------------------*/
|
|
15
|
+
|
|
16
|
+
export type Config = {
|
|
17
|
+
src: string,
|
|
18
|
+
previewImg: string,
|
|
19
|
+
color?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*----------------------------------
|
|
23
|
+
- COMPONENT
|
|
24
|
+
----------------------------------*/
|
|
25
|
+
export default ({ src, previewImg, color = '000000' }: Config) => {
|
|
26
|
+
|
|
27
|
+
/*----------------------------------
|
|
28
|
+
- INIT
|
|
29
|
+
----------------------------------*/
|
|
30
|
+
|
|
31
|
+
const [state, setState] = React.useState<'inactive'|'loading'|'paused'|'playing'>('inactive');
|
|
32
|
+
|
|
33
|
+
/*----------------------------------
|
|
34
|
+
- ACTIONS
|
|
35
|
+
----------------------------------*/
|
|
36
|
+
|
|
37
|
+
const play = () => {
|
|
38
|
+
setState('loading');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const VideoPlayer = 'video';
|
|
42
|
+
|
|
43
|
+
/*----------------------------------
|
|
44
|
+
- RENDER
|
|
45
|
+
----------------------------------*/
|
|
46
|
+
return (
|
|
47
|
+
<section class={"video h-4 " + state}>
|
|
48
|
+
|
|
49
|
+
{(state === 'inactive' || state === 'loading') ? (
|
|
50
|
+
<img class="preview" src={previewImg} />
|
|
51
|
+
) : (
|
|
52
|
+
<VideoPlayer src={src} />
|
|
53
|
+
)}
|
|
54
|
+
|
|
55
|
+
<div class="actions col al-center" style={{
|
|
56
|
+
backgroundColor: '#' + color + 'aa'
|
|
57
|
+
}}>
|
|
58
|
+
{(state === 'inactive' || state === 'paused') ? (
|
|
59
|
+
<Button icon="play" shape="pill" onClick={play} />
|
|
60
|
+
) : state === 'loading' ? (
|
|
61
|
+
<i src="spin" />
|
|
62
|
+
) : state === 'playing' ? (
|
|
63
|
+
<Button icon="pause" shape="pill" onClick={play} />
|
|
64
|
+
) : null}
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
</section>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
@@ -154,12 +154,12 @@ export default (props: Props) => {
|
|
|
154
154
|
? bouton([menu.data], [menu.index])
|
|
155
155
|
: bouton(menu.data, menu.index)
|
|
156
156
|
) : {})}
|
|
157
|
-
|
|
157
|
+
icon={icone}
|
|
158
158
|
onClick={onClick && (() => multi
|
|
159
159
|
? onClick([menu.data], [menu.index])
|
|
160
160
|
: onClick(menu.data, menu.index)
|
|
161
161
|
)}
|
|
162
|
-
|
|
162
|
+
link={lien && lien(menu.data, menu.index)}
|
|
163
163
|
forme="lien"
|
|
164
164
|
>
|
|
165
165
|
{label}
|
|
@@ -22,7 +22,7 @@ import { timeSince } from '@common/data/dates';
|
|
|
22
22
|
- COMPOSANT
|
|
23
23
|
----------------------------------*/
|
|
24
24
|
export default ({ since }: {
|
|
25
|
-
since:
|
|
25
|
+
since: Parameters<typeof timeSince>[0]
|
|
26
26
|
}) => {
|
|
27
27
|
|
|
28
28
|
const [text, setDisplay] = React.useState(timeSince(since));
|
|
@@ -1,18 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
export { Link } from '../services/router/components/Link';
|
|
1
3
|
export { default as Button } from './button';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
// Containers
|
|
6
|
+
export { default as Card } from './Card';
|
|
7
|
+
export { default as Popover } from './containers/Popover';
|
|
4
8
|
export { default as Table } from './Table';
|
|
5
|
-
export { default as
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
export { default as Row } from './Row';
|
|
10
|
+
|
|
11
|
+
// Media
|
|
12
|
+
export { default as Logo } from './logo';
|
|
13
|
+
export { default as Video } from './Video';
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
export { default as Textarea } from './input/Textarea';
|
|
15
|
+
// Input
|
|
11
16
|
export { default as Number } from './input/Number';
|
|
12
17
|
export { default as Slider } from './input/Slider';
|
|
13
|
-
export { default as Upload } from './input/Upload';
|
|
14
18
|
export { default as Radio } from './input/Radio';
|
|
15
19
|
|
|
20
|
+
// Data
|
|
21
|
+
export { default as Amount } from './Amount';
|
|
22
|
+
export { default as Time } from './data/Time';
|
|
23
|
+
export { default as SpinText } from './data/spintext';
|
|
24
|
+
export { default as Progressbar } from './data/progressbar';
|
|
25
|
+
export { default as CircularProgressbar } from './data/progressbar/circular';
|
|
26
|
+
|
|
27
|
+
// Input V3
|
|
28
|
+
export { default as Select } from './Select';
|
|
29
|
+
export { default as String } from './inputv3/string';
|
|
30
|
+
export { default as File } from './inputv3/file';
|
|
31
|
+
|
|
16
32
|
// TOD: fix popover component
|
|
17
33
|
//export { default as Date } from './input/Date';
|
|
18
34
|
//export { default as Periode } from './input/Periode';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
// Core libs
|
|
10
|
+
import { useState } from '@client/hooks';
|
|
11
|
+
|
|
12
|
+
/*----------------------------------
|
|
13
|
+
- TYPES
|
|
14
|
+
----------------------------------*/
|
|
15
|
+
|
|
16
|
+
export type InputBaseProps<TValue> = {
|
|
17
|
+
value: TValue,
|
|
18
|
+
title: string, // Now mandatory
|
|
19
|
+
onChange?: (newValue: TValue) => void,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type TInputState<TValue> = {
|
|
23
|
+
value: TValue,
|
|
24
|
+
fieldProps: {[key: string]: any},
|
|
25
|
+
valueSource: 'internal'|'external',
|
|
26
|
+
focus: boolean,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*----------------------------------
|
|
30
|
+
- HOOKS
|
|
31
|
+
----------------------------------*/
|
|
32
|
+
export function useInput<TValue>(
|
|
33
|
+
{ value: externalValue, onChange }: InputBaseProps<TValue>,
|
|
34
|
+
defaultValue: TValue,
|
|
35
|
+
): [
|
|
36
|
+
state: TInputState<TValue>,
|
|
37
|
+
setValue: (value: TValue) => void,
|
|
38
|
+
commitValue: () => void,
|
|
39
|
+
setState: (state: Partial<TInputState<TValue>>) => void,
|
|
40
|
+
] {
|
|
41
|
+
|
|
42
|
+
const [state, setState] = useState<TInputState<TValue>>({
|
|
43
|
+
value: externalValue !== undefined ? externalValue : defaultValue,
|
|
44
|
+
valueSource: 'external',
|
|
45
|
+
fieldProps: {},
|
|
46
|
+
focus: false
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const setValue = (value: TValue) => setState({ value, valueSource: 'internal' });
|
|
50
|
+
|
|
51
|
+
const commitValue = () => {
|
|
52
|
+
console.log(`[input] Commit value:`, state.value);
|
|
53
|
+
if (onChange !== undefined)
|
|
54
|
+
onChange(state.value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// External value change
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
|
|
60
|
+
if (externalValue !== undefined && externalValue !== state.value) {
|
|
61
|
+
console.log("External value change", externalValue);
|
|
62
|
+
setState({ value: externalValue, valueSource: 'external' })
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}, [externalValue]);
|
|
66
|
+
|
|
67
|
+
return [state, setValue, commitValue, setState]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/*----------------------------------
|
|
71
|
+
- COMPONENT
|
|
72
|
+
----------------------------------*/
|
|
73
|
+
import './base.less';
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Normalize file between browser and nodejs side
|
|
2
|
+
export default class FileToUpload {
|
|
3
|
+
|
|
4
|
+
public name: string;
|
|
5
|
+
public size: number;
|
|
6
|
+
public type: string;
|
|
7
|
+
|
|
8
|
+
public data: File;
|
|
9
|
+
|
|
10
|
+
// Retrieved on backend only
|
|
11
|
+
public md5?: string;
|
|
12
|
+
public ext?: string;
|
|
13
|
+
|
|
14
|
+
public constructor(opts: {
|
|
15
|
+
name: string,
|
|
16
|
+
size: number,
|
|
17
|
+
type: string,
|
|
18
|
+
|
|
19
|
+
data: File,
|
|
20
|
+
|
|
21
|
+
md5?: string,
|
|
22
|
+
ext?: string,
|
|
23
|
+
}) {
|
|
24
|
+
|
|
25
|
+
this.name = opts.name;
|
|
26
|
+
this.size = opts.size;
|
|
27
|
+
this.type = opts.type;
|
|
28
|
+
|
|
29
|
+
this.data = opts.data;
|
|
30
|
+
|
|
31
|
+
this.md5 = opts.md5;
|
|
32
|
+
this.ext = opts.ext;
|
|
33
|
+
}
|
|
34
|
+
}
|