proteum 1.0.0 → 1.0.2
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/cli/app/config.ts +54 -0
- package/cli/app/index.ts +195 -0
- package/cli/bin.js +35 -0
- package/cli/commands/build.ts +34 -0
- package/cli/commands/deploy/app.ts +29 -0
- package/cli/commands/deploy/web.ts +60 -0
- package/cli/commands/dev.ts +109 -0
- package/cli/commands/init.ts +85 -0
- package/cli/compiler/client/identite.ts +72 -0
- package/cli/compiler/client/index.ts +335 -0
- package/cli/compiler/common/babel/index.ts +170 -0
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +586 -0
- package/cli/compiler/common/babel/routes/imports.ts +127 -0
- package/cli/compiler/common/babel/routes/routes.ts +1130 -0
- package/cli/compiler/common/files/autres.ts +39 -0
- package/cli/compiler/common/files/images.ts +42 -0
- package/cli/compiler/common/files/style.ts +80 -0
- package/cli/compiler/common/index.ts +160 -0
- package/cli/compiler/index.ts +564 -0
- package/cli/compiler/server/index.ts +211 -0
- package/cli/index.ts +189 -0
- package/cli/paths.ts +165 -0
- package/cli/print.ts +12 -0
- package/cli/tsconfig.json +42 -0
- package/cli/utils/index.ts +22 -0
- package/cli/utils/keyboard.ts +78 -0
- package/client/app/index.ts +2 -0
- package/client/components/Dialog/Manager.tsx +3 -49
- package/client/components/Dialog/index.less +3 -1
- package/client/components/index.ts +1 -2
- package/client/services/router/index.tsx +6 -16
- package/common/errors/index.tsx +12 -31
- package/doc/TODO.md +1 -1
- package/package.json +58 -20
- package/server/app/container/console/index.ts +1 -1
- package/server/services/auth/index.ts +62 -27
- package/server/services/auth/router/request.ts +17 -6
- package/server/services/router/http/index.ts +1 -1
- package/server/services/router/response/index.ts +1 -1
- package/server/services/schema/request.ts +28 -10
- package/tsconfig.common.json +2 -1
- package/changelog.md +0 -5
- package/client/components/Button.tsx +0 -298
- package/client/components/Dialog/card.tsx +0 -208
- package/client/data/input.ts +0 -32
- package/client/pages/bug.tsx.old +0 -60
- package/templates/composant.tsx +0 -40
- package/templates/form.ts +0 -30
- package/templates/modal.tsx +0 -47
- package/templates/modele.ts +0 -56
- package/templates/page.tsx +0 -74
- package/templates/route.ts +0 -43
- package/templates/service.ts +0 -75
- package/vscode/copyimportationpath/.eslintrc.json +0 -24
- package/vscode/copyimportationpath/.vscodeignore +0 -12
- package/vscode/copyimportationpath/CHANGELOG.md +0 -9
- package/vscode/copyimportationpath/README.md +0 -3
- package/vscode/copyimportationpath/copyimportationpath-0.0.1.vsix +0 -0
- package/vscode/copyimportationpath/out/extension.js +0 -206
- package/vscode/copyimportationpath/out/extension.js.map +0 -1
- package/vscode/copyimportationpath/package-lock.json +0 -4536
- package/vscode/copyimportationpath/package.json +0 -86
- package/vscode/copyimportationpath/src/extension.ts +0 -300
- package/vscode/copyimportationpath/tsconfig.json +0 -22
- package/vscode/copyimportationpath/vsc-extension-quickstart.md +0 -42
|
@@ -8,7 +8,6 @@ import jwt from 'jsonwebtoken';
|
|
|
8
8
|
// Core
|
|
9
9
|
import type { default as Router, Request as ServerRequest, TAnyRouter } from '@server/services/router';
|
|
10
10
|
import RequestService from '@server/services/router/request/service';
|
|
11
|
-
import { InputError, AuthRequired, Forbidden } from '@common/errors';
|
|
12
11
|
|
|
13
12
|
// Specific
|
|
14
13
|
import type AuthenticationRouterService from '.';
|
|
@@ -45,10 +44,22 @@ export default class UsersRequestService<
|
|
|
45
44
|
return this.users.logout( this.request );
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
public check(): TUser;
|
|
48
|
+
|
|
48
49
|
// TODO: return user type according to entity
|
|
49
|
-
public check(role: TUserRole,
|
|
50
|
-
|
|
51
|
-
public check(role:
|
|
52
|
-
|
|
50
|
+
public check(role: TUserRole, feature: null): TUser;
|
|
51
|
+
|
|
52
|
+
public check(role: false): null;
|
|
53
|
+
|
|
54
|
+
public check(role: TUserRole, feature: FeatureKeys, action?: string): TUser;
|
|
55
|
+
|
|
56
|
+
public check(role: false, feature: FeatureKeys, action?: string): null;
|
|
57
|
+
|
|
58
|
+
public check(
|
|
59
|
+
role: TUserRole | false = 'USER',
|
|
60
|
+
feature?: FeatureKeys | null,
|
|
61
|
+
action?: string
|
|
62
|
+
) {
|
|
63
|
+
return this.users.check( this.request, role, feature, action ) as any;
|
|
53
64
|
}
|
|
54
|
-
}
|
|
65
|
+
}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
6
|
import zod from 'zod';
|
|
7
|
-
import { SomeType } from 'zod/v4/core';
|
|
8
7
|
|
|
9
8
|
// Core
|
|
10
9
|
import {
|
|
@@ -24,6 +23,18 @@ export type TConfig = {
|
|
|
24
23
|
debug?: boolean
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
type TValidationSchema = zod.ZodTypeAny;
|
|
27
|
+
type TValidationShape = zod.ZodRawShape;
|
|
28
|
+
|
|
29
|
+
const isZodSchema = (fields: unknown): fields is TValidationSchema => {
|
|
30
|
+
return (
|
|
31
|
+
typeof fields === 'object'
|
|
32
|
+
&& fields !== null
|
|
33
|
+
&& 'safeParse' in fields
|
|
34
|
+
&& typeof (fields as TValidationSchema).safeParse === 'function'
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
/*----------------------------------
|
|
28
39
|
- SERVICE
|
|
29
40
|
----------------------------------*/
|
|
@@ -32,18 +43,25 @@ export default(
|
|
|
32
43
|
config: TConfig,
|
|
33
44
|
router = request.router,
|
|
34
45
|
app = router.app
|
|
35
|
-
) =>
|
|
36
|
-
|
|
37
|
-
...schema,
|
|
46
|
+
) => {
|
|
38
47
|
|
|
39
|
-
validate( fields:
|
|
48
|
+
function validate<TSchema extends TValidationSchema>( fields: TSchema ): zod.output<TSchema>;
|
|
49
|
+
function validate<TShape extends TValidationShape>( fields: TShape ): zod.output<zod.ZodObject<TShape>>;
|
|
50
|
+
function validate( fields: TValidationSchema | TValidationShape ) {
|
|
40
51
|
|
|
41
52
|
config.debug && console.log(LogPrefix, "Validate request data:", request.data);
|
|
42
53
|
|
|
43
|
-
const
|
|
54
|
+
const validationSchema = isZodSchema(fields) ? fields : zod.object(fields);
|
|
44
55
|
|
|
45
|
-
const preprocessedSchema = preprocessSchema(
|
|
56
|
+
//const preprocessedSchema = preprocessSchema(validationSchema);
|
|
46
57
|
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
58
|
+
return validationSchema.parse(request.data);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
|
|
63
|
+
...schema,
|
|
64
|
+
|
|
65
|
+
validate,
|
|
66
|
+
}
|
|
67
|
+
}
|
package/tsconfig.common.json
CHANGED
package/changelog.md
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Npm
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { VNode, RefObject,ComponentChild } from 'preact';
|
|
8
|
-
|
|
9
|
-
// Core
|
|
10
|
-
import { shouldOpenNewTab } from '@client/services/router/components/Link';
|
|
11
|
-
import { history } from '@client/services/router/request/history';
|
|
12
|
-
import useContext from '@/client/context';
|
|
13
|
-
|
|
14
|
-
/*----------------------------------
|
|
15
|
-
- TYPES
|
|
16
|
-
----------------------------------*/
|
|
17
|
-
|
|
18
|
-
export type Props = {
|
|
19
|
-
|
|
20
|
-
id?: string,
|
|
21
|
-
refElem?: RefObject<HTMLElement>,
|
|
22
|
-
|
|
23
|
-
icon?: ComponentChild,
|
|
24
|
-
iconR?: ComponentChild,
|
|
25
|
-
|
|
26
|
-
prefix?: ComponentChild,
|
|
27
|
-
suffix?: ComponentChild,
|
|
28
|
-
|
|
29
|
-
tag?: "a" | "button",
|
|
30
|
-
type?: 'guide' | 'primary' | 'secondary' | 'link',
|
|
31
|
-
shape?: 'default' | 'icon' | 'tile' | 'pill' | 'custom',
|
|
32
|
-
size?: TComponentSize,
|
|
33
|
-
class?: string,
|
|
34
|
-
|
|
35
|
-
state?: [string, React.StateUpdater<string>],
|
|
36
|
-
active?: boolean,
|
|
37
|
-
selected?: boolean,
|
|
38
|
-
disabled?: boolean,
|
|
39
|
-
loading?: boolean,
|
|
40
|
-
autoFocus?: boolean,
|
|
41
|
-
onClick?: (e: MouseEvent) => any,
|
|
42
|
-
async?: boolean,
|
|
43
|
-
|
|
44
|
-
submenu?: ComponentChild,
|
|
45
|
-
nav?: boolean | 'exact'
|
|
46
|
-
|
|
47
|
-
// SEO: if icon only, should provinde a hint (aria-label)
|
|
48
|
-
} & ({
|
|
49
|
-
hint: string,
|
|
50
|
-
children?: ComponentChild | ComponentChild[],
|
|
51
|
-
} | {
|
|
52
|
-
children: ComponentChild | ComponentChild[],
|
|
53
|
-
hint?: string,
|
|
54
|
-
}) & (TButtonProps | TLinkProps)
|
|
55
|
-
|
|
56
|
-
export type TButtonProps = React.JSX.HTMLAttributes<HTMLButtonElement>
|
|
57
|
-
|
|
58
|
-
export type TLinkProps = React.JSX.HTMLAttributes<HTMLAnchorElement>
|
|
59
|
-
|
|
60
|
-
/*----------------------------------
|
|
61
|
-
- HELPERS
|
|
62
|
-
----------------------------------*/
|
|
63
|
-
const trimSlash = (str: string): string => {
|
|
64
|
-
return str.endsWith('/') ? str.slice(0, -1) : str;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const isCurrentUrl = (currentUrl: string, url: string, exact?: boolean) => {
|
|
68
|
-
return (
|
|
69
|
-
(exact && (url === currentUrl || trimSlash(url) === currentUrl))
|
|
70
|
-
||
|
|
71
|
-
(!exact && currentUrl.startsWith(url))
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/*----------------------------------
|
|
76
|
-
- CONTROLEUR
|
|
77
|
-
----------------------------------*/
|
|
78
|
-
export default ({
|
|
79
|
-
|
|
80
|
-
id,
|
|
81
|
-
|
|
82
|
-
// Content
|
|
83
|
-
icon, prefix,
|
|
84
|
-
children,
|
|
85
|
-
iconR, suffix,
|
|
86
|
-
submenu,
|
|
87
|
-
nav,
|
|
88
|
-
hint,
|
|
89
|
-
|
|
90
|
-
// Style
|
|
91
|
-
class: className,
|
|
92
|
-
shape,
|
|
93
|
-
size,
|
|
94
|
-
type,
|
|
95
|
-
|
|
96
|
-
// Interactions
|
|
97
|
-
active,
|
|
98
|
-
selected,
|
|
99
|
-
state: stateUpdater,
|
|
100
|
-
disabled,
|
|
101
|
-
loading,
|
|
102
|
-
//autoFocus,
|
|
103
|
-
async,
|
|
104
|
-
|
|
105
|
-
// HTML attributes
|
|
106
|
-
tag: Tag,
|
|
107
|
-
refElem,
|
|
108
|
-
...props
|
|
109
|
-
|
|
110
|
-
}: Props) => {
|
|
111
|
-
|
|
112
|
-
const ctx = useContext();
|
|
113
|
-
let [isSelected, setIsSelected] = React.useState(false);
|
|
114
|
-
let [isActive, setIsActive] = React.useState(false);
|
|
115
|
-
const [isLoading, setLoading] = React.useState(false);
|
|
116
|
-
|
|
117
|
-
if (isLoading || loading) {
|
|
118
|
-
icon = <i src="spin" />
|
|
119
|
-
iconR = undefined;
|
|
120
|
-
disabled = true;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (stateUpdater && id !== undefined) {
|
|
124
|
-
const [active, setActive] = stateUpdater;
|
|
125
|
-
if (id === active)
|
|
126
|
-
isSelected = true;
|
|
127
|
-
props.onClick = () => setActive(id);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Hint
|
|
131
|
-
if (hint !== undefined) {
|
|
132
|
-
props['aria-label'] = hint;
|
|
133
|
-
props.title = hint;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Shape classes
|
|
137
|
-
const classNames: string[] = ['btn'];
|
|
138
|
-
if (className)
|
|
139
|
-
classNames.push(className);
|
|
140
|
-
|
|
141
|
-
if (shape !== undefined) {
|
|
142
|
-
if (shape === 'tile')
|
|
143
|
-
classNames.push('col');
|
|
144
|
-
else
|
|
145
|
-
classNames.push(shape);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (size !== undefined)
|
|
149
|
-
classNames.push(size);
|
|
150
|
-
|
|
151
|
-
if (icon) {
|
|
152
|
-
if (children === undefined)
|
|
153
|
-
classNames.push('icon');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// state classes
|
|
157
|
-
const [isMouseDown, setMouseDown] = React.useState(false);
|
|
158
|
-
props.onMouseDown = () => setMouseDown(true);
|
|
159
|
-
props.onMouseUp = () => setMouseDown(false);
|
|
160
|
-
props.onMouseLeave = () => setMouseDown(false);
|
|
161
|
-
|
|
162
|
-
// Theming & state
|
|
163
|
-
if (isMouseDown)
|
|
164
|
-
classNames.push('pressed');
|
|
165
|
-
else if (selected || isSelected === true)
|
|
166
|
-
classNames.push('bg accent');
|
|
167
|
-
else if (type !== undefined)
|
|
168
|
-
classNames.push(type === 'link' ? type : (' bg ' + type));
|
|
169
|
-
|
|
170
|
-
if (active || isActive === true)
|
|
171
|
-
classNames.push('active');
|
|
172
|
-
|
|
173
|
-
// Icon
|
|
174
|
-
if (prefix === undefined && icon !== undefined)
|
|
175
|
-
prefix = typeof icon === "string" ? <i class={"svg-" + icon} /> : icon;
|
|
176
|
-
if (suffix === undefined && iconR !== undefined)
|
|
177
|
-
suffix = typeof iconR === "string" ? <i class={"svg-" + iconR} /> : iconR;
|
|
178
|
-
|
|
179
|
-
// Render
|
|
180
|
-
if ('link' in props || Tag === "a") {
|
|
181
|
-
|
|
182
|
-
// Link (only if enabled)
|
|
183
|
-
if (!disabled) {
|
|
184
|
-
|
|
185
|
-
props.href = props.link;
|
|
186
|
-
|
|
187
|
-
// External = open in new tab by default
|
|
188
|
-
if (shouldOpenNewTab( props.href, props.target ))
|
|
189
|
-
props.target = '_blank';
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Nav
|
|
193
|
-
if (nav && props.target === undefined) {
|
|
194
|
-
|
|
195
|
-
const checkIfCurrentUrl = (url: string) =>
|
|
196
|
-
isCurrentUrl(url, props.link, nav === 'exact');
|
|
197
|
-
|
|
198
|
-
React.useEffect(() => {
|
|
199
|
-
|
|
200
|
-
// Init
|
|
201
|
-
if (checkIfCurrentUrl(ctx.request.path))
|
|
202
|
-
setIsActive(true);
|
|
203
|
-
|
|
204
|
-
// On location change
|
|
205
|
-
return history?.listen(({ location }) => {
|
|
206
|
-
|
|
207
|
-
setIsActive( checkIfCurrentUrl(location.pathname) );
|
|
208
|
-
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
}, []);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
Tag = 'a';
|
|
215
|
-
|
|
216
|
-
} else {
|
|
217
|
-
Tag = 'button';
|
|
218
|
-
|
|
219
|
-
// Avoid to trigget onclick when presing enter
|
|
220
|
-
if (type !== 'primary')
|
|
221
|
-
props.type = 'button';
|
|
222
|
-
else
|
|
223
|
-
props.type = 'submit';
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
let render: VNode = (
|
|
227
|
-
<Tag {...props} id={id} class={classNames.join(' ')} disabled={disabled} ref={refElem} onClick={(e: MouseEvent) => {
|
|
228
|
-
|
|
229
|
-
// annulation si:
|
|
230
|
-
// - Pas clic gauche
|
|
231
|
-
// - Event annulé
|
|
232
|
-
if (e.button !== 0)
|
|
233
|
-
return;
|
|
234
|
-
|
|
235
|
-
// Disabled
|
|
236
|
-
if (disabled)
|
|
237
|
-
return false;
|
|
238
|
-
|
|
239
|
-
// Custom event
|
|
240
|
-
if (props.onClick !== undefined) {
|
|
241
|
-
|
|
242
|
-
const returned = props.onClick(e);
|
|
243
|
-
if (async && returned?.then) {
|
|
244
|
-
setLoading(true);
|
|
245
|
-
returned.finally(() => setLoading(false));
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Link
|
|
250
|
-
let nativeEvent: boolean = false;
|
|
251
|
-
if (('link' in props) && !e.defaultPrevented) {
|
|
252
|
-
|
|
253
|
-
// Nouvelle fenetre = event par defaut
|
|
254
|
-
if (props.target === '_blank') {
|
|
255
|
-
|
|
256
|
-
nativeEvent = true;
|
|
257
|
-
|
|
258
|
-
// Page change = loading indicator
|
|
259
|
-
} else if (props.target === "_self") {
|
|
260
|
-
|
|
261
|
-
setLoading(true);
|
|
262
|
-
window.location.href = props.link;
|
|
263
|
-
|
|
264
|
-
} else {
|
|
265
|
-
|
|
266
|
-
history?.push(props.link);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!nativeEvent) {
|
|
271
|
-
e.preventDefault();
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
}}>
|
|
275
|
-
{prefix}
|
|
276
|
-
{children === undefined
|
|
277
|
-
? null
|
|
278
|
-
: shape === 'custom'
|
|
279
|
-
? children : (
|
|
280
|
-
<span class={"label"}>
|
|
281
|
-
{children}
|
|
282
|
-
</span>
|
|
283
|
-
)}
|
|
284
|
-
{suffix}
|
|
285
|
-
</Tag>
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
if (Tag === "li" || submenu) {
|
|
289
|
-
render = (
|
|
290
|
-
<li>
|
|
291
|
-
{render}
|
|
292
|
-
{submenu}
|
|
293
|
-
</li>
|
|
294
|
-
)
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
return render;
|
|
298
|
-
}
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Npm
|
|
6
|
-
import React from 'react';
|
|
7
|
-
|
|
8
|
-
// Composants globaux
|
|
9
|
-
import Button from '@client/components/Button';
|
|
10
|
-
|
|
11
|
-
/*----------------------------------
|
|
12
|
-
- TYPES
|
|
13
|
-
----------------------------------*/
|
|
14
|
-
import { ComponentChild } from 'preact';
|
|
15
|
-
|
|
16
|
-
type funcBtns = () => void
|
|
17
|
-
|
|
18
|
-
type Boutons = { [label: string]: funcBtns }
|
|
19
|
-
|
|
20
|
-
/*----------------------------------
|
|
21
|
-
- CONTENU
|
|
22
|
-
----------------------------------*/
|
|
23
|
-
export type Props = {
|
|
24
|
-
|
|
25
|
-
// Informations modale
|
|
26
|
-
type?: 'primary' | 'success' | 'warning' | 'error' | 'loading' | 'info',
|
|
27
|
-
cover?: string,
|
|
28
|
-
icon?: ComponentChild,
|
|
29
|
-
title?: string | ComponentChild,
|
|
30
|
-
className?: string,
|
|
31
|
-
|
|
32
|
-
children?: ComponentChild,
|
|
33
|
-
isToast?: boolean,
|
|
34
|
-
width?: number,
|
|
35
|
-
|
|
36
|
-
footer?: ComponentChild,
|
|
37
|
-
boutons?: Boutons | null, // nul = pas de footer
|
|
38
|
-
defaultBtn?: string,
|
|
39
|
-
|
|
40
|
-
prison?: boolean,
|
|
41
|
-
/* Hide after x seconds */autohide?: number | false,
|
|
42
|
-
close?: funcBtns,
|
|
43
|
-
onClose?: () => Promise<any>,
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default ({
|
|
47
|
-
|
|
48
|
-
// Content
|
|
49
|
-
type,
|
|
50
|
-
cover,
|
|
51
|
-
icon,
|
|
52
|
-
title,
|
|
53
|
-
className = '',
|
|
54
|
-
|
|
55
|
-
children,
|
|
56
|
-
isToast,
|
|
57
|
-
width,
|
|
58
|
-
|
|
59
|
-
footer,
|
|
60
|
-
boutons,
|
|
61
|
-
defaultBtn,
|
|
62
|
-
|
|
63
|
-
onClose,
|
|
64
|
-
close,
|
|
65
|
-
autohide,
|
|
66
|
-
prison,
|
|
67
|
-
|
|
68
|
-
}: Props) => {
|
|
69
|
-
|
|
70
|
-
// Boutons
|
|
71
|
-
if (footer === undefined && boutons !== null) {
|
|
72
|
-
|
|
73
|
-
// Default buttons
|
|
74
|
-
if (boutons === undefined || !Object.keys(boutons).length) {
|
|
75
|
-
|
|
76
|
-
// Toast: by default, if no buttons, we autohide after 3 seconds
|
|
77
|
-
if (autohide === undefined)
|
|
78
|
-
autohide = 3;
|
|
79
|
-
|
|
80
|
-
// If isToast, we show a default OK button
|
|
81
|
-
if (close && !isToast)
|
|
82
|
-
boutons = { 'Ok': () => close(true) };
|
|
83
|
-
else
|
|
84
|
-
boutons = null;
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (boutons !== null) {
|
|
89
|
-
|
|
90
|
-
const nbBtns = Object.keys(boutons).length;
|
|
91
|
-
|
|
92
|
-
footer = Object.entries(boutons).map(([texte, action]: [string, Function], index: number) => {
|
|
93
|
-
const dernier = nbBtns > 1 && index === nbBtns - 1;
|
|
94
|
-
return (
|
|
95
|
-
<Button
|
|
96
|
-
async
|
|
97
|
-
onClick={() => action()}
|
|
98
|
-
type={(defaultBtn === undefined ? dernier : (defaultBtn === texte)) ? 'primary' : undefined}
|
|
99
|
-
>
|
|
100
|
-
{texte}
|
|
101
|
-
</Button>
|
|
102
|
-
)
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (typeof icon === 'string')
|
|
108
|
-
icon = <i class={"svg-" + icon} />
|
|
109
|
-
else if (icon === undefined)
|
|
110
|
-
switch (type) {
|
|
111
|
-
case 'info':
|
|
112
|
-
icon = <i src="info-circle" />
|
|
113
|
-
break;
|
|
114
|
-
case 'success':
|
|
115
|
-
icon = <i src="check-circle" />
|
|
116
|
-
break;
|
|
117
|
-
case 'warning':
|
|
118
|
-
icon = <i src="exclamation-circle" />
|
|
119
|
-
break;
|
|
120
|
-
case 'error':
|
|
121
|
-
icon = <i src="times-circle" />
|
|
122
|
-
break;
|
|
123
|
-
case 'loading':
|
|
124
|
-
icon = <i src="spin" />
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Autohide
|
|
129
|
-
if (isToast)
|
|
130
|
-
React.useEffect(() => {
|
|
131
|
-
if (autohide) {
|
|
132
|
-
const timeout = setTimeout(() => close(true), autohide * 1000);
|
|
133
|
-
return () => clearTimeout(timeout);
|
|
134
|
-
}
|
|
135
|
-
}, []);
|
|
136
|
-
|
|
137
|
-
let render = isToast ? (
|
|
138
|
-
<div class="card row bg dark" onClick={() => isToast && !prison && close(true)}>
|
|
139
|
-
|
|
140
|
-
{icon}
|
|
141
|
-
|
|
142
|
-
<div>
|
|
143
|
-
|
|
144
|
-
{typeof title === "string" ? (
|
|
145
|
-
<strong>{title}</strong>
|
|
146
|
-
) : title}
|
|
147
|
-
|
|
148
|
-
{children}
|
|
149
|
-
|
|
150
|
-
</div>
|
|
151
|
-
|
|
152
|
-
</div>
|
|
153
|
-
) : (
|
|
154
|
-
<div class={"card pd-2 col al-top " + className} style={width === undefined
|
|
155
|
-
? {}
|
|
156
|
-
: { minWidth: width + "px", maxWidth: width + "px" }
|
|
157
|
-
}>
|
|
158
|
-
|
|
159
|
-
{(title || icon) && (
|
|
160
|
-
<header {...{
|
|
161
|
-
class: ('col ' + type),
|
|
162
|
-
style: cover ? {
|
|
163
|
-
backgroundImage: 'url(' + cover + ')'
|
|
164
|
-
} : undefined
|
|
165
|
-
}}>
|
|
166
|
-
|
|
167
|
-
{icon}
|
|
168
|
-
|
|
169
|
-
{typeof title === "string" ? (
|
|
170
|
-
<strong>{title}</strong>
|
|
171
|
-
) : title}
|
|
172
|
-
|
|
173
|
-
{(!prison && close) && (
|
|
174
|
-
<Button class="close" icon="times" size="s" shape="pill" onClick={async () => {
|
|
175
|
-
if (typeof close === "function") {
|
|
176
|
-
|
|
177
|
-
if (onClose !== undefined)
|
|
178
|
-
onClose(false);
|
|
179
|
-
else
|
|
180
|
-
close(false);
|
|
181
|
-
}
|
|
182
|
-
}} />
|
|
183
|
-
)}
|
|
184
|
-
|
|
185
|
-
</header>
|
|
186
|
-
)}
|
|
187
|
-
|
|
188
|
-
{children && (
|
|
189
|
-
<div class="col content">
|
|
190
|
-
|
|
191
|
-
{children}
|
|
192
|
-
|
|
193
|
-
</div>
|
|
194
|
-
)}
|
|
195
|
-
|
|
196
|
-
{footer && (
|
|
197
|
-
<footer class="row fill actions">
|
|
198
|
-
|
|
199
|
-
{footer}
|
|
200
|
-
|
|
201
|
-
</footer>
|
|
202
|
-
)}
|
|
203
|
-
|
|
204
|
-
</div>
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
return render;
|
|
208
|
-
}
|
package/client/data/input.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Libs métier
|
|
6
|
-
import buildValidators, { champ } from '@common/data/input/validators/build';
|
|
7
|
-
import { validateurFichier, TOptsValidateurFichier } from '@common/data/input/validators/basic';
|
|
8
|
-
|
|
9
|
-
/*----------------------------------
|
|
10
|
-
- VALIDATEURS
|
|
11
|
-
----------------------------------*/
|
|
12
|
-
|
|
13
|
-
export default buildValidators({
|
|
14
|
-
|
|
15
|
-
file: ({ ...opts }: TOptsValidateurFichier & {}) => champ<object>('fichier', {
|
|
16
|
-
...opts,
|
|
17
|
-
valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
|
|
18
|
-
|
|
19
|
-
console.log('VALIDER FICHIER COTÉ CLIENT', val);
|
|
20
|
-
|
|
21
|
-
// Chaine = url ancien fichier = conservation = sera ignoré coté serveur
|
|
22
|
-
if (typeof val === 'string')
|
|
23
|
-
return val;
|
|
24
|
-
|
|
25
|
-
// Validation universelle
|
|
26
|
-
val = await validateurFichier(opts, val, donneesSaisie, donneesRetour);
|
|
27
|
-
|
|
28
|
-
return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
});
|