cronapp-framework-js 1.0.5 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/app.js CHANGED
@@ -20,7 +20,8 @@ var cronappModules = [
20
20
  'ui.tinymce',
21
21
  'ngCookies',
22
22
  'kendo.directives',
23
- 'sync.service'
23
+ 'sync.service',
24
+ 'cronapp.frontboost'
24
25
  ];
25
26
 
26
27
  if (window.customModules) {
@@ -51,294 +52,362 @@ var customizeRoute = () => {
51
52
  var app = (function() {
52
53
  customizeRoute();
53
54
  return angular.module('MyApp', cronappModules)
54
- .constant('LOCALES', {
55
- 'locales': {
56
- 'pt_br': 'Portugues (Brasil)',
57
- 'en_us': 'English'
58
- },
59
- 'preferredLocale': 'pt_br',
60
- 'urlPrefix': ''
61
- })
62
- .config(['$locationProvider', function($locationProvider) {
63
- $locationProvider.hashPrefix('');
64
- }])
65
- .config([
66
- '$httpProvider',
67
- function($httpProvider) {
68
- $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
69
- }
70
- ])
71
- .config( [
72
- '$compileProvider',
73
- function( $compileProvider )
74
- {
75
- $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript|chrome-extension):/);
76
- }
77
- ])
78
- .config(function($stateProvider, $urlRouterProvider, NotificationProvider) {
79
- NotificationProvider.setOptions({
80
- delay: 5000,
81
- startTop: 20,
82
- startRight: 10,
83
- verticalSpacing: 20,
84
- horizontalSpacing: 20,
85
- positionX: 'right',
86
- positionY: 'top',
87
- templateUrl: 'node_modules/cronapp-framework-js/components/templates/angular-ui-notification.template.html'
88
- });
89
- window.NotificationProviderOptions = NotificationProvider.options;
90
- window.stateProviderDefine.handle($stateProvider);
91
-
92
- // For any unmatched url, redirect to /state1
93
- $urlRouterProvider.otherwise("/error/404");
94
- })
95
- .factory('originPath', ['$location', function($location) {
96
- var originPath = {
97
- request: function(config) {
98
- config.headers['origin-path'] = $location.path();
99
- return config;
55
+ .constant('LOCALES', {
56
+ 'locales': {
57
+ 'pt_br': 'Portugues (Brasil)',
58
+ 'en_us': 'English'
59
+ },
60
+ 'preferredLocale': 'pt_br',
61
+ 'urlPrefix': ''
62
+ })
63
+ .factory('SessionService', ['$rootScope', '$state', '$location', 'FrontBoostAuthenticationService', function ($rootScope, $state, $location, FrontBoostAuthenticationService) {
64
+ return {
65
+ async checkSession($scope) {
66
+ let response;
67
+ if (!await FrontBoostAuthenticationService.isAvailable()) {
68
+ try {
69
+ response = await $http({
70
+ method: 'GET',
71
+ url: window.hostApp + 'me'
72
+ });
73
+ } catch (error) {
74
+ console.error('Error checking session:', error);
75
+ }
76
+ } else {
77
+ try {
78
+ const info = await FrontBoostAuthenticationService.getSessionInfo();
79
+ if (info.isLoggedIn) {
80
+ // Convert the session info to the format expected by handleSuccess
81
+ response = {
82
+ status: 200,
83
+ data: {
84
+ user: info.profile,
85
+ // Include other fields that might be needed by your app
86
+ username: info.profile.preferred_username || info.profile.email || info.profile.name,
87
+ // The FrontBoost auth service already manages tokens internally
88
+ // We only need to create a structure compatible with the expected format
89
+ token: info.access_token
90
+ }
91
+ };
92
+ }
93
+ } catch (error) {
94
+ console.error('Error checking session:', error);
95
+ }
100
96
  }
101
- };
102
- return originPath;
103
- }])
104
- .config(
105
- ['$logProvider',
106
- function ($logProvider) {
107
- $logProvider.debugEnabled(false);
108
- }]
109
- )
110
- .config(['$httpProvider', function($httpProvider) {
111
- $httpProvider.interceptors.push('originPath');
112
- }])
113
- .config(function($translateProvider, tmhDynamicLocaleProvider) {
114
-
115
- $translateProvider.uniformLanguageTag('bcp47');
116
- $translateProvider.useLoader('customTranslateLoader', {
117
- files: [{
118
- prefix: 'i18n/locale_',
119
- suffix: '.json'
120
- },
121
- {
122
- prefix: 'node_modules/cronapp-framework-js/i18n/locale_',
123
- suffix: '.json'
124
- },
125
- {
126
- prefix: 'node_modules/cronapi-js/i18n/locale_',
127
- suffix: '.json'
128
- }]
129
- });
130
97
 
131
- $translateProvider
132
- .registerAvailableLanguageKeys(
133
- window.translations.localesKeys,
134
- window.translations.localesRef
135
- )
136
- .determinePreferredLanguage();
98
+ if (response && response.status == 200) {
99
+ let data = getRequestData(response);
100
+ // Store data response on session storage
101
+ // The local storage will be cleaned when the browser window is closed
102
+ if (typeof (Storage) !== "undefined") {
103
+ // save the user data on localStorage
104
+ localStorage.setItem("_u", JSON.stringify(data));
105
+ $rootScope.session = JSON.parse(localStorage._u);
106
+ } else {
107
+ // Sorry! No Web Storage support.
108
+ // The home page may not work if it depends
109
+ // on the logged user data
110
+ }
137
111
 
138
- var locale = (window.navigator.userLanguage || window.navigator.language).replace('-', '_').toLowerCase();
139
- $translateProvider.use(locale);
140
- $translateProvider.preferredLanguage(locale);
141
- $translateProvider.fallbackLanguage('en_us');
112
+ // Redirect to home page
113
+ let returnUrl = cronapi.screen.getParam('returnUrl');
114
+ if (returnUrl) {
115
+ window.location.hash = returnUrl;
116
+ }
117
+ else {
118
+ window.location = $state.href('home', {}, { absolute: true });
119
+ }
142
120
 
143
- $translateProvider.useSanitizeValueStrategy('escaped');
121
+ if ($scope.cronapi) {
122
+ $scope.cronapi.forceCloseAllModal();
123
+ }
144
124
 
145
- tmhDynamicLocaleProvider.localeLocationPattern('node_modules/angular-i18n/angular-locale_{{locale}}.js');
125
+ // Verify if the 'onLogin' event is defined and it is a function (it can be a string pointing to a non project blockly) and run it.
126
+ if ($scope.blockly && $scope.blockly.events && $scope.blockly.events.onLogin && $scope.blockly.events.onLogin instanceof Function) {
127
+ $scope.blockly.events.onLogin();
128
+ }
129
+ }
130
+ }
131
+ };
132
+ }])
133
+ .config(['$locationProvider', function($locationProvider) {
134
+ $locationProvider.hashPrefix('');
135
+ }])
136
+ .config([
137
+ '$httpProvider',
138
+ function($httpProvider) {
139
+ $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
140
+ }
141
+ ])
142
+ .config( [
143
+ '$compileProvider',
144
+ function( $compileProvider )
145
+ {
146
+ $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript|chrome-extension):/);
147
+ }
148
+ ])
149
+ .config(function($stateProvider, $urlRouterProvider, NotificationProvider) {
150
+ NotificationProvider.setOptions({
151
+ delay: 5000,
152
+ startTop: 20,
153
+ startRight: 10,
154
+ verticalSpacing: 20,
155
+ horizontalSpacing: 20,
156
+ positionX: 'right',
157
+ positionY: 'top',
158
+ templateUrl: 'node_modules/cronapp-framework-js/components/templates/angular-ui-notification.template.html'
159
+ });
160
+ window.NotificationProviderOptions = NotificationProvider.options;
161
+ window.stateProviderDefine.handle($stateProvider);
162
+
163
+ // For any unmatched url, redirect to /state1
164
+ $urlRouterProvider.otherwise("/error/404");
165
+ })
166
+ .factory('originPath', ['$location', function($location) {
167
+ var originPath = {
168
+ request: function(config) {
169
+ config.headers['origin-path'] = $location.path();
170
+ return config;
171
+ }
172
+ };
173
+ return originPath;
174
+ }])
175
+ .config(
176
+ ['$logProvider',
177
+ function ($logProvider) {
178
+ $logProvider.debugEnabled(true);
179
+ }]
180
+ )
181
+ .config(function($translateProvider, tmhDynamicLocaleProvider) {
182
+
183
+ $translateProvider.uniformLanguageTag('bcp47');
184
+ $translateProvider.useLoader('customTranslateLoader', {
185
+ files: [{
186
+ prefix: 'i18n/locale_',
187
+ suffix: '.json'
188
+ },
189
+ {
190
+ prefix: 'node_modules/cronapp-framework-js/i18n/locale_',
191
+ suffix: '.json'
192
+ },
193
+ {
194
+ prefix: 'node_modules/cronapi-js/i18n/locale_',
195
+ suffix: '.json'
196
+ }]
197
+ });
146
198
 
147
- if (moment)
148
- moment.locale(locale);
149
- })
150
- .config(function($sceProvider) {
151
- $sceProvider.enabled(false);
152
- })
199
+ $translateProvider
200
+ .registerAvailableLanguageKeys(
201
+ window.translations.localesKeys,
202
+ window.translations.localesRef
203
+ )
204
+ .determinePreferredLanguage();
205
+
206
+ var locale = (window.navigator.userLanguage || window.navigator.language).replace('-', '_').toLowerCase();
207
+ $translateProvider.use(locale);
208
+ $translateProvider.preferredLanguage(locale);
209
+ $translateProvider.fallbackLanguage('en_us');
210
+
211
+ $translateProvider.useSanitizeValueStrategy('escaped');
212
+
213
+ tmhDynamicLocaleProvider.localeLocationPattern('node_modules/angular-i18n/angular-locale_{{locale}}.js');
214
+
215
+ if (moment)
216
+ moment.locale(locale);
217
+ })
218
+ .config(function($sceProvider) {
219
+ $sceProvider.enabled(false);
220
+ })
221
+
222
+ .directive('crnValue', ['$parse', function($parse) {
223
+ return {
224
+ restrict: 'A',
225
+ require: '^ngModel',
226
+ link: function(scope, element, attr, ngModelCtrl) {
227
+ var evaluatedValue;
228
+ if (attr.value) {
229
+ evaluatedValue = attr.value;
230
+ } else {
231
+ evaluatedValue = $parse(attr.crnValue)(scope);
232
+ }
153
233
 
154
- .directive('crnValue', ['$parse', function($parse) {
155
- return {
156
- restrict: 'A',
157
- require: '^ngModel',
158
- link: function(scope, element, attr, ngModelCtrl) {
159
- var evaluatedValue;
160
- if (attr.value) {
161
- evaluatedValue = attr.value;
162
- } else {
163
- evaluatedValue = $parse(attr.crnValue)(scope);
164
- }
234
+ element.attr("data-evaluated", JSON.stringify(evaluatedValue));
235
+ element.bind("click", function(event) {
236
+ scope.$apply(function() {
237
+ ngModelCtrl.$setViewValue(evaluatedValue);
238
+ $(element).data('changed', true);
239
+ }.bind(element));
240
+ });
165
241
 
166
- element.attr("data-evaluated", JSON.stringify(evaluatedValue));
167
- element.bind("click", function(event) {
168
- scope.$apply(function() {
169
- ngModelCtrl.$setViewValue(evaluatedValue);
170
- $(element).data('changed', true);
171
- }.bind(element));
172
- });
173
-
174
- scope.$watch(function(){return ngModelCtrl.$modelValue}, function(value, old){
175
- if (value !== old) {
176
- var dataEvaluated = element.attr("data-evaluated");
177
- var changed = $(element).data('changed');
178
- $(element).data('changed', false);
179
- if (!changed) {
180
- if (value && JSON.stringify(''+value) === dataEvaluated) {
181
- $(element)[0].checked = true
182
- } else {
183
- $(element)[0].checked = false;
184
- }
242
+ scope.$watch(function(){return ngModelCtrl.$modelValue}, function(value, old){
243
+ if (value !== old) {
244
+ var dataEvaluated = element.attr("data-evaluated");
245
+ var changed = $(element).data('changed');
246
+ $(element).data('changed', false);
247
+ if (!changed) {
248
+ if (value && JSON.stringify(''+value) === dataEvaluated) {
249
+ $(element)[0].checked = true
250
+ } else {
251
+ $(element)[0].checked = false;
185
252
  }
186
253
  }
187
- });
188
- }
254
+ }
255
+ });
256
+ }
257
+ };
258
+ }])
259
+
260
+ .decorator("$xhrFactory", [
261
+ "$delegate", "$injector",
262
+ function($delegate, $injector) {
263
+ return function(method, url) {
264
+ var xhr = $delegate(method, url);
265
+ var $http = $injector.get("$http");
266
+ var callConfig = $http.pendingRequests[$http.pendingRequests.length - 1];
267
+ if (angular.isFunction(callConfig.onProgress))
268
+ xhr.upload.addEventListener("progress",callConfig.onProgress);
269
+ return xhr;
189
270
  };
190
- }])
191
-
192
- .decorator("$xhrFactory", [
193
- "$delegate", "$injector",
194
- function($delegate, $injector) {
195
- return function(method, url) {
196
- var xhr = $delegate(method, url);
197
- var $http = $injector.get("$http");
198
- var callConfig = $http.pendingRequests[$http.pendingRequests.length - 1];
199
- if (angular.isFunction(callConfig.onProgress))
200
- xhr.upload.addEventListener("progress",callConfig.onProgress);
201
- return xhr;
202
- };
271
+ }
272
+ ])
273
+ // General controller
274
+ .controller('PageController', function($controller, $scope, $stateParams, $location, $http, $rootScope, $translate, Notification, UploadService, $timeout, $state, ReportService, DashboardService, FrontBoostCommandService, $log) {
275
+ // save state params into scope
276
+ $scope.params = $stateParams;
277
+ $scope.$http = $http;
278
+ $scope.Notification = Notification;
279
+ $scope.UploadService = UploadService;
280
+ $scope.$state = $state;
281
+
282
+ app.registerEventsCronapi($scope, $translate, $location);
283
+ app.registerFrontBoostFunctions($scope, FrontBoostCommandService, $log);
284
+
285
+ $("form").kendoValidator({
286
+ errorTemplate: '<span class="k-widget k-tooltip-validation k-x-invalid-msg-block">#=message#</span>',
287
+ messages:{
288
+ required: ''
203
289
  }
204
- ])
205
- // General controller
206
- .controller('PageController', function($controller, $scope, $stateParams, $location, $http, $rootScope, $translate, Notification, UploadService, $timeout, $state, ReportService, DashboardService) {
207
- // save state params into scope
208
- $scope.params = $stateParams;
209
- $scope.$http = $http;
210
- $scope.Notification = Notification;
211
- $scope.UploadService = UploadService;
212
- $scope.$state = $state;
213
-
214
- app.registerEventsCronapi($scope, $translate, $location);
215
-
216
- $("form").kendoValidator({
217
- errorTemplate: '<span class="k-widget k-tooltip-validation k-x-invalid-msg-block">#=message#</span>',
218
- messages:{
219
- required: ''
220
- }
221
- });
290
+ });
222
291
 
223
- $rootScope.getReport = function(reportName, params, config) {
224
- ReportService.openReport(reportName, params, config);
225
- };
292
+ $rootScope.getReport = function(reportName, params, config) {
293
+ ReportService.openReport(reportName, params, config);
294
+ };
226
295
 
227
- $rootScope.getDashboard = function(dashboardName, params, config) {
228
- DashboardService.openDashboard(dashboardName, params, config);
229
- };
296
+ $rootScope.getDashboard = function(dashboardName, params, config) {
297
+ DashboardService.openDashboard(dashboardName, params, config);
298
+ };
230
299
 
231
- // Query string params
232
- var queryStringParams = $location.search();
233
- for (var key in queryStringParams) {
234
- if (queryStringParams.hasOwnProperty(key)) {
235
- $scope.params[key] = queryStringParams[key];
236
- }
300
+ // Query string params
301
+ var queryStringParams = $location.search();
302
+ for (var key in queryStringParams) {
303
+ if (queryStringParams.hasOwnProperty(key)) {
304
+ $scope.params[key] = queryStringParams[key];
237
305
  }
306
+ }
238
307
 
239
- try {
240
- var contextAfterPageController = $controller('AfterPageController', { $scope: $scope });
241
- app.copyContext(contextAfterPageController, this, 'AfterPageController');
242
- } catch(e) {}
308
+ try {
309
+ var contextAfterPageController = $controller('AfterPageController', { $scope: $scope });
310
+ app.copyContext(contextAfterPageController, this, 'AfterPageController');
311
+ } catch(e) {}
243
312
 
244
- $timeout(function () {
245
- // Verify if the 'afterPageRender' event is defined and it is a function (it can be a string pointing to a non project blockly) and run it.
246
- if ($scope.blockly && $scope.blockly.events && $scope.blockly.events.afterPageRender && $scope.blockly.events.afterPageRender instanceof Function) {
247
- $scope.blockly.events.afterPageRender();
248
- }
249
- });
313
+ $timeout(function () {
314
+ // Verify if the 'afterPageRender' event is defined and it is a function (it can be a string pointing to a non project blockly) and run it.
315
+ if ($scope.blockly && $scope.blockly.events && $scope.blockly.events.afterPageRender && $scope.blockly.events.afterPageRender instanceof Function) {
316
+ $scope.blockly.events.afterPageRender();
317
+ }
318
+ });
250
319
 
251
- })
252
-
253
- .run(function($rootScope, $state, $stateParams, $timeout, $transitions) {
254
- // It's very handy to add references to $state and $stateParams to the $rootScope
255
- // so that you can access them from any scope within your applications.For example,
256
- // <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
257
- // to active whenever 'contacts.list' or one of its decendents is active.
258
- $rootScope.$state = $state;
259
- $rootScope.$stateParams = $stateParams;
260
-
261
- const $stateChangeError = function(error) {
262
- if (error) {
263
- const errorMessage = error.toString();
264
- if (error.type === 6 && error.detail.config.url.includes("=_.view.html") ) {
265
- $state.go('login');
266
- }
267
- else if (errorMessage.includes('=404')) {
268
- $state.go('404');
269
- }
270
- else if (errorMessage.includes('=403')) {
271
- $state.go('403');
272
- }
273
- else if (errorMessage.includes('=401')) {
274
- localStorage.removeItem('_u');
275
- $state.go('loginReturnUrl', { "returnUrl" : window.location.hash });
276
- } else {
277
- $state.go('404');
278
- }
320
+ })
321
+ .run(function($rootScope, $state, $stateParams, $timeout, $transitions, FrontBoostAuthenticationService) {
322
+ // It's very handy to add references to $state and $stateParams to the $rootScope
323
+ // so that you can access them from any scope within your applications.For example,
324
+ // <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
325
+ // to active whenever 'contacts.list' or one of its decendents is active.
326
+ FrontBoostAuthenticationService.init();
327
+
328
+ $rootScope.$state = $state;
329
+ $rootScope.$stateParams = $stateParams;
330
+
331
+ const $stateChangeError = function(error) {
332
+ if (error) {
333
+ const errorMessage = error.toString();
334
+ if (error.type === 6 && error.detail?.config?.url?.includes("=_.view.html") ) {
335
+ $state.go('login');
336
+ }
337
+ else if (errorMessage.includes('=404')) {
338
+ $state.go('404');
339
+ }
340
+ else if (errorMessage.includes('=403')) {
341
+ $state.go('403');
342
+ }
343
+ else if (errorMessage.includes('=401')) {
344
+ localStorage.removeItem('_u');
345
+ $state.go('loginReturnUrl', { "returnUrl" : window.location.hash });
279
346
  } else {
280
347
  $state.go('404');
281
348
  }
282
- };
349
+ } else {
350
+ $state.go('404');
351
+ }
352
+ };
283
353
 
284
- const $stateChangeSuccess = function(currentRoute) {
285
- $timeout(() => {
286
- let systemName = $('#projectName').length ? $('#projectName').val() : $('h1:first').length && $('h1:first').text().trim().length ? $('h1:first').text().trim() : '';
354
+ const $stateChangeSuccess = function(currentRoute) {
355
+ $timeout(() => {
356
+ let systemName = $('#projectName').length ? $('#projectName').val() : $('h1:first').length && $('h1:first').text().trim().length ? $('h1:first').text().trim() : '';
287
357
 
288
- const urlPattern = /\/(?:.(?!\/))+$/gm;
289
- let currentWindow = window.location.hash;
290
- let pageName;
358
+ const urlPattern = /\/(?:.(?!\/))+$/gm;
359
+ let currentWindow = window.location.hash;
360
+ let pageName;
291
361
 
292
- if ((m = urlPattern.exec(currentWindow)) !== null) {
293
- m.forEach(match => pageName = match);
294
- } else {
295
- pageName = currentRoute.name
296
- }
362
+ if ((m = urlPattern.exec(currentWindow)) !== null) {
363
+ m.forEach(match => pageName = match);
364
+ } else {
365
+ pageName = currentRoute.name
366
+ }
297
367
 
298
- let isCrud = $('form[crn-datasource]').length;
299
- let prettyPageName = window.camelCaseToSentenceCase(window.toCamelCase(pageName.split('?')[0].replace("/", "")));
300
- // Get the H1 or H2 text to concat with the App name to set the title page
301
- if (isCrud) {
302
- if ($('h1.title').length){
303
- prettyPageName = $('h1.title').text();
304
- } else if ($('h2.title').length){
305
- prettyPageName = $('h2.title').text();
306
- }
368
+ let isCrud = $('form[crn-datasource]').length;
369
+ let prettyPageName = window.camelCaseToSentenceCase(window.toCamelCase(pageName.split('?')[0].replace("/", "")));
370
+ // Get the H1 or H2 text to concat with the App name to set the title page
371
+ if (isCrud) {
372
+ if ($('h1.title').length){
373
+ prettyPageName = $('h1.title').text();
374
+ } else if ($('h2.title').length){
375
+ prettyPageName = $('h2.title').text();
307
376
  }
377
+ }
308
378
 
309
- let title = '';
379
+ let title = '';
310
380
 
311
- title = prettyPageName + (systemName.length ? ' - ' + systemName : '' );
381
+ title = prettyPageName + (systemName.length ? ' - ' + systemName : '' );
312
382
 
313
- $rootScope.viewTitle = title || currentRoute.name;
314
- $rootScope.viewTitleOnly = prettyPageName || currentRoute.name;
315
- $rootScope.systemName = systemName;
316
- let $mainLinks = $('.main-nav-link');
317
- if ($mainLinks && $mainLinks.length && $($('.main-nav-link').get(0)).is(":visible")) {
318
- $(".main-access").focus();
319
- // $($('.main-nav-link').get(0)).focus();
320
- // $($('.main-nav-link').get(0)).blur();
321
- } else {
322
- let $inputsMain = $('[role=main]').find('input');
323
- if ($inputsMain && $inputsMain.length) {
324
- let cantFocus = ['date', 'datetime', 'time'];
325
- let $firstInput = $($inputsMain[0]);
326
- if ( !cantFocus.includes($firstInput.data('type')) ) {
327
- $firstInput.focus();
328
- }
383
+ $rootScope.viewTitle = title || currentRoute.name;
384
+ $rootScope.viewTitleOnly = prettyPageName || currentRoute.name;
385
+ $rootScope.systemName = systemName;
386
+ let $mainLinks = $('.main-nav-link');
387
+ if ($mainLinks && $mainLinks.length && $($('.main-nav-link').get(0)).is(":visible")) {
388
+ $(".main-access").focus();
389
+ // $($('.main-nav-link').get(0)).focus();
390
+ // $($('.main-nav-link').get(0)).blur();
391
+ } else {
392
+ let $inputsMain = $('[role=main]').find('input');
393
+ if ($inputsMain && $inputsMain.length) {
394
+ let cantFocus = ['date', 'datetime', 'time'];
395
+ let $firstInput = $($inputsMain[0]);
396
+ if ( !cantFocus.includes($firstInput.data('type')) ) {
397
+ $firstInput.focus();
329
398
  }
330
399
  }
400
+ }
331
401
 
332
- $rootScope.renderFinished = true;
333
- registerComponentScripts();
334
- });
335
- };
402
+ $rootScope.renderFinished = true;
403
+ registerComponentScripts();
404
+ });
405
+ };
336
406
 
337
- $transitions.onSuccess({}, (transition) => $stateChangeSuccess(transition.to()));
338
- $state.defaultErrorHandler(error => $stateChangeError(error));
339
- })
407
+ $transitions.onSuccess({}, (transition) => $stateChangeSuccess(transition.to()));
408
+ $state.defaultErrorHandler(error => $stateChangeError(error));
409
+ })
340
410
  .config(function($httpProvider) {
341
- $httpProvider.defaults.withCredentials = true;
342
411
  // Create an interceptor to handle CSRF tokens (consistent with other implementations)
343
412
  $httpProvider.interceptors.push(function() {
344
413
  return {
@@ -404,11 +473,11 @@ app.registerEventsCronapi = function($scope, $translate, $location) {
404
473
  $scope.params = {};
405
474
 
406
475
  let makeCopy = (from, to) => {
407
- for (let key in from) {
408
- if (from.hasOwnProperty(key)) {
409
- to[key] = from[key];
410
- }
476
+ for (let key in from) {
477
+ if (from.hasOwnProperty(key)) {
478
+ to[key] = from[key];
411
479
  }
480
+ }
412
481
  };
413
482
  makeCopy($stateParams, $scope.params);
414
483
  makeCopy(queryStringParams, $scope.params);
@@ -444,6 +513,47 @@ app.registerEventsCronapi = function($scope, $translate, $location) {
444
513
  }
445
514
  };
446
515
 
516
+ app.registerFrontBoostFunctions = function ($scope, FrontBoostCommandService, $log) {
517
+ $scope.handleFrontBoostCommand = async function (encodedPayload) {
518
+ try {
519
+ const decodedPayload = atob(encodedPayload);
520
+ const payload = JSON.parse(decodedPayload);
521
+
522
+ if (payload && payload.actions) {
523
+ // Create the context. This object will be mutated by each command in the sequence.
524
+ const context = {
525
+ vars: $scope.vars,
526
+ params: $scope.params,
527
+ };
528
+
529
+ // Execute commands sequentially.
530
+ for (const rawAction of payload.actions) {
531
+ if (rawAction && rawAction.command) {
532
+ try {
533
+ await FrontBoostCommandService.handleCommand($scope, rawAction.command, context);
534
+ } catch (error) {
535
+ $log.error('Error processing FrontBoost command:', error);
536
+ break;
537
+ }
538
+ } else {
539
+ $log.warn('Skipping invalid command object in payload:', rawAction);
540
+ }
541
+ }
542
+
543
+ // Safely apply the mutated context back to the scope.
544
+ $scope.$evalAsync(() => {
545
+ $scope.params = context.params;
546
+ $scope.vars = context.vars;
547
+ });
548
+ } else {
549
+ $log.error('Invalid command structure: missing commands property');
550
+ }
551
+ } catch (error) {
552
+ $log.error('Error processing FrontBoost command:', error);
553
+ }
554
+ }
555
+ };
556
+
447
557
  app.copyContext = function(fromContext, toContext, controllerName) {
448
558
  if (fromContext) {
449
559
  for (var item in fromContext) {
@@ -495,8 +605,8 @@ app.factory('customTranslateLoader', function ($http, $q) {
495
605
  };
496
606
 
497
607
  var deferred = $q.defer(),
498
- promises = [],
499
- length = options.files.length;
608
+ promises = [],
609
+ length = options.files.length;
500
610
 
501
611
  for (var i = 0; i < length; i++) {
502
612
  promises.push(load({
@@ -508,7 +618,7 @@ app.factory('customTranslateLoader', function ($http, $q) {
508
618
 
509
619
  $q.all(promises).then(function (data) {
510
620
  var length = data.length,
511
- mergedData = {};
621
+ mergedData = {};
512
622
 
513
623
  for (var i = 0; i < length; i++) {
514
624
  for (var key in data[i]) {
@@ -528,7 +638,7 @@ app.factory('customTranslateLoader', function ($http, $q) {
528
638
  });
529
639
 
530
640
  window.safeApply = function(fn) {
531
- var phase = this.$root.$$phase;
641
+ var phase = this.$root?.$$phase;
532
642
  if (phase === '$apply' || phase === '$digest') {
533
643
  if (fn && (typeof(fn) === 'function')) {
534
644
  fn();
@@ -542,15 +652,15 @@ window.toCamelCase = function(str) {
542
652
  if (str !== null) {
543
653
  // Lower cases the string
544
654
  return str.toLowerCase()
545
- // Replaces any - or _ or . characters with a space
546
- .replace( /[-_\.]+/g, ' ')
547
- // Removes any non alphanumeric characters
548
- .replace( /[^\w\s]/g, '')
549
- // Uppercases the first character in each group immediately following a space
550
- // (delimited by spaces)
551
- .replace( / (.)/g, function($1) { return $1.toUpperCase(); })
552
- // Removes spaces
553
- .replace( / /g, '' );
655
+ // Replaces any - or _ or . characters with a space
656
+ .replace( /[-_\.]+/g, ' ')
657
+ // Removes any non alphanumeric characters
658
+ .replace( /[^\w\s]/g, '')
659
+ // Uppercases the first character in each group immediately following a space
660
+ // (delimited by spaces)
661
+ .replace( / (.)/g, function($1) { return $1.toUpperCase(); })
662
+ // Removes spaces
663
+ .replace( / /g, '' );
554
664
  }
555
665
  return str;
556
666
  };