Merge branch 'master' of github.com:sharelatex/web-sharelatex

This commit is contained in:
Henry Oswald 2014-03-21 12:20:58 +00:00
commit 63a5f2bf44
12 changed files with 188 additions and 70 deletions

View file

@ -124,7 +124,7 @@ module.exports = class Router
app.get '/Project/:Project_id/version', SecutiryManager.requestCanAccessProject, versioningController.listVersions
app.get '/Project/:Project_id/version/:Version_id', SecutiryManager.requestCanAccessProject, versioningController.getVersion
app.get "/project/:Project_id/doc/:doc_id/updates", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
app.get "/project/:Project_id/updates", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
app.get "/project/:Project_id/doc/:doc_id/diff", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi

View file

@ -443,7 +443,8 @@
input(type="radio",name="toVersion").change-selector-to
div(class='change-description')
div(class='change-date') {{date}}
div.changed-docs {{docs}}
div.change-date {{date}}
div {{{users}}}
div(class='restore')

View file

@ -35,6 +35,8 @@ define [
identifier: "editor"
element: @editorPanel
@initializeEditor()
@bindToFileTreeEvents()
@enable()
@loadingIndicator = $(@templates.loadingIndicator)
@editorPanel.find("#editor").append(@loadingIndicator)
@leftPanel = @editorPanel.find("#leftEditorPanel")
@ -42,6 +44,11 @@ define [
@initSplitView()
@switchToFlatView()
bindToFileTreeEvents: () ->
@ide.fileTreeManager.on "open:doc", (doc_id, options = {}) =>
if @enabled
@openDoc doc_id, options
initSplitView: () ->
splitter = @editorPanel.find("#editorSplitter")
options =
@ -352,9 +359,8 @@ define [
getCurrentDocId: () ->
@current_doc_id
show: () ->
$("#editor").show()
hide: () ->
$("#editor").hide()
enable: () ->
@enabled = true
disable: () ->
@enabled = false

View file

@ -76,7 +76,7 @@ define [
openDoc: (doc, line) ->
doc_id = doc.id or doc
@ide.editor.openDoc(doc_id, line: line)
@trigger "open:doc", doc_id, line: line
@selectEntity(doc_id)
$.localStorage "doc.open_id.#{@project_id}", doc_id
@ -86,8 +86,7 @@ define [
@openDoc(doc_id, line)
openFile: (file) ->
@ide.mainAreaManager.change('file')
@ide.fileViewManager.showFile(file)
@trigger "open:file", file
@selectEntity(file.id)
openFolder: (folder) ->

View file

@ -13,5 +13,20 @@ define [
@ide.layoutManager.on "resize", () => @view.onResize()
@view.onResize()
@bindToFileTreeEvents()
@enable()
bindToFileTreeEvents: () ->
@ide.fileTreeManager.on "open:file", (file) =>
if @enabled
@showFile(file)
showFile: (file) ->
@ide.mainAreaManager.change('file')
@view.setModel(file)
enable: () ->
@enabled = true
disable: () ->
@enabled = false

View file

@ -106,12 +106,12 @@ define [
@sideBarView = new SideBarManager(@, $("#sections"))
selectElement = @sideBarView.selectElement
mainAreaManager = @mainAreaManager = new MainAreaManager(@, $("#content"))
@fileTreeManager = new FileTreeManager(@)
@editor = new Editor(@)
@pdfManager = new PdfManager(@)
if @userSettings.autoComplete
@autoCompleteManager = new AutoCompleteManager(@)
@spellingManager = new SpellingManager(@)
@fileTreeManager = new FileTreeManager(@)
@fileUploadManager = new FileUploadManager(@)
@searchManager = new SearchManager(@)
@cursorManager = new CursorManager(@)
@ -119,6 +119,8 @@ define [
@analyticsManager = new AnalyticsManager(@)
if @userSettings.trackChanges
@trackChangesManager = new TrackChangesManager(@)
else
@historyManager = new HistoryManager(@)
@setLoadingMessage("Connecting")
firstConnect = true
@ -186,7 +188,6 @@ define [
_.extend(Ide::, Backbone.Events)
window.ide = ide = new Ide()
ide.historyManager = new HistoryManager ide
ide.projectMembersManager = new ProjectMembersManager ide
ide.settingsManager = new SettingsManager ide
ide.helpManager = new HelpManager ide

View file

@ -12,26 +12,39 @@ define [
@state = "closed"
$("#toolbar").on "mouseenter", () => @onMouseOver()
$("#toolbar").on "mouseleave", (e) => @onMouseOut(e)
@tabs = []
addTab: (options) ->
@tabs.push options
tabEl = $(Mustache.to_html @templates.tab, options)
tabEl.find("a").attr("href", "#" + options.id)
contentEl = $(Mustache.to_html @templates.content, options)
contentEl.append(options.content)
if options.content?
contentEl = $(Mustache.to_html @templates.content, options)
contentEl.append(options.content)
$("#tab-content").append(contentEl)
if options.active
tabEl.addClass("active")
contentEl.addClass("active")
contentEl?.addClass("active")
if options.after?
tabEl.insertAfter($("##{options.after}-tab-li"))
else
$("#tabs").append(tabEl)
$("#tab-content").append(contentEl)
$("body").scrollTop(0)
tabEl.on "shown", () =>
$("body").scrollTop(0)
options.onShown() if options.onShown?
for other_tab in @tabs
if other_tab.id != options.id and other_tab.active and other_tab.onHidden?
other_tab.onHidden()
other_tab.active = false
options.active = true
if options.lock
@lockOpen()
else
@ -40,6 +53,7 @@ define [
if options.contract
@contract()
lockOpen: () ->
@locked_open = true
$("#toolbar").css({

View file

@ -112,7 +112,7 @@ define [
view.setHoverUnselected()
triggerChangeDiff: () ->
@trigger "change_diff", @collection.models[@selectedFromIndex], @collection.models[@selectedToIndex]
@trigger "change_diff", @selectedFromIndex, @selectedToIndex
listShorterThanContainer: ->
@$el.height() > @$(".change-list").height()
@ -131,12 +131,12 @@ define [
callback(error)
success: (collection, response) =>
@hideLoading()
if response.updates.length == @collection.batchSize
@loadUntilFull(callback)
else
if @collection.isAtEnd()
@atEndOfCollection = true
@showEmptyMessageIfCollectionEmpty()
callback()
else
@loadUntilFull(callback)
else
callback() if callback?
@ -189,9 +189,16 @@ define [
hue: user.hue()
name: user.name()
}
docNames = []
for doc in @model.get("docs")
if doc.entity?
docNames.push doc.entity.get("name")
else
docNames.push "deleted"
data = {
date: moment(parseInt(@model.get("end_ts"), 10)).calendar()
users: userHtml.join("")
docs: docNames.join(", ")
}
@$el.html Mustache.to_html(@templates.item, data)
@ -236,20 +243,20 @@ define [
@$(".change-selector-to").prop("checked", checked)
setSelected: (first, last) ->
@$el.addClass("selected")
@$el.addClass("selected-change")
if first
@$el.addClass("selected-to")
@$el.addClass("selected-change-to")
else
@$el.removeClass("selected-to")
@$el.removeClass("selected-change-to")
if last
@$el.addClass("selected-from")
@$el.addClass("selected-change-from")
else
@$el.removeClass("selected-from")
@$el.removeClass("selected-change-from")
setUnselected: () ->
@$el.removeClass("selected-to")
@$el.removeClass("selected-from")
@$el.removeClass("selected")
@$el.removeClass("selected-change-to")
@$el.removeClass("selected-change-from")
@$el.removeClass("selected-change")
setHoverSelected: (first, last) ->
@$el.addClass("hover-selected")

View file

@ -13,11 +13,17 @@ define [
constructor: (@ide) ->
@project_id = window.userSettings.project_id
@$el = $(@template)
$("#editorWrapper").append(@$el)
@hideEl()
@ide.mainAreaManager.addArea
identifier: "trackChanges"
element: @$el
@ide.editor.on "change:doc", () =>
@hideEl()
@ide.tabManager.addTab
id: "history"
name: "History"
after: "code"
contract: true
onShown: () => @show()
onHidden: () => @hide()
@ide.editor.on "resize", () =>
@diffView?.resize()
@ -26,20 +32,18 @@ define [
e.preventDefault
@hide()
@ide.fileTreeManager.on "contextmenu:beforeshow", (entity, entries) =>
if entity instanceof Doc
entries.push {
divider: true
}, {
text: "History"
onClick: () =>
@show(entity.id)
}
@bindToFileTreeEvents()
show: (@doc_id) ->
@ide.fileTreeManager.selectEntity(@doc_id)
@disable()
@changes = new ChangeList([], doc_id: @doc_id, project_id: @project_id)
bindToFileTreeEvents: () ->
@ide.fileTreeManager.on "open:doc", (doc_id) =>
if @enabled
@doc_id = doc_id
@updateDiff()
show: () ->
@changes = new ChangeList([], project_id: @project_id, ide: @ide)
@changeListView = new ChangeListView(
collection : @changes,
@ -49,8 +53,8 @@ define [
@changeListView.loadUntilFull (error) =>
@autoSelectDiff()
@changeListView.on "change_diff", (fromModel, toModel) =>
@showDiff(fromModel, toModel)
@changeListView.on "change_diff", (fromIndex, toIndex) =>
@selectDocAndUpdateDiff(fromIndex, toIndex)
@changeListView.on "restore", (change) =>
@restore(change)
@ -58,11 +62,17 @@ define [
if @diffView?
@diffView.destroy()
@showEl()
@ide.mainAreaManager.change "trackChanges"
@ide.editor.disable()
@ide.fileViewManager.disable()
@enable()
hide: () ->
@hideEl()
@ide.editor.enable()
@ide.fileViewManager.enable()
@disable()
@ide.fileTreeManager.openDoc(@doc_id)
@ide.mainAreaManager.change "editor"
autoSelectDiff: () ->
if @changes.models.length == 0
@ -81,15 +91,39 @@ define [
toChange = @changes.models[0]
fromChange = @changes.models[fromIndex]
@showDiff(fromChange, toChange)
@changeListView.setSelectionRange(fromIndex, 0)
@updateDiff()
selectDocAndUpdateDiff: (fromIndex, toIndex) ->
doc_ids = []
for change in @changes.models.slice(toIndex, fromIndex + 1)
for doc in change.get("docs") or []
doc_ids.push doc.id if doc.id not in doc_ids
if !@doc_id? or @doc_id not in doc_ids
@doc_id = doc_ids[0]
@updateDiff()
updateDiff: () ->
fromIndex = @changeListView.selectedFromIndex
toIndex = @changeListView.selectedToIndex
if !toIndex? or !fromIndex?
console.log "No selection - what should we do!?"
return
{from, to} = @_findDocVersionsRangeInSelection(@doc_id, fromIndex, toIndex)
if !from? or !to?
console.log "No diff, should probably just show latest version"
return
showDiff: (fromModel, toModel) ->
@diff = new Diff({
project_id: @project_id
doc_id: @doc_id
from: fromModel.get("fromVersion")
to: toModel.get("toVersion")
from: from
to: to
})
if @diffView?
@ -100,13 +134,25 @@ define [
)
@diff.fetch()
showEl: ->
@ide.editor.hide()
@$el.show()
@ide.fileTreeManager.selectEntity(@doc_id)
hideEl: () ->
@ide.editor.show()
@$el.hide()
_findDocVersionsRangeInSelection: (doc_id, fromIndex, toIndex) ->
from = null
to = null
for change in @changes.models.slice(toIndex, fromIndex + 1)
for doc in change.get("docs")
if doc.id == doc_id
if from? and to?
from = Math.min(from, doc.fromV)
to = Math.max(to, doc.toV)
else
from = doc.fromV
to = doc.toV
break
return {from, to}
restore: (change) ->
name = @ide.fileTreeManager.getNameOfEntityId(@doc_id)
@ -141,4 +187,10 @@ define [
callback(error)
}
enable: () ->
@enabled = true
disable: () ->
@enabled = false
return TrackChangesManager

View file

@ -7,12 +7,20 @@ define [
model = {
start_ts: change.meta.start_ts
end_ts: change.meta.end_ts
fromVersion: change.fromV
toVersion: change.toV
}
model.users = []
for user in change.meta.users or []
model.users.push User.findOrBuild(user.id, user)
if model.users.length == 0
model.users.push User.getAnonymousUser()
model.docs = []
for doc_id, data of change.docs
model.docs.push
id: doc_id
fromV: data.fromV
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)
return model

View file

@ -4,21 +4,29 @@ define [
], (Change)->
ChangeList = Backbone.Collection.extend
model: Change
batchSize: 25
batchSize: 10
initialize: (models, @options) ->
@ide = @options.ide
@atEnd = false
url: () ->
url = "/project/#{@options.project_id}/doc/#{@options.doc_id}/updates?limit=#{@batchSize}"
if @models.length > 0
last = @models[@models.length - 1]
url += "&to=#{last.get("fromVersion") - 1}"
url = "/project/#{@options.project_id}/updates?min_count=#{@batchSize}"
if @nextBeforeTimestamp?
url += "&before=#{@nextBeforeTimestamp}"
return url
isAtEnd: () -> @atEnd
parse: (json) ->
@nextBeforeTimestamp = json.nextBeforeTimestamp
@atEnd = !@nextBeforeTimestamp
return json.updates
fetchNextBatch: (options = {}) ->
if @isAtEnd()
options.success?(@)
return
options.add = true
@fetch options

View file

@ -126,10 +126,14 @@
min-height: 38px;
}
.change-name {
font-size: 0.9em;
font-size: 11px;
color: #666;
text-transform: capitalize;
}
.change-date {
margin-top: 2px;
font-size: 12px;
}
.color-square {
display: inline-block;
height: 10px;
@ -137,6 +141,9 @@
margin-right: 4px;
margin-bottom: -1px;
}
.changed-docs {
font-weight: bold;
}
.restore {
a {
display: block;
@ -153,7 +160,7 @@
li.loading-changes, li.empty-message {
padding: 6px;
}
li.selected {
li.selected-change {
background-color: #eaeaea;
.change-selectors {
.range {
@ -161,7 +168,7 @@
}
}
}
li.selected-to {
li.selected-change-to {
.change-selectors {
.range {
top: 10px;
@ -171,7 +178,7 @@
}
}
}
li.selected-from {
li.selected-change-from {
.change-selectors {
.range {
bottom: 37px;
@ -223,7 +230,7 @@
}
}
}
li.selected-from.hover-selected-from {
li.selected-change-from.hover-selected-from {
.change-selectors {
.range {
bottom: 37px;