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