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 { 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';
44 APIURLHEADER, ERRORDATA, TYPEAWS, TYPEAZURE, TYPEOPENSTACK, TYPEOPENVIMNEBULA, TYPEOTERS,
45 TYPESECTION, TYPEVMWARE, VIM_TYPES
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';
55 * @Component takes NewVimaccountComponent.html as template url
58 selector: 'app-new-vimaccount',
59 templateUrl: './NewVimaccountComponent.html',
60 styleUrls: ['./NewVimaccountComponent.scss']
62 /** Exporting a class @exports NewVimaccountComponent */
63 export class NewVimaccountComponent implements OnInit {
64 /** To inject services @public */
65 public injector: Injector;
67 /** FormGroup vim New Account added to the form @ html @public */
68 public vimNewAccountForm: FormGroup;
70 /** Supported Vim type for the dropdown */
71 public vimType: TYPESECTION[];
73 /** Supported Vim type for the dropdown */
74 public selectedVimType: string;
76 /** Form submission Add */
77 public submitted: boolean = false;
79 /** Showing more details of collapase */
80 public isCollapsed: boolean = false;
82 /** Check the Projects loading results @public */
83 public isLocationLoadingResults: boolean = false;
85 /** Give the message for the loading @public */
86 public message: string = 'PLEASEWAIT';
88 /** Handle the formate Change @public */
89 public defaults: {} = {
93 /** To Set Mode @public */
94 public mode: string = 'text/x-yaml';
96 /** To Set Mode @public */
97 public modeDefault: string = 'yaml';
99 /** options @public */
100 public options: {} = {
101 // eslint-disable-next-line no-invalid-this
102 mode: this.modeDefault,
103 showCursorWhenSelecting: true,
109 gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
110 autoCloseBrackets: true,
117 public data: string = '';
119 /** Element ref for fileInput @public */
120 @ViewChild('fileInput', { static: true }) public fileInput: ElementRef;
122 /** Element ref for fileInput @public */
123 @ViewChild('fileInputLabel', { static: true }) public fileInputLabel: ElementRef;
125 /** Contains all methods related to shared @private */
126 public sharedService: SharedService;
128 /** Instance of the rest service @private */
129 private restService: RestService;
131 /** Holds the instance of router class @private */
132 private router: Router;
134 /** Controls the header form @private */
135 private headers: HttpHeaders;
137 /** FormBuilder instance added to the formBuilder @private */
138 private formBuilder: FormBuilder;
140 /** Notifier service to popup notification @private */
141 private notifierService: NotifierService;
143 /** Contains tranlsate instance @private */
144 private translateService: TranslateService;
146 /** VIM Details @private */
147 private vimDetail: VimAccountDetails[];
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);
159 /** convenience getter for easy access to form fields */
160 get f(): FormGroup['controls'] { return this.vimNewAccountForm.controls; }
163 * Lifecyle Hooks the trigger before component is instantiate
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'
172 this.initializeForm();
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],
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],
187 latitude: ['', Validators.pattern(this.sharedService.REGX_LAT_PATTERN)],
188 longitude: ['', Validators.pattern(this.sharedService.REGX_LONG_PATTERN)],
189 config: this.paramsBuilder()
193 /** Generate params for config @public */
194 public paramsBuilder(): FormGroup {
195 return this.formBuilder.group({
200 /** On modal submit newVimAccountSubmit will called @public */
201 public newVimAccountSubmit(): void {
202 this.submitted = true;
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 }));
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];
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;
223 if (isNullOrUndefined(this.vimNewAccountForm.value.config.location)) {
224 delete this.vimNewAccountForm.value.config.location;
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];
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 }
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 => {
254 }, (error: ERRORDATA): void => {
255 this.restService.handleError(error, 'post');
256 this.isLocationLoadingResults = false;
260 /** HandleChange function @public */
261 public handleChange($event: string): void {
265 /** Routing to VIM Account Details Page @public */
266 public onVimAccountBack(): void {
267 this.router.navigate(['vim/details']).catch((): void => {
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'));
283 this.notifierService.notify('error', this.translateService.instant('ERROR'));
285 this.fileInputLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
286 this.fileInput.nativeElement.value = null;
288 } else if (files && files.length > 1) {
289 this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
291 this.fileInputLabel.nativeElement.innerText = files[0].name;
292 this.fileInput.nativeElement.value = null;
295 /** Load sample config based on VIM type @public */
296 public loadSampleConfig(): void {
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');
314 this.defaults['text/x-yaml'] = jsyaml.dump(TYPEOTERS);
315 this.data = JSON.stringify(TYPEOTERS, null, '\t');
319 /** Clear config parameters @public */
320 public clearConfig(): void {
321 this.defaults['text/x-yaml'] = '';
323 this.fileInput.nativeElement.value = null;