summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoav Schneiderman <yoav.schneiderman@intl.att.com>2019-11-20 16:50:45 +0200
committerEinat Vinouze <einat.vinouze@intl.att.com>2019-11-26 12:41:29 +0200
commit091343aa4bbf1bd6b882e08113d90685c1c84ffe (patch)
treefbef4bda9987a59dff5109cf5cc401f95eb05068
parentee6c513301200be38c3602a4c3084c2ff3bde10c (diff)
Allow platform multi-selection for VNF in modern UI
Issue-ID: VID-722 Change-Id: Id87f59fff128e277d9158b83f3908754375c8b01 Signed-off-by: Yoav Schneiderman <yoav.schneiderman@intl.att.com> Signed-off-by: Einat Vinouze <einat.vinouze@intl.att.com>
-rw-r--r--features.properties.md3
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/properties/Features.java1
-rw-r--r--vid-automation/src/main/java/org/onap/simulator/presetGenerator/presets/mso/PresetMSOCreateVnfALaCarteCypress2.java2
-rw-r--r--vid-automation/src/main/java/vid/automation/test/infra/Features.java1
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationALaCarteApiTest.java3
-rw-r--r--vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-testapi.json2
-rw-r--r--vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json2
-rw-r--r--vid-automation/src/test/resources/features.properties2
-rw-r--r--vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts89
-rw-r--r--vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json2
-rw-r--r--vid-webpack-master/cypress/support/steps/genericForm/genericFormAction.steps.ts21
-rw-r--r--vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.html40
-rw-r--r--vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.spec.ts74
-rw-r--r--vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.ts45
-rw-r--r--vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.service.ts50
-rw-r--r--vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.model.ts11
-rw-r--r--vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.spec.ts30
-rw-r--r--vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.ts52
-rw-r--r--vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html5
-rw-r--r--vid-webpack-master/src/app/shared/models/formControlModels/multiselectFormControl.model.ts10
-rw-r--r--vid-webpack-master/src/app/shared/shared.module.ts2
21 files changed, 308 insertions, 139 deletions
diff --git a/features.properties.md b/features.properties.md
index 45d5922c7..20db29813 100644
--- a/features.properties.md
+++ b/features.properties.md
@@ -188,3 +188,6 @@
* FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
When flag is true, VID use macro_services_by_invariant_uuid.json file to identify if csar without instantiation type is macro service.
Otherwise, MACRO_SERVICES list in vidConfiguration.js is used to identify if it's a macro service (in ng1 code)
+
+* FLAG_2002_VNF_PLATFORM_MULTI_SELECT
+ When flag is true the platform will appear as a multi select field, if false the platform will be dropdown list. \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
index d6d7a6aa2..6a6ac6898 100644
--- a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
+++ b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
@@ -79,6 +79,7 @@ public enum Features implements Feature {
FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH,
FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE,
FLAG_2002_ANY_ALACARTE_BESIDES_EXCLUDED_NEW_INSTANTIATION_UI,
+ FLAG_2002_VNF_PLATFORM_MULTI_SELECT,
FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS,
FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
;
diff --git a/vid-automation/src/main/java/org/onap/simulator/presetGenerator/presets/mso/PresetMSOCreateVnfALaCarteCypress2.java b/vid-automation/src/main/java/org/onap/simulator/presetGenerator/presets/mso/PresetMSOCreateVnfALaCarteCypress2.java
index 96424e803..da1c3ffcf 100644
--- a/vid-automation/src/main/java/org/onap/simulator/presetGenerator/presets/mso/PresetMSOCreateVnfALaCarteCypress2.java
+++ b/vid-automation/src/main/java/org/onap/simulator/presetGenerator/presets/mso/PresetMSOCreateVnfALaCarteCypress2.java
@@ -24,7 +24,7 @@ public class PresetMSOCreateVnfALaCarteCypress2 extends PresetMSOCreateVnfBase {
"{\"lcpCloudRegionId\":\"just another region\"," +
addCloudOwnerIfNeeded() +
"\"tenantId\":\"092eb9e8e4b7412e8787dd091bc58e86\"}," +
- "\"platform\":{\"platformName\":\"xxx1\"}," +
+ "\"platform\":{\"platformName\":\"xxx1,platform\"}," +
"\"modelInfo\":" +
"{\"modelCustomizationId\":\"1da7b585-5e61-4993-b95e-8e6606c81e45\"," +
"\"modelCustomizationName\":\"2017-488_PASQUALE-vPE 0\"," +
diff --git a/vid-automation/src/main/java/vid/automation/test/infra/Features.java b/vid-automation/src/main/java/vid/automation/test/infra/Features.java
index c1a505276..208f463d1 100644
--- a/vid-automation/src/main/java/vid/automation/test/infra/Features.java
+++ b/vid-automation/src/main/java/vid/automation/test/infra/Features.java
@@ -54,6 +54,7 @@ public enum Features implements Feature {
FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH,
FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE,
FLAG_2002_ANY_ALACARTE_BESIDES_EXCLUDED_NEW_INSTANTIATION_UI,
+ FLAG_2002_VNF_PLATFORM_MULTI_SELECT,
FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS,
FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
;
diff --git a/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationALaCarteApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationALaCarteApiTest.java
index 92d3f79c8..8fe0580aa 100644
--- a/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationALaCarteApiTest.java
+++ b/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationALaCarteApiTest.java
@@ -8,7 +8,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset.DEFAULT_INSTANCE_ID;
@@ -20,14 +19,12 @@ import static vid.automation.test.services.SimulatorApi.retrieveRecordedRequests
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-
import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetCloudOwnersByCloudRegionId;
diff --git a/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-testapi.json b/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-testapi.json
index dfdab76f7..1c22fb894 100644
--- a/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-testapi.json
+++ b/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-testapi.json
@@ -101,7 +101,7 @@
"lcpCloudRegionId": "AAIAIC25",
"legacyRegion": "just another region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "platformName": "xxx1",
+ "platformName": "xxx1,platform",
"lineOfBusiness": "zzz1",
"instanceParams": [
{}
diff --git a/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json b/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json
index cc1d5b566..7924340c0 100644
--- a/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json
+++ b/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json
@@ -98,7 +98,7 @@
"lcpCloudRegionId": "AAIAIC25",
"legacyRegion": "just another region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "platformName": "xxx1",
+ "platformName": "xxx1,platform",
"lineOfBusiness": "zzz1",
"instanceParams": [
{}
diff --git a/vid-automation/src/test/resources/features.properties b/vid-automation/src/test/resources/features.properties
index 3b7fd310d..84522ae2b 100644
--- a/vid-automation/src/test/resources/features.properties
+++ b/vid-automation/src/test/resources/features.properties
@@ -35,3 +35,5 @@ FLAG_FLASH_REDUCED_RESPONSE_CHANGEMG = true
FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE = false
FLAG_SHOW_ORCHESTRATION_TYPE = false
FLAG_1911_INSTANTIATION_ORDER_BUTTON_IN_ASYNC_ALACARTE = false
+FLAG_A_LA_CARTE_PLATFORM_MULTI_SELECT = false
+
diff --git a/vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts
index 57c673262..14b4bdc14 100644
--- a/vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts
+++ b/vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts
@@ -14,15 +14,15 @@ describe('A la carte', function () {
const CONFIRM_BUTTON: string = 'confirmButton';
beforeEach(() => {
- cy.clearSessionStorage();
- cy.setReduxState();
- cy.preventErrorsOnLoading();
- cy.initAAIMock();
- cy.initVidMock();
- cy.mockLatestVersionForService(SERVICE_ID, SERVICE_INVARIANT_ID);
- cy.initAlaCarteService();
- cy.initZones();
- cy.login();
+ cy.clearSessionStorage();
+ cy.setReduxState();
+ cy.preventErrorsOnLoading();
+ cy.initAAIMock();
+ cy.initVidMock();
+ cy.mockLatestVersionForService(SERVICE_ID, SERVICE_INVARIANT_ID);
+ cy.initAlaCarteService();
+ cy.initZones();
+ cy.login();
});
afterEach(() => {
@@ -30,8 +30,7 @@ describe('A la carte', function () {
});
-
- it(`service name should be mandatory : serviceEcompNaming = true`, ()=> {
+ it(`service name should be mandatory : serviceEcompNaming = true`, () => {
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/basicService.json').then((res) => {
jsonBuilderAAIService.basicJson(res,
Cypress.config('baseUrl') + '/rest/models/services/' + SERVICE_ID,
@@ -43,13 +42,13 @@ describe('A la carte', function () {
});
});
- it(`Service a-la-carte`, ()=> {
+ it(`Service a-la-carte`, () => {
- const subscriptionServiceType : string = "TYLER SILVIA";
- const owningEntityName : string = "WayneHolland";
- const rollbackOnFailure : string = "true";
- const projectName : string = "WATKINS";
- const instanceName : string = "serviceInstanceName";
+ const subscriptionServiceType: string = "TYLER SILVIA";
+ const owningEntityName: string = "WayneHolland";
+ const rollbackOnFailure: string = "true";
+ const projectName: string = "WATKINS";
+ const instanceName: string = "serviceInstanceName";
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/emptyServiceRedux.json').then((res) => {
cy.setTestApiParamToGR();
@@ -91,8 +90,20 @@ describe('A la carte', function () {
});
});
+ it(`VNF a-la-carte`, () => {
+ cy.readFile('cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json').then((res) => {
+ res['FLAG_2002_VNF_PLATFORM_MULTI_SELECT'] = true;
+ cy.server()
+ .route({
+ method: 'GET',
+ delay: 0,
+ status: 200,
+ url: Cypress.config('baseUrl') + "/flags**",
+ response: res
+ }).as('initFlags with multi select');
+ });
+
- it(`VNF a-la-carte`, ()=> {
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/emptyServiceRedux.json').then((res) => {
cy.setTestApiParamToGR();
res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.vidNotions.instantiationType = 'ALaCarte';
@@ -119,31 +130,42 @@ describe('A la carte', function () {
cy.get('#quantity-select').should('have.attr', 'disabled');
cy.getElementByDataTestsId('form-set').click({force: true}).then(() => {
cy.getElementByDataTestsId('node-2017-488_PASQUALE-vPE 0-add-btn').click({force: true}).then(() => {
+
cy.selectDropdownOptionByText('productFamily', 'Emanuel');
cy.selectDropdownOptionByText('lcpRegion', 'AAIAIC25');
cy.typeToInput("lcpRegionText", "just another region");
cy.selectDropdownOptionByText('tenant', 'USP-SIP-IC-24335-T-01');
cy.selectDropdownOptionByText('lineOfBusiness', 'zzz1');
- cy.selectDropdownOptionByText('platform', 'xxx1');
+
+ cy.selelctPlatformValue(false, 'xxx1');
+
cy.getElementByDataTestsId('form-set').click({force: true}).then(() => {
- cy.getReduxState().then((state) => {
-
- const vnf = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs['2017-488_PASQUALE-vPE 0'];
- cy.readFile('../vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json').then((file) => {
- file.vnfs['2017-488_PASQUALE-vPE 0'].trackById = vnf.trackById;
- file.vnfs['2017-488_PASQUALE-vPE 0'].vfModules = {};
- file.vnfs['2017-488_PASQUALE-vPE 0'].upgradedVFMSonsCounter = 0;
- cy.deepCompare(vnf, file.vnfs['2017-488_PASQUALE-vPE 0'])
+
+ const vnfMenuBtnDataTestId = 'node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0-menu-btn';
+
+ cy.getElementByDataTestsId(vnfMenuBtnDataTestId).click({force: true}).then(() => {
+ cy.getElementByDataTestsId('context-menu-edit').click({force: true});
+ cy.selelctPlatformValue(false, 'platform');
+ cy.getElementByDataTestsId('form-set').click({force: true}).then(() => {
+ cy.getReduxState().then((state) => {
+
+ const vnf = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs['2017-488_PASQUALE-vPE 0'];
+ cy.readFile('../vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json').then((file) => {
+ file.vnfs['2017-488_PASQUALE-vPE 0'].trackById = vnf.trackById;
+ file.vnfs['2017-488_PASQUALE-vPE 0'].vfModules = {};
+ file.vnfs['2017-488_PASQUALE-vPE 0'].upgradedVFMSonsCounter = 0;
+ cy.deepCompare(vnf, file.vnfs['2017-488_PASQUALE-vPE 0'])
+ });
+ });
});
});
});
-
});
});
});
});
- it(`Network a-la-carte`, ()=> {
+ it(`Network a-la-carte`, () => {
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/emptyServiceRedux.json').then((res) => {
cy.setTestApiParamToGR();
res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.vidNotions.instantiationType = 'ALaCarte';
@@ -173,7 +195,8 @@ describe('A la carte', function () {
cy.setReduxState(<any>res);
cy.openIframe('app/ui/#/servicePlanning?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd');
cy.getElementByDataTestsId("node-ExtVL 0-add-btn").click({force: true});
- cy.selectDropdownOptionByText("platform", "xxx1");
+
+ cy.selelctPlatformValue(true, 'xxx1');
cy.selectDropdownOptionByText("lcpRegion", "AAIAIC25");
cy.selectDropdownOptionByText("tenant", "USP-SIP-IC-24335-T-01");
cy.selectDropdownOptionByText("productFamily", "ERICA");
@@ -193,7 +216,7 @@ describe('A la carte', function () {
});
});
- it(`VFModule a-la-carte`, ()=> {
+ it(`VFModule a-la-carte`, () => {
var timeBomb = new Date('12/09/2018');
if (new Date() < timeBomb) {
return;
@@ -210,7 +233,7 @@ describe('A la carte', function () {
cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
cy.selectDropdownOptionByText('tenant', 'AIN Web Tool-15-D-STTest2');
cy.selectDropdownOptionByText('lineOfBusiness', 'zzz1');
- cy.selectDropdownOptionByText('platform', 'xxx1');
+ cy.selelctPlatformValue(true, 'xxx1');
cy.getElementByDataTestsId('form-set').click({force: true}).then(() => {
const vnfName = '2017-488_PASQUALE-vPE 0';
let vfModulesNames: Array<string> = [
@@ -261,7 +284,7 @@ describe('A la carte', function () {
.get('.error').contains(INSTANCE_NAME_NOT_MANDATORY_MESSAGE);
}
- function addVfModule (vnfName: string, vfModuleName: string, instanceName: string, lcpRegion: string, legacyRegion: string, tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean): Chainable<any> {
+ function addVfModule(vnfName: string, vfModuleName: string, instanceName: string, lcpRegion: string, legacyRegion: string, tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean): Chainable<any> {
return cy.getElementByDataTestsId('node-' + vnfName).click({force: true}).then(() => {
cy.getElementByDataTestsId('node-' + vfModuleName + '-add-btn').click({force: true}).then(() => {
cy.getElementByDataTestsId('instanceName').clear().type(instanceName, {force: true}).then(() => {
diff --git a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
index d9561f168..53038ed4e 100644
--- a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
+++ b/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
@@ -19,5 +19,7 @@
"FLAG_FLASH_REPLACE_VF_MODULE": true,
"FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT": true,
"FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE": false,
+ "FLAG_1911_INSTANTIATION_ORDER_BUTTON_IN_ASYNC_ALACARTE": false,
+ "FLAG_2002_VNF_PLATFORM_MULTI_SELECT" : false,
"FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS": true
}
diff --git a/vid-webpack-master/cypress/support/steps/genericForm/genericFormAction.steps.ts b/vid-webpack-master/cypress/support/steps/genericForm/genericFormAction.steps.ts
index 9786369cf..41784daff 100644
--- a/vid-webpack-master/cypress/support/steps/genericForm/genericFormAction.steps.ts
+++ b/vid-webpack-master/cypress/support/steps/genericForm/genericFormAction.steps.ts
@@ -1,12 +1,29 @@
declare namespace Cypress {
interface Chainable {
genericFormSubmitForm: typeof genericFormSubmitForm
+ selelctPlatformValue: typeof selelctPlatformValue
}
}
-function genericFormSubmitForm() : Chainable<any> {
- return cy.getElementByDataTestsId('form-set').click({force: true});
+
+
+
+function selelctPlatformValue(isDropdown: boolean, selectOption: string){
+ if (isDropdown) {
+ cy.selectDropdownOptionByText('platform', selectOption);
+ } else {
+ cy.getElementByDataTestsId("multi-selectPlatform").get('.c-btn').click({force: true})
+ .getElementByDataTestsId(`multi-selectPlatform-${selectOption}`).click()
+ .getElementByDataTestsId("multi-selectPlatform").get('.c-btn').click({force: true});
+
+ }
+}
+
+
+function genericFormSubmitForm(): Chainable<any> {
+ return cy.getElementByDataTestsId('form-set').click({force: true});
}
Cypress.Commands.add('genericFormSubmitForm', genericFormSubmitForm);
+Cypress.Commands.add('selelctPlatformValue', selelctPlatformValue);
diff --git a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.html b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.html
index f7c4894b2..f205259e4 100644
--- a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.html
+++ b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.html
@@ -1,16 +1,26 @@
-<div>
- <div class="details-item" *ngIf="data != null && form != null">
- <label [ngClass]="{'required': data.isRequired()}"
- for="{{data?.dataTestId}}">{{data?.displayName}}:</label>
- <angular2-multiselect id="{{data?.dataTestId}}"
- [attr.data-tests-id]="data?.dataTestId"
- [formControl]="form.controls[data.controlName]"
- [(ngModel)]="data.selectedItems"
- [data]="data?.options$"
- [settings]="data?.settings"
- title="{{data.tooltip}}"
- [ngClass]="{'error-style' : form?.controls[data?.controlName]?.touched && form?.controls[data?.controlName]?.errors}">
- </angular2-multiselect>
- </div>
-</div>
+<div class="details-item" *ngIf="data != null && form != null">
+ <label [ngClass]="{'required': data.isRequired()}"
+ for="{{data?.dataTestId}}-select">{{data?.displayName}}:</label>
+
+ <angular2-multiselect
+ [attr.data-tests-id]="data?.dataTestId"
+ [data]="options"
+ [(ngModel)]="selectedItems"
+ [settings]="dropdownSettings"
+ (onSelect)="onItemSelect($event)"
+ (onDeSelect)="OnItemDeSelect($event)"
+ (onSelectAll)="onSelectAll($event)"
+ (onDeSelectAll)="onDeSelectAll($event)">>
+ <c-item>
+ <ng-template let-item="item">
+ <label
+ [attr.data-tests-id]="data.dataTestId + '-' + item?.itemName"
+ style="color: #333;min-width: 150px;">{{item?.itemName}}</label>
+ </ng-template>
+ </c-item>
+ </angular2-multiselect>
+
+ <form-control-error *ngIf="data?.hasEmptyOptions && data?.isRequired()"
+ [message]="'No results for this request. Please change criteria.'"></form-control-error>
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.spec.ts b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.spec.ts
deleted file mode 100644
index 81c8d4679..000000000
--- a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.spec.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import {ComponentFixture, TestBed} from '@angular/core/testing';
-import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'
-import {CommonModule} from "@angular/common";
-import {FormBuilder, FormControl, ReactiveFormsModule, Validators} from "@angular/forms";
-import {
- ValidatorModel,
- ValidatorOptions
-} from "../../../../models/formControlModels/formControl.model";
-import {FormControlMessageErrorComponent} from "../../errorMessage/formControlMessageError.component";
-import {BrowserModule} from "@angular/platform-browser";
-import {MultiselectFormControlComponent} from "./multiselect.formControl.component";
-import {MultiselectFormControl} from "../../../../models/formControlModels/multiselectFormControl.model";
-import { of } from "rxjs";
-describe('Dropdown Form Control Component', () => {
- let component: MultiselectFormControlComponent;
- let fixture: ComponentFixture<MultiselectFormControlComponent>;
- let fb: FormBuilder;
-
- beforeAll(done => (async () => {
- TestBed.configureTestingModule({
- imports: [CommonModule, BrowserModule, ReactiveFormsModule],
- providers: [FormBuilder],
- declarations: [MultiselectFormControlComponent, FormControlMessageErrorComponent],
- schemas: [CUSTOM_ELEMENTS_SCHEMA]
- });
- await TestBed.compileComponents();
-
- fixture = TestBed.createComponent(MultiselectFormControlComponent);
- component = fixture.componentInstance;
- fb = TestBed.get(FormBuilder);
-
- })().then(done).catch(done.fail));
-
- test('component should initialize basic parameters', () => {
- component.data = new MultiselectFormControl({
- displayName: "display Name",
- validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
- dataTestId: "data-test-id",
- placeHolder: "place holder",
- controlName: 'testDropdown',
- options: of([
- 'option1',
- 'option2',
- 'option3',
- 'onBlur'
- ])
- });
-
- component.data.hasErrors = function () {
- return this.formGroup.controls[this.controlName].touched && this.formGroup.controls[this.controlName].errors ? ['error-style'] : [];
- };
-
- component.data.onBlur = function () {
- component.form.controls['testDropdown'].setValue('onBlur');
- };
-
- component.form = fb.group({
- 'testDropdown': new FormControl({
- value: component.data.value,
- disabled: false
- }, Validators.compose(component.data.validations.map(item => item.validator)))
- });
-
- component.form.controls['testDropdown'].setValue('');
- expect(component.form.controls['testDropdown'].errors.required).toBeTruthy();
- component.form.controls['testDropdown'].setValue('option2');
- expect(component.form.controls['testDropdown'].errors).toBeFalsy();
- component.data.onBlur();
- expect(component.form.controls['testDropdown'].value).toEqual('onBlur');
- expect(component.form.controls['testDropdown'].errors).toBeFalsy();
- }
- )
-});
-
diff --git a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.ts b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.ts
index 4b98c7e26..9b900dedf 100644
--- a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.ts
+++ b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.component.ts
@@ -1,6 +1,8 @@
import {Component, Input, OnChanges, SimpleChanges} from "@angular/core";
import {FormGroup} from "@angular/forms";
import {MultiselectFormControl} from "../../../../models/formControlModels/multiselectFormControl.model";
+import {MultiselectFormControlService} from "./multiselect.formControl.service";
+import {MultiSelectItem} from "./multiselect.model";
@Component({
selector: 'multiselect-form-control',
@@ -8,13 +10,52 @@ import {MultiselectFormControl} from "../../../../models/formControlModels/multi
})
export class MultiselectFormControlComponent implements OnChanges{
@Input() data: MultiselectFormControl = null;
+ @Input() multiselectOptions: [] = null;
+ @Input() selectedItems = [];
@Input() form: FormGroup = null;
- ngOnChanges(changes: SimpleChanges): void {
+
+ multiselectFormControlService : MultiselectFormControlService;
+ constructor(private _multiselectFormControlService : MultiselectFormControlService){
+ this.multiselectFormControlService = _multiselectFormControlService;
+ }
+ dropdownSettings = {
+ singleSelection : false
+ };
+
+ options : MultiSelectItem[];
+
+
+
+ async ngOnChanges(changes: SimpleChanges) {
+ if(this.data.options$){
+ this._multiselectFormControlService.convertOriginalItems(this.data).then((options)=>{
+ this.options = options;
+ this._multiselectFormControlService.convertSelectedItems(this.data).then((res)=> {
+ this.selectedItems = res;
+ this.form.controls[this.data.controlName].setValue(this.selectedItems);
+ })
+ });
+
+ }
if (changes["data"] !== undefined && changes["data"].currentValue !== changes["data"].previousValue && changes["data"].firstChange) {
- if(this.data.onInit){
+ if (this.data.onInit) {
this.data.onInit(this.data, this.form);
}
}
}
+
+ onItemSelect(item:any){
+ this.data.onChange(this.selectedItems ,this.form);
+ }
+ OnItemDeSelect(item:any){
+ this.data.onChange(this.selectedItems ,this.form);
+ }
+ onSelectAll(items: any){
+ this.data.onChange(this.selectedItems ,this.form);
+ }
+ onDeSelectAll(items: any){
+ this.data.onChange(this.selectedItems ,this.form);
+ }
}
+
diff --git a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.service.ts b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.service.ts
new file mode 100644
index 000000000..4a9580563
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.formControl.service.ts
@@ -0,0 +1,50 @@
+import {Injectable} from "@angular/core";
+import {MultiselectFormControl} from "../../../../models/formControlModels/multiselectFormControl.model";
+import {MultiSelectItem} from "./multiselect.model";
+import * as _ from "lodash";
+
+
+@Injectable()
+export class MultiselectFormControlService {
+
+ convertOriginalItems = (data : MultiselectFormControl) : Promise<MultiSelectItem[]> => {
+ return new Promise<MultiSelectItem[]>((resolve) =>{
+ let result: MultiSelectItem[] = [];
+ if(data.options$) {
+ let index: number = 1;
+ data.options$.map((originalItems: any) => {
+ result.push(new MultiSelectItem(index, originalItems[data.ngValue], originalItems[data.selectedFieldName]));
+ index++;
+ });
+ }
+ resolve(result);
+ })
+ };
+
+
+ convertOptionsToHashMap = (config : MultiselectFormControl) => {
+ let index = 1;
+ return _.reduce(config.options$ , (obj, param: any ) => {
+ param.index = index;
+ index++;
+ obj[param[config.ngValue]] = param;
+ return obj;
+ }, {});
+ };
+
+ convertSelectedItems(data : MultiselectFormControl) : Promise<MultiSelectItem[]>{
+ return new Promise<MultiSelectItem[]>((resolve) =>{
+ let result: MultiSelectItem[] = [];
+ const hashMap = this.convertOptionsToHashMap(data);
+
+ if(data.options$ && data.value) {
+ const convertArray = data.convertOriginalDataToArray ? data.convertOriginalDataToArray(data.value) : data.value;
+ convertArray.map((itemId) => {
+ const uniqueIdentifier = itemId.trim();
+ result.push(new MultiSelectItem(hashMap[uniqueIdentifier].index, hashMap[uniqueIdentifier][data.ngValue], hashMap[uniqueIdentifier][data.selectedFieldName]));
+ });
+ }
+ resolve(result);
+ });
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.model.ts b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.model.ts
new file mode 100644
index 000000000..a495211d4
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formControls/component/multiselect/multiselect.model.ts
@@ -0,0 +1,11 @@
+export class MultiSelectItem {
+ id : number;
+ itemId : number;
+ itemName : string;
+
+ constructor(genericId: number, itemId : number, itemName : string){
+ this.id = genericId;
+ this.itemId = itemId;
+ this.itemName = itemName;
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.spec.ts b/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.spec.ts
index 5c6e25c6b..9230ccfa7 100644
--- a/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.spec.ts
+++ b/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.spec.ts
@@ -16,6 +16,7 @@ import {VnfControlGenerator} from "./vnf.control.generator";
import {Observable} from "rxjs";
import {SelectOption} from "../../../../models/selectOption";
import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
+import {FormControlType} from "../../../../models/formControlModels/formControlTypes.enum";
class MockAppStore<T> {
getState(){
@@ -939,6 +940,35 @@ describe('VNF Control Generator', () => {
})().then(done).catch(done.fail));
+
+ test('should call platform dropdown control', ()=>{
+ spyOn(service, 'getPlatformDropdownControl');
+
+ service.getPlatformControl(null, [], false);
+
+ expect(service.getPlatformDropdownControl).toBeCalledWith(null, []);
+ });
+
+ test('should call platform multi select control', ()=>{
+ spyOn(service, 'getPlatformMultiselectControl');
+
+ service.getPlatformControl(null, [], true);
+
+ expect(service.getPlatformMultiselectControl).toBeCalledWith(null, []);
+ });
+
+ test('should generate platform multi select control', ()=>{
+ const control = service.getPlatformMultiselectControl(null, []);
+ expect(control.type).toEqual(FormControlType.MULTI_SELECT);
+ expect(control.controlName).toEqual('platformName');
+ expect(control.displayName).toEqual('Platform');
+ expect(control.dataTestId).toEqual('multi-selectPlatform');
+ expect(control.selectedFieldName).toEqual('name');
+ expect(control.value).toEqual('');
+ expect(control.onChange).toBeDefined();
+ expect(control.convertOriginalDataToArray).toBeDefined();
+ });
+
test('getMacroFormControls check for mandatory controls', () => {
const serviceId : string = "6e59c5de-f052-46fa-aa7e-2fca9d674c44";
const vnfName : string = "VF_vGeraldine 0";
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.ts b/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.ts
index 7760ba8ad..55177aaac 100644
--- a/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.ts
+++ b/vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vnfGenerator/vnf.control.generator.ts
@@ -20,6 +20,8 @@ import {Observable, of} from "rxjs";
import {SelectOption} from "../../../../models/selectOption";
import * as _ from 'lodash';
import {Constants} from "../../../../utils/constants";
+import {MultiselectFormControl} from "../../../../models/formControlModels/multiselectFormControl.model";
+import {MultiSelectItem} from "../../../formControls/component/multiselect/multiselect.model";
export enum FormControlNames {
INSTANCE_NAME = 'instanceName',
@@ -101,12 +103,13 @@ export class VnfControlGenerator {
const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfName]);
if (!_.isNil(vnfModel)) {
+ const flags = this.store.getState().global.flags;
result.push(this.getInstanceName(vnfInstance, serviceId, vnfName, vnfModel.isEcompGeneratedNaming));
result.push(this._basicControlGenerator.getProductFamilyControl(vnfInstance, result, false));
result.push(this.getLcpRegionControl(serviceId, vnfInstance, result));
result.push(this._basicControlGenerator.getLegacyRegion(vnfInstance));
result.push(this.getTenantControl(serviceId, vnfInstance, result));
- result.push(this.getPlatformControl(vnfInstance, result));
+ result.push(this.getPlatformControl(vnfInstance, result, flags['FLAG_2002_VNF_PLATFORM_MULTI_SELECT']));
result.push(this.getLineOfBusinessControl(vnfInstance, result));
result.push(this.getRollbackOnFailureControl(vnfInstance, result));
}
@@ -139,20 +142,59 @@ export class VnfControlGenerator {
})
};
- getPlatformControl = (instance: any, controls: FormControlModel[]): DropdownFormControl => {
+
+
+ getPlatformDropdownControl = (instance: any, controls: FormControlModel[]) : DropdownFormControl => {
return new DropdownFormControl({
- type: FormControlType.DROPDOWN,
+ type: FormControlType.DROPDOWN ,
controlName: 'platformName',
displayName: 'Platform',
dataTestId: 'platform',
+ selectedFieldName : null ,
+ ngValue : null,
placeHolder: 'Select Platform',
isDisabled: false,
name: "platform",
value: instance ? instance.platformName : null,
validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
onInitSelectedField: ['platformList'],
- onInit: this._basicControlGenerator.getSubscribeInitResult.bind(null, this._aaiService.getCategoryParameters)
- })
+ onInit: this._basicControlGenerator.getSubscribeInitResult.bind(null, this._aaiService.getCategoryParameters),
+ });
+ };
+
+ getPlatformMultiselectControl = (instance: any, controls: FormControlModel[]) : MultiselectFormControl => {
+ return new MultiselectFormControl({
+ type: FormControlType.MULTI_SELECT ,
+ controlName: 'platformName',
+ displayName: 'Platform',
+ dataTestId: 'multi-selectPlatform',
+ selectedFieldName : 'name' ,
+ ngValue : 'name',
+ placeHolder: 'Select Platform',
+ isDisabled: false,
+ name: "platform",
+ value: instance ? instance.platformName : '',
+ validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
+ onInitSelectedField: ['platformList'],
+ onInit: this._basicControlGenerator.getSubscribeInitResult.bind(null, this._aaiService.getCategoryParameters),
+ onChange : (param: MultiSelectItem[], form: FormGroup) => {
+ form.controls['platformName'].setValue(param.map((multiSelectItem: MultiSelectItem)=>{
+ return multiSelectItem.itemName
+ }).join(','));
+ },
+ convertOriginalDataToArray : (value?: string) => {
+ if(_.isNil(value)) return [];
+ return value.split(',');
+ }
+ });
+ };
+
+ getPlatformControl = (instance: any, controls: FormControlModel[], isMultiSelect?: boolean): MultiselectFormControl | DropdownFormControl => {
+ const shouldGenerateDropdown = isMultiSelect === undefined || isMultiSelect === false;
+ if(shouldGenerateDropdown){
+ return this.getPlatformDropdownControl(instance, controls);
+ }
+ return this.getPlatformMultiselectControl(instance, controls);
};
getTenantControl = (serviceId: string, instance: any, controls: FormControlModel[]): DropdownFormControl => {
diff --git a/vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html b/vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html
index d4c5118b3..edf86823c 100644
--- a/vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html
+++ b/vid-webpack-master/src/app/shared/components/genericForm/generic-form.component.html
@@ -6,6 +6,11 @@
<checkbox-form-control *ngSwitchCase="'CHECKBOX'" [data]="formControl" [form]="dynamicFormGroup" ></checkbox-form-control>
<dropdown-form-control *ngSwitchCase="'DROPDOWN'" [data]="formControl" [form]="dynamicFormGroup" ></dropdown-form-control>
<file-form-control *ngSwitchCase="'FILE'" [data]="formControl" [form]="dynamicFormGroup"></file-form-control>
+ <multiselect-form-control *ngSwitchCase="'MULTI_SELECT'"
+ [data]="formControl"
+ [form]="dynamicFormGroup"
+ [multiselectOptions]="formControl?.options$"
+ [selectedItems]="formControl.value"></multiselect-form-control>
</div>
<div *ngIf="dynamicFormGroup != null && formControl != null && dynamicFormGroup.controls[formControl.controlName]?.errors">
<div *ngFor="let validatorModel of formControl?.validations">
diff --git a/vid-webpack-master/src/app/shared/models/formControlModels/multiselectFormControl.model.ts b/vid-webpack-master/src/app/shared/models/formControlModels/multiselectFormControl.model.ts
index b13745104..09fc1d250 100644
--- a/vid-webpack-master/src/app/shared/models/formControlModels/multiselectFormControl.model.ts
+++ b/vid-webpack-master/src/app/shared/models/formControlModels/multiselectFormControl.model.ts
@@ -7,10 +7,13 @@ export class MultiselectFormControl extends FormControlModel{
options$ : Observable<any[]>;
args : string[];
onInit: (data : MultiselectFormControl, form: FormGroup) => Observable<any>;
- selectedItems : string;
+ selectedItems : any[];
onInitSelectedItems : string[];
+ selectedFieldName : string;
ngValue : string;
settings: {};
+ onInitSelectedField?: string[];
+ convertOriginalDataToArray? : (values)=> void;
constructor(data) {
@@ -18,10 +21,13 @@ export class MultiselectFormControl extends FormControlModel{
this.type = FormControlType.MULTI_SELECT;
this.options$ = data.options;
this.onInit = data.onInit;
- this.selectedItems = data.selectedItems;
+ this.selectedItems = data.selectedItems || [];
this.onInitSelectedItems = data.onInitSelectedItems ? data.onInitSelectedItems : null;
this.ngValue = data.selectedField ? data.selectedField : 'id';
+ this.selectedFieldName = data.selectedFieldName;
this.settings = data.settings || {};
+ this.onInitSelectedField = data.onInitSelectedField ? data.onInitSelectedField : null;
+ this.convertOriginalDataToArray = data.convertOriginalDataToArray ? data.convertOriginalDataToArray : null
}
}
diff --git a/vid-webpack-master/src/app/shared/shared.module.ts b/vid-webpack-master/src/app/shared/shared.module.ts
index d486f2975..d246771af 100644
--- a/vid-webpack-master/src/app/shared/shared.module.ts
+++ b/vid-webpack-master/src/app/shared/shared.module.ts
@@ -73,6 +73,7 @@ import {ClickOutsideDirective} from "./directives/clickOutside/clickOutside.dire
import {DynamicInputsComponent} from "./components/dynamic-inputs/dynamic-inputs.component";
import {DynamicInputLabelPipe} from "./pipes/dynamicInputLabel/dynamic-input-label.pipe";
import {ModelInformationService} from "./components/model-information/model-information.service";
+import {MultiselectFormControlService} from "./components/formControls/component/multiselect/multiselect.formControl.service";
@NgModule({
@@ -196,6 +197,7 @@ import {ModelInformationService} from "./components/model-information/model-info
ErrorMsgService,
DataFilterPipe,
ModelInformationService,
+ MultiselectFormControlService
]
})
export class SharedModule {