Fix mod ui build issues
[dcaegen2/platform.git] / mod2 / ui / src / app / microservices / microservices.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, ViewChild, ElementRef, Input, EventEmitter, Output } from '@angular/core';
20 import { MatTableDataSource } from '@angular/material/table';
21 import { Table } from 'primeng/table';
22 import { MessageService } from 'primeng/api';
23 import { trigger, state, style, transition, animate } from '@angular/animations';
24 import { BaseMicroserviceService } from '../services/base-microservice.service';
25 import { MsAddService } from '../services/ms-add.service';
26 import { MicroserviceInstanceService } from '../services/microservice-instance.service';
27 import { AuthService } from '../services/auth.service';
28 import { DatePipe } from '@angular/common';
29 import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';
30 import { DownloadService } from '../services/download.service';
31
32 @Component({
33   selector: 'app-microservices',
34   templateUrl: './microservices.component.html',
35   styleUrls: ['./microservices.component.css'],
36   animations: [
37     trigger('rowExpansionTrigger', [
38       state('void', style({
39         transform: 'translateX(-10%)',
40         opacity: 0
41       })),
42       state('active', style({
43         transform: 'translateX(0)',
44         opacity: 1
45       })),
46       transition('* <=> *', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
47     ])
48   ],
49   providers: [DatePipe]
50 })
51 export class MicroservicesComponent implements OnInit {
52     @ViewChild(Table, { static: false }) dt: Table;
53
54     /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
55     msElements: any[] = [];
56     dataSource = new MatTableDataSource<any>(this.msElements);
57     cols: any[] = [
58         { field: 'name', header: 'MS Name' },
59         { field: 'tag', header: 'MS Tag' },
60         { field: 'serviceName', header: 'Service Short Name'},
61         { field: 'type', header: 'Type', width: '11%' },
62         { field: 'namespace', header: 'Namespace', width: '15%' },
63         { field: 'status', header: 'Status', width: '90px' }
64     ];
65     columns: any[];
66     loadTable: boolean;
67     filteredRows: any;
68     downloadItems: { label: string; command: () => void; }[];
69     showAddChangeMsInstance: boolean;
70     addInstanceTo: string = "";
71     msInstanceStates: { label: string, value: string }[] = [
72         { label: 'New',           value: 'new' },
73         { label: 'In Dev',        value: 'in-dev' },
74         { label: 'Dev Complete',  value: 'dev-complete' },
75         { label: 'In Test',       value: 'in-test' },
76         { label: 'Certified',     value: 'certified' },
77         { label: 'Prod Deployed', value: 'prod-deployed' }
78     ]
79
80     // Json to add MS to DB, returned from child
81     msAddChangeJson: any;
82
83     showMsAddChangeDialog: boolean = false;
84     currentRow: any;
85     currentMsRow: string = "";
86     addOrChange: string;
87     username: string;
88     errorMessage: any;
89     successMessage: string;
90
91     constructor(private spinnerService: Ng4LoadingSpinnerService, private baseMsService: BaseMicroserviceService,
92                 private msInstanceApi: MicroserviceInstanceService, private messageService: MessageService,
93                 private addChangeMsApi: MsAddService, private authService: AuthService, private datePipe: DatePipe,
94                 private downloadService: DownloadService) { }
95
96     ngOnInit() {
97         this.username = this.authService.getUser().username;
98         this.getAllMs();
99     }
100
101     getAllMs() {
102         this.spinnerService.show();
103         this.msElements = [];
104         this.loadTable = false;
105         
106         this.baseMsService.getAllBaseMs()
107         .subscribe((data: any[]) => {
108             this.fillTable(data)
109         })
110
111         this.columns = this.cols.map(col => ({ title: col.header, dataKey: col.field }));
112     }
113
114     /*checks when table is filtered and stores filtered data in new 
115     object to be downloaded when download button is clicked*/
116     onTableFiltered(values) {
117         if (values !== null) {
118             this.filteredRows = values;
119         } else {
120             this.filteredRows = this.msElements;
121         }
122     }
123
124     //download table as excel file
125     exportTable(exportTo: string) {
126         let downloadElements: any[] = []
127
128         //labels array not handled well by excel download so converted them to a single string
129         for (let row of this.filteredRows) {
130             let labels;
131             let notes;
132             if (exportTo === "excel") {
133                 if (row.metadata.labels !== undefined) {
134                     labels = row.metadata.labels.join(",")
135                 }
136             } else {
137                 labels = row.metadata.labels
138             }
139
140             if (row.metadata.notes !== null && row.metadata.notes !== undefined && row.metadata.notes !== '') {
141                 notes = encodeURI(row.metadata.notes).replace(/%20/g, " ").replace(/%0A/g, "\\n")
142             }
143
144             downloadElements.push({
145                 MS_Name: row.name,
146                 MS_Tag: row.tag,
147                 Service_Short_Name: row.serviceName,
148                 Type: row.type,
149                 Location: row.location,
150                 Namespace: row.namespace,
151                 Status: row.status,
152                 Created_By: row.metadata.createdBy,
153                 Created_On: row.metadata.createdOn,
154                 Updated_By: row.metadata.updatedBy,
155                 Updated_On: row.metadata.updatedOn,
156                 Notes: notes,
157                 Labels: labels
158             })
159         }
160         
161         let csvHeaders = []
162
163         if (exportTo === "csv") {
164             csvHeaders = [
165                 "MS_Name", 
166                 "MS_Tag", 
167                 "Service_Short_Name", 
168                 "Type", 
169                 "Location", 
170                 "Namespace", 
171                 "Status", 
172                 "Created_By", 
173                 "Created_On", 
174                 "Updated_By", 
175                 "Updated_On", 
176                 "Notes", 
177                 "Labels" 
178             ];
179         }
180
181         this.downloadService.exportTableData(exportTo, downloadElements, csvHeaders)
182     }
183
184     // * * * * * Show the Dialog to Add a MS (<app-ms-add-change> tag in the html) * * * * *
185     showAddChangeDialog(rowData) {
186         this.showMsAddChangeDialog = true;
187         this.currentRow = rowData;
188         if (this.currentRow) {
189             this.addOrChange = "Change";
190         } else {
191             this.addOrChange = "Add";
192         }
193     }
194
195     // * * * * * Add or Change a MS * * * * *
196     // The response includes the entire MS record that was Added or Changed, (along with ID and audit fields).
197     // When Added, the response is added directly to the table.  When Changed, the current record is updated field-by-field.
198     addOrChangeMs(jsonFromChildDialog) {
199         if (jsonFromChildDialog) {
200             this.msAddChangeJson = jsonFromChildDialog;
201             if (this.addOrChange == "Change") {
202                 this.currentMsRow = this.currentRow['id']
203             }
204             this.addChangeMsApi.addChangeMsToCatalog(this.addOrChange, this.currentMsRow, this.msAddChangeJson).subscribe(
205                 (response: any) => {
206                     if (this.addOrChange == "Add") {
207                         this.msElements.unshift(response);
208                         this.successMessage = "Microservice Added";
209                     } else {
210                         this.updateCurrentRow(jsonFromChildDialog);
211                         this.successMessage = "Microservice Updated";
212                     }
213                     this.showMsAddChangeDialog = false;
214                     this.messageService.add({ key: 'addChangeSuccess', severity: 'success', summary: 'Success', detail: this.successMessage, life: 5000 });
215                     },
216                 errResponse => {
217                     // for testing only - this.updateCurrentRow(jsonFromChildDialog);
218                     this.messageService.add({ key: 'msAddChangeError', severity: 'error', summary: 'Error', detail: errResponse.error.message, sticky: true });
219                 }
220             )
221         }
222         else {
223             this.showMsAddChangeDialog = false;
224         };
225     }
226
227     updateCurrentRow(jsonFromChildDialog) {
228         const newRow = JSON.parse(jsonFromChildDialog);
229         this.currentRow['name']               = newRow['name'];
230         this.currentRow['serviceName']        = newRow['serviceName'];
231         this.currentRow['type']               = newRow['type'];
232         this.currentRow['location']           = newRow['location'];
233         this.currentRow['namespace']          = newRow['namespace'];
234         this.currentRow['metadata']['labels'] = newRow['metadata']['labels'];
235         this.currentRow['metadata']['notes']  = newRow['metadata']['notes'];
236     }
237
238     /* * * * Show pop up for Adding a new MS Instance * * * */
239     showAddChangeMsInstanceDialog(data) {
240         this.addInstanceTo = data['name']
241         this.showAddChangeMsInstance = true
242     }
243
244     /* * * * Call API to Add a new MS Instance * * * */
245     addMsInstance(body) {
246         if (body === null) {
247             this.showAddChangeMsInstance = false;
248         } else {
249             this.msInstanceApi.addChangeMsInstance("ADD", this.addInstanceTo, body).subscribe(
250                 (data) => {
251                     this.messageService.add({ key: 'addChangeSuccess', severity: 'success', summary: 'Success', detail: "MS Instance Added", life: 5000 });
252                     this.showAddChangeMsInstance = false;
253                 },
254                 (errResponse) => {
255                     console.log(errResponse)
256                     this.messageService.add({ key: 'instanceAddChangeError', severity: 'error', summary: 'Error', detail: errResponse.error.message, sticky: true });
257                 }
258             )
259         }
260     }
261
262     //fill object with microservice data, to be used to fill table. 
263     //checks if fields are empty and if they are, store 'N/A' as the values
264     fillTable(data) {
265         for (let elem of data) {
266             var tempMsElement: any = {
267                 id:          elem.id,
268                 name:        elem.name,
269                 tag:         elem.tag,
270                 serviceName: elem.serviceName,
271                 type:        elem.type,
272                 location:    elem.location,
273                 namespace:   elem.namespace,
274                 status:      elem.status,
275                 metadata: {
276                     createdBy: elem.metadata.createdBy,
277                     createdOn: this.datePipe.transform(elem.metadata.createdOn, 'MM-dd-yyyy HH:mm'),
278                     updatedBy: elem.metadata.updatedBy,
279                     updatedOn: this.datePipe.transform(elem.metadata.updatedOn, 'MM-dd-yyyy HH:mm'),
280                     notes:     elem.metadata.notes,
281                     labels:    elem.metadata.labels
282                 },
283                 msInstances: elem.msInstances
284             }
285             this.msElements.push(tempMsElement)
286         }
287         this.filteredRows = this.msElements
288         this.loadTable = true;
289         this.spinnerService.hide();
290     }
291 }
292
293 export interface AddMsInstance{
294   name: string,
295   release: string, 
296   metadata: {
297     scrumLead: string,
298     scrumLeadId: string,
299     systemsEngineer: string,
300     systemsEngineerId: string,
301     developer: string;
302     developerId: string;
303     pstDueDate: string,
304     pstDueIteration: string,
305     eteDueDate: string,
306     eteDueIteration: string,
307     labels: string[],
308     notes: string
309   }
310   user: string
311 }