5htp-core 0.4.2 → 0.4.3

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.
Files changed (48) hide show
  1. package/package.json +4 -12
  2. package/src/client/app/component.tsx +11 -2
  3. package/src/client/assets/css/components/button.less +10 -10
  4. package/src/client/assets/css/components/other.less +0 -1
  5. package/src/client/assets/css/core.less +0 -4
  6. package/src/client/assets/css/text/text.less +1 -2
  7. package/src/client/assets/css/text/titres.less +0 -5
  8. package/src/client/assets/css/utils/layouts.less +5 -5
  9. package/src/client/assets/css/utils/sizing.less +6 -6
  10. package/src/client/components/Dialog/card.tsx +1 -1
  11. package/src/client/components/button.tsx +1 -1
  12. package/src/client/components/containers/Popover/index.tsx +2 -2
  13. package/src/client/components/index.ts +5 -16
  14. package/src/client/components/inputv3/index.tsx +2 -5
  15. package/src/client/services/router/components/Page.tsx +1 -2
  16. package/src/client/services/router/components/router.tsx +4 -8
  17. package/src/client/services/router/request/api.ts +31 -52
  18. package/src/client/services/router/response/index.tsx +2 -0
  19. package/src/common/data/dates.ts +50 -6
  20. package/src/common/router/layouts.ts +14 -5
  21. package/src/common/router/response/page.ts +12 -6
  22. package/src/common/validation/validators.ts +0 -4
  23. package/src/server/app/container/config.ts +2 -1
  24. package/src/server/services/router/http/index.ts +16 -22
  25. package/src/server/services/router/response/page/index.tsx +0 -0
  26. package/src/client/assets/fonts/Inter/index.less +0 -77
  27. package/src/client/assets/fonts/Inter/latin-500.woff2 +0 -0
  28. package/src/client/assets/fonts/Inter/latin-600.woff2 +0 -0
  29. package/src/client/assets/fonts/Inter/latin-800.woff2 +0 -0
  30. package/src/client/assets/fonts/Inter/latin-ext-500.woff2 +0 -0
  31. package/src/client/assets/fonts/Inter/latin-ext-600.woff2 +0 -0
  32. package/src/client/assets/fonts/Inter/latin-ext-800.woff2 +0 -0
  33. package/src/client/assets/fonts/Rubik/cyrillic-ext.woff2 +0 -0
  34. package/src/client/assets/fonts/Rubik/cyrillic.woff2 +0 -0
  35. package/src/client/assets/fonts/Rubik/hebrew.woff2 +0 -0
  36. package/src/client/assets/fonts/Rubik/index.less +0 -30
  37. package/src/client/assets/fonts/Rubik/latin-ext.woff2 +0 -0
  38. package/src/client/assets/fonts/Rubik/latin.woff2 +0 -0
  39. package/src/client/components/Amount.tsx +0 -38
  40. package/src/client/components/Form_old/index.tsx +0 -450
  41. package/src/client/components/Form_old/index.tsx.old +0 -436
  42. package/src/client/components/dropdown.old/Manager.tsx +0 -164
  43. package/src/client/components/dropdown.old/getPosition.ts +0 -137
  44. package/src/client/components/dropdown.old/index.tsx +0 -99
  45. package/src/client/components/dropdown.old/popover.less +0 -56
  46. package/src/client/components/input/Base/Choix.ts +0 -48
  47. package/src/client/components/input/Base/index.tsx +0 -432
  48. package/src/client/components/input/BaseV2/index.tsx +0 -72
