summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraribeiro <anderson.ribeiro@est.tech>2022-01-13 14:33:25 +0000
committerMichael Morris <michael.morris@est.tech>2022-01-26 12:57:51 +0000
commitc2fa1b7e8d43a236219d1f6ad2831de1af296cb4 (patch)
treec4ebc43f939b859ab5ef854d22d126961ee2e88c
parent7a98ee137b17a808635b06d72955e01ac84fe55b (diff)
View Interface definition on VFC
Add Interface support to VFC view UI Issue-ID: SDC-3850 Signed-off-by: aribeiro <anderson.ribeiro@est.tech> Change-Id: Icd195c939af39d40ae8c617e740323dd3e70fc15
-rw-r--r--catalog-ui/configurations/menu.js1
-rw-r--r--catalog-ui/src/app/app.ts12
-rw-r--r--catalog-ui/src/app/modules/directive-module.ts8
-rw-r--r--catalog-ui/src/app/modules/view-model-module.ts2
-rw-r--r--catalog-ui/src/app/ng2/app.module.ts4
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/interface-operations.component.ts3
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html24
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.ts3
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.module.ts47
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html85
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.less234
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts233
-rw-r--r--catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts4
-rw-r--r--catalog-ui/src/app/utils/constants.ts1
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view-model.ts35
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view.html27
-rw-r--r--catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition.less26
-rw-r--r--catalog-ui/src/assets/languages/en_US.json3
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java40
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java16
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/InterfaceDefinitionFlow.java56
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java5
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java14
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java6
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java (renamed from integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java)9
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionPage.java96
26 files changed, 960 insertions, 34 deletions
diff --git a/catalog-ui/configurations/menu.js b/catalog-ui/configurations/menu.js
index beecfd16b2..38f504bb57 100644
--- a/catalog-ui/configurations/menu.js
+++ b/catalog-ui/configurations/menu.js
@@ -228,6 +228,7 @@ const SDC_MENU_CONFIG = {
{"text": "TOSCA Artifacts", "action": "onMenuItemPressed", "state": "workspace.tosca_artifacts"},
{"text": "Properties", "action": "onMenuItemPressed", "state": "workspace.properties"},
{"text": "Attributes", "action": "onMenuItemPressed", "state": "workspace.attributes"},
+ {"text": "Interfaces", "action": "onMenuItemPressed", "state": "workspace.interface-definition"},
{"text": "Req. & Capabilities", "action": "onMenuItemPressed", "state": "workspace.reqAndCap"},
{"text": "Activity Log", "action": "onMenuItemPressed", "state": "workspace.activity_log"}
],
diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts
index 87930fd12e..ffa43895a7 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -512,6 +512,18 @@ ng1appModule.config([
);
$stateProvider.state(
+ States.WORKSPACE_INTERFACE_DEFINITION, {
+ url: 'interfaceDefinition',
+ parent: 'workspace',
+ controller: viewModelsModuleName + '.InterfaceDefinitionViewModel',
+ templateUrl: './view-models/workspace/tabs/interface-definition/interface-definition-view.html',
+ data: {
+ bodyClass: 'interfaceDefinition'
+ }
+ }
+ );
+
+ $stateProvider.state(
'workspace.plugins', {
url: 'plugins/*path',
parent: 'workspace',
diff --git a/catalog-ui/src/app/modules/directive-module.ts b/catalog-ui/src/app/modules/directive-module.ts
index 270a764e86..7719f7389f 100644
--- a/catalog-ui/src/app/modules/directive-module.ts
+++ b/catalog-ui/src/app/modules/directive-module.ts
@@ -96,6 +96,7 @@ import {DeploymentArtifactsPageComponent} from "../ng2/pages/workspace/deploymen
import {ReqAndCapabilitiesComponent} from "../ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component";
import {DistributionComponent} from '../ng2/pages/workspace/disribution/distribution.component';
import {AttributesOutputsComponent} from "../ng2/pages/attributes-outputs/attributes-outputs.page.component";
+import {InterfaceDefinitionComponent} from "../ng2/pages/interface-definition/interface-definition.page.component";
let moduleName: string = 'Sdc.Directives';
let directiveModule: ng.IModule = angular.module(moduleName, []);
@@ -245,6 +246,12 @@ directiveModule.directive('interfaceOperation', downgradeComponent({
outputs: []
}) as angular.IDirectiveFactory);
+directiveModule.directive('interfaceDefinition', downgradeComponent({
+ component: InterfaceDefinitionComponent,
+ inputs: ['component', 'readonly'],
+ outputs: []
+}) as angular.IDirectiveFactory);
+
directiveModule.directive('ng2MultilineEllipsis', downgradeComponent({
component: MultilineEllipsisComponent,
inputs: ['lines', 'lineHeight', 'className'],
@@ -309,6 +316,7 @@ directiveModule.directive('informationArtifactPage', downgradeComponent({
inputs: [],
outputs: []
}) as angular.IDirectiveFactory);
+
directiveModule.directive('deploymentArtifactPage', downgradeComponent({
component: DeploymentArtifactsPageComponent,
inputs: [],
diff --git a/catalog-ui/src/app/modules/view-model-module.ts b/catalog-ui/src/app/modules/view-model-module.ts
index 5b8fc5944a..dd08135f33 100644
--- a/catalog-ui/src/app/modules/view-model-module.ts
+++ b/catalog-ui/src/app/modules/view-model-module.ts
@@ -36,6 +36,7 @@ import {PropertiesViewModel} from "../view-models/workspace/tabs/properties/prop
import {ManagementWorkflowViewModel} from "../view-models/workspace/tabs/management-workflow/management-workflow-view-model";
import {InterfaceOperationViewModel} from "../view-models/workspace/tabs/interface-operation/interface-operation-view-model";
import {NetworkCallFlowViewModel} from "../view-models/workspace/tabs/network-call-flow/network-call-flow-view-model";
+import {InterfaceDefinitionViewModel} from "../view-models/workspace/tabs/interface-definition/interface-definition-view-model";
let moduleName:string = 'Sdc.ViewModels';
let viewModelModule:ng.IModule = angular.module(moduleName, []);
@@ -59,4 +60,5 @@ viewModelModule
.controller(moduleName + '.PropertiesViewModel', PropertiesViewModel)
.controller(moduleName + '.ManagementWorkflowViewModel', ManagementWorkflowViewModel)
.controller(moduleName + '.InterfaceOperationViewModel', InterfaceOperationViewModel)
+ .controller(moduleName + '.InterfaceDefinitionViewModel', InterfaceDefinitionViewModel)
.controller(moduleName + '.NetworkCallFlowViewModel', NetworkCallFlowViewModel);
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index 5b12ae9f48..f6ba919427 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -102,6 +102,7 @@ import {AttributesOutputsModule} from "./pages/attributes-outputs/attributes-out
import { ElementService } from "./services/element.service";
import { ModelService } from "./services/model.service";
import {ToscaArtifactService} from "./services/tosca-artifact.service";
+import {InterfaceDefinitionModule} from "./pages/interface-definition/interface-definition.module";
declare const __ENV__: string;
@@ -156,8 +157,9 @@ export function configServiceFactory(config: ConfigService, authService: Authent
PluginFrameModule,
PluginsModule,
InterfaceOperationModule,
+ InterfaceDefinitionModule,
OperationCreatorModule,
- InterfaceOperationHandlerModule,
+ InterfaceOperationHandlerModule,
ServicePathCreatorModule,
ServicePathsListModule,
ServicePathSelectorModule,
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
index 2cc91a92a0..60d66788ac 100644
--- 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
@@ -227,7 +227,8 @@ export class InterfaceOperationsComponent {
toscaArtifactTypes: this.toscaArtifactTypes,
selectedInterface: interfaceModel,
selectedInterfaceOperation: operation,
- validityChangedCallback: this.enableOrDisableSaveButton
+ validityChangedCallback: this.enableOrDisableSaveButton,
+ isViewOnly: false
}
);
this.modalInstance.instance.open();
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
index 428c4cd5ed..6dec4160f6 100644
--- 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
@@ -28,7 +28,7 @@
<sdc-input
label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
[(value)]="interfaceType"
- [disabled]="true">
+ [disabled]=isViewOnly>
</sdc-input>
</div>
@@ -36,7 +36,7 @@
<sdc-input
label="{{ 'OPERATION_NAME' | translate }}"
[(value)]="operationToUpdate.name"
- [disabled]="true">
+ [disabled]=isViewOnly>
</sdc-input>
</div>
</div>
@@ -46,7 +46,8 @@
label="{{'OPERATION_DESCRIPTION' | translate}}"
[(value)]="operationToUpdate.description"
testId="interface-operation-description"
- (valueChange)="onDescriptionChange($event)">
+ (valueChange)="onDescriptionChange($event)"
+ [disabled]=isViewOnly>
</sdc-input>
</div>
@@ -55,7 +56,8 @@
<div class="form-item">
<checkbox [label]="'Add Artifact To Implementation'"
[(checked)]="enableAddArtifactImplementation"
- (checkedChange)="onMarkToAddArtifactToImplementation($event)">
+ (checkedChange)="onMarkToAddArtifactToImplementation($event)"
+ [disabled]=isViewOnly>
</checkbox>
</div>
<div class="form-item" *ngIf="!enableAddArtifactImplementation">
@@ -63,7 +65,8 @@
label="{{'INTERFACE_OPERATION_IMPLEMENTATION_NAME' | translate}}"
testId="interface-operation-implementation-name"
[(value)]="artifactName"
- (valueChange)="onImplementationNameChange($event)">
+ (valueChange)="onImplementationNameChange($event)"
+ [disabled]=isViewOnly>
</sdc-input>
</div>
@@ -76,7 +79,8 @@
[selectedOption]="toscaArtifactTypeSelected"
placeHolder="{{toscaArtifactTypeSelected != undefined ? toscaArtifactTypeSelected : 'Select...'}}"
(changed)="onSelectToscaArtifactType($event)"
- [options]="toscaArtifactTypes">
+ [options]="toscaArtifactTypes"
+ [disabled]=isViewOnly>
</sdc-dropdown>
</div>
<div class="form-item" *ngIf="toscaArtifactTypeSelected && enableAddArtifactImplementation">
@@ -85,7 +89,8 @@
data-tests-id="artifactFile"
[(value)]="artifactName"
[required]="true"
- (valueChange)="onArtifactFileChange($event)">
+ (valueChange)="onArtifactFileChange($event)"
+ [disabled]=isViewOnly>
</sdc-input>
</div>
<div class="form-item">
@@ -93,7 +98,8 @@
label="{{ 'ARTIFACT_VERSION' | translate }}"
data-tests-id="artifactVersion"
[(value)]="artifactVersion"
- (valueChange)="onArtifactVersionChange($event)">
+ (valueChange)="onArtifactVersionChange($event)"
+ [disabled]=isViewOnly>
</sdc-input>
</div>
</div>
@@ -122,7 +128,7 @@
<div class="separator-buttons">
<tab tabTitle="Inputs"></tab>
<a class="add-param-link add-btn"
- [ngClass]="{'disabled': readonly}"
+ [ngClass]="{'disabled': readonly || isViewOnly}"
(click)="onAddInput()">{{'OPERATION_ADD_INPUT' | translate}}
</a>
</div>
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
index 6e4ae45487..1099391548 100644
--- 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
@@ -49,6 +49,7 @@ export class InterfaceOperationHandlerComponent {
selectedInterface: UIInterfaceModel;
selectedInterfaceOperation: InterfaceOperationModel;
validityChangedCallback: Function;
+ isViewOnly: boolean;
};
interfaceType: string;
@@ -60,6 +61,7 @@ export class InterfaceOperationHandlerComponent {
properties: Array<PropertyParamRowComponent> = [];
isLoading: boolean = false;
readonly: boolean;
+ isViewOnly: boolean;
toscaArtifactTypeSelected: string;
toscaArtifactTypeProperties: Array<PropertyBEModel> = [];
@@ -70,6 +72,7 @@ export class InterfaceOperationHandlerComponent {
propertyValueValid: boolean = true;
ngOnInit() {
+ this.isViewOnly = this.input.isViewOnly;
this.interfaceType = this.input.selectedInterface.displayType();
this.operationToUpdate = new InterfaceOperationModel(this.input.selectedInterfaceOperation);
this.operationToUpdate.interfaceId = this.input.selectedInterface.uniqueId;
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.module.ts b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.module.ts
new file mode 100644
index 0000000000..27a7f111d2
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.module.ts
@@ -0,0 +1,47 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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 {UiElementsModule} from "app/ng2/components/ui/ui-elements.module";
+import {TranslateModule} from "app/ng2/shared/translator/translate.module";
+import { SdcUiComponentsModule } from 'onap-ui-angular';
+import {InterfaceDefinitionComponent} from "./interface-definition.page.component";
+import {InterfaceOperationHandlerModule} from "../composition/interface-operatons/operation-creator/interface-operation-handler.module";
+
+@NgModule({
+ declarations: [
+ InterfaceDefinitionComponent,
+ ],
+ imports: [
+ CommonModule,
+ SdcUiComponentsModule,
+ UiElementsModule,
+ TranslateModule,
+ InterfaceOperationHandlerModule
+ ],
+ exports: [],
+ entryComponents: [
+ InterfaceDefinitionComponent
+ ],
+ providers: []
+})
+
+export class InterfaceDefinitionModule {}
diff --git a/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html
new file mode 100644
index 0000000000..25ccf111a1
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html
@@ -0,0 +1,85 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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-definition">
+ <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
+ <div *ngIf="isInterfaceListEmpty()">
+ <div class="interface-empty-msg">
+ <div>{{ 'INTERFACE_DATA_EMPTY' | translate }}</div>
+ </div>
+ </div>
+ <div class="operation-list">
+ <div *ngIf="!isInterfaceListEmpty()">
+ <div class="expand-collapse" *ngIf="isOperationListEmpty()">
+ <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 interface of interfaces">
+ <div class="interface-accordion" (click)="interface.toggleCollapse()">
+ <span
+ class="chevron-container"
+ [ngClass]="{'isCollapsed': interface.isCollapsed}"
+ *ngIf="isOperationListEmpty()">
+ <svg-icon
+ name="caret1-down-o"
+ mode="primary"
+ size="small">
+ </svg-icon>
+ </span>
+ <span class="interface-name">{{interface.type}}</span>
+ </div>
+
+ <div class="generic-table" *ngIf="!interface.isCollapsed && isOperationListEmpty()">
+ <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 interface.operations"
+ (click)="onSelectInterfaceOperation(interface, 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/interface-definition/interface-definition.page.component.less b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.less
new file mode 100644
index 0000000000..2b76c8c0ec
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.less
@@ -0,0 +1,234 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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 '../../../../assets/styles/variables.less';
+@import '../../../../assets/styles/override.less';
+
+.interface-definition {
+ font-size: 14px;
+
+ .interface-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;
+ }
+
+ .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/interface-definition/interface-definition.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts
new file mode 100644
index 0000000000..2a77b5e996
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts
@@ -0,0 +1,233 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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, Inject, ComponentRef} from '@angular/core';
+import {Component as IComponent } from 'app/models/components/component';
+
+import { SdcConfigToken, ISdcConfig } from "app/ng2/config/sdc-config.config";
+import {TranslateService } from "app/ng2/shared/translator/translate.service";
+
+import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
+import {ModalService } from 'app/ng2/services/modal.service';
+import {
+ OperationModel,
+ InterfaceModel,
+ CapabilitiesGroup,
+ ButtonModel, ModalModel
+} from 'app/models';
+
+import {ComponentServiceNg2 } from 'app/ng2/services/component-services/component.service';
+
+import { SdcUiServices } from 'onap-ui-angular';
+import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
+import {InputOperationParameter, InterfaceOperationModel} from "../../../models/interfaceOperation";
+import {PropertyParamRowComponent} from "../composition/interface-operatons/operation-creator/property-param-row/property-param-row.component";
+import {InterfaceOperationHandlerComponent} from "../composition/interface-operatons/operation-creator/interface-operation-handler.component";
+import {DropdownValue} from "../../components/ui/form-components/dropdown/ui-element-dropdown.component";
+
+export class UIOperationModel extends OperationModel {
+ isCollapsed: boolean = true;
+ isEllipsis: boolean;
+ MAX_LENGTH = 75;
+
+ constructor(operation: OperationModel) {
+ 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;
+ }
+}
+
+// tslint:disable-next-line:max-classes-per-file
+class ModalTranslation {
+ CREATE_TITLE: string;
+ EDIT_TITLE: string;
+ DELETE_TITLE: string;
+ CANCEL_BUTTON: string;
+ SAVE_BUTTON: string;
+ CREATE_BUTTON: string;
+ DELETE_BUTTON: string;
+ deleteText: Function;
+
+ constructor(private TranslateService: TranslateService) {
+ this.TranslateService.languageChangedObservable.subscribe(lang => {
+ this.CREATE_TITLE = this.TranslateService.translate("INTERFACE_CREATE_TITLE");
+ this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
+ this.DELETE_TITLE = this.TranslateService.translate("INTERFACE_DELETE_TITLE");
+ this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
+ this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
+ this.CREATE_BUTTON = this.TranslateService.translate("INTERFACE_CREATE_BUTTON");
+ this.DELETE_BUTTON = this.TranslateService.translate("INTERFACE_DELETE_BUTTON");
+ this.deleteText = (operationName) => this.TranslateService.translate("INTERFACE_DELETE_TEXT", {operationName});
+ });
+ }
+}
+
+// tslint:disable-next-line:max-classes-per-file
+export class UIInterfaceModel extends InterfaceModel {
+ isCollapsed: boolean = false;
+
+ constructor(interfaceData?: any) {
+ super(interfaceData);
+ this.operations = _.map(
+ this.operations,
+ (operation) => new UIOperationModel(operation)
+ );
+ }
+
+ toggleCollapse() {
+ this.isCollapsed = !this.isCollapsed;
+ }
+}
+
+// tslint:disable-next-line:max-classes-per-file
+@Component({
+ selector: 'interface-definition',
+ templateUrl: './interface-definition.page.component.html',
+ styleUrls: ['interface-definition.page.component.less'],
+ providers: [ModalService, TranslateService]
+})
+
+export class InterfaceDefinitionComponent {
+
+ modalInstance: ComponentRef<ModalComponent>;
+ interfaces: UIInterfaceModel[];
+ inputs: Array<InputOperationParameter> = [];
+
+ properties: Array<PropertyParamRowComponent> = [];
+ deploymentArtifactsFilePath: Array<DropdownValue> = [];
+
+ toscaArtifactTypes: Array<DropdownValue> = [];
+
+ isLoading: boolean;
+ interfaceTypes: { [interfaceType: string]: string[] };
+ modalTranslation: ModalTranslation;
+ workflows: any[];
+ capabilities: CapabilitiesGroup;
+
+ @Input() component: IComponent;
+ @Input() readonly: boolean;
+ @Input() enableMenuItems: Function;
+ @Input() disableMenuItems: Function;
+
+ constructor(
+ @Inject(SdcConfigToken) private sdcConfig: ISdcConfig,
+ @Inject("$state") private $state: ng.ui.IStateService,
+ private translateService: TranslateService,
+ private componentServiceNg2: ComponentServiceNg2,
+ private modalServiceNg2: ModalService,
+ private modalServiceSdcUI: SdcUiServices.ModalService,
+ private topologyTemplateService: TopologyTemplateService
+ ) {
+ this.modalTranslation = new ModalTranslation(translateService);
+ }
+
+ ngOnInit(): void {
+ if(this.component) {
+ this.initInterfaceDefinition();
+ }
+ }
+
+ private cancelAndCloseModal = () => {
+ return this.modalServiceNg2.closeCurrentModal();
+ }
+
+ private enableOrDisableSaveButton = (): boolean => {
+ return true;
+ }
+
+ 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', () =>
+ null, this.enableOrDisableSaveButton);
+ const interfaceDataModal: ModalModel =
+ new ModalModel('l', this.modalTranslation.EDIT_TITLE, '', [saveButton, cancelButton], 'custom');
+ this.modalInstance = this.modalServiceNg2.createCustomModal(interfaceDataModal);
+
+ this.modalServiceNg2.addDynamicContentToModal(
+ this.modalInstance,
+ InterfaceOperationHandlerComponent,
+ {
+ deploymentArtifactsFilePath: this.deploymentArtifactsFilePath,
+ toscaArtifactTypes: this.toscaArtifactTypes,
+ selectedInterface: interfaceModel,
+ selectedInterfaceOperation: operation,
+ validityChangedCallback: this.enableOrDisableSaveButton,
+ isViewOnly: true
+ }
+ );
+ this.modalInstance.instance.open();
+ }
+
+ private initInterfaceDefinition() {
+ this.isLoading = true;
+ this.interfaces = [];
+ this.topologyTemplateService.getComponentInterfaceOperations(this.component.componentType, this.component.uniqueId)
+ .subscribe((response) => {
+ if (response.interfaces) {
+ this.interfaces = _.map(response.interfaces, (interfaceModel) => new UIInterfaceModel(interfaceModel));
+ }
+ this.isLoading = false;
+ });
+ }
+
+ collapseAll(value: boolean = true): void {
+ _.forEach(this.interfaces, (interfaceData) => {
+ interfaceData.isCollapsed = value;
+ });
+ }
+
+ isAllCollapsed(): boolean {
+ return _.every(this.interfaces, (interfaceData) => interfaceData.isCollapsed);
+ }
+
+ isAllExpanded(): boolean {
+ return _.every(this.interfaces, (interfaceData) => !interfaceData.isCollapsed);
+ }
+
+ isInterfaceListEmpty(): boolean {
+ return this.interfaces.length === 0;
+ }
+
+ isOperationListEmpty(): boolean {
+ return _.filter(this.interfaces, (interfaceData) =>
+ interfaceData.operations && interfaceData.operations.length > 0).length > 0;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts
index 20425f810a..49f273c716 100644
--- a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts
@@ -145,6 +145,10 @@ export class TopologyTemplateService {
return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS]);
}
+ getComponentInterfaceOperations(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
+ return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS]);
+ }
+
getComponentInformationalArtifactsAndInstances(component: Component): Observable<ComponentGenericResponse> {
return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS, COMPONENT_FIELDS.COMPONENT_INSTANCES]);
}
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 58aa402b02..ab706e7088 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -292,6 +292,7 @@ export class States {
public static WORKSPACE_TOSCA_ARTIFACTS = 'workspace.tosca_artifacts';
public static WORKSPACE_COMPOSITION = 'workspace.composition';
public static WORKSPACE_INTERFACE_OPERATION = 'workspace.interface_operation';
+ public static WORKSPACE_INTERFACE_DEFINITION = 'workspace.interface-definition';
public static WORKSPACE_NETWORK_CALL_FLOW = 'workspace.network_call_flow';
public static WORKSPACE_MANAGEMENT_WORKFLOW = 'workspace.management_workflow';
public static WORKSPACE_DEPLOYMENT = 'workspace.deployment';
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view-model.ts
new file mode 100644
index 0000000000..46ba0317d9
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view-model.ts
@@ -0,0 +1,35 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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=========================================================
+*/
+'use strict';
+
+import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
+
+export interface IInterfaceDefinitionViewModelScope extends IWorkspaceViewModelScope {};
+
+export class InterfaceDefinitionViewModel {
+
+ static '$inject' = [
+ '$scope'
+ ];
+
+ constructor(private $scope: IInterfaceDefinitionViewModelScope) {}
+
+}
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view.html b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view.html
new file mode 100644
index 0000000000..4eba48871d
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition-view.html
@@ -0,0 +1,27 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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="workspace-interface-definition">
+ <interface-definition
+ [component]="component"
+ [readonly]="isViewMode() || !isDesigner()"
+ [disableMenuItems]="disableMenuItems"
+ [enableMenuItems]="enableMenuItems">
+ </interface-definition>
+</div>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition.less b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition.less
new file mode 100644
index 0000000000..ce0264e13d
--- /dev/null
+++ b/catalog-ui/src/app/view-models/workspace/tabs/interface-definition/interface-definition.less
@@ -0,0 +1,26 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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=========================================================
+*/
+.workspace-interface-definition {
+ width: 100%;
+ display: inline-block;
+ top: -26px;
+ position: relative;
+}
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index 1a79c0a6bb..1779a0a92d 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -441,6 +441,9 @@
"SERVICE_PATH_SELECTOR_SHOW_ALL_VALUE" : "⚊ Show all ⚊",
"SERVICE_OPERATION_PROPERTY_TOOLTIP_TEXT": "Service properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.",
+ "=========== INTERFACE DEFINITION ==========": "",
+ "INTERFACE_DATA_EMPTY": "No Interface data to display",
+
"=========== INTERFACE OPERATION ==========": "",
"INTERFACE_ADD_OPERATION": "Add Operation",
"INTERFACE_EXPAND_ALL": "Expand All",
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
index 834732b6f2..bac613861b 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
@@ -47,6 +47,7 @@ import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
+import org.onap.sdc.frontend.ci.tests.flow.InterfaceDefinitionFlow;
import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
import org.onap.sdc.frontend.ci.tests.pages.AttributeModal;
import org.onap.sdc.frontend.ci.tests.pages.AttributesPage;
@@ -55,9 +56,10 @@ import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInformationTab;
-import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsModal;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
@@ -115,6 +117,10 @@ public class ImportVfcUiTest extends SetupCDTest {
yamlObject = downloadToscaArtifact(componentPage);
checkMetadata(yamlObject, vfcCreateData);
checkNodeTypes(yamlObject);
+
+ componentPage = viewInterfaceDefinitionFromVFC(componentPage);
+ componentPage.isLoaded();
+
homePage.getTopNavComponent().clickOnHome();
// TC - Import VFC with interface inputs
@@ -135,6 +141,23 @@ public class ImportVfcUiTest extends SetupCDTest {
}
+ private ComponentPage viewInterfaceDefinitionFromVFC(final ComponentPage componentPage) {
+ final InterfaceDefinitionFlow interfaceDefinitionFlow = new InterfaceDefinitionFlow(webDriver);
+ interfaceDefinitionFlow.run(componentPage);
+ final InterfaceDefinitionPage interfaceDefinitionPage = interfaceDefinitionFlow.getLandedPage()
+ .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return InterfaceDefinitionPage"));
+ final var OPERATION_NAME = "create";
+ assertTrue(interfaceDefinitionPage.isInterfaceDefinitionOperationPresent(OPERATION_NAME));
+ final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal = interfaceDefinitionPage.clickOnInterfaceDefinitionOperation(
+ OPERATION_NAME);
+ interfaceDefinitionOperationsModal.isLoaded();
+ ExtentTestActions
+ .takeScreenshot(Status.INFO, "clickOnOInterfaceOperation", "Interface Definition Operation Modal opened");
+ checkInterfaceDefinitionData(interfaceDefinitionOperationsModal);
+ interfaceDefinitionOperationsModal.clickOnCancel();
+ return interfaceDefinitionPage;
+ }
+
@Test
public void importVfcWithModel() {
final String fileName = "VFC-For-Model.yaml";
@@ -146,6 +169,13 @@ public class ImportVfcUiTest extends SetupCDTest {
componentPage.isLoaded();
}
+ private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) {
+ assertTrue(interfaceDefinitionOperationsModal.getDescription().isEmpty());
+ assertEquals(interfaceDefinitionOperationsModal.getImplementationName(), "path/to/my/implementation.sh");
+ assertEquals(interfaceDefinitionOperationsModal.getInputName(), "first");
+ assertEquals(interfaceDefinitionOperationsModal.getInputValue(), "1234");
+ }
+
private ComponentPage manageAttributes(final ComponentPage componentPage) {
final AttributesPage attributesPage = componentPage.goToAttributes();
attributesPage.isLoaded();
@@ -189,7 +219,7 @@ public class ImportVfcUiTest extends SetupCDTest {
compositionInterfaceOperationsTab.isLoaded();
ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab", "Composition Interface Operations Tab opened");
assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
- CompositionInterfaceOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
+ InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
compositionInterfaceOperationsModal.isLoaded();
ExtentTestActions
.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
@@ -198,7 +228,7 @@ public class ImportVfcUiTest extends SetupCDTest {
compositionInterfaceOperationsModal.addInput();
ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.addInput", "Adding Input");
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData = new CompositionInterfaceOperationsModal.InterfaceOperationsData
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData = new InterfaceDefinitionOperationsModal.InterfaceOperationsData
("This is CREATE operation", "fullPath/to/my/newImplementation.sh", "second", "9876");
compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
compositionInterfaceOperationsTab.isLoaded();
@@ -370,8 +400,8 @@ public class ImportVfcUiTest extends SetupCDTest {
}
- private void checkCompositionInterfaceOperations(final CompositionInterfaceOperationsModal compositionInterfaceOperationsModal,
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+ private void checkCompositionInterfaceOperations(final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal,
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription());
assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName());
assertEquals(interfaceOperationsData.getInputName(), compositionInterfaceOperationsModal.getInputName());
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
index 8bec8353ef..a2dbd5729e 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
@@ -78,7 +78,7 @@ import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInformationTab;
-import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsModal;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.RelationshipWizardInterfaceOperation.InterfaceOperationsData;
@@ -247,8 +247,8 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
compositionPage.isLoaded();
ExtentTestActions.addScreenshot(Status.INFO, "select-VFC-node", "Selecting Node on composition");
compositionPage.selectNode(vfcs.get(1).getName());
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData =
- new CompositionInterfaceOperationsModal.InterfaceOperationsData("IT for updating an Interface Operation",
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
+ new InterfaceDefinitionOperationsModal.InterfaceOperationsData("IT for updating an Interface Operation",
"MyIntegrationTestImplementationName", "My_IT_InputName", "My_IT_InputValue");
updateInterfaceOperation(compositionPage, interfaceOperationsData);
componentPage = compositionPage.goToGeneral();
@@ -374,7 +374,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
* @throws IOException
*/
private void updateInterfaceOperation(final CompositionPage compositionPage,
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData) throws IOException {
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) throws IOException {
final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
detailSideBar.isLoaded();
final CompositionInterfaceOperationsTab compositionInterfaceOperationsTab =
@@ -383,7 +383,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab",
"Composition Interface Operations Tab loaded");
assertTrue(compositionInterfaceOperationsTab.isOperationPresent(interfaceOperationName));
- final CompositionInterfaceOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
+ final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
.clickOnOperation(interfaceOperationName);
compositionInterfaceOperationsModal.isLoaded();
ExtentTestActions.takeScreenshot(Status.INFO, "update-interface-operation-modal", "Loading Interface Operations Modal");
@@ -405,13 +405,13 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
* @param interfaceOperationsData The Updated Interface Definition
*/
private void validateUpdatedInterfaceOperation(final CompositionDetailSideBarComponent detailSideBar,
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
final CompositionInterfaceOperationsTab compositionInterfaceOperationsTab = (CompositionInterfaceOperationsTab) detailSideBar
.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
compositionInterfaceOperationsTab.isLoaded();
assertTrue(compositionInterfaceOperationsTab.isOperationPresent(interfaceOperationName));
assertTrue(compositionInterfaceOperationsTab.isDescriptionPresent());
- final CompositionInterfaceOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
+ final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
.clickOnOperation(interfaceOperationName);
compositionInterfaceOperationsModal.isLoaded();
ExtentTestActions.takeScreenshot(Status.INFO, "validate-updated-interface-operation",
@@ -428,7 +428,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
}
private void verifyToscaTemplateHasUpdatedInterfaceOperation(final Map<?, ?> toscaTemplateYaml,
- final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+ final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
assertNotNull(toscaTemplateYaml, "No contents in TOSCA Template");
final Map<String, Object> topologyTemplateTosca = getMapEntry((Map<String, Object>) toscaTemplateYaml, "topology_template");
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/InterfaceDefinitionFlow.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/InterfaceDefinitionFlow.java
new file mode 100644
index 0000000000..a0955ff800
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/InterfaceDefinitionFlow.java
@@ -0,0 +1,56 @@
+/*
+ * ============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=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.flow;
+
+import com.aventstack.extentreports.Status;
+import java.util.Optional;
+import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
+import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
+import org.onap.sdc.frontend.ci.tests.pages.PageObject;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * UI Flow for managing an Interface Definition from a component
+ */
+public class InterfaceDefinitionFlow extends AbstractUiTestFlow {
+
+ private InterfaceDefinitionPage interfaceDefinitionPage;
+
+ public InterfaceDefinitionFlow(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public Optional<PageObject> run(final PageObject... pageObjects) {
+ extendTest.log(Status.INFO, "Downloading Tosca CSAR generated");
+ final ComponentPage componentPage = findParameter(pageObjects, ComponentPage.class);
+ componentPage.isLoaded();
+ interfaceDefinitionPage = componentPage.goToInterfaceDefinition();
+ interfaceDefinitionPage.isLoaded();
+ ExtentTestActions.takeScreenshot(Status.INFO, "interface-definition-page", "Interface Definition page loaded");
+ return Optional.of(interfaceDefinitionPage);
+ }
+
+ @Override
+ public Optional<InterfaceDefinitionPage> getLandedPage() {
+ return Optional.ofNullable(interfaceDefinitionPage);
+ }
+}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java
index ada3410318..f690cca3f5 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java
@@ -20,6 +20,7 @@ package org.onap.sdc.frontend.ci.tests.pages;
import org.onap.sdc.frontend.ci.tests.datatypes.LifeCycleStateEnum;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
import org.onap.sdc.frontend.ci.tests.utilities.LoaderHelper;
@@ -59,6 +60,10 @@ public class ComponentPage extends AbstractPageObject {
return resourceLeftSideMenu.clickOnToscaArtifactsMenuItem();
}
+ public InterfaceDefinitionPage goToInterfaceDefinition() {
+ return resourceLeftSideMenu.clickOnInterfaceDefinitionMenuItem();
+ }
+
public CompositionPage goToComposition() {
return resourceLeftSideMenu.clickOnCompositionMenuItem();
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java
index f0a973910f..68a447eadf 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java
@@ -22,6 +22,7 @@ package org.onap.sdc.frontend.ci.tests.pages;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
@@ -95,6 +96,16 @@ public class ResourceLeftSideMenu extends AbstractPageObject {
}
/**
+ * Clicks on the Interface Definition menu item.
+ *
+ * @return the next page object
+ */
+ public InterfaceDefinitionPage clickOnInterfaceDefinitionMenuItem() {
+ wrappingElement.findElement(By.xpath(XpathSelector.INTERFACE_DEFINITION_MENU.getXpath())).click();
+ return new InterfaceDefinitionPage(webDriver);
+ }
+
+ /**
* Clicks on the 'General' menu item.
*
* @return the next page object
@@ -127,7 +138,8 @@ public class ResourceLeftSideMenu extends AbstractPageObject {
GENERAL_MENU("GeneralLeftSideMenu", "//*[@data-tests-id='%s']"),
COMPOSITION_MENU("CompositionLeftSideMenu", "//*[@data-tests-id='%s']"),
REQUIREMENT_CAPABILITY_MENU("Req. & CapabilitiesLeftSideMenu", "//*[@data-tests-id='%s']"),
- TOSCA_ARTIFACTS_MENU("TOSCA ArtifactsLeftSideMenu", "//*[@data-tests-id='%s']");
+ TOSCA_ARTIFACTS_MENU("TOSCA ArtifactsLeftSideMenu", "//*[@data-tests-id='%s']"),
+ INTERFACE_DEFINITION_MENU("InterfacesLeftSideMenu", "//*[@data-tests-id='%s']");
@Getter
private final String id;
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java
index c67293939e..60a732afd5 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java
@@ -19,8 +19,6 @@
package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
@@ -66,10 +64,10 @@ public class CompositionInterfaceOperationsTab extends AbstractPageObject {
}
}
- public CompositionInterfaceOperationsModal clickOnOperation(final String operationName) {
+ public InterfaceDefinitionOperationsModal clickOnOperation(final String operationName) {
final WebElement webElementInterfaceRow = webElement.findElement(By.xpath(XpathSelector.INTERFACE_ROW.getXPath()));
webElementInterfaceRow.findElement(By.xpath(XpathSelector.FIELD_NAME_SPAN.getXPath(operationName))).click();
- return new CompositionInterfaceOperationsModal(webDriver);
+ return new InterfaceDefinitionOperationsModal(webDriver);
}
@AllArgsConstructor
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java
index 8fac69c944..cb2ee3d282 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java
@@ -31,9 +31,9 @@ import org.openqa.selenium.WebElement;
/**
* Represents the Composition Interface Operations Modal.
*/
-public class CompositionInterfaceOperationsModal extends AbstractPageObject {
+public class InterfaceDefinitionOperationsModal extends AbstractPageObject {
- public CompositionInterfaceOperationsModal(final WebDriver webDriver) {
+ public InterfaceDefinitionOperationsModal(final WebDriver webDriver) {
super(webDriver);
}
@@ -44,9 +44,8 @@ public class CompositionInterfaceOperationsModal extends AbstractPageObject {
waitForElementVisibility(By.xpath(XpathSelector.OPERATION_NAME_LABEL.getXPath()));
waitForElementVisibility(By.xpath(XpathSelector.INPUT_NAME_SPAN.getXPath()));
waitForElementVisibility(By.xpath(XpathSelector.INPUT_VALUE_SPAN.getXPath()));
-
- waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath()));
- waitToBeClickable(By.xpath(XpathSelector.SAVE_BTN.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.SAVE_BTN.getXPath()));
waitToBeClickable(By.xpath(XpathSelector.CANCEL_BTN.getXPath()));
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionPage.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionPage.java
new file mode 100644
index 0000000000..a40878ac14
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionPage.java
@@ -0,0 +1,96 @@
+/*
+ * ============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=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+public class InterfaceDefinitionPage extends ComponentPage {
+
+ private WebElement wrappingElement;
+
+ public InterfaceDefinitionPage(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public void isLoaded() {
+ wrappingElement = waitForElementVisibility(By.xpath(XpathSelector.MAIN_DIV.getXpath()), 5);
+ waitForElementVisibility(By.xpath(XpathSelector.TITLE_DIV.getXpath()), 5);
+ waitForElementVisibility(By.xpath(XpathSelector.INTERFACE_NAME_SPAN.getXpath()), 5);
+ }
+
+ public boolean isInterfaceDefinitionOperationPresent(final String operationName) {
+ try {
+ final WebElement webElementInterfaceRow = wrappingElement.findElement(
+ By.xpath(InterfaceDefinitionPage.XpathSelector.INTERFACE_ROW.getXpath()));
+ webElementInterfaceRow.findElement(By.xpath(InterfaceDefinitionPage.XpathSelector.FIELD_NAME_SPAN.getXpath(operationName)));
+ } catch (final Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ public InterfaceDefinitionOperationsModal clickOnInterfaceDefinitionOperation(final String operationName) {
+ final WebElement webElementInterfaceRow = wrappingElement.findElement(
+ By.xpath(InterfaceDefinitionPage.XpathSelector.INTERFACE_ROW.getXpath()));
+ webElementInterfaceRow.findElement(By.xpath(InterfaceDefinitionPage.XpathSelector.FIELD_NAME_SPAN.getXpath(operationName))).click();
+ return new InterfaceDefinitionOperationsModal(webDriver);
+ }
+
+ /**
+ * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+ */
+ @AllArgsConstructor
+ private enum XpathSelector {
+ MAIN_DIV("w-sdc-main-right-container", "//div[@class='%s']"),
+ TITLE_DIV("tab-title", "//div[contains(@class,'%s') and contains(text(), 'Interfaces')]"),
+ INTERFACE_NAME_SPAN("//span[@class='interface-name']"),
+
+ INTERFACE_OPERATIONS("//div[@class='interface-operations']"),
+ OPERATION_LIST("//div[@class='operation-list']"),
+ EXPAND_COLLAPSE("//div[@class='expand-collapse']"),
+ INTERFACE_ACCORDION("//div[@class='interface-accordion']"),
+ INTERFACE_ROW("//div[contains(@class,'interface-row')]"),
+ FIELD_NAME_SPAN("//span[contains(@class,'field-name') and contains(text(), '%s')]"),
+ FIELD_DESCRIPTION_SPAN("//span[contains(@class,'field-description')]");
+
+ @Getter
+ private String id;
+ private final String xpathFormat;
+
+ XpathSelector(final String xpathFormat) {
+ this.xpathFormat = xpathFormat;
+ }
+
+ public String getXpath() {
+ return String.format(xpathFormat, id);
+ }
+
+ public String getXpath(final String... params) {
+ return String.format(xpathFormat, params);
+ }
+
+ }
+}