This option is enabled only for instantiate jobs.
IF the user click on this option, the previous instantiation is opened in drawing board,
and the user can create another one from this template.
+
+* FLAG_2002_UNLIMITED_MAX
+ when flag is true and max_instances is not declare than user can add unlimited VND, NETWORK, VFMODULE,
+ User can duplicate up to 10 record in single time.
+ If the flag is false and max_instances is not declare the max will be 1 else max_instances value.
FLAG_2004_INSTANTIATION_STATUS_FILTER,
FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER,
+ FLAG_2002_UNLIMITED_MAX,
;
"FLAG_SERVICE_MODEL_CACHE": true,
"FLAG_1906_COMPONENT_INFO" : false,
"FLAG_2002_VNF_PLATFORM_MULTI_SELECT" : false,
+ "FLAG_2002_UNLIMITED_MAX" : true
},
"type": "[FLAGS] Update"
},
['Model version', '2.0'],
['Model customization ID', '91415b44-753d-494c-926a-456a9172bbb9'],
['Min instances', '0'],
- ['Max instances', '1']
+ //['Max instances', '1']
];
const extraLabelsAndValuesForInstance = [['Instance type', 'VNF2_INSTANCE_TYPE'],['In maintenance','true'], ['Instance ID', 'VNF2_INSTANCE_ID']];
testComponentInfoByType('node-VF_vGeraldine 0', labelsAndValuesForModel,'VNF INFO',
"FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER": true,
"FLAG_2004_INSTANTIATION_STATUS_FILTER": true,
"FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false,
+ "FLAG_2002_UNLIMITED_MAX" : true,
"FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true
}
import {NgRedux} from '@angular-redux/store';
import {ITreeNode} from "angular-tree-component/dist/defs/api";
import {SdcUiServices} from "onap-ui-angular";
-import {IModalConfig} from "onap-ui-angular/dist/components/common";
+import {IModalConfig} from 'onap-ui-angular/dist/components/common';
import {AppState} from "../../../shared/store/reducers";
import {getTestBed, TestBed} from "@angular/core/testing";
+import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
class MockAppStore<T> {
getState(){
class MockModalService<T> {}
+class MockFeatureFlagsService extends FeatureFlagsService{
+ getAllFlags(): { [p: string]: boolean } {
+ return {};
+ }
+}
+
describe('Drawing board tree service', () => {
let injector;
let service: DuplicateService;
let store : NgRedux<AppState>;
+ let featureFlagsService : FeatureFlagsService;
beforeAll(done => (async () => {
TestBed.configureTestingModule({
providers : [
DuplicateService,
LogService,
+ {provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockAppStore},
{provide: SdcUiServices.ModalService, useClass: MockModalService}
]
injector = getTestBed();
service = injector.get(DuplicateService);
store = injector.get(NgRedux);
+ featureFlagsService = injector.get(FeatureFlagsService);
})().then(done).catch(done.fail));
}
}
+ }
+ },
+ global : {
+ flags : {
+
}
}
}
import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
import {changeInstanceCounter, duplicateBulkInstances} from "../../../shared/storeUtil/utils/general/general.actions";
import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config";
+import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
+import {Utils} from "../../../shared/utils/utils";
@Injectable()
export class DuplicateService {
- constructor(private _logService : LogService, private _store: NgRedux<AppState>, modalService: SdcUiServices.ModalService) {
+ constructor(private _logService: LogService, private _store: NgRedux<AppState>, modalService: SdcUiServices.ModalService) {
this.modalService = modalService;
}
- numberOfDuplicates:number;
+ numberOfDuplicates: number;
+
setNumberOfDuplicates(numberOfDuplicates: number) {
this.numberOfDuplicates = numberOfDuplicates;
}
storeKey: string = null;
padding = '0000';
modalService: SdcUiServices.ModalService;
- store : NgRedux<AppState>;
- existingNames : {[key: string] : any};
- currentNode : ITreeNode = null;
-
+ store: NgRedux<AppState>;
+ existingNames: { [key: string]: any };
+ currentNode: ITreeNode = null;
canDuplicate(node: ITreeNode): boolean {
return node.data.type === 'VF' || node.data.type === 'VL';
}
- isEnabled(node: ITreeNode, store: NgRedux<AppState>, serviceId : string): boolean {
- if(!_.isNil(node) && !_.isNil(node.data.menuActions['duplicate'])){
- if(this.hasMissingData(node)) return false;
- const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node);
- const max : number = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][node.data.modelName].properties['max_instances'] || 1;
+ isEnabled(node: ITreeNode, store: NgRedux<AppState>, serviceId: string): boolean {
+ if (!_.isNil(node) && !_.isNil(node.data.menuActions['duplicate'])) {
+ if (this.hasMissingData(node)) return false;
+ const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node);
+ const flags = FeatureFlagsService.getAllFlags(store);
+
const currentExisting: number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][node.data.modelUniqueId];
+ const maxInstances = Utils.getMaxFirstLevel(store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][node.data.modelName].properties, flags);
+ if (_.isNil(maxInstances)) {
+ return true;
+ } else {
+ return maxInstances - currentExisting > 0;
+ }
- return max - currentExisting > 0;
- }else {
+ } else {
return false;
}
}
- hasMissingData(node : ITreeNode): boolean {
- if(!_.isNil(node)){
- if(node.data.missingData) return true;
- if(!_.isNil(node.data.children)){
- for(let child of node.data.children) {
- if(child.missingData){
+ hasMissingData(node: ITreeNode): boolean {
+ if (!_.isNil(node)) {
+ if (node.data.missingData) return true;
+ if (!_.isNil(node.data.children)) {
+ for (let child of node.data.children) {
+ if (child.missingData) {
return true;
}
}
return false;
}
- getRemainsInstance(modelId : string, modelName : string, serviceId : string, store: NgRedux<AppState>, node : ITreeNode) : number {
- const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node);
- const properties = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][modelName].properties;
- const currentExisting : number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][modelId];
- return (!_.isNil(properties) && !_.isNil(properties['max_instances'])) ? properties['max_instances'] - currentExisting : null;
+ getRemainsInstance(modelId: string, modelName: string, serviceId: string, store: NgRedux<AppState>, node: ITreeNode): number {
+ const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node);
+ const properties = store.getState().service.serviceHierarchy[serviceId][typeNodeInformation.hierarchyName][modelName].properties;
+ const currentExisting: number = store.getState().service.serviceInstance[serviceId][typeNodeInformation.existingMappingCounterName][modelId];
+
+ const flags = FeatureFlagsService.getAllFlags(store);
+ const maxInstances = Utils.getMaxFirstLevel(properties, flags);
+ if (_.isNil(maxInstances)) {
+ return 10;
+ } else {
+ return maxInstances - currentExisting;
+ }
}
-
- openDuplicateModal(currentServiceId: string, currentUuid: string, currentId: string, storeKey : string, numberOfDuplicate: number, _store : NgRedux<AppState>, node: ITreeNode): IModalConfig {
+ openDuplicateModal(currentServiceId: string, currentUuid: string, currentId: string, storeKey: string, numberOfDuplicate: number, _store: NgRedux<AppState>, node: ITreeNode): IModalConfig {
this.currentInstanceId = currentId;
this.currentServiceId = currentServiceId;
this.maxNumberOfDuplicate = this.getRemainsInstance(currentUuid, currentId, currentServiceId, _store, node);
this.currentNode = node;
- return {
+ return {
size: SdcUiCommon.ModalSize.medium,
title: 'Duplicate Node',
type: SdcUiCommon.ModalType.custom,
};
}
- duplicate(node : ITreeNode): void {
- const typeNodeInformation : TypeNodeInformation = new TypeNodeInformation(node);
+ duplicate(node: ITreeNode): void {
+ const typeNodeInformation: TypeNodeInformation = new TypeNodeInformation(node);
this.existingNames = this.store.getState().service.serviceInstance[this.currentServiceId].existingNames;
- const toClone = this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName][this.storeKey];
+ const toClone = this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName][this.storeKey];
let newObjects = {};
- for(let i = 0; i < this.numberOfDuplicates; i++) {
+ for (let i = 0; i < this.numberOfDuplicates; i++) {
const uniqueStoreKey = this.generateUniqueStoreKey(this.currentServiceId, this.currentInstanceId, this.store.getState().service.serviceInstance[this.currentServiceId][typeNodeInformation.hierarchyName], newObjects);
const clone = this.cloneVnf(toClone, this.currentInstanceId);
newObjects[uniqueStoreKey] = clone;
}
- cloneVnf(vnf : VnfInstance, originalName: string): VnfInstance {
- let newUniqueVnf : VnfInstance = _.cloneDeep(vnf);
+ cloneVnf(vnf: VnfInstance, originalName: string): VnfInstance {
+ let newUniqueVnf: VnfInstance = _.cloneDeep(vnf);
newUniqueVnf.originalName = originalName;
newUniqueVnf.trackById = DefaultDataGeneratorService.createRandomTrackById();
- if (!_.isNil(vnf.instanceName)){
+ if (!_.isNil(vnf.instanceName)) {
newUniqueVnf.instanceName = this.ensureUniqueNameOrGenerateOne(vnf.instanceName);
}
const vfModuleModel: VfModuleMap = vnf.vfModules[vf_module_model_name];
for (let vfModule in vfModuleModel) {
newUniqueVnf.vfModules[vf_module_model_name][vfModule].trackById = DefaultDataGeneratorService.createRandomTrackById();
- if (!_.isNil(vfModuleModel[vfModule].instanceName)){
+ if (!_.isNil(vfModuleModel[vfModule].instanceName)) {
newUniqueVnf.vfModules[vf_module_model_name][vfModule].instanceName = this.ensureUniqueNameOrGenerateOne(vfModuleModel[vfModule].instanceName);
}
- if (!_.isNil(vfModuleModel[vfModule].volumeGroupName)){
+ if (!_.isNil(vfModuleModel[vfModule].volumeGroupName)) {
newUniqueVnf.vfModules[vf_module_model_name][vfModule].volumeGroupName = this.ensureUniqueNameOrGenerateOne(vfModuleModel[vfModule].volumeGroupName);
}
}
return newUniqueVnf;
}
- ensureUniqueNameOrGenerateOne(instanceName){
+ ensureUniqueNameOrGenerateOne(instanceName) {
let uniqueInstanceName = instanceName;
if (this.isAlreadyExists(instanceName, this.existingNames)) {
uniqueInstanceName = this.generateNextUniqueName(instanceName, this.existingNames);
}
- isAlreadyExists(name : string, existingNames : {[key: string] : any}){
+ isAlreadyExists(name: string, existingNames: { [key: string]: any }) {
return _.has(existingNames, name.toLowerCase());
}
- generateNextUniqueName(name : string, existingNames : {[key: string] : any}) :string{
+ generateNextUniqueName(name: string, existingNames: { [key: string]: any }): string {
let suffix = "000";
let counter = 1;
- if (name.match(/^.*_[\d]{3}$/)){
+ if (name.match(/^.*_[\d]{3}$/)) {
name = name.substring(0, name.length - 4);
}
- while(true){
- let paddingNumber : string = this.getNumberAsPaddingString(counter, suffix);
+ while (true) {
+ let paddingNumber: string = this.getNumberAsPaddingString(counter, suffix);
let candidateUniqueName = name + '_' + paddingNumber;
- if(!this.isAlreadyExists(candidateUniqueName, existingNames)){
+ if (!this.isAlreadyExists(candidateUniqueName, existingNames)) {
return candidateUniqueName;
}
counter++;
}
}
- generateUniqueStoreKey(serviceId : string, objectName : string, existing : any, newObjects: any) : string {
+ generateUniqueStoreKey(serviceId: string, objectName: string, existing: any, newObjects: any): string {
let counter = 1;
- while(true){
- let paddingNumber : string = this.getNumberAsPaddingString(counter, this.padding);
+ while (true) {
+ let paddingNumber: string = this.getNumberAsPaddingString(counter, this.padding);
const name = objectName + ':' + paddingNumber;
- if(_.isNil(existing[name]) && _.isNil(newObjects[name])){
+ if (_.isNil(existing[name]) && _.isNil(newObjects[name])) {
return name;
}
counter++;
import {IframeService} from "../../../../../shared/utils/iframe.service";
import {DuplicateService} from "../../../duplicate/duplicate.service";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
+import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
class MockAppStore<T> {
getState() {
global: {
'drawingBoardStatus': DrawingBoardModes.CREATE
},
- service : {
- serviceHierarchy : {
- 'servicedId' : {
- 'networks' : {
- 'networkName' : {
- 'properties' : {
- 'max_instances' : 1
+ service: {
+ serviceHierarchy: {
+ 'servicedId': {
+ 'networks': {
+ 'networkName': {
+ 'properties': {
+ 'max_instances': 1
}
}
}
}
},
- serviceInstance : {
- 'servicedId' : {
- 'existingNetworksCounterMap' : {
- 'networkId' : 1
+ serviceInstance: {
+ 'servicedId': {
+ 'existingNetworksCounterMap': {
+ 'networkId': 1
},
- 'networks' : {
- 'networkName' :{
+ 'networks': {
+ 'networkName': {
'action': 'Create',
- 'originalName' : 'networkName'
+ 'originalName': 'networkName'
}
}
}
}
}
}
+
+class MockFeatureFlagsService extends FeatureFlagsService {
+ getAllFlags(): { [p: string]: boolean } {
+ return {};
+ }
+}
+
+
describe('Network Model Info', () => {
let injector;
- let _dynamicInputsService : DynamicInputsService;
- let _sharedTreeService : SharedTreeService;
+ let _dynamicInputsService: DynamicInputsService;
+ let _sharedTreeService: SharedTreeService;
let networkModel: NetworkModelInfo;
- let _dialogService : DialogService;
- let _networkPopupService : NetworkPopupService;
- let _duplicateService : DuplicateService;
- let _iframeService : IframeService;
+ let _dialogService: DialogService;
+ let _networkPopupService: NetworkPopupService;
+ let _duplicateService: DuplicateService;
+ let _iframeService: IframeService;
+ let _featureFlagsService: FeatureFlagsService;
beforeAll(done => (async () => {
TestBed.configureTestingModule({
IframeService,
DuplicateService,
{provide: NgRedux, useClass: MockAppStore},
+ {provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
MockNgRedux]
});
await TestBed.compileComponents();
injector = getTestBed();
_sharedTreeService = injector.get(SharedTreeService);
- networkModel = new NetworkModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _networkPopupService, _duplicateService, null, _iframeService, MockNgRedux.getInstance());
+ _featureFlagsService = injector.get(FeatureFlagsService);
+
+ networkModel = new NetworkModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _networkPopupService, _duplicateService, null, _iframeService, _featureFlagsService, MockNgRedux.getInstance());
})().then(done).catch(done.fail));
test('NetworkModelInfo should be defined', () => {
expect(model.type).toEqual('VL');
});
- test('showNodeIcons should return false if reachLimit of max', ()=>{
- let serviceId : string = 'servicedId';
+ test('showNodeIcons should return false if reachLimit of max', () => {
+ let serviceId: string = 'servicedId';
let node = {
- data : {
- id : 'networkId',
- name : 'networkName',
- modelCustomizationId : 'modelCustomizationId'
+ data: {
+ id: 'networkId',
+ name: 'networkName',
+ modelCustomizationId: 'modelCustomizationId'
}
};
jest.spyOn(_sharedTreeService, 'getExistingInstancesWithDeleteMode').mockReturnValue(0);
jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({
- global : {},
- service : {
- serviceHierarchy : {
- 'servicedId' : {
- 'networks' : {
- 'networkName' : {
- 'properties' : {
- 'max_instances' : 1
+ global: {},
+ service: {
+ serviceHierarchy: {
+ 'servicedId': {
+ 'networks': {
+ 'networkName': {
+ 'properties': {
+ 'max_instances': 1
}
}
}
}
},
- serviceInstance : {
- 'servicedId' : {
- 'existingNetworksCounterMap' : {
- 'modelCustomizationId' : 1
+ serviceInstance: {
+ 'servicedId': {
+ 'existingNetworksCounterMap': {
+ 'modelCustomizationId': 1
},
- 'networks' : {
- 'networkName' :{
-
- }
+ 'networks': {
+ 'networkName': {}
}
}
}
});
let result = networkModel.showNodeIcons(<any>node, serviceId);
- expect(result).toEqual(new AvailableNodeIcons(true , false));
+ expect(result).toEqual(new AvailableNodeIcons(true, false));
});
- test('showNodeIcons should return true if not reachLimit of max', ()=>{
- let serviceId : string = 'servicedId';
+ test('showNodeIcons should return true if not reachLimit of max', () => {
+ let serviceId: string = 'servicedId';
let node = {
- data : {
- id : 'networkId',
- name : 'networkName'
+ data: {
+ id: 'networkId',
+ name: 'networkName'
}
};
jest.spyOn(_sharedTreeService, 'getExistingInstancesWithDeleteMode').mockReturnValue(0);
jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({
- global : {},
- service : {
- serviceHierarchy : {
- 'servicedId' : {
- 'networks' : {
- 'networkName' : {
- 'properties' : {
- 'max_instances' : 2
+ global: {},
+ service: {
+ serviceHierarchy: {
+ 'servicedId': {
+ 'networks': {
+ 'networkName': {
+ 'properties': {
+ 'max_instances': 2
}
}
}
}
},
- serviceInstance : {
- 'servicedId' : {
- 'existingNetworksCounterMap' : {
- 'networkId' : 1
+ serviceInstance: {
+ 'servicedId': {
+ 'existingNetworksCounterMap': {
+ 'networkId': 1
},
- 'networks' : {
- 'networkName' :{
-
- }
+ 'networks': {
+ 'networkName': {}
}
}
}
});
let result = networkModel.showNodeIcons(<any>node, serviceId);
- expect(result).toEqual(new AvailableNodeIcons(true , false));
+ expect(result).toEqual(new AvailableNodeIcons(true, false));
});
- test('getNodeCount should return number of nodes', ()=>{
- let serviceId : string = 'servicedId';
+ test('getNodeCount should return number of nodes', () => {
+ let serviceId: string = 'servicedId';
jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({
- global : {},
- service : {
- serviceHierarchy : {
- 'servicedId' : {
- 'networks' : {
- 'networkName' : {
- 'properties' : {
- 'max_instances' : 1
+ global: {},
+ service: {
+ serviceHierarchy: {
+ 'servicedId': {
+ 'networks': {
+ 'networkName': {
+ 'properties': {
+ 'max_instances': 1
}
}
}
}
},
- serviceInstance : {
- 'servicedId' : {
- 'existingNetworksCounterMap' : {
- 'modelCustomizationId' : 1
+ serviceInstance: {
+ 'servicedId': {
+ 'existingNetworksCounterMap': {
+ 'modelCustomizationId': 1
},
- 'networks' : {
- 'networkName' :{
+ 'networks': {
+ 'networkName': {
'action': 'Create',
- 'originalName' : 'networkName'
+ 'originalName': 'networkName'
}
}
}
});
let node = {
- data : {
- id : 'networkId',
- name : 'networkName',
+ data: {
+ id: 'networkId',
+ name: 'networkName',
action: 'Create',
- modelCustomizationId : "modelCustomizationId",
+ modelCustomizationId: "modelCustomizationId",
modelUniqueId: "modelCustomizationId"
}
};
- let result = networkModel.getNodeCount(<any>node , serviceId);
+ let result = networkModel.getNodeCount(<any>node, serviceId);
expect(result).toEqual(1);
node.data.modelCustomizationId = 'networkId_notExist';
node.data.modelUniqueId = 'networkId_notExist';
- result = networkModel.getNodeCount(<any>node , serviceId);
+ result = networkModel.getNodeCount(<any>node, serviceId);
expect(result).toEqual(0);
});
- test('getMenuAction: showAuditInfoNetwork', ()=>{
+ test('getMenuAction: showAuditInfoNetwork', () => {
jest.spyOn(MockNgRedux.getInstance(), 'getState').mockReturnValue({
global: {
});
jest.spyOn(_sharedTreeService, 'isRetryMode').mockReturnValue(true);
let node = {
- data : {
+ data: {
"modelId": "6b528779-44a3-4472-bdff-9cd15ec93450",
"action": "Create",
"isFailed": true,
test('Info for network should be correct', () => {
const model = getNetworkModel();
const instance = getNetworkInstance();
- let actualNetworkInfo = networkModel.getInfo(model,instance);
+ let actualNetworkInfo = networkModel.getInfo(model, instance);
let expectedNetworkInfo = [
ModelInformationItem.createInstance('Network role', "network role 1, network role 2"),
ModelInformationItem.createInstance("Route target id", null),
expect(actualNetworkInfo).toEqual(expectedNetworkInfo);
});
- function getNetworkModel(){
+ function getNetworkModel() {
return {
- "customizationUuid":"94fdd893-4a36-4d70-b16a-ec29c54c184f",
- "name":"ExtVL",
- "version":"37.0",
- "description":"ECOMP generic virtual link (network) base type for all other service-level and global networks",
- "uuid":"ddc3f20c-08b5-40fd-af72-c6d14636b986",
- "invariantUuid":"379f816b-a7aa-422f-be30-17114ff50b7c",
- "max":1,
- "min":0,
- "isEcompGeneratedNaming":false,
- "type":"VL",
- "modelCustomizationName":"ExtVL 0",
- "roles":["network role 1"," network role 2"],
- "properties":{
- "network_role":"network role 1, network role 2",
+ "customizationUuid": "94fdd893-4a36-4d70-b16a-ec29c54c184f",
+ "name": "ExtVL",
+ "version": "37.0",
+ "description": "ECOMP generic virtual link (network) base type for all other service-level and global networks",
+ "uuid": "ddc3f20c-08b5-40fd-af72-c6d14636b986",
+ "invariantUuid": "379f816b-a7aa-422f-be30-17114ff50b7c",
+ "max": 1,
+ "min": 0,
+ "isEcompGeneratedNaming": false,
+ "type": "VL",
+ "modelCustomizationName": "ExtVL 0",
+ "roles": ["network role 1", " network role 2"],
+ "properties": {
+ "network_role": "network role 1, network role 2",
"network_assignments":
"{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}",
- "exVL_naming":"{ecomp_generated_naming=true}","network_flows":"{is_network_policy=false, is_bound_to_vpn=false}",
- "network_homing":"{ecomp_selected_instance_node_target=false}"
+ "exVL_naming": "{ecomp_generated_naming=true}",
+ "network_flows": "{is_network_policy=false, is_bound_to_vpn=false}",
+ "network_homing": "{ecomp_selected_instance_node_target=false}"
}
};
}
-
-
- function getServiceHierarchy(){
+ function getServiceHierarchy() {
return {
"service": {
"uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config";
import {ComponentInfoType} from "../../../component-info/component-info-model";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
+import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
export class NetworkModelInfo implements ILevelNodeInfo {
constructor(private _dynamicInputsService: DynamicInputsService,
private _duplicateService: DuplicateService,
private modalService: SdcUiServices.ModalService,
private _iframeService: IframeService,
+ private _featureFlagsService: FeatureFlagsService,
private _store: NgRedux<AppState>) {
}
************************************************************/
getModel = (networkModelId: string, instance: NetworkInstance, serviceHierarchy): NetworkModel => {
const originalModelName = instance.originalName ? instance.originalName : networkModelId;
- return new NetworkModel(serviceHierarchy[this.name][originalModelName]);
+ return new NetworkModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags());
};
counter -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'networks');
const properties = this._store.getState().service.serviceHierarchy[serviceModelId].networks[node.data.name].properties;
- const maxInstances: number = !_.isNil(properties) ? (properties.max_instances || 1) : 1;
- const isReachedLimit = !(maxInstances > counter);
+ const flags = FeatureFlagsService.getAllFlags(this._store);
+ const isReachedLimit: boolean = this._sharedTreeService.isReachedToMaxInstances(properties, counter, flags);
const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !isReachedLimit;
return new AvailableNodeIcons(showAddIcon, isReachedLimit)
}
}
+class MockFeatureFlagsService extends FeatureFlagsService{
+ getAllFlags(): { [p: string]: boolean } {
+ return {};
+ }
+}
+
describe('VFModule Model Info', () => {
let injector;
let _dynamicInputsService : DynamicInputsService;
let _vfModuleUpgradePopupService : VfModuleUpgradePopupService;
let _iframeService : IframeService;
let _componentInfoService : ComponentInfoService;
+ let _featureFlagsService : FeatureFlagsService;
+
beforeAll(done => (async () => {
TestBed.configureTestingModule({
AaiService,
HttpClient,
HttpHandler,
- FeatureFlagsService,
+ {provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
ComponentInfoService
]
});
injector = getTestBed();
_sharedTreeService = injector.get(SharedTreeService);
_componentInfoService = injector.get(ComponentInfoService)
- vfModuleModel = new VFModuleModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vfModulePopupService, _vfModuleUpgradePopupService, _iframeService, MockNgRedux.getInstance(),_componentInfoService);
+ _featureFlagsService = injector.get(FeatureFlagsService);
+ vfModuleModel = new VFModuleModelInfo(_dynamicInputsService, _sharedTreeService, _dialogService, _vfModulePopupService, _vfModuleUpgradePopupService, _iframeService,_featureFlagsService, MockNgRedux.getInstance(),_componentInfoService);
})().then(done).catch(done.fail));
private _vfModulePopupService: VfModulePopuopService,
private _vfModuleUpgradePopupService: VfModuleUpgradePopupService,
private _iframeService: IframeService,
+ private _featureFlagsService: FeatureFlagsService,
private _store: NgRedux<AppState>,
private _componentInfoService: ComponentInfoService) {
}
maxNodes = vnfModules[node.data.name].properties.maxCountInstances || 1;
}
return !(maxNodes > currentNodeCount);
-
}
getMenuAction(node: ITreeNode, serviceModelId: string): { [methodName: string]: { method: Function, visible: Function, enable: Function } } {
import {HttpClient, HttpHandler} from "@angular/common/http";
import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
import {VfModuleUpgradePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
+class MockFeatureFlagsService extends FeatureFlagsService{
+ getAllFlags(): { [p: string]: boolean } {
+ return {};
+ }
+}
describe('Vnf Model Info', () => {
let injector;
let _duplicateService : DuplicateService;
let _iframeService : IframeService;
let _componentInfoService : ComponentInfoService;
+ let _featureFlagsService : FeatureFlagsService;
let _store : NgRedux<AppState>;
let vnfModel: VnfModelInfo;
AaiService,
HttpClient,
HttpHandler,
- FeatureFlagsService,
+ {provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
ComponentInfoService,
IframeService]
}).compileComponents();
injector = getTestBed();
_sharedTreeService = injector.get(SharedTreeService);
_store = injector.get(NgRedux);
- _componentInfoService = injector.get(ComponentInfoService);
+ _featureFlagsService = injector.get(FeatureFlagsService);
vnfModel = new VnfModelInfo(
_dynamicInputsService,
null,
_iframeService,
_componentInfoService,
+ _featureFlagsService,
_store);
import {ComponentInfoService} from "../../../component-info/component-info.service";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
import {VfModuleUpgradePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
+import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
export class VnfModelInfo implements ILevelNodeInfo {
constructor(private _dynamicInputsService: DynamicInputsService,
private _dialogService: DialogService,
private _vnfPopupService: VnfPopupService,
private _vfModulePopupService: VfModulePopuopService,
- private _vfModuleUpgradePopupService : VfModuleUpgradePopupService,
+ private _vfModuleUpgradePopupService: VfModuleUpgradePopupService,
private _duplicateService: DuplicateService,
private modalService: SdcUiServices.ModalService,
private _iframeService: IframeService,
private _componentInfoService: ComponentInfoService,
+ private _featureFlagsService: FeatureFlagsService,
private _store: NgRedux<AppState>) {
}
************************************************************/
getModel = (vnfModelId: string, instance: VnfInstance, serviceHierarchy): VNFModel => {
const originalModelName = instance.originalName ? instance.originalName : vnfModelId;
- return new VNFModel(serviceHierarchy[this.name][originalModelName]);
+ return new VNFModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags());
};
node.typeName = this.typeName;
node.menuActions = this.getMenuAction(<any>node, model.uuid);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
- node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: "";
+ node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
node = this._sharedTreeService.addingStatusProperty(node);
return node;
};
* return next level object (VFModule)
************************************************************/
getNextLevelObject = (): VFModuleModelInfo => {
- return new VFModuleModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vfModulePopupService, this._vfModuleUpgradePopupService, this._iframeService, this._store, this._componentInfoService);
+ return new VFModuleModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vfModulePopupService, this._vfModuleUpgradePopupService, this._iframeService, this._featureFlagsService, this._store, this._componentInfoService);
};
/***********************************************************
counter -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'vnfs');
const properties = this._store.getState().service.serviceHierarchy[serviceModelId].vnfs[node.data.name].properties;
- const maxInstances: number = !_.isNil(properties) ? (properties.max_instances || 1) : 1;
- const isReachedLimit = !(maxInstances > counter);
+ const flags = FeatureFlagsService.getAllFlags(this._store);
+ const isReachedLimit: boolean = this._sharedTreeService.isReachedToMaxInstances(properties, counter, flags);
const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !isReachedLimit;
return new AvailableNodeIcons(showAddIcon, isReachedLimit)
}
},
showAuditInfo: {
method: (node, serviceModelId) => {
- const instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.data.vnfStoreKey];
- this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNF', this);
- },
+ const instance = this._store.getState().service.serviceInstance[serviceModelId].vnfs[node.data.vnfStoreKey];
+ this._sharedTreeService.openAuditInfoModal(node, serviceModelId, instance, 'VNF', this);
+ },
visible: (node) => this._sharedTreeService.shouldShowAuditInfo(node),
enable: (node) => this._sharedTreeService.shouldShowAuditInfo(node)
},
getInfo(model, instance): ModelInformationItem[] {
const modelInformation = !_.isEmpty(model) ? [
- ModelInformationItem.createInstance("Min instances", !_.isNull(model.min)? String(model.min): null),
- ModelInformationItem.createInstance("Max instances", !_.isNull(model.max)? String(model.max): null)
+ ModelInformationItem.createInstance("Min instances", !_.isNull(model.min) ? String(model.min) : null),
+ ModelInformationItem.createInstance("Max instances", !_.isNull(model.max) ? String(model.max) : null)
] : [];
const instanceInfo = !_.isEmpty(instance) ? [
undoDeleteActionVrfInstance
} from "../../../../../shared/storeUtil/utils/vrf/vrf.actions";
import * as _ from "lodash";
+import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
export class VrfModelInfo implements ILevelNodeInfo {
constructor(private _store: NgRedux<AppState>,
private _sharedTreeService: SharedTreeService,
private _dialogService: DialogService,
private _iframeService: IframeService,
+ private _featureFlagsService : FeatureFlagsService,
private _networkStepService: NetworkStepService,
private _vpnStepService: VpnStepService) {
}
return new VpnModelInfo(this._store, this._sharedTreeService);
} else {
if (nextLevelType === 'networks') {
- return new NetworkModelInfo(null, this._sharedTreeService, null, null, null, null, null, this._store);
+ return new NetworkModelInfo(null, this._sharedTreeService, null, null, null, null, null,this._featureFlagsService, this._store);
}
}
};
import {ObjectToTreeService} from "../objectToTree.service";
import * as _ from "lodash";
import {IModelTreeNodeModel} from "../../../objectsToTree/objectToModelTree/modelTreeNode.model";
+import {FeatureFlagsService} from "../../../../shared/services/featureFlag/feature-flags.service";
@Injectable()
export class ObjectToModelTreeService {
numberOfPlusButton: number;
- constructor(private _objectToTreeService: ObjectToTreeService) {
+
+ constructor(private _objectToTreeService: ObjectToTreeService, private _featureFlagsService: FeatureFlagsService) {
}
/***********************************************************
let _this = this;
const firstLevelOptions: ILevelNodeInfo[] = _this._objectToTreeService.getFirstLevelOptions();
let nodes = [];
+ let flags = this._featureFlagsService.getAllFlags();
for (let option of firstLevelOptions) {
_.forOwn(serviceModel[option.name], function (item, key) {
- nodes.push(_this.addFirstLevelModel(serviceModel.service.uuid, key, item, item.type, serviceModel, option));
+ nodes.push(_this.addFirstLevelModel(serviceModel.service.uuid, key, item, item.type, serviceModel, option, flags));
});
}
return nodes;
}
- calculateNumberOfNodesWithPlusIcon(serviceModel, nodes) : void {
- this.numberOfPlusButton = nodes.reduce((sum, node)=>{
- let showNodeIconResult = node.showNodeIcons({data : node}, serviceModel.service.uuid);
- return (!_.isNil(showNodeIconResult) && showNodeIconResult.addIcon && !showNodeIconResult.vIcon) ? sum + 1 : sum;
+ calculateNumberOfNodesWithPlusIcon(serviceModel, nodes): void {
+ this.numberOfPlusButton = nodes.reduce((sum, node) => {
+ let showNodeIconResult = node.showNodeIcons({data: node}, serviceModel.service.uuid);
+ return (!_.isNil(showNodeIconResult) && showNodeIconResult.addIcon && !showNodeIconResult.vIcon) ? sum + 1 : sum;
}, 0);
}
* @param parentModel - current parent Model object
* @param levelNodeInfo - current level node information
************************************************************/
- private addFirstLevelModel(serviceId: string, name, currentModel, type, parentModel, levelNodeInfo: ILevelNodeInfo) {
- let node = ObjectToModelTreeService.convertItemToTreeNode(serviceId, name, currentModel, type, null, levelNodeInfo);
- node.children = this.addNextLevelNodes(serviceId, currentModel, parentModel, levelNodeInfo, node);
+ private addFirstLevelModel(serviceId: string, name, currentModel, type, parentModel, levelNodeInfo: ILevelNodeInfo, flags?: { [key: string]: boolean }) {
+ let node = ObjectToModelTreeService.convertItemToTreeNode(serviceId, name, currentModel, type, null, levelNodeInfo, flags);
+ node.children = this.addNextLevelNodes(serviceId, currentModel, parentModel, levelNodeInfo, node, flags);
return node;
}
* @param levelNodeInfo - current level node information
* @param parentNode - parent node.
************************************************************/
- addNextLevelNodes(serviceId: string, currentModel, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode): any[] {
+ addNextLevelNodes(serviceId: string, currentModel, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode, flags?: { [key: string]: boolean }): any[] {
if (!_.isNil(levelNodeInfo.childNames) && levelNodeInfo.childNames.length > 0) {
levelNodeInfo.childNames.forEach(function (childName) {
if (!_.isNil(currentModel[childName])) {
let nextLevelNodeInfo = levelNodeInfo.getNextLevelObject.apply(this, [childName]);
parentNode.children = Object.keys(currentModel[childName]).map((key) =>
- ObjectToModelTreeService.convertItemToTreeNode(serviceId, key, currentModel[childName][key], childName, currentModel, nextLevelNodeInfo));
+ ObjectToModelTreeService.convertItemToTreeNode(serviceId, key, currentModel[childName][key], childName, currentModel, nextLevelNodeInfo, flags));
}
})
}
* @param parentModel - current parent model
* @param levelNodeInfo - current levelNodeInfo object
************************************************************/
- static convertItemToTreeNode(serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo) {
- let node : IModelTreeNodeModel = {
+ static convertItemToTreeNode(serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo, flags?: { [key: string]: boolean }) {
+ const type: string = levelNodeInfo.getType();
+ let node: IModelTreeNodeModel = {
id: currentModel.customizationUuid || currentModel.uuid,
- modelCustomizationId : currentModel.customizationUuid,
- modelVersionId: currentModel.uuid,
- modelUniqueId : currentModel.customizationUuid || currentModel.uuid,
+ modelCustomizationId: currentModel.customizationUuid,
+ modelVersionId: currentModel.uuid,
+ modelUniqueId: currentModel.customizationUuid || currentModel.uuid,
name: name,
tooltip: levelNodeInfo.getTooltip(),
- type: levelNodeInfo.getType(),
+ type,
count: currentModel.count || 0,
- max: currentModel.max || 1,
+ max: ObjectToModelTreeService.getMax(currentModel, type, flags),
children: [],
disabled: false,
dynamicInputs: levelNodeInfo.updateDynamicInputsDataFromModel(currentModel),
return node;
}
+ static getMax(currentModel, type, flags: { [key: string]: boolean }) {
+ if (flags && !!flags['FLAG_2002_UNLIMITED_MAX'] && (type === 'VF' || type === 'Network' || type === 'VFmodule')) {
+ return !_.isNil(currentModel.max) ? currentModel.max : null;
+ } else {
+ return currentModel.max || 1
+ }
+ }
- static addExtraFunctionality(node, serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo){
+
+ static addExtraFunctionality(node, serviceId: string, name: string, currentModel: any, valueType: string, parentModel: string, levelNodeInfo: ILevelNodeInfo) {
node.onAddClick = (node, serviceId) => levelNodeInfo.onClickAdd(node, serviceId);
node.getNodeCount = (node, serviceId) => levelNodeInfo.getNodeCount(node, serviceId);
node.getMenuAction = (node, serviceId) => levelNodeInfo.getMenuAction(node, serviceId);
node.showNodeIcons = (node, serviceId) => levelNodeInfo.showNodeIcons(node, serviceId);
node.typeName = levelNodeInfo.typeName;
node.getModel = levelNodeInfo.getModel.bind(levelNodeInfo);
- node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : ()=>{};
+ node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : () => {
+ };
node.componentInfoType = levelNodeInfo.componentInfoType;
return node;
}
import {NetworkStepService} from "./models/vrf/vrfModal/networkStep/network.step.service";
import {VpnStepService} from "./models/vrf/vrfModal/vpnStep/vpn.step.service";
import { VfModuleUpgradePopupService } from "../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
+import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
@Injectable()
export class ObjectToTreeService {
private _networkStepService : NetworkStepService,
private _vpnStepService : VpnStepService,
private _aaiService : AaiService,
+ private _featureFlagsService: FeatureFlagsService,
private _store : NgRedux<AppState>) {
}
* return all first optional first level of the model tree
************************************************************/
getFirstLevelOptions(): ILevelNodeInfo[] {
- return [new VnfModelInfo(this._dynamicInputsService, this._sharedTreeService, this._defaultDataGeneratorService, this._dialogService, this._vnfPopupService, this._vfModulePopupService, this._vfModuleUpgradePopupService,this._duplicateService, this._modalService, this._iframeService, this._componentInfoService, this._store)
- , new NetworkModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._networkPopupService, this._duplicateService, this._modalService, this._iframeService, this._store),
+ return [new VnfModelInfo(this._dynamicInputsService, this._sharedTreeService, this._defaultDataGeneratorService, this._dialogService, this._vnfPopupService, this._vfModulePopupService, this._vfModuleUpgradePopupService,this._duplicateService, this._modalService, this._iframeService, this._componentInfoService, this._featureFlagsService, this._store)
+ , new NetworkModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._networkPopupService, this._duplicateService, this._modalService, this._iframeService, this._featureFlagsService, this._store),
new PnfModelInfo(),
- new VrfModelInfo(this._store, this._sharedTreeService, this._dialogService, this._iframeService, this._networkStepService, this._vpnStepService),
+ new VrfModelInfo(this._store, this._sharedTreeService, this._dialogService, this._iframeService, this._featureFlagsService, this._networkStepService, this._vpnStepService),
new CollectionResourceModelInfo(this._store, this._sharedTreeService),
new ConfigurationModelInfo(this._dynamicInputsService, this._sharedTreeService),
new VnfGroupingModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._vnfGroupPopupService, this._iframeService, this._aaiService, this._store)];
import {undoUpgradeService, upgradeService} from "../../../shared/storeUtil/utils/service/service.actions";
import {VNFMethods} from "../../../shared/storeUtil/utils/vnf/vnf.actions";
import {FeatureFlagsService, Features} from "../../../shared/services/featureFlag/feature-flags.service";
+import {Utils} from "../../../shared/utils/utils";
@Injectable()
export class SharedTreeService {
const mode = this._store.getState().global.drawingBoardStatus;
return mode === DrawingBoardModes.EDIT || mode=== DrawingBoardModes.CREATE;
}
+
+
+ isReachedToMaxInstances(properties, counter, flags): boolean{
+ let maxInstances = Utils.getMaxFirstLevel(properties, flags);
+ if(_.isNil(maxInstances)){
+ return false;
+ }else {
+ return !(maxInstances > counter);
+ }
+ }
/************************************************
return number of instances with action Delete
@type: vnfs networks, vngGroups (not vfModule)
import {VfModule} from "../../../models/vfModule";
import {VNFModel} from "../../../models/vnfModel";
import {VnfGroupModel} from "../../../models/vnfGroupModel";
+import {FeatureFlagsService} from "../../../services/featureFlag/feature-flags.service";
@Injectable()
export class BasicPopupService {
}
getModelFromResponse(result: any, modelType: string, modelName: string) {
+ let flags = FeatureFlagsService.getAllFlags(this._store);
let rawModel = result[modelType][modelName];
if (!rawModel) return;
switch (modelType){
case 'vnfs' : {
- return new VNFModel(rawModel);
+ return new VNFModel(rawModel, flags);
}
case 'vfModules' : {
return new VfModule(rawModel);
}
case 'networks' : {
- return new NetworkModel(rawModel);
+ return new NetworkModel(rawModel, flags);
}
case 'vnfGroups' : {
return new VnfGroupModel(rawModel);
Level1Model, Level1ModelProperties,
Level1ModelResponseInterface
} from "./nodeModel";
-import {VfcInstanceGroupMap} from "./vfcInstanceGroupMap";
+import {Utils} from "../utils/utils";
-export interface NetworkProperties extends Level1ModelProperties{
+export interface NetworkProperties extends Level1ModelProperties {
ecomp_generated_naming: string;
network_role: string;
}
-export interface NetworkModelResponseInterface extends Level1ModelResponseInterface{
+export interface NetworkModelResponseInterface extends Level1ModelResponseInterface {
properties: NetworkProperties;
}
-export class NetworkModel extends Level1Model{
+export class NetworkModel extends Level1Model {
roles: string[] = [];
properties: NetworkProperties;
- constructor(networkJson?: NetworkModelResponseInterface){
+ constructor(networkJson?: NetworkModelResponseInterface, flags?: { [key: string]: boolean }) {
super(networkJson);
- if(networkJson && networkJson.properties){
+ if (networkJson && networkJson.properties) {
this.properties = networkJson.properties;
// expecting network_role to be a comma-saparated list
this.roles = networkJson.properties.network_role ? networkJson.properties.network_role.split(',') : [];
+ this.max = Utils.getMaxFirstLevel(this.properties, flags);
}
}
Level1ModelProperties,
Level1ModelResponseInterface
} from "./nodeModel";
+import {Utils} from "../utils/utils";
-
-
-export interface VnfProperties extends Level1ModelProperties{
+export interface VnfProperties extends Level1ModelProperties {
ecomp_generated_naming: string;
}
-export interface VNFModelResponseInterface extends Level1ModelResponseInterface{
+export interface VNFModelResponseInterface extends Level1ModelResponseInterface {
properties: VnfProperties;
}
-export class VNFModel extends Level1Model{
+export class VNFModel extends Level1Model {
properties: VnfProperties;
- constructor(vnfJson?: VNFModelResponseInterface) {
+ constructor(vnfJson?: VNFModelResponseInterface, flags?: { [key: string]: boolean }) {
super(vnfJson);
if (vnfJson) {
this.properties = vnfJson.properties;
+ this.max = Utils.getMaxFirstLevel(this.properties, flags);
}
}
-
}
return FeatureFlagsService.getFlagState(flag, this.store);
}
+ public getAllFlags(): { [key: string]: boolean}{
+ return this.store.getState().global.flags;
+ }
+
+ public static getAllFlags(store: NgRedux<AppState>): { [key: string]: boolean}{
+ return store.getState().global.flags;
+ }
+
/*static method for easy refactoring of code, so no injection of FeatureFlagsService is needed*/
public static getFlagState(flag: Features, store: NgRedux<AppState>):boolean {
let storeStateGlobalFields = store.getState().global;
export class Utils {
+ static getMaxFirstLevel(properties, flags: { [key: string]: boolean }) : number | null{
+ if (flags && !!flags['FLAG_2002_UNLIMITED_MAX']) {
+ return !_.isNil(properties) && !_.isNil(properties.max_instances) ? properties.max_instances : null;
+ } else {
+ return properties.max_instances || 1;
+ }
+ }
+
public static clampNumber = (number, min, max) => {
return Math.max(min, Math.min(number, max));
};