@@ -1,450 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import React from 'react';
7
- import { ComponentChild, FunctionComponent } from 'preact';
8
- import dottie from 'dottie';
9
-
10
- // Libs
11
- import { TListeErreursSaisie, InputErrorSchema } from '@common/errors';
12
- import { propsDefautChampForm, TBasePropsChamp } from '@client/components/input/Base';
13
- import { TSchema, TRetourValidation, initDonnees, validate as validerSchema, TSchemaChampComplet } from '@common/data/input/validate';
14
- import { simpleDeepCopy, chemin } from '@common/data/objets';
15
- import { ContexteOnglets } from '@client/components/containers/tabs';
16
- import useContext from '@/client/context';
17
-
18
- /*----------------------------------
19
- - TYPES ENTREE
20
- ----------------------------------*/
21
-
22
- export type TComposantChamps<TDonnees> = { [nomChamp in keyof TDonnees]: ComponentChild };
23
-
24
- type TPropsHook<TDonnees extends TObjetDonnees> = {
25
-
26
- // Informations générales
27
- //nom: string,
28
- donnees?: TDonnees,
29
-
30
- // Présentation & état
31
- progression?: false | number,
32
- autosave?: boolean,
33
- readOnly?: boolean,
34
-
35
- // Actions
36
- onChange?: (donnees: TDonnees, validation: TRetourValidation<TDonnees> | false) => void,
37
- afterValidation?: (validation: TRetourValidation<TDonnees>) => void,
38
- refActions?: (actionsForm: TActionsForm<TDonnees>) => void,
39
- onSet?: { [nomChamp: string]: (anciennesDonnees: TDonnees, nouvellesDonnees: TDonnees) => TDonnees }
40
-
41
- // Champs
42
- propsChamps?: { [cle: string]: any }
43
- }
44
-
45
-
46
- /*----------------------------------
47
- - TYPES SORTIE
48
- ----------------------------------*/
49
-
50
- type TChamps = {[name: string]: FunctionComponent<TBasePropsChamp<any, any, any>>}
51
-
52
- export type TActionsForm<TDonnees extends TObjetDonnees> = {
53
-
54
- envoyer: (e?: any) => Promise<void>,
55
- set: (valeurs: Partial<TDonnees>) => void,
56
- get: (champ?: string) => any | TDonnees,
57
-
58
- saisie: Partial<TDonnees>,
59
- form: TActionsForm<TDonnees>,
60
- schema: TSchema,
61
- changes: number
62
- }
63
-
64
- /*----------------------------------
65
- - COMPOSANTS
66
- ----------------------------------*/
67
-
68
- const debug = false;
69
-
70
- export const useForm = <TDonnees extends TObjetDonnees>(
71
- schema: TSchema,
72
- send: string | ((donnees: TDonnees) => Promise < boolean | undefined | void>),
73
- props: TPropsHook<TDonnees> = {}
74
- ): [TChamps, TActionsForm<TDonnees>, TDonnees] => {
75
-
76
- const refChamps = React.useRef<{ [nomChamp: string]: HTMLElement }>({});
77
-
78
- const { api } = useContext();
79
-
80
- /*----------------------------------
81
- - INIT
82
- ----------------------------------*/
83
-
84
- // State
85
- const [state, setState] = React.useState<{
86
- donnees: Partial<TDonnees>,
87
- erreurs: TListeErreursSaisie,
88
- errorsCount: number,
89
- progression: false | number,
90
- changed: Partial<TDonnees> // Nom des champs changés depuis le dernier enregistrement
91
- }>({
92
- donnees: props.donnees || {},
93
- erreurs: {},
94
- errorsCount: 0,
95
- progression: false,
96
- changed: {}
97
- });
98
-
99
- const donneesExternes = props.donnees !== undefined && props.onChange !== undefined;
100
- const donneesInit = ((donneesExternes ? props.donnees : state.donnees) || {}) as Partial<TDonnees>
101
- const donnees = initDonnees(schema, donneesInit, true);
102
-
103
- /*----------------------------------
104
- - METHODES
105
- ----------------------------------*/
106
- function get(champ: string): any;
107
- function get(): TDonnees;
108
- function get(champ?: string): any | TDonnees {
109
- return champ === undefined
110
- ? donnees
111
- : donnees[champ];
112
- }
113
-
114
- async function set<TNomDonnee extends keyof TDonnees>(nom: TNomDonnee, valeur: TDonnees[TNomDonnee]): Promise<void>;
115
- async function set<TNomDonnee extends keyof TDonnees>(donnees: Partial<TDonnees>): Promise<void>;
116
- async function set<TNomDonnee extends keyof TDonnees>(...args:
117
- [donnees: Partial<TDonnees>]
118
- |
119
- [nom: TNomDonnee, valeur: TDonnees[TNomDonnee]]
120
- ): Promise<void> {
121
-
122
- if (args.length === 1)
123
- await onChange(args[0]);
124
- else
125
- await onChange({ [args[0]]: args[1] } as unknown as Partial<TDonnees>);
126
-
127
- }
128
-
129
- async function onChange(
130
- valeursInit: Partial<TDonnees>,
131
- newState: Partial<typeof state> = {},
132
- ): Promise<{ erreurs: TListeErreursSaisie, errorsCount: number }> {
133
-
134
- // RAPPEL: donnees = anciennes données
135
-
136
- // TODO: Saisie champ: si saisieManuelle, set state local et appel props.onchange quand onblur, sinon appel props.onchange direct
137
- // Le useEffect mettra à jour le state s différence entre state.valeur et props.valeur
138
- let changees: Partial<TDonnees> = {};
139
- for (const cle in valeursInit)
140
- if (valeursInit[cle] !== donnees[cle])
141
- changees[cle] = valeursInit[cle];
142
-
143
- if (debug) console.log(`[form][saisie] onChange`, changees);
144
-
145
- let errorsCount: number = 0;
146
- let erreurs: TListeErreursSaisie = {}
147
- if (Object.keys(changees).length !== 0) {
148
-
149
- // Validation des données changées
150
- // TODO: conserver erreurs des champs n'ayant pas été changés
151
- let nouvellesDonnees: Partial<TDonnees>;
152
- ({
153
- valeurs: nouvellesDonnees,
154
- errorsCount,
155
- erreurs
156
- } = await valider(valeursInit));
157
-
158
- if (debug && errorsCount !== 0) console.log(`[form][saisie] erreurs`, erreurs);
159
-
160
- newState.erreurs = erreurs;
161
- newState.errorsCount = errorsCount;
162
-
163
- // Validation & mapping personnalisé
164
- /*if (props.filtres?.after)
165
- nouvellesDonnees = props.filtres.after(nouvellesDonnees, donnees);*/
166
-
167
- // Copie + fusion sans références
168
- const donneesCompletes = simpleDeepCopy(donnees, nouvellesDonnees);
169
- const changed = { ...state.changed, ...nouvellesDonnees };
170
-
171
- // Màj valeur + erreurs
172
- // Le passage d'une fonction permet de récupérer le dernier state, ce qui évite à composantChamps de redevenir undefined
173
- setState((stateA) => ({
174
- ...stateA,
175
- donnees: donneesCompletes,
176
- changed: changed,
177
- ...newState
178
- }));
179
-
180
- if (props.onChange && errorsCount === 0)
181
- props.onChange(donneesCompletes, { valeurs: nouvellesDonnees, errorsCount, erreurs, changed });
182
-
183
- /*if (valider && props.autosave === true) {
184
-
185
- if (props.envoyer === undefined)
186
- throw new Error("autosave = true, mais aucune fonction d'enregistrement n'est passée dans props.envoyer");
187
-
188
- await envoyer();
189
-
190
-
191
- }*/
192
- }
193
-
194
- return { erreurs, errorsCount };
195
- }
196
-
197
- async function valider(
198
- donneesAvalider: Partial<TDonnees>
199
- ): Promise<TRetourValidation<TDonnees>> {
200
-
201
- console.log(`[form][saisie] Valider`, donneesAvalider, 'Données complètes =', donnees);
202
-
203
- // Pas de valeur pécifiées = on valide toutes les données du form
204
- const retour = await validerSchema(schema, donneesAvalider, donnees, undefined, {
205
- corriger: true
206
- });
207
-
208
- // Focus sur le premier champ ayant déclenché une erreur
209
- if (retour.errorsCount !== 0) {
210
-
211
- const cheminChamp = Object.keys(retour.erreurs)[0]
212
- const champ = chemin.get(schema, cheminChamp);
213
-
214
- // Scroll
215
- const elemChamp = refChamps.current[cheminChamp];
216
- elemChamp?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' })
217
-
218
-
219
- }
220
-
221
- if (props.afterValidation !== undefined)
222
- props.afterValidation(retour, actions);
223
-
224
- return retour;
225
- }
226
-
227
- async function envoyer(additionnalData: TObjetDonnees = {}): Promise<boolean> {
228
-
229
- if (props.readOnly)
230
- return false;
231
-
232
- // Déjà en cours d'envoi
233
- if (props.progression !== undefined && props.progression !== false)
234
- return false;
235
-
236
- if (state.errorsCount !== 0)
237
- return false;
238
-
239
- console.log(`[form][saisie] Envoyer`, donnees);
240
-
241
- // Validation de l'ensemble des champs
242
- const { erreurs, errorsCount, valeurs } = await valider(donnees);
243
- if (errorsCount !== 0) {
244
- setState((stateA) => ({ ...stateA, erreurs, errorsCount }));
245
- console.error('Erreurs formulaire', erreurs);
246
- return false;
247
- }
248
-
249
- console.log("@@@ Envoi formulaire 2", valeurs);
250
-
251
- // Envoi
252
- if (send !== undefined) {
253
-
254
- if (!('progression' in props))
255
- setState((stateA) => ({ ...stateA, progression: 0 }));
256
-
257
- if (typeof send === 'string') {
258
- const url = send;
259
- send = (donnees: TDonnees) => api.post(url, donnees).run();
260
- }
261
-
262
- // Ayant été validée, on estime que les données sont complètes
263
- return await send({ ...donnees, ...additionnalData }).then((envoye: boolean | undefined) => {
264
-
265
- if (envoye !== false) {
266
-
267
- setState((stateA) => ({
268
- ...stateA,
269
- progression: ('progression' in props)
270
- ? stateA.progression
271
- : false,
272
- changed: {} // Reset de la liste des données changées
273
- }));
274
-
275
- return true;
276
- } else
277
- return false;
278
-
279
- }).catch((e) => {
280
-
281
- if (debug) console.log("RETOUR ERREURS API", e);
282
-
283
- if (e instanceof InputErrorSchema) {
284
-
285
- setState((stateA) => ({
286
- ...stateA,
287
- erreurs: e.erreursSaisie,
288
- progression: 'progression' in props ? stateA.progression : false
289
- }));
290
-
291
- } else
292
- throw e;
293
-
294
- return false;
295
-
296
- });
297
- }
298
-
299
- return false;
300
- }
301
-
302
- /*----------------------------------
303
- - RENDU CHAMPS
304
- ----------------------------------*/
305
- function rendreChamp(
306
- champ: TSchemaChampComplet | undefined,
307
- donneesSchema: TObjetDonnees | undefined,
308
- chemin: string,
309
- propsChamp: TObjetDonnees
310
- ) {
311
-
312
- // Inexistant
313
- if (champ === undefined)
314
- return 'Champ inexistant: ' + chemin;
315
-
316
- const { rendu, as, activer, ...attrs } = champ;
317
-
318
- // Désactivé
319
- if (activer !== undefined && activer(donnees) === false)
320
- return null;
321
-
322
- // N'est pas destiné à être rendu
323
- if (rendu === undefined)
324
- return null;
325
-
326
- const schemaPath = chemin.split('.');
327
- const nomChamp = schemaPath.pop() as string;
328
-
329
- // Correction valeur selon as
330
- const valeur = donneesSchema === undefined
331
- ? undefined
332
- : (as === undefined
333
- ? donneesSchema[nomChamp]
334
- // Champ composé de plusieurs valeurs
335
- : as.map((nomDonnee) => donneesSchema[nomDonnee])
336
- );
337
-
338
- // Rendu
339
- return React.createElement( rendu, {
340
- // Config par défaut pour les champs appartenant au form (ex: label systèmatique)
341
- ...propsDefautChampForm,
342
-
343
- // Attributs définis via le schema
344
- ...attrs,
345
- // Attributs définis via l'appel du composant
346
- ...propsChamp,
347
-
348
- // Rattachement au form
349
- ref: (ref: HTMLElement) => refChamps.current[chemin] = ref?.base,
350
- nom: nomChamp,
351
- valeur: valeur,
352
- as: as,
353
- valider: undefined, // Pas de validation dans le champ. On fait tous les champs em même temps depuis le form
354
- erreurs: state.erreurs[chemin],
355
- readOnly: props.readOnly, // Si le form est readonly, alors tous ses champs le sont obligatoirement
356
- onChange: async (nouvelleValeur: any) => {
357
-
358
- // Mapping données
359
- let nouvellesDonnees: Partial<TDonnees>;
360
- if (as !== undefined) {
361
- nouvellesDonnees = dottie.transform({
362
- [[...schemaPath, as[0]].join('.')]: nouvelleValeur[0],
363
- [[...schemaPath, as[1]].join('.')]: nouvelleValeur[1]
364
- });
365
- // Mapping classique
366
- } else
367
- nouvellesDonnees = dottie.transform({
368
- [chemin]: nouvelleValeur
369
- });
370
-
371
- // Application des changements
372
- const { errorsCount } = await onChange(nouvellesDonnees, {});
373
-
374
- // Si aucune erreur, onChange propre au champ + gestion erreurs
375
- if (propsChamp.onChange !== undefined && errorsCount === 0)
376
- await propsChamp.onChange(nouvelleValeur).catch((e) => {
377
- setState((stateA) => ({
378
- ...stateA,
379
- erreurs: {
380
- ...stateA.erreurs,
381
- [chemin]: [e]
382
- }
383
- }));
384
- })
385
- },
386
- });
387
-
388
- }
389
-
390
- /*----------------------------------
391
- - RETOUR
392
- ----------------------------------*/
393
-
394
- // Will be transformed by babel
395
- const Champs = {
396
- schema,
397
- data: donnees,
398
- render: rendreChamp
399
- } as unknown as TChamps
400
-
401
- const actions = {
402
- envoyer,
403
- get,
404
- set,
405
- render: rendreChamp,
406
- schema,
407
- changes: Object.keys(state.changed).length
408
- }
409
-
410
- return [Champs, actions, donnees];
411
- }
412
-
413
- export default <TDonnees extends TObjetDonnees>({
414
-
415
- ...props
416
-
417
- }: React.JSX.HTMLAttributes<HTMLFormElement> & {}) => {
418
-
419
- const refForm = React.useRef<HTMLFormElement>(null);
420
- const ctx = useContext();
421
-
422
- // Autofocus
423
- React.useEffect(() => {
424
-
425
- const firstInput = refForm.current?.querySelector("[autofocus]");
426
- if (firstInput) {
427
-
428
- //ctx.Application.requestFocus();
429
- firstInput.focus();
430
- firstInput.select();
431
- firstInput.click();
432
-
433
- }
434
-
435
- });
436
-
437
- const submit = (e) => {
438
- e.preventDefault();
439
- return false;
440
- }
441
-
442
- return (
443
- <form {...props} ref={refForm} onSubmit={submit} />
444
- );
445
-
446
- /*
447
- <Chargement progression={'progression' in props ? props.progression : state.progression}>
448
- </Chargement>
449
- */
450
- }