diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input')
4 files changed, 410 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html new file mode 100644 index 0000000000..6753b82167 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.html @@ -0,0 +1,69 @@ +<!-- + ~ - + ~ ============LICENSE_START======================================================= + ~ Copyright (C) 2022 Nordix Foundation. + ~ ================================================================================ + ~ 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. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + ~ ============LICENSE_END========================================================= + --> + +<div> + <div *ngIf="!isView && showAddLink" class="add-button-container"> + <a class="add-btn" data-tests-id="add-input.add-input-link" + (click)="showAddInput()">{{'OPERATION_ADD_INPUT' | translate}} + </a> + </div> + <form *ngIf="showForm" [formGroup]="inputForm" (ngSubmit)="onSubmit()"> + <label class="occurrences-label">{{'ADD_INPUT_TITLE' | translate}}</label> + <div> + <label class="sdc-input-label" for="input-name">{{'OPERATION_INPUT_NAME' | translate}}</label> + <input id="input-name" class="sdc-input" type="text" formControlName="name" data-tests-id="add-input.input-name"/> + </div> + <div> + <label class="sdc-input-label" for="input-type">{{'OPERATION_INPUT_TYPE' | translate}}</label> + <sdc-combo-box + id="input-type" + [placeHolder]="inputToAdd.type != undefined ? inputToAdd.type : 'Select...'" + [data]="inputTypeOptions" + [selectedValue]="inputToAdd.type" + (itemSelected)="onChangeInputType($event)" + [testId]="'add-input.input-type'" + [disabled]="isView" + > + </sdc-combo-box> + </div> + <div *ngIf="showInputSchema"> + <label class="sdc-input-label" for="input-schema">{{'OPERATION_INPUT_SCHEMA' | translate}}</label> + <sdc-combo-box + id="input-schema" + [placeHolder]="getSchemaPlaceholder()" + [data]="inputSchemaOptions" + [selectedValue]="getSchemaType()" + (itemSelected)="onChangeInputSchema($event)" + [testId]="'add-input.input-schema'" + [disabled]="isView" + > + </sdc-combo-box> + </div> + <div class="confirmation-button-container" *ngIf="!isView"> + <button type="submit" class="tlv-btn blue" [disabled]="!inputForm.valid" data-tests-id="add-input.add-input-btn"> + {{'OPERATION_ADD_INPUT' | translate}} + </button> + <button type="button" class="tlv-btn outline white" (click)="onCancel()" data-tests-id="add-input.cancel-btn"> + {{'OPERATION_CANCEL' | translate}} + </button> + </div> + </form> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less new file mode 100644 index 0000000000..5eb4a7f5b1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.less @@ -0,0 +1,64 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +.add-button-container { + display: flex; + flex-flow: row wrap; + justify-content: flex-end; + margin: 7px 5px 7px 0; +} + +.confirmation-button-container { + display: flex; + flex-flow: row wrap; + justify-content: flex-end; + margin: 7px 5px 7px 0; + button { + margin: 0 5px; + } +} + +.sdc-input-label { + margin-bottom: 5px; + display: block; + font-family: OpenSans-Semibold, Arial, sans-serif; + font-style: normal; + font-weight: 600; + font-size: 12px; +} + +.sdc-input { + box-sizing: border-box; + padding: 0 10px; + height: 38px; + width: 100%; + border: solid 1px #d2d2d2; + border-radius: 2px; + color: #5a5a5a; +} + +.add-param-link { + +} + +.add-btn { + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts new file mode 100644 index 0000000000..2c6c1e6614 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.spec.ts @@ -0,0 +1,67 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {AddInputComponent} from './add-input.component'; +import {TranslateModule} from '../../../../../shared/translator/translate.module'; +import {ReactiveFormsModule} from '@angular/forms'; +import {SdcUiComponentsModule} from 'onap-ui-angular/dist'; +import {Observable} from 'rxjs/Observable'; +import {DataTypesMap} from '../../../../../../models/data-types-map'; +import {TranslateService} from '../../../../../shared/translator/translate.service'; + +const translateServiceMock: Partial<TranslateService> = { + translate: jest.fn((str: string) => { + }) +}; + +describe('AddInputComponent', () => { + let component: AddInputComponent; + let fixture: ComponentFixture<AddInputComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AddInputComponent ], + imports: [ + TranslateModule, + SdcUiComponentsModule, + ReactiveFormsModule + ], + providers: [ + { provide: TranslateService, useValue: translateServiceMock } + ] + }) + .compileComponents(); + + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddInputComponent); + component = fixture.componentInstance; + component.dataTypeMap$ = new Observable<DataTypesMap>(); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts new file mode 100644 index 0000000000..6632d1a69e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/add-input/add-input.component.ts @@ -0,0 +1,210 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {InputOperationParameter} from '../../../../../../models/interfaceOperation'; +import {IDropDownOption} from 'onap-ui-angular/dist/form-elements/dropdown/dropdown-models'; +import {Observable} from 'rxjs/Observable'; +import {AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from '@angular/forms'; +import {PROPERTY_TYPES} from '../../../../../../utils/constants'; +import {SchemaProperty, SchemaPropertyGroupModel} from '../../../../../../models/schema-property'; +import {DataTypeModel} from "../../../../../../models/data-types"; + +@Component({ + selector: 'app-add-input', + templateUrl: './add-input.component.html', + styleUrls: ['./add-input.component.less'] +}) +export class AddInputComponent implements OnInit { + + @Input('dataTypeMap') dataTypeMap$: Observable<Map<string, DataTypeModel>>; + @Input('isView') isView: boolean; + @Input() existingInputNames: Array<string> = []; + @Output('onAddInput') onAddInputEvent: EventEmitter<InputOperationParameter>; + + dataTypeMap: Map<string, DataTypeModel>; + inputToAdd: InputOperationParameter; + inputTypeOptions: Array<IDropDownOption>; + inputSchemaOptions: Array<IDropDownOption>; + showForm: boolean = false; + showAddLink: boolean = true; + showInputSchema: boolean = false; + + inputForm: FormGroup; + + constructor() { + this.onAddInputEvent = new EventEmitter<InputOperationParameter>(); + this.inputTypeOptions = []; + this.inputSchemaOptions = []; + this.inputToAdd = new InputOperationParameter(); + } + + schemaValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { + const type = control.get('type'); + const schema = control.get('schema'); + return (type.value === 'list' || type.value === 'map') && !schema.value ? { schemaRequired: true } : null; + }; + + uniqueNameValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { + const name = control.get('name'); + return this.existingInputNames.indexOf(name.value) === -1 ? null : { nameIsNotUnique: true }; + }; + + ngOnInit() { + this.initForm(); + this.initInputType(); + } + + private initForm() { + this.inputForm = new FormGroup({ + name: new FormControl({value: '', disabled: this.isView}, [Validators.required, Validators.minLength(1)]), + type: new FormControl({value: '', disabled: this.isView}, [Validators.required, Validators.minLength(1)]), + schema: new FormControl({value: '', disabled: this.isView}) + }, { validators: [this.schemaValidator, this.uniqueNameValidator] }); + } + + private initInputType() { + this.dataTypeMap$.subscribe((dataTypesMap: Map<string, DataTypeModel>) => { + this.dataTypeMap = dataTypesMap; + this.inputTypeOptions = []; + this.inputSchemaOptions = []; + dataTypesMap.forEach((value, key) => { + const entry = {label: key, value: key}; + this.inputTypeOptions.push(entry); + if (key != PROPERTY_TYPES.LIST && key != PROPERTY_TYPES.MAP) { + this.inputSchemaOptions.push(entry); + } + }); + }); + } + + onChangeInputType(inputType) { + const typeForm = this.inputForm.get('type'); + if (!inputType) { + this.inputToAdd.type = undefined; + typeForm.setValue(undefined); + this.toggleInputSchema(); + return; + } + typeForm.setValue(inputType); + this.inputToAdd.type = inputType; + this.toggleInputSchema(); + } + + onChangeInputSchema(inputSchema: string) { + const schemaForm = this.inputForm.get('schema'); + if (!inputSchema) { + this.inputToAdd.schema = undefined; + schemaForm.setValue(undefined); + return; + } + schemaForm.setValue(inputSchema); + this.inputToAdd.schema = new SchemaPropertyGroupModel(); + this.inputToAdd.schema.property = new SchemaProperty(); + this.inputToAdd.schema.property.type = inputSchema; + } + + onSubmit() { + this.trimForm(); + if (this.inputForm.valid) { + const nameForm = this.inputForm.get('name'); + const typeForm = this.inputForm.get('type'); + const schemaForm = this.inputForm.get('schema'); + const input = new InputOperationParameter(); + input.name = nameForm.value; + input.type = typeForm.value; + if (this.typeHasSchema()) { + input.schema = new SchemaPropertyGroupModel(); + input.schema.property = new SchemaProperty(); + input.schema.property.type = schemaForm.value; + } + input.inputId = this.generateUniqueId(); + this.onAddInputEvent.emit(input); + this.hideAddInput(); + this.resetForm(); + } + } + + showAddInput() { + this.showForm = true; + this.showAddLink = false; + } + + hideAddInput() { + this.showForm = false; + this.showAddLink = true; + } + + onCancel() { + this.hideAddInput(); + this.resetForm(); + } + + private generateUniqueId(): string { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const charactersLength = characters.length; + for (let i = 0; i < 36; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; + } + + private resetForm() { + this.inputForm.reset(); + this.showInputSchema = false; + this.inputToAdd = new InputOperationParameter(); + } + + getSchemaType() { + return this.inputToAdd.schema == undefined ? undefined : this.inputToAdd.schema.property.type; + } + + getSchemaPlaceholder() { + const schemaType = this.getSchemaType(); + return schemaType === undefined ? 'Select...' : schemaType; + } + + private toggleInputSchema() { + this.showInputSchema = this.typeHasSchema(); + } + + private typeHasSchema() { + const typeForm = this.inputForm.get('type'); + return typeForm.value == PROPERTY_TYPES.LIST || typeForm.value == PROPERTY_TYPES.MAP; + } + + private trimForm() { + const nameForm = this.inputForm.get('name'); + if (nameForm.value) { + nameForm.setValue(nameForm.value.trim()); + } + const typeForm = this.inputForm.get('type'); + if (typeForm.value) { + typeForm.setValue(typeForm.value.trim()); + } + const schemaForm = this.inputForm.get('schema'); + if (schemaForm.value) { + schemaForm.setValue(schemaForm.value.trim()); + } + } + +} |