Retrieve data types based on component model
[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         'workspace.plugins', {
516           url: 'plugins/*path',
517           parent: 'workspace',
518           template: '<plugin-context-view></plugin-context-view>',
519           resolve: {
520             componentData: ['injectComponent', '$stateParams', function (injectComponent: Component, $stateParams) {
521               $stateParams.component = injectComponent;
522               return injectComponent;
523             }],
524           }
525
526         }
527     );
528
529     $stateProvider.state(
530         'adminDashboard', {
531           url: '/adminDashboard',
532           templateUrl: './view-models/admin-dashboard/admin-dashboard-view.html',
533           controller: viewModelsModuleName + '.AdminDashboardViewModel',
534           permissions: ['ADMIN']
535         }
536     );
537
538     $stateProvider.state(
539         'onboardVendor', {
540           url: '/onboardVendor',
541           templateUrl: './view-models/onboard-vendor/onboard-vendor-view.html',
542           controller: viewModelsModuleName + '.OnboardVendorViewModel'
543         }
544     );
545
546     $stateProvider.state(
547         'plugins', {
548           url: '/plugins/*path',
549           template: '<plugin-tab-view></plugin-tab-view>'
550         }
551     );
552
553     // Build the states for all hosted apps dynamically
554     _.each(hostedApplications, (hostedApp) => {
555       if (hostedApp.exists) {
556         $stateProvider.state(
557             hostedApp.state.name, {
558               url: hostedApp.state.url,
559               templateUrl: './view-models/dcae-app/dcae-app-view.html',
560               controller: viewModelsModuleName + hostedApp.state.controllerName
561             }
562         );
563       }
564     });
565
566     $stateProvider.state(
567         'catalog', {
568           url: '/catalog?filter.components&filter.resourceSubTypes&filter.categories&filter.statuses&filter.order&filter.term&filter.active',
569           template: '<catalog-page></catalog-page>',
570           resolve: {
571             auth: ["$q", "AuthenticationServiceNg2", ($q: any, authService: AuthenticationService) => {
572               let userInfo: IUserProperties = authService.getLoggedinUser();
573               if (userInfo) {
574                 return $q.when(userInfo);
575               } else {
576                 return $q.reject({authenticated: false});
577               }
578             }]
579           }
580         }
581     );
582
583     $stateProvider.state(
584         'error-403', {
585           url: '/error-403',
586           templateUrl: "./view-models/modals/error-modal/error-403-view.html",
587           controller: viewModelsModuleName + '.ErrorViewModel'
588         }
589     );
590
591     tooltipsConfigProvider.options({
592       side: 'bottom',
593       delay: '600',
594       class: 'tooltip-custom',
595       lazy: 0,
596       try: 0
597     });
598
599   }
600 ]);
601
602 ng1appModule.value('ValidationPattern', /^[\s\w\&_.:-]{1,1024}$/);
603 ng1appModule.value('ComponentNameValidationPattern', /^(?=.*[^. ])[\s\w\&_.:-]{1,1024}$/); //DE250513 - same as ValidationPattern above, plus requirement that name not consist of dots and/or spaces alone.
604 ng1appModule.value('PropertyNameValidationPattern', /^[a-zA-Z0-9_:-]{1,50}$/);// DE210977
605 ng1appModule.value('TagValidationPattern', /^[\s\w_.-]{1,50}$/);
606 ng1appModule.value('VendorReleaseValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,25}$/);
607 ng1appModule.value('VendorNameValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,60}$/);
608 ng1appModule.value('VendorModelNumberValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,65}$/);
609 ng1appModule.value('ServiceTypeAndRoleValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,256}$/);
610 ng1appModule.value('ContactIdValidationPattern', /^[\s\w-]{1,50}$/);
611 ng1appModule.value('UserIdValidationPattern', /^[\s\w-]{1,50}$/);
612 ng1appModule.value('LabelValidationPattern', /^[\sa-zA-Z0-9+-]{1,25}$/);
613 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})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/);
614 ng1appModule.value('IntegerValidationPattern', /^(([-+]?\d+)|([-+]?0x[0-9a-fA-F]+))$/);
615 ng1appModule.value('IntegerNoLeadingZeroValidationPattern', /^(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)$/);
616 ng1appModule.value('FloatValidationPattern', /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?$/);
617 ng1appModule.value('NumberValidationPattern', /^((([-+]?\d+)|([-+]?0x[0-9a-fA-F]+))|([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?))$/);
618 ng1appModule.value('KeyValidationPattern', /^[\s\w-]{1,50}$/);
619 ng1appModule.value('CommentValidationPattern', /^[\u0000-\u00BF]*$/);
620 ng1appModule.value('BooleanValidationPattern', /^([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])$/);
621 ng1appModule.value('MapKeyValidationPattern', /^[\w]{1,50}$/);
622
623 ng1appModule.constant('sdcConfig', sdcConfig);
624 ng1appModule.constant('sdcMenu', sdcMenu);
625
626 ng1appModule.run([
627   '$http',
628   'Sdc.Services.CacheService',
629   'Sdc.Services.CookieService',
630   'AuthenticationServiceNg2',
631   '$state',
632   '$rootScope',
633   '$location',
634   'sdcMenu',
635   'Sdc.Services.EcompHeaderService',
636   'LeftPaletteLoaderService',
637   'Sdc.Services.DataTypesService',
638   'AngularJSBridge',
639   '$templateCache',
640   'ModalServiceSdcUI',
641   ($http: ng.IHttpService,
642    cacheService: CacheService,
643    cookieService: CookieService,
644    authService: AuthenticationService,
645    $state: ng.ui.IStateService,
646    $rootScope: ng.IRootScopeService,
647    $location: ng.ILocationService,
648    sdcMenu: IAppMenu,
649    ecompHeaderService: EcompHeaderService,
650    LeftPaletteLoaderService: LeftPaletteLoaderService,
651    DataTypesService: DataTypesService,
652    AngularJSBridge,
653    $templateCache: ng.ITemplateCacheService,
654    ModalServiceSdcUI: SdcUiServices.ModalService): void => {
655     $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
656     $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
657
658     // Add hosted applications to sdcConfig
659     sdcConfig.hostedApplications = hostedApplications;
660
661     //handle http config
662     $http.defaults.withCredentials = true;
663     // $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
664     $http.defaults.headers.common[cookieService.getUserIdSuffix()] = cookieService.getUserId();
665
666     DataTypesService.fetchDataTypesByModel(null);
667
668     //handle stateChangeStart
669     let internalDeregisterStateChangeStartWatcher: Function = (): void => {
670       if (deregisterStateChangeStartWatcher) {
671         deregisterStateChangeStartWatcher();
672         deregisterStateChangeStartWatcher = null;
673       }
674       if (deregisterStateChangeSuccessWatcher) {
675         deregisterStateChangeSuccessWatcher();
676         deregisterStateChangeSuccessWatcher = null;
677       }
678     };
679
680     let removeLoader: Function = (): void => {
681       $(".sdc-loading-page .main-loader").addClass("animated fadeOut");
682       $(".sdc-loading-page .caption1").addClass("animated fadeOut");
683       $(".sdc-loading-page .caption2").addClass("animated fadeOut");
684       window.setTimeout((): void => {
685         $(".sdc-loading-page .main-loader").css("display", "none");
686         $(".sdc-loading-page .caption1").css("display", "none");
687         $(".sdc-loading-page .caption2").css("display", "none");
688         $(".sdc-loading-page").addClass("animated fadeOut");
689       }, 1000);
690     };
691
692     let onNavigateOut: Function = (toState, toParams): void => {
693       let onOk: Function = (): void => {
694         $state.current.data.unsavedChanges = false;
695         $state.go(toState.name, toParams);
696       };
697
698       let data = sdcMenu.alertMessages.exitWithoutSaving;
699       const okButton = {
700         testId: "OK",
701         text: sdcMenu.alertMessages.okButton,
702         type: SdcUiCommon.ButtonType.warning,
703         callback: onOk,
704         closeModal: true
705       } as SdcUiComponents.ModalButtonComponent;
706       //open notify to user if changes are not saved
707       ModalServiceSdcUI.openWarningModal(data.title,
708           data.message,
709           'navigate-modal',
710           [okButton]);
711     };
712
713     let onStateChangeStart: Function = (event, toState, toParams, fromState, fromParams): void => {
714       console.info((new Date()).getTime());
715       console.info('$stateChangeStart', toState.name);
716       if (toState.name !== 'error-403' && !authService.getLoggedinUser()) {
717
718
719         authService.authenticate().subscribe((userInfo: IUserProperties) => {
720           if (!doesUserHasAccess(toState, userInfo)) {
721             $state.go('error-403');
722             console.info('User has no permissions');
723             return;
724           }
725           authService.setLoggedinUser(userInfo);
726           setTimeout(function () {
727
728             removeLoader();
729
730             if (authService.getLoggedinUser().role === 'ADMIN') {
731               // toState.name = "adminDashboard";
732               $state.go("adminDashboard", toParams);
733               return;
734             }
735
736             // After user authorized init categories
737             window.setTimeout((): void => {
738               if ($state.current.name === '') {
739                 $state.go(toState.name, toParams);
740               }
741
742               console.log("------$state.current.name=" + $state.current.name);
743
744             }, 1000);
745
746           }, 0);
747
748         }, () => {
749           $state.go('error-403');
750         });
751       } else if (authService.getLoggedinUser()) {
752         let user: IUserProperties = authService.getLoggedinUser();
753         if (!cacheService.contains('user')) {
754           cacheService.set('user', user);
755         }
756
757         if (!doesUserHasAccess(toState, authService.getLoggedinUser())) {
758           event.preventDefault();
759           $state.go('error-403');
760           console.info('User has no permissions');
761         }
762
763         if (authService.getLoggedinUser().role === 'ADMIN') {
764           // toState.name = "adminDashboard";
765           $state.go("adminDashboard", toParams);
766           return;
767         }
768
769
770         //if form is dirty and not save  - notify to user
771         if (fromState.data && fromState.data.unsavedChanges && fromParams.id != toParams.id) {
772           event.preventDefault();
773           onNavigateOut(toState, toParams);
774         }
775       }
776
777       // if enetering workspace, set the previousState param
778       if (toState.name.indexOf('workspace') !== -1) {
779         if (!toParams.previousState) {
780           const tmpPreviousState1 = fromParams && fromParams.previousState;
781           const tmpPreviousState2 = (['dashboard', 'catalog'].indexOf(fromState.name) !== -1) ? fromState.name : 'catalog';
782           toParams.previousState = tmpPreviousState1 || tmpPreviousState2;
783         }
784       }
785
786     };
787
788     let onStateChangeSuccess: Function = (event, toState, toParams, fromState, fromParams): void => {
789       console.info('$stateChangeSuccess', toState.name);
790
791       // Workaround in case we are entering other state then workspace (user move to catalog)
792       // remove the changeComponentCsarVersion, user should open again the VSP list and select one for update.
793       if (toState.name.indexOf('workspace') === -1) {
794         if (cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
795           cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
796         }
797         if (cacheService.contains(PREVIOUS_CSAR_COMPONENT)) {
798           cacheService.remove(PREVIOUS_CSAR_COMPONENT);
799         }
800       }
801
802       //set body class
803       $rootScope['bodyClass'] = 'default-class';
804       if (toState.data && toState.data.bodyClass) {
805         $rootScope['bodyClass'] = toState.data.bodyClass;
806       }
807     };
808
809     let doesUserHasAccess: Function = (toState, user): boolean => {
810
811       let isUserHasAccess = true;
812       if (toState.permissions && toState.permissions.length > 0) {
813         isUserHasAccess = _.includes(toState.permissions, user.role);
814       }
815       return isUserHasAccess;
816     };
817     let deregisterStateChangeStartWatcher: Function;
818     let deregisterStateChangeSuccessWatcher: Function;
819
820     let registerStateChangeStartWatcher: Function = (): void => {
821       internalDeregisterStateChangeStartWatcher();
822       console.info('registerStateChangeStartWatcher $stateChangeStart');
823       deregisterStateChangeStartWatcher = $rootScope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams): void => {
824         onStateChangeStart(event, toState, toParams, fromState, fromParams);
825       });
826       deregisterStateChangeSuccessWatcher = $rootScope.$on('$stateChangeSuccess', (event, toState, toParams, fromState, fromParams): void => {
827         onStateChangeSuccess(event, toState, toParams, fromState, fromParams);
828       });
829     };
830     registerStateChangeStartWatcher();
831   }]);
832