@supersoniks/concorde 2.0.2 → 2.0.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 (102) hide show
  1. package/README.md +1 -0
  2. package/concorde-core.bundle.js +748 -690
  3. package/concorde-core.es.js +3897 -3116
  4. package/core/_types/types.d.ts +2 -4
  5. package/core/components/functional/date/date.d.ts +4 -2
  6. package/core/components/functional/date/date.js +28 -13
  7. package/core/components/functional/fetch/fetch.d.ts +9 -10
  8. package/core/components/functional/fetch/fetch.js +21 -5
  9. package/core/components/functional/list/list.d.ts +7 -10
  10. package/core/components/functional/list/list.js +19 -4
  11. package/core/components/functional/queue/queue.d.ts +3 -2
  12. package/core/components/functional/queue/queue.js +66 -61
  13. package/core/components/functional/router/router.d.ts +1 -0
  14. package/core/components/functional/router/router.js +12 -1
  15. package/core/components/functional/sdui/sdui.d.ts +2 -7
  16. package/core/components/functional/submit/submit.js +11 -4
  17. package/core/components/ui/_css/scroll.js +13 -11
  18. package/core/components/ui/_css/size.js +1 -1
  19. package/core/components/ui/alert/alert.d.ts +14 -3
  20. package/core/components/ui/alert/alert.js +34 -4
  21. package/core/components/ui/badge/badge.js +10 -3
  22. package/core/components/ui/button/button.d.ts +19 -10
  23. package/core/components/ui/button/button.js +77 -22
  24. package/core/components/ui/captcha/captcha.d.ts +5 -4
  25. package/core/components/ui/captcha/captcha.js +33 -9
  26. package/core/components/ui/divider/divider.d.ts +2 -0
  27. package/core/components/ui/divider/divider.js +17 -2
  28. package/core/components/ui/form/checkbox/checkbox.d.ts +24 -9
  29. package/core/components/ui/form/checkbox/checkbox.js +4 -6
  30. package/core/components/ui/form/css/form-control.js +40 -7
  31. package/core/components/ui/form/fieldset/fieldset.d.ts +1 -0
  32. package/core/components/ui/form/fieldset/fieldset.js +14 -1
  33. package/core/components/ui/form/fieldset/legend-description.js +3 -3
  34. package/core/components/ui/form/fieldset/legend.js +2 -8
  35. package/core/components/ui/form/input/input.d.ts +4 -5
  36. package/core/components/ui/form/input/input.js +17 -13
  37. package/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts +3 -5
  38. package/core/components/ui/form/input-autocomplete/input-autocomplete.js +9 -9
  39. package/core/components/ui/form/select/select.d.ts +4 -1
  40. package/core/components/ui/form/select/select.js +25 -18
  41. package/core/components/ui/form/textarea/textarea.d.ts +4 -5
  42. package/core/components/ui/form/textarea/textarea.js +19 -10
  43. package/core/components/ui/group/group.js +3 -3
  44. package/core/components/ui/icon/icon.js +2 -1
  45. package/core/components/ui/icon/icons.d.ts +0 -4
  46. package/core/components/ui/icon/icons.js +3 -16
  47. package/core/components/ui/link/link.d.ts +5 -2
  48. package/core/components/ui/link/link.js +31 -2
  49. package/core/components/ui/loader/loader.d.ts +4 -1
  50. package/core/components/ui/loader/loader.js +11 -3
  51. package/core/components/ui/loader/styles/inline.js +14 -16
  52. package/core/components/ui/menu/menu-item.js +2 -1
  53. package/core/components/ui/menu/menu.js +6 -22
  54. package/core/components/ui/modal/modal-close.js +2 -1
  55. package/core/components/ui/modal/modal.d.ts +13 -1
  56. package/core/components/ui/modal/modal.js +70 -10
  57. package/core/components/ui/pop/pop.d.ts +9 -3
  58. package/core/components/ui/pop/pop.js +46 -23
  59. package/core/components/ui/table/table-tr.d.ts +10 -2
  60. package/core/components/ui/table/table-tr.js +30 -2
  61. package/core/components/ui/table/table.d.ts +1 -0
  62. package/core/components/ui/table/table.js +7 -1
  63. package/core/components/ui/theme/theme-collection/core-variables.js +8 -19
  64. package/core/components/ui/theme/theme.d.ts +6 -0
  65. package/core/components/ui/theme/theme.js +11 -13
  66. package/core/components/ui/toast/message-subscriber.d.ts +0 -8
  67. package/core/components/ui/toast/message-subscriber.js +0 -46
  68. package/core/components/ui/toast/toast-item.js +31 -40
  69. package/core/components/ui/toast/toast.d.ts +5 -1
  70. package/core/components/ui/toast/toast.js +80 -13
  71. package/core/components/ui/tooltip/tooltip.d.ts +3 -1
  72. package/core/components/ui/tooltip/tooltip.js +22 -0
  73. package/core/decorators/Subscriber.d.ts +3 -3
  74. package/core/decorators/Subscriber.js +64 -21
  75. package/core/directives/DataProvider.d.ts +12 -7
  76. package/core/directives/DataProvider.js +23 -8
  77. package/core/directives/Wording.d.ts +42 -0
  78. package/core/directives/Wording.js +202 -0
  79. package/core/mixins/Fetcher.d.ts +8 -11
  80. package/core/mixins/Fetcher.js +38 -22
  81. package/core/mixins/FormCheckable.d.ts +1 -4
  82. package/core/mixins/FormElement.d.ts +1 -0
  83. package/core/mixins/FormElement.js +3 -6
  84. package/core/mixins/FormInput.d.ts +3 -5
  85. package/core/mixins/FormInput.js +4 -0
  86. package/core/mixins/Subscriber.d.ts +0 -4
  87. package/core/mixins/Subscriber.js +13 -89
  88. package/core/mixins/TemplatesContainer.js +9 -0
  89. package/core/utils/Format.d.ts +1 -0
  90. package/core/utils/Format.js +16 -0
  91. package/core/utils/HTML.d.ts +13 -0
  92. package/core/utils/HTML.js +42 -3
  93. package/core/utils/Objects.d.ts +1 -0
  94. package/core/utils/Objects.js +5 -0
  95. package/core/utils/PublisherProxy.d.ts +16 -10
  96. package/core/utils/PublisherProxy.js +100 -64
  97. package/core/utils/Utils.d.ts +1 -0
  98. package/core/utils/Utils.js +5 -0
  99. package/core/utils/api.d.ts +26 -0
  100. package/core/utils/api.js +135 -3
  101. package/mixins.d.ts +6 -16
  102. package/package.json +7 -2
