Merge "Refactor, fix code formatting and add unittests"
[dcaegen2/platform.git] / mod2 / ui / src / app / comp-spec-add / comp-spec-add.component.ts
1 /* 
2  *  # ============LICENSE_START=======================================================
3  *  # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
4  *  # ================================================================================
5  *  # Licensed under the Apache License, Version 2.0 (the "License");
6  *  # you may not use this file except in compliance with the License.
7  *  # You may obtain a copy of the License at
8  *  #
9  *  #      http://www.apache.org/licenses/LICENSE-2.0
10  *  #
11  *  # Unless required by applicable law or agreed to in writing, software
12  *  # distributed under the License is distributed on an "AS IS" BASIS,
13  *  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  # See the License for the specific language governing permissions and
15  *  # limitations under the License.
16  *  # ============LICENSE_END=========================================================
17  */
18
19 import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
20 import { InputTextModule } from 'primeng/inputtext';
21 import { DropdownModule } from 'primeng/dropdown';
22 import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
23 import { AuthService } from '../services/auth.service';
24 import { MessageService } from 'primeng/api';
25
26 interface Type {
27     type: string;
28 }
29
30 @Component({
31     selector: 'app-comp-spec-add',
32     templateUrl: './comp-spec-add.component.html',
33     styleUrls: ['./comp-spec-add.component.css']
34 })
35
36 export class CompSpecAddComponent implements OnInit {
37
38     compSpecSelected: any;
39     compSpecContent: any;
40
41     policySelected: any;
42     policyContent: any;
43
44     csAddForm: FormGroup;
45     //  The loggged in user
46     username: string;
47
48     //  Input form fields
49     type: string;
50     labels: string;
51     notes: string;
52     specFile: any;
53     policyJson: any;
54
55     //  Dropdowns
56     types: Type[];
57     
58     //  Build JSON as a string
59     csAddString: any;
60     //  Return JSON to parent component
61     csAddJson: any;
62     
63     constructor(private fb: FormBuilder, private authService: AuthService, private messageService: MessageService) {
64     }
65
66     @Input() visible: boolean;
67     @Output() handler: EventEmitter<any> = new EventEmitter();
68
69     ngOnInit() {
70         //  The logged in user
71         this.username = this.authService.getUser().username;
72
73         this.csAddForm = new FormGroup({
74             type: new FormControl(),
75             labels: new FormControl(),
76             notes: new FormControl(),
77             specFile: new FormControl(),
78             policyJson: new FormControl()
79         });
80     
81         //  FORM fields and validations
82         this.csAddForm = this.fb.group({
83             type: ['', [Validators.required]],
84             labels: ['', []],
85             notes: ['', []],
86             specFile: ['', []],
87             policyJson: ['', []]
88         });
89     
90         // TYPE Dropdown
91         this.types = [
92             { type: 'DOCKER' },
93             { type: 'K8S' }
94         ];
95     }
96
97     saveCs() {
98         this.createOutputJson();
99         this.csAddJson = JSON.stringify(this.csAddString);
100         this.handler.emit(this.csAddJson);
101         this.closeDialog();
102     }
103
104     //  Create the JSON to be sent to the parent component
105     //  The "labels" functions below take into account leading/trailing spaces, multiple spaces between labels, and conversion into an array
106     createOutputJson() {
107         this.validateJsonStructure();
108
109         let policy;
110         if(this.policyContent !== undefined){
111             policy = JSON.parse(this.policyContent)
112         } else {
113             policy = null
114         }
115
116         this.csAddString = {
117             specContent: JSON.parse(this.compSpecContent),
118             policyJson: policy,
119             type: this.csAddForm.value['type'].type,
120             metadata: {
121                 labels: this.csAddForm.value['labels'].trim().replace(/\s{2,}/g, ' ').split(" "),
122                 notes: this.csAddForm.value['notes']
123             },
124             user: this.username
125         };
126     }
127
128     //  Validate, catch, display JSON structure error, and quit!
129     validateJsonStructure() {
130         try {
131             JSON.parse(this.compSpecContent);
132         } catch (error) {
133             this.messageService.add({ key: 'jsonError', severity: 'error', summary: 'Invalid Component Spec JSON', detail: error, sticky: true });
134             throw new Error('JSON Structure error, quit!');
135         }
136         
137         if(this.policyContent !== undefined){
138             try {
139                 JSON.parse(this.policyContent);
140             } catch (error) {
141                 this.messageService.add({ key: 'jsonError', severity: 'error', summary: 'Invalid Policy JSON', detail: error, sticky: true });
142                 throw new Error('JSON Structure error, quit!');
143             }
144         }
145     }
146
147     //  Read the selected Component Spec JSON file
148     onCompSpecUpload(event) {
149         this.compSpecSelected = event.target.files[0];
150         this.readCsFileContent(this.compSpecSelected);
151     }
152     //Read the selected Component Spec JSON file
153     onPolicyUpload(event) {
154         this.policySelected = event.target.files[0];
155         this.readPolicyFileContent(this.policySelected);
156     }
157
158     readCsFileContent(file) {
159         if (file) {
160             let fileReader = new FileReader();
161             fileReader.onload = (e) => { this.compSpecContent = fileReader.result; };
162             fileReader.readAsText(file);
163         }
164     }
165
166     readPolicyFileContent(file) {
167         if (file) {
168             let fileReader = new FileReader();
169             fileReader.onload = (e) => { this.policyContent = fileReader.result; };
170             fileReader.readAsText(file);
171         }
172     }
173
174     //  The handler emits 'null' back to parent to close dialog and make it available again when clicked
175     closeDialog() {
176         this.visible = false;
177         this.handler.emit(null);
178     }
179
180 }