a57b7822a7a50591fa485325f04323971a62fee1
[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 { isNullOrUndefined } from 'util';
22 import { HttpHeaders } from '@angular/common/http';
23 import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
24 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
25 import { Router } from '@angular/router';
26 import { TranslateService } from '@ngx-translate/core';
27 import { NotifierService } from 'angular-notifier';
28 import 'codemirror/addon/dialog/dialog';
29 import 'codemirror/addon/display/autorefresh';
30 import 'codemirror/addon/display/fullscreen';
31 import 'codemirror/addon/edit/closebrackets';
32 import 'codemirror/addon/edit/matchbrackets';
33 import 'codemirror/addon/fold/brace-fold';
34 import 'codemirror/addon/fold/foldcode';
35 import 'codemirror/addon/fold/foldgutter';
36 import 'codemirror/addon/search/search';
37 import 'codemirror/addon/search/searchcursor';
38 import 'codemirror/keymap/sublime';
39 import 'codemirror/lib/codemirror';
40 import 'codemirror/mode/javascript/javascript';
41 import 'codemirror/mode/markdown/markdown';
42 import 'codemirror/mode/yaml/yaml';
43 import {
44   APIURLHEADER, ERRORDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS,
45   TYPESECTION, TYPEVMWARE, VIM_TYPES
46 } from 'CommonModel';
47 import { environment } from 'environment';
48 import * as jsyaml from 'js-yaml';
49 import { RestService } from 'RestService';
50 import { SharedService } from 'SharedService';
51 import { VimAccountDetails } from 'VimAccountModel';
52
53 /**
54  * Creating component
55  * @Component takes NewVimaccountComponent.html as template url
56  */
57 @Component({
58   selector: 'app-new-vimaccount',
59   templateUrl: './NewVimaccountComponent.html',
60   styleUrls: ['./NewVimaccountComponent.scss']
61 })
62 /** Exporting a class @exports NewVimaccountComponent */
63 export class NewVimaccountComponent implements OnInit {
64   /** To inject services @public */
65   public injector: Injector;
66
67   /** FormGroup vim New Account added to the form @ html @public */
68   public vimNewAccountForm: FormGroup;
69
70   /** Supported Vim type for the dropdown */
71   public vimType: TYPESECTION[];
72
73   /** Supported Vim type for the dropdown */
74   public selectedVimType: string;
75
76   /** Form submission Add */
77   public submitted: boolean = false;
78
79   /** Showing more details of collapase */
80   public isCollapsed: boolean = false;
81
82   /** Check the Projects loading results @public */
83   public isLocationLoadingResults: boolean = false;
84
85   /** Give the message for the loading @public */
86   public message: string = 'PLEASEWAIT';
87
88   /** Handle the formate Change @public */
89   public defaults: {} = {
90     'text/x-yaml': ''
91   };
92
93   /** To Set Mode @public */
94   public mode: string = 'text/x-yaml';
95
96   /** To Set Mode @public */
97   public modeDefault: string = 'yaml';
98
99   /** options @public */
100   public options: {} = {
101     // eslint-disable-next-line no-invalid-this
102     mode: this.modeDefault,
103     showCursorWhenSelecting: true,
104     autofocus: true,
105     autoRefresh: true,
106     lineNumbers: true,
107     lineWrapping: true,
108     foldGutter: true,
109     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
110     autoCloseBrackets: true,
111     matchBrackets: true,
112     theme: 'neat',
113     keyMap: 'sublime'
114   };
115
116   /** Data @public */
117   public data: string = '';
118
119   /** Element ref for fileInput @public */
120   @ViewChild('fileInput', { static: true }) public fileInput: ElementRef;
121
122   /** Element ref for fileInput @public */
123   @ViewChild('fileInputLabel', { static: true }) public fileInputLabel: ElementRef;
124
125   /** Contains all methods related to shared @private */
126   public sharedService: SharedService;
127
128   /** Instance of the rest service @private */
129   private restService: RestService;
130
131   /** Holds the instance of router class @private */
132   private router: Router;
133
134   /** Controls the header form @private */
135   private headers: HttpHeaders;
136
137   /** FormBuilder instance added to the formBuilder @private */
138   private formBuilder: FormBuilder;
139
140   /** Notifier service to popup notification @private */
141   private notifierService: NotifierService;
142
143   /** Contains tranlsate instance @private */
144   private translateService: TranslateService;
145
146   /** VIM Details @private */
147   private vimDetail: VimAccountDetails[];
148
149   constructor(injector: Injector) {
150     this.injector = injector;
151     this.restService = this.injector.get(RestService);
152     this.formBuilder = this.injector.get(FormBuilder);
153     this.router = this.injector.get(Router);
154     this.notifierService = this.injector.get(NotifierService);
155     this.translateService = this.injector.get(TranslateService);
156     this.sharedService = this.injector.get(SharedService);
157   }
158
159   /** convenience getter for easy access to form fields */
160   get f(): FormGroup['controls'] { return this.vimNewAccountForm.controls; }
161
162   /**
163    * Lifecyle Hooks the trigger before component is instantiate
164    */
165   public ngOnInit(): void {
166     this.vimType = VIM_TYPES;
167     this.headers = new HttpHeaders({
168       Accept: 'application/json',
169       'Content-Type': 'application/json',
170       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
171     });
172     this.initializeForm();
173   }
174
175   /** VIM Initialize Forms @public */
176   public initializeForm(): void {
177     this.vimNewAccountForm = this.formBuilder.group({
178       name: [null, Validators.required],
179       vim_type: [null, Validators.required],
180       vim_tenant_name: [null, Validators.required],
181       description: [null],
182       vim_url: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_URL_PATTERN)]],
183       schema_type: [''],
184       vim_user: [null, Validators.required],
185       vim_password: [null, Validators.required],
186       locationName: [''],
187       latitude: ['', Validators.pattern(this.sharedService.REGX_LAT_PATTERN)],
188       longitude: ['', Validators.pattern(this.sharedService.REGX_LONG_PATTERN)],
189       config: this.paramsBuilder()
190     });
191   }
192
193   /** Generate params for config @public */
194   public paramsBuilder(): FormGroup {
195     return this.formBuilder.group({
196       location: [null]
197     });
198   }
199
200   /** On modal submit newVimAccountSubmit will called @public */
201   public newVimAccountSubmit(): void {
202     this.submitted = true;
203
204     if (!this.vimNewAccountForm.invalid) {
205       this.isLocationLoadingResults = true;
206       this.sharedService.cleanForm(this.vimNewAccountForm, 'vim');
207       if (!isNullOrUndefined(this.data) && this.data !== '') {
208         Object.assign(this.vimNewAccountForm.value.config, jsyaml.load(this.data.toString(), { json: true }));
209       } else {
210         Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
211           if (res !== 'location') {
212             // eslint-disable-next-line @typescript-eslint/no-dynamic-delete, security/detect-object-injection
213             delete this.vimNewAccountForm.value.config[res];
214           }
215         });
216       }
217       if (!isNullOrUndefined(this.vimNewAccountForm.value.latitude) && !isNullOrUndefined(this.vimNewAccountForm.value.longitude)) {
218         this.vimNewAccountForm.value.config.location = this.vimNewAccountForm.value.locationName + ',' +
219           this.vimNewAccountForm.value.longitude + ',' +
220           this.vimNewAccountForm.value.latitude;
221       }
222
223       if (isNullOrUndefined(this.vimNewAccountForm.value.config.location)) {
224         delete this.vimNewAccountForm.value.config.location;
225       }
226
227       Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
228         // eslint-disable-next-line security/detect-object-injection
229         if (isNullOrUndefined(this.vimNewAccountForm.value.config[res]) || this.vimNewAccountForm.value.config[res] === '') {
230           // eslint-disable-next-line @typescript-eslint/no-dynamic-delete, security/detect-object-injection
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 }