@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
@@ -19,19 +19,22 @@ function getObservables(observable) {
19
19
  set.add(publisher);
20
20
  return set;
21
21
  }
22
- return new Set(observable);
22
+ return new Set([observable]);
23
23
  }
24
24
  class ObserveDirective extends AsyncDirective {
25
- constructor() {
26
- super(...arguments);
25
+ unsubscribe() {
26
+ this.observables.forEach((publisher) => publisher.offAssign(this.onAssign));
27
+ }
28
+ /* eslint-disable @typescript-eslint/no-explicit-any*/
29
+ constructor(partInfo) {
30
+ super(partInfo);
27
31
  this.observables = new Set();
28
32
  this.onAssign = (v) => {
29
33
  this.setValue(v);
30
34
  };
35
+ this.node = partInfo.options?.host;
31
36
  }
32
- unsubscribe() {
33
- this.observables.forEach((publisher) => publisher.offAssign(this.onAssign));
34
- }
37
+ /* eslint-enable @typescript-eslint/no-explicit-any*/
35
38
  render(observable) {
36
39
  if (this.observable !== observable) {
37
40
  this.observable = observable;
@@ -63,7 +66,7 @@ class ObserveDirective extends AsyncDirective {
63
66
  // When the directive is disconnected from the DOM, unsubscribe to ensure
64
67
  // the directive instance can be garbage collected
65
68
  disconnected() {
66
- this.unsubscribe?.();
69
+ this.unsubscribe();
67
70
  }
68
71
  // If the subtree the directive is in was disconnected and subsequently
69
72
  // re-connected, re-subscribe to make the directive operable again
@@ -82,6 +85,18 @@ export const sub = dir;
82
85
  export const get = (id) => {
83
86
  return getObservables(id).values().next().value.get();
84
87
  };
85
- const deepee = (id) => getObservables(id).values().next();
88
+ const deepee = (id, defaultValue) => {
89
+ const value = getObservables(id).values().next().value;
90
+ if (defaultValue !== undefined) {
91
+ const innerValue = value.get();
92
+ if (Objects.isEmpty(innerValue)) {
93
+ value.set(defaultValue);
94
+ }
95
+ }
96
+ return value;
97
+ };
86
98
  export const dataProvider = deepee;
87
99
  export const dp = deepee;
100
+ export const set = (id, value) => {
101
+ getObservables(id).values().next().value.set(value);
102
+ };
@@ -0,0 +1,42 @@
1
+ import { AsyncDirective } from "lit/async-directive.js";
2
+ import { APIConfiguration } from "@supersoniks/concorde/core/utils/api";
3
+ import API from "@supersoniks/concorde/core/utils/api";
4
+ import { SearchableDomElement } from "../utils/HTML";
5
+ type ApiCallKey = {
6
+ apiConfiguration: APIConfiguration;
7
+ wordingProvider: string | null;
8
+ wordingVersionProvider: string | null;
9
+ };
10
+ type ApiCallValue = {
11
+ api: API;
12
+ keysToTranslate: Set<string>;
13
+ translatedKeys: Set<string>;
14
+ wordingProvider: string | null;
15
+ callIndex: number;
16
+ wordingVersionProvider: string | null;
17
+ apiCallKey: ApiCallKey;
18
+ };
19
+ export declare const loadingString = "";
20
+ export declare const isWordingReady: (key: string) => boolean;
21
+ export default class WordingDirective extends AsyncDirective {
22
+ static publisher: any;
23
+ unsubscribe(): void;
24
+ key?: string;
25
+ node?: SearchableDomElement;
26
+ useUnsafeHTML: boolean;
27
+ constructor(partInfo: any);
28
+ render(key: string, useUnsafeHTML?: boolean): symbol;
29
+ static firstCall: boolean;
30
+ static callApi(node: SearchableDomElement | null, key: string, relaunch?: boolean, usedApiCall?: ApiCallValue): Promise<void>;
31
+ static versionProviderHandlers: Map<ApiCallValue, (v: number) => void>;
32
+ static handleVersionProvider(node: SearchableDomElement): ((v: number) => void) | undefined;
33
+ onAssign: (v: unknown) => void;
34
+ subscribe(key: string): void;
35
+ disconnected(): void;
36
+ reconnected(): void;
37
+ }
38
+ export declare const wording: (key: string, useUnsafeHTML?: boolean | undefined) => import("lit-html/directive").DirectiveResult<typeof WordingDirective>;
39
+ export declare const unsafeWording: (key: string) => import("lit-html/directive").DirectiveResult<typeof WordingDirective>;
40
+ export declare const t: (key: string, useUnsafeHTML?: boolean | undefined) => import("lit-html/directive").DirectiveResult<typeof WordingDirective>;
41
+ export declare const w: (key: string, useUnsafeHTML?: boolean | undefined) => import("lit-html/directive").DirectiveResult<typeof WordingDirective>;
42
+ export {};
@@ -0,0 +1,202 @@
1
+ import { AsyncDirective } from "lit/async-directive.js";
2
+ import { directive } from "lit/directive.js";
3
+ import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
4
+ import { dp } from "@supersoniks/concorde/core/directives/DataProvider";
5
+ import { noChange } from "lit";
6
+ import API from "@supersoniks/concorde/core/utils/api";
7
+ import Objects from "../utils/Objects";
8
+ import HTML from "../utils/HTML";
9
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
10
+ const apiCalls = new Map();
11
+ const getApiCall = (node) => {
12
+ if (!node)
13
+ return null;
14
+ const configuration = HTML.getApiConfiguration(node);
15
+ const wordingProvider = HTML.getAncestorAttributeValue(node, "wordingProvider");
16
+ const wordingVersionProvider = HTML.getAncestorAttributeValue(node, "wordingVersionProvider");
17
+ const searchedKey = { apiConfiguration: configuration, wordingProvider: wordingProvider, wordingVersionProvider: wordingVersionProvider };
18
+ //touver une api avec la même configuration en comparant les avec l'utilitaire Objects deepEqual
19
+ let apiCall = null;
20
+ for (const [key, value] of apiCalls) {
21
+ if (Objects.deepEqual(key, searchedKey)) {
22
+ apiCall = value;
23
+ break;
24
+ }
25
+ }
26
+ if (!apiCall) {
27
+ const api = new API(configuration);
28
+ apiCall = {
29
+ api,
30
+ keysToTranslate: new Set(),
31
+ translatedKeys: new Set(),
32
+ wordingProvider,
33
+ callIndex: 0,
34
+ wordingVersionProvider: wordingVersionProvider,
35
+ apiCallKey: searchedKey,
36
+ };
37
+ apiCalls.set(searchedKey, apiCall);
38
+ }
39
+ return apiCall;
40
+ };
41
+ export const loadingString = "";
42
+ export const isWordingReady = (key) => {
43
+ const value = WordingDirective.publisher["wording_" + key].get();
44
+ return value !== loadingString && value != null;
45
+ };
46
+ class WordingDirective extends AsyncDirective {
47
+ unsubscribe() {
48
+ WordingDirective.publisher["wording_" + this.key].offAssign(this.onAssign);
49
+ }
50
+ /* eslint-disable @typescript-eslint/no-explicit-any*/
51
+ constructor(partInfo) {
52
+ super(partInfo);
53
+ this.useUnsafeHTML = false;
54
+ this.onAssign = (v) => {
55
+ const value = this.useUnsafeHTML ? unsafeHTML(v) : v;
56
+ this.setValue(value);
57
+ };
58
+ this.node = partInfo.options.host; // options n'est pas déclaré sur PartInfo mais exist en réalité d'où le typage "any"
59
+ }
60
+ /* eslint-enable @typescript-eslint/no-explicit-any*/
61
+ render(key, useUnsafeHTML = false) {
62
+ this.useUnsafeHTML = useUnsafeHTML;
63
+ if (this.key !== key) {
64
+ this.key = key;
65
+ if (this.isConnected) {
66
+ this.subscribe(key);
67
+ }
68
+ }
69
+ return noChange;
70
+ }
71
+ static async callApi(node, key, relaunch = true, usedApiCall) {
72
+ await PublisherManager.getInstance().isLocalStrorageReady;
73
+ if (WordingDirective.firstCall) {
74
+ WordingDirective.firstCall = false;
75
+ //clean keys of the publisher that are equivalent to the loading string
76
+ const keys = Object.keys(WordingDirective.publisher.get());
77
+ for (const key of keys) {
78
+ if (WordingDirective.publisher.get()[key] === loadingString) {
79
+ delete WordingDirective.publisher[key];
80
+ }
81
+ }
82
+ }
83
+ if (node) {
84
+ const wordingVersionProvider = HTML.getAncestorAttributeValue(node, "wordingVersionProvider");
85
+ if (wordingVersionProvider) {
86
+ dp(wordingVersionProvider).onAssign(WordingDirective.handleVersionProvider(node));
87
+ }
88
+ }
89
+ let hasWordingForKey = WordingDirective.publisher.get()["wording_" + key] != null;
90
+ const apiCall = usedApiCall || getApiCall(node);
91
+ if (!apiCall)
92
+ return;
93
+ if (hasWordingForKey && key !== "") {
94
+ apiCall.translatedKeys.add(key);
95
+ return;
96
+ }
97
+ apiCall.callIndex++;
98
+ const callIndex = apiCall.callIndex;
99
+ const wordingProvider = apiCall.wordingProvider ?? "";
100
+ // if the wording provider is unfortunately not set, we don't call the api now.
101
+ // We will try later
102
+ if (!wordingProvider && relaunch) {
103
+ window.setTimeout(async () => {
104
+ WordingDirective.callApi(null, key, false, apiCall);
105
+ }, 1000);
106
+ return;
107
+ }
108
+ //
109
+ //
110
+ const api = apiCall.api;
111
+ window.queueMicrotask(async () => {
112
+ hasWordingForKey = WordingDirective.publisher["wording_" + key].get() != null;
113
+ if (!hasWordingForKey && key !== "") {
114
+ apiCall.keysToTranslate.add(key);
115
+ WordingDirective.publisher["wording_" + key] = loadingString;
116
+ }
117
+ if (callIndex !== apiCall.callIndex)
118
+ return;
119
+ const wordings = Array.from(apiCall.keysToTranslate);
120
+ if (!wordings.length)
121
+ return;
122
+ const splittedUrl = wordingProvider.split("?");
123
+ const locationURL = splittedUrl.shift();
124
+ const queryString = (splittedUrl.length > 0 ? splittedUrl.join("?") + "&" : "") + "labels[]=" + wordings.join("&labels[]=");
125
+ const calledURL = locationURL + "?" + queryString;
126
+ apiCall.translatedKeys = new Set([...apiCall.translatedKeys, ...apiCall.keysToTranslate]);
127
+ apiCall.keysToTranslate.clear();
128
+ const result = (await api.get(calledURL));
129
+ for (const key in result) {
130
+ WordingDirective.publisher["wording_" + key] = result[key];
131
+ }
132
+ });
133
+ }
134
+ //check if the wording version has changed
135
+ static handleVersionProvider(node) {
136
+ const apiCall = getApiCall(node);
137
+ if (!apiCall)
138
+ return;
139
+ if (WordingDirective.versionProviderHandlers.has(apiCall)) {
140
+ return WordingDirective.versionProviderHandlers.get(apiCall);
141
+ }
142
+ const versionProviderHandler = function (version) {
143
+ const wordingVersionProvider = apiCall.wordingVersionProvider;
144
+ if (!wordingVersionProvider)
145
+ return;
146
+ //
147
+ const currentVersions = WordingDirective.publisher.get().__wording_versions__ ?? [];
148
+ if (version == null)
149
+ return;
150
+ const currentVersionData = currentVersions.find((v) => v.serviceURL === apiCall.api.serviceURL) || {
151
+ serviceURL: apiCall.api.serviceURL,
152
+ version: 0,
153
+ };
154
+ if (!currentVersions.includes(currentVersionData))
155
+ currentVersions.push(currentVersionData);
156
+ if (version === currentVersionData.version) {
157
+ return;
158
+ }
159
+ currentVersionData.version = version;
160
+ WordingDirective.publisher.set({ __wording_versions__: currentVersions });
161
+ for (const apiCall of apiCalls.values()) {
162
+ apiCall.keysToTranslate = new Set(apiCall.translatedKeys);
163
+ if (apiCall.keysToTranslate.size > 0) {
164
+ WordingDirective.callApi(null, "", false, apiCall);
165
+ }
166
+ }
167
+ };
168
+ WordingDirective.versionProviderHandlers.set(apiCall, versionProviderHandler);
169
+ return versionProviderHandler;
170
+ }
171
+ // Subscribes to the key, calling the directive's asynchronous
172
+ // setValue API each time the value changes
173
+ subscribe(key) {
174
+ this.unsubscribe();
175
+ // this.onAssign = (v: unknown) => {
176
+ // this.setValue(v);
177
+ // };
178
+ WordingDirective.publisher["wording_" + key].onAssign(this.onAssign);
179
+ WordingDirective.callApi(this.node, key);
180
+ }
181
+ // When the directive is disconnected from the DOM, unsubscribe to ensure
182
+ // the directive instance can be garbage collected
183
+ disconnected() {
184
+ this.unsubscribe();
185
+ }
186
+ // If the subtree the directive is in was disconnected and subsequently
187
+ // re-connected, re-subscribe to make the directive operable again
188
+ reconnected() {
189
+ if (!this.key)
190
+ return;
191
+ this.subscribe(this.key);
192
+ }
193
+ }
194
+ WordingDirective.publisher = PublisherManager.get("sonic-wording", { localStorageMode: "enabled" });
195
+ WordingDirective.firstCall = true;
196
+ WordingDirective.versionProviderHandlers = new Map();
197
+ export default WordingDirective;
198
+ //autoUpdate directive
199
+ export const wording = directive(WordingDirective);
200
+ export const unsafeWording = (key) => wording(key, true);
201
+ export const t = wording;
202
+ export const w = wording;
@@ -2,11 +2,13 @@
2
2
  import "@supersoniks/concorde/core/components/ui/button/button";
3
3
  import { SubscriberInterface } from "@supersoniks/concorde/core/mixins/Subscriber";
4
4
  import API from "@supersoniks/concorde/core/utils/api";
5
- import { PublisherContentType } from "../_types/types";
6
5
  import { MixinArgsType } from "../_types/types";
7
6
  import { ResultTypeInterface } from "@supersoniks/concorde/core/utils/api";
8
7
  type Constructor<T> = new (...args: MixinArgsType[]) => T;
9
- declare const Fetcher: <T extends Constructor<SubscriberInterface<PropsType>>, PropsType extends PublisherContentType = PublisherContentType>(superClass: T, propsType?: PropsType | undefined) => {
8
+ export declare const invalidateFetchersInError: () => void;
9
+ export declare const onFetchError: (errorListener: (apiResponse: Response) => void) => void;
10
+ export declare const offFetchError: (errorListener: (apiResponse: Response) => void) => void;
11
+ declare const Fetcher: <T extends Constructor<SubscriberInterface<PropsType>>, PropsType extends unknown = unknown>(superClass: T, propsType?: PropsType | undefined) => {
10
12
  new (...args: MixinArgsType[]): {
11
13
  api: API | null;
12
14
  /**
@@ -23,20 +25,19 @@ declare const Fetcher: <T extends Constructor<SubscriberInterface<PropsType>>, P
23
25
  */
24
26
  isLoading: boolean;
25
27
  lazyLoad?: boolean | undefined;
26
- noLoader?: boolean | undefined;
27
28
  /**
28
29
  * IObserver est l'intersection observer qui permet de charger les données au scroll si l'attribut lazyload est renseigné
29
30
  */
30
31
  iObserver: IntersectionObserver | null;
31
- /**
32
- * un loader est affiché par défaut si l'attribut noLoader n'est pas renseigné
33
- */
34
- isDefaultLoaderEnabled: boolean;
35
32
  /**
36
33
  * On peut désactiver le fetch programmatiquement via cette propriété.
37
34
  * Cela est le cas pour le composant sonic-list qui ne fetch que si l'attribut fetch est renseigné
38
35
  */
39
36
  isFetchEnabled: boolean;
37
+ /**
38
+ * Result of the fetch
39
+ */
40
+ fetchedData: any;
40
41
  _endPoint: string;
41
42
  props: (PropsType & ResultTypeInterface) | null;
42
43
  endPoint: string;
@@ -84,10 +85,6 @@ declare const Fetcher: <T extends Constructor<SubscriberInterface<PropsType>>, P
84
85
  getAttribute(name: string): string;
85
86
  hasAttribute(attributeName: string): boolean;
86
87
  getBoundingClientRect(): DOMRect;
87
- onConnected(callback: (component: any) => void): void;
88
- offConnected(callback: (component: any) => void): void;
89
- onDisconnected(callback: (component: any) => void): void;
90
- offDisconnected(callback: (component: any) => void): void;
91
88
  };
92
89
  } & T;
93
90
  export default Fetcher;
@@ -5,12 +5,31 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import "@supersoniks/concorde/core/components/ui/button/button";
8
- import { Loader } from "@supersoniks/concorde/core/components/ui/loader/loader";
9
8
  import { SonicToast } from "@supersoniks/concorde/core/components/ui/toast/toast";
10
9
  import API from "@supersoniks/concorde/core/utils/api";
11
10
  import Objects from "@supersoniks/concorde/core/utils/Objects";
12
11
  import { PublisherManager } from "@supersoniks/concorde/utils";
13
12
  import { property } from "lit/decorators.js";
13
+ const fetchersInError = new Set();
14
+ export const invalidateFetchersInError = () => {
15
+ const fetchersInErrorCopy = new Set(fetchersInError);
16
+ fetchersInError.clear();
17
+ for (const fetcher of fetchersInErrorCopy) {
18
+ fetcher._fetchData();
19
+ }
20
+ };
21
+ const errorsListeners = new Set();
22
+ export const onFetchError = (errorListener) => {
23
+ errorsListeners.add(errorListener);
24
+ };
25
+ export const offFetchError = (errorListener) => {
26
+ errorsListeners.delete(errorListener);
27
+ };
28
+ const dispatchFetchError = (apiResponse) => {
29
+ for (const listener of errorsListeners) {
30
+ listener(apiResponse);
31
+ }
32
+ };
14
33
  const Fetcher = (superClass, propsType) => {
15
34
  propsType;
16
35
  class FetcherElement extends superClass {
@@ -34,15 +53,15 @@ const Fetcher = (superClass, propsType) => {
34
53
  * IObserver est l'intersection observer qui permet de charger les données au scroll si l'attribut lazyload est renseigné
35
54
  */
36
55
  this.iObserver = null;
37
- /**
38
- * un loader est affiché par défaut si l'attribut noLoader n'est pas renseigné
39
- */
40
- this.isDefaultLoaderEnabled = true;
41
56
  /**
42
57
  * On peut désactiver le fetch programmatiquement via cette propriété.
43
58
  * Cela est le cas pour le composant sonic-list qui ne fetch que si l'attribut fetch est renseigné
44
59
  */
45
60
  this.isFetchEnabled = true;
61
+ /**
62
+ * Result of the fetch
63
+ */
64
+ this.fetchedData = null;
46
65
  this._endPoint = "";
47
66
  this.requestId = 0;
48
67
  this.refetchEveryMs = 0;
@@ -70,6 +89,7 @@ const Fetcher = (superClass, propsType) => {
70
89
  * Un Toast est affiché si le chargement échoue
71
90
  */
72
91
  async _fetchData() {
92
+ this.requestUpdate();
73
93
  if (!this.isFetchEnabled)
74
94
  return;
75
95
  this.api = new API(this.getApiConfiguration());
@@ -82,10 +102,6 @@ const Fetcher = (superClass, propsType) => {
82
102
  }
83
103
  if (!this.isConnected)
84
104
  return;
85
- const hasLoader = this.isDefaultLoaderEnabled && !this.noLoader;
86
- if (hasLoader) {
87
- Loader.show();
88
- }
89
105
  const headerData = PublisherManager.getInstance().get(this.getAncestorAttributeValue("headersDataProvider")).get();
90
106
  this.isLoading = true;
91
107
  if (Objects.isObject(this.props) && Object.keys(this.props || {}).length > 0 && this.isFirstLoad) {
@@ -96,33 +112,33 @@ const Fetcher = (superClass, propsType) => {
96
112
  });
97
113
  }
98
114
  let data = await this.api.get(this.endPoint || this.dataProvider || "", headerData);
115
+ this.fetchedData = data;
116
+ if (this.api.lastResult && !this.api.lastResult.ok) {
117
+ fetchersInError.add(this);
118
+ dispatchFetchError(this.api.lastResult);
119
+ }
99
120
  if (!this.isConnected) {
100
- if (hasLoader)
101
- Loader.hide();
102
121
  return;
103
122
  }
104
- // Je garde ça mais normalement ça n'arrive jamais
105
123
  if (!data) {
106
- SonicToast.add({ text: "Network Error", status: "error" });
124
+ // Cela n'arrive normalement que lorsque l'on quitte une page pendant un fetch on n'affiche donc pas de message
107
125
  this.isLoading = false;
108
- if (hasLoader) {
109
- Loader.hide();
126
+ if (this.refetchEveryMs && this.isConnected) {
127
+ this.refetchTimeOutId = setTimeout(() => this._fetchData(), this.refetchEveryMs);
110
128
  }
111
129
  return;
112
130
  }
113
- // Si data ne contient que la réponse HTTP, avec un statut not ok, on affiche un message
114
131
  else if (data._sonic_http_response_ && !data._sonic_http_response_.ok && Object.keys(data).length === 1) {
132
+ // Si data ne contient que la réponse HTTP, avec un statut not ok, on affiche un message
115
133
  SonicToast.add({ text: "Network Error", status: "error" });
116
134
  }
117
- if (hasLoader) {
118
- Loader.hide();
119
- }
120
135
  if (this.key) {
121
136
  const response = data._sonic_http_response_;
122
137
  /* preserveOtherKeys s'exprime lorsque le paramètre "key" est défini
123
138
  * Conserve les autres propriétés de l'objet reçu, en plus des propriétés définies sous "key"
124
139
  */
125
- data = Objects.traverse(data, this.key.split("."), this.hasAttribute("preserveOtherKeys"));
140
+ const path = this.key.split(".");
141
+ data = Objects.traverse(data, path, this.hasAttribute("preserveOtherKeys"));
126
142
  if (data && Objects.isObject(data) && response)
127
143
  data._sonic_http_response_ = response;
128
144
  }
@@ -143,12 +159,11 @@ const Fetcher = (superClass, propsType) => {
143
159
  connectedCallback() {
144
160
  // this.noShadowDom = "";
145
161
  this.lazyLoad = this.lazyLoad !== undefined ? this.lazyLoad : this.hasAttribute("lazyload");
146
- this.noLoader = this.noLoader !== undefined ? this.noLoader : this.hasAttribute("noloader");
147
162
  super.connectedCallback();
148
163
  if (!this.isFetchEnabled) {
149
164
  return;
150
165
  }
151
- this.key = this.getAttribute("key");
166
+ this.key = this.key != "" ? this.key : this.getAttribute("key");
152
167
  if (this.props) {
153
168
  this.publisher.set(this.props);
154
169
  }
@@ -174,6 +189,7 @@ const Fetcher = (superClass, propsType) => {
174
189
  const options = {
175
190
  root: null,
176
191
  rootMargin: Math.max(window.innerWidth * boundsRatio, window.innerHeight * boundsRatio) + "px",
192
+ threshold: 0.9,
177
193
  };
178
194
  this.iObserver = new IntersectionObserver((entries) => this.onIntersection(entries), options);
179
195
  let elt = (this.shadowRoot ? this.shadowRoot.children[0] : this.children[0]);
@@ -46,6 +46,7 @@ declare const Form: <T extends Constructor<FormElementInterface>>(superClass: T)
46
46
  getFormPublisher(): any;
47
47
  updateDataValue(): void;
48
48
  handleBlur(e?: Event | undefined): void;
49
+ setValueFromPublisher(value: string | object | string[] | null | undefined): void;
49
50
  focus?: (() => void) | undefined;
50
51
  shadowRoot?: ShadowRoot | undefined;
51
52
  error: boolean;
@@ -82,10 +83,6 @@ declare const Form: <T extends Constructor<FormElementInterface>>(superClass: T)
82
83
  getAttribute(name: string): string;
83
84
  hasAttribute(attributeName: string): boolean;
84
85
  getBoundingClientRect(): DOMRect;
85
- onConnected(callback: (component: any) => void): void;
86
- offConnected(callback: (component: any) => void): void;
87
- onDisconnected(callback: (component: any) => void): void;
88
- offDisconnected(callback: (component: any) => void): void;
89
86
  };
90
87
  } & T;
91
88
  export default Form;
@@ -9,6 +9,7 @@ export interface FormElementInterface extends SubscriberInterface {
9
9
  handleChange(e?: Event): void;
10
10
  handleBlur(e?: Event): void;
11
11
  getValueForFormPublisher(): FormElementValue;
12
+ setValueFromPublisher(value: FormElementValue): void;
12
13
  validateFormElement(): void;
13
14
  focus?: () => void;
14
15
  forceAutoFill: boolean;
@@ -39,7 +39,7 @@ const Form = (superClass) => {
39
39
  this.onValueAssign = (value) => {
40
40
  this.setValueFromPublisher(value);
41
41
  };
42
- this.onFormValueAssign = (value) => {
42
+ this.onFormValueAssign = async (value) => {
43
43
  this.setFormValueFromPublisher(value);
44
44
  };
45
45
  this.onFormDataInValidate = () => {
@@ -74,8 +74,7 @@ const Form = (superClass) => {
74
74
  }
75
75
  getFormPublisher() {
76
76
  if (!this.formDataProvider)
77
- this.formDataProvider =
78
- this.getAncestorAttributeValue("formDataProvider");
77
+ this.formDataProvider = this.getAncestorAttributeValue("formDataProvider");
79
78
  if (this.formDataProvider) {
80
79
  return PublisherManager.get(this.formDataProvider);
81
80
  }
@@ -121,9 +120,7 @@ const Form = (superClass) => {
121
120
  }
122
121
  initPublisher() {
123
122
  let formPublisher = this.getFormPublisher();
124
- const value = this.hasAncestorAttribute("initFromPublisher") &&
125
- this._name &&
126
- formPublisher[this._name].get()
123
+ const value = this.hasAncestorAttribute("initFromPublisher") && this._name && formPublisher[this._name].get()
127
124
  ? formPublisher[this._name].get()
128
125
  : this.getAttribute("value");
129
126
  if (this._name && this.publisher)
@@ -16,13 +16,15 @@ declare const Form: <T extends Constructor<FormElementInterface>>(superClass: T)
16
16
  description: string | undefined;
17
17
  _label?: string | undefined;
18
18
  label: string | undefined;
19
+ status: "default" | "success" | "error" | "warning" | "info";
19
20
  tabindex?: number | undefined;
20
- 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;
21
+ 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;
21
22
  getFormPublisher(): any;
22
23
  updateDataValue(): void;
23
24
  handleChange(e?: Event | undefined): void;
24
25
  handleBlur(e?: Event | undefined): void;
25
26
  getValueForFormPublisher(): string | object | string[] | null | undefined;
27
+ setValueFromPublisher(value: string | object | string[] | null | undefined): void;
26
28
  focus?: (() => void) | undefined;
27
29
  shadowRoot?: ShadowRoot | undefined;
28
30
  error: boolean;
@@ -63,10 +65,6 @@ declare const Form: <T extends Constructor<FormElementInterface>>(superClass: T)
63
65
  hasAttribute(attributeName: string): boolean;
64
66
  disconnectedCallback(): void;
65
67
  getBoundingClientRect(): DOMRect;
66
- onConnected(callback: (component: any) => void): void;
67
- offConnected(callback: (component: any) => void): void;
68
- onDisconnected(callback: (component: any) => void): void;
69
- offDisconnected(callback: (component: any) => void): void;
70
68
  };
71
69
  } & T;
72
70
  export default Form;
@@ -15,6 +15,7 @@ const Form = (superClass) => {
15
15
  * On peut essayer text, date, color, email par exemple, mais pas radio/checkbox/range a priori
16
16
  */
17
17
  this._type = "text";
18
+ this.status = "default";
18
19
  args;
19
20
  }
20
21
  validateFormElement() {
@@ -66,6 +67,9 @@ const Form = (superClass) => {
66
67
  __decorate([
67
68
  property()
68
69
  ], FormInput.prototype, "label", null);
70
+ __decorate([
71
+ property({ type: String, reflect: true })
72
+ ], FormInput.prototype, "status", void 0);
69
73
  __decorate([
70
74
  property({ type: Number })
71
75
  ], FormInput.prototype, "tabindex", void 0);
@@ -31,10 +31,6 @@ export interface SubscriberInterface<PropsType = CoreJSType> {
31
31
  hasAttribute(attributeName: string): boolean;
32
32
  disconnectedCallback(): void;
33
33
  getBoundingClientRect(): DOMRect;
34
- onConnected(callback: (component: any) => void): void;
35
- offConnected(callback: (component: any) => void): void;
36
- onDisconnected(callback: (component: any) => void): void;
37
- offDisconnected(callback: (component: any) => void): void;
38
34
  }
39
35
  declare const Subscriber: <PropsType = CoreJSType, T extends Constructor<LitElement> = Constructor<LitElement>>(superClass: T, type?: PropsType | undefined) => Constructor<SubscriberInterface<PropsType>> & T;
40
36
  export default Subscriber;