RIFT-15577 - part one: make 'Add' immediately create catalog item in backend

Signed-off-by: Bob Gallagher <bob.gallagher@riftio.com>
diff --git a/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js b/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js
index 89e0a87..2808412 100644
--- a/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js
+++ b/skyquake/plugins/composer/src/src/libraries/model/DescriptorTemplates.js
@@ -26,11 +26,10 @@
 import guid from './../guid'
 import InstanceCounter from './../InstanceCounter'
 
+const generateName = (prefix, counter) => prefix + '-' + InstanceCounter.count(counter);
+
 export default {
 	'vnfd': {
-		'id': '5b9af24e-2c8f-4792-9d6e-ff9eabb97f15',
-		'name': 'vnfd-1',
-		'short-name': 'vnfd-1',
 		'description': 'A simple VNF descriptor w/ one VDU',
 		'version': '1.0',
 		'connection-point': [
@@ -41,8 +40,11 @@
 		],
 		'vdu': [
 			{
-				'id': 'abd6831e-f811-4580-9aad-1de9c6424180',
-				'name': 'vdu-1',
+				'uiState': {
+					'type': 'vdu'
+				},
+				'id': () => guid(5),
+				'name': () => generateName('vdu', 'vnfd.vdu'),
 				'vm-flavor': {
 					'vcpu-count': 4,
 					'memory-mb': 16384,
@@ -63,7 +65,7 @@
 	},
 	'vnfd.internal-vld': {
 		'id': () => guid(),
-		'name': () => 'vld-' + InstanceCounter.count('new.vnfd.internal-vld'),
+		'name': () => generateName('vld', 'new.vnfd.internal-vld'),
 		'description': 'Virtual link for internal fabric',
 		'type': 'ELAN'
 	}
diff --git a/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js b/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js
index ea57627..1098f0e 100644
--- a/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js
+++ b/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js
@@ -49,6 +49,18 @@
 	return _.isEqual(aMetaData, bMetaData);
 };
 
+function createItem (type) {
+	let newItem = DescriptorModelMetaFactory.createModelInstanceForType(type);
+	if (newItem){
+		newItem.id = guid();
+		UID.assignUniqueId(newItem.uiState);
+		newItem.uiState.isNew = true;
+		newItem.uiState.modified = true;
+		newItem.uiState['instance-ref-count'] = 0;
+	}
+	return newItem;
+}
+
 class CatalogDataStore {
 
 	constructor() {
@@ -133,16 +145,13 @@
 	}
 
 	addNewItemToCatalog(newItem) {
-		const id = guid();
 		const type = newItem.uiState.type;
-		newItem.id = id;
-		UID.assignUniqueId(newItem.uiState);
 		this.getCatalogs().filter(d => d.type === type).forEach(catalog => {
 			catalog.descriptors.push(newItem);
 		});
 		// update indexes and integrate new model into catalog
 		this.updateCatalogIndexes(this.getCatalogs());
-		return this.getCatalogItemById(id);
+		return this.getCatalogItemById(newItem.id);
 	}
 
 	updateCatalogIndexes(catalogs) {
@@ -445,18 +454,8 @@
 	}
 
 	createCatalogItem(type = 'nsd') {
-		const model = DescriptorModelMetaFactory.createModelInstanceForType(type);
-		if (model) {
-			const newItem = this.addNewItemToCatalog(model);
-			newItem.uiState.isNew = true;
-			newItem.uiState.modified = true;
-			newItem.uiState['instance-ref-count'] = 0;
-			// open the new model for editing in the canvas/details panels
-			setTimeout(() => {
-				this.selectCatalogItem(newItem);
-				CatalogItemsActions.editCatalogItem.defer(newItem);
-			}, 200);
-		}
+		const newItem = createItem(type);
+		this.saveItem(newItem)
 	}
 
 	duplicateSelectedCatalogItem() {
@@ -464,6 +463,8 @@
 		if (item) {
 			const newItem = _.cloneDeep(item);
 			newItem.name = newItem.name + ' Copy';
+			newItem.id = guid();
+			UID.assignUniqueId(newItem.uiState);
 			const nsd = this.addNewItemToCatalog(newItem);
 			this.selectCatalogItem(nsd);
 			nsd.uiState.isNew = true;
@@ -537,7 +538,13 @@
 	saveCatalogItem() {
 		const activeItem = ComposerAppStore.getState().item;
 		if (activeItem) {
-			if (activeItem.uiState['instance-ref-count'] > 0) {
+			this.saveItem(activeItem);
+		}
+	}
+
+	saveItem(item) {
+		if (item) {
+			if (item.uiState['instance-ref-count'] > 0) {
 				console.log('cannot save NSD/VNFD with references to instantiated Network Services');
 				ComposerAppActions.showError.defer({
 					errorMessage: 'Cannot save NSD/VNFD with references to instantiated Network Services'
@@ -545,25 +552,29 @@
 				return;
 			}
 			const success = () => {
-				delete activeItem.uiState.isNew;
-				delete activeItem.uiState.modified;
-				this.updateCatalogItem(activeItem);
+				delete item.uiState.modified;
+				if (item.uiState.isNew) {
+					this.addNewItemToCatalog(item);
+					delete item.uiState.isNew;
+				} else {
+					this.updateCatalogItem(item);
+				}
 				// TODO should the save action clear the undo/redo stack back to the beginning?
-				this.resetSnapshots(activeItem);
+				this.resetSnapshots(item);
 				ModalOverlayActions.hideModalOverlay.defer();
-				CatalogItemsActions.editCatalogItem.defer(activeItem);
+				CatalogItemsActions.editCatalogItem.defer(item);
 			};
 			const failure = () => {
 				ModalOverlayActions.hideModalOverlay.defer();
-				CatalogItemsActions.editCatalogItem.defer(activeItem);
+				CatalogItemsActions.editCatalogItem.defer(item);
 			};
 			const exception = () => {
-				console.warn('unable to save catalog item', activeItem);
+				console.warn('unable to save catalog item', item);
 				ModalOverlayActions.hideModalOverlay.defer();
-				CatalogItemsActions.editCatalogItem.defer(activeItem);
+				CatalogItemsActions.editCatalogItem.defer(item);
 			};
 			ModalOverlayActions.showModalOverlay.defer();
-			this.getInstance().saveCatalogItem(activeItem).then(success, failure).catch(exception);
+			this.getInstance().saveCatalogItem(item).then(success, failure).catch(exception);
 		}
 	}