proteum 1.0.3 → 2.0.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/AGENTS.md +92 -0
- package/agents/codex/AGENTS.md +95 -0
- package/agents/codex/CODING_STYLE.md +71 -0
- package/agents/codex/agents.md.zip +0 -0
- package/agents/codex/client/AGENTS.md +102 -0
- package/agents/codex/client/pages/AGENTS.md +35 -0
- package/agents/codex/server/routes/AGENTS.md +12 -0
- package/agents/codex/server/services/AGENTS.md +137 -0
- package/agents/codex/tests/AGENTS.md +8 -0
- package/cli/app/config.ts +12 -17
- package/cli/app/index.ts +59 -99
- package/cli/bin.js +1 -1
- package/cli/commands/build.ts +23 -12
- package/cli/commands/check.ts +19 -0
- package/cli/commands/deploy/app.ts +4 -8
- package/cli/commands/deploy/web.ts +16 -20
- package/cli/commands/dev.ts +185 -75
- package/cli/commands/devEvents.ts +106 -0
- package/cli/commands/init.ts +63 -57
- package/cli/commands/lint.ts +21 -0
- package/cli/commands/refresh.ts +6 -6
- package/cli/commands/typecheck.ts +18 -0
- package/cli/compiler/client/identite.ts +79 -49
- package/cli/compiler/client/index.ts +132 -214
- package/cli/compiler/common/bundleAnalysis.ts +94 -0
- package/cli/compiler/common/clientManifest.ts +67 -0
- package/cli/compiler/common/controllers.ts +288 -0
- package/cli/compiler/common/files/autres.ts +7 -18
- package/cli/compiler/common/files/images.ts +40 -37
- package/cli/compiler/common/files/style.ts +12 -25
- package/cli/compiler/common/generatedRouteModules.ts +368 -0
- package/cli/compiler/common/index.ts +29 -68
- package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
- package/cli/compiler/common/rspackAliases.ts +13 -0
- package/cli/compiler/common/scripts.ts +37 -0
- package/cli/compiler/index.ts +764 -234
- package/cli/compiler/server/index.ts +52 -77
- package/cli/compiler/writeIfChanged.ts +21 -0
- package/cli/index.ts +65 -90
- package/cli/paths.ts +51 -57
- package/cli/print.ts +17 -11
- package/cli/tsconfig.json +5 -4
- package/cli/utils/agents.ts +100 -0
- package/cli/utils/check.ts +71 -0
- package/cli/utils/index.ts +1 -3
- package/cli/utils/keyboard.ts +8 -25
- package/cli/utils/runProcess.ts +30 -0
- package/client/app/component.tsx +29 -29
- package/client/app/index.ts +36 -57
- package/client/app/service.ts +7 -12
- package/client/app.tsconfig.json +2 -2
- package/client/components/Dialog/Manager.ssr.tsx +40 -0
- package/client/components/Dialog/Manager.tsx +119 -150
- package/client/components/Dialog/status.tsx +3 -3
- package/client/components/index.ts +1 -1
- package/client/components/types.d.ts +1 -3
- package/client/dev/hmr.ts +65 -0
- package/client/global.d.ts +2 -2
- package/client/hooks.ts +6 -9
- package/client/index.ts +2 -1
- package/client/islands/index.ts +7 -0
- package/client/islands/useDeferredModule.ts +199 -0
- package/client/pages/_layout/index.tsx +4 -12
- package/client/pages/useHeader.tsx +14 -21
- package/client/router.ts +27 -0
- package/client/services/router/components/Link.tsx +34 -27
- package/client/services/router/components/Page.tsx +6 -14
- package/client/services/router/components/router.ssr.tsx +36 -0
- package/client/services/router/components/router.tsx +63 -83
- package/client/services/router/index.tsx +185 -220
- package/client/services/router/request/api.ts +97 -119
- package/client/services/router/request/history.ts +2 -2
- package/client/services/router/request/index.ts +13 -12
- package/client/services/router/request/multipart.ts +72 -62
- package/client/services/router/response/index.tsx +68 -61
- package/client/services/router/response/page.ts +28 -32
- package/client/utils/dom.ts +17 -33
- package/common/app/index.ts +3 -3
- package/common/data/chaines/index.ts +22 -23
- package/common/data/dates.ts +35 -70
- package/common/data/markdown.ts +42 -39
- package/common/dev/serverHotReload.ts +26 -0
- package/common/errors/index.tsx +110 -142
- package/common/router/contracts.ts +29 -0
- package/common/router/index.ts +89 -108
- package/common/router/layouts.ts +34 -47
- package/common/router/pageSetup.ts +50 -0
- package/common/router/register.ts +53 -24
- package/common/router/request/api.ts +30 -36
- package/common/router/request/index.ts +2 -8
- package/common/router/response/index.ts +8 -15
- package/common/router/response/page.ts +70 -58
- package/common/utils.ts +1 -1
- package/eslint.js +62 -0
- package/package.json +12 -45
- package/prettier.config.cjs +9 -0
- package/scripts/cleanup-generated-controllers.ts +62 -0
- package/scripts/fix-reference-app-typing.ts +490 -0
- package/scripts/refactor-client-app-imports.ts +244 -0
- package/scripts/refactor-client-pages.ts +587 -0
- package/scripts/refactor-server-controllers.ts +470 -0
- package/scripts/refactor-server-runtime-aliases.ts +360 -0
- package/scripts/restore-client-app-import-files.ts +41 -0
- package/scripts/restore-files-from-git-head.ts +20 -0
- package/scripts/update-codex-agents.ts +35 -0
- package/server/app/commands.ts +35 -64
- package/server/app/container/config.ts +39 -69
- package/server/app/container/console/index.ts +202 -248
- package/server/app/container/index.ts +33 -71
- package/server/app/controller/index.ts +61 -0
- package/server/app/index.ts +39 -105
- package/server/app/service/container.ts +41 -42
- package/server/app/service/index.ts +120 -147
- package/server/context.ts +1 -1
- package/server/index.ts +25 -1
- package/server/services/auth/index.ts +75 -115
- package/server/services/auth/router/index.ts +31 -32
- package/server/services/auth/router/request.ts +14 -16
- package/server/services/cron/CronTask.ts +13 -26
- package/server/services/cron/index.ts +14 -36
- package/server/services/disks/driver.ts +40 -58
- package/server/services/disks/drivers/local/index.ts +79 -90
- package/server/services/disks/drivers/s3/index.ts +116 -163
- package/server/services/disks/index.ts +23 -38
- package/server/services/email/index.ts +45 -104
- package/server/services/email/utils.ts +14 -27
- package/server/services/fetch/index.ts +53 -85
- package/server/services/prisma/Facet.ts +39 -91
- package/server/services/prisma/index.ts +74 -110
- package/server/services/router/generatedRuntime.ts +29 -0
- package/server/services/router/http/index.ts +77 -72
- package/server/services/router/http/multipart.ts +19 -42
- package/server/services/router/index.ts +378 -365
- package/server/services/router/request/api.ts +26 -25
- package/server/services/router/request/index.ts +44 -51
- package/server/services/router/request/service.ts +7 -11
- package/server/services/router/request/validation/zod.ts +111 -148
- package/server/services/router/response/index.ts +110 -125
- package/server/services/router/response/mask/Filter.ts +31 -72
- package/server/services/router/response/mask/index.ts +8 -15
- package/server/services/router/response/mask/selecteurs.ts +11 -25
- package/server/services/router/response/page/clientManifest.ts +25 -0
- package/server/services/router/response/page/document.tsx +199 -127
- package/server/services/router/response/page/index.tsx +89 -94
- package/server/services/router/service.ts +13 -15
- package/server/services/schema/index.ts +17 -26
- package/server/services/schema/request.ts +19 -33
- package/server/services/schema/router/index.ts +8 -11
- package/server/services/security/encrypt/aes/index.ts +15 -35
- package/server/utils/slug.ts +29 -32
- package/skills/clean-project-code/SKILL.md +63 -0
- package/skills/clean-project-code/agents/openai.yaml +4 -0
- package/tsconfig.common.json +4 -3
- package/tsconfig.json +4 -1
- package/types/aliases.d.ts +17 -21
- package/types/controller-input.test.ts +48 -0
- package/types/express-extra.d.ts +6 -0
- package/types/global/constants.d.ts +1 -0
- package/types/global/express-extra.d.ts +6 -0
- package/types/global/modules.d.ts +13 -16
- package/types/global/utils.d.ts +17 -49
- package/types/global/vendors.d.ts +62 -0
- package/types/icons.d.ts +65 -1
- package/types/uuid.d.ts +3 -0
- package/types/vendors.d.ts +62 -0
- package/cli/compiler/common/babel/index.ts +0 -173
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +0 -586
- package/cli/compiler/common/babel/routes/imports.ts +0 -127
- package/cli/compiler/common/babel/routes/routes.ts +0 -1170
- package/client/services/captcha/index.ts +0 -67
- package/client/services/socket/index.ts +0 -147
- package/common/data/rte/nodes.ts +0 -83
- package/common/data/stats.ts +0 -90
- package/common/utils/rte.ts +0 -183
- package/server/services/auth/old.ts +0 -277
- package/server/services/cache/commands.ts +0 -41
- package/server/services/cache/index.ts +0 -297
- package/server/services/cache/service.json +0 -6
- package/server/services/socket/index.ts +0 -162
- package/server/services/socket/scope.ts +0 -226
- package/server/services/socket/service.json +0 -6
- package/server/services_old/SocketClient.ts +0 -92
- package/server/services_old/Token.old.ts +0 -97
package/client/app/index.ts
CHANGED
|
@@ -3,15 +3,12 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (typeof window === 'undefined')
|
|
9
|
-
throw new Error(`This file shouldn't be loaded on server side !!!!`);
|
|
6
|
+
if (typeof window === 'undefined') throw new Error(`This file shouldn't be loaded on server side !!!!`);
|
|
10
7
|
|
|
11
8
|
window.dev && require('preact/debug');
|
|
12
9
|
|
|
13
10
|
// Core
|
|
14
|
-
import { CoreError
|
|
11
|
+
import { CoreError } from '@common/errors';
|
|
15
12
|
import type { Layout } from '@common/router';
|
|
16
13
|
import { createDialog } from '@client/components/Dialog/Manager';
|
|
17
14
|
|
|
@@ -26,7 +23,8 @@ export { default as Service } from './service';
|
|
|
26
23
|
|
|
27
24
|
declare global {
|
|
28
25
|
interface Window {
|
|
29
|
-
dev: boolean
|
|
26
|
+
dev: boolean;
|
|
27
|
+
app?: Application;
|
|
30
28
|
/*context: ClientContext,
|
|
31
29
|
user: User,*/
|
|
32
30
|
/*context: ClientContext,
|
|
@@ -34,22 +32,12 @@ declare global {
|
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
export type TBugReportInfos = {
|
|
38
|
-
stacktrace?: string,
|
|
39
|
-
observation?: string,
|
|
40
|
-
before?: string,
|
|
41
|
-
}
|
|
35
|
+
export type TBugReportInfos = { stacktrace?: string; observation?: string; before?: string };
|
|
42
36
|
|
|
43
|
-
export type TClientBugReportInfos = TBugReportInfos & {
|
|
44
|
-
context?: string,
|
|
45
|
-
guiVersion: string,
|
|
46
|
-
url: string,
|
|
47
|
-
}
|
|
37
|
+
export type TClientBugReportInfos = TBugReportInfos & { context?: string; guiVersion: string; url: string };
|
|
48
38
|
|
|
49
39
|
// Without prettify, we don't get a clear list of the class properties
|
|
50
|
-
type Prettify<T> = {
|
|
51
|
-
[K in keyof T]: T[K];
|
|
52
|
-
} & {};
|
|
40
|
+
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
53
41
|
|
|
54
42
|
export type ApplicationProperties = Prettify<keyof Application>;
|
|
55
43
|
|
|
@@ -57,20 +45,17 @@ export type ApplicationProperties = Prettify<keyof Application>;
|
|
|
57
45
|
- CLASS
|
|
58
46
|
----------------------------------*/
|
|
59
47
|
export default abstract class Application {
|
|
60
|
-
|
|
61
48
|
public side = 'client' as 'client';
|
|
62
49
|
|
|
63
|
-
private servicesList: AnyService[] = []
|
|
50
|
+
private servicesList: AnyService[] = [];
|
|
64
51
|
|
|
65
52
|
// TODO: merge modal and toast in the same instance
|
|
66
53
|
public modal = createDialog(this, false);
|
|
67
54
|
public toast = createDialog(this, true);
|
|
68
55
|
|
|
69
|
-
public constructor() {
|
|
56
|
+
public constructor() {}
|
|
70
57
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
public registerService( service: AnyService ) {
|
|
58
|
+
public registerService(service: AnyService) {
|
|
74
59
|
console.log(`[app] Register service`, service.constructor?.name);
|
|
75
60
|
this.servicesList.push(service);
|
|
76
61
|
}
|
|
@@ -84,7 +69,6 @@ export default abstract class Application {
|
|
|
84
69
|
public abstract boot(): void;
|
|
85
70
|
|
|
86
71
|
public startServices() {
|
|
87
|
-
|
|
88
72
|
console.log(`[app] Starting ${this.servicesList.length} services.`);
|
|
89
73
|
|
|
90
74
|
for (const service of this.servicesList) {
|
|
@@ -96,49 +80,44 @@ export default abstract class Application {
|
|
|
96
80
|
}
|
|
97
81
|
|
|
98
82
|
public bindErrorHandlers() {
|
|
99
|
-
|
|
100
83
|
// Impossible de recup le stacktrace ...
|
|
101
|
-
window.addEventListener(
|
|
84
|
+
window.addEventListener('unhandledrejection', (e) => {
|
|
102
85
|
const error = new Error(e.reason); // How to get stacktrace ?
|
|
103
86
|
this.handleError(error);
|
|
104
87
|
});
|
|
105
|
-
|
|
88
|
+
|
|
106
89
|
window.onerror = (message, file, line, col, stacktrace) => {
|
|
107
90
|
console.error(`Exception catched by method B`, message);
|
|
108
|
-
this.reportBug({
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// TODO in toas service: app.on('bug', () => toast.warning( ... ))
|
|
113
|
-
/*context?.toast.warning("Bug detected",
|
|
91
|
+
this.reportBug({ stacktrace: stacktrace?.stack || JSON.stringify({ message, file, line, col }) }).then(
|
|
92
|
+
() => {
|
|
93
|
+
// TODO in toas service: app.on('bug', () => toast.warning( ... ))
|
|
94
|
+
/*context?.toast.warning("Bug detected",
|
|
114
95
|
"A bug report has been sent, because I've detected a bug on the interface. I'm really sorry for the interruption.",
|
|
115
96
|
null,
|
|
116
97
|
{ autohide: false });*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
};
|
|
120
101
|
}
|
|
121
102
|
|
|
122
|
-
public abstract handleError(
|
|
123
|
-
|
|
103
|
+
public abstract handleError(error: CoreError | Error): void;
|
|
104
|
+
|
|
124
105
|
public abstract handleUpdate(): void;
|
|
125
106
|
|
|
126
107
|
// TODO: move on app side
|
|
127
|
-
public reportBug = (infos: TBugReportInfos) =>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
public setLayout(layout: Layout) {
|
|
108
|
+
public reportBug = (infos: TBugReportInfos) =>
|
|
109
|
+
fetch('/feedback/bug/ui', {
|
|
110
|
+
method: 'POST',
|
|
111
|
+
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
url: window.location.pathname,
|
|
114
|
+
context: JSON.stringify((window as Window & { ssr?: unknown }).ssr),
|
|
115
|
+
guiVersion: BUILD_DATE,
|
|
116
|
+
...infos,
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
public setLayout(_layout: Layout) {
|
|
142
121
|
throw new Error(`page.setLayout has been called before the function is assigned from the <App /> component.`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
122
|
+
}
|
|
123
|
+
}
|
package/client/app/service.ts
CHANGED
|
@@ -2,33 +2,28 @@
|
|
|
2
2
|
- DEPENDANCES
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
|
-
import type Application from
|
|
5
|
+
import type Application from '.';
|
|
6
6
|
|
|
7
7
|
/*----------------------------------
|
|
8
8
|
- TYPES: OPTIONS
|
|
9
9
|
----------------------------------*/
|
|
10
10
|
|
|
11
|
-
export type AnyService = Service<{}, Application
|
|
11
|
+
export type AnyService = Service<{}, Application>;
|
|
12
12
|
|
|
13
13
|
/*----------------------------------
|
|
14
14
|
- CLASS
|
|
15
15
|
----------------------------------*/
|
|
16
|
-
export default abstract class Service<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
> {
|
|
20
|
-
public constructor(
|
|
21
|
-
public app: TApplication,
|
|
16
|
+
export default abstract class Service<TConfig extends {}, TApplication extends Application> {
|
|
17
|
+
public constructor(
|
|
18
|
+
public app: TApplication,
|
|
22
19
|
public config: TConfig,
|
|
23
20
|
) {
|
|
24
|
-
|
|
25
21
|
// 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.`);
|
|
22
|
+
if (typeof window === 'undefined') throw new Error(`Client services shouldn't be loaded on server side.`);
|
|
28
23
|
|
|
29
24
|
// Make the app aware of his services
|
|
30
25
|
app.registerService(this);
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
public abstract start(): void;
|
|
34
|
-
}
|
|
29
|
+
}
|
package/client/app.tsconfig.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"@common/*": ["../node_modules/proteum/common/*"],
|
|
10
10
|
|
|
11
11
|
// Only used for typings (ex: ServerResponse)
|
|
12
|
-
// Removed before
|
|
12
|
+
// Removed before bundling
|
|
13
13
|
"@server/*": ["../node_modules/proteum/server/*"],
|
|
14
14
|
"@/*": ["./*"],
|
|
15
15
|
|
|
@@ -25,4 +25,4 @@
|
|
|
25
25
|
".",
|
|
26
26
|
"../../node_modules/proteum/types/global"
|
|
27
27
|
]
|
|
28
|
-
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { ComponentChild } from 'preact';
|
|
8
|
+
|
|
9
|
+
type TDialogControls = { close: (returnedValue?: unknown) => void; then: (cb: (value: unknown) => void) => void };
|
|
10
|
+
|
|
11
|
+
type TDialogActions = {
|
|
12
|
+
setToasts: (setter: (old: ComponentChild[]) => ComponentChild[]) => void;
|
|
13
|
+
setModals: (setter: (old: ComponentChild[]) => ComponentChild[]) => void;
|
|
14
|
+
show: (...args: unknown[]) => TDialogControls;
|
|
15
|
+
loading: (title: string) => TDialogControls;
|
|
16
|
+
info: (...args: unknown[]) => TDialogControls;
|
|
17
|
+
success: (...args: unknown[]) => TDialogControls;
|
|
18
|
+
warning: (...args: unknown[]) => TDialogControls;
|
|
19
|
+
error: (...args: unknown[]) => TDialogControls;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const noopControls = (): TDialogControls => ({ close: () => undefined, then: () => undefined });
|
|
23
|
+
|
|
24
|
+
export const createDialog = (_app?: unknown, _isToast?: boolean): TDialogActions => ({
|
|
25
|
+
setToasts: () => undefined,
|
|
26
|
+
setModals: () => undefined,
|
|
27
|
+
show: () => noopControls(),
|
|
28
|
+
loading: () => noopControls(),
|
|
29
|
+
info: () => noopControls(),
|
|
30
|
+
success: () => noopControls(),
|
|
31
|
+
warning: () => noopControls(),
|
|
32
|
+
error: () => noopControls(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/*----------------------------------
|
|
36
|
+
- COMPOSANT
|
|
37
|
+
----------------------------------*/
|
|
38
|
+
export default function DialogManager() {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
@@ -8,7 +8,7 @@ import { ComponentChild } from 'preact';
|
|
|
8
8
|
|
|
9
9
|
// Core
|
|
10
10
|
import useContext from '@/client/context';
|
|
11
|
-
import {
|
|
11
|
+
import { focusContent } from '@client/utils/dom';
|
|
12
12
|
|
|
13
13
|
// Specific
|
|
14
14
|
import type Application from '../../app';
|
|
@@ -21,123 +21,135 @@ import type Application from '../../app';
|
|
|
21
21
|
- TYPES: DECLARATIONS
|
|
22
22
|
----------------------------------*/
|
|
23
23
|
|
|
24
|
-
type TParams = { [cle: string]: unknown }
|
|
24
|
+
type TParams = { [cle: string]: unknown };
|
|
25
25
|
|
|
26
|
-
type
|
|
26
|
+
type CardInfos = TParams & {
|
|
27
|
+
title?: string;
|
|
28
|
+
content?: ComponentChild;
|
|
29
|
+
boutons?: ComponentChild;
|
|
30
|
+
type?: string;
|
|
31
|
+
close?: (returnedValue?: unknown) => void;
|
|
32
|
+
isToast?: boolean;
|
|
33
|
+
};
|
|
27
34
|
|
|
28
|
-
type
|
|
29
|
-
content?: ComponentChild,
|
|
30
|
-
data?: {},
|
|
31
|
-
className?: string,
|
|
32
|
-
})
|
|
35
|
+
type TDialogRendererProps = CardInfos & { isToast?: boolean };
|
|
33
36
|
|
|
34
|
-
type
|
|
37
|
+
type ComposantToast = React.ComponentType<TDialogRendererProps> & { data?: object };
|
|
38
|
+
|
|
39
|
+
type TOptsToast = CardInfos & { content?: ComponentChild; data?: {}; className?: string };
|
|
40
|
+
|
|
41
|
+
type TOnCloseCallback<TReturnType extends any> = (returnedValue: TReturnType) => void;
|
|
35
42
|
|
|
36
43
|
type TToastShortcutArgs = [
|
|
37
|
-
title: TOptsToast[
|
|
38
|
-
content?: TOptsToast[
|
|
39
|
-
boutons?: TOptsToast[
|
|
44
|
+
title: TOptsToast['title'],
|
|
45
|
+
content?: TOptsToast['content'],
|
|
46
|
+
boutons?: TOptsToast['boutons'],
|
|
40
47
|
options?: TOptsToast,
|
|
41
|
-
]
|
|
48
|
+
];
|
|
42
49
|
|
|
43
|
-
export type TDialogControls = {
|
|
44
|
-
close: TOnCloseCallback<any>,
|
|
45
|
-
then: (cb: TOnCloseCallback<any>) => any
|
|
46
|
-
}
|
|
50
|
+
export type TDialogControls = { close: TOnCloseCallback<any>; then: (cb: TOnCloseCallback<any>) => any };
|
|
47
51
|
|
|
48
52
|
type TDialogContentArg = ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast;
|
|
49
53
|
|
|
50
|
-
type TDialogShowArgs =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
type TDialogShowArgs =
|
|
55
|
+
| [
|
|
56
|
+
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
57
|
+
Content: TDialogContentArg,
|
|
58
|
+
paramsInit?: TParams,
|
|
59
|
+
]
|
|
60
|
+
| [
|
|
61
|
+
title: string,
|
|
62
|
+
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
63
|
+
Content: TDialogContentArg,
|
|
64
|
+
paramsInit?: TParams,
|
|
65
|
+
];
|
|
60
66
|
|
|
61
67
|
type DialogActions = {
|
|
68
|
+
setToasts: (setter: (old: ComponentChild[]) => ComponentChild[]) => void;
|
|
69
|
+
setModals: (setter: (old: ComponentChild[]) => ComponentChild[]) => void;
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
setModals: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
|
|
71
|
+
show: (...args: TDialogShowArgs) => TDialogControls;
|
|
65
72
|
|
|
66
|
-
|
|
73
|
+
loading: (title: string) => TDialogControls;
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
info: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls;
|
|
69
76
|
|
|
70
|
-
|
|
77
|
+
success: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls;
|
|
71
78
|
|
|
72
|
-
|
|
79
|
+
warning: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls;
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
error: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls,
|
|
77
|
-
}
|
|
81
|
+
error: (...[title, content, boutons, options]: TToastShortcutArgs) => TDialogControls;
|
|
82
|
+
};
|
|
78
83
|
|
|
79
84
|
/*----------------------------------
|
|
80
85
|
- SERVICE CONTEXTE
|
|
81
86
|
----------------------------------*/
|
|
82
87
|
let idA: number = 0;
|
|
83
|
-
export const createDialog = (app: Application, isToast: boolean): DialogActions => {
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
const isPromiseContent = (value: TDialogContentArg): value is Promise<{ default: ComposantToast }> =>
|
|
90
|
+
typeof value === 'object' && value !== null && 'then' in value;
|
|
86
91
|
|
|
92
|
+
const isDialogRenderer = (value: TDialogContentArg): value is ComposantToast => typeof value === 'function';
|
|
93
|
+
|
|
94
|
+
const DefaultDialogContent = ({ title, content, boutons, type, isToast }: TDialogRendererProps) => (
|
|
95
|
+
<div class={`dialog-card${type ? ` ${type}` : ''}${isToast ? ' is-toast' : ''}`}>
|
|
96
|
+
{title ? <header>{title}</header> : null}
|
|
97
|
+
{content ? <div class="dialog-card__content">{content}</div> : null}
|
|
98
|
+
{boutons ? <footer>{boutons}</footer> : null}
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
export const createDialog = (app: Application, isToast: boolean): DialogActions => {
|
|
103
|
+
const show = <TReturnType extends any = true>(...args: TDialogShowArgs): TDialogControls => {
|
|
87
104
|
let onClose: TOnCloseCallback<TReturnType>;
|
|
88
105
|
const id = idA++;
|
|
89
106
|
|
|
90
107
|
// Parse args
|
|
91
|
-
let title: string | undefined;
|
|
108
|
+
let title: string | undefined;
|
|
92
109
|
let Content: TDialogContentArg;
|
|
93
110
|
let paramsInit: TParams = {};
|
|
94
111
|
if (typeof args[0] === 'string') {
|
|
95
|
-
[
|
|
112
|
+
const [nextTitle, nextContent, nextParams] = args as [string, TDialogContentArg, TParams?];
|
|
113
|
+
title = nextTitle;
|
|
114
|
+
Content = nextContent;
|
|
115
|
+
paramsInit = nextParams || {};
|
|
96
116
|
} else {
|
|
97
|
-
[
|
|
117
|
+
const [nextContent, nextParams] = args as [TDialogContentArg, TParams?];
|
|
118
|
+
Content = nextContent;
|
|
119
|
+
paramsInit = nextParams || {};
|
|
98
120
|
}
|
|
99
121
|
|
|
100
122
|
// Set instance management function
|
|
101
|
-
const setDialog = isToast
|
|
102
|
-
? instance.setToasts
|
|
103
|
-
: instance.setModals;
|
|
123
|
+
const setDialog = isToast ? instance.setToasts : instance.setModals;
|
|
104
124
|
|
|
105
125
|
// Close function
|
|
106
126
|
const close = (retour: TReturnType) => {
|
|
127
|
+
setDialog((q) =>
|
|
128
|
+
(q as Array<ComponentChild & { id?: number }>).filter((m) => m && m.id !== id) as ComponentChild[],
|
|
129
|
+
);
|
|
107
130
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (onClose !== undefined)
|
|
111
|
-
onClose(retour);
|
|
131
|
+
if (onClose !== undefined) onClose(retour);
|
|
112
132
|
};
|
|
113
133
|
|
|
114
134
|
const promise = new Promise(async (resolve: TOnCloseCallback<TReturnType>) => {
|
|
115
|
-
onClose = resolve
|
|
135
|
+
onClose = resolve;
|
|
116
136
|
|
|
117
137
|
let render: ComponentChild;
|
|
118
|
-
let propsRendu:
|
|
119
|
-
|
|
120
|
-
close: close
|
|
121
|
-
};
|
|
122
|
-
|
|
138
|
+
let propsRendu: TDialogRendererProps = { ...paramsInit, close: close };
|
|
139
|
+
|
|
123
140
|
// modal.show( import('./modalSupprimer') )
|
|
124
141
|
// -> Fetch component
|
|
125
|
-
if (Content
|
|
126
|
-
Content = (await Content).default;
|
|
142
|
+
if (isPromiseContent(Content)) Content = (await Content).default;
|
|
127
143
|
|
|
128
144
|
// modal.show('Supprimer', import('./modalSupprimer'))
|
|
129
|
-
// -> Shortcut for
|
|
130
|
-
if (title !== undefined)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
// -> Shortcut for passing a title to the component or default card renderer.
|
|
146
|
+
if (title !== undefined) propsRendu.title = title;
|
|
147
|
+
|
|
148
|
+
if (isDialogRenderer(Content)) {
|
|
149
|
+
render = <Content {...propsRendu} isToast={isToast} />;
|
|
150
|
+
} else {
|
|
151
|
+
render = <DefaultDialogContent {...propsRendu} {...Content} isToast={isToast} />;
|
|
135
152
|
}
|
|
136
|
-
// modal.show( ToastSupprimer )
|
|
137
|
-
// -> Content is a component rendering a Card
|
|
138
|
-
render = (
|
|
139
|
-
<Content {...propsRendu} isToast={isToast} />
|
|
140
|
-
)
|
|
141
153
|
|
|
142
154
|
// Chargeur de données
|
|
143
155
|
/*if (('data' in ComposantCharge) && typeof ComposantCharge.data === 'function') {
|
|
@@ -149,115 +161,72 @@ export const createDialog = (app: Application, isToast: boolean): DialogActions
|
|
|
149
161
|
await execFetchersState(fetchersStateA);
|
|
150
162
|
|
|
151
163
|
}*/
|
|
152
|
-
|
|
153
|
-
if (!isToast)
|
|
154
|
-
render = (
|
|
155
|
-
<div class="modal">
|
|
156
|
-
{render}
|
|
157
|
-
</div>
|
|
158
|
-
)
|
|
159
164
|
|
|
160
|
-
render
|
|
165
|
+
if (!isToast) render = <div class="modal">{render}</div>;
|
|
161
166
|
|
|
162
|
-
|
|
167
|
+
(render as ComponentChild & { id?: number }).id = id;
|
|
168
|
+
|
|
169
|
+
setDialog((q) => [...q, render]);
|
|
163
170
|
});
|
|
164
171
|
|
|
165
|
-
return {
|
|
166
|
-
close,
|
|
167
|
-
then: (cb) => promise.then(cb)
|
|
168
|
-
}
|
|
172
|
+
return { close, then: (cb) => promise.then(cb) };
|
|
169
173
|
};
|
|
170
174
|
|
|
171
175
|
const instance: DialogActions = {
|
|
172
|
-
|
|
173
176
|
show: show,
|
|
174
177
|
|
|
175
|
-
setToasts:
|
|
176
|
-
setModals:
|
|
177
|
-
|
|
178
|
-
loading: (title: string) => show({
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
title: title,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
boutons,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
title: title,
|
|
193
|
-
type: 'success',
|
|
194
|
-
content: content && <p>{content}</p>,
|
|
195
|
-
boutons,
|
|
196
|
-
...options
|
|
197
|
-
}),
|
|
198
|
-
|
|
199
|
-
warning: (...[title, content, boutons, options]: TToastShortcutArgs) => show({
|
|
200
|
-
title: title,
|
|
201
|
-
type: 'warn',
|
|
202
|
-
content: content && <p>{content}</p>,
|
|
203
|
-
boutons,
|
|
204
|
-
...options
|
|
205
|
-
}),
|
|
206
|
-
|
|
207
|
-
error: (...[title, content, boutons, options]: TToastShortcutArgs) => show({
|
|
208
|
-
title: title,
|
|
209
|
-
type: 'error',
|
|
210
|
-
content: content && <p>{content}</p>,
|
|
211
|
-
boutons,
|
|
212
|
-
...options
|
|
213
|
-
}),
|
|
214
|
-
}
|
|
178
|
+
setToasts: () => undefined,
|
|
179
|
+
setModals: () => undefined,
|
|
180
|
+
|
|
181
|
+
loading: (title: string) => show({ title: title, type: 'loading' }),
|
|
182
|
+
|
|
183
|
+
info: (...[title, content, boutons, options]: TToastShortcutArgs) =>
|
|
184
|
+
show({ title: title, type: 'info', content: content && <p>{content}</p>, boutons, ...options }),
|
|
185
|
+
|
|
186
|
+
success: (...[title, content, boutons, options]: TToastShortcutArgs) =>
|
|
187
|
+
show({ title: title, type: 'success', content: content && <p>{content}</p>, boutons, ...options }),
|
|
188
|
+
|
|
189
|
+
warning: (...[title, content, boutons, options]: TToastShortcutArgs) =>
|
|
190
|
+
show({ title: title, type: 'warn', content: content && <p>{content}</p>, boutons, ...options }),
|
|
191
|
+
|
|
192
|
+
error: (...[title, content, boutons, options]: TToastShortcutArgs) =>
|
|
193
|
+
show({ title: title, type: 'error', content: content && <p>{content}</p>, boutons, ...options }),
|
|
194
|
+
};
|
|
215
195
|
|
|
216
196
|
return instance;
|
|
217
|
-
}
|
|
197
|
+
};
|
|
218
198
|
|
|
219
199
|
/*----------------------------------
|
|
220
200
|
- COMPOSANT
|
|
221
201
|
----------------------------------*/
|
|
222
202
|
import './index.less';
|
|
223
203
|
export default () => {
|
|
224
|
-
|
|
225
204
|
const app = useContext();
|
|
226
205
|
|
|
227
206
|
const [modals, setModals] = React.useState<ComponentChild[]>([]);
|
|
228
207
|
const [toasts, setToasts] = React.useState<ComponentChild[]>([]);
|
|
229
208
|
|
|
230
|
-
if (app.side === 'client') {
|
|
231
|
-
app.modal.setModals = setModals;
|
|
232
|
-
app.toast.setToasts = setToasts;
|
|
209
|
+
if (app.side === 'client' && app.modal && app.toast) {
|
|
210
|
+
(app.modal as DialogActions).setModals = setModals;
|
|
211
|
+
(app.toast as DialogActions).setToasts = setToasts;
|
|
233
212
|
}
|
|
234
213
|
|
|
235
214
|
React.useEffect(() => {
|
|
236
|
-
|
|
237
215
|
console.log('Updated toast list');
|
|
238
216
|
|
|
239
|
-
const modals = document.querySelectorAll(
|
|
240
|
-
if (modals.length === 0)
|
|
241
|
-
return;
|
|
217
|
+
const modals = document.querySelectorAll('#modals > .modal');
|
|
218
|
+
if (modals.length === 0) return;
|
|
242
219
|
|
|
243
220
|
// Focus
|
|
244
|
-
const lastToast = modals[
|
|
245
|
-
focusContent(
|
|
246
|
-
|
|
221
|
+
const lastToast = modals[modals.length - 1];
|
|
222
|
+
focusContent(lastToast as HTMLElement);
|
|
247
223
|
});
|
|
248
|
-
|
|
249
|
-
return
|
|
250
|
-
|
|
251
|
-
<div id="modals">
|
|
252
|
-
|
|
253
|
-
</div>
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
<div id="toasts">
|
|
258
|
-
{toasts}
|
|
259
|
-
</div>
|
|
260
|
-
) : null}
|
|
261
|
-
</>
|
|
262
|
-
|
|
263
|
-
}
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<>
|
|
227
|
+
{modals.length !== 0 ? <div id="modals">{modals}</div> : null}
|
|
228
|
+
|
|
229
|
+
{toasts.length !== 0 ? <div id="toasts">{toasts}</div> : null}
|
|
230
|
+
</>
|
|
231
|
+
);
|
|
232
|
+
};
|
|
@@ -11,7 +11,7 @@ export const SuccessAnimation = (
|
|
|
11
11
|
</g>
|
|
12
12
|
</svg>
|
|
13
13
|
</div>
|
|
14
|
-
)
|
|
14
|
+
);
|
|
15
15
|
|
|
16
16
|
export const WarningAnimation = (
|
|
17
17
|
<div class="svg-box">
|
|
@@ -29,7 +29,7 @@ export const WarningAnimation = (
|
|
|
29
29
|
</g>
|
|
30
30
|
</svg>
|
|
31
31
|
</div>
|
|
32
|
-
)
|
|
32
|
+
);
|
|
33
33
|
|
|
34
34
|
export const ErrorAnimation = (
|
|
35
35
|
<div class="svg-box">
|
|
@@ -45,4 +45,4 @@ export const ErrorAnimation = (
|
|
|
45
45
|
</g>
|
|
46
46
|
</svg>
|
|
47
47
|
</div>
|
|
48
|
-
)
|
|
48
|
+
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Link } from '../services/router/components/Link';
|
|
1
|
+
export { Link } from '../services/router/components/Link';
|