update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / composer / src / src / stores / ComposerAppStore.js
index c9675b7..27220d4 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  *
  *   Copyright 2016 RIFT.IO Inc
 import _isNumber from 'lodash/isNumber'
 import _cloneDeep from 'lodash/cloneDeep'
 import _isEmpty from 'lodash/isEmpty'
+import _isArray from 'lodash/isArray'
 import _mergeWith from 'lodash/mergeWith'
 import _uniqBy from 'lodash/uniqBy'
 import _isEqual from 'lodash/isEqual'
 import _findIndex from 'lodash/findIndex'
 import _remove from 'lodash/remove'
+import _get from 'lodash/get';
+import _set from 'lodash/set';
 import d3 from 'd3'
 import alt from '../alt'
 import UID from '../libraries/UniqueId'
+import DescriptorModel from '../libraries/model/DescriptorModel'
 import DescriptorModelFactory from '../libraries/model/DescriptorModelFactory'
 import PanelResizeAction from '../actions/PanelResizeAction'
 import CatalogItemsActions from '../actions/CatalogItemsActions'
 import CanvasEditorActions from '../actions/CanvasEditorActions'
+import DescriptorEditorActions from '../actions/DescriptorEditorActions'
 import ComposerAppActions from '../actions/ComposerAppActions'
 import CatalogFilterActions from '../actions/CatalogFilterActions'
 import CanvasPanelTrayActions from '../actions/CanvasPanelTrayActions'
@@ -43,6 +47,9 @@ import isFullScreen from '../libraries/isFullScreen'
 import FileManagerSource from '../components/filemanager/FileManagerSource';
 import FileManagerActions from '../components/filemanager/FileManagerActions';
 
+import Property from '../libraries/model/DescriptorModelMetaProperty'
+import DescriptorModelMetaFactory from '../libraries/model/DescriptorModelMetaFactory'
+
 import React from 'react';
 
 //Hack for crouton fix. Should eventually put composer in skyquake alt context
