diff options
Diffstat (limited to 'mod2/ui/src/app/ms-add-change')
4 files changed, 413 insertions, 0 deletions
diff --git a/mod2/ui/src/app/ms-add-change/ms-add-change.component.css b/mod2/ui/src/app/ms-add-change/ms-add-change.component.css new file mode 100644 index 0000000..f256b2f --- /dev/null +++ b/mod2/ui/src/app/ms-add-change/ms-add-change.component.css @@ -0,0 +1,57 @@ +/* + * # ============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: 150px; +} + +.inputFieldSm { + width: 200px; + height: 35px; + padding-left: 6px; +} +.inputFieldMed { + width: 300px; + height: 35px; + padding-left: 6px; +} +.inputFieldLg { + width: 400px; + height: 35px; + padding-left: 6px; +} + +.validationMsg { + padding-left: 175px; + color: red; + font-size: 11px; + font-weight: 550; +} + +.validationMsgWarning { + padding-left: 175px; + color: rgb(255, 81, 0); + font-size: 11px; + font-weight: 550; +}
\ No newline at end of file diff --git a/mod2/ui/src/app/ms-add-change/ms-add-change.component.html b/mod2/ui/src/app/ms-add-change/ms-add-change.component.html new file mode 100644 index 0000000..2fd19d7 --- /dev/null +++ b/mod2/ui/src/app/ms-add-change/ms-add-change.component.html @@ -0,0 +1,109 @@ +<!-- + # ============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]="guiHeader" [(visible)]="visible" appendTo="body" [modal]="true" [transitionOptions]="'300ms'" + [closeOnEscape]="false" [closable]="false" [style]="{width: '645px'}" (onHide)="closeDialog()"> + + <!-- "Add / Change MS" Error Message --> + <p-toast key="msAddChangeError" [style]="{width: '500px'}"></p-toast> + + <!-- * * * * * Input fields * * * * * --> + <form [formGroup]="msAddForm" (ngSubmit)="saveMs()" class="bg-faded"> + <!-- * * * MS Name * * * --> + <div class="input"> + <label class="inputLabel">MS Name<span style="color:red">*</span></label> + <input class="inputFieldMed" type="text" pInputText formControlName="name"> + </div> + <!-- * * * MS Tag * * * --> + <div class="input"> + <label class="inputLabel">MS Tag<span style="color:red">*</span></label> + <input *ngIf="!currentRow" class="inputFieldMed" type="text" pInputText formControlName="tag"> + <!-- If Updating (vs ADDing) the data, the "Tag" is Read-Only --> + <input *ngIf="currentRow" class="inputFieldMed" type="text" pInputText formControlName="tag" style="border:none" readonly> + <!-- * * * (Validation Rules Display) * * * --> + <div class="validationMsg" *ngIf="msAddForm.controls['tag'].invalid && + !msAddForm.value['tag']=='' && + msAddForm.controls['tag'].value.length < 51"> + Format: lowercase alphanumeric with embedded dashes (5-50 characters) + </div> + <!-- * * * (Validation Rule - length > 50) * * * --> + <div class="validationMsg" *ngIf="msAddForm.controls['tag'].value.length > 50"> + MS Tag cannot exceed 50 chars + </div> + </div> + <!-- * * * Service Short Name * * * --> + <div class="input"> + <label class="inputLabel">Service Short Name</label> + <input class="inputFieldMed" type="text" pInputText formControlName="serviceName"> + <!-- * * * (Validation Rules Display) * * * --> + <div class="validationMsg" *ngIf="msAddForm.controls['serviceName'].invalid && + !msAddForm.value['serviceName']=='' && + msAddForm.controls['serviceName'].value.length < 26"> + Format: lowercase alpha with embedded dashes + </div> + <!-- * * * (Warning! Global vs Central/Edge Service Name length) * * * --> + <div class="validationMsgWarning" *ngIf="msAddForm.controls['serviceName'].valid && + msAddForm.controls['serviceName'].value.length > 12 && + msAddForm.controls['serviceName'].value.length < 26"> + Warning! Only Global Site short names can exceed 12 chars (max 25) + </div> + <!-- * * * (Validation Rule - length > 25) * * * --> + <div class="validationMsg" *ngIf="msAddForm.controls['serviceName'].value.length > 25"> + Global Site short names cannot exceed 25 chars + </div> + </div> + <!-- * * * 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> + <!-- * * * Location + <div class="input"> + <label class="inputLabel">Location<span style="color:red">*</span></label> + <p-dropdown [options]="locations" placeholder="Select Location" optionLabel="location" formControlName="location"></p-dropdown> + </div> + * * * --> + <!-- * * * Namespace * * * --> + <div class="input"> + <label class="inputLabel">Namespace</label> + <input class="inputFieldMed" type="text" pInputText formControlName="namespace"> + <!-- * * * (Validation Rules Display) * * * --> + <div class="validationMsg" *ngIf="msAddForm.controls['namespace'].invalid && !msAddForm.value['namespace']==''"> + Format: lowercase alphanumeric with embedded dashes + </div> + </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 172px; 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> + <!-- * * * ADD and CANCEL buttons * * * --> + <div style="float: right; padding: 20px 45px"> + <button pButton type="button" (click)="closeDialog()" style="margin-right: 10px" label="Cancel"></button> + <button pButton type="submit" class="ui-button-success" style="width: 77px; text-align:center" [label]="addOrUpdate" + [disabled]="!msAddForm.valid || !msAddForm.value['name'].trim()"></button> + </div> + </form> + +</p-dialog> diff --git a/mod2/ui/src/app/ms-add-change/ms-add-change.component.spec.ts b/mod2/ui/src/app/ms-add-change/ms-add-change.component.spec.ts new file mode 100644 index 0000000..4ba7ae9 --- /dev/null +++ b/mod2/ui/src/app/ms-add-change/ms-add-change.component.spec.ts @@ -0,0 +1,67 @@ +/* + * # ============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 { 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 { MsAddChangeComponent } from './ms-add-change.component'; + +describe('MsAddChangeComponent', () => { + let component: MsAddChangeComponent; + let fixture: ComponentFixture<MsAddChangeComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [MsAddChangeComponent], + imports: [ + DialogModule, + DropdownModule, + ToastModule, + FormsModule, + ReactiveFormsModule, + ButtonModule, + HttpClientTestingModule, + RouterTestingModule + ], + providers: [ + MessageService, + { provide: JWT_OPTIONS, useValue: JWT_OPTIONS }, + JwtHelperService + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MsAddChangeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mod2/ui/src/app/ms-add-change/ms-add-change.component.ts b/mod2/ui/src/app/ms-add-change/ms-add-change.component.ts new file mode 100644 index 0000000..6991104 --- /dev/null +++ b/mod2/ui/src/app/ms-add-change/ms-add-change.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'; + +interface Type { + type: string; +} +interface Location { + location: string; +} + +@Component({ + selector: 'app-ms-add-change', + templateUrl: './ms-add-change.component.html', + styleUrls: ['./ms-add-change.component.css'] +}) + +export class MsAddChangeComponent implements OnInit { + + guiHeader: string = "Microservice ADD" + // Used for the Add/Update button label + addOrUpdate: string = "Add"; + + msAddForm: FormGroup; + // The loggged in user + username: string; + + // Input form fields + name: string; + tag: string; + serviceName: string = ""; + type: string; + location: string; + namespace: string; + labels: string; + notes: string; + + // Dropdowns + types: Type[]; + locations: Location[]; + + // Return JSON to parent component + msAddChangeString: any; + msAddChangeJson: any; + + constructor(private fb: FormBuilder, private authService: AuthService) { + } + + @Input() visible: boolean; + @Input() currentRow: any; + @Output() handler: EventEmitter<any> = new EventEmitter(); + + ngOnInit() { + // The logged in user + this.username = this.authService.getUser().username; + + this.msAddForm = new FormGroup({ + name: new FormControl(), + tag: new FormControl(), + serviceName: new FormControl(), + type: new FormControl(), + //location: new FormControl(), + namespace: new FormControl(), + labels: new FormControl(), + notes: new FormControl() + }); + + // FORM fields and validations + this.msAddForm = this.fb.group({ + name: ['', [Validators.required]], + tag: ['', [Validators.required, Validators.pattern('^([a-z0-9](-[a-z0-9])*)+$'), Validators.minLength(5), Validators.maxLength(50)]], + serviceName: ['', [Validators.pattern('^([a-z](-[a-z])*)+$'), Validators.maxLength(25)]], + type: ['', [Validators.required]], + //location: ['', [Validators.required]], + namespace: ['', [Validators.pattern('^([a-z0-9](-[a-z0-9])*)+$')]], + labels: ['', []], + notes: ['', []] + }, + {updateOn: "blur"} + ); + + // TYPE Dropdown + this.types = [ + { type: 'FM_COLLECTOR' }, + { type: 'PM_COLLECTOR' }, + { type: 'ANALYTIC' }, + { type: 'TICK' }, + { type: 'OTHER' } + ]; + // LOCATION Dropdown + this.locations = [ + { location: 'EDGE' }, + { location: 'CENTRAL' }, + { location: 'UNSPECIFIED' } + ]; + + // "Update" was selected, so populate the current row data in the GUI + if (this.currentRow) { + this.guiHeader = "Microservice Update"; + this.addOrUpdate = "Update"; + this.populateFields(); + } + + } + + populateFields() { + let labelsStr: string; + if (this.currentRow['metadata']['labels']) { + labelsStr = this.currentRow['metadata']['labels'].join(' ') + } + + // Prevent validation (length check) from failing in the html + if (this.currentRow['serviceName']) { + this.serviceName = this.currentRow['serviceName'] + } + + this.msAddForm.patchValue({ + name: this.currentRow['name'], + tag: this.currentRow['tag'], + serviceName: this.serviceName, + type: {type: this.currentRow['type']}, + //location: {location: this.currentRow['location']}, + namespace: this.currentRow['namespace'], + labels: labelsStr, + notes: this.currentRow['metadata']['notes'] + }) + } + + // 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); + } + + // 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.msAddChangeString = { + name: this.msAddForm.value['name'].trim(), + tag: this.msAddForm.value['tag'], + serviceName: this.msAddForm.value['serviceName'], + type: this.msAddForm.value['type'].type, + location: 'UNSPECIFIED', + //location: this.msAddForm.value['location'].location, + namespace: this.msAddForm.value['namespace'].trim(), + metadata: { + labels: this.msAddForm.value['labels'].trim().replace(/\s{2,}/g, ' ').split(" "), + notes: this.msAddForm.value['notes'] + }, + user: this.username + }; + } + + saveMs() { + this.createOutputJson(); + this.msAddChangeJson = JSON.stringify(this.msAddChangeString); + this.handler.emit(this.msAddChangeJson); + } + +} |