Fix for Bug 1495 NG-UI does not start on Air-gapped environments.
[osm/NG-UI.git] / src / app / vim-accounts / new-vimaccount / NewVimaccountComponent.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15
16  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18 /**
19  * @file Vim Account Component.
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
23 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { Router } from '@angular/router';
25 import { TranslateService } from '@ngx-translate/core';
26 import { NotifierService } from 'angular-notifier';
27 import 'codemirror/addon/dialog/dialog';
28 import 'codemirror/addon/display/autorefresh';
29 import 'codemirror/addon/display/fullscreen';
30 import 'codemirror/addon/edit/closebrackets';
31 import 'codemirror/addon/edit/matchbrackets';
32 import 'codemirror/addon/fold/brace-fold';
33 import 'codemirror/addon/fold/foldcode';
34 import 'codemirror/addon/fold/foldgutter';
35 import 'codemirror/addon/search/search';
36 import 'codemirror/addon/search/searchcursor';
37 import 'codemirror/keymap/sublime';
38 import 'codemirror/lib/codemirror';
39 import 'codemirror/mode/javascript/javascript';
40 import 'codemirror/mode/markdown/markdown';
41 import 'codemirror/mode/yaml/yaml';
42 import {
43   APIURLHEADER, ERRORDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS,
44   TYPESECTION, TYPEVMWARE, VIM_TYPES
45 } from 'CommonModel';
46 import { environment } from 'environment';
47 import * as jsyaml from 'js-yaml';
48 import { RestService } from 'RestService';
49 import { SharedService } from 'SharedService';
50 import { isNullOrUndefined } from 'util';
51 import { FEATURES, VIMLOCATION, VIMLOCATIONDATA } from 'VimAccountModel';
52 import { VimAccountDetails, VIMData } from 'VimAccountModel';
53
54 /**
55  * Creating component
56  * @Component takes NewVimaccountComponent.html as template url
57  */
58 @Component({
59   selector: 'app-new-vimaccount',
60   templateUrl: './NewVimaccountComponent.html',
61   styleUrls: ['./NewVimaccountComponent.scss']
62 })
63 /** Exporting a class @exports NewVimaccountComponent */
64 export class NewVimaccountComponent implements OnInit {
65   /** To inject services @public */
66   public injector: Injector;
67
68   /** FormGroup vim New Account added to the form @ html @public */
69   public vimNewAccountForm: FormGroup;
70
71   /** Supported Vim type for the dropdown */
72   public vimType: TYPESECTION[];
73
74   /** Supported Vim type for the dropdown */
75   public selectedVimType: string;
76
77   /** Form submission Add */
78   public submitted: boolean = false;
79
80   /** Showing more details of collapase */
81   public isCollapsed: boolean = false;
82
83   /** Vim location values @public */
84   public getVIMLocation: VIMLOCATIONDATA[] = [];
85
86   /** Check the Projects loading results @public */
87   public isLocationLoadingResults: boolean = false;
88
89   /** Give the message for the loading @public */
90   public message: string = 'PLEASEWAIT';
91
92   /** Handle the formate Change @public */
93   public defaults: {} = {
94     'text/x-yaml': ''
95   };
96
97   /** To Set Mode @public */
98   public mode: string = 'text/x-yaml';
99
100   /** To Set Mode @public */
101   public modeDefault: string = 'yaml';
102
103   /** options @public */
104   public options: {} = {
105     mode: this.modeDefault,
106     showCursorWhenSelecting: true,
107     autofocus: true,
108     autoRefresh: true,
109     lineNumbers: true,
110     lineWrapping: true,
111     foldGutter: true,
112     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
113     autoCloseBrackets: true,
114     matchBrackets: true,
115     theme: 'neat',
116     keyMap: 'sublime'
117   };
118
119   /** Data @public */
120   public data: string = '';
121
122   /** Element ref for fileInput @public */
123   @ViewChild('fileInput', { static: true }) public fileInput: ElementRef;
124
125   /** Element ref for fileInput @public */
126   @ViewChild('fileInputLabel', { static: true }) public fileInputLabel: ElementRef;
127
128   /** Contains all methods related to shared @private */
129   public sharedService: SharedService;
130
131   /** Instance of the rest service @private */
132   private restService: RestService;
133
134   /** Holds the instance of router class @private */
135   private router: Router;
136
137   /** Controls the header form @private */
138   private headers: HttpHeaders;
139
140   /** FormBuilder instance added to the formBuilder @private */
141   private formBuilder: FormBuilder;
142
143   /** Notifier service to popup notification @private */
144   private notifierService: NotifierService;
145
146   /** Contains tranlsate instance @private */
147   private translateService: TranslateService;
148
149   /** VIM Details @private */
150   private vimDetail: VimAccountDetails[];
151
152   constructor(injector: Injector) {
153     this.injector = injector;
154     this.restService = this.injector.get(RestService);
155     this.formBuilder = this.injector.get(FormBuilder);
156     this.router = this.injector.get(Router);
157     this.notifierService = this.injector.get(NotifierService);
158     this.translateService = this.injector.get(TranslateService);
159     this.sharedService = this.injector.get(SharedService);
160   }
161
162   /** convenience getter for easy access to form fields */
163   get f(): FormGroup['controls'] { return this.vimNewAccountForm.controls; }
164
165   /**
166    * Lifecyle Hooks the trigger before component is instantiate
167    */
168   public ngOnInit(): void {
169     this.vimType = VIM_TYPES;
170     this.headers = new HttpHeaders({
171       Accept: 'application/json',
172       'Content-Type': 'application/json',
173       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
174     });
175     this.initializeForm();
176   }
177
178   /** VIM Initialize Forms @public */
179   public initializeForm(): void {
180     this.vimNewAccountForm = this.formBuilder.group({
181       name: [null, Validators.required],
182       vim_type: [null, Validators.required],
183       vim_tenant_name: [null, Validators.required],
184       description: [null],
185       vim_url: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_URL_PATTERN)]],
186       schema_type: [''],
187       vim_user: [null, Validators.required],
188       vim_password: [null, Validators.required],
189       locationName: [''],
190       latitude: ['', Validators.pattern(this.sharedService.REGX_LAT_PATTERN)],
191       longitude: ['', Validators.pattern(this.sharedService.REGX_LONG_PATTERN)],
192       config: this.paramsBuilder()
193     });
194   }
195
196   /** Generate params for config @public */
197   public paramsBuilder(): FormGroup {
198     return this.formBuilder.group({
199       location: [null]
200     });
201   }
202
203   /** On modal submit newVimAccountSubmit will called @public */
204   public newVimAccountSubmit(): void {
205     this.submitted = true;
206
207     if (!this.vimNewAccountForm.invalid) {
208       this.isLocationLoadingResults = true;
209       this.sharedService.cleanForm(this.vimNewAccountForm, 'vim');
210       if (!isNullOrUndefined(this.data) && this.data !== '') {
211         Object.assign(this.vimNewAccountForm.value.config, jsyaml.load(this.data.toString(), { json: true }));
212       } else {
213         Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
214           if (res !== 'location') {
215             delete this.vimNewAccountForm.value.config[res];
216           }
217         });
218       }
219       if (!isNullOrUndefined(this.vimNewAccountForm.value.latitude) && !isNullOrUndefined(this.vimNewAccountForm.value.longitude)) {
220         this.vimNewAccountForm.value.config.location = this.vimNewAccountForm.value.locationName + ',' +
221           this.vimNewAccountForm.value.longitude + ',' +
222           this.vimNewAccountForm.value.latitude;
223       }
224
225       if (isNullOrUndefined(this.vimNewAccountForm.value.config.location)) {
226         delete this.vimNewAccountForm.value.config.location;
227       }
228
229       Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
230         if (isNullOrUndefined(this.vimNewAccountForm.value.config[res]) || this.vimNewAccountForm.value.config[res] === '') {
231           delete this.vimNewAccountForm.value.config[res];
232         }
233       });
234       this.createNewVIM();
235     }
236   }
237
238   /** Create a new VIM Account @public */
239   public createNewVIM(): void {
240     const apiURLHeader: APIURLHEADER = {
241       url: environment.VIMACCOUNTS_URL,
242       httpOptions: { headers: this.headers }
243     };
244     delete this.vimNewAccountForm.value.locationName;
245     delete this.vimNewAccountForm.value.latitude;
246     delete this.vimNewAccountForm.value.longitude;
247     this.restService.postResource(apiURLHeader, this.vimNewAccountForm.value)
248       .subscribe((result: {id: string}): void => {
249         this.notifierService.notify('success', this.translateService.instant('PAGE.VIM.CREATEDSUCCESSFULLY'));
250         this.isLocationLoadingResults = false;
251         this.router.navigate(['vim/info/' + result.id]).catch((): void => {
252           // Error Cached;
253         });
254       }, (error: ERRORDATA): void => {
255         this.restService.handleError(error, 'post');
256         this.isLocationLoadingResults = false;
257       });
258   }
259
260   /** HandleChange function @public */
261   public handleChange($event: string): void {
262     this.data = $event;
263   }
264
265   /** Routing to VIM Account Details Page @public */
266   public onVimAccountBack(): void {
267     this.router.navigate(['vim/details']).catch((): void => {
268       // Error Cached
269     });
270   }
271
272   /** Drag and drop feature and fetchind the details of files  @private */
273   public filesDropped(files: FileList): void {
274     if (files && files.length === 1) {
275       this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
276         const getJson: string = jsyaml.load(fileContent, { json: true });
277         this.defaults['text/x-yaml'] = fileContent;
278         this.data = fileContent;
279       }).catch((err: string): void => {
280         if (err === 'typeError') {
281           this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
282         } else {
283           this.notifierService.notify('error', this.translateService.instant('ERROR'));
284         }
285         this.fileInputLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
286         this.fileInput.nativeElement.value = null;
287       });
288     } else if (files && files.length > 1) {
289       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
290     }
291     this.fileInputLabel.nativeElement.innerText = files[0].name;
292     this.fileInput.nativeElement.value = null;
293   }
294
295   /** Load sample config based on VIM type @public */
296   public loadSampleConfig(): void {
297     this.clearConfig();
298     if (this.selectedVimType === 'openstack') {
299       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENSTACK);
300       this.data = JSON.stringify(TYPEOPENSTACK, null, '\t');
301     } else if (this.selectedVimType === 'aws') {
302       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAWS);
303       this.data = JSON.stringify(TYPEAWS, null, '\t');
304     } else if (this.selectedVimType === 'vmware') {
305       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEVMWARE);
306       this.data = JSON.stringify(TYPEVMWARE, null, '\t');
307     } else if (this.selectedVimType === 'openvim' || this.selectedVimType === 'opennebula') {
308       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENVIMNEBULA);
309       this.data = JSON.stringify(TYPEOPENVIMNEBULA, null, '\t');
310     } else if (this.selectedVimType === 'azure' || this.selectedVimType === 'opennebula') {
311       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAZURE);
312       this.data = JSON.stringify(TYPEAZURE, null, '\t');
313     } else {
314       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOTERS);
315       this.data = JSON.stringify(TYPEOTERS, null, '\t');
316     }
317   }
318
319   /** Clear config parameters @public */
320   public clearConfig(): void {
321     this.defaults['text/x-yaml'] = '';
322     this.data = '';
323     this.fileInput.nativeElement.value = null;
324   }
325 }