Allow uploading

This commit is contained in:
James Allen 2014-06-22 17:32:15 +01:00
parent f931df6084
commit f1eee96c85
11 changed files with 266 additions and 270 deletions

View file

@ -40,125 +40,10 @@ block content
i.fa.fa-comment
#editor-content(ng-cloak, layout="main", ng-hide="state.loading")
aside#file-tree.ui-layout-west(ng-controller="FileTreeController")
.toolbar.toolbar-small
a(
href,
ng-click="openNewDocModal()",
tooltip-html-unsafe="New<br>File",
tooltip-placement="bottom"
)
i.fa.fa-file
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
.toolbar-right
a(href, tooltip="Rename", tooltip-placement="bottom")
i.fa.fa-pencil
a(href, tooltip="Delete", tooltip-placement="bottom", tooltip-append-to-body="true")
i.fa.fa-trash-o
ul.list-unstyled.file-tree-list
file-entity(
entity="entity",
ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
)
include ./editor/file-tree
.ui-layout-center
script(type='text/ng-template', id='entityListItemTemplate')
li(
ng-class="{ 'selected': entity.selected }",
ng-controller="FileTreeEntityController"
)
.entity(ng-if="entity.type == 'doc'")
.entity-name(ng-click="select()")
//- Just a spacer to align with folders
i.fa.fa-fw.toggle
i.fa.fa-fw.fa-file
| {{ entity.name }}
.entity(ng-if="entity.type == 'file'")
.entity-name(ng-click="select()")
i.fa.fa-fw.toggle
i.fa.fa-fw.fa-image
| {{ entity.name }}
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
.entity-name
i.fa.fa-fw.toggle(
ng-class="{'fa-chevron-right': !expanded, 'fa-chevron-down': expanded}"
ng-click="toggleExpanded()"
)
i.fa.fa-fw(
ng-class="{\
'fa-folder': !expanded, \
'fa-folder-open': expanded \
}"
ng-click="select()"
)
span(ng-click="select()") {{ entity.name }}
ul.list-unstyled(ng-show="expanded")
file-entity(entity="child", ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, '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...
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

View file

@ -0,0 +1,143 @@
aside#file-tree.ui-layout-west(ng-controller="FileTreeController")
.toolbar.toolbar-small
a(
href,
ng-click="openNewDocModal()",
tooltip-html-unsafe="New<br>File",
tooltip-placement="bottom"
)
i.fa.fa-file
a(
href,
ng-click="openNewFolderModal()",
tooltip="New Folder",
tooltip-placement="bottom"
)
i.fa.fa-folder
a(
href,
ng-click="openUploadFileModal()",
tooltip="Upload",
tooltip-placement="bottom"
)
i.fa.fa-upload
.toolbar-right
a(href, tooltip="Rename", tooltip-placement="bottom")
i.fa.fa-pencil
a(href, tooltip="Delete", tooltip-placement="bottom", tooltip-append-to-body="true")
i.fa.fa-trash-o
ul.list-unstyled.file-tree-list
file-entity(
entity="entity",
ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
)
script(type='text/ng-template', id='entityListItemTemplate')
li(
ng-class="{ 'selected': entity.selected }",
ng-controller="FileTreeEntityController"
)
.entity(ng-if="entity.type == 'doc'")
.entity-name(ng-click="select()")
//- Just a spacer to align with folders
i.fa.fa-fw.toggle
i.fa.fa-fw.fa-file
| {{ entity.name }}
.entity(ng-if="entity.type == 'file'")
.entity-name(ng-click="select()")
i.fa.fa-fw.toggle
i.fa.fa-fw.fa-image
| {{ entity.name }}
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
.entity-name
i.fa.fa-fw.toggle(
ng-class="{'fa-chevron-right': !expanded, 'fa-chevron-down': expanded}"
ng-click="toggleExpanded()"
)
i.fa.fa-fw(
ng-class="{\
'fa-folder': !expanded, \
'fa-folder-open': expanded \
}"
ng-click="select()"
)
span(ng-click="select()") {{ entity.name }}
ul.list-unstyled(ng-show="expanded")
file-entity(entity="child", ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, '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...
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...
script(type="text/ng-template", id="uploadFileModalTemplate")
.modal-header
h3 Upload File(s)
.modal-body(
fine-upload
endpoint="/project/{{ project_id }}/upload"
waiting-for-response-text="Inserting file..."
failed-upload-text="Upload failed, sorry :("
upload-button-text="Select file(s)"
drag-area-text="drag file(s)"
hint-text="Hint: Press and hold the Control (Ctrl) key to select multiple files"
multiple="true"
on-complete-callback="onComplete"
on-upload-callback="onUpload"
params="{'folder_id': parent_folder_id}"
)
span Upload file(s)
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel

View file

@ -419,7 +419,17 @@ block content
script(type="text/ng-template", id="uploadProjectModalTemplate")
.modal-header
h3 Upload Zipped Project
.modal-body(ng-fine-upload)
.modal-body(
fine-upload
endpoint="/project/new/upload"
waiting-for-response-text="Creating project..."
failed-upload-text="Upload failed. Is it a valid zip file?"
upload-button-text="Select a .zip file"
drag-area-text="drag .zip file"
multiple="false"
allowed-extensions="['zip']"
on-complete-callback="onComplete"
)
span Upload a zipped project
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel

View file

@ -1,76 +0,0 @@
.box
.page-header
h2 Project Settings
.tabbable
ul.nav.nav-tabs
li.active
a(href='#generalProjectSettings', data-toggle="tab") General
li
a(href='#exportSettings', data-toggle="tab") Export & Copy
li
a(href='#deleteProjectTab', data-toggle="tab") Delete Project
li#manageDropboxSettiingsTabLink
a(href='#dropboxProjectSettings', data-toggle='tab') Dropbox
span.label.label-warning beta
.tab-content.form-horizontal
.tab-pane#generalProjectSettings.form.form-horizontal.active
if privilegeLevel == 'owner' || privilegeLevel == 'readAndWrite'
.control-group
label(for='xlInput').control-label Project Name
.controls
.input
input.projectName(type='text', value=project.name)
.control-group
label(for='input').control-label Root Document
.controls
.input
select#rootDocList
.control-group
label(for='spellCheck').control-label
| Spell check
.controls
select(name="spellCheckLanguage")#spellCheckLanguageSelection
option(value="",selected=(project.spellCheckLanguage == "")) Off
optgroup(label="Language")
for language in languages
option(
value=language.code,
selected=(language.code == project.spellCheckLanguage)
)= language.name
.control-group#multipleCompilers
label(for='input').control-label Compiler
.controls
.input
select#compilers
option(value='latex') LaTeX
option(value='pdflatex') pdfLaTeX
option(value='xelatex') XeLaTeX
option(value='lualatex') LuaLaTeX
else
span You do not have permission to modify these settings.
if privilegeLevel == 'owner'
.control-group
label(for='select').control-label Public Access
.controls
select#publicAccessLevel
option(value='private') Private
option(value='readOnly') Public - Read Only
option(value='readAndWrite') Public - Read and Write
.tab-pane#exportSettings
a.btn#DownloadZip Download Project as Zip
div &nbsp;
a.btn(href='/project/'+project._id+'/clone').cloneProject Clone Project
.tab-pane#deleteProjectTab
if privilegeLevel == 'owner'
button#deleteProject.btn.btn-danger Delete Project
else
span You do not have permission to modify these settings.
.tab-pane#dropboxProjectSettings

View file

@ -1,38 +0,0 @@
#controls
button#previous
img(src='images/go-up.svg', align='top', height='32')
| Previous
button#next
img(src='images/go-down.svg', align='top', height='32')
| Next
.separator
input#pageNumber(type='number', value='1', size='4', min='1')
span /
span#numPages --
.separator
button#next(title='Zoom Out')
img(src='images/zoom-out.svg', align='top', height='32')
button#next(title='Zoom In')
img(src='images/zoom-in.svg', align='top', height='32')
.separator
select#scaleSelect
option#customScaleOption(value='custom')
option(value='0.5') 50%
option(value='0.75') 75%
option(value='1') 100%
option(value='1.25') 125%
option(value='1.5', selected='selected') 150%
option(value='2') 200%
option#pageWidthOption(value='page-width') Page Width
option#pageFitOption(value='page-fit') Page Fit
.separator
button#print
img(src='images/document-print.svg', align='top', height='32')
| Print
.separator
input#fileInput(type='file')
.separator
span#info --
#loading Loading... 0%
#viewer

View file

@ -0,0 +1,69 @@
define [
"base"
"../../libs/fineuploader"
], (App) ->
App.directive 'fineUpload', ($timeout) ->
return {
scope: {
multiple: "="
endpoint: "@"
waitingForResponseText: "@"
failedUploadText: "@"
uploadButtonText: "@"
dragAreaText: "@"
hintText: "@"
allowedExtensions: "="
onCompleteCallback: "="
onUploadCallback: "="
params: "="
}
link: (scope, element, attrs) ->
multiple = scope.multiple or false
endpoint = scope.endpoint
if scope.allowedExtensions?
validation =
allowedExtensions: scope.allowedExtensions
else
validation = {}
text =
waitingForResponse: scope.waitingForResponseText or "Processing..."
failUpload: scope.failedUploadText or "Failed :("
uploadButton: scope.uploadButtonText or "Upload"
dragAreaText = scope.dragAreaText or "drag here"
hintText = scope.hintText or ""
onComplete = scope.onCompleteCallback or () ->
onUpload = scope.onUploadCallback or () ->
params = scope.params or {}
params._csrf = window.csrfToken
console.log "PARAMS", params
new qq.FineUploader
element: element[0]
multiple: multiple
disabledCancelForFormUploads: true
validation: validation
request:
endpoint: endpoint
forceMultipart: true
params: params
paramsInBody: false
callbacks:
onComplete: onComplete
onUpload: onUpload
text: text
template: """
<div class="qq-uploader">
<div class="qq-upload-drop-area"><span>{dragZoneText}</span></div>
<div class="qq-upload-button btn btn-primary btn-lg">
<div>{uploadButtonText}</div>
</div>
<span class="or btn-lg"> or </span>
<span class="drag-here btn-lg">#{dragAreaText}</span>
<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>
<div class="small">#{hintText}</div>
<ul class="qq-upload-list"></ul>
</div>
"""
}

View file

@ -4,6 +4,7 @@ define [
"ide/directives/layout"
"ide/services/ide"
"directives/focusOn"
"directives/fineUpload"
], (
App
FileTreeManager
@ -16,7 +17,7 @@ define [
window._ide = ide
ide.project_id = window.project_id
ide.project_id = $scope.project_id = window.project_id
ide.$scope = $scope
ide.socket = io.connect null,
reconnect: false

View file

@ -97,7 +97,11 @@ define [
return folder
getCurrentFolder: (startFolder = @$scope.rootFolder) ->
getCurrentFolder: () ->
# Return the root folder if nothing is selected
@_getCurrentFolder(@$scope.rootFolder) or @$scope.rootFolder
_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
@ -108,7 +112,7 @@ define [
return startFolder
if entity.type == "folder"
result = @getCurrentFolder(entity)
result = @_getCurrentFolder(entity)
return result if result?
return null

View file

@ -14,6 +14,13 @@ define [
controller: "NewFolderModalController"
)
$scope.openUploadFileModal = () ->
$modal.open(
templateUrl: "uploadFileModalTemplate"
controller: "UploadFileModalController"
scope: $scope
)
$scope.orderByFoldersFirst = (entity) ->
return 0 if entity.type == "folder"
return 1
@ -61,6 +68,27 @@ define [
$scope.state.inflight = false
$modalInstance.close()
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
]
App.controller "UploadFileModalController", [
"$scope", "ide", "$modalInstance", "$timeout",
($scope, ide, $modalInstance, $timeout) ->
parent_folder = ide.fileTreeManager.getCurrentFolder()
$scope.parent_folder_id = parent_folder?.id
uploadCount = 0
$scope.onUpload = () ->
uploadCount++
$scope.onComplete = (error, name, response) ->
$timeout (() ->
uploadCount--
if uploadCount == 0 and response? and response.success
$modalInstance.close("done")
), 250
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
]

View file

@ -7,5 +7,6 @@ define [
"directives/focusInput"
"directives/focusOn"
"directives/equals"
"directives/fineUpload"
], () ->
angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -1,6 +1,5 @@
define [
"base"
"../libs/fineuploader"
], (App) ->
App.directive 'ngEnter', () ->
return (scope, element, attrs) ->
@ -10,7 +9,6 @@ define [
scope.$eval(attrs.ngEnter, event: event)
event.preventDefault()
App.filter "formatDate", () ->
(date, format = "Do MMM YYYY, h:mm a") ->
moment(date).format(format)
@ -607,40 +605,11 @@ define [
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
App.directive 'ngFineUpload', ($timeout) ->
return (scope, element, attrs) ->
new qq.FineUploader
element: element[0]
multiple: false
disabledCancelForFormUploads: true
validation:
allowedExtensions: ["zip"]
request:
endpoint: "/project/new/upload"
forceMultipart: true
params:
_csrf: window.csrfToken
callbacks:
onComplete: (error, name, response)->
if response.project_id?
window.location = '/project/'+response.project_id
text:
waitingForResponse: "Creating project..."
failUpload: "Upload failed. Is it a valid zip file?"
uploadButton: "Select a .zip file"
template: """
<div class="qq-uploader">
<div class="qq-upload-drop-area"><span>{dragZoneText}</span></div>
<div class="qq-upload-button btn btn-primary btn-lg">
<div>{uploadButtonText}</div>
</div>
<span class="or btn-lg"> or </span>
<span class="drag-here btn-lg">drag a .zip file</span>
<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>
<ul class="qq-upload-list"></ul>
</div>
"""
App.controller 'UploadProjectModalController', ($scope, $modalInstance, $timeout) ->
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
$scope.onComplete = (error, name, response) ->
if response.project_id?
window.location = '/project/' + response.project_id