mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-30 00:55:25 -05:00
Allow deleting of projects forever
This commit is contained in:
parent
4b8f57de80
commit
2fb8620ba0
8 changed files with 93 additions and 9 deletions
|
@ -18,8 +18,15 @@ module.exports =
|
||||||
|
|
||||||
deleteProject: (req, res) ->
|
deleteProject: (req, res) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
logger.log project_id:project_id, "received request to delete project"
|
forever = req.query?.forever?
|
||||||
projectDeleter.archiveProject project_id, (err)->
|
logger.log project_id: project_id, forever: forever, "received request to delete project"
|
||||||
|
|
||||||
|
if forever
|
||||||
|
doDelete = projectDeleter.deleteProject
|
||||||
|
else
|
||||||
|
doDelete = projectDeleter.archiveProject
|
||||||
|
|
||||||
|
doDelete project_id, (err)->
|
||||||
if err?
|
if err?
|
||||||
res.send 500
|
res.send 500
|
||||||
else
|
else
|
||||||
|
|
|
@ -5,7 +5,7 @@ tagsHandler = require("../Tags/TagsHandler")
|
||||||
async = require("async")
|
async = require("async")
|
||||||
FileStoreHandler = require("../FileStore/FileStoreHandler")
|
FileStoreHandler = require("../FileStore/FileStoreHandler")
|
||||||
|
|
||||||
module.exports =
|
module.exports = ProjectDeleter =
|
||||||
|
|
||||||
markAsDeletedByExternalSource : (project_id, callback)->
|
markAsDeletedByExternalSource : (project_id, callback)->
|
||||||
logger.log project_id:project_id, "marking project as deleted by external data source"
|
logger.log project_id:project_id, "marking project as deleted by external data source"
|
||||||
|
@ -20,6 +20,12 @@ module.exports =
|
||||||
logger.log owner_id:owner_id, "deleting users projects"
|
logger.log owner_id:owner_id, "deleting users projects"
|
||||||
Project.remove owner_ref:owner_id, callback
|
Project.remove owner_ref:owner_id, callback
|
||||||
|
|
||||||
|
deleteProject: (project_id, callback = (error) ->) ->
|
||||||
|
# archiveProject takes care of the clean-up
|
||||||
|
ProjectDeleter.archiveProject project_id, (error) ->
|
||||||
|
logger.log project_id: project_id, "deleting project"
|
||||||
|
Project.remove _id: project_id, callback
|
||||||
|
|
||||||
archiveProject: (project_id, callback = (error) ->)->
|
archiveProject: (project_id, callback = (error) ->)->
|
||||||
logger.log project_id:project_id, "deleting project"
|
logger.log project_id:project_id, "deleting project"
|
||||||
Project.findById project_id, (err, project)=>
|
Project.findById project_id, (err, project)=>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#deleteEntityModal(style='display: none')
|
#archiveEntityModal(style='display: none')
|
||||||
.modal
|
.modal
|
||||||
.modal-header
|
.modal-header
|
||||||
h3 Delete Project
|
h3 Delete Project
|
||||||
|
@ -6,6 +6,21 @@
|
||||||
span.message Are you sure you want to delete
|
span.message Are you sure you want to delete
|
||||||
strong.name Project
|
strong.name Project
|
||||||
| ?
|
| ?
|
||||||
|
.modal-footer
|
||||||
|
button.btn.btn-danger.confirm Delete
|
||||||
|
button.btn.cancel No
|
||||||
|
|
||||||
|
#deleteEntityModal(style='display: none')
|
||||||
|
.modal
|
||||||
|
.modal-header
|
||||||
|
h3 Delete Project
|
||||||
|
.modal-body
|
||||||
|
p Are you sure you want to delete
|
||||||
|
strong.name Project
|
||||||
|
| ?
|
||||||
|
|
||||||
|
p
|
||||||
|
strong It will not be possible to recover your project once deleted.
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-danger.confirm Delete Forever
|
button.btn.btn-danger.confirm Delete Forever
|
||||||
button.btn.cancel No
|
button.btn.cancel No
|
||||||
|
|
|
@ -5,8 +5,10 @@ block content
|
||||||
-each project in projects
|
-each project in projects
|
||||||
- project_id = project._id.toString()
|
- project_id = project._id.toString()
|
||||||
.project_entry(id=project_id)
|
.project_entry(id=project_id)
|
||||||
.btn-group.project-actions
|
.project-actions
|
||||||
a.btn(href='/project/'+project_id+'/restore', data-csrf=csrfToken, data-id=project_id).restoreProject Restore
|
a.btn(href='/project/'+project_id+'/restore', data-csrf=csrfToken, data-id=project_id).restoreProject Restore
|
||||||
|
|
|
||||||
|
a.btn.btn-danger(href='/project/'+project_id+'?forever=true', data-csrf=csrfToken, data-name=project.name, data-id=project_id).deleteProject Delete Forever
|
||||||
.projectName #{project.name}
|
.projectName #{project.name}
|
||||||
|
|
||||||
include ../general/sidebar
|
include ../general/sidebar
|
||||||
|
|
|
@ -33,7 +33,7 @@ block content
|
||||||
li
|
li
|
||||||
a(href='/project/'+project_id+'/rename', data-name=project.name, data-id=project_id, data-csrf=csrfToken).renameProject Rename
|
a(href='/project/'+project_id+'/rename', data-name=project.name, data-id=project_id, data-csrf=csrfToken).renameProject Rename
|
||||||
li
|
li
|
||||||
a(href='/project/'+project_id, data-name=project.name, data-id=project_id, data-csrf=csrfToken).deleteProject Delete
|
a(href='/project/'+project_id, data-name=project.name, data-id=project_id, data-csrf=csrfToken).archiveProject Delete
|
||||||
-else
|
-else
|
||||||
li
|
li
|
||||||
a(href='/project/'+project_id+'/leave', data-name=project.name, data-id=project_id, data-csrf=csrfToken).leaveProject Leave
|
a(href='/project/'+project_id+'/leave', data-name=project.name, data-id=project_id, data-csrf=csrfToken).leaveProject Leave
|
||||||
|
|
|
@ -79,6 +79,35 @@ require [
|
||||||
$modal.find('.cancel').click (e)->
|
$modal.find('.cancel').click (e)->
|
||||||
$modal.modal('hide')
|
$modal.modal('hide')
|
||||||
|
|
||||||
|
$('.archiveProject').click (event)->
|
||||||
|
event.preventDefault()
|
||||||
|
$modal = $('#archiveEntityModal')
|
||||||
|
$confirm = $modal.find('.confirm')
|
||||||
|
$modal.modal({backdrop:true, show:true, keyboard:true})
|
||||||
|
name = $(@).data("name")
|
||||||
|
id = $(@).data("id")
|
||||||
|
|
||||||
|
$modal.find(".name").text(name)
|
||||||
|
|
||||||
|
href = this.href
|
||||||
|
self = @
|
||||||
|
$confirm.on 'click', (e) =>
|
||||||
|
$.ajax
|
||||||
|
url: href
|
||||||
|
type:'DELETE'
|
||||||
|
data:
|
||||||
|
_csrf: $(@).data("csrf")
|
||||||
|
success: (data)->
|
||||||
|
$modal.modal('hide')
|
||||||
|
if data.message
|
||||||
|
new Message data
|
||||||
|
else
|
||||||
|
$("##{id}").fadeOut(1000)
|
||||||
|
$modal.on 'hide', ->
|
||||||
|
$confirm.off 'click'
|
||||||
|
$modal.find('.cancel').click (e)->
|
||||||
|
$modal.modal('hide')
|
||||||
|
|
||||||
$('.renameProject').click (event)->
|
$('.renameProject').click (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
$modal = $('#renameProjectModal')
|
$modal = $('#renameProjectModal')
|
||||||
|
|
|
@ -18,8 +18,9 @@ describe "ProjectController", ->
|
||||||
url:"chat.com"
|
url:"chat.com"
|
||||||
siteUrl: "mysite.com"
|
siteUrl: "mysite.com"
|
||||||
@ProjectDeleter =
|
@ProjectDeleter =
|
||||||
archiveProject: sinon.stub().callsArgWith(1)
|
archiveProject: sinon.stub().callsArg(1)
|
||||||
restoreProject: sinon.stub().callsArgWith(1)
|
deleteProject: sinon.stub().callsArg(1)
|
||||||
|
restoreProject: sinon.stub().callsArg(1)
|
||||||
findArchivedProjects: sinon.stub()
|
findArchivedProjects: sinon.stub()
|
||||||
@ProjectDuplicator =
|
@ProjectDuplicator =
|
||||||
duplicate: sinon.stub().callsArgWith(3, null, {_id:@project_id})
|
duplicate: sinon.stub().callsArgWith(3, null, {_id:@project_id})
|
||||||
|
@ -70,13 +71,21 @@ describe "ProjectController", ->
|
||||||
jsPath:"js path here"
|
jsPath:"js path here"
|
||||||
|
|
||||||
describe "deleteProject", ->
|
describe "deleteProject", ->
|
||||||
it "should tell the project deleter", (done)->
|
it "should tell the project deleter to archive when forever=false", (done)->
|
||||||
@res.send = (code)=>
|
@res.send = (code)=>
|
||||||
@ProjectDeleter.archiveProject.calledWith(@project_id).should.equal true
|
@ProjectDeleter.archiveProject.calledWith(@project_id).should.equal true
|
||||||
code.should.equal 200
|
code.should.equal 200
|
||||||
done()
|
done()
|
||||||
@ProjectController.deleteProject @req, @res
|
@ProjectController.deleteProject @req, @res
|
||||||
|
|
||||||
|
it "should tell the project deleter to delete when forever=true", (done)->
|
||||||
|
@req.query = forever: "true"
|
||||||
|
@res.send = (code)=>
|
||||||
|
@ProjectDeleter.deleteProject.calledWith(@project_id).should.equal true
|
||||||
|
code.should.equal 200
|
||||||
|
done()
|
||||||
|
@ProjectController.deleteProject @req, @res
|
||||||
|
|
||||||
describe "restoreProject", ->
|
describe "restoreProject", ->
|
||||||
it "should tell the project deleter", (done)->
|
it "should tell the project deleter", (done)->
|
||||||
@res.send = (code)=>
|
@res.send = (code)=>
|
||||||
|
|
|
@ -55,6 +55,22 @@ describe 'Project deleter', ->
|
||||||
@Project.remove.calledWith(owner_ref:user_id).should.equal true
|
@Project.remove.calledWith(owner_ref:user_id).should.equal true
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
describe "deleteProject", ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
@project_id = "mock-project-id-123"
|
||||||
|
@deleter.archiveProject = sinon.stub().callsArg(1)
|
||||||
|
|
||||||
|
@deleter.deleteProject @project_id, done
|
||||||
|
|
||||||
|
it "should archive the project to clean it up", ->
|
||||||
|
@deleter.archiveProject
|
||||||
|
.calledWith(@project_id)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should remove the project from Mongo", ->
|
||||||
|
@Project.remove
|
||||||
|
.calledWith(_id: @project_id)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
describe "archiveProject", ->
|
describe "archiveProject", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
|
Loading…
Reference in a new issue