PluginProbe
seQura / 3.0.6
seQura v3.0.6
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / assets / js / src / core / StateController.js

StateController.js in seQura 3.0.6, at assets/js/src/core/StateController.js

445 lines 15.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 if (!window.SequraFE) {
2 window.SequraFE = {};
3 }
4
5 SequraFE.appStates = {
6 ONBOARDING: 'onboarding',
7 SETTINGS: 'settings',
8 PAYMENT: 'payment',
9 TRANSACTION: 'transactions',
10 ADVANCED: 'advanced'
11 };
12
13 SequraFE.appPages = {
14 ONBOARDING: {
15 CONNECT: 'connect',
16 COUNTRIES: 'countries',
17 WIDGETS: 'widgets'
18 },
19 SETTINGS: {
20 GENERAL: 'general',
21 CONNECTION: 'connection',
22 ORDER_STATUS: 'order_status',
23 WIDGET: 'widget'
24 },
25 PAYMENT: {
26 METHODS: 'methods'
27 },
28 TRANSACTION: {
29 LOGS: 'logs'
30 },
31 ADVANCED: {
32 DEBUG: 'debug'
33 }
34 };
35
36 (function () {
37 /**
38 * @typedef Store
39 * @property {string} storeId
40 * @property {string} storeName
41 */
42
43 /**
44 * @typedef StateConfiguration
45 * @property {string} stateUrl
46 * @property {string} storesUrl
47 * @property {string} currentStoreUrl
48 * @property {string} getConnectionDataUrl
49 * @property {string} versionUrl
50 * @property {string} shopNameUrl
51 * @property {Record<string, any>} pageConfiguration
52 */
53
54 /**
55 * @typedef Version
56 * @property {string} current
57 * @property {string | null} new
58 * @property {string | null} downloadNewVersionUrl
59 */
60
61 /**
62 * @typedef ShopName
63 * @property {string} shopName
64 */
65
66 /**
67 * @typedef DataStore
68 * @property {Version | null} version
69 * @property {Store[] | null} stores
70 * @property {ConnectionSettings | null} connectionSettings
71 * @property {CountrySettings | null} countrySettings
72 * @property {GeneralSettings | null} generalSettings
73 * @property {OrderStatusMapping[] | null} orderStatusSettings
74 * @property {WidgetSettings | null} widgetSettings
75 * @property {PaymentMethod[] | null} paymentMethods
76 * @property {SellingCountry[] | null} sellingCountries
77 * @property {Category[] | null} shopCategories
78 * @property {ShopOrderStatus[] | null} shopOrderStatuses
79 * @property {ShopPaymentMethod[] | null} shopPaymentMethods
80 * @property {TransactionLog[] | null} transactionLogs
81 * @property {string[] | null} logs
82 * @property {CountryPaymentMethod[] | null} allPaymentMethods
83 */
84
85 /**
86 * Main controller of the application.
87 *
88 * @param {StateConfiguration} configuration
89 *
90 * @constructor
91 */
92 function StateController(configuration) {
93 /** @type AjaxServiceType */
94 const api = SequraFE.ajaxService;
95 const { pageControllerFactory, templateService, utilities } = SequraFE;
96
97 let currentState = '';
98 let previousState = '';
99
100 /**
101 * @type {DataStore}
102 */
103 let dataStore;
104
105 const clearDataStore = () => {
106 dataStore = {
107 version: null,
108 stores: null,
109 connectionSettings: null,
110 countrySettings: null,
111 generalSettings: null,
112 orderStatusSettings: null,
113 widgetSettings: null,
114 paymentMethods: null,
115 sellingCountries: null,
116 shopCategories: null,
117 shopOrderStatuses: null,
118 shopPaymentMethods: null,
119 transactionLogs: null,
120 logs: null,
121 logsSettingsRes: null,
122 allPaymentMethods: null
123 };
124 }
125
126 clearDataStore();
127
128 /**
129 * Main entry point for the application.
130 * Determines the current state and runs the start controller.
131 */
132 this.display = () => {
133 utilities.showLoader();
134 clearDataStore();
135 templateService.clearMainPage();
136
137 window.addEventListener('hashchange', updateStateOnHashChange, false);
138
139 api.get(configuration.currentStoreUrl, null, SequraFE.customHeader)
140 .then(
141 /** @param {Store|Store[]} response */
142 (response) => {
143 const loadStore = (store) => {
144 this.setStoreId(store.storeId);
145
146 return displayPageBasedOnState();
147 };
148
149 let store = !Array.isArray(response) ?
150 response :
151 response.find((s) => s.storeId === this.getStoreId());
152
153 if (!store) {
154 // the active store is probably deleted, we need to switch to the default store
155 return api.get(configuration.currentStoreUrl, null, SequraFE.customHeader).then(loadStore);
156 }
157
158 return loadStore(store);
159 }
160 )
161 };
162
163 /**
164 * Updates the application state on a hash change.
165 */
166 const updateStateOnHashChange = () => {
167 const state = window.location.hash.substring(1);
168 state && this.goToState(state);
169 };
170
171 /**
172 * Opens a specific page based on the current state.
173 */
174 const displayPageBasedOnState = () => {
175 utilities.showLoader();
176 const hasVersion = SequraFE?.integration?.hasVersion ?? true;
177 const isMultistore = SequraFE?.integration?.isMultistore ?? true;
178
179 return Promise.all([
180 hasVersion ? api.get(configuration.versionUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader) : null,
181 isMultistore ? api.get(configuration.storesUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader) : null,
182 api.get(configuration.pageConfiguration.onboarding.getConnectionDataUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader),
183 api.get(configuration.pageConfiguration.onboarding.getCountrySettingsUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader),
184 SequraFE.pages.onboarding.includes(SequraFE.appPages.ONBOARDING.WIDGETS) ? api.get(configuration.pageConfiguration.onboarding.getWidgetSettingsUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader) : null,
185 api.get(configuration.pageConfiguration.advanced.saveLogsSettingsUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader),
186 ]).then(([versionRes, storesRes, connectionSettingsRes, countrySettingsRes, widgetSettingsRes, logsSettingsRes]) => {
187 dataStore.version = versionRes;
188 dataStore.stores = storesRes ?? [];
189 dataStore.connectionSettings = connectionSettingsRes;
190 dataStore.countrySettings = countrySettingsRes;
191 dataStore.widgetSettings = widgetSettingsRes;
192 dataStore.logsSettings = logsSettingsRes;
193 return api.get(configuration.stateUrl.replace('{storeId}', this.getStoreId()), null, SequraFE.customHeader);
194 }).then((stateRes) => {
195 if (SequraFE.state.getCredentialsChanged()) {
196 SequraFE.state.removeCredentialsChanged();
197 }
198
199 let page = this.getPage();
200 if (stateRes.state === SequraFE.appStates.ONBOARDING) {
201 this.goToState(SequraFE.appStates.ONBOARDING, null, true);
202
203 return;
204 }
205
206 if (SequraFE.pages?.transactions?.includes(page)) {
207 this.goToState(SequraFE.appStates.TRANSACTION + '-' + SequraFE.appPages.TRANSACTION.LOGS, null, true)
208
209 return;
210 }
211
212 if (SequraFE.pages?.advanced?.includes(page)) {
213 this.goToState(SequraFE.appStates.ADVANCED + '-' + page, null, true)
214 return;
215 }
216
217 if (!page || SequraFE.pages.payment?.includes(page)) {
218 this.goToState(SequraFE.appStates.PAYMENT + '-' + SequraFE.appPages.PAYMENT.METHODS, null, true)
219
220 return;
221 }
222
223 this.goToState(SequraFE.appStates.SETTINGS + '-' + page, null, true);
224 }).catch(e => {
225 console.error(e);
226 });
227 };
228
229 /**
230 * Navigates to a state.
231 *
232 * @param {string} state
233 * @param {Record<string, any> | null?} additionalConfig
234 * @param {boolean} [force=false]
235 */
236 this.goToState = (state, additionalConfig = null, force = false) => {
237 if ((currentState === state && !force)) {
238 return;
239 }
240
241 utilities.showLoader();
242 let [controllerName, page] = state.split('-');
243
244 if (controllerName === SequraFE.appStates.ONBOARDING) {
245 if (
246 dataStore.connectionSettings?.username &&
247 dataStore.countrySettings?.length &&
248 (!SequraFE.pages.onboarding.includes(SequraFE.appPages.ONBOARDING.WIDGETS) || dataStore.widgetSettings?.useWidgets !== undefined) &&
249 !SequraFE.state.getCredentialsChanged()
250 ) {
251 currentState.split('-')[0] === SequraFE.appStates.ONBOARDING ?
252 this.goToState(SequraFE.appStates.PAYMENT + '-' + SequraFE.appPages.PAYMENT.METHODS) :
253 this.goToState(currentState, null, true);
254
255 return;
256 }
257
258 if (!page) {
259 page = SequraFE.appPages.ONBOARDING.WIDGETS;
260 }
261
262 switch (page) {
263 case SequraFE.appPages.ONBOARDING.COUNTRIES:
264 if (!dataStore.connectionSettings?.username) {
265 page = SequraFE.appPages.ONBOARDING.CONNECT
266 }
267
268 break;
269 case SequraFE.appPages.ONBOARDING.WIDGETS:
270 if (dataStore.countrySettings?.length === 0 || SequraFE.state.getCredentialsChanged()) {
271 page = SequraFE.appPages.ONBOARDING.COUNTRIES
272 }
273
274 if (!dataStore.connectionSettings?.username) {
275 page = SequraFE.appPages.ONBOARDING.CONNECT
276 }
277 break;
278 default:
279 page = SequraFE.appPages.ONBOARDING.CONNECT
280 }
281
282 displayPage(controllerName + '-' + page, additionalConfig);
283
284 return;
285 }
286
287 if (
288 !dataStore.connectionSettings?.username ||
289 dataStore.countrySettings?.length === 0 ||
290 (SequraFE.pages.onboarding.includes(SequraFE.appPages.ONBOARDING.WIDGETS) && dataStore.widgetSettings?.useWidgets === undefined) ||
291 SequraFE.state.getCredentialsChanged()
292 ) {
293 this.goToState(SequraFE.appStates.ONBOARDING, additionalConfig, true);
294
295 return;
296 }
297
298 displayPage(state, additionalConfig);
299 };
300
301 const displayPage = (state, additionalConfig = null) => {
302 let [controllerName, page] = state.split('-');
303 if (!Object.values(SequraFE.appStates).includes(controllerName)) {
304 SequraFE.state.display();
305 }
306
307 if (!page || !SequraFE.pages[controllerName]?.includes(page)) {
308 page = SequraFE.pages[controllerName]?.[0];
309 state = page ? controllerName + '-' + page : controllerName;
310 }
311
312 const config = { storeId: this.getStoreId(), ...(additionalConfig || {}) };
313 const controller = pageControllerFactory.getInstance(
314 controllerName,
315 getControllerConfiguration(controllerName, page)
316 );
317
318 previousState = currentState;
319 currentState = state;
320 setPage(page);
321
322 window.location.hash = state;
323 controller && controller.display(config);
324 }
325
326 /**
327 * Gets controller configuration.
328 *
329 * @param {string} controllerName
330 * @param {string?} page
331 *
332 * @return {Record<string, any>}
333 */
334 const getControllerConfiguration = (controllerName, page) => {
335 let config = utilities.cloneObject(configuration.pageConfiguration[controllerName] || {});
336 Object.keys(config).forEach((key) => {
337 config[key] = config[key].replace('{storeId}', this.getStoreId);
338 })
339
340 page && (config.page = page);
341
342 return config;
343 };
344
345 /**
346 * Sets the application page to local storage.
347 *
348 * @param {string} page
349 */
350 const setPage = (page) => {
351 localStorage.setItem('sq-page', page);
352 }
353
354 /**
355 * Gets the application page from local storage.
356 *
357 * @returns {string}
358 */
359 this.getPage = () => {
360 if (window.location.hash) {
361 let page = window.location.hash.substring(1);
362 if (page) {
363 page = page.split('-')[1];
364 if (page) {
365 setPage(page);
366 return page;
367 }
368 }
369 }
370 return localStorage.getItem('sq-page');
371 }
372
373 /**
374 * Sets the credentials changed flag to local storage.
375 */
376 this.setCredentialsChanged = () => {
377 SequraFE.state.setData('paymentMethods', null);
378 SequraFE.state.setData('allPaymentMethods', null);
379 localStorage.setItem('sq-password-changed', '1');
380 }
381
382 /**
383 * Removes the credentials changed flag from local storage.
384 *
385 * @returns {string}
386 */
387 this.removeCredentialsChanged = () => {
388 localStorage.removeItem('sq-password-changed');
389 }
390
391 /**
392 * Gets the credentials changed flag from local storage.
393 *
394 * @returns {string}
395 */
396 this.getCredentialsChanged = () => {
397 return localStorage.getItem('sq-password-changed');
398 }
399
400 /**
401 * Sets the store ID to local storage.
402 *
403 * @param {string} storeId
404 */
405 this.setStoreId = (storeId) => {
406 sessionStorage.setItem('sq-active-store-id', storeId);
407 };
408
409 /**
410 * Gets the store ID from local storage.
411 *
412 * @returns {string}
413 */
414 this.getStoreId = () => {
415 return sessionStorage.getItem('sq-active-store-id');
416 };
417
418 /**
419 * Returns a getVersion promise.
420 *
421 * @returns {Promise<ShopName>}
422 */
423 this.getShopName = () => {
424 return api.get(configuration.shopNameUrl, () => {
425 }, SequraFE.customHeader);
426 };
427
428 this.getData = (key) => {
429 if (!Object.keys(dataStore).includes(key)) {
430 return null;
431 }
432
433 return dataStore[key];
434 }
435
436 this.setData = (key, value) => {
437 if (Object.keys(dataStore).includes(key)) {
438 dataStore[key] = value;
439 }
440 }
441 }
442
443 SequraFE.StateController = StateController;
444 })();
445