summaryrefslogtreecommitdiffstats
path: root/mod2/ui/src/app/comp-spec-add
diff options
context:
space:
mode:
Diffstat (limited to 'mod2/ui/src/app/comp-spec-add')
-rw-r--r--mod2/ui/src/app/comp-spec-add/comp-spec-add.component.css43
-rw-r--r--mod2/ui/src/app/comp-spec-add/comp-spec-add.component.html64
-rw-r--r--mod2/ui/src/app/comp-spec-add/comp-spec-add.component.spec.ts77
-rw-r--r--mod2/ui/src/app/comp-spec-add/comp-spec-add.component.ts180
4 files changed, 364 insertions, 0 deletions
diff --git a/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.css b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.css
new file mode 100644
index 0000000..54806ab
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.css
@@ -0,0 +1,43 @@
+/*
+ * # ============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=========================================================
+ */
+
+.input {
+ padding-top: 10px;
+}
+
+.inputLabel {
+ font-weight: 600;
+ margin-left: 20px;
+ width: 135px;
+}
+
+.inputFieldSm {
+ width: 200px;
+ height: 35px;
+ padding-left: 6px;
+}
+.inputFieldMed {
+ width: 300px;
+ height: 35px;
+ padding-left: 6px;
+}
+.inputFieldLg {
+ width: 400px;
+ height: 35px;
+ padding-left: 6px;
+}
diff --git a/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.html b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.html
new file mode 100644
index 0000000..f15f19b
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.html
@@ -0,0 +1,64 @@
+<!--
+ # ============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=========================================================
+ -->
+
+<p-dialog *ngIf="visible" header="Component Spec ADD" [(visible)]="visible" appendTo="body" [modal]="true" [transitionOptions]="'300ms'"
+ [closeOnEscape]="false" [closable]="false" [style]="{width: '650px'}" (onHide)="closeDialog()">
+
+ <!-- * * * * * Input fields * * * * * -->
+ <form [formGroup]="csAddForm" (ngSubmit)="saveCs()" class="bg-faded">
+ <!-- * * * Type * * * -->
+ <div class="input">
+ <label class="inputLabel">Type<span style="color:red">*</span></label>
+ <p-dropdown [options]="types" placeholder="Select Type" optionLabel="type" formControlName="type"></p-dropdown>
+ </div>
+ <!-- * * * Labels * * * -->
+ <div class="input">
+ <label class="inputLabel">Labels</label>
+ <input class="inputFieldLg" type="text" pInputText formControlName="labels" />
+ </div>
+ <span style="padding: 9px 0px 0px 158px; font-size: 13px;">(Separate labels with a space)</span>
+ <!-- * * * Notes * * * -->
+ <div class="input">
+ <label class="inputLabel" style="vertical-align: top">Notes</label>
+ <textarea class="inputFieldLg" [rows]="1" [cols]="30" pInputTextarea autoResize="autoResize" formControlName="notes"></textarea>
+ </div>
+ <!-- * * * Comp Spec File Select * * * -->
+ <div class="input">
+ <label class="inputLabel">Component Spec<span style="color:red">*</span></label>
+
+ <input type="file" style="width: 460px; color:blue; font-style: italic;" (input)="onCompSpecUpload($event)" name="myfile" id="myfile" accept=".json">
+ </div>
+
+ <!-- * * * Policy File Select * * * -->
+ <div class="input">
+ <label class="inputLabel">Policy</label>
+
+ <input type="file" style="width: 460px; color:blue; font-style: italic;" (input)="onPolicyUpload($event)"
+ name="myPolicyFile" id="myPolicyFile" accept=".json">
+ </div>
+
+ <!-- * * * ADD and Cancel buttons * * * -->
+ <div style="float: right; padding: 20px 45px">
+ <button pButton type="button" (click)="closeDialog()" label="Cancel"></button>&nbsp;
+ <button pButton type="submit" class="ui-button-success" label="Add" [disabled]="!csAddForm.valid || !compSpecSelected" style="width: 70px"></button>
+ </div>
+ </form>
+
+ <p-toast key="jsonError" [style]="{width: '430px'}"></p-toast>
+
+</p-dialog>
diff --git a/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.spec.ts b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.spec.ts
new file mode 100644
index 0000000..e29a110
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.spec.ts
@@ -0,0 +1,77 @@
+/*
+ * # ============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 { HttpClientTestingModule } from '@angular/common/http/testing';
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterTestingModule } from '@angular/router/testing';
+import { JwtHelperService, JWT_OPTIONS } from '@auth0/angular-jwt';
+import { MessageService } from 'primeng/api';
+import { ButtonModule } from 'primeng/button';
+import { DialogModule } from 'primeng/dialog';
+import { DropdownModule } from 'primeng/dropdown';
+import { ToastModule } from 'primeng/toast';
+
+
+import { CompSpecAddComponent } from './comp-spec-add.component';
+
+describe('CompSpecAddComponent', () => {
+ let component: CompSpecAddComponent;
+ let fixture: ComponentFixture<CompSpecAddComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [CompSpecAddComponent],
+ imports: [
+ DialogModule,
+ DropdownModule,
+ ToastModule,
+ FormsModule,
+ ReactiveFormsModule,
+ ButtonModule,
+ HttpClientTestingModule,
+ RouterTestingModule
+ ],
+ providers: [
+ MessageService,
+ { provide: JWT_OPTIONS, useValue: JWT_OPTIONS },
+ JwtHelperService
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CompSpecAddComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it(`should invalidate spec JSON structure`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecAddComponent);
+ const app = fixture.debugElement.componentInstance;
+ let mockErrorJson = "test: 'test}"
+ app.compSpecContent = mockErrorJson
+ expect(() => app.validateJsonStructure()).toThrowError('JSON Structure error, quit!')
+ }));
+
+});
diff --git a/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.ts b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.ts
new file mode 100644
index 0000000..7564852
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-add/comp-spec-add.component.ts
@@ -0,0 +1,180 @@
+/*
+ * # ============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, Input, Output, EventEmitter } from '@angular/core';
+import { InputTextModule } from 'primeng/inputtext';
+import { DropdownModule } from 'primeng/dropdown';
+import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
+import { AuthService } from '../services/auth.service';
+import { MessageService } from 'primeng/api';
+
+interface Type {
+ type: string;
+}
+
+@Component({
+ selector: 'app-comp-spec-add',
+ templateUrl: './comp-spec-add.component.html',
+ styleUrls: ['./comp-spec-add.component.css']
+})
+
+export class CompSpecAddComponent implements OnInit {
+
+ compSpecSelected: any;
+ compSpecContent: any;
+
+ policySelected: any;
+ policyContent: any;
+
+ csAddForm: FormGroup;
+ // The loggged in user
+ username: string;
+
+ // Input form fields
+ type: string;
+ labels: string;
+ notes: string;
+ specFile: any;
+ policyJson: any;
+
+ // Dropdowns
+ types: Type[];
+
+ // Build JSON as a string
+ csAddString: any;
+ // Return JSON to parent component
+ csAddJson: any;
+
+ constructor(private fb: FormBuilder, private authService: AuthService, private messageService: MessageService) {
+ }
+
+ @Input() visible: boolean;
+ @Output() handler: EventEmitter<any> = new EventEmitter();
+
+ ngOnInit() {
+ // The logged in user
+ this.username = this.authService.getUser().username;
+
+ this.csAddForm = new FormGroup({
+ type: new FormControl(),
+ labels: new FormControl(),
+ notes: new FormControl(),
+ specFile: new FormControl(),
+ policyJson: new FormControl()
+ });
+
+ // FORM fields and validations
+ this.csAddForm = this.fb.group({
+ type: ['', [Validators.required]],
+ labels: ['', []],
+ notes: ['', []],
+ specFile: ['', []],
+ policyJson: ['', []]
+ });
+
+ // TYPE Dropdown
+ this.types = [
+ { type: 'DOCKER' },
+ { type: 'K8S' }
+ ];
+ }
+
+ saveCs() {
+ this.createOutputJson();
+ this.csAddJson = JSON.stringify(this.csAddString);
+ this.handler.emit(this.csAddJson);
+ this.closeDialog();
+ }
+
+ // Create the JSON to be sent to the parent component
+ // The "labels" functions below take into account leading/trailing spaces, multiple spaces between labels, and conversion into an array
+ createOutputJson() {
+ this.validateJsonStructure();
+
+ let policy;
+ if(this.policyContent !== undefined){
+ policy = JSON.parse(this.policyContent)
+ } else {
+ policy = null
+ }
+
+ this.csAddString = {
+ specContent: JSON.parse(this.compSpecContent),
+ policyJson: policy,
+ type: this.csAddForm.value['type'].type,
+ metadata: {
+ labels: this.csAddForm.value['labels'].trim().replace(/\s{2,}/g, ' ').split(" "),
+ notes: this.csAddForm.value['notes']
+ },
+ user: this.username
+ };
+ }
+
+ // Validate, catch, display JSON structure error, and quit!
+ validateJsonStructure() {
+ try {
+ JSON.parse(this.compSpecContent);
+ } catch (error) {
+ this.messageService.add({ key: 'jsonError', severity: 'error', summary: 'Invalid Component Spec JSON', detail: error, sticky: true });
+ throw new Error('JSON Structure error, quit!');
+ }
+
+ if(this.policyContent !== undefined){
+ try {
+ JSON.parse(this.policyContent);
+ } catch (error) {
+ this.messageService.add({ key: 'jsonError', severity: 'error', summary: 'Invalid Policy JSON', detail: error, sticky: true });
+ throw new Error('JSON Structure error, quit!');
+ }
+ }
+ }
+
+ // Read the selected Component Spec JSON file
+ onCompSpecUpload(event) {
+ this.compSpecSelected = event.target.files[0];
+ this.readCsFileContent(this.compSpecSelected);
+ }
+ //Read the selected Component Spec JSON file
+ onPolicyUpload(event) {
+ this.policySelected = event.target.files[0];
+ this.readPolicyFileContent(this.policySelected);
+ }
+
+ readCsFileContent(file) {
+ if (file) {
+ let fileReader = new FileReader();
+ fileReader.onload = (e) => { this.compSpecContent = fileReader.result; };
+ fileReader.readAsText(file);
+ }
+ }
+
+ readPolicyFileContent(file) {
+ if (file) {
+ let fileReader = new FileReader();
+ fileReader.onload = (e) => { this.policyContent = fileReader.result; };
+ fileReader.readAsText(file);
+ }
+ }
+
+ // The handler emits 'null' back to parent to close dialog and make it available again when clicked
+ closeDialog() {
+ this.visible = false;
+ this.handler.emit(null);
+ }
+
+}