diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index a5dffc961f..19e9d98da5 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -163,7 +163,7 @@ module.exports = EditorController = logger.log sl_req_id:sl_req_id, "sending new doc to project #{project_id}" Metrics.inc "editor.add-doc" ProjectEntityHandler.addDoc project_id, folder_id, docName, docLines, sl_req_id, (err, doc, folder_id)=> - EditorRealTimeController.emitToRoom(project_id, 'docCreated', folder_id, doc) + EditorRealTimeController.emitToRoom(project_id, 'reciveNewDoc', folder_id, doc) callback(err, doc) addFile: (project_id, folder_id, fileName, path, sl_req_id, callback = (error, file)->)-> diff --git a/services/web/app/coffee/Features/Editor/EditorHttpController.coffee b/services/web/app/coffee/Features/Editor/EditorHttpController.coffee index 94daaf340f..33bd97633f 100644 --- a/services/web/app/coffee/Features/Editor/EditorHttpController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorHttpController.coffee @@ -20,6 +20,7 @@ module.exports = EditorHttpController = doc_id: doc._id } + addDoc: (req, res, next) -> project_id = req.params.Project_id name = req.body.name @@ -27,3 +28,11 @@ module.exports = EditorHttpController = EditorController.addDoc project_id, parent_folder_id, name, [], (error, doc) -> return next(error) if error? res.json doc + + addFolder: (req, res, next) -> + project_id = req.params.Project_id + name = req.body.name + parent_folder_id = req.body.parent_folder_id + EditorController.addFolder project_id, parent_folder_id, name, (error, doc) -> + return next(error) if error? + res.json doc diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 965ff54fba..7f5439a3da 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -88,6 +88,7 @@ module.exports = class Router app.get '/Project/:Project_id/file/:File_id', SecurityManager.requestCanAccessProject, FileStoreController.getFile app.post '/project/:Project_id/doc', SecurityManager.requestCanModifyProject, EditorHttpController.addDoc + app.post '/project/:Project_id/folder', SecurityManager.requestCanModifyProject, EditorHttpController.addFolder app.post '/project/:Project_id/compile', SecurityManager.requestCanAccessProject, CompileController.compile app.get '/Project/:Project_id/output/output.pdf', SecurityManager.requestCanAccessProject, CompileController.downloadPdf diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade index e2603473b0..5e7df86ffd 100644 --- a/services/web/app/views/project/editor.jade +++ b/services/web/app/views/project/editor.jade @@ -49,7 +49,12 @@ block content tooltip-placement="bottom" ) i.fa.fa-file - a(href, tooltip="New Folder", tooltip-placement="bottom") + a( + href, + ng-click="openNewFolderModal()", + tooltip="New Folder", + tooltip-placement="bottom" + ) i.fa.fa-folder a(href, tooltip="Upload File", tooltip-placement="bottom") i.fa.fa-upload @@ -63,7 +68,7 @@ block content ul.list-unstyled.file-tree-list file-entity( entity="entity", - ng-repeat="entity in rootFolder.children | orderBy:'name'" + ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']" ) .ui-layout-center @@ -102,7 +107,7 @@ block content span(ng-click="select()") {{ entity.name }} ul.list-unstyled(ng-show="expanded") - file-entity(entity="child", ng-repeat="child in entity.children | orderBy:'name'") + file-entity(entity="child", ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']") script(type='text/ng-template', id='newDocModalTemplate') .modal-header @@ -129,6 +134,31 @@ block content span(ng-hide="state.inflight") Create span(ng-show="state.inflight") Creating... + script(type='text/ng-template', id='newFolderModalTemplate') + .modal-header + h3 New File + .modal-body + form(novalidate, name="newFolderForm") + input.form-control( + type="text", + placeholder="Folder Name", + required, + ng-model="inputs.name", + ng-enter="create()", + focus-on="open" + ) + .modal-footer + button.btn.btn-default( + ng-disabled="state.inflight" + ng-click="cancel()" + ) Cancel + button.btn.btn-primary( + ng-disabled="newFolderForm.$invalid || state.inflight" + ng-click="create()" + ) + span(ng-hide="state.inflight") Create + span(ng-show="state.inflight") Creating... + //- #loadingScreen //- h3 Loading... //- p#loadingMessage Loading editor diff --git a/services/web/public/coffee/app/ide/file-tree/FileTreeManager.coffee b/services/web/public/coffee/app/ide/file-tree/FileTreeManager.coffee index 4958fc1665..52acc80ecd 100644 --- a/services/web/public/coffee/app/ide/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/app/ide/file-tree/FileTreeManager.coffee @@ -12,8 +12,7 @@ define [ @_bindToSocketEvents() _bindToSocketEvents: () -> - @ide.socket.on "docCreated", (parent_folder_id, doc) => - console.log "Doc created", parent_folder_id, doc + @ide.socket.on "reciveNewDoc", (parent_folder_id, doc) => parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder @$scope.$apply () -> parent_folder.children.push { @@ -22,6 +21,25 @@ define [ type: "doc" } + @ide.socket.on "reciveNewFile", (parent_folder_id, file) => + parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder + @$scope.$apply () -> + parent_folder.children.push { + name: file.name + id: file._id + type: "file" + } + + @ide.socket.on "reciveNewFolder", (parent_folder_id, folder) => + parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder + @$scope.$apply () -> + parent_folder.children.push { + name: folder.name + id: folder._id + type: "folder" + children: [] + } + findEntityById: (id) -> @_findEntityByIdInFolder @$scope.rootFolder, id @@ -96,7 +114,7 @@ define [ return null createDocInCurrentFolder: (name, callback = (error, doc) ->) -> - # We'll wait for the socket.io 'createDoc' notification to actually + # We'll wait for the socket.io notification to actually # add the doc for us. parent_folder = @getCurrentFolder() $.ajax { @@ -110,7 +128,25 @@ define [ } dataType: "json" success: (doc) -> - console.log "Got doc from POST", doc callback(null, doc) failure: (error) -> callback(error) } + + createFolderInCurrentFolder: (name, callback = (error, doc) ->) -> + # We'll wait for the socket.io notification to actually + # add the folder for us. + parent_folder = @getCurrentFolder() + $.ajax { + url: "/project/#{@ide.project_id}/folder" + type: "POST" + contentType: "application/json; charset=utf-8" + data: JSON.stringify { + name: name, + parent_folder_id: parent_folder?.id + _csrf: window.csrfToken + } + dataType: "json" + success: (folder) -> + callback(null, folder) + failure: (error) -> callback(error) + } diff --git a/services/web/public/coffee/app/ide/file-tree/controllers/FileTreeController.coffee b/services/web/public/coffee/app/ide/file-tree/controllers/FileTreeController.coffee index efdb769a77..f5bf3c889e 100644 --- a/services/web/public/coffee/app/ide/file-tree/controllers/FileTreeController.coffee +++ b/services/web/public/coffee/app/ide/file-tree/controllers/FileTreeController.coffee @@ -5,8 +5,18 @@ define [ $scope.openNewDocModal = () -> $modal.open( templateUrl: "newDocModalTemplate" - controller: "NewDocModalController" + controller: "NewDocModalController" ) + + $scope.openNewFolderModal = () -> + $modal.open( + templateUrl: "newFolderModalTemplate" + controller: "NewFolderModalController" + ) + + $scope.orderByFoldersFirst = (entity) -> + return 0 if entity.type == "folder" + return 1 ] App.controller "NewDocModalController", [ @@ -28,6 +38,29 @@ define [ $scope.state.inflight = false $modalInstance.close() + $scope.cancel = () -> + $modalInstance.dismiss('cancel') + ] + + App.controller "NewFolderModalController", [ + "$scope", "ide", "$modalInstance", "$timeout", + ($scope, ide, $modalInstance, $timeout) -> + $scope.inputs = + name: "name" + $scope.state = + inflight: false + + $modalInstance.opened.then () -> + $timeout () -> + $scope.$broadcast "open" + , 700 + + $scope.create = () -> + $scope.state.inflight = true + ide.fileTreeManager.createFolderInCurrentFolder $scope.inputs.name, (error, doc) -> + $scope.state.inflight = false + $modalInstance.close() + $scope.cancel = () -> $modalInstance.dismiss('cancel') ] \ No newline at end of file diff --git a/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee index 3dc2d33a26..f2facd0876 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee @@ -68,3 +68,24 @@ describe "EditorHttpController", -> .calledWith(@doc) .should.equal true + describe "addFolder", -> + beforeEach -> + @folder = { "mock": "folder" } + @req.params = + Project_id: @project_id + @req.body = + name: @name = "folder-name" + parent_folder_id: @parent_folder_id + @EditorController.addFolder = sinon.stub().callsArgWith(3, null, @folder) + @EditorHttpController.addFolder @req, @res + + it "should call EditorController.addFolder", -> + @EditorController.addFolder + .calledWith(@project_id, @parent_folder_id, @name) + .should.equal true + + it "should send the folder back as JSON", -> + @res.json + .calledWith(@folder) + .should.equal true +