@@ -52,13 +59,13 @@ let NotificationError = null;
 import utils from '../libraries/utils';
 
 class ComponentBridge extends React.Component {
-    constructor(props) {
-        super(props);
-        NotificationError = this.props.flux.actions.global.showNotification;
-    }
-    render(){
-        return <i></i>
-    }
+       constructor(props) {
+               super(props);
+               NotificationError = this.props.flux.actions.global.showNotification;
+       }
+       render() {
+               return <i > </i>
+       }
 }
 const getDefault = (name, defaultValue) => {
        const val = window.localStorage.getItem('defaults-' + name);
@@ -106,8 +113,8 @@ const uiTransientState = {};
 class ComposerAppStore {
 
        constructor() {
-        //Bridge for crouton fix
-        this.ComponentBridgeElement = SkyquakeComponent(ComponentBridge);
+               //Bridge for crouton fix
+               this.ComponentBridgeElement = SkyquakeComponent(ComponentBridge);
 
                this.exportAsync(FileManagerSource)
                // the catalog item currently being edited in the composer
@@ -126,6 +133,8 @@ class ComposerAppStore {
                this.drag = null;
                this.message = '';
                this.messageType = '';
+               this.showHelp = { onFocus: false, forAll: true, forNothing: false },
+                       this.detailPanel = { collapsed: true, hidden: false }
                this.showJSONViewer = false;
                this.showClassifiers = {};
                this.editPathsMode = false;
@@ -137,11 +146,11 @@ class ComposerAppStore {
                this.downloadJobs = {};
                this.containers = [];
                this.newPathName = '';
+               this.displayedPanel = 'forwarding'; //or parameter
                //End File  manager values
                this.bindListeners({
                        onResize: PanelResizeAction.RESIZE,
                        editCatalogItem: CatalogItemsActions.EDIT_CATALOG_ITEM,
-                       catalogItemMetaDataChanged: CatalogItemsActions.CATALOG_ITEM_META_DATA_CHANGED,
                        catalogItemDescriptorChanged: CatalogItemsActions.CATALOG_ITEM_DESCRIPTOR_CHANGED,
                        toggleShowMoreInfo: CanvasEditorActions.TOGGLE_SHOW_MORE_INFO,
                        showMoreInfo: CanvasEditorActions.SHOW_MORE_INFO,
@@ -152,6 +161,7 @@ class ComposerAppStore {
                        addVirtualDeploymentDescriptor: CanvasEditorActions.ADD_VIRTUAL_DEPLOYMENT_DESCRIPTOR,
                        selectModel: ComposerAppActions.SELECT_MODEL,
                        outlineModel: ComposerAppActions.OUTLINE_MODEL,
+                       modelSaveError: ComposerAppActions.RECORD_DESCRIPTOR_ERROR,
                        showError: ComposerAppActions.SHOW_ERROR,
                        clearError: ComposerAppActions.CLEAR_ERROR,
                        setDragState: ComposerAppActions.SET_DRAG_STATE,
@@ -178,38 +188,64 @@ class ComposerAppStore {
                        openDownloadMonitoringSocketSuccess: FileManagerActions.openDownloadMonitoringSocketSuccess,
                        getFilelistSocketSuccess: FileManagerActions.getFilelistSocketSuccess,
                        newPathNameUpdated: FileManagerActions.newPathNameUpdated,
-                       createDirectory: FileManagerActions.createDirectory
+                       createDirectory: FileManagerActions.createDirectory,
+                       modelSetOpenState: DescriptorEditorActions.setOpenState,
+                       modelError: DescriptorEditorActions.setError,
+                       modelSet: DescriptorEditorActions.setValue,
+                       modelAssign: DescriptorEditorActions.assignValue,
+                       modelListNew: DescriptorEditorActions.addListItem,
+                       modelListRemove: DescriptorEditorActions.removeListItem,
+                       showHelpForNothing: DescriptorEditorActions.showHelpForNothing,
+                       showHelpForAll: DescriptorEditorActions.showHelpForAll,
+                       showHelpOnFocus: DescriptorEditorActions.showHelpOnFocus,
+                       collapseAllPanels: DescriptorEditorActions.collapseAllPanels,
+                       expandAllPanels: DescriptorEditorActions.expandAllPanels,
+                       modelForceOpenState: DescriptorEditorActions.expandPanel,
+                       showPanelsWithData: DescriptorEditorActions.showPanelsWithData
+
                });
-        this.exportPublicMethods({
-            closeFileManagerSockets: this.closeFileManagerSockets.bind(this)
-        })
+               this.exportPublicMethods({
+                       closeFileManagerSockets: this.closeFileManagerSockets.bind(this)
+               })
        }
 
        onResize(e) {
+               const layout = Object.assign({}, this.layout);
                if (e.type === 'resize-manager.resize.catalog-panel') {
-                       const layout = Object.assign({}, this.layout);
                        layout.left = Math.max(0, layout.left - e.moved.x);
                        if (layout.left !== this.layout.left) {
-                               this.setState({layout: layout});
+                               this.setState({
+                                       layout: layout
+                               });
                        }
                } else if (e.type === 'resize-manager.resize.details-panel') {
-                       const layout = Object.assign({}, this.layout);
                        layout.right = Math.max(0, layout.right + e.moved.x);
                        if (layout.right !== this.layout.right) {
-                               this.setState({layout: layout});
+                               this.setState({
+                                       layout: layout
+                               });
                        }
                } else if (/^resize-manager\.resize\.canvas-panel-tray/.test(e.type)) {
-                       const layout = Object.assign({}, this.layout);
                        layout.bottom = Math.max(25, layout.bottom + e.moved.y);
                        if (layout.bottom !== this.layout.bottom) {
-                               const zoom = autoZoomCanvasScale(layout.bottom) ;
+                               const zoom = autoZoomCanvasScale(layout.bottom);
                                if (this.zoom !== zoom) {
-                                       this.setState({layout: layout, zoom: zoom});
+                                       this.setState({
+                                               layout: layout,
+                                               zoom: zoom
+                                       });
                                } else {
-                                       this.setState({layout: layout});
+                                       this.setState({
+                                               layout: layout
+                                       });
                                }
                        }
-               } else if (e.type !== 'resize') {
+               } else if (e.type == 'resize') {
+                       layout.height = e.target.innerHeight;
+                       this.setState({
+                               layout: layout
+                       });
+               } else {
                        console.log('no resize handler for ', e.type, '. Do you need to add a handler in ComposerAppStore::onResize()?')
                }
                SelectionManager.refreshOutline();
@@ -219,14 +255,17 @@ class ComposerAppStore {
                const self = this;
                let containers = [];
                let cpNumber = 0;
-               if(!document.body.classList.contains('resizing')) {
+               if (!document.body.classList.contains('resizing')) {
                        containers = [item].reduce(DescriptorModelFactory.buildCatalogItemFactory(CatalogDataStore.getState().catalogs), []);
 
                        containers.filter(d => DescriptorModelFactory.isConnectionPoint(d)).forEach(d => {
                                d.cpNumber = ++cpNumber;
                                containers.filter(d => DescriptorModelFactory.isVnfdConnectionPointRef(d)).filter(ref => ref.key === d.key).forEach(ref => ref.cpNumber = d.cpNumber);
                        });
-                       this.setState({containers: containers, item: _cloneDeep(item)});
+                       this.setState({
+                               containers: containers,
+                               item: _cloneDeep(item)
+                       });
                }
                SelectionManager.refreshOutline();
        }
@@ -246,44 +285,291 @@ class ComposerAppStore {
                        this.openFileManagerSockets(item);
                }
        }
-       catalogItemMetaDataChanged(item) {
-               this.updateItem(item);
-       }
 
        catalogItemDescriptorChanged(itemDescriptor) {
-               this.catalogItemMetaDataChanged(itemDescriptor.model);
+               this.updateItem(itemDescriptor.model);
+       }
+
+       setItemError(descriptor, path, message) {
+               // save locally and globally
+               descriptor.setUiState('error', path, message);
+               if (descriptor.parent) {
+                       let parentPath = [];
+                       while (descriptor.parent) {
+                               parentPath.push(descriptor.type);
+                               const index = descriptor.parent.model[descriptor.type].findIndex(item => item.id === descriptor.id);
+                               parentPath.push(index);
+                               descriptor = descriptor.parent;
+                       }
+                       parentPath.length && descriptor.setUiState('error', parentPath.concat(path), message);
+               } else if (path.length > 1 && descriptor[path[0]]) {
+                       // if we are indirectly editing a sub model set the error state in the sub model
+                       descriptor[path[0]][path[1]].setUiState('error', path.slice(2), message);
+               }
+       }
+
+       modelSaveError(input) {
+               const { descriptor, type, id } = input;
+               const errorMessage = {
+                       'data-missing': "Required value.",
+                       'missing-element': "Incomplete configuration."
+               }
+               if (descriptor.id === id) {
+                       let error = input.error;
+                       let rpcError = null;
+                       if (typeof error === 'string') {
+                               try {
+                                       error = JSON.parse(error);
+                               } catch (e) {
+                                       error = {};
+                               }
+                       }
+                       rpcError = error['rcp-error']
+                               || (error['rcp-reply'] && error['rcp-reply']['rcp-error'])
+                               || (error.body && error.body['rpc-reply'] && error.body['rpc-reply']['rpc-error']);
+                       if (rpcError) {
+                               const errorTag = rpcError['error-tag'];
+                               const message = errorMessage[errorTag] || errorTag;
+                               let errPath = rpcError['error-path'].trim();
+                               errPath = errPath.replace(/[-\w]*:/g, '');
+                               errPath = errPath.slice(errPath.indexOf('/' + type + '[') + 1);
+                               const path = [];
+                               let splitIndex = errPath.indexOf('/');
+                               function ripOutNodeExpression(str, complexNode) {
+                                       const expressionEnd = str.indexOf(']');
+                                       complexNode.push(str.slice(1, expressionEnd));
+                                       if (str.charAt(expressionEnd + 1) === '[') {
+                                               str = str.slice(expressionEnd + 1);
+                                               return ripOutNodeExpression(str, complexNode)
+                                       }
+                                       return str.slice(expressionEnd + 2);
+                               }
+                               while (splitIndex > -1) {
+                                       const expressionStart = errPath.indexOf('[');
+                                       if (expressionStart > 0 && expressionStart < splitIndex) {
+                                               const complexNode = [];
+                                               complexNode.push(errPath.slice(0, expressionStart));
+                                               errPath = errPath.slice(expressionStart);
+                                               errPath = ripOutNodeExpression(errPath, complexNode);
+                                               path.push(complexNode);
+                                       } else {
+                                               path.push(errPath.slice(0, splitIndex))
+                                               errPath = errPath.slice(splitIndex + 1);
+                                       }
+                                       splitIndex = errPath.indexOf('/');
+                               }
+                               const expressionStart = errPath.indexOf('[');
+                               if (expressionStart > 0) {
+                                       const complexNode = [];
+                                       complexNode.push(errPath.slice(0, expressionStart));
+                                       errPath = errPath.slice(expressionStart);
+                                       errPath = ripOutNodeExpression(errPath, complexNode);
+                               } else {
+                                       path.push(errPath.slice(0))
+                               }
+                               let model = descriptor.model;
+                               path.shift();
+                               let fullPath = path.reduce((a, p, i) => {
+                                       let element = p;
+                                       let subPath = [];
+                                       if (Array.isArray(p)) {
+                                               element = p.shift();
+                                               subPath = p;
+                                       }
+                                       a.push(element);
+                                       model = model[element];
+                                       const match = subPath.reduce((m, e) => {
+                                               const id = e.split('=');
+                                               const key = id[0];
+                                               let value = id[1];
+                                               value = value.charAt(0) === "'" ? value.split("'")[1] : value;
+                                               m.push({ key, value });
+                                               return m;
+                                       }, []);
+                                       if (match.length) {
+                                               const index = model.findIndex(obj => match.every(e => obj[e.key] == e.value));
+                                               a.push(index);
+                                               model = model[index];
+                                       }
+                                       return a;
+                               }, []);
+                               this.setItemError(descriptor, fullPath, message);
+                               this.updateItem(descriptor.getRoot().model);
+                       }
+               }
+       }
+
+       modelError(input) {
+               const { descriptor, path, message } = input;
+               this.setItemError(descriptor, path, message);
+               this.updateItem(descriptor.getRoot().model)
+       }
+
+       modelSet(input) {
+               const { descriptor, path, value } = input;
+               _set(descriptor.model, path, value);
+               this.setItemError(descriptor, path, null);
+               this.updateItem(descriptor.getRoot().model)
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(descriptor.getRoot());
+       }
+
+       modelSetOpenState(input) {
+               const { descriptor, path, isOpen } = input;
+               descriptor.setUiState('opened', path, isOpen);
+               this.updateItem(descriptor.getRoot().model)
+       }
+
+       modelForceOpenState(input) {
+               const { descriptor, path } = input;
+               let openPath = [];
+               const targetPath = _isArray(path) ? path : [path];
+               targetPath.forEach(p => {
+                       openPath.push(p);
+                       descriptor.setUiState('opened', openPath, true);
+               });
+               this.updateItem(descriptor.getRoot().model)
+       }
+
+       modelAssign(input) {
+               const { descriptor, path, source } = input;
+               let obj = _get(descriptor.model, path) || {};
+               Object.assign(obj, source);
+               this.updateItem(descriptor.getRoot().model)
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(descriptor.getRoot());
+       }
+
+       modelListNew(input) {
+               const { descriptor, path, property } = input;
+               const create = Property.getContainerCreateMethod(property, descriptor);
+               if (create) {
+                       const model = null;
+                       create(model, path, property);
+               } else {
+                       // get a unique name for the new list item based on the current list content
+                       // some lists, based on the key, may not get a uniqueName generated here
+                       const uniqueName = DescriptorModelMetaFactory.generateItemUniqueName(descriptor.model[property.name], property);
+                       const value = Property.createModelInstance(property, uniqueName);
+                       let list = _get(descriptor.model, path) || [];
+                       list.push(value);
+                       _set(descriptor.model, path, list);
+               }
+               const list = _get(descriptor.model, path);
+               let openPath = path.slice();
+               descriptor.setUiState('opened', openPath, true);
+               openPath.push((list.length - 1).toString());
+               descriptor.setUiState('opened', openPath, true);
+               function traverseProps(properties) {
+                       properties.forEach((p) => {
+                               if (p.type === 'list' || p.type === 'container') {
+                                       openPath.push(p.name);
+                                       descriptor.setUiState('opened', openPath, true);
+                                       p.type === 'container' && traverseProps(p.properties);
+                                       openPath.pop();
+                               }
+                       });
+               }
+               traverseProps(property.properties);
+               this.updateItem(descriptor.getRoot().model);
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(descriptor.getRoot());
+       }
+
+       modelListRemove(input) {
+               const { descriptor, path, property } = input;
+               const removeMethod = Property.getContainerMethod(property, descriptor, 'remove');
+               if (removeMethod) {
+                       removeMethod(_get(descriptor.model, path));
+               } else {
+                       const index = path.pop();
+                       let list = _get(descriptor.model, path);
+                       list = list.splice(index, 1);
+               }
+               this.updateItem(descriptor.getRoot().model);
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(descriptor.getRoot());
+       }
+
+       showHelpForNothing() {
+               this.setState({ showHelp: { onFocus: false, forAll: false, forNothing: true } })
+       }
+
+       showHelpForAll() {
+               this.setState({ showHelp: { onFocus: false, forAll: true, forNothing: false } })
+       }
+
+       showHelpOnFocus() {
+               this.setState({ showHelp: { onFocus: true, forAll: false, forNothing: false } })
+       }
+
+       clearOpenPanelState(descriptor) {
+               if (descriptor) {
+                       descriptor.setUiState('opened', [], {});
+                       this.updateItem(descriptor.getRoot().model);
+               }
+       }
+       collapseAllPanels(input) {
+               this.setState({ openPanelsWithData: false, collapsePanelsByDefault: true });
+               this.clearOpenPanelState(input.descriptor);
+       }
+
+       expandAllPanels(input) {
+               this.setState({ openPanelsWithData: false, collapsePanelsByDefault: false });
+               this.clearOpenPanelState(input.descriptor);
+       }
+
+       showPanelsWithData(input) {
+               this.setState({ openPanelsWithData: true, collapsePanelsByDefault: true });
+               this.clearOpenPanelState(input.descriptor);
        }
 
        showMoreInfo() {
-               this.setState({showMore: true});
+               this.setState({
+                       showMore: true
+               });
        }
 
        showLessInfo() {
-               this.setState({showMore: false});
+               this.setState({
+                       showMore: false
+               });
        }
 
        showError(data) {
-        NotificationError.defer({msg: data.errorMessage, type: 'error'})
-        // this.setState({message: data.errorMessage, messageType: 'error'});
+               NotificationError.defer({
+                       msg: data.errorMessage,
+                       type: 'error',
+                       rpcError: data.rpcError
+               })
+               // this.setState({message: data.errorMessage, messageType: 'error'});
        }
 
        clearError() {
-               this.setState({message: '', messageType: ''});
+               this.setState({
+                       message: '',
+                       messageType: ''
+               });
        }
 
        toggleShowMoreInfo() {
-               this.setState({showMore: !this.showMore});
+               this.setState({
+                       showMore: !this.showMore
+               });
        }
 
        applyDefaultLayout() {
                if (this.item && this.item.uiState && this.item.uiState.containerPositionMap) {
                        if (!_isEmpty(this.item.uiState.containerPositionMap)) {
                                this.item.uiState.containerPositionMap = {};
+                               this.updateItem(this.item);
                                CatalogItemsActions.catalogItemMetaDataChanged.defer(this.item);
                        }
                }
        }
 
+       updateItemNotifyLetSettleCheckMetaData(descriptor) {
+               this.updateItem(descriptor.model);
+               CatalogItemsActions.catalogItemDescriptorChanged.defer(descriptor);
+               setTimeout(() => CatalogItemsActions.catalogItemMetaDataChanged(this.item), 100);
+       }
+
        addVirtualLinkDescriptor(dropCoordinates = null) {
                let vld;
                if (this.item) {
@@ -298,8 +584,7 @@ class ComposerAppStore {
                                vld.uiState.dropCoordinates = dropCoordinates;
                                SelectionManager.clearSelectionAndRemoveOutline();
                                SelectionManager.addSelection(vld);
-                               this.updateItem(vld.getRoot().model);
-                               CatalogItemsActions.catalogItemDescriptorChanged.defer(vld.getRoot());
+                               this.updateItemNotifyLetSettleCheckMetaData(vld.getRoot());
                        }
                }
        }
@@ -311,8 +596,7 @@ class ComposerAppStore {
                        fg.uiState.dropCoordinates = dropCoordinates;
                        SelectionManager.clearSelectionAndRemoveOutline();
                        SelectionManager.addSelection(fg);
-                       this.updateItem(nsdc.model);
-                       CatalogItemsActions.catalogItemDescriptorChanged.defer(nsdc);
+                       this.updateItemNotifyLetSettleCheckMetaData(nsdc);
                }
        }
 
@@ -323,15 +607,14 @@ class ComposerAppStore {
                        vdu.uiState.dropCoordinates = dropCoordinates;
                        SelectionManager.clearSelectionAndRemoveOutline();
                        SelectionManager.addSelection(vdu);
-                       this.updateItem(vdu.getRoot().model);
-                       CatalogItemsActions.catalogItemDescriptorChanged.defer(vdu.getRoot());
+                       this.updateItemNotifyLetSettleCheckMetaData(vdu.getRoot());
                }
        }
 
        selectModel(container) {
                if (SelectionManager.select(container)) {
                        const model = DescriptorModelFactory.isContainer(container) ? container.getRoot().model : container;
-                       this.catalogItemMetaDataChanged(model);
+                       this.updateItem(model);
                }
        }
 
@@ -344,36 +627,57 @@ class ComposerAppStore {
 
        clearSelection() {
                SelectionManager.clearSelectionAndRemoveOutline();
-               this.catalogItemMetaDataChanged(this.item);
        }
 
        setDragState(dragState) {
-               this.setState({drag: dragState});
+               this.setState({
+                       drag: dragState
+               });
        }
 
        filterCatalogByType(typeValue) {
-               this.setState({filterCatalogByTypeValue: typeValue})
+               this.setState({
+                       filterCatalogByTypeValue: typeValue
+               })
        }
 
        setCanvasZoom(zoom) {
-               this.setState({zoom: zoom});
+               this.setState({
+                       zoom: zoom
+               });
        }
 
        showJsonViewer() {
-               this.setState({showJSONViewer: true});
+               this.setState({
+                       showJSONViewer: true
+               });
        }
 
        closeJsonViewer() {
-               this.setState({showJSONViewer: false});
+               this.setState({
+                       showJSONViewer: false
+               });
        }
 
-       toggleCanvasPanelTray() {
+       toggleCanvasPanelTray(event) {
                const layout = this.layout;
-               if (layout.bottom > 25) {
+               const attrMap = event.target.attributes;
+               let panelEvent = null;
+               for (let k in attrMap) {
+                       if (attrMap[k].name == 'data-event') {
+                               panelEvent = attrMap[k].nodeValue;
+                       }
+               }
+               if ((layout.bottom > 25) && ((panelEvent == this.displayedPanel) || panelEvent == 'arrow')) {
                        this.closeCanvasPanelTray();
                } else {
                        this.openCanvasPanelTray();
                }
+               if (panelEvent != 'arrow') {
+                       this.setState({
+                               displayedPanel: panelEvent
+                       })
+               }
        }
 
        openCanvasPanelTray() {
@@ -384,9 +688,15 @@ class ComposerAppStore {
                };
                const zoom = defaults.defaultPanelTrayOpenZoom;
                if (this.zoom !== zoom) {
-                       this.setState({layout: layout, zoom: zoom, restoreZoom: this.zoom});
+                       this.setState({
+                               layout: layout,
+                               zoom: zoom,
+                               restoreZoom: this.zoom
+                       });
                } else {
-                       this.setState({layout: layout});
+                       this.setState({
+                               layout: layout
+                       });
                }
        }
 
@@ -398,9 +708,16 @@ class ComposerAppStore {
                };
                const zoom = this.restoreZoom || autoZoomCanvasScale(layout.bottom);
                if (this.zoom !== zoom) {
-                       this.setState({layout: layout, zoom: zoom, restoreZoom: null});
+                       this.setState({
+                               layout: layout,
+                               zoom: zoom,
+                               restoreZoom: null
+                       });
                } else {
-                       this.setState({layout: layout, restoreZoom: null});
+                       this.setState({
+                               layout: layout,
+                               restoreZoom: null
+                       });
                }
        }
 
@@ -412,7 +729,7 @@ class ComposerAppStore {
                 */
                const eventNames = ['fullscreenchange', 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange'];
 
-               const appRoot = document.body;//.getElementById('RIFT_wareLaunchpadComposerAppRoot');
+               const appRoot = document.body; //.getElementById('RIFT_wareLaunchpadComposerAppRoot');
 
                const comp = this;
 
@@ -424,9 +741,16 @@ class ComposerAppStore {
                                uiTransientState.restoreLayout = restoreLayout;
                                layout.left = 0;
                                layout.right = 0;
-                               comp.setState({fullScreenMode: true, layout: layout, restoreLayout: restoreLayout});
+                               comp.setState({
+                                       fullScreenMode: true,
+                                       layout: layout,
+                                       restoreLayout: restoreLayout
+                               });
                        } else {
-                               comp.setState({fullScreenMode: false, layout: uiTransientState.restoreLayout});
+                               comp.setState({
+                                       fullScreenMode: false,
+                                       layout: uiTransientState.restoreLayout
+                               });
                        }
 
                }
@@ -464,7 +788,9 @@ class ComposerAppStore {
                        document.webkitExitFullscreen();
                }
 
-               this.setState({fullScreenMode: false});
+               this.setState({
+                       fullScreenMode: false
+               });
 
        }
        showAssets() {
@@ -482,39 +808,41 @@ class ComposerAppStore {
        getFilelistSuccess(data) {
                let self = this;
                let filesState = null;
-        if (self.fileMonitoringSocketID) {
-               let newState = {};
-               if(data.hasOwnProperty('contents')) {
-                       filesState = updateFileState( _cloneDeep(this.filesState),data);
+               if (self.fileMonitoringSocketID) {
+                       let newState = {};
+                       if (data.hasOwnProperty('contents')) {
+                               filesState = updateFileState(_cloneDeep(this.filesState), data);
                                let normalizedData = normalizeTree(data);
                                newState = {
                                        files: {
-                                               data: _mergeWith(normalizedData.data, self.files.data, function(obj, src) {
-                                                       return _uniqBy(obj? obj.concat(src) : src, 'name');
+                                               data: _mergeWith(normalizedData.data, self.files.data, function (obj, src) {
+                                                       return _uniqBy(obj ? obj.concat(src) : src, 'name');
                                                }),
                                                id: normalizedData.id
                                        },
                                        filesState: filesState
                                }
-               } else {
-                       newState = {
-                               files: false
-                       }
-               }
-               if(!_isEqual(newState.files, this.files) || ! _isEqual(newState.fileState, this.fileState)) {
-                       this.setState(newState);
-               }
-
-        }
+                       } else {
+                               newState = {
+                                       files: false
+                               }
+                       }
+                       if (!_isEqual(newState.files, this.files) || !_isEqual(newState.fileState, this.fileState)) {
+                               this.setState(newState);
+                       }
+
+               }
+
                function normalizeTree(data) {
                        let f = {
-                               id:[],
-                               data:{}
+                               id: [],
+                               data: {}
                        };
+
                        function getContents(d) {
-                               if(d.hasOwnProperty('contents')) {
+                               if (d.hasOwnProperty('contents')) {
                                        let contents = [];
-                                       d.contents.map(function(c,i) {
+                                       d.contents.map(function (c, i) {
                                                if (!c.hasOwnProperty('contents')) {
                                                        contents.push(c);
                                                } else {
@@ -526,11 +854,12 @@ class ComposerAppStore {
                                }
                        }
                        getContents(data);
-                       return f;
+                       return f;
                }
+
                function updateFileState(obj, d) {
                        d.newFile = '';
-                       if(d.hasOwnProperty('contents')) {
+                       if (d.hasOwnProperty('contents')) {
                                d.contents.map(updateFileState.bind(null, obj))
                        }
                        // override any "pending" state we may have initialized
@@ -556,7 +885,7 @@ class ComposerAppStore {
                });
        }
        addFileSuccess = (data) => {
-               if(!data.refresh) {
+               if (!data.refresh) {
                        let path = data.path;
                        if (path.startsWith('readme')) {
                                // this asset type stuff should be in a more common location
@@ -568,24 +897,29 @@ class ComposerAppStore {
                        let assetGroup = files.data[path] || [];
                        if (fileName) {
                                let name = path + '/' + fileName;
-                               if (assetGroup.findIndex(f => f.name === name) == -1){
-                                       assetGroup.push({name});
+                               if (assetGroup.findIndex(f => f.name === name) == -1) {
+                                       assetGroup.push({
+                                               name
+                                       });
                                }
                        }
                        files.data[path] = assetGroup;
-                       if (files.id.indexOf(path) == -1){
+                       if (files.id.indexOf(path) == -1) {
                                files.id.push(path);
                        }
                        let filesState = _cloneDeep(this.filesState);
                        filesState[name] = "DOWNLOADING";
-                       this.setState({files, filesState});
+                       this.setState({
+                               files,
+                               filesState
+                       });
                }
 
        }
        startWatchingJob = () => {
                let ws = window.multiplexer.channel(this.jobSocketId);
                this.setState({
-                       jobSocket:null
+                       jobSocket: null
                })
        }
        openDownloadMonitoringSocketSuccess = (id) => {
@@ -594,39 +928,39 @@ class ComposerAppStore {
                let downloadJobs = _cloneDeep(self.downloadJobs);
                let newFiles = false;
                ws.onmessage = (socket) => {
-            if (self.files && self.files.length > 0) {
-                let jobs = [];
-                try {
-                    jobs = JSON.parse(socket.data);
-                } catch(e) {}
-                newFiles = _cloneDeep(self.files);
-                jobs.map(function(j) {
-                    //check if not in completed state
-                    let fullPath = j['package-path'];
-                    let path = fullPath.split('/');
-                    let fileName = path.pop();
-                    path = path.join('/');
-                    let index = _findIndex(self.files.data[path], function(o){
-                        return fullPath == o.name
-                    });
-                    if((index > -1) && newFiles.data[path][index]) {
-                        newFiles.data[path][index].status = j.status
+                       if (self.files && self.files.length > 0) {
+                               let jobs = [];
+                               try {
+                                       jobs = JSON.parse(socket.data);
+                               } catch (e) { }
+                               newFiles = _cloneDeep(self.files);
+                               jobs.map(function (j) {
+                                       //check if not in completed state
+                                       let fullPath = j['package-path'];
+                                       let path = fullPath.split('/');
+                                       let fileName = path.pop();
+                                       path = path.join('/');
+                                       let index = _findIndex(self.files.data[path], function (o) {
+                                               return fullPath == o.name
+                                       });
+                                       if ((index > -1) && newFiles.data[path][index]) {
+                                               newFiles.data[path][index].status = j.status
                                        } else {
-                        if(j.status.toUpperCase() == 'LOADING...' || j.status.toUpperCase() == 'IN_PROGRESS') {
-                            newFiles.data[path].push({
-                                status: j.status,
-                                name: fullPath
-                            })
-                        } else {
-                            // if ()
-                        }
+                                               if (j.status.toUpperCase() == 'LOADING...' || j.status.toUpperCase() == 'IN_PROGRESS') {
+                                                       newFiles.data[path].push({
+                                                               status: j.status,
+                                                               name: fullPath
+                                                       })
+                                               } else {
+                                                       // if ()
+                                               }
                                        }
-                })
-                self.setState({
-                    files: newFiles
-                })
-                       // console.log(JSON.parse(socket.data));
-            }
+                               })
+                               self.setState({
+                                       files: newFiles
+                               })
+                               // console.log(JSON.parse(socket.data));
+                       }
                }
                this.setState({
                        jobSocketId: id,
@@ -638,20 +972,20 @@ class ComposerAppStore {
                let self = this;
                let ws = window.multiplexer.channel(id);
                ws.onmessage = (socket) => {
-            if (self.fileMonitoringSocketID) {
-                let data = [];
-                try {
-                    data = JSON.parse(socket.data);
-                } catch(e) {}
-                self.getFilelistSuccess(data)
-            }
+                       if (self.fileMonitoringSocketID) {
+                               let data = [];
+                               try {
+                                       data = JSON.parse(socket.data);
+                               } catch (e) { }
+                               self.getFilelistSuccess(data)
+                       }
                }
 
                this.setState({
                        filesState: [],
                        files: {
-                               id:[],
-                               data:{}
+                               id: [],
+                               data: {}
                        },
                        fileMonitoringSocketID: id,
                        fileMonitoringSocket: ws
@@ -659,31 +993,34 @@ class ComposerAppStore {
 
        }
        closeFileManagerSockets() {
-        this.fileMonitoringSocketID = null;
-        this.setState({
-                jobSocketId : null,
-                fileMonitoringSocketID : null
-                // jobSocket : null,
-                // fileMonitoringSocket : null,
-        });
+               this.fileMonitoringSocketID = null;
+               this.setState({
+                       jobSocketId: null,
+                       fileMonitoringSocketID: null
+                       // jobSocket : null,
+                       // fileMonitoringSocket : null,
+               });
                this.jobSocket && this.jobSocket.close();
                this.fileMonitoringSocket && this.fileMonitoringSocket.close();
-        console.log('closing');
+               console.log('closing');
        }
        openFileManagerSockets(i) {
                let self = this;
                let item = i || self.item;
-        // this.closeFileManagerSockets();
-               this.getInstance().openFileMonitoringSocket(item.id, item.uiState.type).then(function() {
-        //     // self.getInstance().openDownloadMonitoringSocket(item.id);
+               // this.closeFileManagerSockets();
+               this.getInstance().openFileMonitoringSocket(item.id, item.uiState.type).then(function () {
+                       //      // self.getInstance().openDownloadMonitoringSocket(item.id);
                });
-        this.getInstance().openDownloadMonitoringSocket(item.id);
+               this.getInstance().openDownloadMonitoringSocket(item.id);
        }
        endWatchingJob(id) {
 
        }
        deletePackageFile(asset) {
-               let {assetType, path} = asset;
+               let {
+                       assetType,
+                       path
+               } = asset;
                let id = this.item.id;
                let type = this.item.uiState.type;
                this.getInstance().deleteFile(id, type, assetType, path);
@@ -691,7 +1028,7 @@ class ComposerAppStore {
        deleteFileSuccess = (data) => {
                let name = null;
                let path = null;
-               if (data.assetFolder === 'readme'){
+               if (data.assetFolder === 'readme') {
                        // freak'n root folder is special
                        name = data.path;
                        path = ['.'];
@@ -702,7 +1039,7 @@ class ComposerAppStore {
                }
                let files = _cloneDeep(this.files);
                let filesForPath = files.data[path.join('/')]
-               _remove(filesForPath, function(c) {
+               _remove(filesForPath, function (c) {
                        return c.name == name;
                });
 
@@ -741,4 +1078,4 @@ class ComposerAppStore {
        }
 }
 
-export default alt.createStore(ComposerAppStore, 'ComposerAppStore');
+export default alt.createStore(ComposerAppStore, 'ComposerAppStore');
\ No newline at end of file