Add in creating of files to editor

This commit is contained in:
James Allen 2014-06-22 12:10:42 +01:00
parent 6d0053e709
commit f41534ee4d
11 changed files with 203 additions and 28 deletions

View file

@ -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, 'reciveNewDoc', folder_id, doc)
EditorRealTimeController.emitToRoom(project_id, 'docCreated', folder_id, doc)
callback(err, doc)
addFile: (project_id, folder_id, fileName, path, sl_req_id, callback = (error, file)->)->

View file

@ -1,6 +1,7 @@
ProjectEntityHandler = require "../Project/ProjectEntityHandler"
logger = require "logger-sharelatex"
EditorRealTimeController = require "./EditorRealTimeController"
EditorController = require "./EditorController"
module.exports = EditorHttpController =
restoreDoc: (req, res, next) ->
@ -19,3 +20,10 @@ module.exports = EditorHttpController =
doc_id: doc._id
}
addDoc: (req, res, next) ->
project_id = req.params.Project_id
name = req.body.name
parent_folder_id = req.body.parent_folder_id
EditorController.addDoc project_id, parent_folder_id, name, [], (error, doc) ->
return next(error) if error?
res.json doc

View file

@ -87,6 +87,8 @@ module.exports = class Router
app.get '/Project/:Project_id', SecurityManager.requestCanAccessProject, ProjectController.loadEditor
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/compile', SecurityManager.requestCanAccessProject, CompileController.compile
app.get '/Project/:Project_id/output/output.pdf', SecurityManager.requestCanAccessProject, CompileController.downloadPdf
app.get /^\/project\/([^\/]*)\/output\/(.*)$/,

View file

@ -40,9 +40,14 @@ block content
i.fa.fa-comment
#editor-content(ng-cloak, layout="main", ng-hide="state.loading")
aside#file-tree.ui-layout-west
aside#file-tree.ui-layout-west(ng-controller="FileTreeController")
.toolbar.toolbar-small
a(href, tooltip-html-unsafe="New<br>File", tooltip-placement="bottom")
a(
href,
ng-click="openNewDocModal()",
tooltip-html-unsafe="New<br>File",
tooltip-placement="bottom"
)
i.fa.fa-file
a(href, tooltip="New Folder", tooltip-placement="bottom")
i.fa.fa-folder
@ -58,7 +63,7 @@ block content
ul.list-unstyled.file-tree-list
file-entity(
entity="entity",
ng-repeat="entity in rootFolder.children"
ng-repeat="entity in rootFolder.children | orderBy:'name'"
)
.ui-layout-center
@ -97,8 +102,32 @@ block content
span(ng-click="select()") {{ entity.name }}
ul.list-unstyled(ng-show="expanded")
file-entity(entity="child", ng-repeat="child in entity.children")
file-entity(entity="child", ng-repeat="child in entity.children | orderBy:'name'")
script(type='text/ng-template', id='newDocModalTemplate')
.modal-header
h3 New File
.modal-body
form(novalidate, name="newDocForm")
input.form-control(
type="text",
placeholder="File 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="newDocForm.$invalid || state.inflight"
ng-click="create()"
)
span(ng-hide="state.inflight") Create
span(ng-show="state.inflight") Creating...
//- #loadingScreen
//- h3 Loading...

View file

