aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimamSidero <imam.hussain@est.tech>2023-08-24 11:48:06 +0100
committerMichael Morris <michael.morris@est.tech>2023-09-04 14:21:30 +0000
commit0c47a1b7118b45eecbbb0064b635efb026173ec4 (patch)
tree863e35ed75b70a5f27f632b95bf8d7b38c437d72
parentb945edb543cc7283908a019bd8859ad936572e86 (diff)
Provide UI page for interface assignment in service for VFC instances
Support for interface assignment page for VFC instances is provided in service instances Issue-ID: SDC-4602 Signed-off-by: Imam hussain <imam.hussain@est.tech> Change-Id: I4cabef02db381278d37d21da981d3ec4c04e5967
-rw-r--r--catalog-ui/configurations/menu.js1
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.module.ts2
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.html131
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.less96
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-definition/interface-definition.page.component.ts81
-rw-r--r--catalog-ui/src/app/ng2/services/component-services/component.service.ts4
6 files changed, 246 insertions, 69 deletions
diff --git a/catalog-ui/configurations/menu.js b/catalog-ui/configurations/menu.js
index a5114d857a..54c1b63d7d 100644
--- a/catalog-ui/configurations/menu.js
+++ b/catalog-ui/configurations/menu.js
@@ -297,6 +297,7 @@ const SDC_MENU_CONFIG = {
{"text": "Network Call Flow ", "action": "onMenuItemPressed", "state": "workspace.network_call_flow"},
{"text": "Distribution","action": "onMenuItemPressed","state": "workspace.distribution","disabledRoles": ["ADMIN"]},
{"text": "Deployment", "action": "onMenuItemPressed", "state": "workspace.deployment"},
+ {"text": "Interfaces Assignment", "action": "onMenuItemPressed", "state": "workspace.interface-definition"},
{"text": "Properties Assignment", "action": "onMenuItemPressed", "state": "workspace.properties_assignment"},
{"text": "Attributes & Outputs", "action": "onMenuItemPressed", "state": "workspace.attributes_outputs"}
],
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
index 27a7f111d2..ea6279ec87 100644
--- 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
@@ -24,6 +24,7 @@ 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 {HierarchyNavigationModule} from "../../components/logic/hierarchy-navigtion/hierarchy-navigation.module";
import {InterfaceOperationHandlerModule} from "../composition/interface-operatons/operation-creator/interface-operation-handler.module";
@NgModule({
@@ -34,6 +35,7 @@ import {InterfaceOperationHandlerModule} from "../composition/interface-operaton
CommonModule,
SdcUiComponentsModule,
UiElementsModule,
+ HierarchyNavigationModule,
TranslateModule,
InterfaceOperationHandlerModule
],
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
index bf36df0593..15fe65a784 100644
--- 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
@@ -19,73 +19,92 @@
-->
<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 class="left-column">
+ <div *ngIf="isInterfaceListEmpty()">
+ <div class="interface-empty-msg">
+ <div>{{ 'INTERFACE_DATA_EMPTY' | translate }}</div>
+ </div>
</div>
- </div>
- <div
- class="top-add-btn add-btn"
- [ngClass]="{'disabled': readonly}"
- data-tests-id="add-operation"
- (click)="onSelectInterfaceOperation(undefined, undefined)">
+ <div class="top-add-btn add-btn" [ngClass]="{'disabled': readonly}" *ngIf="!component.isService()" data-tests-id="add-operation" (click)="onSelectInterfaceOperation(undefined, undefined)">
{{ 'INTERFACE_ADD_OPERATION' | translate }}
- </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 interface1 of interfaces">
- <div class="interface-accordion" (click)="interface1.toggleCollapse()">
- <span
- class="chevron-container"
- [ngClass]="{'isCollapsed': interface1.isCollapsed}"
- *ngIf="isOperationListEmpty()">
- <svg-icon
- name="caret1-down-o"
- mode="primary"
- size="small">
- </svg-icon>
- </span>
- <span class="interface-name">{{interface1.type}}</span>
+ </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="generic-table" *ngIf="!interface1.isCollapsed && isOperationListEmpty()">
- <div class="header-row table-row">
+ <div class="interface-row" *ngFor="let interface1 of interfaces">
+ <div class="interface-accordion" (click)="interface1.toggleCollapse()">
<span
- class="cell header-cell field-name header-name">
- {{ 'INTERFACE_HEADER_NAME' | translate }}
+ class="chevron-container"
+ [ngClass]="{'isCollapsed': interface1.isCollapsed}"
+ *ngIf="isOperationListEmpty()">
+ <svg-icon
+ name="caret1-down-o"
+ mode="primary"
+ size="small">
+ </svg-icon>
</span>
- <span class="cell header-cell field-description header-description">
- {{ 'INTERFACE_HEADER_DESCRIPTION' | translate }}
- </span>
- <span class="cell field-delete" *ngIf="!readonly"><span class="delete-col-header"></span></span>
+ <span class="interface-name">{{interface1.type}}</span>
</div>
- <div class="data-row" *ngFor="let operation of interface1.operations">
- <span class="cell field-name"
- (click)="onSelectInterfaceOperation(interface1, operation)">{{operation.name}}</span>
- <span class="cell field-description" (click)="onSelectInterfaceOperation(interface1, operation)"
- [ngClass]="{'collapsed': operation.isCollapsed}">{{operation.getDescriptionEllipsis()}}
- <span class="more-or-less link" (click)="operation.toggleCollapsed($event)">
- {{!operation.isEllipsis ? '' : operation.isCollapsed ? 'More' : 'Less'}}
+
+ <div class="generic-table" *ngIf="!interface1.isCollapsed && isOperationListEmpty()">
+ <div class="header-row table-row">
+ <span
+ class="cell header-cell field-name header-name">
+ {{ 'INTERFACE_HEADER_NAME' | translate }}
</span>
- </span>
- <span class="cell field-delete" *ngIf="!readonly">
- <button class="table-delete-btn" (click)="onRemoveOperation(operation)"></button>
- </span>
+ <span class="cell header-cell field-description header-description">
+ {{ 'INTERFACE_HEADER_DESCRIPTION' | translate }}
+ </span>
+ <span class="cell field-delete" *ngIf="!readonly"><span class="delete-col-header"></span></span>
+ </div>
+ <div class="data-row" *ngFor="let operation of interface1.operations">
+ <span class="cell field-name"
+ (click)="onSelectInterfaceOperation(interface1, operation)">{{operation.name}}</span>
+ <span class="cell field-description" (click)="onSelectInterfaceOperation(interface1, operation)"
+ [ngClass]="{'collapsed': operation.isCollapsed}">{{operation.getDescriptionEllipsis()}}
+ <span class="more-or-less link" (click)="operation.toggleCollapsed($event)">
+ {{!operation.isEllipsis ? '' : operation.isCollapsed ? 'More' : 'Less'}}
+ </span>
+ </span>
+ <span class="cell field-delete" *ngIf="!readonly">
+ <button class="table-delete-btn" (click)="onRemoveOperation(operation)"></button>
+ </span>
+ </div>
</div>
</div>
</div>
</div>
</div>
+ <div class="right-column" *ngIf="component.isService()">
+ <div class="add-btn" [ngClass]="{'disabled': disableFlag}" data-tests-id="add-operation" (click)="onSelectInterfaceOperation(undefined, undefined)">
+ {{ 'INTERFACE_ADD_OPERATION' | translate }}
+ </div>
+ <tabs #hierarchyNavTabs tabStyle="simple-tabs" class="gray-border">
+ <tab tabTitle="Composition">
+ <div class="hierarchy-nav-container">
+ <loader [display]="loadingInstances" [size]="'medium'" [relative]="true" [loaderDelay]="500"></loader>
+ <div class="hierarchy-header white-sub-header">
+ <span tooltip="{{component.name}}">{{component.name}}</span>
+ </div>
+ <div *ngIf="!instancesNavigationData || instancesNavigationData.length === 0">No data to display</div>
+ <hierarchy-navigation class="hierarchy-nav"
+ (updateSelected)="onInstanceSelectedUpdate($event)"
+ [displayData]="instancesNavigationData"
+ [selectedItem]="selectedInstanceData?.uniqueId"
+ [displayOptions]="hierarchyInstancesDisplayOptions"></hierarchy-navigation>
+ </div>
+ </tab>
+ </tabs>
+ </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
index 464732e016..67e2dae2e1 100644
--- 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
@@ -23,7 +23,9 @@
@import '../../../../assets/styles/sprite-old.less';
.interface-definition {
font-size: 14px;
-
+ display:flex;
+ flex-direction:row;
+ height: 100%;
.delete-col-header{
.sprite;
.sprite.e-sdc-small-icon-delete;
@@ -53,14 +55,6 @@
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;
@@ -79,7 +73,7 @@
.operation-list {
border-top: 1px solid @main_color_o;
padding-top: 5px;
-
+
.empty-list-container {
width: 100%;
display: flex;
@@ -250,4 +244,86 @@
}
}
+ .left-column {
+ flex: 1 0 500px;
+ position: relative;
+ min-width:930px;
+ }
+ .right-column {
+ display:flex;
+ flex:0 0 350px;
+ flex-direction:column;
+ margin: 0px 0 0 1em;
+ overflow-x:auto;
+ .add-btn{
+ align-self: flex-end;
+ margin-top: 10px;
+ margin-bottom: 19px;
+ }
+ /deep/ .tabs {
+ border-bottom: solid 1px #d0d0d0;
+ }
+
+ /deep/ .tab {
+ flex: none;
+ padding: 8px 20px 0;
+ font-size: 14px;
+ line-height:30px;
+ font-family: @font-opensans-regular;
+
+ &.active {
+ font-family: @font-opensans-medium;
+ }
+ }
+ }
+
+ .hierarchy-tabs {
+ flex: 0 0 40px;
+ }
+
+ .gray-border {
+ border: 1px solid #ddd;
+ }
+
+ /deep/ .white-sub-header {
+ background-color: #fffefe;
+ box-shadow: 0px 1px 0.99px 0.01px rgba(34, 31, 31, 0.15);
+ border-bottom: #d2d2d2 solid 1px;
+ font-size:14px;
+ text-align:left;
+ flex:0 0 auto;
+ padding: 10px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ text-transform: uppercase;
+
+ &.hierarchy-header {
+ padding-left:20px;
+ &.selected {
+ background-color: #e6f6fb;
+ }
+ }
+
+ }
+
+ .hierarchy-header {
+
+ span{
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ max-width: 290px;
+ }
+ }
+
+ .hierarchy-nav {
+ flex:1;
+ overflow:auto;
+ display: grid;
+ margin-top: 1em;
+ margin-left: 1em;
+ font-size: 12px;
+ padding-top: 1em;
+ }
}
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
index 90d6a6cfde..23c855ecb1 100644
--- 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
@@ -21,7 +21,7 @@
import {Component, ComponentRef, Inject, Input} from '@angular/core';
import {Component as IComponent} from 'app/models/components/component';
import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
-
+import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
import {ISdcConfig, SdcConfigToken} from "app/ng2/config/sdc-config.config";
import {TranslateService} from "app/ng2/shared/translator/translate.service";
import {IModalButtonComponent, SdcUiServices} from 'onap-ui-angular';
@@ -34,6 +34,7 @@ import {
CapabilitiesGroup,
InputBEModel,
InterfaceModel,
+ ComponentInstance,
ModalModel,
OperationModel,
WORKFLOW_ASSOCIATION_OPTIONS
@@ -49,6 +50,7 @@ import {ToscaArtifactService} from "../../services/tosca-artifact.service";
import {InterfaceOperationComponent} from "../interface-operation/interface-operation.page.component";
import {Observable} from "rxjs/Observable";
import {PluginsService} from 'app/ng2/services/plugins.service';
+import { InstanceFeDetails } from 'app/models/instance-fe-details';
export class UIOperationModel extends OperationModel {
isCollapsed: boolean = true;
@@ -132,6 +134,13 @@ export class InterfaceDefinitionComponent {
interfaces: UIInterfaceModel[];
inputs: InputBEModel[];
+ instancesNavigationData = [];
+ instances: any = [];
+ loadingInstances: boolean = false;
+ selectedInstanceData: any = null;
+ hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
+ disableFlag : boolean = true;
+
deploymentArtifactsFilePath: Array<DropdownValue> = [];
toscaArtifactTypes: Array<DropdownValue> = [];
@@ -148,6 +157,7 @@ export class InterfaceDefinitionComponent {
enableWorkflowAssociation: boolean;
workflowIsOnline: boolean;
validImplementationProps:boolean = true;
+ serviceInterfaces: InterfaceModel[];
@Input() component: IComponent;
@Input() readonly: boolean;
@@ -176,21 +186,39 @@ export class InterfaceDefinitionComponent {
ngOnInit(): void {
this.isLoading = true;
this.interfaces = [];
+ //this.disableFlag = this.readonly;
this.workflowIsOnline = !_.isUndefined(this.PluginsService.getPluginByStateUrl('workflowDesigner'));
Observable.forkJoin(
this.ComponentServiceNg2.getInterfaceOperations(this.component),
this.ComponentServiceNg2.getComponentInputs(this.component),
this.ComponentServiceNg2.getInterfaceTypes(this.component),
- this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.component.componentType, this.component.uniqueId)
+ this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.component.componentType, this.component.uniqueId),
+ this.componentServiceNg2.getComponentResourcePropertiesData(this.component)
).subscribe((response: any[]) => {
const callback = (workflows) => {
this.isLoading = false;
+ this.serviceInterfaces = response[0].interfaces;
this.initInterfaces(response[0].interfaces);
this.sortInterfaces();
this.inputs = response[1].inputs;
this.interfaceTypes = response[2];
this.workflows = (workflows.items) ? workflows.items : workflows;
this.capabilities = response[3].capabilities;
+ this.instances = response[4].componentInstances;
+ const serviceInstance = new ComponentInstance();
+ serviceInstance.name = "SELF";
+ serviceInstance.uniqueId = this.component.uniqueId;
+ if (this.instances != null) {
+ this.instances.unshift(serviceInstance);
+ } else {
+ this.instances = [serviceInstance];
+ }
+ _.forEach(this.instances, (instance) => {
+ this.instancesNavigationData.push(instance);
+ });
+ this.onInstanceSelectedUpdate(this.instancesNavigationData[0]);
+ this.loadingInstances = false;
+
};
if (this.enableWorkflowAssociation && this.workflowIsOnline) {
this.WorkflowServiceNg2.getWorkflows().subscribe(
@@ -204,9 +232,55 @@ export class InterfaceDefinitionComponent {
callback([]);
}
});
+
this.loadToscaArtifacts();
}
+ onInstanceSelectedUpdate = (instance: any) => {
+ this.selectedInstanceData = instance;
+ if (instance.name != "SELF") {
+ this.disableFlag = true;
+ let newInterfaces : InterfaceModel[] = [];
+ if (instance.interfaces instanceof Array) {
+ instance.interfaces.forEach(result => {
+ let interfaceObj = new InterfaceModel();
+ interfaceObj.type = result.type;
+ interfaceObj.uniqueId = result.uniqueId;
+ if (result.operations instanceof Array) {
+ interfaceObj.operations = result.operations;
+ } else if (!_.isEmpty(result.operations)) {
+ interfaceObj.operations = [];
+ Object.keys(result.operations).forEach(name => {
+ interfaceObj.operations.push(result.operations[name]);
+ });
+ }
+ newInterfaces.push(interfaceObj);
+ });
+ } else {
+ Object.keys(instance.interfaces).forEach(key => {
+ let obj = instance.interfaces[key];
+ let interfaceObj = new InterfaceModel();
+ interfaceObj.type = obj.type;
+ interfaceObj.uniqueId = obj.uniqueId;
+ if (obj.operations instanceof Array) {
+ interfaceObj.operations = obj.operations;
+ } else if (!_.isEmpty(obj.operations)) {
+ interfaceObj.operations = [];
+ Object.keys(obj.operations).forEach(name => {
+ interfaceObj.operations.push(obj.operations[name]);
+ });
+ }
+ newInterfaces.push(interfaceObj);
+ });
+ }
+ this.interfaces = newInterfaces.map((interf) => new UIInterfaceModel(interf));
+ } else {
+ //this.disableFlag = this.readonly;
+ this.interfaces = this.serviceInterfaces.map((interf) => new UIInterfaceModel(interf));
+ }
+ this.sortInterfaces();
+ }
+
initInterfaces(interfaces: InterfaceModel[]): void {
if (interfaces) {
this.interfaces = interfaces.map((interf) => new UIInterfaceModel(interf));
@@ -222,6 +296,9 @@ export class InterfaceDefinitionComponent {
if(this.readonly) {
return disable;
}
+ if (this.component.isService()) {
+ return disable;
+ }
let selectedInterfaceOperation = this.modalInstance.instance.dynamicContent.instance.selectedInterfaceOperation;
let isInterfaceOperation:boolean = !(typeof selectedInterfaceOperation == 'undefined' || _.isEmpty(selectedInterfaceOperation));
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index 450e66ead2..eca70bee5f 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -114,7 +114,7 @@ export class ComponentServiceNg2 {
}
getComponentResourcePropertiesData(component: Component): Observable<ComponentGenericResponse> {
- return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
}
getComponentResourceAttributesData(component: Component): Observable<ComponentGenericResponse> {
@@ -157,6 +157,8 @@ export class ComponentServiceNg2 {
return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS]);
}
+
+
getInterfaceOperation(component: Component, operation: OperationModel): Observable<OperationModel> {
return this.http.get<OperationModel>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId);
}