@@ -1,7 +1,12 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any*/
1
+ import HTML from "./HTML";
2
2
  function isComplex(value) {
3
3
  return typeof value === "object" && value != null;
4
4
  }
5
+ const queueTaskPromise = async () => {
6
+ return new Promise((resolve) => {
7
+ window.queueMicrotask(() => resolve(null));
8
+ });
9
+ };
5
10
  /**
6
11
  * Custom Proxy contient les méthodes des publishers retournés par PublisherManager.get(publisherId) qui seront utilisées couramment
7
12
  */
@@ -16,6 +21,7 @@ export class PublisherProxy {
16
21
  this._templateFillListeners_ = new Set();
17
22
  this._lockInternalMutationPublishing_ = false;
18
23
  this._instanceCounter_ = 0;
24
+ this._assignmentId_ = 0;
19
25
  this._value_ = target;
20
26
  this.parent = parentProxPub || null;
21
27
  this.root = this;
@@ -52,20 +58,26 @@ export class PublisherProxy {
52
58
  }
53
59
  _publishInternalMutation_(lockInternalMutationsTransmission = false) {
54
60
  this._mutationListeners_.forEach((handler) => handler());
55
- if (lockInternalMutationsTransmission)
56
- return;
57
- if (!PublisherManager.changed && this._is_savable_) {
61
+ if (this._is_savable_ && !PublisherManager.changed) {
58
62
  PublisherManager.changed = true;
59
63
  PublisherManager.saveId++;
60
64
  const saveId = PublisherManager.saveId;
61
65
  setTimeout(() => PublisherManager.getInstance().saveToLocalStorage(saveId), 1000);
62
66
  }
67
+ if (lockInternalMutationsTransmission)
68
+ return;
63
69
  if (this.parent) {
64
70
  this.parent._publishInternalMutation_();
65
71
  }
66
72
  }
67
- _publishAssignement_(lockInternalMutationsTransmission = false) {
68
- this._assignListeners_.forEach((handler) => handler(this.get()));
73
+ async _publishAssignement_(lockInternalMutationsTransmission = false) {
74
+ this._assignmentId_++;
75
+ const currentId = this._assignmentId_;
76
+ await queueTaskPromise();
77
+ if (currentId !== this._assignmentId_)
78
+ return;
79
+ const newValue = this.get();
80
+ this._assignListeners_.forEach((handler) => handler(newValue));
69
81
  this._publishInternalMutation_(lockInternalMutationsTransmission);
70
82
  }
71
83
  _publishInvalidation_() {
@@ -98,6 +110,8 @@ export class PublisherProxy {
98
110
  onAssign(handler, directHandlerCall = true) {
99
111
  if (typeof handler != "function")
100
112
  return;
113
+ if (this._assignListeners_.has(handler))
114
+ return;
101
115
  this._assignListeners_.add(handler);
102
116
  if (directHandlerCall)
103
117
  handler(this.get());
@@ -194,7 +208,7 @@ export class PublisherProxy {
194
208
  /**
195
209
  * Assigne une nouvelle valeur au proxy ce qui déclenche la transmission de la donnée en fonction des "écouteurs" associés
196
210
  */
197
- set(newValue, lockInternalMutationsTransmission = false) {
211
+ async set(newValue, lockInternalMutationsTransmission = false) {
198
212
  /**
199
213
  * On retounre tout de suite si la valeur n'a pas changé
200
214
  */
@@ -211,13 +225,14 @@ export class PublisherProxy {
211
225
  */
212
226
  const prevValue = this._value_;
213
227
  this._value_ = isComplex(newValue) ? newValue : { __value: newValue };
228
+ this._cachedGet_ = undefined;
214
229
  /**
215
230
  * Si il s'agit d'une valeur primitive (un entier, une chaine ) la valeure en renseignée par un objet contenant la vaeur {__value}
216
231
  * On publie juste et on sen va.
217
232
  */
218
233
  const isPrimitiveValue = Object.prototype.hasOwnProperty.call(this._value_, "__value");
219
234
  if (isPrimitiveValue) {
220
- this._publishAssignement_(lockInternalMutationsTransmission);
235
+ await this._publishAssignement_(lockInternalMutationsTransmission);
221
236
  return true;
222
237
  }
223
238
  /**
@@ -227,15 +242,14 @@ export class PublisherProxy {
227
242
  * On publie les maj au fur et a mesure de modifications
228
243
  */
229
244
  for (const key in this._value_) {
230
- if (typeof this._value_[key] === "undefined")
245
+ if (this._value_[key] === undefined)
231
246
  delete this._value_[key];
232
247
  }
233
- Array.from(this._proxies_.keys()).forEach((key) => {
248
+ this._proxies_.forEach((subProxy, key) => {
234
249
  /**
235
250
  * On supprime les proxys qui ne sont plus dans la nouvelle valeur si ils n'on pas d'écouteurs
236
251
  **/
237
- if (typeof this._value_[key] === "undefined" && this._proxies_.has(key)) {
238
- const subProxy = this._proxies_.get(key);
252
+ if (this._value_[key] === undefined) {
239
253
  if (!subProxy?.hasListener()) {
240
254
  this._proxies_.delete(key);
241
255
  }
@@ -250,7 +264,7 @@ export class PublisherProxy {
250
264
  /**
251
265
  * On prévient les écouteurs que la valeur a changé
252
266
  */
253
- this._publishAssignement_();
267
+ await this._publishAssignement_();
254
268
  /**
255
269
  * Si la donnée est complexe (objet, tableau)
256
270
  * on crée les proxys pour les sous-éléments qui n'en on pas
@@ -262,27 +276,29 @@ export class PublisherProxy {
262
276
  const isVComplex = isComplex(v);
263
277
  const valueV = isVComplex ? v : { __value: v };
264
278
  if (!this._proxies_.has(key)) {
265
- const newPublisher = new Publisher({}, this);
266
- this._proxies_.set(key, newPublisher);
267
- newPublisher._proxies_.set("_parent_", this);
279
+ // A surveiller ancienne version
280
+ // const newPublisher = new Publisher({}, this);
281
+ // this._proxies_.set(key, newPublisher);
282
+ // newPublisher._proxies_.set("_parent_", this);
283
+ this._publishDynamicFilling_(key, v);
284
+ continue;
268
285
  }
269
- this._proxies_.get(key)?.set(valueV, true);
286
+ await this._proxies_.get(key)?.set(valueV, true);
270
287
  this._publishDynamicFilling_(key, v);
271
288
  }
272
289
  }
273
290
  return true;
274
291
  }
275
- /**
276
- * Extraire la valeur actuelle du proxy
277
- */
278
292
  get() {
293
+ if (this._cachedGet_ !== undefined)
294
+ return this._cachedGet_;
279
295
  if (PublisherManager.modifiedCollectore.length > 0)
280
296
  PublisherManager.modifiedCollectore[0].add(this);
281
297
  if (Object.prototype.hasOwnProperty.call(this._value_, "__value")) {
282
298
  const v = this._value_.__value;
283
- return (v != undefined ? v : null);
299
+ return (this._cachedGet_ = (v != undefined ? v : null));
284
300
  }
285
- return this._value_;
301
+ return (this._cachedGet_ = this._value_);
286
302
  }
287
303
  /**
288
304
  * retourner le webcomponent auquel le proxy est associé
@@ -299,11 +315,9 @@ export class PublisherProxy {
299
315
  }
300
316
  PublisherProxy.instances = new Map();
301
317
  PublisherProxy.instancesCounter = 0;
302
- /**
303
- * Utilitaires de gestion des Publisher
304
- * Obtenir, replacer ou supprimer un Publisher
305
- *
306
- */
318
+ if (typeof __BUILD_DATE__ === "undefined") {
319
+ window.__BUILD_DATE__ = "No build date";
320
+ }
307
321
  export class PublisherManager {
308
322
  constructor() {
309
323
  this.enabledLocaStorageProxies = [];
@@ -383,6 +397,8 @@ export class PublisherManager {
383
397
  * shortcut static pour supprimer un publisher de la liste et appel également delete sur le publisher ce qui le supprime, de même que ses sous publishers
384
398
  */
385
399
  static delete(id) {
400
+ if (!id)
401
+ return false;
386
402
  return PublisherManager.getInstance().delete(id);
387
403
  }
388
404
  /**
@@ -391,7 +407,7 @@ export class PublisherManager {
391
407
  */
392
408
  async setLocalData(publisher, id) {
393
409
  await this.isLocalStrorageReady;
394
- publisher.set(this.localStorageData[id + "¤page:>" + document.location.pathname]?.data || publisher.get());
410
+ publisher.set(this.localStorageData[id + "¤lang_" + HTML.getLanguage()]?.data || publisher.get());
395
411
  }
396
412
  get(id, options) {
397
413
  const hasLocalStorage = options?.localStorageMode === "enabled";
@@ -416,7 +432,15 @@ export class PublisherManager {
416
432
  this.publishers.set(id, publisher);
417
433
  }
418
434
  /**
419
- * supprimer un publisher de la liste et appel également delete sur le publisher ce qui le supprime, de même que ses sous publishers
435
+ * @warning
436
+ * !!!!! ATTENTION !!!!!
437
+ * Il est fort à aprier que vous ne voulez pas utiliser cette methode
438
+ * Il s'agit d'une supression complete
439
+ * * du publisher de la liste
440
+ * * des bindings
441
+ * * de même que ses sous publishers
442
+ *
443
+ * UTILISEZ PLUTÔT la méthode publisher.set({}) pour réinitialiser un publisher sans perdre les ecouteurs
420
444
  */
421
445
  delete(id) {
422
446
  if (!this.publishers.has(id))
@@ -445,7 +469,7 @@ export class PublisherManager {
445
469
  const data = publisher?.get();
446
470
  if (!data)
447
471
  continue;
448
- this.localStorageData[key + "¤page:>" + document.location.pathname] = {
472
+ this.localStorageData[key + "¤lang_" + HTML.getLanguage()] = {
449
473
  lastModifiationMS: new Date().getTime(),
450
474
  data: data,
451
475
  };
@@ -495,11 +519,48 @@ export class PublisherManager {
495
519
  return new TextDecoder().decode(result);
496
520
  }
497
521
  }
522
+ PublisherManager.buildDate = __BUILD_DATE__;
498
523
  PublisherManager.changed = false;
499
524
  PublisherManager.saving = false;
500
525
  PublisherManager.saveId = 0;
501
526
  PublisherManager.instance = null;
502
527
  PublisherManager.modifiedCollectore = [];
528
+ const internalProps = new Set([
529
+ "invalidate",
530
+ "onInvalidate",
531
+ "offInvalidate",
532
+ "onAssign",
533
+ "offAssign",
534
+ "startDynamicFilling",
535
+ "stopDynamicFilling",
536
+ "startTemplateFilling",
537
+ "stopTemplateFilling",
538
+ "onInternalMutation",
539
+ "offInternalMutation",
540
+ "set",
541
+ "get",
542
+ "$tag",
543
+ "_cachedGet_",
544
+ "_templateFillListeners_",
545
+ "_fillListeners_",
546
+ "_assignListeners_",
547
+ "_invalidateListeners_",
548
+ "_publishInternalMutation_",
549
+ "hasListener",
550
+ "delete",
551
+ "_mutationListeners_",
552
+ "_publishDynamicFilling_",
553
+ "_publishInvalidation_",
554
+ "_publishTemplateFilling_",
555
+ "_publishAssignement_",
556
+ "_proxies_",
557
+ "parent",
558
+ "_value_",
559
+ "_is_savable_",
560
+ "_lockInternalMutationPublishing_",
561
+ "_instanceCounter_",
562
+ "_assignmentId_",
563
+ ]);
503
564
  /**
504
565
  * Le Proxy Javascript
505
566
  */
@@ -516,40 +577,7 @@ export default class Publisher extends PublisherProxy {
516
577
  if (sKey == Symbol.toPrimitive) {
517
578
  return () => thisProxy.get();
518
579
  }
519
- if ([
520
- "invalidate",
521
- "onInvalidate",
522
- "offInvalidate",
523
- "onAssign",
524
- "offAssign",
525
- "startDynamicFilling",
526
- "stopDynamicFilling",
527
- "startTemplateFilling",
528
- "stopTemplateFilling",
529
- "onInternalMutation",
530
- "offInternalMutation",
531
- "set",
532
- "get",
533
- "$tag",
534
- "_templateFillListeners_",
535
- "_fillListeners_",
536
- "_assignListeners_",
537
- "_invalidateListeners_",
538
- "_publishInternalMutation_",
539
- "hasListener",
540
- "delete",
541
- "_mutationListeners_",
542
- "_publishDynamicFilling_",
543
- "_publishInvalidation_",
544
- "_publishTemplateFilling_",
545
- "_publishAssignement_",
546
- "_proxies_",
547
- "parent",
548
- "_value_",
549
- "_is_savable_",
550
- "_lockInternalMutationPublishing_",
551
- "_instanceCounter_",
552
- ].includes(sKey))
580
+ if (internalProps.has(sKey))
553
581
  return publisherInstance[sKey];
554
582
  if (!publisherInstance._proxies_.has(sKey)) {
555
583
  const vValue = publisherInstance._value_[sKey];
@@ -569,6 +597,14 @@ export default class Publisher extends PublisherProxy {
569
597
  publisherInstance._value_ = vValue;
570
598
  return true;
571
599
  }
600
+ if (sKey == "_cachedGet_") {
601
+ publisherInstance._cachedGet_ = vValue;
602
+ return true;
603
+ }
604
+ if (sKey == "_assignmentId_") {
605
+ publisherInstance._assignmentId_ = vValue;
606
+ return true;
607
+ }
572
608
  if (sKey == "_is_savable_") {
573
609
  publisherInstance._is_savable_ = vValue;
574
610
  return true;
@@ -1,3 +1,4 @@
1
1
  export default class Utils {
2
+ static queueTaskPromise(): Promise<unknown>;
2
3
  static delayPromise(timeoutMs: number): Promise<unknown>;
3
4
  }
@@ -1,4 +1,9 @@
1
1
  export default class Utils {
2
+ static async queueTaskPromise() {
3
+ return new Promise((resolve) => {
4
+ window.queueMicrotask(() => resolve(null));
5
+ });
6
+ }
2
7
  static async delayPromise(timeoutMs) {
3
8
  return new Promise((resolve) => {
4
9
  setTimeout(resolve, timeoutMs);
@@ -1,6 +1,8 @@
1
1
  import { CoreJSType } from "@supersoniks/concorde/core/_types/types";
2
2
  export type APIConfiguration = {
3
3
  serviceURL: string | null;
4
+ /** un flag pour indiquer de bloquer les appels suivant au même serviceurl tant que celuis-ci n'a pas terminé */
5
+ blockUntilDone?: boolean;
4
6
  token: string | null;
5
7
  userName: string | null;
6
8
  password: string | null;
@@ -10,6 +12,7 @@ export type APIConfiguration = {
10
12
  credentials?: RequestCredentials;
11
13
  cache?: RequestCache;
12
14
  };
15
+ export type CallState = "loading" | "done" | "error" | undefined;
13
16
  export type ResultTypeInterface = CoreJSType & {
14
17
  _sonic_http_response_?: Response;
15
18
  text?: string;
@@ -70,18 +73,37 @@ declare class API {
70
73
  * Tableau static des tentatives échouées de récupération auto du token
71
74
  */
72
75
  static failledTokenUpdates: Map<string | null, true>;
76
+ /**
77
+ * Tableau static des flags pour savoir si le premier appel a été fait pour chaque serviceURL
78
+ */
79
+ static firstCallDoneFlags: Map<string | null, CallState>;
73
80
  /**
74
81
  * Le endPoint pour obtenir le bearer token qui sera concaténé à l'url du service
75
82
  */
76
83
  addHTTPResponse: boolean;
77
84
  cache: RequestCache;
78
85
  lastResult?: Response;
86
+ isServiceSimulated: boolean;
87
+ blockUntilDone: boolean;
79
88
  constructor(config: APIConfiguration);
80
89
  handleResult(fetchResult: Response, lastCall: APICall): Promise<ResultTypeInterface>;
81
90
  /**
82
91
  * Basic auth
83
92
  */
84
93
  auth(): Promise<void>;
94
+ /**
95
+ * avec localget, on ne passe pas par le système de token
96
+ * on recupère path sans les searchparams nommée pathWithoutSearchParams
97
+ * on cherche dans PublisherManager.get(pathWithoutSearchParams).get() les données qui matchent les searchparams présents dans path
98
+ * on retourne les données selon le même format que le retour de get
99
+ *
100
+ * @todo netttoyer
101
+ */
102
+ localGet<T>(dataProvider: string, searchString: string): Promise<T & ResultTypeInterface>;
103
+ /**
104
+ * firstCallDone is a function that returns a promise that is resolved when the first call to the API is done for each serviceURL whatever api instance is used
105
+ */
106
+ firstCallDone(): Promise<unknown>;
85
107
  get<T>(path: string, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
86
108
  /**
87
109
  * Création du header, avec authentification si besoin
@@ -105,6 +127,10 @@ declare class API {
105
127
  * Appel send en utilisant le méthode POST
106
128
  */
107
129
  post<T, SendType = CoreJSType>(path: string, data: SendType, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
130
+ /**
131
+ * Appel send en utilisant le méthode PATCH
132
+ */
133
+ patch<T, SendType = CoreJSType>(path: string, data: SendType, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
108
134
  /**
109
135
  * Appel send en utilisant le méthode delete
110
136
  */
package/core/utils/api.js CHANGED
@@ -2,6 +2,7 @@
2
2
  /* eslint no-async-promise-executor: 0 */ // --> OFF
3
3
  import HTML from "@supersoniks/concorde/core/utils/HTML";
4
4
  import Objects from "@supersoniks/concorde/core/utils/Objects";
5
+ import { PublisherManager } from "./PublisherProxy";
5
6
  class API {
6
7
  set token(token) {
7
8
  this._token = token;
@@ -31,7 +32,13 @@ class API {
31
32
  */
32
33
  this.addHTTPResponse = false;
33
34
  this.cache = "default";
35
+ this.isServiceSimulated = false;
36
+ this.blockUntilDone = false;
34
37
  this.serviceURL = config.serviceURL;
38
+ this.blockUntilDone = config.blockUntilDone || false;
39
+ if (this.serviceURL == "publisher://") {
40
+ this.isServiceSimulated = true;
41
+ }
35
42
  if (!this.serviceURL)
36
43
  this.serviceURL = document.location.origin;
37
44
  this.userName = config.userName;
@@ -45,6 +52,7 @@ class API {
45
52
  this.cache = config.cache || "default";
46
53
  }
47
54
  async handleResult(fetchResult, lastCall) {
55
+ API.firstCallDoneFlags.set(this.serviceURL, "done");
48
56
  this.lastResult = fetchResult;
49
57
  const contentType = fetchResult.headers.get("content-type")?.toLowerCase();
50
58
  const httpCode = fetchResult.status;
@@ -118,7 +126,116 @@ class API {
118
126
  API.failledTokenUpdates.set(this.serviceURL, true);
119
127
  }
120
128
  }
129
+ /**
130
+ * avec localget, on ne passe pas par le système de token
131
+ * on recupère path sans les searchparams nommée pathWithoutSearchParams
132
+ * on cherche dans PublisherManager.get(pathWithoutSearchParams).get() les données qui matchent les searchparams présents dans path
133
+ * on retourne les données selon le même format que le retour de get
134
+ *
135
+ * @todo netttoyer
136
+ */
137
+ async localGet(dataProvider, searchString) {
138
+ const publisher = PublisherManager.get(dataProvider);
139
+ console.log(publisher);
140
+ const searchParams = new URLSearchParams(searchString.split("?")[1] || "");
141
+ const dataObject = publisher.get();
142
+ let data = [];
143
+ if (!Array.isArray(dataObject)) {
144
+ data = [dataObject];
145
+ }
146
+ else {
147
+ data = dataObject;
148
+ }
149
+ const result = [];
150
+ let limit = Number.POSITIVE_INFINITY;
151
+ let offset = 0;
152
+ let limitOffsetparams = 0;
153
+ if (searchParams.has("limit")) {
154
+ limit = parseInt(searchParams.get("limit") || "0");
155
+ limitOffsetparams++;
156
+ }
157
+ if (searchParams.has("offset")) {
158
+ offset = parseInt(searchParams.get("offset") || "0");
159
+ limitOffsetparams++;
160
+ }
161
+ if (limitOffsetparams > 0) {
162
+ searchParams.delete("limit");
163
+ searchParams.delete("offset");
164
+ }
165
+ if (searchParams.size === 0)
166
+ return data.slice(offset, offset + limit);
167
+ for (const [key, value] of searchParams.entries()) {
168
+ const values = value.split(",").map((s) => s.trim());
169
+ for (const v of values) {
170
+ for (const item of data) {
171
+ //si l'item est une valeur primitive on regarde si vaue correspond à item simplement
172
+ if (typeof item !== "object") {
173
+ if (!isNaN(+value)) {
174
+ if (item == value) {
175
+ result.push(item);
176
+ }
177
+ }
178
+ else if (item.toString().includes(value)) {
179
+ result.push(item);
180
+ }
181
+ }
182
+ else {
183
+ const record = item;
184
+ //si l'item est un objet
185
+ //faire un comparaison de la version string de la même clef dans item pour voir si elle contient value
186
+ if (!record[key])
187
+ continue;
188
+ //si la valeur est un nombre, on compare les valeurs directement
189
+ if (!isNaN(+v)) {
190
+ if (record[key] == v) {
191
+ result.push(item);
192
+ }
193
+ }
194
+ else {
195
+ if (record[key]?.toString().toLowerCase().includes(v.toLowerCase())) {
196
+ result.push(item);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return result.slice(offset, offset + limit);
204
+ }
205
+ /**
206
+ * firstCallDone is a function that returns a promise that is resolved when the first call to the API is done for each serviceURL whatever api instance is used
207
+ */
208
+ firstCallDone() {
209
+ return new Promise((resolve) => {
210
+ if (!API.firstCallDoneFlags.has(this.serviceURL)) {
211
+ API.firstCallDoneFlags.set(this.serviceURL, "loading");
212
+ resolve(true);
213
+ }
214
+ else {
215
+ const loop = () => {
216
+ if (![undefined, "loading"].includes(API.firstCallDoneFlags.get(this.serviceURL))) {
217
+ resolve(true);
218
+ }
219
+ else {
220
+ window.requestAnimationFrame(loop);
221
+ }
222
+ };
223
+ loop();
224
+ }
225
+ });
226
+ }
121
227
  async get(path, additionalHeaders) {
228
+ await this.firstCallDone();
229
+ if (this.blockUntilDone) {
230
+ API.firstCallDoneFlags.set(this.serviceURL, "loading");
231
+ }
232
+ const regExp = /dataProvider\((.*?)\)(.*?)$/;
233
+ if (regExp.test(path)) {
234
+ const match = path.match(regExp);
235
+ if (!match)
236
+ throw new Error("dataProvider path is not valid");
237
+ return await this.localGet(match[1], match[2]);
238
+ }
122
239
  const lastCall = {
123
240
  apiMethod: "get",
124
241
  path: path,
@@ -132,9 +249,14 @@ class API {
132
249
  });
133
250
  if (!API.loadingGetPromises.has(mapKey)) {
134
251
  const promise = new Promise(async (resolve) => {
135
- const result = await fetch(url, { headers: headers, credentials: this.credentials, cache: this.cache });
136
- const handledResult = await this.handleResult(result, lastCall);
137
- resolve(handledResult);
252
+ try {
253
+ const result = await fetch(url, { headers: headers, credentials: this.credentials, cache: this.cache });
254
+ const handledResult = await this.handleResult(result, lastCall);
255
+ resolve(handledResult);
256
+ }
257
+ catch (e) {
258
+ resolve(null);
259
+ }
138
260
  });
139
261
  API.loadingGetPromises.set(mapKey, promise);
140
262
  }
@@ -233,6 +355,12 @@ class API {
233
355
  async post(path, data, additionalHeaders) {
234
356
  return this.send(path, data, "POST", additionalHeaders);
235
357
  }
358
+ /**
359
+ * Appel send en utilisant le méthode PATCH
360
+ */
361
+ async patch(path, data, additionalHeaders) {
362
+ return this.send(path, data, "PATCH", additionalHeaders);
363
+ }
236
364
  /**
237
365
  * Appel send en utilisant le méthode delete
238
366
  */
@@ -256,4 +384,8 @@ API.invalidTokens = [];
256
384
  * Tableau static des tentatives échouées de récupération auto du token
257
385
  */
258
386
  API.failledTokenUpdates = new Map();
387
+ /**
388
+ * Tableau static des flags pour savoir si le premier appel a été fait pour chaque serviceURL
389
+ */
390
+ API.firstCallDoneFlags = new Map();
259
391
  export default API;
package/mixins.d.ts CHANGED
@@ -1,15 +1,14 @@
1
1
  /// <reference types="node" />
2
- export declare const Fetcher: <T extends new (...args: any[]) => mySubscriber.SubscriberInterface<PropsType>, PropsType extends import("./core/_types/types").PublisherContentType = import("./core/_types/types").PublisherContentType>(superClass: T, propsType?: PropsType | undefined) => {
2
+ export declare const Fetcher: <T extends new (...args: any[]) => mySubscriber.SubscriberInterface<PropsType>, PropsType extends unknown = unknown>(superClass: T, propsType?: PropsType | undefined) => {
3
3
  new (...args: any[]): {
4
4
  api: import("./core/utils/api").default | null;
5
5
  key: string;
6
6
  isFirstLoad: boolean;
7
7
  isLoading: boolean;
8
8
  lazyLoad?: boolean | undefined;
9
- noLoader?: boolean | undefined;
10
9
  iObserver: IntersectionObserver | null;
11
- isDefaultLoaderEnabled: boolean;
12
10
  isFetchEnabled: boolean;
11
+ fetchedData: any;
13
12
  _endPoint: string;
14
13
  props: (PropsType & import("./core/utils/api").ResultTypeInterface) | null;
15
14
  endPoint: string;
@@ -48,10 +47,6 @@ export declare const Fetcher: <T extends new (...args: any[]) => mySubscriber.Su
48
47
  getAttribute(name: string): string;
49
48
  hasAttribute(attributeName: string): boolean;
50
49
  getBoundingClientRect(): DOMRect;
51
- onConnected(callback: (component: any) => void): void;
52
- offConnected(callback: (component: any) => void): void;
53
- onDisconnected(callback: (component: any) => void): void;
54
- offDisconnected(callback: (component: any) => void): void;
55
50
  };
56
51
  } & T;
57
52
  export declare const FormCheckable: <T extends new (...args: any[]) => myFormElement.FormElementInterface>(superClass: T) => {
@@ -78,6 +73,7 @@ export declare const FormCheckable: <T extends new (...args: any[]) => myFormEle
78
73
  getFormPublisher(): any;
79
74
  updateDataValue(): void;
80
75
  handleBlur(e?: Event | undefined): void;
76
+ setValueFromPublisher(value: string | object | string[] | null | undefined): void;
81
77
  focus?: (() => void) | undefined;
82
78
  shadowRoot?: ShadowRoot | undefined;
83
79
  error: boolean;
@@ -114,10 +110,6 @@ export declare const FormCheckable: <T extends new (...args: any[]) => myFormEle
114
110
  getAttribute(name: string): string;
115
111
  hasAttribute(attributeName: string): boolean;
116
112
  getBoundingClientRect(): DOMRect;
117
- onConnected(callback: (component: any) => void): void;
118
- offConnected(callback: (component: any) => void): void;
119
- onDisconnected(callback: (component: any) => void): void;
120
- offDisconnected(callback: (component: any) => void): void;
121
113
  };
122
114
  } & T;
123
115
  import * as myFormElement from "@supersoniks/concorde/core/mixins/FormElement";
@@ -132,13 +124,15 @@ export declare const FormInput: <T extends new (...args: any[]) => myFormElement
132
124
  description: string | undefined;
133
125
  _label?: string | undefined;
134
126
  label: string | undefined;
127
+ status: "error" | "default" | "success" | "warning" | "info";
135
128
  tabindex?: number | undefined;
136
- autocomplete?: "url" | "name" | "on" | "additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday-day" | "bday-month" | "bday-year" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "new-password" | "one-time-code" | "organization" | "postal-code" | "street-address" | "transaction-amount" | "transaction-currency" | "username" | "email" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "language" | "nickname" | "organization-title" | "cc-additional-name" | "bday" | "sex" | "impp" | "photo" | undefined;
129
+ autocomplete?: "url" | "name" | "off" | "on" | "additional-name" | "address-level1" | "address-level2" | "address-level3" | "address-level4" | "address-line1" | "address-line2" | "address-line3" | "bday-day" | "bday-month" | "bday-year" | "cc-csc" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-family-name" | "cc-given-name" | "cc-name" | "cc-number" | "cc-type" | "country" | "country-name" | "current-password" | "family-name" | "given-name" | "honorific-prefix" | "honorific-suffix" | "new-password" | "one-time-code" | "organization" | "postal-code" | "street-address" | "transaction-amount" | "transaction-currency" | "username" | "email" | "tel" | "tel-area-code" | "tel-country-code" | "tel-extension" | "tel-local" | "tel-national" | "language" | "nickname" | "organization-title" | "cc-additional-name" | "bday" | "sex" | "impp" | "photo" | undefined;
137
130
  getFormPublisher(): any;
138
131
  updateDataValue(): void;
139
132
  handleChange(e?: Event | undefined): void;
140
133
  handleBlur(e?: Event | undefined): void;
141
134
  getValueForFormPublisher(): string | object | string[] | null | undefined;
135
+ setValueFromPublisher(value: string | object | string[] | null | undefined): void;
142
136
  focus?: (() => void) | undefined;
143
137
  shadowRoot?: ShadowRoot | undefined;
144
138
  error: boolean;
@@ -179,10 +173,6 @@ export declare const FormInput: <T extends new (...args: any[]) => myFormElement
179
173
  hasAttribute(attributeName: string): boolean;
180
174
  disconnectedCallback(): void;
181
175
  getBoundingClientRect(): DOMRect;
182
- onConnected(callback: (component: any) => void): void;
183
- offConnected(callback: (component: any) => void): void;
184
- onDisconnected(callback: (component: any) => void): void;
185
- offDisconnected(callback: (component: any) => void): void;
186
176
  };
187
177
  } & T;
188
178
  import * as mySubscriber from "@supersoniks/concorde/core/mixins/Subscriber";