@ -2,35 +2,35 @@ define [
"base"
"ide/file-tree/FileTreeManager"
"ide/directives/layout"
"ide/services/ide"
"directives/focusOn"
], (
App
FileTreeManager
) ->
App.controller "IdeController", ["$scope", "$timeout", ($scope, $timeout) ->
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
$scope.state = {
loading: true
load_progress: 40
}
window.ide = ide = {
'$scope': $scope
}
window._ide = ide
ide.project_id = window.project_id
ide.$scope = $scope
ide.socket = io.connect null,
reconnect: false
"force new connection": true
ide.fileTreeManager = new FileTreeManager(ide, $scope)
$scope.project_id = window.project_id
ioOptions =
reconnect: false
"force new connection": true
$scope.socket = io.connect null, ioOptions
$scope.socket.on "connect", () ->
ide.socket.on "connect", () ->
$scope.$apply () ->
$scope.state.load_progress = 80
joinProject = () =>
$scope.socket.emit 'joinProject', {
project_id: $scope.project_id
ide.socket.emit 'joinProject', {
project_id: ide.project_id
}, (err, project, permissionsLevel, protocolVersion) =>
if $scope.protocolVersion? and $scope.protocolVersion != protocolVersion
location.reload(true)
@ -43,8 +43,6 @@ define [
$scope.$emit "project:joined"
console.log "Project", $scope.project, $scope.rootFolder
setTimeout(joinProject, 100) ]
angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -1,30 +1,61 @@
define [
"ide/file-tree/directives/fileEntity"
"ide/file-tree/controllers/FileTreeController"
"ide/file-tree/controllers/FileTreeFolderController"
"ide/file-tree/controllers/FileTreeEntityController"
], () ->
class FileTreeManager
constructor: (@ide, @$scope) ->
@$scope.$on "project:joined", =>
console.log "Joined"
@loadRootFolder()
@_bindToSocketEvents()
_bindToSocketEvents: () ->
@ide.socket.on "docCreated", (parent_folder_id, doc) =>
console.log "Doc created", parent_folder_id, doc
parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
@$scope.$apply () ->
parent_folder.children.push {
name: doc.name
id: doc._id
type: "doc"
}
findEntityById: (id) ->
@_findEntityByIdInFolder @$scope.rootFolder, id
_findEntityByIdInFolder: (folder, id) ->
for entity in folder.children or []
if entity.id == id
return entity
else if entity.children?
result = @_findEntityByIdInFolder(entity, id)
return result if result?
return null
forEachEntity: (callback) ->
@_forEachEntityInFolder(@$scope.rootFolder, callback)
_forEachEntityInFolder: (folder, callback) ->
for entity in folder.children
for entity in folder.children or []
callback(entity)
if entity.children?
@_forEachEntityInFolder(entity, callback)
# forEachFolder: (callback) ->
# @forEachEntity (entity) ->
# if entity.type == "folder"
# callback(entity)
loadRootFolder: () ->
@$scope.rootFolder = @_parseFolder(@$scope.project.rootFolder[0])
_parseFolder: (rawFolder) ->
folder = {
name: rawFolder.name
id: rawFolder.id
id: rawFolder._id
type: "folder"
children: []
}
@ -32,18 +63,54 @@ define [
for doc in rawFolder.docs or []
folder.children.push {
name: doc.name
type: "doc"
id: doc._id
type: "doc"
}
for file in rawFolder.fileRefs or []
folder.children.push {
name: file.name
type: "file"
id: file._id
type: "file"
}
for childFolder in rawFolder.folders or []
folder.children.push @_parseFolder(childFolder)
return folder
getCurrentFolder: (startFolder = @$scope.rootFolder) ->
for entity in startFolder.children or []
# The 'current' folder is either the one selected, or
# the one containing the selected doc/file
if entity.selected
if entity.type == "folder"
return entity
else
return startFolder
if entity.type == "folder"
result = @getCurrentFolder(entity)
return result if result?
return null
createDocInCurrentFolder: (name, callback = (error, doc) ->) ->
# We'll wait for the socket.io 'createDoc' notification to actually
# add the doc for us.
parent_folder = @getCurrentFolder()
$.ajax {
url: "/project/#{@ide.project_id}/doc"
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: (doc) ->
console.log "Got doc from POST", doc
callback(null, doc)
failure: (error) -> callback(error)
}

View file

@ -0,0 +1,33 @@
define [
"base"
], (App) ->
App.controller "FileTreeController", ["$scope", "$modal", ($scope, $modal) ->
$scope.openNewDocModal = () ->
$modal.open(
templateUrl: "newDocModalTemplate"
controller: "NewDocModalController"
)
]
App.controller "NewDocModalController", [
"$scope", "ide", "$modalInstance", "$timeout",
($scope, ide, $modalInstance, $timeout) ->
$scope.inputs =
name: "name.tex"
$scope.state =
inflight: false
$modalInstance.opened.then () ->
$timeout () ->
$scope.$broadcast "open"
, 700
$scope.create = () ->
$scope.state.inflight = true
ide.fileTreeManager.createDocInCurrentFolder $scope.inputs.name, (error, doc) ->
$scope.state.inflight = false
$modalInstance.close()
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
]

View file

@ -1,7 +1,7 @@
define [
"base"
], (App) ->
App.controller "FileTreeEntityController", ["$scope", ($scope) ->
App.controller "FileTreeEntityController", ["$scope", "ide", ($scope, ide) ->
$scope.select = ($event) ->
ide.fileTreeManager.forEachEntity (entity) ->
entity.selected = false

View file

@ -0,0 +1,7 @@
define [
"base"
], (App) ->
# We create and provide this as service so that we can access the global ide
# from within other parts of the angular app.
App.factory "ide", () ->
return {}

View file

@ -71,7 +71,14 @@
ul.file-tree-list {
font-size: 0.8rem;
margin-top: (@line-height-computed / 4);
margin: 0;
padding: (@line-height-computed / 4) 0;
position: absolute;
top: 32px;
bottom: 0;
left: 0;
right: 0;
overflow-y: scroll;
ul {
margin-left: (@line-height-computed / 2);

View file

@ -9,8 +9,10 @@ describe "EditorHttpController", ->
'../Project/ProjectEntityHandler' : @ProjectEntityHandler = {}
"./EditorRealTimeController": @EditorRealTimeController = {}
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
"./EditorController": @EditorController = {}
@project_id = "mock-project-id"
@doc_id = "mock-doc-id"
@parent_folder_id = "mock-folder-id"
@req = {}
@res =
send: sinon.stub()
@ -44,3 +46,25 @@ describe "EditorHttpController", ->
@res.json
.calledWith(doc_id: @new_doc_id)
.should.equal true
describe "addDoc", ->
beforeEach ->
@doc = { "mock": "doc" }
@req.params =
Project_id: @project_id
@req.body =
name: @name = "doc-name"
parent_folder_id: @parent_folder_id
@EditorController.addDoc = sinon.stub().callsArgWith(4, null, @doc)
@EditorHttpController.addDoc @req, @res
it "should call EditorController.addDoc", ->
@EditorController.addDoc
.calledWith(@project_id, @parent_folder_id, @name, [])
.should.equal true
it "should send the doc back as JSON", ->
@res.json
.calledWith(@doc)
.should.equal true