From 457685063fd4b960441e482cc8b88fa8c972a7d2 Mon Sep 17 00:00:00 2001 From: Nicholas Soteropoulos Date: Mon, 14 Sep 2020 17:19:10 -0400 Subject: Fix mod ui build issues Change-Id: I4d002645240852a3a5f1964d9ffa2cac11c45b47 Signed-off-by: Nicholas Soteropoulos Issue-ID: DCAEGEN2-2317 Signed-off-by: Nicholas Soteropoulos --- .../ui/src/app/comp-specs/comp-specs.component.css | 121 ++++++++++++ .../src/app/comp-specs/comp-specs.component.html | 189 ++++++++++++++++++ .../app/comp-specs/comp-specs.component.spec.ts | 133 +++++++++++++ mod2/ui/src/app/comp-specs/comp-specs.component.ts | 211 +++++++++++++++++++++ 4 files changed, 654 insertions(+) create mode 100644 mod2/ui/src/app/comp-specs/comp-specs.component.css create mode 100644 mod2/ui/src/app/comp-specs/comp-specs.component.html create mode 100644 mod2/ui/src/app/comp-specs/comp-specs.component.spec.ts create mode 100644 mod2/ui/src/app/comp-specs/comp-specs.component.ts (limited to 'mod2/ui/src/app/comp-specs') diff --git a/mod2/ui/src/app/comp-specs/comp-specs.component.css b/mod2/ui/src/app/comp-specs/comp-specs.component.css new file mode 100644 index 0000000..5f86e73 --- /dev/null +++ b/mod2/ui/src/app/comp-specs/comp-specs.component.css @@ -0,0 +1,121 @@ +/* + * # ============LICENSE_START======================================================= + * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. + * # ================================================================================ + * # Licensed under the Apache License, Version 2.0 (the "License"); + * # you may not use this file except in compliance with the License. + * # You may obtain a copy of the License at + * # + * # http://www.apache.org/licenses/LICENSE-2.0 + * # + * # Unless required by applicable law or agreed to in writing, software + * # distributed under the License is distributed on an "AS IS" BASIS, + * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * # See the License for the specific language governing permissions and + * # limitations under the License. + * # ============LICENSE_END========================================================= + */ + +td{ + word-break:break-all +} + +textarea +{ + font-size: 12px; +} + +.table_actions_button{ + background-color: transparent; + border: none; + width: 20px; + height: 20px; + vertical-align: middle; +} + +.row-expand-layout{ + display: grid; + grid-template-columns: 30% 40% auto; + grid-gap: 10px; + grid-auto-rows: minmax(100px, auto); +} + +.row-expand-card{ + font-size: 12px; + grid-row: 1; + border-radius: 5px; + border: 1px solid slategray; + padding: 10px; + /* This height prevents vertical scroll bar in Notes */ + height: 92px; + overflow: hidden; +} + +label { + cursor: pointer; +} + +.fa-refresh{ + cursor: pointer; +} + +.input{ + padding-top: 10px; +} + +.inputLabel { + font-weight: 600; + margin-left: 20px; + width: 140px; +} + +.inputFieldSm { + width: 200px; + height: 35px; + padding-left: 6px; +} +.inputFieldMed { + width: 300px; + height: 35px; + padding-left: 6px; +} +.inputFieldLg { + width: 400px; + height: 35px; + padding-left: 6px; +} + +.table_action_item{ + outline: none; + font-size: 12px; +} + +::ng-deep .mat-menu-content { +padding-top: 0px !important; +padding-bottom: 0px !important; +} +.mat-menu-item{ +line-height:30px; +height:30px; +} + +.greenStatus{ + background-color: rgba(80, 233, 105, 0.87) +} + +.redStatus{ + background-color: rgba(255, 29, 29, 0.733) +} + +.blueStatus{ + background-color: rgba(0, 183, 255, 0.432) +} + +.greyStatus{ + background-color: rgba(150, 150, 150, 0.432) +} + +.ui-state-highlight { + background-color: #878C94 !important; + color: black !important; +} diff --git a/mod2/ui/src/app/comp-specs/comp-specs.component.html b/mod2/ui/src/app/comp-specs/comp-specs.component.html new file mode 100644 index 0000000..3061cdf --- /dev/null +++ b/mod2/ui/src/app/comp-specs/comp-specs.component.html @@ -0,0 +1,189 @@ + + +
+ + + +
+ +
+ + + + + +
+ +

Component Specs

+ +
+
+ + + + + + {{col.header}}
+ + + + Actions + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ {{csElem[col.field]}} +
+
{{csElem[col.field]}}
+ + + + +
+ + + +
+ View +
+ + +
+ +
+ +
+
+ + +
+ + + + + +
+ +
+ Created By: {{rowData.metadata.createdBy}}
+ Created On: {{rowData.metadata.createdOn}}
+ Updated By: {{rowData.metadata.updatedBy}}
+ Updated On: {{rowData.metadata.updatedOn}} +
+ +
+ Notes:
+ +
{{rowData.metadata.notes}}
+
+
+ +
+ Labels:
+
+
+ {{label}} +
+
+
+
+ + +
+
+ + +
+ + +
+
+ + + +
{{specContentToView | json}}
+ + + + +
+ + + +
{{policyJsonToView | json}}
+ + + + +
diff --git a/mod2/ui/src/app/comp-specs/comp-specs.component.spec.ts b/mod2/ui/src/app/comp-specs/comp-specs.component.spec.ts new file mode 100644 index 0000000..64405e3 --- /dev/null +++ b/mod2/ui/src/app/comp-specs/comp-specs.component.spec.ts @@ -0,0 +1,133 @@ +/* + * # ============LICENSE_START======================================================= + * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. + * # ================================================================================ + * # Licensed under the Apache License, Version 2.0 (the "License"); + * # you may not use this file except in compliance with the License. + * # You may obtain a copy of the License at + * # + * # http://www.apache.org/licenses/LICENSE-2.0 + * # + * # Unless required by applicable law or agreed to in writing, software + * # distributed under the License is distributed on an "AS IS" BASIS, + * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * # See the License for the specific language governing permissions and + * # limitations under the License. + * # ============LICENSE_END========================================================= + */ + +import { HttpClientModule } from '@angular/common/http'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatMenuModule, MatTooltipModule } from '@angular/material'; +import { RouterTestingModule } from '@angular/router/testing'; +import { JwtHelperService, JWT_OPTIONS } from '@auth0/angular-jwt'; +import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner'; +import { MessageService } from 'primeng/api'; +import { ButtonModule } from 'primeng/button'; +import { DialogModule } from 'primeng/dialog'; +import { DropdownModule } from 'primeng/dropdown'; +import { ScrollPanelModule } from 'primeng/scrollpanel'; +import { TableModule } from 'primeng/table'; +import { ToastModule } from 'primeng/toast'; + +import { CompSpecsComponent } from './comp-specs.component'; + +describe('CompSpecsComponent', () => { + let component: CompSpecsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + CompSpecsComponent + ], + imports: [ + Ng4LoadingSpinnerModule, + TableModule, + MatMenuModule, + ScrollPanelModule, + ToastModule, + DialogModule, + DropdownModule, + FormsModule, + ReactiveFormsModule, + ButtonModule, + HttpClientModule, + ToastModule, + RouterTestingModule, + MatTooltipModule + ], + providers: [ + MessageService, + { provide: JWT_OPTIONS, useValue: JWT_OPTIONS }, + JwtHelperService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CompSpecsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it(`should fill csElements Object`, () => { + const fixture = TestBed.createComponent(CompSpecsComponent); + const app = fixture.debugElement.componentInstance; + + let mockCsElement = [{ + id: 'testId1234', + name: 'test-MS', + type: 'k8s', + specContent: '', + policyJson: 'test', + status: 'New', + msInstanceInfo: { + release: '2008', + name: 'test Ms', + }, + metadata: { + createdBy: 'test', + createdOn: '01-01-2020 12:00', + updatedBy: 'test', + updatedOn: '01-01-2020 12:00', + notes: 'test', + labels: ['test'], + } + }] + + app.fillTable(mockCsElement) + + expect(app.loadTable).toEqual(true); + expect(app.csElements.length).toEqual(1); + }); + + it(`should set spec content to view`, () => { + const fixture = TestBed.createComponent(CompSpecsComponent); + const app = fixture.debugElement.componentInstance; + let mockData = { + specContent: 'test' + } + app.showViewCsDialog(mockData) + expect(app.showViewCs).toEqual(true); + expect(app.specContentToView).toEqual('test'); + }); + + it(`should set policy json content to view`, () => { + const fixture = TestBed.createComponent(CompSpecsComponent); + const app = fixture.debugElement.componentInstance; + let mockData = { + policyJson: 'test' + } + app.showViewPolicyDialog(mockData) + expect(app.showViewPolicy).toEqual(true); + expect(app.policyJsonToView).toEqual('test'); + }); +}); + diff --git a/mod2/ui/src/app/comp-specs/comp-specs.component.ts b/mod2/ui/src/app/comp-specs/comp-specs.component.ts new file mode 100644 index 0000000..4327c0b --- /dev/null +++ b/mod2/ui/src/app/comp-specs/comp-specs.component.ts @@ -0,0 +1,211 @@ +/* + * # ============LICENSE_START======================================================= + * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. + * # ================================================================================ + * # Licensed under the Apache License, Version 2.0 (the "License"); + * # you may not use this file except in compliance with the License. + * # You may obtain a copy of the License at + * # + * # http://www.apache.org/licenses/LICENSE-2.0 + * # + * # Unless required by applicable law or agreed to in writing, software + * # distributed under the License is distributed on an "AS IS" BASIS, + * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * # See the License for the specific language governing permissions and + * # limitations under the License. + * # ============LICENSE_END========================================================= + */ + +import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; +import { compSpecsService } from '../services/comp-specs-service.service'; +import { Table } from 'primeng/table'; +import { MessageService } from 'primeng/api'; +import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner'; +import { DatePipe } from '@angular/common'; +import { trigger, state, transition, style, animate } from '@angular/animations'; +import { ActivatedRoute } from '@angular/router'; +import { DownloadService } from '../services/download.service'; + +@Component({ + selector: 'app-comp-specs', + templateUrl: './comp-specs.component.html', + styleUrls: ['./comp-specs.component.css'], + animations: [ + trigger('rowExpansionTrigger', [ + state('void', style({ + transform: 'translateX(-10%)', + opacity: 0 + })), + state('active', style({ + transform: 'translateX(0)', + opacity: 1 + })), + transition('* <=> *', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)')) + ]) + ], + providers: [DatePipe] +}) +export class CompSpecsComponent implements OnInit { + @ViewChild(Table, { static: false }) dt: Table; + + csElements: any[] = []; + + cols: any[] = [ + { field: 'instanceName', header: 'Instance Name' }, + { field: 'release', header: 'Release', width: '15%' }, + { field: 'type', header: 'Type', width: '15%' }, + { field: 'policy', header: 'Policy', width: '15%' }, + { field: 'status', header: 'Status', width: '15%' } + ]; + + columns: any[]; + loadTable: boolean; + filteredRows: any; + summaryRows: any; + downloadItems: { label: string; command: () => void; }[]; + + msInstanceId: string; + msInstanceName: any; + msInstanceRelease: any; + + constructor(private csApis: compSpecsService, private messageService: MessageService, + private spinnerService: Ng4LoadingSpinnerService, private datePipe: DatePipe, + private route: ActivatedRoute, private downloadService: DownloadService) { } + + //create table of comp specs + ngOnInit() { + this.loadTable = false; + + this.route.queryParams.subscribe((params) => { + this.msInstanceId = params['instanceId']; + }); + + this.getAllCs() + } + + getAllCs() { + + this.csElements = []; + + this.csApis.getAllCompSpecs(this.msInstanceId) + .subscribe((data: any[]) => { + this.fillTable(data) + }) + + this.columns = this.cols.map(col => ({ title: col.header, dataKey: col.field })); + } + + //filter table + onTableFiltered(values) { + if (values) { this.filteredRows = values; } + else { this.filteredRows = this.summaryRows; } + } + + /* * * * Export ms instance table to excel or csv * * * */ + exportTable(exportTo) { + let downloadElements: any[] = [] + + //labels array not handled well by excel download so converted them to a single string + for (let row of this.filteredRows) { + let labels; + let notes; + if (exportTo === "excel") { + if (row.metadata.labels !== undefined) { + labels = row.metadata.labels.join(",") + } + } else { + labels = row.metadata.labels + } + + if (row.metadata.notes !== null && row.metadata.notes !== undefined && row.metadata.notes !== '') { + notes = encodeURI(row.metadata.notes).replace(/%20/g, " ").replace(/%0A/g, "\\n") + } + + downloadElements.push({ + Instance_Name: row.instanceName, + Release: row.release, + Type: row.type, + Status: row.status, + Created_By: row.metadata.createdBy, + Created_On: row.metadata.createdOn, + Updated_By: row.metadata.updatedBy, + Updated_On: row.metadata.updatedOn, + Notes: notes, + Labels: labels + }) + } + + let arrHeader = [] + + if (exportTo === "csv") { + arrHeader = [ + "Instance_Name", + "Release", + "Type", + "Status", + "Created_By", + "Created_On", + "Updated_By", + "Updated_On", + "Notes", + "Labels" + ]; + } + + this.downloadService.exportTableData(exportTo, downloadElements, arrHeader) + } + + //fill object with microservice data, to be used to fill table. + //checks if fields are empty and if they are, store 'N/A' as the values + fillTable(data) { + for (let elem of data) { + let policy = ''; + if(elem.policyJson){policy = "Included"} + + let tempCsElement: any = { + id: elem.id, + instanceName: elem.msInstanceInfo.name, + release: elem.msInstanceInfo.release, + type: elem.type, + policy: policy, + status: elem.status, + specContent: elem.specContent, + policyJson: elem.policyJson, + metadata: { + createdBy: elem.metadata.createdBy, + createdOn: this.datePipe.transform(elem.metadata.createdOn, 'MM-dd-yyyy HH:mm'), + updatedBy: elem.metadata.updatedBy, + updatedOn: this.datePipe.transform(elem.metadata.updatedOn, 'MM-dd-yyyy HH:mm'), + notes: elem.metadata.notes, + labels: elem.metadata.labels + } + } + this.csElements.unshift(tempCsElement) + } + this.msInstanceName = this.csElements[0]['instanceName'] + this.msInstanceRelease = this.csElements[0]['release'] + this.filteredRows = this.csElements + this.loadTable = true; + this.spinnerService.hide(); + } + + showViewCs: boolean = false; + specContentToView: string; + showViewCsDialog(data) { + this.showViewCs = true; + this.specContentToView = data.specContent; + } + + showViewPolicy: boolean = false; + policyJsonToView: string; + showViewPolicyDialog(data) { + this.showViewPolicy = true; + this.policyJsonToView = data.policyJson; + } + + /* * * * Download single spec file or policy * * * */ + download(content, contentType) { + let fileName = `${this.msInstanceName}_${this.msInstanceRelease}_${contentType}` + this.downloadService.downloadJSON(content, fileName) + } +} \ No newline at end of file -- cgit 1.2.3-korg