5htp-core 0.1.2-3 → 0.2.0
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/changelog.md +5 -0
- package/doc/TODO.md +71 -0
- package/package.json +5 -4
- package/src/client/{App.tsx → app/component.tsx} +15 -8
- package/src/client/app/index.ts +128 -0
- package/src/client/app/service.ts +34 -0
- package/src/client/app.tsconfig.json +0 -4
- package/src/client/components/Card/index.tsx +1 -1
- package/src/client/components/Dialog/Manager.tsx +39 -12
- package/src/client/components/Form/index.tsx +1 -1
- package/src/client/components/button.tsx +2 -2
- package/src/client/components/containers/Popover/index.tsx +1 -1
- package/src/client/components/data/spintext/index.tsx +1 -1
- package/src/client/components/dropdown/index.tsx +1 -1
- package/src/client/components/index.ts +8 -0
- package/src/client/components/input/BaseV2/index.tsx +1 -1
- package/src/client/components/input/UploadImage/index.tsx +1 -1
- package/src/client/hooks/index.ts +5 -0
- package/src/client/hooks/useState/index.tsx +2 -2
- package/src/client/hooks.ts +22 -0
- package/src/client/index.ts +5 -0
- package/src/client/pages/_layout/landing/index.tsx +0 -2
- package/src/client/pages/_messages/400.tsx +2 -2
- package/src/client/pages/_messages/401.tsx +2 -2
- package/src/client/pages/_messages/403.tsx +2 -2
- package/src/client/pages/_messages/404.tsx +2 -2
- package/src/client/pages/_messages/500.tsx +2 -2
- package/src/client/pages/bug.tsx +1 -1
- package/src/client/pages/useHeader.tsx +1 -1
- package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
- package/src/client/services/metrics/index.ts +37 -0
- package/src/client/{router → services/router/components}/Link.tsx +1 -1
- package/src/client/services/router/components/Page.tsx +59 -0
- package/src/client/{router/component.tsx → services/router/components/router.tsx} +43 -74
- package/src/client/services/router/index.tsx +448 -0
- package/src/client/services/router/request/api.ts +229 -0
- package/src/client/{router → services/router}/request/history.ts +0 -0
- package/src/client/services/router/request/index.ts +52 -0
- package/src/client/services/router/response/index.tsx +107 -0
- package/src/client/services/router/response/page.ts +95 -0
- package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
- package/src/client/utils/dom.ts +1 -1
- package/src/common/app/index.ts +9 -0
- package/src/common/data/chaines/index.ts +9 -6
- package/src/common/data/input/validate.ts +3 -166
- package/src/common/data/objets.ts +25 -0
- package/src/common/data/tableaux.ts +8 -0
- package/src/common/errors/index.ts +3 -1
- package/src/common/router/index.ts +67 -88
- package/src/common/router/layouts.ts +50 -0
- package/src/common/router/register.ts +62 -0
- package/src/common/router/request/api.ts +72 -0
- package/src/common/router/request/index.ts +31 -0
- package/src/common/router/{response.ts → response/index.ts} +9 -13
- package/src/common/router/response/page.ts +40 -56
- package/src/common/validation/index.ts +3 -0
- package/src/common/validation/schema.ts +184 -0
- package/src/common/validation/validator.ts +88 -0
- package/src/common/validation/validators.ts +313 -0
- package/src/server/app/config.ts +8 -10
- package/src/server/app/index.ts +81 -124
- package/src/server/app/service.ts +98 -0
- package/src/server/app.tsconfig.json +0 -8
- package/src/server/error/index.ts +13 -0
- package/src/server/index.ts +5 -0
- package/src/server/patch.ts +0 -6
- package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
- package/src/server/services/console/bugReporter.ts +26 -16
- package/src/server/services/console/index.ts +50 -51
- package/src/server/services/cron/index.ts +12 -26
- package/src/server/services/database/bucket.ts +40 -0
- package/src/server/services/database/connection.ts +206 -75
- package/src/server/services/database/datatypes.ts +63 -40
- package/src/server/services/database/index.ts +295 -272
- package/src/server/services/database/metas.ts +246 -135
- package/src/server/services/database/stats.ts +151 -126
- package/src/server/services/email/index.ts +24 -54
- package/src/server/services/{router/request/services → metrics}/detect.ts +6 -10
- package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
- package/src/server/services/{http → router/http}/index.ts +19 -47
- package/src/server/services/{http → router/http}/multipart.ts +0 -0
- package/src/server/services/{http → router/http}/session.ts.old +0 -0
- package/src/server/services/router/index.ts +273 -203
- package/src/server/services/router/request/api.ts +73 -0
- package/src/server/services/router/request/index.ts +16 -95
- package/src/server/services/router/request/service.ts +21 -0
- package/src/server/services/router/response/index.ts +125 -64
- package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
- package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
- package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
- package/src/server/services/router/response/page/document.tsx +194 -0
- package/src/server/services/router/response/page/index.tsx +157 -0
- package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
- package/src/server/services/router/service.ts +48 -0
- package/src/server/services/schema/index.ts +47 -0
- package/src/server/services/schema/request.ts +55 -0
- package/src/server/services/schema/router.ts +33 -0
- package/src/server/services/socket/index.ts +38 -43
- package/src/server/services/socket/scope.ts +6 -4
- package/src/server/services/users/index.ts +203 -0
- package/src/server/services/{auth/base.ts → users/old.ts} +20 -111
- package/src/server/services/users/router/index.ts +72 -0
- package/src/server/services/users/router/request.ts +49 -0
- package/src/types/aliases.d.ts +43 -2
- package/templates/composant.tsx +1 -1
- package/templates/modal.tsx +1 -1
- package/templates/page.tsx +1 -1
- package/tsconfig.common.json +0 -4
- package/src/client/context/api.ts +0 -92
- package/src/client/context/index.ts +0 -246
- package/src/client/index.tsx +0 -129
- package/src/client/router/index.ts +0 -286
- package/src/client/router/request/index.ts +0 -106
- package/src/client/router/response/index.ts +0 -38
- package/src/client/router/route.ts +0 -75
- package/src/common/data/input/validators/basic.ts +0 -299
- package/src/common/data/input/validators/build.ts +0 -63
- package/src/common/router/request.ts +0 -83
- package/src/server/data/ApiClient.ts +0 -119
- package/src/server/data/input.ts +0 -41
- package/src/server/libs/pages/document.static.tsx +0 -41
- package/src/server/libs/pages/document.tsx +0 -203
- package/src/server/libs/pages/render.tsx +0 -90
- package/src/server/routes/auth.ts +0 -151
- package/src/server/services/redis/index.ts +0 -71
- package/src/server/services/router/request/services/auth.ts +0 -177
package/changelog.md
ADDED
package/doc/TODO.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
* Fix erreurs type Client / Server context
|
|
2
|
+
* Server side: ServerContext
|
|
3
|
+
* Client side: ClientContext | ServerContext
|
|
4
|
+
* PageResponse extends Response
|
|
5
|
+
* Toast service
|
|
6
|
+
* ClientApplication hooks
|
|
7
|
+
app.on('bug')
|
|
8
|
+
app.on('error')
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Dependancies injection
|
|
12
|
+
|
|
13
|
+
# Full stack Pages
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import Router from '@server/services/router';
|
|
17
|
+
import { TRouterContext as ServerServices } from '@server/services/router/response';
|
|
18
|
+
import { TRouterContext as ClientServices } from '@client/services/router/response';
|
|
19
|
+
|
|
20
|
+
abstract class Controller<
|
|
21
|
+
TRouter extends Router,
|
|
22
|
+
TData extends any = any,
|
|
23
|
+
TUserAccess extends string = string
|
|
24
|
+
> {
|
|
25
|
+
|
|
26
|
+
abstract auth: TUserAccess;
|
|
27
|
+
|
|
28
|
+
abstract get( services: ServerServices<TRouter> ): Promise<TData>;
|
|
29
|
+
|
|
30
|
+
abstract render( context: TData, services: ClientServices<TRouter> ): ComponentChild;
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
//? /headhunter/missions/suggested'
|
|
37
|
+
class Missions extends Controller<CrossPath["router"]> {
|
|
38
|
+
|
|
39
|
+
auth = 'USER';
|
|
40
|
+
|
|
41
|
+
async get({ headhunting, response, auth }) {
|
|
42
|
+
|
|
43
|
+
const user = await auth.check('USER');
|
|
44
|
+
|
|
45
|
+
const suggested = await headhunting.missions.Suggest( user );
|
|
46
|
+
|
|
47
|
+
return { suggested }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
render({ page, api, suggested }) {
|
|
51
|
+
return (
|
|
52
|
+
<Page title="App title here" subtitle="SEO description here">{page.loading || <>
|
|
53
|
+
|
|
54
|
+
<section class="col">
|
|
55
|
+
|
|
56
|
+
<header class="row">
|
|
57
|
+
<h2 class="col-1">Suggested Missions</h2>
|
|
58
|
+
</header>
|
|
59
|
+
|
|
60
|
+
<div class="grid xa3">
|
|
61
|
+
{suggested.map( mission => (
|
|
62
|
+
<MissionCard mission={mission} />
|
|
63
|
+
))}
|
|
64
|
+
</div>
|
|
65
|
+
</section>
|
|
66
|
+
|
|
67
|
+
</>}</Page>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "Convenient Full Stack TypeScript framework designed for Performance and Productivity.",
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"framework"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@sendgrid/mail": "^7.4.6",
|
|
17
16
|
"accepts": "^1.3.7",
|
|
18
17
|
"activity-detector": "^3.0.0",
|
|
19
18
|
"ansi-to-html": "^0.7.1",
|
|
20
19
|
"array-move": "^3.0.1",
|
|
20
|
+
"axios": "^1.2.1",
|
|
21
21
|
"bowser": "^2.11.0",
|
|
22
22
|
"chart.js": "^3.6.2",
|
|
23
23
|
"cli-highlight": "^2.1.11",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"@types/nodemailer": "^6.4.4",
|
|
84
84
|
"@types/universal-analytics": "^0.4.5",
|
|
85
85
|
"@types/webpack-env": "^1.16.2",
|
|
86
|
-
"@types/ws": "^7.4.7"
|
|
86
|
+
"@types/ws": "^7.4.7",
|
|
87
|
+
"babel-plugin-glob-import": "^0.0.3"
|
|
87
88
|
}
|
|
88
89
|
}
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
|
-
import { ReactClientContext, ClientContext } from '@client/context';
|
|
10
|
-
import DialogManager from '@client/components/Dialog/Manager'
|
|
11
9
|
import type { Layout } from '@common/router';
|
|
10
|
+
import { ReactClientContext } from '@/client/context';
|
|
11
|
+
import DialogManager from '@client/components/Dialog/Manager'
|
|
12
12
|
|
|
13
13
|
// Core components
|
|
14
|
-
import Router from '@client/router/
|
|
14
|
+
import Router from '@client/services/router/components/router';
|
|
15
|
+
import type { TClientOrServerContext } from '@common/router';
|
|
15
16
|
|
|
16
17
|
// Resources
|
|
17
18
|
import "@client/assets/css/core.less";
|
|
@@ -19,20 +20,26 @@ import "@client/assets/css/core.less";
|
|
|
19
20
|
/*----------------------------------
|
|
20
21
|
- COMPOSANT
|
|
21
22
|
----------------------------------*/
|
|
22
|
-
export default function App ({ context }: {
|
|
23
|
+
export default function App ({ context }: {
|
|
24
|
+
context: TClientOrServerContext,
|
|
25
|
+
}) {
|
|
23
26
|
|
|
24
|
-
const route = context.
|
|
27
|
+
const route = context.route;
|
|
25
28
|
const curLayout = route.options.layout;
|
|
26
29
|
const [layout, setLayout] = React.useState<Layout | false | undefined>(curLayout);
|
|
27
|
-
|
|
30
|
+
|
|
31
|
+
// TODO: context.page is always provided in the context on the client side
|
|
32
|
+
if (context.app.side === "client")
|
|
33
|
+
context.app.setLayout = setLayout;
|
|
28
34
|
|
|
29
35
|
return (
|
|
30
36
|
<ReactClientContext.Provider value={context}>
|
|
31
37
|
|
|
32
|
-
<DialogManager />
|
|
38
|
+
<DialogManager context={context} />
|
|
33
39
|
|
|
34
40
|
{!layout ? <>
|
|
35
|
-
|
|
41
|
+
{/* TODO: move to app, because here, we're not aware that the router service has been defined */}
|
|
42
|
+
<Router service={context.router} />
|
|
36
43
|
</> : <>
|
|
37
44
|
<layout.Component context={context} />
|
|
38
45
|
</>}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
if (typeof window === 'undefined')
|
|
6
|
+
throw new Error(`This file shouldn't be loaded on server side !!!!`);
|
|
7
|
+
|
|
8
|
+
window.dev && require('preact/debug');
|
|
9
|
+
|
|
10
|
+
// Core
|
|
11
|
+
import { Erreur } from '@common/errors';
|
|
12
|
+
import type { Layout } from '@common/router';
|
|
13
|
+
import { createDialog } from '@client/components/Dialog/Manager';
|
|
14
|
+
|
|
15
|
+
// Local
|
|
16
|
+
import type { AnyService } from './service';
|
|
17
|
+
|
|
18
|
+
export { default as Service } from './service';
|
|
19
|
+
|
|
20
|
+
/*----------------------------------
|
|
21
|
+
- TYPES
|
|
22
|
+
----------------------------------*/
|
|
23
|
+
|
|
24
|
+
declare global {
|
|
25
|
+
interface Window {
|
|
26
|
+
dev: boolean,
|
|
27
|
+
// Defined by loading gtag.js
|
|
28
|
+
gtag: (action: string, name: string, params?: any) => void,
|
|
29
|
+
/*context: ClientContext,
|
|
30
|
+
user: User,*/
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type TBugReportInfos = {
|
|
35
|
+
stacktrace?: string,
|
|
36
|
+
observation?: string,
|
|
37
|
+
before?: string,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/*----------------------------------
|
|
41
|
+
- CLASS
|
|
42
|
+
----------------------------------*/
|
|
43
|
+
export default abstract class Application {
|
|
44
|
+
|
|
45
|
+
public side = 'client' as 'client';
|
|
46
|
+
|
|
47
|
+
private servicesList: AnyService[] = []
|
|
48
|
+
|
|
49
|
+
// TODO: merge modal and toast in the same instance
|
|
50
|
+
public modal = createDialog(this, false);
|
|
51
|
+
public toast = createDialog(this, true);
|
|
52
|
+
|
|
53
|
+
public constructor() {
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public registerService( service: AnyService ) {
|
|
58
|
+
console.log(`[app] Register service`, service.constructor?.name);
|
|
59
|
+
this.servicesList.push(service);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public start() {
|
|
63
|
+
this.bindErrorHandlers();
|
|
64
|
+
this.startServices();
|
|
65
|
+
this.boot();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public abstract boot(): void;
|
|
69
|
+
|
|
70
|
+
public startServices() {
|
|
71
|
+
|
|
72
|
+
console.log(`[app] Starting ${this.servicesList.length} services.`);
|
|
73
|
+
|
|
74
|
+
for (const service of this.servicesList) {
|
|
75
|
+
console.log(`[app] Start service`, service);
|
|
76
|
+
service.start();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`[app] All ${this.servicesList.length} services were started.`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public bindErrorHandlers() {
|
|
83
|
+
|
|
84
|
+
// Impossible de recup le stacktrace ...
|
|
85
|
+
/*window.addEventListener("unhandledrejection", (e) => {
|
|
86
|
+
clientBug(JSON.stringify(e))
|
|
87
|
+
console.log("unhandledrejection", e.stack);
|
|
88
|
+
|
|
89
|
+
});*/
|
|
90
|
+
|
|
91
|
+
window.onerror = (message, file, line, col, stacktrace) =>
|
|
92
|
+
this.reportBug({
|
|
93
|
+
stacktrace: stacktrace?.stack || JSON.stringify({ message, file, line, col })
|
|
94
|
+
}).then(() => {
|
|
95
|
+
|
|
96
|
+
// TODO in toas service: app.on('bug', () => toast.warning( ... ))
|
|
97
|
+
/*context?.toast.warning("Bug detected",
|
|
98
|
+
"A bug report has been sent, because I've detected a bug on the interface. I'm really sorry for the interruption.",
|
|
99
|
+
null,
|
|
100
|
+
{ autohide: false });*/
|
|
101
|
+
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public handleError( error: Erreur | Error, httpCode?: number ) {
|
|
106
|
+
|
|
107
|
+
/*console.error(`[api] Network error:`, e);
|
|
108
|
+
context.toast.error("Please check your internet connection and try again.", undefined, null, { autohide: false });*/
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public reportBug = (infos: TBugReportInfos) => fetch('/help/bug/gui', {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: {
|
|
114
|
+
'Accept': "application/json",
|
|
115
|
+
'Content-Type': 'application/json'
|
|
116
|
+
},
|
|
117
|
+
body: JSON.stringify({
|
|
118
|
+
url: window.location.pathname,
|
|
119
|
+
ssrData: JSON.stringify(window["ssr"]),
|
|
120
|
+
guiVersion: BUILD_DATE,
|
|
121
|
+
...infos
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
public setLayout(layout: Layout) {
|
|
126
|
+
throw new Error(`page.setLayout has been called before the function is assigned from the <App /> component.`);
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
import type Application from ".";
|
|
6
|
+
|
|
7
|
+
/*----------------------------------
|
|
8
|
+
- TYPES: OPTIONS
|
|
9
|
+
----------------------------------*/
|
|
10
|
+
|
|
11
|
+
export type AnyService = Service<{}, Application>
|
|
12
|
+
|
|
13
|
+
/*----------------------------------
|
|
14
|
+
- CLASS
|
|
15
|
+
----------------------------------*/
|
|
16
|
+
export default abstract class Service<
|
|
17
|
+
TConfig extends {},
|
|
18
|
+
TApplication extends Application
|
|
19
|
+
> {
|
|
20
|
+
public constructor(
|
|
21
|
+
public app: TApplication,
|
|
22
|
+
public config: TConfig,
|
|
23
|
+
) {
|
|
24
|
+
|
|
25
|
+
// No client service should be loaded from server side
|
|
26
|
+
if (typeof window === 'undefined')
|
|
27
|
+
throw new Error(`Client services shouldn't be loaded on server side.`);
|
|
28
|
+
|
|
29
|
+
// Make the app aware of his services
|
|
30
|
+
app.registerService(this);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public abstract start(): void;
|
|
34
|
+
}
|
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
// Only used for typings (ex: ServerResponse)
|
|
12
12
|
// Removed before webpack compilation
|
|
13
13
|
"@server/*": ["../node_modules/5htp-core/src/server/*"],
|
|
14
|
-
"@validator": ["../node_modules/5htp-core/src/client/data/input"],
|
|
15
|
-
"@router": ["../node_modules/5htp-core/src/client/router"],
|
|
16
|
-
"@errors": ["../node_modules/5htp-core/src/common/errors"],
|
|
17
|
-
"@models": ["../.cache/client/models"],
|
|
18
14
|
"@/*": ["./*"],
|
|
19
15
|
|
|
20
16
|
// ATTENTION: Les références à preact doivent toujours pointer vers la même instance
|
|
@@ -7,11 +7,10 @@ import React from 'react';
|
|
|
7
7
|
import { ComponentChild } from 'preact';
|
|
8
8
|
|
|
9
9
|
// Libs
|
|
10
|
-
import useContext
|
|
11
|
-
import { ClientResponse } from '@client/router';
|
|
12
|
-
import { initStateAsync, execFetchersState } from '@client/hooks/useState/fetchers';
|
|
10
|
+
import useContext from '@/client/context';
|
|
13
11
|
|
|
14
12
|
// Métier
|
|
13
|
+
import type Application from '../../app';
|
|
15
14
|
import Card, { Props as CardInfos } from './card';
|
|
16
15
|
import Button from '../button';
|
|
17
16
|
|
|
@@ -43,11 +42,34 @@ export type TDialogControls = {
|
|
|
43
42
|
then: (cb: TOnCloseCallback<any>) => any
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
type DialogActions = {
|
|
46
|
+
|
|
47
|
+
setToasts: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
|
|
48
|
+
|
|
49
|
+
show: (
|
|
50
|
+
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
51
|
+
Content: ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast,
|
|
52
|
+
paramsInit?: TParams
|
|
53
|
+
) => TDialogControls,
|
|
54
|
+
|
|
55
|
+
confirm: (title: string, content: string | ComponentChild, defaultBtn: 'Yes'|'No') => TDialogControls,
|
|
56
|
+
|
|
57
|
+
loading: (title: string) => TDialogControls,
|
|
58
|
+
|
|
59
|
+
info: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls,
|
|
60
|
+
|
|
61
|
+
success: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls,
|
|
62
|
+
|
|
63
|
+
warning: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls,
|
|
64
|
+
|
|
65
|
+
error: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls,
|
|
66
|
+
}
|
|
67
|
+
|
|
46
68
|
/*----------------------------------
|
|
47
69
|
- SERVICE CONTEXTE
|
|
48
70
|
----------------------------------*/
|
|
49
71
|
let idA: number = 0;
|
|
50
|
-
export const createDialog = (
|
|
72
|
+
export const createDialog = (app: Application, isToast: boolean): DialogActions => {
|
|
51
73
|
|
|
52
74
|
const show = <TReturnType extends any = true>(
|
|
53
75
|
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
@@ -60,7 +82,7 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
60
82
|
|
|
61
83
|
const close = (retour: TReturnType) => {
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
instance.setToasts(q => q.filter(m => m.id !== id))
|
|
64
86
|
|
|
65
87
|
if (onClose !== undefined)
|
|
66
88
|
onClose(retour);
|
|
@@ -105,7 +127,7 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
105
127
|
// Chargeur de données
|
|
106
128
|
/*if (('data' in ComposantCharge) && typeof ComposantCharge.data === 'function') {
|
|
107
129
|
|
|
108
|
-
propsRendu.data = await ComposantCharge.data(
|
|
130
|
+
propsRendu.data = await ComposantCharge.data(app, paramsInit);
|
|
109
131
|
|
|
110
132
|
const { fetchersStateA } = initStateAsync(propsRendu.data, {}, false);
|
|
111
133
|
|
|
@@ -125,7 +147,7 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
125
147
|
|
|
126
148
|
render["id"] = id;
|
|
127
149
|
|
|
128
|
-
|
|
150
|
+
instance.setToasts(q => [...q, render]);
|
|
129
151
|
});
|
|
130
152
|
|
|
131
153
|
return {
|
|
@@ -134,9 +156,12 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
134
156
|
}
|
|
135
157
|
};
|
|
136
158
|
|
|
137
|
-
|
|
159
|
+
const instance: DialogActions = {
|
|
160
|
+
|
|
138
161
|
show: show,
|
|
139
162
|
|
|
163
|
+
setToasts: undefined as unknown as DialogActions["setToasts"],
|
|
164
|
+
|
|
140
165
|
confirm: (title: string, content: string | ComponentChild, defaultBtn: 'Yes'|'No' = 'No') => show<boolean>(({ close }) => (
|
|
141
166
|
<div class="col">
|
|
142
167
|
<header>
|
|
@@ -156,7 +181,7 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
156
181
|
</div>
|
|
157
182
|
)),
|
|
158
183
|
|
|
159
|
-
loading: (title: string) =>
|
|
184
|
+
loading: (title: string) => app.loadIndicator = show({
|
|
160
185
|
title: title,
|
|
161
186
|
type: 'loading'
|
|
162
187
|
}),
|
|
@@ -193,6 +218,8 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
193
218
|
...options
|
|
194
219
|
}),
|
|
195
220
|
}
|
|
221
|
+
|
|
222
|
+
return instance;
|
|
196
223
|
}
|
|
197
224
|
|
|
198
225
|
/*----------------------------------
|
|
@@ -201,12 +228,12 @@ export const createDialog = (ctx: ClientContext, isToast: boolean) => {
|
|
|
201
228
|
import './index.less';
|
|
202
229
|
export default () => {
|
|
203
230
|
|
|
204
|
-
const
|
|
231
|
+
const app = useContext();
|
|
205
232
|
|
|
206
233
|
const [rendered, setRendered] = React.useState<ComponentChild[]>([]);
|
|
207
234
|
|
|
208
|
-
|
|
209
|
-
|
|
235
|
+
if (app.side === 'client')
|
|
236
|
+
app.modal.setToasts = app.toast.setToasts = setRendered;
|
|
210
237
|
|
|
211
238
|
React.useEffect(() => {
|
|
212
239
|
|
|
@@ -13,7 +13,7 @@ import { propsDefautChampForm, TBasePropsChamp } from '@client/components/input/
|
|
|
13
13
|
import { TSchema, TRetourValidation, initDonnees, validate as validerSchema, TSchemaChampComplet } from '@common/data/input/validate';
|
|
14
14
|
import { simpleDeepCopy, chemin } from '@common/data/objets';
|
|
15
15
|
import { ContexteOnglets } from '@client/components/containers/tabs';
|
|
16
|
-
import useContext from '
|
|
16
|
+
import useContext from '@/client/context';
|
|
17
17
|
|
|
18
18
|
/*----------------------------------
|
|
19
19
|
- TYPES ENTREE
|
|
@@ -7,8 +7,8 @@ import React from 'react';
|
|
|
7
7
|
import { VNode, RefObject,ComponentChild } from 'preact';
|
|
8
8
|
|
|
9
9
|
// Core
|
|
10
|
-
import { history } from '@client/router/request/history';
|
|
11
|
-
import useContext from '
|
|
10
|
+
import { history } from '@client/services/router/request/history';
|
|
11
|
+
import useContext from '@/client/context';
|
|
12
12
|
|
|
13
13
|
/*----------------------------------
|
|
14
14
|
- TYPES
|
|
@@ -15,7 +15,7 @@ import Bouton, { Props as PropsBouton } from '@client/components/button';
|
|
|
15
15
|
// Libs
|
|
16
16
|
import getPosition, { TSide } from './getPosition';
|
|
17
17
|
import { blurable, deepContains } from '@client/utils/dom';
|
|
18
|
-
import useContexte from '
|
|
18
|
+
import useContexte from '@/client/context';
|
|
19
19
|
|
|
20
20
|
/*----------------------------------
|
|
21
21
|
- TYPES
|
|
@@ -12,7 +12,7 @@ import { TDialogControls } from '../Dialog/Manager';
|
|
|
12
12
|
export type { TDialogControls } from '../Dialog/Manager';
|
|
13
13
|
|
|
14
14
|
// Libs
|
|
15
|
-
import useContexte from '
|
|
15
|
+
import useContexte from '@/client/context';
|
|
16
16
|
|
|
17
17
|
/*----------------------------------
|
|
18
18
|
- TYPES
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as Button } from './button';
|
|
2
|
+
export { default as Row } from './row';
|
|
3
|
+
export { default as Card } from './card';
|
|
4
|
+
export { default as Table } from './Table';
|
|
5
|
+
export { default as Select } from './Select';
|
|
6
|
+
export { default as Amount } from './Amount';
|
|
7
|
+
export { default as Logo } from './Logo';
|
|
8
|
+
export { default as Input } from './input';
|
|
@@ -9,7 +9,7 @@ import { ComponentChild } from 'preact';
|
|
|
9
9
|
import Bouton from '@client/components/button';
|
|
10
10
|
|
|
11
11
|
// Libs
|
|
12
|
-
import useContext, { useState } from '
|
|
12
|
+
import useContext, { useState } from '@/client/context';
|
|
13
13
|
import NormalisedFile from '@common/data/file';
|
|
14
14
|
|
|
15
15
|
// Ressources
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as useState } from './useState';
|
|
2
|
+
export { default as useActivity } from './useActivity';
|
|
3
|
+
export { default as useComponent } from './useComponent';
|
|
4
|
+
export { default as useScript } from './useScript';
|
|
5
|
+
export { default as useVisible } from './useVisible';
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { useState as reactUseState, useEffect as reactUseEffect } from 'preact/hooks';
|
|
7
7
|
|
|
8
8
|
// Libs
|
|
9
|
-
import useContexte from '
|
|
9
|
+
import useContexte from '@/client/context';
|
|
10
10
|
|
|
11
11
|
// Libs spécifiques
|
|
12
12
|
import { execFetchersState, initStateAsync } from './fetchers';
|
|
@@ -18,7 +18,7 @@ import { execFetchersState, initStateAsync } from './fetchers';
|
|
|
18
18
|
|
|
19
19
|
import TRequeteApi, { TOptionsRequete } from '@common/api';
|
|
20
20
|
|
|
21
|
-
import { TDataResolved } from '@client/router';
|
|
21
|
+
import { TDataResolved } from '@client/services/router';
|
|
22
22
|
|
|
23
23
|
/*----------------------------------
|
|
24
24
|
- TYPES: DEFINITIONS
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ComponentChild } from 'preact';
|
|
3
|
+
|
|
4
|
+
// Hooks
|
|
5
|
+
/*export { default as useState } from '@client/hooks/useState';
|
|
6
|
+
export type { TActions as TActionsState } from '@client/hooks/useState';
|
|
7
|
+
export { default as useComponent } from '@client/hooks/useComponent';
|
|
8
|
+
export { default as useScript } from '@client/hooks/useScript';*/
|
|
9
|
+
|
|
10
|
+
// Utils
|
|
11
|
+
export const Switch = (val: string | number, options: { [cle: string]: ComponentChild }) => {
|
|
12
|
+
return (val in options) ? options[val] : null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useState = <TData extends TObjetDonnees>(initial: TData): [
|
|
16
|
+
TData,
|
|
17
|
+
(data: Partial<TData>) => void
|
|
18
|
+
] => {
|
|
19
|
+
const [state, setState] = React.useState<TData>(initial);
|
|
20
|
+
const setPartialState = (data: Partial<TData>) => setState(current => ({ ...current, ...data }));
|
|
21
|
+
return [state, setPartialState]
|
|
22
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
|
-
import
|
|
9
|
+
import { router } from '@app';
|
|
10
10
|
import Button from '@client/components/button';
|
|
11
11
|
|
|
12
12
|
// App
|
|
@@ -15,7 +15,7 @@ import useHeader from '@client/pages/useHeader';
|
|
|
15
15
|
/*----------------------------------
|
|
16
16
|
- CONTROLEUR
|
|
17
17
|
----------------------------------*/
|
|
18
|
-
|
|
18
|
+
router.error(400, {}, ({ message, modal }) => {
|
|
19
19
|
|
|
20
20
|
if (!message)
|
|
21
21
|
message = "The request you made is incorrect.";
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
|
-
import
|
|
9
|
+
import { router } from '@app';
|
|
10
10
|
import Button from '@client/components/button';
|
|
11
11
|
|
|
12
12
|
// App
|
|
@@ -18,7 +18,7 @@ import Button from '@client/components/button';
|
|
|
18
18
|
/*----------------------------------
|
|
19
19
|
- CONTROLEUR
|
|
20
20
|
----------------------------------*/
|
|
21
|
-
|
|
21
|
+
router.error(401, { }, ({ api, toast, modal, request, page }) => {
|
|
22
22
|
|
|
23
23
|
request.response?.redirect('/');
|
|
24
24
|
|