RIFT-16086, 16089, support folder names with spaces
[osm/UI.git] / skyquake / plugins / composer / src / src / components / filemanager / FileManager.jsx
index ce490a0..ed9ea93 100644 (file)
@@ -18,7 +18,8 @@
 
 
 //https://raw.githubusercontent.com/RIFTIO/RIFT.ware/master/rift-shell
-import _ from 'lodash'
+import _cloneDeep from 'lodash/cloneDeep'
+import _findIndex from 'lodash/findIndex'
 import React from 'react';
 import ReactDOM from 'react-dom';
 import TreeView from 'react-treeview';
@@ -83,11 +84,11 @@ class FileManager extends React.Component {
             let splitUrl = url.split('/');
             let fileName = splitUrl[splitUrl.length - 1];
             folder.pop;
-            let fullPath = _.cloneDeep(folder);
+            let fullPath = _cloneDeep(folder);
             fullPath.push(fileName);
             fullPath = fullPath.join('/');
             folder = folder.join('/');
-            let fileIndex = _.findIndex(files[folder], function(f) {
+            let fileIndex = _findIndex(files[folder], function(f) {
                 return f.name == fullPath;
             })
             if (fileIndex == -1) {
@@ -105,7 +106,13 @@ class FileManager extends React.Component {
         let html = (
             <div className="FileManager">
                 <PanelWrapper style={{flexDirection: 'column'}}>
-                    {self.props.files && self.props.files.id && buildList(self, self.props.files) }
+                <Panel className="addFileSection" style={{backgroundColor: 'transparent'}} no-corners>
+                    <div className="inputSection">
+                        <TextInput placeholder="some/path" value={this.props.newPathName} label="create a new directory" onChange={FileManagerActions.newPathNameUpdated} />
+                        <Button label="Create" onClick={FileManagerActions.createDirectory} />
+                    </div>
+                </Panel>
+                {self.props.files && self.props.files.id && buildList(self, self.props.files) }
                 </PanelWrapper>
             </div>
         )
@@ -117,7 +124,7 @@ class FileManager extends React.Component {
 function buildList(self, data) {
     let toReturn = [];
     data.id.map(function(k,i) {
-        toReturn.push (contentFolder(self, data.data[k], k, i, self.props.filesState, self.updateFileLocationInput, self.sendDownloadFileRequst, self.deleteFile));
+        toReturn.push (contentFolder(self, data.data[k], k, k+i, self.props.filesState, self.updateFileLocationInput, self.sendDownloadFileRequst, self.deleteFile));
     });
     return toReturn.reverse();
 }
@@ -125,7 +132,8 @@ function buildList(self, data) {
 function contentFolder(context, folder, path, key, inputState, updateFn, sendDownloadFileRequst, deleteFn) {
     let type = context.props.type;
     let id = context.props.item.id;
-    const onboardDropZone = createDropZone.bind(this, FileManagerUploadDropZone.ACTIONS.onboard, '.ComposerAppAddFile.' + path.replace('/', '-'), type, id, path);
+    let classId = `DZ-${path.replace(/\/|\s+/g, '-')}`;
+    const onboardDropZone = createDropZone.bind(this, FileManagerUploadDropZone.ACTIONS.onboard, '.ComposerAppAddFile.' + classId, type, id, path);
     return (
         <Panel title={path} key={key} itemClassName="nested" no-corners>
         <div className="folder">
@@ -163,11 +171,12 @@ class ItemUpload extends React.Component {
     }
     render() {
         let {type, id, path, key, ...props} = this.props;
+        let classId = `DZ-${path.replace(/\/|\s+/g, '-')}`;
         return (
             <div className="inputSection">
                 <label className="sqTextInput" style={{flexDirection: 'row', alignItems:'center'}}>
                     <span>Upload File</span>
-                    <Button className={'ComposerAppAddFile ' + path.replace('/', '-')} label="BROWSE"/>
+                    <Button className={'ComposerAppAddFile ' + classId} label="BROWSE"/>
                 </label>
             </div>
         )
@@ -177,6 +186,7 @@ function contentFile(context, file, path, key, deleteFn) {
     const name = stripPath(file.name, path);
     const id = context.props.item.id;
     const type = context.props.type;
+    const downloadHost = API_SERVER.match('localhost') || API_SERVER.match('127.0.0.1') ? `${window.location.protocol}//${window.location.hostname}` : API_SERVER;
     //{`${window.location.protocol}//${API_SERVER}:4567/api/package${type}/${id}/${path}/${name}`}
     return (
         <div className="file" key={key}>
@@ -186,7 +196,7 @@ function contentFile(context, file, path, key, deleteFn) {
                         {file.status && (file.status == 'IN_PROGRESS' || file.status == 'DOWNLOADING'  )  ? <LoadingIndicator size={2} /> : file.status }
                     </div>
                     <div className="file-name">
-                        <a target="_blank" href={`${API_SERVER}:4567/api/package/${type}/${id}/${path}/${name}`}>{name}</a>
+                        <a target="_blank" href={`${downloadHost}:4567/api/package/${type}/${id}/${path}/${name}`}>{name}</a>
                     </div>
                 </div>
                 <div className="file-action" style={{display: (!file.status || (file && file.status.toLowerCase() != 'loading...')) ? 'inherit' : 'none', cursor: 'pointer'}} onClick={deleteFn(file.name)}>X</div>