Feature-5950: Management of quotas in VIM Account
[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 { 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     mode: this.modeDefault,
102     showCursorWhenSelecting: true,
103     autofocus: true,
104     autoRefresh: true,
105     lineNumbers: true,
106     lineWrapping: true,
107     foldGutter: true,
108     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
109     autoCloseBrackets: true,
110     matchBrackets: true,
111     theme: 'neat',
112     keyMap: 'sublime'
113   };
114
115   /** Data @public */
116   public data: string = '';
117
118   /** Element ref for fileInput @public */
119   @ViewChild('fileInput', { static: true }) public fileInput: ElementRef;
120
121   /** Element ref for fileInput @public */
122   @ViewChild('fileInputLabel', { static: true }) public fileInputLabel: ElementRef;
123
124   /** Contains all methods related to shared @private */
125   public sharedService: SharedService;
126
127   /** Instance of the rest service @private */
128   private restService: RestService;
129
130   /** Holds the instance of router class @private */
131   private router: Router;
132
133   /** Controls the header form @private */
134   private headers: HttpHeaders;
135
136   /** FormBuilder instance added to the formBuilder @private */
137   private formBuilder: FormBuilder;
138
139   /** Notifier service to popup notification @private */
140   private notifierService: NotifierService;
141
142   /** Contains tranlsate instance @private */
143   private translateService: TranslateService;
144
145   /** VIM Details @private */
146   private vimDetail: VimAccountDetails[];
147
148   constructor(injector: Injector) {
149     this.injector = injector;
150     this.restService = this.injector.get(RestService);
151     this.formBuilder = this.injector.get(FormBuilder);
152     this.router = this.injector.get(Router);
153     this.notifierService = this.injector.get(NotifierService);
154     this.translateService = this.injector.get(TranslateService);
155     this.sharedService = this.injector.get(SharedService);
156   }
157
158   /** convenience getter for easy access to form fields */
159   get f(): FormGroup['controls'] { return this.vimNewAccountForm.controls; }
160
161   /**
162    * Lifecyle Hooks the trigger before component is instantiate
163    */
164   public ngOnInit(): void {
165     this.vimType = VIM_TYPES;
166     this.headers = new HttpHeaders({
167       Accept: 'application/json',
168       'Content-Type': 'application/json',
169       'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
170     });
171     this.initializeForm();
172   }
173
174   /** VIM Initialize Forms @public */
175   public initializeForm(): void {
176     this.vimNewAccountForm = this.formBuilder.group({
177       name: [null, Validators.required],
178       vim_type: [null, Validators.required],
179       vim_tenant_name: [null, Validators.required],
180       description: [null],
181       vim_url: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_URL_PATTERN)]],
182       schema_type: [''],
183       vim_user: [null, Validators.required],
184       vim_password: [null, Validators.required],
185       locationName: [''],
186       latitude: ['', Validators.pattern(this.sharedService.REGX_LAT_PATTERN)],
187       longitude: ['', Validators.pattern(this.sharedService.REGX_LONG_PATTERN)],
188       config: this.paramsBuilder()
189     });
190   }
191
192   /** Generate params for config @public */
193   public paramsBuilder(): FormGroup {
194     return this.formBuilder.group({
195       location: [null]
196     });
197   }
198
199   /** On modal submit newVimAccountSubmit will called @public */
200   public newVimAccountSubmit(): void {
201     this.submitted = true;
202
203     if (!this.vimNewAccountForm.invalid) {
204       this.isLocationLoadingResults = true;
205       this.sharedService.cleanForm(this.vimNewAccountForm, 'vim');
206       if (!isNullOrUndefined(this.data) && this.data !== '') {
207         Object.assign(this.vimNewAccountForm.value.config, jsyaml.load(this.data.toString(), { json: true }));
208       } else {
209         Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
210           if (res !== 'location') {
211             delete this.vimNewAccountForm.value.config[res];
212           }
213         });
214       }
215       if (!isNullOrUndefined(this.vimNewAccountForm.value.latitude) && !isNullOrUndefined(this.vimNewAccountForm.value.longitude)) {
216         this.vimNewAccountForm.value.config.location = this.vimNewAccountForm.value.locationName + ',' +
217           this.vimNewAccountForm.value.longitude + ',' +
218           this.vimNewAccountForm.value.latitude;
219       }
220
221       if (isNullOrUndefined(this.vimNewAccountForm.value.config.location)) {
222         delete this.vimNewAccountForm.value.config.location;
223       }
224
225       Object.keys(this.vimNewAccountForm.value.config).forEach((res: string): void => {
226         if (isNullOrUndefined(this.vimNewAccountForm.value.config[res]) || this.vimNewAccountForm.value.config[res] === '') {
227           delete this.vimNewAccountForm.value.config[res];
228         }
229       });
230       this.createNewVIM();
231     }
232   }
233
234   /** Create a new VIM Account @public */
235   public createNewVIM(): void {
236     const apiURLHeader: APIURLHEADER = {
237       url: environment.VIMACCOUNTS_URL,
238       httpOptions: { headers: this.headers }
239     };
240     delete this.vimNewAccountForm.value.locationName;
241     delete this.vimNewAccountForm.value.latitude;
242     delete this.vimNewAccountForm.value.longitude;
243     this.restService.postResource(apiURLHeader, this.vimNewAccountForm.value)
244       .subscribe((result: {id: string}): void => {
245         this.notifierService.notify('success', this.translateService.instant('PAGE.VIM.CREATEDSUCCESSFULLY'));
246         this.isLocationLoadingResults = false;
247         this.router.navigate(['vim/info/' + result.id]).catch((): void => {
248           // Error Cached;
249         });
250       }, (error: ERRORDATA): void => {
251         this.restService.handleError(error, 'post');
252         this.isLocationLoadingResults = false;
253       });
254   }
255
256   /** HandleChange function @public */
257   public handleChange($event: string): void {
258     this.data = $event;
259   }
260
261   /** Routing to VIM Account Details Page @public */
262   public onVimAccountBack(): void {
263     this.router.navigate(['vim/details']).catch((): void => {
264       // Error Cached
265     });
266   }
267
268   /** Drag and drop feature and fetchind the details of files  @private */
269   public filesDropped(files: FileList): void {
270     if (files && files.length === 1) {
271       this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
272         const getJson: string = jsyaml.load(fileContent, { json: true });
273         this.defaults['text/x-yaml'] = fileContent;
274         this.data = fileContent;
275       }).catch((err: string): void => {
276         if (err === 'typeError') {
277           this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
278         } else {
279           this.notifierService.notify('error', this.translateService.instant('ERROR'));
280         }
281         this.fileInputLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
282         this.fileInput.nativeElement.value = null;
283       });
284     } else if (files && files.length > 1) {
285       this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
286     }
287     this.fileInputLabel.nativeElement.innerText = files[0].name;
288     this.fileInput.nativeElement.value = null;
289   }
290
291   /** Load sample config based on VIM type @public */
292   public loadSampleConfig(): void {
293     this.clearConfig();
294     if (this.selectedVimType === 'openstack') {
295       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENSTACK);
296       this.data = JSON.stringify(TYPEOPENSTACK, null, '\t');
297     } else if (this.selectedVimType === 'aws') {
298       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAWS);
299       this.data = JSON.stringify(TYPEAWS, null, '\t');
300     } else if (this.selectedVimType === 'vmware') {
301       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEVMWARE);
302       this.data = JSON.stringify(TYPEVMWARE, null, '\t');
303     } else if (this.selectedVimType === 'openvim' || this.selectedVimType === 'opennebula') {
304       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENVIMNEBULA);
305       this.data = JSON.stringify(TYPEOPENVIMNEBULA, null, '\t');
306     } else if (this.selectedVimType === 'azure' || this.selectedVimType === 'opennebula') {
307       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAZURE);
308       this.data = JSON.stringify(TYPEAZURE, null, '\t');
309     } else {
310       this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOTERS);
311       this.data = JSON.stringify(TYPEOTERS, null, '\t');
312     }
313   }
314
315   /** Clear config parameters @public */
316   public clearConfig(): void {
317     this.defaults['text/x-yaml'] = '';
318     this.data = '';
319     this.fileInput.nativeElement.value = null;
320   }
321 }