bugfix for operations screen 46/104646/1 1.6.4
authorilanap <ilanap@amdocs.com>
Wed, 1 Apr 2020 11:25:35 +0000 (14:25 +0300)
committerOfir Sonsino <ofir.sonsino@intl.att.com>
Wed, 1 Apr 2020 12:04:02 +0000 (12:04 +0000)
Add Operation Button is missing in Service management
committing fix by Akiva

Issue-ID: SDC-2843
Signed-off-by: ilanap <ilanap@amdocs.com>
Change-Id: I9a6c89e45ea425eb9abf827906562e14a39cf1ff

catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
catalog-ui/src/app/utils/constants.ts
catalog-ui/webpack.server.js

index 9d41c37..4f93e72 100644 (file)
@@ -1,5 +1,5 @@
 import * as _ from "lodash";
-import { Component, Input, Output, ComponentRef, Inject } from '@angular/core';
+import { Component, Input, Inject } from '@angular/core';
 import {Component as IComponent } from 'app/models/components/component';
 
 import { SdcConfigToken, ISdcConfig } from "app/ng2/config/sdc-config.config";
@@ -7,7 +7,7 @@ import {TranslateService } from "app/ng2/shared/translator/translate.service";
 
 import {Observable } from "rxjs/Observable";
 
