diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/interface-operatons')
10 files changed, 1178 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.html new file mode 100644 index 0000000000..7567b90365 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.html @@ -0,0 +1,80 @@ +<!-- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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========================================================= +--> + +<div class="interface-operations"> + <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader> + <div class="operation-list"> + <div *ngIf="!isListEmpty()"> + <div class="expand-collapse"> + <a class="link" + [ngClass]="{'disabled': isAllExpanded()}" + (click)="collapseAll(false)">{{ 'INTERFACE_EXPAND_ALL' | translate }} + </a> | + <a class="link" + [ngClass]="{'disabled': isAllCollapsed()}" + (click)="collapseAll()"> + {{ 'INTERFACE_COLLAPSE_ALL' | translate }} + </a> + </div> + + <div class="interface-row" *ngFor="let interface1 of interfaces"> + <div class="interface-accordion" (click)="interface1.toggleCollapse()"> + <span + class="chevron-container" + [ngClass]="{'isCollapsed': interface1.isCollapsed}"> + <svg-icon + name="caret1-down-o" + mode="primary" + size="small"> + </svg-icon> + </span> + <span class="interface-name">{{interface1.displayType()}}</span> + </div> + + <div class="generic-table" *ngIf="!interface1.isCollapsed"> + <div class="header-row table-row"> + <span + class="cell header-cell field-name header-name"> + {{ 'INTERFACE_HEADER_NAME' | translate }} + </span> + <span class="cell header-cell field-description header-description"> + {{ 'INTERFACE_HEADER_DESCRIPTION' | translate }} + </span> + </div> + + <div class="data-row" *ngFor="let operation of interface1.operations" + (click)="onSelectInterfaceOperation(interface1, operation)"> + <span + class="cell field-name"> + {{operation.name}} + </span> + <span class="cell field-description" + [ngClass]="{'collapsed': operation.isCollapsed}"> + {{operation.getDescriptionEllipsis()}} + <span class="more-or-less link" (click)="operation.toggleCollapsed($event)"> + {{!operation.isEllipsis ? '' : operation.isCollapsed ? 'More' : 'Less'}} + </span> + </span> + </div> + </div> + </div> + </div> + </div> +</div> diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.less new file mode 100644 index 0000000000..1ebfb1fe82 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.less @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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 './../../../../../assets/styles/override.less'; +@import './../../../../../assets/styles/variables.less'; + +.interface-operations { + font-size: 14px; + + .top-add-btn { + position: relative; + top: -31px; + text-transform: uppercase; + font-size: 14px; + font-family: @font-opensans-medium; + } + + .link { + color: @sdcui_color_blue; + text-decoration: underline; + font-family: @font-opensans-regular; + + &:not(.disabled) { + &:not(.empty-list-add-btn) { + &:hover { + color: @sdcui_color_dark-blue; + cursor: pointer; + } + } + } + } + + .operation-list { + border-top: 1px solid @main_color_o; + padding-top: 5px; + + .empty-list-container { + width: 100%; + display: flex; + justify-content: center; + + .empty-list-add-btn { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + border: 1px solid @main_color_o; + margin-top: 50px; + + height: 229px; + width: 480px; + + &.disabled { + pointer-events: none; + } + + &:hover { + &:not(.disabled) { + border: 1px solid @sdcui_color_blue; + cursor: pointer; + } + } + + .button-text { + margin-top: 9px; + font-family: @font-opensans-medium; + font-size: 16px; + text-transform: uppercase; + color: @sdcui_color_blue; + } + } + } + + .expand-collapse { + margin-top: 4px; + margin-bottom: 18px; + color: @sdcui_color_light-gray; + } + + .interface-row { + width: 100%; + margin-top: 13px; + border-bottom: 1px solid @main_color_o; + padding-left: 4px; + min-height: 37px; + + + .interface-accordion { + cursor: pointer; + + .chevron-container { + position: relative; + margin-right: 5px; + + &.isCollapsed { + right: -6px; + top: 0; + * { + transform: rotate(270deg); + } + } + &:not(.isCollapsed) { + top: 6px; + } + * { + &:hover { + cursor: pointer; + } + } + } + .interface-name { + font-size: 18px; + font-family: @font-opensans-bold; + margin-bottom: 15px; + } + } + + .generic-table { + margin-bottom: 24px; + margin-top: 10px; + margin-left: 22px; + font-size: 14px; + + .header-row, .data-row { + .cell { + &.field-description { + flex: 2.5; + } + + &.field-actions { + flex-basis: 72px; + display: flex; + justify-content: center; + align-items: center; + } + } + } + + .header-row { + .cell { + background: @sdcui_color_silver; + + &.field-actions { + font-size: 10px; + } + } + } + + .data-row { + cursor: pointer; + + &:hover { + background: @sdcui_color_light-silver; + + .cell { + &.field-name { + color: @sdcui_color_dark-blue; + } + } + } + + &:not(:hover) { + .field-actions { + visibility: hidden; + } + } + + .cell { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + + &.field-description { + &:not(.collapsed) { + white-space: normal; + } + &.collapsed { + text-overflow: clip; + } + .more-or-less { + margin-left: 5px; + } + } + + &.field-actions { + .delete-action { + position: relative; + top: 2px; + } + } + } + + } + } + + } + } +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts new file mode 100644 index 0000000000..304fbcec3e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts @@ -0,0 +1,247 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2021 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +import {Component, ComponentRef, Input} from '@angular/core'; +import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; +import {TranslateService} from "../../../shared/translator/translate.service"; +import {ModalService } from 'app/ng2/services/modal.service'; +import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component'; +import { + Component as TopologyTemplate +} from "../../../../models/components/component"; +import {PluginsService} from "app/ng2/services/plugins.service"; +import {SelectedComponentType} from "../common/store/graph.actions"; + +import {WorkspaceService} from "../../workspace/workspace.service"; +import { + ComponentInstanceInterfaceModel, + InterfaceOperationModel +} from "../../../../models/interfaceOperation"; +import { + InterfaceOperationHandlerComponent +} from "./operation-creator/interface-operation-handler.component"; + +import { + ButtonModel, + ComponentMetadata, + InterfaceModel, + InputBEModel, + ModalModel, + ComponentInstance +} from 'app/models'; + +export class UIInterfaceOperationModel extends InterfaceOperationModel { + isCollapsed: boolean = true; + isEllipsis: boolean; + MAX_LENGTH = 75; + _description: string; + + constructor(operation: InterfaceOperationModel) { + super(operation); + + if (!operation.description) { + this.description = ''; + } + + if (this.description.length > this.MAX_LENGTH) { + this.isEllipsis = true; + } else { + this.isEllipsis = false; + } + } + + getDescriptionEllipsis(): string { + if (this.isCollapsed && this.description.length > this.MAX_LENGTH) { + return this.description.substr(0, this.MAX_LENGTH - 3) + '...'; + } + return this.description; + } + + toggleCollapsed(e) { + e.stopPropagation(); + this.isCollapsed = !this.isCollapsed; + } +} + +class ModalTranslation { + EDIT_TITLE: string; + CANCEL_BUTTON: string; + SAVE_BUTTON: string; + + constructor(private TranslateService: TranslateService) { + this.TranslateService.languageChangedObservable.subscribe(lang => { + this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE'); + this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON"); + this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON"); + }); + } +} + +export class UIInterfaceModel extends ComponentInstanceInterfaceModel { + isCollapsed: boolean = false; + + constructor(interf?: any) { + super(interf); + this.operations = _.map( + this.operations, + (operation) => new UIInterfaceOperationModel(operation) + ); + } + + toggleCollapse() { + this.isCollapsed = !this.isCollapsed; + } +} + +@Component({ + selector: 'app-interface-operations', + templateUrl: './interface-operations.component.html', + styleUrls: ['./interface-operations.component.less'], + providers: [ModalService, TranslateService] +}) +export class InterfaceOperationsComponent { + interfaces: UIInterfaceModel[]; + selectedOperation: InterfaceOperationModel; + inputs: Array<InputBEModel>; + isLoading: boolean; + interfaceTypes: { [interfaceType: string]: string[] }; + topologyTemplate: TopologyTemplate; + componentMetaData: ComponentMetadata; + componentInstanceSelected: ComponentInstance; + modalInstance: ComponentRef<ModalComponent>; + modalTranslation: ModalTranslation; + componentInstancesInterfaces: Map<string, InterfaceModel[]>; + + @Input() component: ComponentInstance; + @Input() readonly: boolean; + @Input() enableMenuItems: Function; + @Input() disableMenuItems: Function; + @Input() componentType: SelectedComponentType; + + + constructor( + private TranslateService: TranslateService, + private PluginsService: PluginsService, + private topologyTemplateService: TopologyTemplateService, + private modalServiceNg2: ModalService, + private workspaceService: WorkspaceService, + ) { + this.modalTranslation = new ModalTranslation(TranslateService); + } + + ngOnInit(): void { + this.componentMetaData = this.workspaceService.metadata; + this.loadComponentInstances(); + } + + private loadComponentInstances() { + this.isLoading = true; + this.topologyTemplateService.getComponentInstances(this.componentMetaData.componentType, this.componentMetaData.uniqueId) + .subscribe((response) => { + this.componentInstanceSelected = response.componentInstances.find(ci => ci.uniqueId === this.component.uniqueId); + this.initComponentInstanceInterfaceOperations(); + this.isLoading = false; + }); + } + + private initComponentInstanceInterfaceOperations() { + this.initInterfaces(this.componentInstanceSelected.interfaces); + this.sortInterfaces(); + } + + private initInterfaces(interfaces: InterfaceModel[]): void { + this.interfaces = _.map(interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel)); + } + + private sortInterfaces(): void { + this.interfaces = _.filter(this.interfaces, (interf) => interf.operations && interf.operations.length > 0); // remove empty interfaces + this.interfaces.sort((a, b) => a.type.localeCompare(b.type)); // sort interfaces alphabetically + _.forEach(this.interfaces, (interf) => { + interf.operations.sort((a, b) => a.name.localeCompare(b.name)); // sort operations alphabetically + }); + } + + collapseAll(value: boolean = true): void { + _.forEach(this.interfaces, (interf) => { + interf.isCollapsed = value; + }); + } + + isAllCollapsed(): boolean { + return _.every(this.interfaces, (interf) => interf.isCollapsed); + } + + isAllExpanded(): boolean { + return _.every(this.interfaces, (interf) => !interf.isCollapsed); + } + + isListEmpty(): boolean { + return _.filter( + this.interfaces, + (interf) => interf.operations && interf.operations.length > 0 + ).length === 0; + } + + private enableOrDisableSaveButton = (): boolean => { + return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); + } + + onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) { + const cancelButton: ButtonModel = new ButtonModel(this.modalTranslation.CANCEL_BUTTON, 'outline white', this.cancelAndCloseModal); + const saveButton: ButtonModel = new ButtonModel(this.modalTranslation.SAVE_BUTTON, 'blue', () => + this.updateInterfaceOperation(), this.enableOrDisableSaveButton); + const modalModel: ModalModel = new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom'); + this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); + + this.modalServiceNg2.addDynamicContentToModal( + this.modalInstance, + InterfaceOperationHandlerComponent, + { + selectedInterface: interfaceModel, + selectedInterfaceOperation: operation, + validityChangedCallback: this.enableOrDisableSaveButton + } + ); + this.modalInstance.instance.open(); + } + + private cancelAndCloseModal = () => { + this.loadComponentInstances(); + return this.modalServiceNg2.closeCurrentModal(); + } + + private updateInterfaceOperation() { + this.isLoading = true; + let operationUpdated = this.modalInstance.instance.dynamicContent.instance.operationToUpdate; + this.topologyTemplateService.updateComponentInstanceInterfaceOperation( + this.componentMetaData.uniqueId, + this.componentMetaData.componentType, + this.componentInstanceSelected.uniqueId, + operationUpdated) + .subscribe((updatedComponentInstance: ComponentInstance) => { + this.componentInstanceSelected = new ComponentInstance(updatedComponentInstance); + this.initComponentInstanceInterfaceOperations(); + }); + this.modalServiceNg2.closeCurrentModal(); + this.isLoading = false; + } + +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html new file mode 100644 index 0000000000..80aceeadda --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html @@ -0,0 +1,44 @@ +<!-- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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========================================================= + --> + +<div class="cell field-input-name"> + <sdc-input + [(value)]="input.name" + (valueChange)="onChange()"> + </sdc-input> +</div> + +<div class="cell field-input-value"> + <sdc-input + [(value)]="input.toscaDefaultValue" + (valueChange)="onChange()"> + </sdc-input> + +</div> + +<div class="cell remove" *ngIf="!readonly"> + <svg-icon + name="trash-o" + mode="info" + size="small" + (click)="onRemoveInput(input)" + [clickable]="true"> + </svg-icon> +</div> diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less new file mode 100644 index 0000000000..12eacc6473 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.less @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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 '../../../../../../../assets/styles/variables.less'; + +.remove { + display: flex; + align-items: center; + justify-content: center; + + svg-icon { + position: relative; + right: -3px; + + &:hover { + cursor: pointer; + } + } +} + +.cell { + min-height: 50px; + padding: 10px; + display: flex; + align-items: center; + + > * { + flex-basis: 100%; + } + + /deep/ select { + height: 30px; + } + + input { + height: 30px; + border: none; + padding-left: 10px; + } + + select { + width: 100%; + } + + &.field-property { + &:last-child { + flex: 1; + } + + .no-properties-error { + color: @func_color_q; + font-style: italic; + } + } +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts new file mode 100644 index 0000000000..48bb804173 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.ts @@ -0,0 +1,48 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2021 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +import {Component, Input} from '@angular/core'; +import {InputOperationParameter} from "../../../../../../models/interfaceOperation"; + +@Component({ + selector: 'input-param-row', + templateUrl: './input-param-row.component.html', + styleUrls: ['./input-param-row.component.less'] +}) + +export class InputParamRowComponent { + @Input() input: InputOperationParameter; + @Input() onRemoveInput: Function; + @Input() readonly: boolean; + @Input() validityChanged: Function; + + constructor() { + } + + ngOnInit() { + this.validityChanged(); + } + + onChange() { + this.validityChanged(); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html new file mode 100644 index 0000000000..cd2d6063c1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html @@ -0,0 +1,86 @@ +<!-- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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========================================================= +--> + +<div class="operation-handler"> + <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader> + + <form class="w-sdc-form"> + + <div class="side-by-side"> + <div class="form-item"> + <sdc-input + label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}" + [(value)]="interfaceType" + [disabled]="true"> + </sdc-input> + </div> + + <div class="form-item"> + <sdc-input + label="{{ 'OPERATION_NAME' | translate }}" + [(value)]="operationToUpdate.name" + [disabled]="true"> + </sdc-input> + </div> + </div> + + <div class="i-sdc-form-item"> + <sdc-input + label="{{'OPERATION_DESCRIPTION' | translate}}" + [(value)]="operationToUpdate.description" + (valueChange)="onDescriptionChange($event)"> + </sdc-input> + </div> + + <div class="i-sdc-form-item"> + <sdc-input + label="{{'IMPLEMENTATION_NAME' | translate}}" + [(value)]="operationToUpdate.implementation.artifactName"> + </sdc-input> + </div> + + <div class="separator-buttons"> + <tab tabTitle="Inputs"></tab> + <a class="add-param-link add-btn" + [ngClass]="{'disabled': readonly}" + (click)="onAddInput()">{{'OPERATION_ADD_INPUT' | translate}} + </a> + </div> + + <div class="generic-table"> + <div class="header-row table-row"> + <span class="cell header-cell field-input-name">{{ 'OPERATION_PARAM_NAME' | translate }}</span> + <span class="cell header-cell field-input-value">{{ 'OPERATION_INPUT_VALUE' | translate }}</span> + <span class="cell header-cell remove">●●●</span> + </div> + <div class="empty-msg data-row" *ngIf="!inputs.length"> + <div>{{ 'OPERATION_INPUT_EMPTY' | translate }}</div> + </div> + <input-param-row + *ngFor="let inputParameter of inputs" + class="data-row" + [input]="inputParameter" + [onRemoveInput]="onRemoveInput" + [validityChanged]="validityChanged"> + </input-param-row> + </div> + + </form> +</div> diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less new file mode 100644 index 0000000000..8bbed9de02 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.less @@ -0,0 +1,200 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021 Nordix Foundation. 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 '../../../../../../assets/styles/variables.less'; +@import '../../../../../../assets/styles/override.less'; + +.operation-handler { + font-family: @font-opensans-regular; + user-select: none; + padding-top: 12px; + padding-bottom: 20px; + + .i-sdc-form-label { + font-size: 12px; + } + + .w-sdc-form .i-sdc-form-item { + margin-bottom: 15px; + } + + textarea { + min-height: 74px; + margin-bottom: 18px; + } + + /deep/ .sdc-dropdown__component-container { + .sdc-dropdown__header { + height: 38px; + line-height: 35px; + + svg-icon { + margin: 13px 6px; + } + } + } + + /deep/ .sdc-input { + margin-bottom: 0; + + .sdc-input__input { + height: 38px; + } + } + + .side-by-side { + display: flex; + + .form-item { + flex: 1; + + &:first-child { + margin-right: 14px; + flex-basis: 37%; + flex-grow: 0; + flex-shrink: 0; + } + + &:nth-child(3) { + margin-left: 14px; + flex: 0.4; + } + + .i-sdc-form-file-upload { + height: 37px; + margin-bottom: 0; + + .i-sdc-form-file-name { + padding: 8px 10px; + } + + .i-sdc-form-file-upload-x-btn { + top: 13px; + } + + .file-upload-browse-btn { + height: 100%; + padding: 7px 6px; + z-index: 1; + } + } + + } + } + + .archive-warning { + font-family: @font-opensans-bold; + color: @main_color_i; + } + + .no-workflow-warning { + font-family: @font-opensans-bold; + color: @sdcui_color_red; + float: right; + } + + .input-param-title { + font-size: 16px; + text-transform: uppercase; + } + + .separator-buttons { + display: flex; + justify-content: space-between; + margin-top: 10px; + + .add-param-link { + &:not(.disabled):hover { + cursor: pointer; + } + } + + .tab { + width: 84px; + text-align: center; + } + } + + .generic-table { + max-height: 244px; + min-height: 91px; + background: @main_color_p; + + .header-row .header-cell { + .info-icon { + float: right; + position: relative; + top: 2px; + } + /deep/ .tooltip-inner { + padding: 2px; + max-width: 270px; + font-size: 11px; + } + &.remove { + padding: 10px; + font-size: 10px; + } + } + + .data-row { + &.empty-msg { + .bold-message { + font-family: @font-opensans-bold; + } + + :first-child { + &:not(:only-child) { + margin: 6px 0; + } + } + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 14px; + } + } + + /deep/ .cell { + &.field-input-name, &.field-input-value{ + flex: 1; + } + + &.field-property { + &, &:last-child { + flex: 1; + } + } + + &.field-mandatory { + flex: 0.5; + text-align: center; + } + + &.remove { + min-width: 40px; + max-width: 40px; + } + } + + } +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts new file mode 100644 index 0000000000..1618af4aea --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts @@ -0,0 +1,130 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2021 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +import {Component} from '@angular/core'; +import {UIInterfaceModel} from "../interface-operations.component"; +import { + InputOperationParameter, + InterfaceOperationModel, + IOperationParamsList +} from "../../../../../models/interfaceOperation"; +import {TranslateService} from "../../../../shared/translator/translate.service"; + +@Component({ + selector: 'operation-handler', + templateUrl: './interface-operation-handler.component.html', + styleUrls: ['./interface-operation-handler.component.less'], + providers: [TranslateService] +}) + +export class InterfaceOperationHandlerComponent { + + input: { + selectedInterface: UIInterfaceModel; + selectedInterfaceOperation: InterfaceOperationModel; + validityChangedCallback: Function; + }; + + interfaceType: string; + interfaceOperationName: string; + operationToUpdate: InterfaceOperationModel; + inputs: Array<InputOperationParameter> = []; + isLoading: boolean = false; + readonly: boolean; + + ngOnInit() { + this.interfaceType = this.input.selectedInterface.displayType(); + this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation); + this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId; + this.operationToUpdate.interfaceType = this.input.selectedInterface.type; + if (!this.operationToUpdate.inputs) { + this.operationToUpdate.inputs = new class implements IOperationParamsList { + listToscaDataDefinition: Array<InputOperationParameter> = []; + } + } + this.inputs = this.operationToUpdate.inputs.listToscaDataDefinition; + this.removeImplementationQuote(); + this.validityChanged(); + } + + onAddInput(inputOperationParameter?: InputOperationParameter): void { + let newInput = new InputOperationParameter(inputOperationParameter) + newInput.type = "string"; + newInput.inputId = this.generateUniqueId(); + this.inputs.push(newInput); + this.validityChanged(); + } + + onRemoveInput = (inputParam: InputOperationParameter): void => { + let index = this.inputs.indexOf(inputParam); + this.inputs.splice(index, 1); + this.validityChanged(); + } + + 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; + } + + validityChanged = () => { + let validState = this.checkFormValidForSubmit(); + this.input.validityChangedCallback(validState); + if (validState) { + this.readonly = false; + } + } + + onDescriptionChange= (value: any): void => { + this.operationToUpdate.description = value; + } + + private checkFormValidForSubmit = (): boolean => { + return this.operationToUpdate.name && this.isParamsValid(); + } + + private isParamsValid = (): boolean => { + const isInputValid = (input) => input.name && input.inputId; + const isValid = this.inputs.every(isInputValid); + if (!isValid) { + this.readonly = true; + } + return isValid; + } + + private removeImplementationQuote(): void { + if (!this.operationToUpdate.implementation + || !this.operationToUpdate.implementation.artifactName) { + return; + } + + let implementation = this.operationToUpdate.implementation.artifactName.trim(); + + if (implementation.startsWith("'") && implementation.endsWith("'")) { + this.operationToUpdate.implementation.artifactName = implementation.slice(1, -1); + } + } + +} diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts new file mode 100644 index 0000000000..deba50aa7d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.module.ts @@ -0,0 +1,55 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2021 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +import {NgModule} from "@angular/core"; +import {CommonModule} from "@angular/common"; + +import {FormsModule} from "@angular/forms"; +import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; +import {TranslateModule} from "app/ng2/shared/translator/translate.module"; + +import {SdcUiComponentsModule} from 'onap-ui-angular'; +import {UiElementsModule} from '../../../../components/ui/ui-elements.module'; +import {InputParamRowComponent} from './input-param-row/input-param-row.component'; +import {InterfaceOperationHandlerComponent} from "./interface-operation-handler.component"; + +@NgModule({ + declarations: [ + InterfaceOperationHandlerComponent, + InputParamRowComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + FormsModule, + FormElementsModule, + TranslateModule, + UiElementsModule + ], + exports: [], + entryComponents: [ + InterfaceOperationHandlerComponent + ], + providers: [] +}) + +export class InterfaceOperationHandlerModule { +} |