X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FUI.git;a=blobdiff_plain;f=skyquake%2Fplugins%2Fcomposer%2Fsrc%2Fsrc%2Fstores%2FCatalogDataStore.js;h=9179f21471de6343debc934f96eff7b7815f7c10;hp=ea57627603c40a5dcce9a0447a5224d4d7f8b3d6;hb=refs%2Ftags%2Fv2.0.1;hpb=30879fffbecf6d78cde249fecf68f6335555711a diff --git a/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js b/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js index ea5762760..9179f2147 100644 --- a/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js +++ b/skyquake/plugins/composer/src/src/stores/CatalogDataStore.js @@ -1,6 +1,6 @@ /* - * + * * Copyright 2016 RIFT.IO Inc * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,9 @@ */ 'use strict'; -import _ from 'lodash' +import _pick from 'lodash/pick' +import _isEqual from 'lodash/isEqual' +import _cloneDeep from 'lodash/cloneDeep' import cc from 'change-case' import alt from '../alt' import UID from '../libraries/UniqueId' @@ -34,7 +36,6 @@ import ComposerAppActions from '../actions/ComposerAppActions' import CatalogDataSource from '../sources/CatalogDataSource' import ComposerAppStore from '../stores/ComposerAppStore' import SelectionManager from '../libraries/SelectionManager' -import ExportSelectorDialog from '../components/ExportSelectorDialog' const defaults = { catalogs: [], @@ -44,11 +45,22 @@ const defaults = { const areCatalogItemsMetaDataEqual = function (a, b) { const metaProps = ['id', 'name', 'short-name', 'description', 'vendor', 'version']; - const aMetaData = _.pick(a, metaProps); - const bMetaData = _.pick(b, metaProps); - return _.isEqual(aMetaData, bMetaData); + const aMetaData = _pick(a, metaProps); + const bMetaData = _pick(b, metaProps); + 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; + } + return newItem; +} + class CatalogDataStore { constructor() { @@ -133,16 +145,13 @@ class CatalogDataStore { } 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) { @@ -179,7 +188,6 @@ class CatalogDataStore { }); updatedCatalogs.filter(d => d.type === 'nsd').forEach(catalog => { catalog.descriptors = catalog.descriptors.map(descriptor => { - const instanceRefCount = parseInt(descriptor.uiState['instance-ref-count'], 10); if (descriptor['constituent-vnfd']) { descriptor.vnfd = descriptor['constituent-vnfd'].map(d => { const vnfdId = d['vnfd-id-ref']; @@ -187,12 +195,8 @@ class CatalogDataStore { if (!vnfd) { throw new ReferenceError('no VNFD found in the VNFD Catalog for the constituent-vnfd: ' + d); } - if (!isNaN(instanceRefCount) && instanceRefCount > 0) { - // this will notify user that this item cannot be updated when/if they make a change to it - vnfd.uiState['instance-ref-count'] = instanceRefCount; - } // create an instance of this vnfd to carry transient ui state properties - const instance = _.cloneDeep(vnfd); + const instance = _cloneDeep(vnfd); instance.uiState['member-vnf-index'] = d['member-vnf-index']; instance['vnf-configuration'] = d['vnf-configuration']; instance['start-by-default'] = d['start-by-default']; @@ -309,17 +313,9 @@ class CatalogDataStore { // compare just the catalog uiState data (id, name, short-name, description, etc.) const modified = !areCatalogItemsMetaDataEqual(d, item); if (modified) { - if (d.uiState['instance-ref-count'] > 0) { - console.log('cannot edit NSD/VNFD with references to instantiated Network Services'); - ComposerAppActions.showError.defer({ - errorMessage: 'Cannot edit NSD/VNFD with references to instantiated Network Services' - }); - return _.cloneDeep(d); - } else { - item.uiState.modified = modified; - requiresSave = true; - this.addSnapshot(item); - } + item.uiState.modified = modified; + requiresSave = true; + this.addSnapshot(item); } return item; } @@ -343,17 +339,9 @@ class CatalogDataStore { // replace the old descriptor with the updated one catalog.descriptors = catalog.descriptors.map(d => { if (d.id === descriptorId) { - if (d.uiState['instance-ref-count'] > 0) { - console.log('cannot edit NSD/VNFD with references to instantiated Network Services'); - ComposerAppActions.showError.defer({ - errorMessage: 'Cannot edit NSD/VNFD with references to instantiated Network Services' - }); - return _.cloneDeep(d); - } else { - itemDescriptor.model.uiState.modified = true; - this.addSnapshot(itemDescriptor.model); - return itemDescriptor.model; - } + itemDescriptor.model.uiState.modified = true; + this.addSnapshot(itemDescriptor.model); + return itemDescriptor.model; } return d; }); @@ -405,27 +393,19 @@ class CatalogDataStore { if (item.uiState.isNew) { CatalogDataStore.confirmDelete(remove, confirmDeleteCancel); } else { - if (item.uiState['instance-ref-count'] > 0) { - console.log('cannot delete NSD/VNFD with references to instantiated Network Services'); - ComposerAppActions.showError.defer({ - errorMessage: 'Cannot delete NSD/VNFD with references to instantiated Network Services' - }); - undo(); - } else { - const confirmDeleteOK = event => { - event.preventDefault(); - item.uiState.deleted = true; - this.setState({catalogs: this.getCatalogs()}); - ModalOverlayActions.showModalOverlay.defer(); - this.getInstance().deleteCatalogItem(item.uiState.type, item.id) - .then(remove, undo) - .then(ModalOverlayActions.hideModalOverlay, ModalOverlayActions.hideModalOverlay) - .catch(function() { - console.log('overcoming ES6 unhandled rejection red herring'); - }); - }; - CatalogDataStore.confirmDelete(confirmDeleteOK, confirmDeleteCancel); - } + const confirmDeleteOK = event => { + event.preventDefault(); + item.uiState.deleted = true; + this.setState({catalogs: this.getCatalogs()}); + ModalOverlayActions.showModalOverlay.defer(); + this.getInstance().deleteCatalogItem(item.uiState.type, item.id) + .then(remove, undo) + .then(ModalOverlayActions.hideModalOverlay, ModalOverlayActions.hideModalOverlay) + .catch(function() { + console.log('overcoming ES6 unhandled rejection red herring'); + }); + }; + CatalogDataStore.confirmDelete(confirmDeleteOK, confirmDeleteCancel); } } } @@ -445,40 +425,15 @@ class CatalogDataStore { } 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() { - const item = this.getFirstSelectedCatalogItem(); - if (item) { - const newItem = _.cloneDeep(item); - newItem.name = newItem.name + ' Copy'; - const nsd = this.addNewItemToCatalog(newItem); - this.selectCatalogItem(nsd); - nsd.uiState.isNew = true; - nsd.uiState.modified = true; - nsd.uiState['instance-ref-count'] = 0; - // note duplicated items get a new id, map the layout position - // of the old id to the new id in order to preserve the layout - if (nsd.uiState.containerPositionMap) { - nsd.uiState.containerPositionMap[nsd.id] = nsd.uiState.containerPositionMap[item.id]; - delete nsd.uiState.containerPositionMap[item.id]; - } - setTimeout(() => { - this.selectCatalogItem(nsd); - CatalogItemsActions.editCatalogItem.defer(nsd); - }, 200); + // make request to backend to duplicate an item + const srcItem = this.getFirstSelectedCatalogItem(); + if (srcItem) { + CatalogPackageManagerActions.copyCatalogPackage.defer(srcItem); } } @@ -537,92 +492,58 @@ class CatalogDataStore { saveCatalogItem() { const activeItem = ComposerAppStore.getState().item; if (activeItem) { - if (activeItem.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' - }); - return; - } + this.saveItem(activeItem); + } + } + + saveItem(item) { + if (item) { 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); } } exportSelectedCatalogItems(draggedItem) { - const onSelectFormat = (selectedFormat, event) => { - this.setState({ - selectedFormat: selectedFormat - }); - }; - - const onSelectGrammar = (selectedGrammar, event) => { - this.setState({ - selectedGrammar: selectedGrammar - }); - } - - - const onCancel = () => { - this.resetSelectionState(); - ModalOverlayActions.hideModalOverlay(); - }; - - const onDownload = (event) => { + // collect the selected items and delegate to the catalog package manager action creator + const selectedItems = this.getAllSelectedCatalogItems(); + if (selectedItems.length) { CatalogPackageManagerActions.downloadCatalogPackage.defer({ selectedItems: selectedItems, - selectedFormat: this.selectedFormat, - selectedGrammar: this.selectedGrammar + selectedFormat: 'mano', + selectedGrammar: 'osm' }); this.resetSelectionState(); - ModalOverlayActions.hideModalOverlay(); - return; - } - - if (draggedItem) { - // if item is given make sure it is also selected - //draggedItem.uiState.selected = true; - SelectionManager.addSelection(draggedItem); - this.updateCatalogItem(draggedItem); - } - // collect the selected items and delegate to the catalog package manager action creator - const selectedItems = this.getAllSelectedCatalogItems(); - if (selectedItems.length) { - CatalogDataStore.chooseExportFormat(onSelectFormat, onSelectGrammar, onDownload, onCancel); } } - - static chooseExportFormat(onSelectFormat, onSelectGrammar, onDownload, onCancel) { - ModalOverlayActions.showModalOverlay.defer( - - ); + saveCatalogItemError(data){ + let error = JSON.parse(data.error.responseText); + const errorMsg = error && error.body && error.body['rpc-reply'] && JSON.stringify(error.body['rpc-reply']['rpc-error'], null, ' ') + ComposerAppActions.showError.defer({ + errorMessage: 'Unable to save the descriptor.\n' + errorMsg + }); } - } export default alt.createStore(CatalogDataStore, 'CatalogDataStore');