-import {ModalComponent } from 'app/ng2/components/ui/modal/modal.component';
+import { ModalComponent } from 'onap-ui-angular/dist/modals/modal.component';
 import {ModalService } from 'app/ng2/services/modal.service';
 import {
     InputBEModel,
@@ -118,7 +118,7 @@ export class UIInterfaceModel extends InterfaceModel {
 export class InterfaceOperationComponent {
 
     interfaces: UIInterfaceModel[];
-    modalInstance: ComponentRef<ModalComponent>;
+    modalInstance: ModalComponent;
     openOperation: OperationModel;
     enableWorkflowAssociation: boolean;
     inputs: InputBEModel[];
@@ -152,7 +152,6 @@ export class InterfaceOperationComponent {
     ngOnInit(): void {
         this.isLoading = true;
         this.workflowIsOnline = !_.isUndefined(this.PluginsService.getPluginByStateUrl('workflowDesigner'));
-
         Observable.forkJoin(
             this.ComponentServiceNg2.getInterfaceOperations(this.component),
             this.ComponentServiceNg2.getComponentInputs(this.component),
@@ -165,7 +164,7 @@ export class InterfaceOperationComponent {
                 this.sortInterfaces();
                 this.inputs = response[1].inputs;
                 this.interfaceTypes = response[2];
-                this.workflows = workflows;
+                this.workflows = (workflows.items) ? workflows.items: workflows;
                 this.capabilities = response[3].capabilities;
             };
             if (this.enableWorkflowAssociation && this.workflowIsOnline) {
@@ -216,7 +215,7 @@ export class InterfaceOperationComponent {
     }
 
     getDisabled = (): boolean => {
-        return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+        return !this.modalInstance.innerModalContent.instance.checkFormValidForSubmit();
     }
 
     onEditOperation = (operation?: OperationModel): void => {
@@ -260,7 +259,7 @@ export class InterfaceOperationComponent {
             size: 'small',
             closeModal: true,
             callback: () => {
-                const modalInstance = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance;
+                const modalInstance = this.modalInstance.innerModalContent.instance;
 
                 const {operation, isUsingExistingWF, createParamLists} = modalInstance;
                 createParamLists();
@@ -295,38 +294,54 @@ export class InterfaceOperationComponent {
             buttons: [saveButton, cancelButton] as IModalButtonComponent[]
         };
 
-        this.ModalServiceSdcUI.openCustomModal(modalConfig, OperationCreatorComponent, input);
-
+        this.modalInstance = this.ModalServiceSdcUI.openCustomModal(modalConfig, OperationCreatorComponent, input);
     }
 
     onRemoveOperation = (event: Event, operation: OperationModel): void => {
         event.stopPropagation();
 
-        const confirmCallback = () => {
-            this.ComponentServiceNg2
-                .deleteInterfaceOperation(this.component, operation)
-                .subscribe(() => {
-                    const curInterf = _.find(this.interfaces, (interf) => interf.type === operation.interfaceType);
-                    const index = _.findIndex(curInterf.operations, (el) => el.uniqueId === operation.uniqueId);
-                    curInterf.operations.splice(index, 1);
-                    if (!curInterf.operations.length) {
-                        const interfIndex = _.findIndex(this.interfaces, (interf) => interf.type === operation.interfaceType);
-                        this.interfaces.splice(interfIndex, 1);
-                    }
-                });
-        }
+        const deleteButton: IModalButtonComponent = {
+            id: 'deleteButton',
+            text: this.modalTranslation.DELETE_BUTTON,
+            type: 'primary',
+            size: 'small',
+            closeModal: true,
+            callback: () => {
+                this.ComponentServiceNg2
+                    .deleteInterfaceOperation(this.component, operation)
+                    .subscribe(() => {
+                        const curInterf = _.find(this.interfaces, (interf) => interf.type === operation.interfaceType);
+                        const index = _.findIndex(curInterf.operations, (el) => el.uniqueId === operation.uniqueId);
+                        curInterf.operations.splice(index, 1);
+                        if (!curInterf.operations.length) {
+                            const interfIndex = _.findIndex(this.interfaces, (interf) => interf.type === operation.interfaceType);
+                            this.interfaces.splice(interfIndex, 1);
+                        }
+                    });
+            }
+        };
+
+        const cancelButton: IModalButtonComponent = {
+            id: 'cancelButton',
+            text: this.modalTranslation.CANCEL_BUTTON,
+            type: 'secondary',
+            size: 'small',
+            closeModal: true,
+            callback: () => {
+                this.openOperation = null;
+            },
+        };
 
-        this.ModalServiceSdcUI.openAlertModal(
+        this.ModalServiceSdcUI.openWarningModal(
             this.modalTranslation.DELETE_TITLE,
             this.modalTranslation.deleteText(operation.name),
-            this.modalTranslation.DELETE_BUTTON,
-            confirmCallback,
-            'deleteOperationModal'
+            'deleteOperationModal',
+            [deleteButton, cancelButton],
         );
     }
 
     private enableOrDisableSaveButton = (shouldEnable: boolean): void => {
-        const saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton');
+        const saveButton = this.modalInstance.getButtonById('saveButton');
         saveButton.disabled = !shouldEnable;
     }
 
index df2a505..60cb1d4 100644 (file)
@@ -25,7 +25,7 @@
                     label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
                     [required]="true"
                     testId="interface-name"
-                    selectedOption="{{operation.interfaceType}}"
+                    [selectedOption]="getSelectedDropdown(interfaceNames, operation.interfaceType)"
                     placeHolder="Select..."
                     [disabled]="readonly"
                     (changed)="onSelectInterface($event)"
 
             <div class="form-item" *ngIf="!isInterfaceOther()">
                 <sdc-dropdown
+                    #operationNamesDropdown
                     label="{{ 'OPERATION_NAME' | translate }}"
                     [required]="true"
                     testId="operation-name"
-                    selectedOption="{{operation.name}}"
+                    [selectedOption]="getSelectedDropdown(operationNames, operation.name)"
                     placeHolder="Select..."
                     [disabled]="readonly"
                     (changed)="onSelectOperationName($event)"
         <div class="side-by-side" *ngIf="enableWorkflowAssociation">
             <div class="form-item">
                 <sdc-dropdown
+                    #workflowAssignmentDropdown
                     label="{{ 'OPERATION_WORKFLOW_ASSIGNMENT' | translate }}"
                     placeHolder="Select..."
                     testId="association-type"
-                    selectedOption="{{workflowAssociationType}}"
+                    [selectedOption]="toDropDownOption(workflowAssociationType)"
                     [options]="associationOptions"
                     (changed)="toggleAssociateWorkflow($event)"
                     [disabled]="readonly">
                 <sdc-dropdown
                     placeHolder="Select..."
                     testId="associated-workflow"
-                    selectedOption="{{operation.workflowId}}"
+                    [selectedOption]="getSelectedDropdown(workflows, operation.workflowId)"
                     [options]="workflows"
                     (changed)="onSelectWorkflow($event)"
                     [disabled]="readonly || !workflows.length || !workflowIsOnline">
                     *ngIf="workflowIsOnline && workflows.length"
                     label="{{ 'OPERATION_WORKFLOW_VERSION' | translate }}"
                     testId="associated-workflow-version"
-                    selectedOption="{{operation.workflowVersionId}}"
+                    [selectedOption]="getSelectedDropdown(workflowVersions, operation.workflowVersionId)"
                     [options]="workflowVersions"
                     (changed)="changeWorkflowVersion($event)"
                     [disabled]="!operation.workflowId || archivedWorkflowId === operation.workflowId || readonly">
index 12fba24..23b6781 100644 (file)
@@ -10,14 +10,15 @@ import {
     OperationModel,
     OperationParameter,
     InputBEModel,
-    RadioButtonModel,
     WORKFLOW_ASSOCIATION_OPTIONS,
     Capability
 } from 'app/models';
 
-import {Tabs, Tab} from "app/ng2/components/ui/tabs/tabs.component";
-import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
+import { Tabs } from "app/ng2/components/ui/tabs/tabs.component";
+import { DropdownValue } from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
 import { IDropDownOption } from 'onap-ui-angular';
+import { DropDownComponent } from "onap-ui-angular/dist/components";
+import { DROPDOWN_OPTION_TYPE } from "app/utils/constants";
 
 export class DropDownOption implements IDropDownOption {
     value: string;
@@ -30,9 +31,9 @@ export class DropDownOption implements IDropDownOption {
 }
 
 class TypedDropDownOption extends DropDownOption {
-    type: number;
+    type: string;
 
-    constructor(value: string, label?: string, type?: number) {
+    constructor(value: string, label?: string, type?: string) {
         super(value, label);
         this.type = type;
     }
@@ -106,6 +107,8 @@ export class OperationCreatorComponent implements OperationCreatorInput {
     INTERFACE_OTHER = 'Local';
 
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
+    @ViewChild('operationNamesDropdown') operationNamesDropdown: DropDownComponent;
+    @ViewChild('workflowAssignmentDropdown') workflowAssignmentDropdown: DropDownComponent;
     currentTab: String;
 
     constructor(private workflowServiceNg2: WorkflowServiceNg2, private translateService: TranslateService) {
@@ -117,7 +120,7 @@ export class OperationCreatorComponent implements OperationCreatorInput {
                 new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
             ];
 
-            this.workflowAssociationType = this.operation.workflowAssociationType || WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL;
+            this.workflowAssociationType = this.operation.workflowAssociationType;
         });
 
         this.currentTab = this.TYPE_INPUT;
@@ -137,13 +140,12 @@ export class OperationCreatorComponent implements OperationCreatorInput {
             _.keys(this.interfaceTypes),
             type => this.createInterfaceDropdown(type)
         );
-        this.interfaceNames.unshift(new TypedDropDownOption('Existing Interfaces', 'Existing Interfaces', 1));
+        this.interfaceNames.unshift(new TypedDropDownOption('Existing Interfaces', 'Existing Interfaces', DROPDOWN_OPTION_TYPE.HEADER));
         this.interfaceNames = this.interfaceNames.concat([
-            new TypedDropDownOption(' ', ' ', 3),
-            new TypedDropDownOption(this.INTERFACE_OTHER_HEADER, this.INTERFACE_OTHER_HEADER, 1),
+            new TypedDropDownOption(' ', ' ', DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE),
+            new TypedDropDownOption(this.INTERFACE_OTHER_HEADER, this.INTERFACE_OTHER_HEADER, DROPDOWN_OPTION_TYPE.HEADER),
             new TypedDropDownOption(this.INTERFACE_OTHER)
         ]);
-
         const inputOperation = this.inputOperation;
         this.operation = new OperationModel(inputOperation || {});
 
@@ -187,6 +189,17 @@ export class OperationCreatorComponent implements OperationCreatorInput {
         this.updateTable();
     }
 
+    ngAfterViewInit() {
+        if(this.workflowAssignmentDropdown){
+            this.workflowAssignmentDropdown.allOptions = this.associationOptions && this.associationOptions.length ?
+                this.associationOptions :
+                [
+                    new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL, this.translateService.translate("EXTERNAL_WORKFLOW_ASSOCIATION")),
+                    new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
+                ];
+        }
+    }
+
     reconstructOperation = () => {
 
         const buildAndUpdate = () => {
@@ -280,11 +293,14 @@ export class OperationCreatorComponent implements OperationCreatorInput {
                         curInterf && curInterf.operations || [],
                         op => op.name === name
                     );
-                    const ddType = (existingOp && existingOp.uniqueId !== this.operation.uniqueId) ? 2 : 0;
+                    const ddType = (existingOp && existingOp.uniqueId !== this.operation.uniqueId) ? DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE : DROPDOWN_OPTION_TYPE.SIMPLE;
                     return new TypedDropDownOption(name, name, ddType);
                 }
             )
         );
+        if(this.operationNamesDropdown) {
+            this.operationNamesDropdown.allOptions = <IDropDownOption[]>this.operationNames;
+        }
         this.validityChanged();
     }
 
@@ -522,4 +538,12 @@ export class OperationCreatorComponent implements OperationCreatorInput {
         this.validityChangedCallback(validState);
     }
 
+    getSelectedDropdown(options: DropdownValue[], selectedValue: string): DropdownValue {
+        const selectedDropdown = _.find(options, (option) => option.value === selectedValue);
+        return selectedDropdown || this.toDropDownOption(null);
+    }
+
+    toDropDownOption(val: string) {
+        return { value : val, label: val };
+    }
 }
index de6e703..76cf73f 100644 (file)
@@ -98,6 +98,7 @@ export class ParamRowComponent {
             ),
             prop => new DropdownValue(prop.uniqueId, prop.name)
         );
+        this.filteredInputProps.unshift(new DropdownValue("",""));
 
         this.operationOutputCats = _.filter(
             _.map(
index f161bab..301b3a4 100644 (file)
@@ -78,7 +78,7 @@ export class ComponentGenericResponse  implements Serializable<ComponentGenericR
         if(response.deploymentArtifacts) {
             this.deploymentArtifacts = new ArtifactGroupModel(response.deploymentArtifacts);
         }
-        if(response.inputs) { 
+        if(response.inputs) {
             this.inputs = CommonUtils.initInputs(response.inputs);
         }
         if(response.attributes) {
@@ -100,6 +100,7 @@ export class ComponentGenericResponse  implements Serializable<ComponentGenericR
             this.toscaArtifacts = new ArtifactGroupModel(response.toscaArtifacts);
         }
         if(response.interfaces) {
+            this.interfaces = CommonUtils.initInterfaces(response.interfaces);
             this.interfaceOperations = CommonUtils.initInterfaceOperations(response.interfaces);
         }
         if (response.componentInstancesInterfaces) {
index 8ad8db2..738b4d1 100644 (file)
@@ -412,3 +412,10 @@ export class CANVAS_TAG_MODE {
     static GROUP_TAGGING = "group-tagging";
     static GROUP_TAGGING_HOVER= "group-tagging-hover";
 }
+
+export class DROPDOWN_OPTION_TYPE {
+    static SIMPLE = "Simple";
+    static HEADER = "Header";
+    static DISABLE = "Disable";
+    static HORIZONTAL_LINE = "HorizontalLine";
+}
index b367577..0d43fa1 100644 (file)
@@ -1,8 +1,20 @@
 const mockApis = require('./configurations/mock.json').sdcConfig;
 const proxy = require('http-proxy-middleware');
 const devPort = 9000;
+
 const fePort = 8181;
 const feHost = "localhost";
+const protocol="http";
+const isDirectToFE = false;
+
+/*
+For kubernetes
+const fePort = 30207;
+const wfPort = 30256;
+const feHost = "kubernetes_master";
+const protocol="https";
+const isDirectToFE = true;// whether to proxy to the k8s proxy or to the BE
+*/
 const portalCookieValue = "randomValue"; //for dev solely, in production - the webseal would add the cookie by itself.
 
 module.exports = function (env) {
@@ -38,25 +50,36 @@ module.exports = function (env) {
             ];
 
             // Redirect all '/sdc1/feProxy/rest' to feHost
+            let feProxyOptions = {
+                target: protocol + '://' + feHost + ':' + fePort,
+                changeOrigin: true,
+                secure: false,
+                logLevel: 'debug'
+            }    
+            if (isDirectToFE) {
+                feProxyOptions.pathRewrite= {
+                    '^/sdc1/feProxy/rest' : '/sdc1/feProxy/rest'
+                }
+            } else {
+                feProxyOptions.pathRewrite= {
+                    '^/sdc1/feProxy/rest' : '/sdc2/rest'
+                }
+            }    
             middlewares.push(
-                proxy(['/sdc1/feProxy/rest', '/sdc1/feProxy/uicache'], {
-                    target: 'http://' + feHost + ':' + fePort,
-                    changeOrigin: true,
-                    secure: false
-                }));
+                proxy(['/sdc1/feProxy/rest'], feProxyOptions));
 
             // Redirect all '/sdc1/rest' to feHost
             middlewares.push(
-                proxy(['/sdc1/rest'], {
-                    target: 'http://' + feHost + ':' + fePort,
+                proxy(['/sdc1/rest'],{
+                    target: protocol + '://' + feHost + ':' + fePort,
                     changeOrigin: true,
                     secure: false
                 }));
 
             // Redirect dcae urls to feHost
             middlewares.push(
-                proxy(['/dcae', '/sdc1/feProxy/dcae-api'], {
-                    target: 'http://' + feHost + ':' + fePort,
+                proxy(['/dcae','/sdc1/feProxy/dcae-api'], {
+                    target: protocol + '://' + feHost + ':' + fePort,
                     changeOrigin: true,
                     secure: false,
                     onProxyRes: (proxyRes, req, res) => {
@@ -70,7 +93,7 @@ module.exports = function (env) {
             // Redirect onboarding urls to feHost
             middlewares.push(
                 proxy(['/onboarding', '/sdc1/feProxy/onboarding-api'], {
-                    target: 'http://' + feHost + ':' + fePort,
+                    target: protocol + '://' + feHost + ':' + fePort,
                     changeOrigin: true,
                     secure: false,
                     onProxyRes: (proxyRes, req, res) => {
@@ -81,6 +104,23 @@ module.exports = function (env) {
                     }
                 }));
 
+            // Redirect workflow urls to feHost
+            middlewares.push(
+                proxy(['/sdc1/feProxy/wf', '/wf'], {
+                    target: protocol + '://' + feHost + ':' + wfPort,
+                    changeOrigin: true,
+                    logLevel: 'debug',
+                    secure: false,
+                    pathRewrite: {
+                        '^/sdc1/feProxy' : ''
+                    },
+                    onProxyRes: (proxyRes, req, res) => {
+                        let setCookie = proxyRes.headers['set-cookie'];
+                        if (setCookie) {
+                            setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
+                        }
+                    }
+                }));
             server.use(middlewares);
         }
     };