e7e2828eb543609f9e53bfa23286ddf605991870
[sdc.git] / catalog-ui / src / app / app.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 'use strict';
22
23 import * as _ from "lodash";
24 import "reflect-metadata";
25 import 'ng-infinite-scroll';
26 import './modules/filters.ts';
27 import './modules/utils.ts';
28 import './modules/directive-module.ts';
29 import './modules/service-module';
30 import './modules/view-model-module.ts';
31 import {SdcUiCommon, SdcUiComponents, SdcUiServices} from 'onap-ui-angular';
32 import {
33   CookieService,
34   DataTypesService,
35   EcompHeaderService,
36   LeftPaletteLoaderService
37 } from "./services";
38 import {CacheService, CatalogService, HomeService} from "./services-ng2";
39 import {AuthenticationService} from "app/ng2/services/authentication.service";
40 import {CHANGE_COMPONENT_CSAR_VERSION_FLAG, PREVIOUS_CSAR_COMPONENT, States} from "./utils";
41 import {IAppConfigurtaion, IAppMenu, IHostedApplication, Resource} from "./models";
42 import {ComponentFactory} from "./utils/component-factory";
43 import {Component} from "./models/components/component";
44 import {IUserProperties} from "./models/user";
45 import {WorkspaceService} from "./ng2/pages/workspace/workspace.service";
46
47 let moduleName: string = 'sdcApp';
48 let viewModelsModuleName: string = 'Sdc.ViewModels';
49 let directivesModuleName: string = 'Sdc.Directives';
50 let servicesModuleName: string = 'Sdc.Services';
51 let filtersModuleName: string = 'Sdc.Filters';
52 let utilsModuleName: string = 'Sdc.Utils';
53
54 // Load configuration according to environment.
55 declare var __ENV__: string;
56 let sdcConfig: IAppConfigurtaion;
57 let sdcMenu: IAppMenu;
58 let pathPrefix: string = '';
59 if (__ENV__ === 'dev') {
60   sdcConfig = require('./../../configurations/dev.js');
61 } else if (__ENV__ === 'prod') {
62   sdcConfig = require('./../../configurations/prod.js');
63   pathPrefix = 'sdc1/';
64 } else {
65   console.log("ERROR: Environment configuration not found!");
66 }
67 sdcMenu = require('./../../configurations/menu.js');
68
69 let dependentModules: Array<string> = [
70   'ui.router',
71   'ui.bootstrap',
72   'ui.bootstrap.tpls',
73   'ngDragDrop',
74   'ui-notification',
75   'ngResource',
76   'ngSanitize',
77   'naif.base64',
78   'base64',
79   'uuid4',
80   'checklist-model',
81   'angular.filter',
82   'pascalprecht.translate',
83   '720kb.tooltips',
84   'restangular',
85   'angular-clipboard',
86   'angularResizable',
87   'infinite-scroll',
88   viewModelsModuleName,
89   directivesModuleName,
90   servicesModuleName,
91   filtersModuleName,
92   utilsModuleName
93 ];
94
95 // ===================== Hosted applications section ====================
96 // Define here new hosted apps
97 let hostedApplications: Array<IHostedApplication> = [
98   {
99     "moduleName": "dcaeApp",
100     "navTitle": "DCAE",
101     "defaultState": 'dcae.app.home',
102     "state": {
103       "name": "dcae",
104       "url": "/dcae",
105       "relativeHtmlPath": 'dcae-app/dcae-app-view.html',
106       "controllerName": '.DcaeAppViewModel'
107     }
108   }
109 ];
110
111 // Check if module exists (in case the javascript was not loaded).
112 let isModuleExists = (moduleName: string): boolean => {
113   try {
114     angular.module(moduleName);
115     dependentModules.push(moduleName);
116     return true;
117   } catch (e) {
118     console.log('Module ' + moduleName + ' does not exists');
119     return false;
120   }
121 };
122
123 // Check which hosted applications exists
124 _.each(hostedApplications, (hostedApp) => {
125   if (isModuleExists(hostedApp.moduleName)) {
126     hostedApp['exists'] = true;
127   }
128 });
129 // ===================== Hosted applications section ====================
130
131 export const ng1appModule: ng.IModule = angular.module(moduleName, dependentModules);
132
133 ng1appModule.config([
134   '$stateProvider',
135   '$translateProvider',
136   '$urlRouterProvider',
137   '$httpProvider',
138   'tooltipsConfigProvider',
139   'NotificationProvider',
140   ($stateProvider: any,
141    $translateProvider: any,
142    $urlRouterProvider: ng.ui.IUrlRouterProvider,
143    $httpProvider: ng.IHttpProvider,
144    tooltipsConfigProvider: any,
145    NotificationProvider: any): void => {
146
147     NotificationProvider.setOptions({
148       delay: 5000,
149       startTop: 10,
150       startRight: 10,
151       closeOnClick: true,
152       verticalSpacing: 20,
153       horizontalSpacing: 20,
154       positionX: 'right',
155       positionY: 'top'
156     });
157     NotificationProvider.options.templateUrl = 'notification-custom-template.html';
158
159     $translateProvider.useStaticFilesLoader({
160       prefix: pathPrefix + 'assets/languages/',
161       langKey: '',
162       suffix: '.json?d=' + (new Date()).getTime()
163     });
164     $translateProvider.useSanitizeValueStrategy('escaped');
165     $translateProvider.preferredLanguage('en_US');
166
167     $httpProvider.interceptors.push('Sdc.Services.HeaderInterceptor');
168     $urlRouterProvider.otherwise('dashboard');
169
170     $stateProvider.state(
171         'dashboard', {
172           url: '/dashboard?show&folder&filter.term&filter.status&filter.distributed',
173           template: '<home-page></home-page>',
174           permissions: ['DESIGNER']
175         },
176     );
177
178
179     let componentsParam: Array<any> = ['$stateParams', 'HomeService', 'CatalogService', 'Sdc.Services.CacheService', ($stateParams: any, HomeService: HomeService, CatalogService: CatalogService, cacheService: CacheService) => {
180       if (cacheService.get('breadcrumbsComponentsState') === $stateParams.previousState) {
181         const breadcrumbsComponents = cacheService.get('breadcrumbsComponents');
182         if (breadcrumbsComponents) {
183           return breadcrumbsComponents;
184         }
185       } else {
186         let breadcrumbsComponentsObservable;
187         if ($stateParams.previousState === 'dashboard') {
188           breadcrumbsComponentsObservable = HomeService.getAllComponents(true);
189         } else if ($stateParams.previousState === 'catalog') {
190           breadcrumbsComponentsObservable = CatalogService.getCatalog();
191         } else {
192           cacheService.remove('breadcrumbsComponentsState');
193           cacheService.remove('breadcrumbsComponents');
194           return [];
195         }
196         breadcrumbsComponentsObservable.subscribe((components) => {
197           cacheService.set('breadcrumbsComponentsState', $stateParams.previousState);
198           cacheService.set('breadcrumbsComponents', components);
199         });
200         return breadcrumbsComponentsObservable;
201       }
202     }];
203
204     const oldWorkspaceController: Array<any> = ['$location', ($location: ng.ILocationService) => {
205       // redirect old /workspace/* urls to /catalog/workspace/* url
206       const newUrl = '/catalog' + $location.url();
207       console.log('old workspace path - redirecting to:', newUrl);
208       $location.url(newUrl);
209     }];
210
211     $stateProvider.state(
212         'workspace-old', {
213           url: '/workspace/:id/:type/*workspaceInnerPath',
214           controller: oldWorkspaceController
215         }
216     );
217
218     $stateProvider.state(
219         'workspace', {
220           url: '/:previousState/workspace/:id/:type/',
221           params: {
222             'importedFile': null,
223             'componentCsar': null,
224             'resourceType': null,
225             'disableButtons': null
226           },
227           templateUrl: './view-models/workspace/workspace-view.html',
228           controller: viewModelsModuleName + '.WorkspaceViewModel',
229           resolve: {
230             injectComponent: ['$stateParams', 'ComponentFactory', 'workspaceService', 'Sdc.Services.CacheService', function ($stateParams, ComponentFactory: ComponentFactory, workspaceService: WorkspaceService, cacheService: CacheService) {
231
232               if ($stateParams.id && $stateParams.id.length) { //need to check length in case ID is an empty string
233                 return ComponentFactory.getComponentWithMetadataFromServer($stateParams.type.toUpperCase(), $stateParams.id).then(
234                     (component: Component) => {
235                       if ($stateParams.componentCsar && component.isResource()) {
236                         if ((<Resource>component).csarVersion != $stateParams.componentCsar.csarVersion) {
237                           cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component));
238                         }
239                         component = ComponentFactory.updateComponentFromCsar($stateParams.componentCsar, <Resource>component);
240                       }
241                       workspaceService.setComponentMetadata(component.componentMetadata);
242                       return component;
243                     });
244               } else if ($stateParams.componentCsar && $stateParams.componentCsar.csarUUID) {
245                 return $stateParams.componentCsar;
246               } else {
247                 let emptyComponent = ComponentFactory.createEmptyComponent($stateParams.type.toUpperCase());
248                 if (emptyComponent.isResource() && $stateParams.resourceType) {
249                   // Set the resource type
250                   (<Resource>emptyComponent).resourceType = $stateParams.resourceType;
251                 }
252                 if ($stateParams.importedFile) {
253                   (<Resource>emptyComponent).importedFile = $stateParams.importedFile;
254                 }
255                 return emptyComponent;
256               }
257             }],
258             components: componentsParam
259           }
260         }
261     );
262
263     $stateProvider.state(
264         States.WORKSPACE_GENERAL, {
265           url: 'general',
266           parent: 'workspace',
267           controller: viewModelsModuleName + '.GeneralViewModel',
268           templateUrl: './view-models/workspace/tabs/general/general-view.html',
269           data: {unsavedChanges: false, bodyClass: 'general'}
270         }
271     );
272
273
274     $stateProvider.state(
275         States.WORKSPACE_INFORMATION_ARTIFACTS, {
276           url: 'information_artifacts',
277           parent: 'workspace',
278           template: '<information-artifact-page></information-artifact-page>'
279         }
280     );
281
282     $stateProvider.state(
283         States.WORKSPACE_TOSCA_ARTIFACTS, {
284           url: 'tosca_artifacts',
285           parent: 'workspace',
286           template: '<tosca-artifact-page></tosca-artifact-page>'
287         }
288     );
289
290
291     $stateProvider.state(
292         States.WORKSPACE_DEPLOYMENT_ARTIFACTS, {
293           url: 'deployment_artifacts',
294           parent: 'workspace',
295           template: '<deployment-artifact-page></deployment-artifact-page>'
296         }
297     );
298
299     $stateProvider.state(
300         States.WORKSPACE_PROPERTIES, {
301           url: 'properties',
302           parent: 'workspace',
303           controller: viewModelsModuleName + '.PropertiesViewModel',
304           templateUrl: './view-models/workspace/tabs/properties/properties-view.html',
305           data: {
306             bodyClass: 'properties'
307           }
308         }
309     );
310
311     $stateProvider.state(
312         States.WORKSPACE_PROPERTIES_ASSIGNMENT, {
313           url: 'properties_assignment',
314           params: {'component': null},
315           template: '<properties-assignment></properties-assignment>',
316           parent: 'workspace',
317           resolve: {
318             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
319               //injectComponent.componentService = null; // this is for not passing the service so no one will use old api and start using new api
320               $stateParams.component = injectComponent;
321               return injectComponent;
322             }],
323           },
324           data: {
325             bodyClass: 'properties-assignment'
326           }
327         }
328     );
329
330     $stateProvider.state(
331         States.WORKSPACE_ATTRIBUTES, {
332           url: 'attributes',
333           parent: 'workspace',
334           template: '<attributes></attributes>',
335         }
336     );
337
338     $stateProvider.state(
339         States.WORKSPACE_ATTRIBUTES_OUTPUTS, {
340           url: 'attributes_outputs',
341           parent: 'workspace',
342           template: '<attributes-outputs></attributes-outputs>',
343           resolve: {
344             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
345               $stateParams.component = injectComponent;
346               return injectComponent;
347             }],
348           },
349           data: {
350             bodyClass: 'attributes-outputs'
351           }
352         }
353     );
354
355     $stateProvider.state(
356         States.WORKSPACE_REQUIREMENTS_AND_CAPABILITIES, {
357           url: 'req_and_capabilities',
358           parent: 'workspace',
359           template: '<req-and-capabilities></req-and-capabilities>',
360           data: {
361             bodyClass: 'attributes'
362           }
363         }
364     );
365     $stateProvider.state(
366         States.WORKSPACE_REQUIREMENTS_AND_CAPABILITIES_EDITABLE, {
367           url: 'req_and_capabilities_editable',
368           parent: 'workspace',
369           template: '<req-and-capabilities></req-and-capabilities>',
370           data: {
371             bodyClass: 'attributes'
372           }
373         }
374     );
375
376
377     $stateProvider.state(
378         States.WORKSPACE_MANAGEMENT_WORKFLOW, {
379           parent: 'workspace',
380           url: 'management_workflow',
381           templateUrl: './view-models/workspace/tabs/management-workflow/management-workflow-view.html',
382           controller: viewModelsModuleName + '.ManagementWorkflowViewModel'
383         }
384     );
385
386     $stateProvider.state(
387         States.WORKSPACE_NETWORK_CALL_FLOW, {
388           parent: 'workspace',
389           url: 'network_call_flow',
390           templateUrl: './view-models/workspace/tabs/network-call-flow/network-call-flow-view.html',
391           controller: viewModelsModuleName + '.NetworkCallFlowViewModel'
392         }
393     );
394
395
396     $stateProvider.state(
397         States.WORKSPACE_COMPOSITION, {
398           url: 'composition/',
399           params: {'component': null},
400           parent: 'workspace',
401           template: '<composition-page></composition-page>',
402           resolve: {
403             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
404               //injectComponent.componentService = null; // this is for not passing the service so no one will use old api and start using new api
405               $stateParams.component = injectComponent;
406               return injectComponent;
407             }],
408           },
409           data: {
410             bodyClass: 'composition'
411           }
412         }
413     );
414
415     $stateProvider.state(
416         States.WORKSPACE_ACTIVITY_LOG, {
417           url: 'activity_log/',
418           parent: 'workspace',
419           template: '<activity-log></activity-log>',
420         }
421     );
422
423     $stateProvider.state(
424         States.WORKSPACE_DISTRIBUTION, {
425           url: 'distribution',
426           parent: 'workspace',
427           template: '<distribution></distribution>',
428         }
429     );
430
431     $stateProvider.state(
432         States.WORKSPACE_DEPLOYMENT, {
433           url: 'deployment/',
434           parent: 'workspace',
435           template: '<deployment-page></deployment-page>',
436
437         }
438     );
439
440     $stateProvider.state(
441         'workspace.composition.details', {
442           url: 'details',
443           parent: 'workspace.composition',
444           resolve: {
445             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
446               $stateParams.component = injectComponent;
447               return injectComponent;
448             }],
449           }
450
451         }
452     );
453
454     $stateProvider.state(
455         'workspace.composition.properties', {
456           url: 'properties',
457           parent: 'workspace.composition'
458         }
459     );
460
461     $stateProvider.state(
462         'workspace.composition.artifacts', {
463           url: 'artifacts',
464           parent: 'workspace.composition'
465
466         }
467     );
468
469     $stateProvider.state(
470         'workspace.composition.relations', {
471           url: 'relations',
472           parent: 'workspace.composition'
473         }
474     );
475
476     $stateProvider.state(
477         'workspace.composition.structure', {
478           url: 'structure',
479           parent: 'workspace.composition'
480         }
481     );
482     $stateProvider.state(
483         'workspace.composition.lifecycle', {
484           url: 'lifecycle',
485           parent: 'workspace.composition'
486         }
487     );
488
489     $stateProvider.state(
490         'workspace.composition.api', {
491           url: 'api',
492           parent: 'workspace.composition'
493         }
494     );
495     $stateProvider.state(
496         'workspace.composition.deployment', {
497           url: 'deployment',
498           parent: 'workspace.composition'
499         }
500     );
501
502     $stateProvider.state(
503         States.WORKSPACE_INTERFACE_OPERATION, {
504           url: 'interface_operation',
505           parent: 'workspace',
506           controller: viewModelsModuleName + '.InterfaceOperationViewModel',
507           templateUrl: './view-models/workspace/tabs/interface-operation/interface-operation-view.html',
508           data: {
509             bodyClass: 'interface_operation'
510           }
511         }
512     );
513
514     $stateProvider.state(
515         States.WORKSPACE_INTERFACE_DEFINITION, {
516           url: 'interfaceDefinition',
517           parent: 'workspace',
518           controller: viewModelsModuleName + '.InterfaceDefinitionViewModel',
519           templateUrl: './view-models/workspace/tabs/interface-definition/interface-definition-view.html',
520           data: {
521             bodyClass: 'interfaceDefinition'
522           }
523         }
524     );
525
526     $stateProvider.state(
527         'workspace.plugins', {
528           url: 'plugins/*path',
529           parent: 'workspace',
530           template: '<plugin-context-view></plugin-context-view>',
531           resolve: {
532             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
533               $stateParams.component = injectComponent;
534               return injectComponent;
535             }],
536           }
537
538         }
539     );
540
541     $stateProvider.state(
542         'adminDashboard', {
543           url: '/adminDashboard',
544           templateUrl: './view-models/admin-dashboard/admin-dashboard-view.html',
545           controller: viewModelsModuleName + '.AdminDashboardViewModel',
546           permissions: ['ADMIN']
547         }
548     );
549
550     $stateProvider.state(
551         'onboardVendor', {
552           url: '/onboardVendor',
553           templateUrl: './view-models/onboard-vendor/onboard-vendor-view.html',
554           controller: viewModelsModuleName + '.OnboardVendorViewModel'
555         }
556     );
557
558     $stateProvider.state(
559         'plugins', {
560           url: '/plugins/*path',
561           template: '<plugin-tab-view></plugin-tab-view>'
562         }
563     );
564
565     // Build the states for all hosted apps dynamically
566     _.each(hostedApplications, (hostedApp) => {
567       if (hostedApp.exists) {
568         $stateProvider.state(
569             hostedApp.state.name, {
570               url: hostedApp.state.url,
571               templateUrl: './view-models/dcae-app/dcae-app-view.html',
572               controller: viewModelsModuleName + hostedApp.state.controllerName
573             }
574         );
575       }
576     });
577
578     $stateProvider.state(
579         'catalog', {
580           url: '/catalog?filter.components&filter.resourceSubTypes&filter.categories&filter.statuses&filter.order&filter.term&filter.active',
581           template: '<catalog-page></catalog-page>',
582           resolve: {
583             auth: ["$q", "AuthenticationServiceNg2", ($q: any, authService: AuthenticationService) => {
584               let userInfo: IUserProperties = authService.getLoggedinUser();
585               if (userInfo) {
586                 return $q.when(userInfo);
587               } else {
588                 return $q.reject({authenticated: false});
589               }
590             }]
591           }
592         }
593     );
594
595     $stateProvider.state(
596         'error-403', {
597           url: '/error-403',
598           templateUrl: "./view-models/modals/error-modal/error-403-view.html",
599           controller: viewModelsModuleName + '.ErrorViewModel'
600         }
601     );
602
603     tooltipsConfigProvider.options({
604       side: 'bottom',
605       delay: '600',
606       class: 'tooltip-custom',
607       lazy: 0,
608       try: 0
609     });
610
611   }
612 ]);
613
614 ng1appModule.value('ValidationPattern', /^[\s\w\&_.:-]{1,1024}$/);
615 ng1appModule.value('ComponentNameValidationPattern', /^(?=.*[^. ])[\s\w\&_.:-]{1,1024}$/); //DE250513 - same as ValidationPattern above, plus requirement that name not consist of dots and/or spaces alone.
616 ng1appModule.value('PropertyNameValidationPattern', /^[a-zA-Z0-9_:-]{1,50}$/);// DE210977
617 ng1appModule.value('TagValidationPattern', /^[\s\w_.-]{1,50}$/);
618 ng1appModule.value('VendorReleaseValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,25}$/);
619 ng1appModule.value('VendorNameValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,60}$/);
620 ng1appModule.value('VendorModelNumberValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,65}$/);
621 ng1appModule.value('ServiceTypeAndRoleValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,256}$/);
622 ng1appModule.value('ContactIdValidationPattern', /^[\s\w-]{1,50}$/);
623 ng1appModule.value('UserIdValidationPattern', /^[\s\w-]{1,50}$/);
624 ng1appModule.value('LabelValidationPattern', /^[\sa-zA-Z0-9+-]{1,25}$/);
625 ng1appModule.value('UrlValidationPattern', /^(https?|ftp):\/\/(((([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([A-Za-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([A-Za-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/);
626 ng1appModule.value('IntegerValidationPattern', /^(([-+]?\d+)|([-+]?0x[0-9a-fA-F]+))$/);
627 ng1appModule.value('IntegerNoLeadingZeroValidationPattern', /^(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)$/);
628 ng1appModule.value('FloatValidationPattern', /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?$/);
629 ng1appModule.value('NumberValidationPattern', /^((([-+]?\d+)|([-+]?0x[0-9a-fA-F]+))|([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?))$/);
630 ng1appModule.value('KeyValidationPattern', /^[\s\w-]{1,50}$/);
631 ng1appModule.value('CommentValidationPattern', /^[\u0000-\u00BF]*$/);
632 ng1appModule.value('BooleanValidationPattern', /^([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])$/);
633 ng1appModule.value('MapKeyValidationPattern', /^[\w]{1,50}$/);
634
635 ng1appModule.constant('sdcConfig', sdcConfig);
636 ng1appModule.constant('sdcMenu', sdcMenu);
637
638 ng1appModule.run([
639   '$http',
640   'Sdc.Services.CacheService',
641   'Sdc.Services.CookieService',
642   'AuthenticationServiceNg2',
643   '$state',
644   '$rootScope',
645   '$location',
646   'sdcMenu',
647   'Sdc.Services.EcompHeaderService',
648   'LeftPaletteLoaderService',
649   'Sdc.Services.DataTypesService',
650   'AngularJSBridge',
651   '$templateCache',
652   'ModalServiceSdcUI',
653   ($http: ng.IHttpService,
654    cacheService: CacheService,
655    cookieService: CookieService,
656    authService: AuthenticationService,
657    $state: ng.ui.IStateService,
658    $rootScope: ng.IRootScopeService,
659    $location: ng.ILocationService,
660    sdcMenu: IAppMenu,
661    ecompHeaderService: EcompHeaderService,
662    LeftPaletteLoaderService: LeftPaletteLoaderService,
663    DataTypesService: DataTypesService,
664    AngularJSBridge,
665    $templateCache: ng.ITemplateCacheService,
666    ModalServiceSdcUI: SdcUiServices.ModalService): void => {
667     $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
668     $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
669
670     // Add hosted applications to sdcConfig
671     sdcConfig.hostedApplications = hostedApplications;
672
673     //handle http config
674     $http.defaults.withCredentials = true;
675     // $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
676     $http.defaults.headers.common[cookieService.getUserIdSuffix()] = cookieService.getUserId();
677
678     DataTypesService.loadDataTypesCache(null);
679
680     //handle stateChangeStart
681     let internalDeregisterStateChangeStartWatcher: Function = (): void => {
682       if (deregisterStateChangeStartWatcher) {
683         deregisterStateChangeStartWatcher();
684         deregisterStateChangeStartWatcher = null;
685       }
686       if (deregisterStateChangeSuccessWatcher) {
687         deregisterStateChangeSuccessWatcher();
688         deregisterStateChangeSuccessWatcher = null;
689       }
690     };
691
692     let removeLoader: Function = (): void => {
693       $(".sdc-loading-page .main-loader").addClass("animated fadeOut");
694       $(".sdc-loading-page .caption1").addClass("animated fadeOut");
695       $(".sdc-loading-page .caption2").addClass("animated fadeOut");
696       window.setTimeout((): void => {
697         $(".sdc-loading-page .main-loader").css("display", "none");
698         $(".sdc-loading-page .caption1").css("display", "none");
699         $(".sdc-loading-page .caption2").css("display", "none");
700         $(".sdc-loading-page").addClass("animated fadeOut");
701       }, 1000);
702     };
703
704     let onNavigateOut: Function = (toState, toParams): void => {
705       let onOk: Function = (): void => {
706         $state.current.data.unsavedChanges = false;
707         $state.go(toState.name, toParams);
708       };
709
710       let data = sdcMenu.alertMessages.exitWithoutSaving;
711       const okButton = {
712         testId: "OK",
713         text: sdcMenu.alertMessages.okButton,
714         type: SdcUiCommon.ButtonType.warning,
715         callback: onOk,
716         closeModal: true
717       } as SdcUiComponents.ModalButtonComponent;
718       //open notify to user if changes are not saved
719       ModalServiceSdcUI.openWarningModal(data.title,
720           data.message,
721           'navigate-modal',
722           [okButton]);
723     };
724
725     let onStateChangeStart: Function = (event, toState, toParams, fromState, fromParams): void => {
726       console.info((new Date()).getTime());
727       console.info('$stateChangeStart', toState.name);
728       if (toState.name !== 'error-403' && !authService.getLoggedinUser()) {
729
730
731         authService.authenticate().subscribe((userInfo: IUserProperties) => {
732           if (!doesUserHasAccess(toState, userInfo)) {
733             $state.go('error-403');
734             console.info('User has no permissions');
735             return;
736           }
737           authService.setLoggedinUser(userInfo);
738           setTimeout(function () {
739
740             removeLoader();
741
742             if (authService.getLoggedinUser().role === 'ADMIN') {
743               // toState.name = "adminDashboard";
744               $state.go("adminDashboard", toParams);
745               return;
746             }
747
748             // After user authorized init categories
749             window.setTimeout((): void => {
750               if ($state.current.name === '') {
751                 $state.go(toState.name, toParams);
752               }
753
754               console.log("------$state.current.name=" + $state.current.name);
755
756             }, 1000);
757
758           }, 0);
759
760         }, () => {
761           $state.go('error-403');
762         });
763       } else if (authService.getLoggedinUser()) {
764         let user: IUserProperties = authService.getLoggedinUser();
765         if (!cacheService.contains('user')) {
766           cacheService.set('user', user);
767         }
768
769         if (!doesUserHasAccess(toState, authService.getLoggedinUser())) {
770           event.preventDefault();
771           $state.go('error-403');
772           console.info('User has no permissions');
773         }
774
775         if (authService.getLoggedinUser().role === 'ADMIN') {
776           // toState.name = "adminDashboard";
777           $state.go("adminDashboard", toParams);
778           return;
779         }
780
781
782         //if form is dirty and not save  - notify to user
783         if (fromState.data && fromState.data.unsavedChanges && fromParams.id != toParams.id) {
784           event.preventDefault();
785           onNavigateOut(toState, toParams);
786         }
787       }
788
789       // if enetering workspace, set the previousState param
790       if (toState.name.indexOf('workspace') !== -1) {
791         if (!toParams.previousState) {
792           const tmpPreviousState1 = fromParams && fromParams.previousState;
793           const tmpPreviousState2 = (['dashboard', 'catalog'].indexOf(fromState.name) !== -1) ? fromState.name : 'catalog';
794           toParams.previousState = tmpPreviousState1 || tmpPreviousState2;
795         }
796       }
797
798     };
799
800     let onStateChangeSuccess: Function = (event, toState, toParams, fromState, fromParams): void => {
801       console.info('$stateChangeSuccess', toState.name);
802
803       // Workaround in case we are entering other state then workspace (user move to catalog)
804       // remove the changeComponentCsarVersion, user should open again the VSP list and select one for update.
805       if (toState.name.indexOf('workspace') === -1) {
806         if (cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
807           cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
808         }
809         if (cacheService.contains(PREVIOUS_CSAR_COMPONENT)) {
810           cacheService.remove(PREVIOUS_CSAR_COMPONENT);
811         }
812       }
813
814       //set body class
815       $rootScope['bodyClass'] = 'default-class';
816       if (toState.data && toState.data.bodyClass) {
817         $rootScope['bodyClass'] = toState.data.bodyClass;
818       }
819     };
820
821     let doesUserHasAccess: Function = (toState, user): boolean => {
822
823       let isUserHasAccess = true;
824       if (toState.permissions && toState.permissions.length > 0) {
825         isUserHasAccess = _.includes(toState.permissions, user.role);
826       }
827       return isUserHasAccess;
828     };
829     let deregisterStateChangeStartWatcher: Function;
830     let deregisterStateChangeSuccessWatcher: Function;
831
832     let registerStateChangeStartWatcher: Function = (): void => {
833       internalDeregisterStateChangeStartWatcher();
834       console.info('registerStateChangeStartWatcher $stateChangeStart');
835       deregisterStateChangeStartWatcher = $rootScope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams): void => {
836         onStateChangeStart(event, toState, toParams, fromState, fromParams);
837       });
838       deregisterStateChangeSuccessWatcher = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState, fromParams): void => {
839         onStateChangeSuccess(event, toState, toParams, fromState, fromParams);
840       });
841     };
842     registerStateChangeStartWatcher();
843   }]);
844