mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-15 08:56:57 +00:00
Merge branch 'master' of github.com:sharelatex/web-sharelatex
This commit is contained in:
commit
63a5f2bf44
12 changed files with 188 additions and 70 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue