2 Copyright 2020 TATA ELXSI
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
19 * @file Vim Account Component.
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';
43 APIURLHEADER, ERRORDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS,
44 TYPESECTION, TYPEVMWARE, VIM_TYPES
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';
56 * @Component takes NewVimaccountComponent.html as template url
59 selector: 'app-new-vimaccount',
60 templateUrl: './NewVimaccountComponent.html',
61 styleUrls: ['./NewVimaccountComponent.scss']
63 /** Exporting a class @exports NewVimaccountComponent */
64 export class NewVimaccountComponent implements OnInit {
65 /** To inject services @public */
66 public injector: Injector;
68 /** FormGroup vim New Account added to the form @ html @public */
69 public vimNewAccountForm: FormGroup;
71 /** Supported Vim type for the dropdown */
72 public vimType: TYPESECTION[];
74 /** Supported Vim type for the dropdown */
75 public selectedVimType: string;
77 /** Supported true and false value for the dropdown */
78 public boolValue: {}[];
80 /** Form submission Add */
81 public submitted: boolean = false;
83 /** Showing more details of collapase */
84 public isCollapsed: boolean = false;
86 /** Vim location values @public */
87 public getVIMLocation: VIMLOCATIONDATA[] = [];
89 /** Check the Projects loading results @public */
90 public isLocationLoadingResults: boolean = false;
92 /** Give the message for the loading @public */
93 public message: string = 'PLEASEWAIT';
95 /** set the longitude value of the selected place @public */
96 public setLong: number;
98 /** set the latitude value of the selected place @public */
99 public setLat: number;
101 /** Handle the formate Change @public */
102 public defaults: {} = {
106 /** To Set Mode @public */
107 public mode: string = 'text/x-yaml';
109 /** To Set Mode @public */
110 public modeDefault: string = 'yaml';
112 /** options @public */
113 public options: {} = {
114 mode: this.modeDefault,
115 showCursorWhenSelecting: true,
121 gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
122 autoCloseBrackets: true,
129 public data: string = '';
131 /** Controls the File Type List form @public */
132 public fileTypes: { value: string; viewValue: string; }[] = [];
134 /** Element ref for fileInput @public */
135 @ViewChild('fileInput', { static: true }) public fileInput: ElementRef;
137 /** Element ref for fileInput @public */
138 @ViewChild('fileInputLabel', { static: true }) public fileInputLabel: ElementRef;
140 /** Contains all methods related to shared @private */
141 public sharedService: SharedService;
143 /** Instance of the rest service @private */
144 private restService: RestService;
146 /** Holds the instance of router class @private */
147 private router: Router;
149 /** Controls the header form @private */
150 private headers: HttpHeaders;
152 /** FormBuilder instance added to the formBuilder @private */
153 private formBuilder: FormBuilder;
155 /** Notifier service to popup notification @private */
156 private notifierService: NotifierService;
158 /** Contains tranlsate instance @private */
159 private translateService: TranslateService;
161 /** VIM Details @private */
162 private vimDetail: VimAccountDetails[];
164 /** convenience getter for easy access to form fields */
165 get f(): FormGroup['controls'] { return this.vimNewAccountForm.controls; }
167 constructor(injector: Injector) {
168 this.injector = injector;
169 this.restService = this.injector.get(RestService);
170 this.formBuilder = this.injector.get(FormBuilder);
171 this.router = this.injector.get(Router);
172 this.notifierService = this.injector.get(NotifierService);
173 this.translateService = this.injector.get(TranslateService);
174 this.sharedService = this.injector.get(SharedService);
176 /** Initializing Form Action */
177 this.vimNewAccountForm = this.formBuilder.group({
178 name: [null, Validators.required],
179 vim_type: [null, Validators.required],
180 vim_tenant_name: [null, Validators.required],
182 vim_url: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_URL_PATTERN)]],
184 vim_user: [null, Validators.required],
185 vim_password: [null, Validators.required],
186 config: this.paramsBuilder()
190 /** Generate params for config @public */
191 public paramsBuilder(): FormGroup {
192 return this.formBuilder.group({
198 * Lifecyle Hooks the trigger before component is instantiate
200 public ngOnInit(): void {
201 this.fileTypes = [{ value: 'text/x-yaml', viewValue: 'yaml' }];
202 this.vimType = VIM_TYPES;
204 { id: '', name: 'None' },
205 { id: true, name: 'True' },
206 { id: false, name: 'False' }
208 this.headers = new HttpHeaders({
209 Accept: 'application/json',
210 'Content-Type': 'application/json',
211 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
213 this.getVIMDetails();
216 /** On modal submit newVimAccountSubmit will called @public */
217 public newVimAccountSubmit(): void {
218 this.submitted = true;
219 if (!this.vimNewAccountForm.invalid) {
220 this.isLocationLoadingResults = true;
221 this.sharedService.cleanForm(this.vimNewAccountForm, 'vim');
222 if (!isNullOrUndefined(this.data) && this.data !== '') {
223 Object.assign(this.vimNewAccountForm.value.config, jsyaml.load(this.data.toString(), { json: true }));
225 Object.keys(this.vimNewAccountForm.value.config).forEach((res: string) => {
226 if (res !== 'location') {
227 delete this.vimNewAccountForm.value.config[res];
232 if (isNullOrUndefined(this.vimNewAccountForm.value.config.location)) {
233 delete this.vimNewAccountForm.value.config.location;
235 Object.keys(this.vimNewAccountForm.value.config).forEach((res: string) => {
236 if (isNullOrUndefined(this.vimNewAccountForm.value.config[res]) || this.vimNewAccountForm.value.config[res] === '') {
237 delete this.vimNewAccountForm.value.config[res];
240 const apiURLHeader: APIURLHEADER = {
241 url: environment.VIMACCOUNTS_URL,
242 httpOptions: { headers: this.headers }
244 this.restService.postResource(apiURLHeader, this.vimNewAccountForm.value)
245 .subscribe((result: {}) => {
246 this.notifierService.notify('success', this.translateService.instant('PAGE.VIM.CREATEDSUCCESSFULLY'));
247 this.isLocationLoadingResults = false;
248 this.router.navigate(['vim/details']).catch(() => {
251 // Post the New Vim data and reflect in the VIM Details Page.
252 }, (error: ERRORDATA) => {
253 this.restService.handleError(error, 'post');
254 this.isLocationLoadingResults = false;
259 /** HandleChange function @public */
260 public handleChange($event: string): void {
264 /** Routing to VIM Account Details Page @public */
265 public onVimAccountBack(): void {
266 this.router.navigate(['vim/details']).catch(() => {
271 /** Fetching the location with name,latitude,longitude @public */
272 public fetchLocationLatLong(value: string): void {
273 this.isLocationLoadingResults = true;
274 const newVIMLocation: VIMLOCATIONDATA[] = [];
275 const locationTrack: string = environment.MAPLATLONGAPI_URL;
276 const locationAPIURL: string = locationTrack.replace('{value}', value);
277 this.restService.getResource(locationAPIURL).subscribe((result: VIMLOCATION) => {
278 result.features.forEach((getFeturesResult: FEATURES) => {
279 if ('extent' in getFeturesResult.properties) {
280 getFeturesResult.properties.extent.forEach((extentResult: number, index: number) => {
282 this.setLong = extentResult;
285 this.setLat = extentResult;
289 getFeturesResult.geometry.coordinates.forEach((coordinateResult: number, index: number) => {
291 this.setLong = coordinateResult;
294 this.setLat = coordinateResult;
298 newVIMLocation.push({
299 label: getFeturesResult.properties.name + ',' + getFeturesResult.properties.state + ', ' + getFeturesResult.properties.country,
300 value: getFeturesResult.properties.name + ',' + this.setLong + ',' + this.setLat
303 this.getVIMLocation = newVIMLocation;
304 this.isLocationLoadingResults = false;
305 }, (error: ERRORDATA) => {
306 this.restService.handleError(error, 'get');
307 this.isLocationLoadingResults = false;
311 /** Drag and drop feature and fetchind the details of files @private */
312 public filesDropped(files: FileList): void {
313 if (files && files.length === 1) {
314 this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
315 const getJson: string = jsyaml.load(fileContent, { json: true });
316 this.defaults['text/x-yaml'] = fileContent;
317 this.data = fileContent;
318 }).catch((err: string): void => {
319 if (err === 'typeError') {
320 this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
322 this.notifierService.notify('error', this.translateService.instant('ERROR'));
324 this.fileInputLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
325 this.fileInput.nativeElement.value = null;
327 } else if (files && files.length > 1) {
328 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
330 this.fileInputLabel.nativeElement.innerText = files[0].name;
331 this.fileInput.nativeElement.value = null;
334 /** Location chnage event in select box @public */
335 public locationChange(data: { value: string }): void {
336 this.vimDetail.forEach((vimAccountData: VimAccountDetails) => {
337 if (!isNullOrUndefined(vimAccountData.config.location) && !isNullOrUndefined(data)) {
338 if (vimAccountData.config.location === data.value) {
339 this.notifierService.notify('error', this.translateService.instant('PAGE.VIMDETAILS.LOCATIONERROR'));
340 // tslint:disable-next-line: no-backbone-get-set-outside-model
341 this.vimNewAccountForm.controls.config.get('location').setValue(null);
347 /** Load sample config based on VIM type @public */
348 public loadSampleConfig(): void {
350 if (this.selectedVimType === 'openstack') {
351 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENSTACK);
352 this.data = JSON.stringify(TYPEOPENSTACK, null, '\t');
353 } else if (this.selectedVimType === 'aws') {
354 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAWS);
355 this.data = JSON.stringify(TYPEAWS, null, '\t');
356 } else if (this.selectedVimType === 'vmware') {
357 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEVMWARE);
358 this.data = JSON.stringify(TYPEVMWARE, null, '\t');
359 } else if (this.selectedVimType === 'openvim' || this.selectedVimType === 'opennebula') {
360 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOPENVIMNEBULA);
361 this.data = JSON.stringify(TYPEOPENVIMNEBULA, null, '\t');
362 } else if (this.selectedVimType === 'azure' || this.selectedVimType === 'opennebula') {
363 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEAZURE);
364 this.data = JSON.stringify(TYPEAZURE, null, '\t');
366 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOTERS);
367 this.data = JSON.stringify(TYPEOTERS, null, '\t');
371 /** Clear config parameters @public */
372 public clearConfig(): void {
373 this.defaults['text/x-yaml'] = '';
375 this.fileInput.nativeElement.value = null;
378 /** Method to get VIM details @private */
379 private getVIMDetails(): void {
380 this.isLocationLoadingResults = true;
381 this.restService.getResource(environment.VIMACCOUNTS_URL).subscribe((vimAccountsData: VimAccountDetails[]) => {
382 this.vimDetail = vimAccountsData;
383 this.isLocationLoadingResults = false;
384 }, (error: ERRORDATA) => {
385 this.restService.handleError(error, 'get');
386 this.isLocationLoadingResults = false;