aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui
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 /catalog-ui
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
Diffstat (limited to 'catalog-ui')
-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);
}