From f03b2df46164c71f68eac4d900363a253b1b8e69 Mon Sep 17 00:00:00 2001 From: Daniel Felder Date: Sun, 1 Jun 2014 16:43:52 +0200 Subject: [PATCH 01/10] compile current file if top level document #42 --- .../app/coffee/Features/Compile/ClsiManager.coffee | 11 ++++++++--- .../coffee/Features/Compile/CompileController.coffee | 4 +++- .../app/coffee/Features/Compile/CompileManager.coffee | 2 +- services/web/public/coffee/pdf/CompiledView.coffee | 7 ++++++- services/web/public/coffee/pdf/PdfManager.coffee | 9 ++++++--- 5 files changed, 24 insertions(+), 9 deletions(-) mode change 100644 => 100755 services/web/app/coffee/Features/Compile/ClsiManager.coffee mode change 100644 => 100755 services/web/app/coffee/Features/Compile/CompileController.coffee mode change 100644 => 100755 services/web/app/coffee/Features/Compile/CompileManager.coffee mode change 100644 => 100755 services/web/public/coffee/pdf/CompiledView.coffee diff --git a/services/web/app/coffee/Features/Compile/ClsiManager.coffee b/services/web/app/coffee/Features/Compile/ClsiManager.coffee old mode 100644 new mode 100755 index b7930f5cf3..639511154e --- a/services/web/app/coffee/Features/Compile/ClsiManager.coffee +++ b/services/web/app/coffee/Features/Compile/ClsiManager.coffee @@ -8,8 +8,8 @@ logger = require "logger-sharelatex" url = require("url") module.exports = ClsiManager = - sendRequest: (project_id, callback = (error, success) ->) -> - ClsiManager._buildRequest project_id, (error, req) -> + sendRequest: (project_id, settingsOverride = {}, callback = (error, success) ->) -> + ClsiManager._buildRequest project_id, settingsOverride, (error, req) -> return callback(error) if error? logger.log project_id: project_id, "sending compile to CLSI" ClsiManager._postToClsi project_id, req, (error, response) -> @@ -52,7 +52,7 @@ module.exports = ClsiManager = return outputFiles VALID_COMPILERS: ["pdflatex", "latex", "xelatex", "lualatex"] - _buildRequest: (project_id, callback = (error, request) ->) -> + _buildRequest: (project_id, settingsOverride={}, callback = (error, request) ->) -> Project.findById project_id, {compiler: 1, rootDoc_id: 1}, (error, project) -> return callback(error) if error? return callback(new Errors.NotFoundError("project does not exist: #{project_id}")) if !project? @@ -67,6 +67,7 @@ module.exports = ClsiManager = resources = [] rootResourcePath = null + rootResourcePathOverride = null for path, doc of docs path = path.replace(/^\//, "") # Remove leading / @@ -75,6 +76,10 @@ module.exports = ClsiManager = content: doc.lines.join("\n") if project.rootDoc_id? and doc._id.toString() == project.rootDoc_id.toString() rootResourcePath = path + if settingsOverride.rootDoc_id? and doc._id.toString() == settingsOverride.rootDoc_id.toString() + rootResourcePathOverride = path + + rootResourcePath = rootResourcePathOverride if rootResourcePathOverride? for path, file of files path = path.replace(/^\//, "") # Remove leading / diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee old mode 100644 new mode 100755 index aa4fab9e30..c1071c32cd --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -11,9 +11,11 @@ module.exports = CompileController = compile: (req, res, next = (error) ->) -> project_id = req.params.Project_id isAutoCompile = !!req.query?.auto_compile + settingsOverride = req.body.settingsOverride ? {}; + logger.log "root doc overriden" if settingsOverride.rootDoc_id? AuthenticationController.getLoggedInUserId req, (error, user_id) -> return next(error) if error? - CompileManager.compile project_id, user_id, { isAutoCompile }, (error, status, outputFiles) -> + CompileManager.compile project_id, user_id, { isAutoCompile, settingsOverride }, (error, status, outputFiles) -> return next(error) if error? res.contentType("application/json") res.send 200, JSON.stringify { diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee old mode 100644 new mode 100755 index a0b242e95f..92480917ad --- a/services/web/app/coffee/Features/Compile/CompileManager.coffee +++ b/services/web/app/coffee/Features/Compile/CompileManager.coffee @@ -30,7 +30,7 @@ module.exports = CompileManager = return callback(error) if error? DocumentUpdaterHandler.flushProjectToMongo project_id, (error) -> return callback(error) if error? - ClsiManager.sendRequest project_id, (error, status, outputFiles) -> + ClsiManager.sendRequest project_id, opt.settingsOverride, (error, status, outputFiles) -> return callback(error) if error? logger.log files: outputFiles, "output files" callback(null, status, outputFiles) diff --git a/services/web/public/coffee/pdf/CompiledView.coffee b/services/web/public/coffee/pdf/CompiledView.coffee old mode 100644 new mode 100755 index 4f12007379..74afc1e11b --- a/services/web/public/coffee/pdf/CompiledView.coffee +++ b/services/web/public/coffee/pdf/CompiledView.coffee @@ -204,7 +204,12 @@ define [ recompilePdf: () -> @options.manager.trigger "compile:pdf" - @options.manager.refreshPdf() + rootDocOverride_id = null + for line in @ide.editor.getLines() + match = line.match /(.*)\\documentclass/ + if match and !match[1].match /%/ + rootDocOverride_id = @ide.editor.getCurrentDocId() + @options.manager.refreshPdf {rootDocOverride_id} toggleFlatViewButton: () -> @$("#flatViewButton").button("toggle") toggleSplitViewButton: () -> @$("#splitViewButton").button("toggle") diff --git a/services/web/public/coffee/pdf/PdfManager.coffee b/services/web/public/coffee/pdf/PdfManager.coffee index 04bb682bf9..d988797904 100644 --- a/services/web/public/coffee/pdf/PdfManager.coffee +++ b/services/web/public/coffee/pdf/PdfManager.coffee @@ -143,7 +143,7 @@ define [ @view.onCompiling() @syncButtonsView?.hide() @compiling = true - @_doCompile opts.isAutoCompile, (error, status, outputFiles) => + @_doCompile opts, (error, status, outputFiles) => @compiling = false doneCompiling() @@ -172,16 +172,19 @@ define [ if outputFiles? @view.showOutputFileDownloadLinks(outputFiles) - _doCompile: (isAutoCompile, callback = (error, status, outputFiles) ->) -> + _doCompile: (opts, callback = (error, status, outputFiles) ->) -> url = "/project/#{@ide.project_id}/compile" - if isAutoCompile + if opts.isAutoCompile url += "?auto_compile=true" $.ajax( url: url type: "POST" headers: "X-CSRF-Token": window.csrfToken + contentType: "application/json; charset=utf-8" dataType: 'json' + data: JSON.stringify settingsOverride: + rootDoc_id: opts.rootDocOverride_id ? null success: (body, status, response) -> callback null, body.status, body.outputFiles error: (error) -> From 5ad0ca08f914a40d8cea158330ce64f9fe171082 Mon Sep 17 00:00:00 2001 From: Daniel Felder Date: Sun, 1 Jun 2014 18:16:05 +0200 Subject: [PATCH 02/10] adjusting unit tests --- .../coffee/Features/Compile/CompileController.coffee | 2 +- .../coffee/Features/Compile/CompileManager.coffee | 2 +- .../UnitTests/coffee/Compile/ClsiManagerTests.coffee | 12 ++++++------ .../coffee/Compile/CompileManagerTests.coffee | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee index c1071c32cd..0d919fbd75 100755 --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -11,7 +11,7 @@ module.exports = CompileController = compile: (req, res, next = (error) ->) -> project_id = req.params.Project_id isAutoCompile = !!req.query?.auto_compile - settingsOverride = req.body.settingsOverride ? {}; + settingsOverride = req.body?.settingsOverride ? {}; logger.log "root doc overriden" if settingsOverride.rootDoc_id? AuthenticationController.getLoggedInUserId req, (error, user_id) -> return next(error) if error? diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee index 92480917ad..a245fff101 100755 --- a/services/web/app/coffee/Features/Compile/CompileManager.coffee +++ b/services/web/app/coffee/Features/Compile/CompileManager.coffee @@ -30,7 +30,7 @@ module.exports = CompileManager = return callback(error) if error? DocumentUpdaterHandler.flushProjectToMongo project_id, (error) -> return callback(error) if error? - ClsiManager.sendRequest project_id, opt.settingsOverride, (error, status, outputFiles) -> + ClsiManager.sendRequest project_id, opt.settingsOverride ? null, (error, status, outputFiles) -> return callback(error) if error? logger.log files: outputFiles, "output files" callback(null, status, outputFiles) diff --git a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee index 6791443c9a..236a483214 100644 --- a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee @@ -24,7 +24,7 @@ describe "ClsiManager", -> describe "sendRequest", -> beforeEach -> - @ClsiManager._buildRequest = sinon.stub().callsArgWith(1, null, @request = "mock-request") + @ClsiManager._buildRequest = sinon.stub().callsArgWith(2, null, @request = "mock-request") describe "with a successful compile", -> beforeEach -> @@ -39,7 +39,7 @@ describe "ClsiManager", -> type: "log" }] }) - @ClsiManager.sendRequest @project_id, @callback + @ClsiManager.sendRequest @project_id, {}, @callback it "should build the request", -> @ClsiManager._buildRequest @@ -67,7 +67,7 @@ describe "ClsiManager", -> compile: status: @status = "failure" }) - @ClsiManager.sendRequest @project_id, @callback + @ClsiManager.sendRequest @project_id, {}, @callback it "should call the callback with a failure statue", -> @callback.calledWith(null, @status).should.equal true @@ -121,7 +121,7 @@ describe "ClsiManager", -> describe "with a valid project", -> beforeEach (done) -> - @ClsiManager._buildRequest @project_id, (error, request) => + @ClsiManager._buildRequest @project_id, null, (error, request) => @request = request done() @@ -162,7 +162,7 @@ describe "ClsiManager", -> describe "when the project has an invalid compiler", -> beforeEach (done) -> @project.compiler = "context" - @ClsiManager._buildRequest @project, (error, request) => + @ClsiManager._buildRequest @project, null, (error, request) => @request = request done() @@ -172,7 +172,7 @@ describe "ClsiManager", -> describe "when there is no valid root document", -> beforeEach (done) -> @project.rootDoc_id = "not-valid" - @ClsiManager._buildRequest @project, (@error, @request) => + @ClsiManager._buildRequest @project, null, (@error, @request) => done() it "should return an error", -> diff --git a/services/web/test/UnitTests/coffee/Compile/CompileManagerTests.coffee b/services/web/test/UnitTests/coffee/Compile/CompileManagerTests.coffee index f1b963a8c5..c284341bf2 100644 --- a/services/web/test/UnitTests/coffee/Compile/CompileManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/CompileManagerTests.coffee @@ -36,7 +36,7 @@ describe "CompileManager", -> @CompileManager._checkIfRecentlyCompiled = sinon.stub().callsArgWith(2, null, false) @CompileManager._ensureRootDocumentIsSet = sinon.stub().callsArgWith(1, null) @DocumentUpdaterHandler.flushProjectToMongo = sinon.stub().callsArgWith(1, null) - @ClsiManager.sendRequest = sinon.stub().callsArgWith(1, null, @status = "mock-status") + @ClsiManager.sendRequest = sinon.stub().callsArgWith(2, null, @status = "mock-status") describe "succesfully", -> beforeEach -> From 4320b790bd2f2e8c8834d766d635ed964b525afc Mon Sep 17 00:00:00 2001 From: Daniel Felder Date: Sun, 1 Jun 2014 19:26:33 +0200 Subject: [PATCH 03/10] adjusting unit tests --- .../web/app/coffee/Features/Compile/CompileManager.coffee | 4 ++-- .../UnitTests/coffee/Compile/CompileControllerTests.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/web/app/coffee/Features/Compile/CompileManager.coffee b/services/web/app/coffee/Features/Compile/CompileManager.coffee index a245fff101..972b7d3286 100755 --- a/services/web/app/coffee/Features/Compile/CompileManager.coffee +++ b/services/web/app/coffee/Features/Compile/CompileManager.coffee @@ -25,12 +25,12 @@ module.exports = CompileManager = return callback(error) if error? if recentlyCompiled return callback new Error("project was recently compiled so not continuing") - + CompileManager._ensureRootDocumentIsSet project_id, (error) -> return callback(error) if error? DocumentUpdaterHandler.flushProjectToMongo project_id, (error) -> return callback(error) if error? - ClsiManager.sendRequest project_id, opt.settingsOverride ? null, (error, status, outputFiles) -> + ClsiManager.sendRequest project_id, opt.settingsOverride, (error, status, outputFiles) -> return callback(error) if error? logger.log files: outputFiles, "output files" callback(null, status, outputFiles) diff --git a/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee b/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee index 0820c0431c..fe456995ad 100644 --- a/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee @@ -44,7 +44,7 @@ describe "CompileController", -> it "should do the compile without the auto compile flag", -> @CompileManager.compile - .calledWith(@project_id, @user_id, { isAutoCompile: false }) + .calledWith(@project_id, @user_id, { isAutoCompile: false, settingsOverride:{} }) .should.equal true it "should set the content-type of the response to application/json", -> @@ -71,7 +71,7 @@ describe "CompileController", -> it "should do the compile with the auto compile flag", -> @CompileManager.compile - .calledWith(@project_id, @user_id, { isAutoCompile: true }) + .calledWith(@project_id, @user_id, { isAutoCompile: true, settingsOverride:{} }) .should.equal true describe "downloadPdf", -> From 66dcb376a4ec78bfb7a2c25236066effcf4970b9 Mon Sep 17 00:00:00 2001 From: Daniel Felder Date: Sun, 1 Jun 2014 22:28:19 +0200 Subject: [PATCH 04/10] added unit tests --- .../coffee/Compile/ClsiManagerTests.coffee | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee index 236a483214..6915529b95 100644 --- a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee @@ -159,6 +159,28 @@ describe "ClsiManager", -> }] ) + + describe "when root doc override is valid", -> + beforeEach (done) -> + @ClsiManager._buildRequest @project_id, {rootDoc_id:"mock-doc-id-2"}, (error, request) => + @request = request + done() + + it "should change root path", -> + @request.compile.rootResourcePath.should.equal "chapters/chapter1.tex" + + + describe "when root doc override is invalid", -> + beforeEach (done) -> + @ClsiManager._buildRequest @project_id, {rootDoc_id:"invalid-id"}, (error, request) => + @request = request + done() + + it "should fallback to default root doc", -> + @request.compile.rootResourcePath.should.equal "main.tex" + + + describe "when the project has an invalid compiler", -> beforeEach (done) -> @project.compiler = "context" From 1d12b88b09282aa0b360da52f24d709aea86f23b Mon Sep 17 00:00:00 2001 From: Daniel Felder Date: Thu, 5 Jun 2014 18:00:07 +0200 Subject: [PATCH 05/10] Ignore commented lines when setting root doc #52 Same code I used in public/coffee/pdf/CompiledView.coffee. I didn't test it locally though. --- .../app/coffee/Features/Project/ProjectRootDocManager.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee b/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee index 80f2c70eb3..1c8202ac71 100644 --- a/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee +++ b/services/web/app/coffee/Features/Project/ProjectRootDocManager.coffee @@ -10,7 +10,8 @@ module.exports = ProjectRootDocManager = root_doc_id = null for path, doc of docs for line in doc.lines || [] - if Path.extname(path).match(/\.R?tex$/) and line.match(/\\documentclass/) + match = line.match /(.*)\\documentclass/ # no lookbehind in js regexp :( + if Path.extname(path).match(/\.R?tex$/) and match and !match[1].match /%/ root_doc_id = doc._id if root_doc_id? ProjectEntityHandler.setRootDoc project_id, root_doc_id, sl_req_id, callback From cabaf1ae1a8826bdceb8d5c7b8d2b6c33ebdcabf Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 13:11:39 +0100 Subject: [PATCH 06/10] Show deleted documents when viewing history --- .../Project/ProjectEditorHandler.coffee | 1 + .../coffee/file-tree/FileTreeManager.coffee | 24 ++++++++++++++++--- services/web/public/coffee/models/Doc.coffee | 1 + .../web/public/coffee/models/Folder.coffee | 6 ++--- .../web/public/coffee/models/Project.coffee | 12 +++++++++- .../track-changes/TrackChangesManager.coffee | 4 ++++ .../coffee/track-changes/models/Change.coffee | 2 +- .../Project/ProjectEditorHandlerTests.coffee | 8 +++++++ 8 files changed, 50 insertions(+), 8 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee index 6c78a8e939..4ad3f19bff 100644 --- a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee @@ -15,6 +15,7 @@ module.exports = ProjectEditorHandler = description: project.description spellCheckLanguage: project.spellCheckLanguage deletedByExternalDataSource : project.deletedByExternalDataSource || false + deletedDocs: project.deletedDocs if options.includeUsers result.features = diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index d683a2a795..19cf2f2382 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -3,11 +3,12 @@ define [ "models/File" "models/Folder" "file-tree/FileTreeView" + "file-tree/FolderView" "utils/Effects" "utils/Modal" "libs/backbone" "libs/jquery.storage" -], (Doc, File, Folder, FileTreeView, Effects, Modal) -> +], (Doc, File, Folder, FileTreeView, FolderView, Effects, Modal) -> class FileTreeManager constructor: (@ide) -> _.extend(@, Backbone.Events) @@ -37,6 +38,10 @@ define [ populateFileTree: () -> @view.bindToRootFolder(@project.get("rootFolder")) + @deletedDocsView = new FolderView(model: @project.get("deletedDocs"), manager: @) + @deletedDocsView.render() + $("#sections").append(@deletedDocsView.$el) + @hideDeletedDocs() listenForUpdates: () -> @ide.socket.on 'reciveNewDoc', (folder_id, doc) => @@ -100,8 +105,12 @@ define [ @ide.sideBarView.deselectAll() @views[entity_id]?.select() - getEntity: (entity_id) -> - @views[entity_id]?.model + getEntity: (entity_id, options = {include_deleted: false}) -> + model = @views[entity_id]?.model + if !model? or (model.get("deleted") and !options.include_deleted) + return + else + return model getSelectedEntity: () -> @getEntity(@selected_entity_id) getSelectedEntityId: () -> @getSelectedEntity()?.id @@ -275,6 +284,8 @@ define [ _doDelete: (entity) -> @ide.socket.emit 'deleteEntity', entity.id, entity.get("type") + if entity.get("type") == "doc" + @project.get("deletedDocs").get("children").add entity @onDeleteEntity entity.id onDeleteEntity: (entity_id) -> @@ -286,3 +297,10 @@ define [ setLabels: (labels) -> @view.setLabels(labels) + @deletedDocsView.setLabels(labels) + + showDeletedDocs: () -> + @deletedDocsView.$el.show() + + hideDeletedDocs: () -> + @deletedDocsView.$el.hide() diff --git a/services/web/public/coffee/models/Doc.coffee b/services/web/public/coffee/models/Doc.coffee index 9d98dd2878..a80b3b6acf 100644 --- a/services/web/public/coffee/models/Doc.coffee +++ b/services/web/public/coffee/models/Doc.coffee @@ -9,3 +9,4 @@ define [ attributes = id: rawAttributes._id name: rawAttributes.name + deleted: !!rawAttributes.deleted diff --git a/services/web/public/coffee/models/Folder.coffee b/services/web/public/coffee/models/Folder.coffee index 8106800de9..d9c3df13ec 100644 --- a/services/web/public/coffee/models/Folder.coffee +++ b/services/web/public/coffee/models/Folder.coffee @@ -20,11 +20,11 @@ define [ id: rawAttributes._id name: rawAttributes.name children = [] - for childFolder in rawAttributes.folders + for childFolder in rawAttributes.folders or [] children.push new Folder(childFolder, parse: true) - for file in rawAttributes.fileRefs + for file in rawAttributes.fileRefs or [] children.push new File(file, parse: true) - for doc in rawAttributes.docs + for doc in rawAttributes.docs or [] children.push new Doc(doc, parse: true) attributes.children = new FolderChildren(children) return attributes diff --git a/services/web/public/coffee/models/Project.coffee b/services/web/public/coffee/models/Project.coffee index 92634352b2..f62098b154 100644 --- a/services/web/public/coffee/models/Project.coffee +++ b/services/web/public/coffee/models/Project.coffee @@ -2,8 +2,9 @@ define [ "models/User" "models/ProjectMemberList" "models/Folder" + "models/Doc" "libs/backbone" -], (User, ProjectMemberList, Folder) -> +], (User, ProjectMemberList, Folder, Doc) -> Project = Backbone.Model.extend initialize: -> @on "change:ide", (project, ide) => @@ -39,6 +40,15 @@ define [ member = User.findOrBuild rawMember._id, rawMember members.add member + for doc in rawAttributes.deletedDocs + doc.deleted = true + + attributes.deletedDocs = new Folder({ + _id: "deleted-docs-folder" + name: "Deleted documents" + docs: rawAttributes.deletedDocs + }, parse: true) + return attributes bindToRootDocId: -> diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index d1a8484a91..4d146c923b 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -71,6 +71,9 @@ define [ @ide.mainAreaManager.change "trackChanges" @ide.editor.disable() @ide.fileViewManager.disable() + + @ide.fileTreeManager.showDeletedDocs() + @enable() showUpgradeView: () -> @@ -93,6 +96,7 @@ define [ @ide.fileTreeManager.openDoc(@doc_id) @ide.tabManager.show "code" @resetLabels() + @ide.fileTreeManager.hideDeletedDocs() autoSelectDiff: () -> if @changes.models.length == 0 diff --git a/services/web/public/coffee/track-changes/models/Change.coffee b/services/web/public/coffee/track-changes/models/Change.coffee index 7e2d10315f..ac48997583 100644 --- a/services/web/public/coffee/track-changes/models/Change.coffee +++ b/services/web/public/coffee/track-changes/models/Change.coffee @@ -21,6 +21,6 @@ define [ toV: data.toV # TODO: We should not use a global reference here, but # it's hard to get @ide into Backbone at this point. - entity: ide.fileTreeManager.getEntity(doc_id) + entity: ide.fileTreeManager.getEntity(doc_id, include_deleted: true) return model \ No newline at end of file diff --git a/services/web/test/UnitTests/coffee/Project/ProjectEditorHandlerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectEditorHandlerTests.coffee index 02e23f6785..afb93e68ac 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectEditorHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectEditorHandlerTests.coffee @@ -55,6 +55,10 @@ describe "ProjectEditorHandler", -> last_name : "Write" email : "read-write@sharelatex.com" }] + deletedDocs: [{ + _id: "deleted-doc-id" + name: "main.tex" + }] @handler = SandboxedModule.require modulePath describe "buildProjectModelView", -> @@ -85,6 +89,10 @@ describe "ProjectEditorHandler", -> @result.owner.first_name.should.equal "Owner" @result.owner.last_name.should.equal "ShareLaTeX" @result.owner.privileges.should.equal "owner" + + it "should include the deletedDocs", -> + should.exist @result.deletedDocs + @result.deletedDocs.should.equal @project.deletedDocs it "should gather readOnly_refs and collaberators_refs into a list of members", -> findMember = (id) => From 1e31024bd718156d00672681ce2bbd25bf85459b Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 13:38:07 +0100 Subject: [PATCH 07/10] Show diffs of deleted docs --- services/web/public/coffee/track-changes/models/Diff.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/track-changes/models/Diff.coffee b/services/web/public/coffee/track-changes/models/Diff.coffee index d8ee48726f..e0c108ac66 100644 --- a/services/web/public/coffee/track-changes/models/Diff.coffee +++ b/services/web/public/coffee/track-changes/models/Diff.coffee @@ -5,7 +5,7 @@ define [ Diff = Backbone.Model.extend initialize: (attributes, options) -> @ide = options.ide - @set "doc", @ide.fileTreeManager.getEntity(@get("doc_id")) + @set "doc", @ide.fileTreeManager.getEntity(@get("doc_id"), include_deleted: true) url: () -> url = "/project/#{@get("project_id")}/doc/#{@get("doc_id")}/diff" From 02f48be8256606c63dc4275713cc56a39d32aa8d Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 16:18:25 +0100 Subject: [PATCH 08/10] Allow docs to be restored --- .../Editor/EditorHttpController.coffee | 21 +++++++++ .../Project/ProjectEntityHandler.coffee | 7 +++ services/web/app/coffee/router.coffee | 3 ++ services/web/app/views/templates.jade | 3 ++ .../public/coffee/file-tree/EntityView.coffee | 1 + .../coffee/file-tree/FileTreeManager.coffee | 11 ++++- .../coffee/track-changes/DiffView.coffee | 13 +++++- .../track-changes/TrackChangesManager.coffee | 26 ++++++++++- .../public/stylesheets/less/trackchanges.less | 9 +++- .../Editor/EditorHttpControllerTests.coffee | 46 +++++++++++++++++++ .../Project/ProjectEntityHandlerTests.coffee | 25 ++++++++++ 11 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 services/web/app/coffee/Features/Editor/EditorHttpController.coffee create mode 100644 services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee diff --git a/services/web/app/coffee/Features/Editor/EditorHttpController.coffee b/services/web/app/coffee/Features/Editor/EditorHttpController.coffee new file mode 100644 index 0000000000..57b65d7355 --- /dev/null +++ b/services/web/app/coffee/Features/Editor/EditorHttpController.coffee @@ -0,0 +1,21 @@ +ProjectEntityHandler = require "../Project/ProjectEntityHandler" +logger = require "logger-sharelatex" +EditorRealTimeController = require "./EditorRealTimeController" + +module.exports = EditorHttpController = + restoreDoc: (req, res, next) -> + project_id = req.params.Project_id + doc_id = req.params.doc_id + name = req.body.name + + if !name? + return res.send 400 # Malformed request + + logger.log project_id: project_id, doc_id: doc_id, "restoring doc" + ProjectEntityHandler.restoreDoc project_id, doc_id, name, (err, doc, folder_id) => + return next(error) if error? + EditorRealTimeController.emitToRoom(project_id, 'reciveNewDoc', folder_id, doc) + res.json { + doc_id: doc._id + } + diff --git a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee index 355bb298ec..ac9119d748 100644 --- a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee @@ -135,6 +135,13 @@ module.exports = ProjectEntityHandler = return callback(err) if err? callback(null, doc, folder_id) + restoreDoc: (project_id, doc_id, name, callback = (error, doc, folder_id) ->) -> + # getDoc will return the deleted doc's lines, but we don't actually remove + # the deleted doc, just create a new one from its lines. + ProjectEntityHandler.getDoc project_id, doc_id, (error, lines) -> + return callback(error) if error? + ProjectEntityHandler.addDoc project_id, null, name, lines, callback + addFile: (project_or_id, folder_id, fileName, path, sl_req_id, callback = (error, fileRef, folder_id) ->)-> {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id) Project.getProject project_or_id, "", (err, project) -> diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index cae1e9e4c5..aa7d19c1c7 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -7,6 +7,7 @@ SpellingController = require('./Features/Spelling/SpellingController') SecurityManager = require('./managers/SecurityManager') AuthorizationManager = require('./Features/Security/AuthorizationManager') EditorController = require("./Features/Editor/EditorController") +EditorHttpController = require("./Features/Editor/EditorHttpController") EditorUpdatesController = require("./Features/Editor/EditorUpdatesController") Settings = require('settings-sharelatex') TpdsController = require('./Features/ThirdPartyDataStore/TpdsController') @@ -125,6 +126,8 @@ module.exports = class Router app.get "/project/:Project_id/doc/:doc_id/diff", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi + app.post "/project/:Project_id/doc/:doc_id/restore", SecurityManager.requestCanAccessProject, EditorHttpController.restoreDoc + app.post '/project/:project_id/leave', AuthenticationController.requireLogin(), CollaboratorsController.removeSelfFromProject app.get '/project/:Project_id/collaborators', SecurityManager.requestCanAccessProject(allow_auth_token: true), CollaboratorsController.getCollaborators diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index 9e04573b65..81f3d12dc5 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -472,6 +472,9 @@ .track-changes-diff-toolbar.btn-toolbar .number-of-changes {{ changes }} in {{ name }} a(href="#").restore.btn.btn-small.btn-danger Restore to before these changes + .deleted-info(style="display:none;") + span This file has been deleted + a(href="#").restore-deleted.btn.btn-small.btn-success Restore .track-changes-diff-editor script(type='text/template')#changeListItemTemplate diff --git a/services/web/public/coffee/file-tree/EntityView.coffee b/services/web/public/coffee/file-tree/EntityView.coffee index b00c0cf017..913d076cc5 100644 --- a/services/web/public/coffee/file-tree/EntityView.coffee +++ b/services/web/public/coffee/file-tree/EntityView.coffee @@ -9,6 +9,7 @@ define [ initialize: () -> @ide = @options.manager.ide @manager = @options.manager + console.log "Registering view", @model, @model.id, @ @manager.registerView(@model.id, @) @bindToModel() diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index 19cf2f2382..4e8470f45b 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -38,6 +38,9 @@ define [ populateFileTree: () -> @view.bindToRootFolder(@project.get("rootFolder")) + + if @deletedDocsView? + @deletedDocsView.$el.remove() @deletedDocsView = new FolderView(model: @project.get("deletedDocs"), manager: @) @deletedDocsView.render() $("#sections").append(@deletedDocsView.$el) @@ -72,6 +75,7 @@ define [ @onMoveEntity(entity_id, folder_id) registerView: (entity_id, view) -> + console.log "inside", entity_id, view @views[entity_id] = view addEntityToFolder: (entity, folder_id) -> @@ -284,8 +288,6 @@ define [ _doDelete: (entity) -> @ide.socket.emit 'deleteEntity', entity.id, entity.get("type") - if entity.get("type") == "doc" - @project.get("deletedDocs").get("children").add entity @onDeleteEntity entity.id onDeleteEntity: (entity_id) -> @@ -294,6 +296,11 @@ define [ entity.set("deleted", true) entity.collection?.remove(entity) delete @views[entity_id] + + # Do this after the remove so that it's never in two places at once + # and so that it doesn't get reset by deleting from @views + if entity.get("type") == "doc" + @project.get("deletedDocs").get("children").add entity setLabels: (labels) -> @view.setLabels(labels) diff --git a/services/web/public/coffee/track-changes/DiffView.coffee b/services/web/public/coffee/track-changes/DiffView.coffee index 0ac6002e8c..58e444f72f 100644 --- a/services/web/public/coffee/track-changes/DiffView.coffee +++ b/services/web/public/coffee/track-changes/DiffView.coffee @@ -10,9 +10,14 @@ define [ template: $("#trackChangesDiffTemplate").html() events: - "click .restore": () -> - console.log "click" + "click .restore": (e) -> + e.preventDefault() @trigger "restore" + "click .restore-deleted": (e) -> + e.preventDefault() + @$("a.restore-deleted").attr("disabled", true) + @$("a.restore-deleted").text("Restoring...") + @trigger "restore-deleted" initialize: () -> @model.on "change:diff", () => @render() @@ -31,6 +36,10 @@ define [ if !@model.get("from")? or !@model.get("to")? or changes == 0 @$(".restore").hide() + if @model.get("doc").get("deleted") + @$(".restore").hide() + @$(".deleted-info").show() + @createAceEditor() @aceEditor.setValue(@getPlainDiffContent()) @aceEditor.clearSelection() diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 4d146c923b..63cbaa871e 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -164,7 +164,7 @@ define [ @diffView.remove() if !@diff.get("doc")? - console.log "This document has been deleted. What should we do?" + console.log "This document does not exist. What should we do?" return @diffView = new DiffView( @@ -175,6 +175,15 @@ define [ @diffView.on "restore", () => @restoreDiff(@diff) + @diffView.on "restore-deleted", () => + @restoreDeletedDoc @diff.get("doc"), (error, doc_id) => + return if error? or !doc_id? + setTimeout () => + # Give doc a chance to appear in file tree via socket.io + @hide() + @ide.fileTreeManager.openDoc(doc_id) + , 1000 + @diff.fetch() @ide.fileTreeManager.selectEntity(@doc_id) @@ -221,6 +230,21 @@ define [ }] }) + restoreDeletedDoc: (doc, callback) -> + $.ajax { + url: "/project/#{@project_id}/doc/#{doc.get("id")}/restore" + type: "POST" + dataType: "json" + data: + name: doc.get("name") + headers: + "X-CSRF-Token": window.csrfToken + success: (body, status, response) -> + callback(null, body?.doc_id) + error: (error) -> + callback(error) + } + enable: () -> @enabled = true diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index f9f12bbcc8..963e58fb16 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -30,7 +30,7 @@ background-color: #282828; color: white; border-right: 1px solid white; - .number-of-changes, .restore { + .number-of-changes, .restore, .deleted-info { position: absolute; } .number-of-changes { @@ -42,6 +42,13 @@ bottom: 5px; padding: 3px 9px; } + .deleted-info { + right: 10px; + bottom: 5px; + a { + padding: 3px 9px; + } + } } } diff --git a/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee new file mode 100644 index 0000000000..706476a6c4 --- /dev/null +++ b/services/web/test/UnitTests/coffee/Editor/EditorHttpControllerTests.coffee @@ -0,0 +1,46 @@ +SandboxedModule = require('sandboxed-module') +sinon = require('sinon') +require('chai').should() +modulePath = require('path').join __dirname, '../../../../app/js/Features/Editor/EditorHttpController' + +describe "EditorHttpController", -> + beforeEach -> + @EditorHttpController = SandboxedModule.require modulePath, requires: + '../Project/ProjectEntityHandler' : @ProjectEntityHandler = {} + "./EditorRealTimeController": @EditorRealTimeController = {} + "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } + @project_id = "mock-project-id" + @doc_id = "mock-doc-id" + @req = {} + @res = + send: sinon.stub() + json: sinon.stub() + + describe "restoreDoc", -> + beforeEach -> + @req.params = + Project_id: @project_id + doc_id: @doc_id + @req.body = + name: @name = "doc-name" + @ProjectEntityHandler.restoreDoc = sinon.stub().callsArgWith(3, null, + @doc = { "mock": "doc", _id: @new_doc_id = "new-doc-id" } + @folder_id = "mock-folder-id" + ) + @EditorRealTimeController.emitToRoom = sinon.stub() + @EditorHttpController.restoreDoc @req, @res + + it "should restore the doc", -> + @ProjectEntityHandler.restoreDoc + .calledWith(@project_id, @doc_id, @name) + .should.equal true + + it "should the real-time clients about the new doc", -> + @EditorRealTimeController.emitToRoom + .calledWith(@project_id, 'reciveNewDoc', @folder_id, @doc) + .should.equal true + + it "should return the new doc id", -> + @res.json + .calledWith(doc_id: @new_doc_id) + .should.equal true diff --git a/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee index a66a8f9884..5145e4d64a 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee @@ -339,6 +339,31 @@ describe 'ProjectEntityHandler', -> .calledWith(project_id, @doc._id.toString(), @lines) .should.equal true + describe "restoreDoc", -> + beforeEach -> + @name = "doc-name" + @lines = ['1234','abc'] + @doc = { "mock": "doc" } + @folder_id = "mock-folder-id" + @callback = sinon.stub() + @ProjectEntityHandler.getDoc = sinon.stub().callsArgWith(2, null, @lines) + @ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(4, null, @doc, @folder_id) + + @ProjectEntityHandler.restoreDoc project_id, doc_id, @name, @callback + + it 'should get the doc lines', -> + @ProjectEntityHandler.getDoc + .calledWith(project_id, doc_id) + .should.equal true + + it "should add a new doc with these doc lines", -> + @ProjectEntityHandler.addDoc + .calledWith(project_id, null, @name, @lines) + .should.equal true + + it "should call the callback with the new folder and doc", -> + @callback.calledWith(null, @doc, @folder_id).should.equal true + describe 'adding file', -> fileName = "something.jpg" beforeEach -> From 5c27ff44304038fcf668ad70f05837242019ef68 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 6 Jun 2014 14:24:45 +0100 Subject: [PATCH 09/10] Don't show diffs of deleted docs (much simpler) --- .../Features/Docstore/DocstoreManager.coffee | 9 ++++- .../Project/ProjectEntityHandler.coffee | 9 +++-- services/web/app/views/templates.jade | 11 ++++-- .../coffee/track-changes/DiffView.coffee | 39 +++++++++++-------- .../track-changes/TrackChangesManager.coffee | 2 - .../public/stylesheets/less/trackchanges.less | 13 ++++--- .../Docstore/DocstoreManagerTests.coffee | 16 ++++++++ .../Project/ProjectEntityHandlerTests.coffee | 6 +-- 8 files changed, 69 insertions(+), 36 deletions(-) diff --git a/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee b/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee index 44433d0f14..9a35e43c8b 100644 --- a/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee +++ b/services/web/app/coffee/Features/Docstore/DocstoreManager.coffee @@ -30,9 +30,14 @@ module.exports = DocstoreManager = logger.error err: error, project_id: project_id, "error getting all docs from docstore" callback(error) - getDoc: (project_id, doc_id, callback = (error, lines, rev) ->) -> - logger.log project_id: project_id, doc_id: doc_id, "getting doc in docstore api" + getDoc: (project_id, doc_id, options = {}, callback = (error, lines, rev) ->) -> + if typeof(options) == "function" + callback = options + options = {} + logger.log project_id: project_id, doc_id: doc_id, options: options, "getting doc in docstore api" url = "#{settings.apis.docstore.url}/project/#{project_id}/doc/#{doc_id}" + if options.include_deleted + url += "?include_deleted=true" request.get { url: url json: true diff --git a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee index ac9119d748..8559e1f64c 100644 --- a/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEntityHandler.coffee @@ -111,8 +111,11 @@ module.exports = ProjectEntityHandler = logger.log sl_req_id: sl_req_id, project_id: project_id, "removing root doc" Project.update {_id:project_id}, {$unset: {rootDoc_id: true}}, {}, callback - getDoc: (project_id, doc_id, callback = (error, lines, rev) ->) -> - DocstoreManager.getDoc project_id, doc_id, callback + getDoc: (project_id, doc_id, options = {}, callback = (error, lines, rev) ->) -> + if typeof(options) == "function" + callback = options + options = {} + DocstoreManager.getDoc project_id, doc_id, options, callback addDoc: (project_or_id, folder_id, docName, docLines, sl_req_id, callback = (error, doc, folder_id) ->)=> {callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id) @@ -138,7 +141,7 @@ module.exports = ProjectEntityHandler = restoreDoc: (project_id, doc_id, name, callback = (error, doc, folder_id) ->) -> # getDoc will return the deleted doc's lines, but we don't actually remove # the deleted doc, just create a new one from its lines. - ProjectEntityHandler.getDoc project_id, doc_id, (error, lines) -> + ProjectEntityHandler.getDoc project_id, doc_id, include_deleted: true, (error, lines) -> return callback(error) if error? ProjectEntityHandler.addDoc project_id, null, name, lines, callback diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index 81f3d12dc5..fc6b623590 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -470,11 +470,14 @@ script(type='text/template')#trackChangesDiffTemplate .track-changes-diff-toolbar.btn-toolbar - .number-of-changes {{ changes }} in {{ name }} - a(href="#").restore.btn.btn-small.btn-danger Restore to before these changes + .change-info + .number-of-changes {{ changes }} in {{ name }} + a(href="#").restore.btn.btn-small.btn-danger Restore to before these changes .deleted-info(style="display:none;") - span This file has been deleted - a(href="#").restore-deleted.btn.btn-small.btn-success Restore + strong {{ name }} + .controls + span This file has been deleted + a(href="#").restore-deleted.btn.btn-small.btn-success Restore .track-changes-diff-editor script(type='text/template')#changeListItemTemplate diff --git a/services/web/public/coffee/track-changes/DiffView.coffee b/services/web/public/coffee/track-changes/DiffView.coffee index 58e444f72f..d704ae6bb0 100644 --- a/services/web/public/coffee/track-changes/DiffView.coffee +++ b/services/web/public/coffee/track-changes/DiffView.coffee @@ -20,12 +20,13 @@ define [ @trigger "restore-deleted" initialize: () -> - @model.on "change:diff", () => @render() + if !@model.get("doc").get("deleted") + @model.on "change:diff", () => @render() + @model.fetch() + else + @render() render: -> - diff = @model.get("diff") - return unless diff? - changes = @getNumberOfChanges() html = Mustache.to_html @template, { changes: "#{changes} change#{if changes == 1 then "" else "s"}" @@ -33,22 +34,26 @@ define [ } @$el.html(html) - if !@model.get("from")? or !@model.get("to")? or changes == 0 - @$(".restore").hide() - if @model.get("doc").get("deleted") - @$(".restore").hide() + @$(".change-info").hide() @$(".deleted-info").show() + else + diff = @model.get("diff") + return unless diff? + + if !@model.get("from")? or !@model.get("to")? or changes == 0 + @$(".restore").hide() + + @createAceEditor() + @aceEditor.setValue(@getPlainDiffContent()) + @aceEditor.clearSelection() + @$ace = $(@aceEditor.renderer.container).find(".ace_scroller") + @insertMarkers() + @insertNameTag() + @insertMoreChangeLabels() + @bindToScrollEvents() + @scrollToFirstChange() - @createAceEditor() - @aceEditor.setValue(@getPlainDiffContent()) - @aceEditor.clearSelection() - @$ace = $(@aceEditor.renderer.container).find(".ace_scroller") - @insertMarkers() - @insertNameTag() - @insertMoreChangeLabels() - @bindToScrollEvents() - @scrollToFirstChange() return @ remove: () -> diff --git a/services/web/public/coffee/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/track-changes/TrackChangesManager.coffee index 63cbaa871e..0c45197047 100644 --- a/services/web/public/coffee/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/track-changes/TrackChangesManager.coffee @@ -184,8 +184,6 @@ define [ @ide.fileTreeManager.openDoc(doc_id) , 1000 - @diff.fetch() - @ide.fileTreeManager.selectEntity(@doc_id) diff --git a/services/web/public/stylesheets/less/trackchanges.less b/services/web/public/stylesheets/less/trackchanges.less index 963e58fb16..1b8444686a 100644 --- a/services/web/public/stylesheets/less/trackchanges.less +++ b/services/web/public/stylesheets/less/trackchanges.less @@ -30,7 +30,7 @@ background-color: #282828; color: white; border-right: 1px solid white; - .number-of-changes, .restore, .deleted-info { + .number-of-changes, .restore { position: absolute; } .number-of-changes { @@ -43,10 +43,13 @@ padding: 3px 9px; } .deleted-info { - right: 10px; - bottom: 5px; - a { - padding: 3px 9px; + .controls { + position: absolute; + right: 10px; + bottom: 5px; + a { + padding: 3px 9px; + } } } } diff --git a/services/web/test/UnitTests/coffee/Docstore/DocstoreManagerTests.coffee b/services/web/test/UnitTests/coffee/Docstore/DocstoreManagerTests.coffee index 164a5f656f..c9eda7d1df 100644 --- a/services/web/test/UnitTests/coffee/Docstore/DocstoreManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Docstore/DocstoreManagerTests.coffee @@ -131,6 +131,22 @@ describe "DocstoreManager", -> }, "error getting doc from docstore") .should.equal true + describe "with include_deleted=true", -> + beforeEach -> + @request.get = sinon.stub().callsArgWith(1, null, statusCode: 204, @doc) + @DocstoreManager.getDoc @project_id, @doc_id, include_deleted: true, @callback + + it "should get the doc from the docstore api (including deleted)", -> + @request.get + .calledWith({ + url: "#{@settings.apis.docstore.url}/project/#{@project_id}/doc/#{@doc_id}?include_deleted=true" + json: true + }) + .should.equal true + + it "should call the callback with the lines, version and rev", -> + @callback.calledWith(null, @lines, @rev).should.equal true + describe "getAllDocs", -> describe "with a successful response code", -> beforeEach -> diff --git a/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee index 5145e4d64a..b16c7e1a03 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectEntityHandlerTests.coffee @@ -286,7 +286,7 @@ describe 'ProjectEntityHandler', -> beforeEach -> @lines = ["mock", "doc", "lines"] @rev = 5 - @DocstoreManager.getDoc = sinon.stub().callsArgWith(2, null, @lines, @rev) + @DocstoreManager.getDoc = sinon.stub().callsArgWith(3, null, @lines, @rev) @ProjectEntityHandler.getDoc project_id, doc_id, @callback it "should call the docstore", -> @@ -346,14 +346,14 @@ describe 'ProjectEntityHandler', -> @doc = { "mock": "doc" } @folder_id = "mock-folder-id" @callback = sinon.stub() - @ProjectEntityHandler.getDoc = sinon.stub().callsArgWith(2, null, @lines) + @ProjectEntityHandler.getDoc = sinon.stub().callsArgWith(3, null, @lines) @ProjectEntityHandler.addDoc = sinon.stub().callsArgWith(4, null, @doc, @folder_id) @ProjectEntityHandler.restoreDoc project_id, doc_id, @name, @callback it 'should get the doc lines', -> @ProjectEntityHandler.getDoc - .calledWith(project_id, doc_id) + .calledWith(project_id, doc_id, include_deleted: true) .should.equal true it "should add a new doc with these doc lines", -> From 4fbebfbdc6dcb0561a53bf9a144777a823ed411e Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 6 Jun 2014 14:42:34 +0100 Subject: [PATCH 10/10] Tidy up styles --- services/web/app/views/templates.jade | 6 ++++ .../file-tree/DeletedDocsFolderView.coffee | 29 +++++++++++++++++++ .../public/coffee/file-tree/EntityView.coffee | 2 +- .../coffee/file-tree/FileTreeManager.coffee | 9 +++--- .../web/public/stylesheets/less/editor.less | 8 +++++ 5 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 services/web/public/coffee/file-tree/DeletedDocsFolderView.coffee diff --git a/services/web/app/views/templates.jade b/services/web/app/views/templates.jade index fc6b623590..2d73f73b09 100644 --- a/services/web/app/views/templates.jade +++ b/services/web/app/views/templates.jade @@ -82,6 +82,12 @@ .dropdown-caret i.icon-chevron-down .entity-label.label.label-success + + script(type="text/template")#deletedDocsFolderTemplate + .entity-list-item.entity-deleted-docs-folder(class="entity-{{ type }}", entity-type="{{ type }}", id="{{ id }}") + .clickable.js-clickable + span.name {{ name }} + .entity-label.label.label-success script(type="text/template")#entityListTemplate .contents diff --git a/services/web/public/coffee/file-tree/DeletedDocsFolderView.coffee b/services/web/public/coffee/file-tree/DeletedDocsFolderView.coffee new file mode 100644 index 0000000000..3ce1ec12fd --- /dev/null +++ b/services/web/public/coffee/file-tree/DeletedDocsFolderView.coffee @@ -0,0 +1,29 @@ +define [ + "file-tree/FolderView" +], (FolderView) -> + DeletedDocsFolderView = FolderView.extend + template: $("#deletedDocsFolderTemplate").html() + + render: () -> + @$el.append(Mustache.to_html @template, @model.attributes) + @_bindToDomElements() + @hideRenameBox() + @hideToggle() + @renderEntries() + @showEntries() + return @ + + onClick: () -> + e.preventDefault() + + onToggle: () -> + e.preventDefault() + + getContextMenuEntries: () -> null + + hideToggle: () -> + @$(".js-toggle").hide() + + + + diff --git a/services/web/public/coffee/file-tree/EntityView.coffee b/services/web/public/coffee/file-tree/EntityView.coffee index 913d076cc5..c7b17e7419 100644 --- a/services/web/public/coffee/file-tree/EntityView.coffee +++ b/services/web/public/coffee/file-tree/EntityView.coffee @@ -9,7 +9,6 @@ define [ initialize: () -> @ide = @options.manager.ide @manager = @options.manager - console.log "Registering view", @model, @model.id, @ @manager.registerView(@model.id, @) @bindToModel() @@ -113,6 +112,7 @@ define [ showContextMenu: (position) -> entries = @getContextMenuEntries() + return if !entries? @manager.trigger "contextmenu:beforeshow", @model, entries diff --git a/services/web/public/coffee/file-tree/FileTreeManager.coffee b/services/web/public/coffee/file-tree/FileTreeManager.coffee index 4e8470f45b..2f66bec030 100644 --- a/services/web/public/coffee/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/file-tree/FileTreeManager.coffee @@ -4,11 +4,12 @@ define [ "models/Folder" "file-tree/FileTreeView" "file-tree/FolderView" + "file-tree/DeletedDocsFolderView" "utils/Effects" "utils/Modal" "libs/backbone" "libs/jquery.storage" -], (Doc, File, Folder, FileTreeView, FolderView, Effects, Modal) -> +], (Doc, File, Folder, FileTreeView, FolderView, DeletedDocsFolderView, Effects, Modal) -> class FileTreeManager constructor: (@ide) -> _.extend(@, Backbone.Events) @@ -41,7 +42,7 @@ define [ if @deletedDocsView? @deletedDocsView.$el.remove() - @deletedDocsView = new FolderView(model: @project.get("deletedDocs"), manager: @) + @deletedDocsView = new DeletedDocsFolderView(model: @project.get("deletedDocs"), manager: @) @deletedDocsView.render() $("#sections").append(@deletedDocsView.$el) @hideDeletedDocs() @@ -75,7 +76,6 @@ define [ @onMoveEntity(entity_id, folder_id) registerView: (entity_id, view) -> - console.log "inside", entity_id, view @views[entity_id] = view addEntityToFolder: (entity, folder_id) -> @@ -307,7 +307,8 @@ define [ @deletedDocsView.setLabels(labels) showDeletedDocs: () -> - @deletedDocsView.$el.show() + if @project.get("deletedDocs").get("children").length > 0 + @deletedDocsView.$el.show() hideDeletedDocs: () -> @deletedDocsView.$el.hide() diff --git a/services/web/public/stylesheets/less/editor.less b/services/web/public/stylesheets/less/editor.less index 5f93c15c30..5b016630c9 100644 --- a/services/web/public/stylesheets/less/editor.less +++ b/services/web/public/stylesheets/less/editor.less @@ -509,6 +509,14 @@ body.editor { } } + .entity-deleted-docs-folder { + margin-top: 16px; + span.name { + padding: 6px; + border-bottom: 1px solid #ccc; + } + } + .entity-list { padding-left: 0px; }