mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge branch 'master' of github.com:sharelatex/web-sharelatex
This commit is contained in:
commit
af659e7690
8 changed files with 115 additions and 62 deletions
|
@ -22,7 +22,7 @@
|
|||
|
||||
script(type="text/template")#tabTemplate
|
||||
li(id="{{ id }}-tab-li")
|
||||
a(href="#", data-toggle="tab", data-target="\\#{{ id }}-tab", class="tab-link {{ id }}-tab")
|
||||
a(href="#", data-toggle="tab", data-target="\\#{{ show }}-tab", class="tab-link {{ id }}-tab")
|
||||
.content {{ name }}
|
||||
|
||||
script(type="text/template")#tabContentTemplate
|
||||
|
@ -436,6 +436,12 @@
|
|||
.change-list-area
|
||||
.track-changes-diff
|
||||
|
||||
script(type='text/template')#trackChangesDiffTemplate
|
||||
.track-changes-diff-toolbar.btn-toolbar
|
||||
.number-of-changes {{ changes }} in <strong>{{ name }}</strong>
|
||||
a(href="#").restore.btn.btn-small.btn-danger Restore to before these changes
|
||||
.track-changes-diff-editor
|
||||
|
||||
script(type='text/template')#changeListItemTemplate
|
||||
div(class='change-selectors')
|
||||
div.range
|
||||
|
@ -447,9 +453,6 @@
|
|||
div.change-date {{date}}
|
||||
div {{{users}}}
|
||||
|
||||
div(class='restore')
|
||||
a(href="#") Restore to here
|
||||
|
||||
script(type='text/template')#changeListItemUserTemplate
|
||||
div(class='change-name')
|
||||
div.color-square(style="background-color: hsl({{hue}}, 100%, 70%);")
|
||||
|
|
|
@ -97,7 +97,7 @@ define [
|
|||
@views[@selected_entity_id].deselect()
|
||||
@selected_entity_id = entity_id
|
||||
@ide.sideBarView.deselectAll()
|
||||
@views[entity_id].select()
|
||||
@views[entity_id]?.select()
|
||||
|
||||
getEntity: (entity_id) ->
|
||||
@views[entity_id]?.model
|
||||
|
|
|
@ -17,8 +17,9 @@ define [
|
|||
addTab: (options) ->
|
||||
@tabs.push options
|
||||
|
||||
options.show ||= options.id
|
||||
tabEl = $(Mustache.to_html @templates.tab, options)
|
||||
tabEl.find("a").attr("href", "#" + options.id)
|
||||
tabEl.find("a").attr("href", "#" + options.show)
|
||||
|
||||
if options.content?
|
||||
contentEl = $(Mustache.to_html @templates.content, options)
|
||||
|
@ -53,6 +54,8 @@ define [
|
|||
if options.contract
|
||||
@contract()
|
||||
|
||||
show: (tab) ->
|
||||
$("##{tab}-tab-li > a").tab("show")
|
||||
|
||||
lockOpen: () ->
|
||||
@locked_open = true
|
||||
|
|
|
@ -75,9 +75,6 @@ define [
|
|||
delete @hoverFromIndex
|
||||
@resetHoverStates()
|
||||
|
||||
view.on "click:restore", (e) =>
|
||||
@trigger "restore", view.model
|
||||
|
||||
view.resetSelector(index, @selectedFromIndex, @selectedToIndex)
|
||||
|
||||
setSelectionRange: (fromIndex, toIndex) ->
|
||||
|
@ -173,8 +170,6 @@ define [
|
|||
@trigger "mouseenter:from", args...
|
||||
"mouseleave .change-selector-from": (args...) ->
|
||||
@trigger "mouseleave:from", args...
|
||||
"click .restore a": "onRestoreClick"
|
||||
|
||||
|
||||
templates:
|
||||
item: $("#changeListItemTemplate").html()
|
||||
|
@ -214,10 +209,6 @@ define [
|
|||
onFromSelectorClick: (e) ->
|
||||
@trigger "selected:from", e, @
|
||||
|
||||
onRestoreClick: (e) ->
|
||||
e.preventDefault()
|
||||
@trigger "click:restore", e, @
|
||||
|
||||
isSelectedFrom: () ->
|
||||
@$(".change-selector-from").is(":checked")
|
||||
|
||||
|
|
|
@ -4,15 +4,33 @@ define [
|
|||
"ace/range"
|
||||
"moment"
|
||||
"libs/backbone"
|
||||
"libs/mustache"
|
||||
], (Ace, LatexMode, Range, moment)->
|
||||
DiffView = Backbone.View.extend
|
||||
template: $("#trackChangesDiffTemplate").html()
|
||||
|
||||
events:
|
||||
"click .restore": () ->
|
||||
console.log "click"
|
||||
@trigger "restore"
|
||||
|
||||
initialize: () ->
|
||||
@model.on "change:diff", () => @render()
|
||||
@render()
|
||||
|
||||
render: ->
|
||||
diff = @model.get("diff")
|
||||
return unless diff?
|
||||
|
||||
changes = @getNumberOfChanges()
|
||||
html = Mustache.to_html @template, {
|
||||
changes: "#{changes} change#{if changes == 1 then "" else "s"}"
|
||||
name: @model.get("doc")?.get("name")
|
||||
}
|
||||
@$el.html(html)
|
||||
|
||||
if !@model.get("from")? or !@model.get("to")? or changes == 0
|
||||
@$(".restore").hide()
|
||||
|
||||
@createAceEditor()
|
||||
@aceEditor.setValue(@getPlainDiffContent())
|
||||
@aceEditor.clearSelection()
|
||||
|
@ -24,12 +42,12 @@ define [
|
|||
@scrollToFirstChange()
|
||||
return @
|
||||
|
||||
destroy: () ->
|
||||
remove: () ->
|
||||
@$editor?.remove()
|
||||
@undelegateEvents()
|
||||
|
||||
createAceEditor: () ->
|
||||
@$el.empty()
|
||||
@$editor = $("<div/>")
|
||||
@$editor = @$(".track-changes-diff-editor")
|
||||
@$el.append(@$editor)
|
||||
@aceEditor = Ace.edit(@$editor[0])
|
||||
@aceEditor.setTheme("ace/theme/#{window.userSettings.theme}")
|
||||
|
@ -54,6 +72,12 @@ define [
|
|||
content += entry.u or entry.i or entry.d or ""
|
||||
return content
|
||||
|
||||
getNumberOfChanges: () ->
|
||||
changes = 0
|
||||
for entry in @model.get("diff") or []
|
||||
changes += 1 if entry.i? or entry.d?
|
||||
return changes
|
||||
|
||||
insertMarkers: () ->
|
||||
row = 0
|
||||
column = 0
|
||||
|
|
|
@ -20,6 +20,7 @@ define [
|
|||
@ide.tabManager.addTab
|
||||
id: "history"
|
||||
name: "History"
|
||||
show: "code"
|
||||
after: "code"
|
||||
contract: true
|
||||
onShown: () => @show()
|
||||
|
@ -56,11 +57,8 @@ define [
|
|||
@changeListView.on "change_diff", (fromIndex, toIndex) =>
|
||||
@selectDocAndUpdateDiff(fromIndex, toIndex)
|
||||
|
||||
@changeListView.on "restore", (change) =>
|
||||
@restore(change)
|
||||
|
||||
if @diffView?
|
||||
@diffView.destroy()
|
||||
@diffView.remove()
|
||||
|
||||
@ide.mainAreaManager.change "trackChanges"
|
||||
@ide.editor.disable()
|
||||
|
@ -72,7 +70,7 @@ define [
|
|||
@ide.fileViewManager.enable()
|
||||
@disable()
|
||||
@ide.fileTreeManager.openDoc(@doc_id)
|
||||
@ide.mainAreaManager.change "editor"
|
||||
@ide.tabManager.show "code"
|
||||
|
||||
autoSelectDiff: () ->
|
||||
if @changes.models.length == 0
|
||||
|
@ -113,33 +111,41 @@ define [
|
|||
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
|
||||
{from, to, start_ts, end_ts} = @_findDocVersionsRangeInSelection(@doc_id, fromIndex, toIndex)
|
||||
|
||||
@diff = new Diff({
|
||||
project_id: @project_id
|
||||
doc_id: @doc_id
|
||||
from: from
|
||||
to: to
|
||||
start_ts: start_ts
|
||||
end_ts: end_ts
|
||||
}, {
|
||||
ide: @ide
|
||||
})
|
||||
|
||||
if @diffView?
|
||||
@diffView.destroy()
|
||||
@diffView.remove()
|
||||
|
||||
if !@diff.get("doc")?
|
||||
console.log "This document has been deleted. What should we do?"
|
||||
return
|
||||
|
||||
@diffView = new DiffView(
|
||||
model: @diff
|
||||
el: @$el.find(".track-changes-diff")
|
||||
)
|
||||
|
||||
@diffView.on "restore", () =>
|
||||
@restoreDiff(@diff)
|
||||
|
||||
@diff.fetch()
|
||||
|
||||
@ide.fileTreeManager.selectEntity(@doc_id)
|
||||
|
||||
|
||||
_findDocVersionsRangeInSelection: (doc_id, fromIndex, toIndex) ->
|
||||
from = null
|
||||
to = null
|
||||
from = to = start_ts = end_ts = null
|
||||
|
||||
for change in @changes.models.slice(toIndex, fromIndex + 1)
|
||||
for doc in change.get("docs")
|
||||
|
@ -147,16 +153,20 @@ define [
|
|||
if from? and to?
|
||||
from = Math.min(from, doc.fromV)
|
||||
to = Math.max(to, doc.toV)
|
||||
start_ts = Math.min(start_ts, change.get("start_ts"))
|
||||
end_ts = Math.max(end_ts, change.get("end_ts"))
|
||||
else
|
||||
from = doc.fromV
|
||||
to = doc.toV
|
||||
start_ts = change.get("start_ts")
|
||||
end_ts = change.get("end_ts")
|
||||
break
|
||||
|
||||
return {from, to}
|
||||
return {from, to, start_ts, end_ts}
|
||||
|
||||
restore: (change) ->
|
||||
name = @ide.fileTreeManager.getNameOfEntityId(@doc_id)
|
||||
date = moment(change.get("start_ts")).format("Do MMM YYYY, h:mm:ss a")
|
||||
restoreDiff: (diff) ->
|
||||
name = diff.get("doc")?.get("name")
|
||||
date = moment(diff.get("start_ts")).format("Do MMM YYYY, h:mm:ss a")
|
||||
modal = new Modal({
|
||||
title: "Restore document"
|
||||
message: "Are you sure you want to restore <strong>#{name}</strong> to before the changes on #{date}?"
|
||||
|
@ -169,24 +179,12 @@ define [
|
|||
callback: ($button) =>
|
||||
$button.text("Restoring...")
|
||||
$button.prop("disabled", true)
|
||||
@doRestore change.get("version"), (error) =>
|
||||
diff.restore (error) =>
|
||||
modal.remove()
|
||||
@hide()
|
||||
}]
|
||||
})
|
||||
|
||||
doRestore: (version, callback = (error) ->) ->
|
||||
$.ajax {
|
||||
url: "/project/#{@project_id}/doc/#{@doc_id}/version/#{version}/restore"
|
||||
type: "POST"
|
||||
headers:
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
success: () ->
|
||||
callback()
|
||||
error: (error) ->
|
||||
callback(error)
|
||||
}
|
||||
|
||||
enable: () ->
|
||||
@enabled = true
|
||||
|
||||
|
|
|
@ -3,8 +3,15 @@ define [
|
|||
"libs/backbone"
|
||||
], (User) ->
|
||||
Diff = Backbone.Model.extend
|
||||
initialize: (attributes, options) ->
|
||||
@ide = options.ide
|
||||
@set "doc", @ide.fileTreeManager.getEntity(@get("doc_id"))
|
||||
|
||||
url: () ->
|
||||
"/project/#{@get("project_id")}/doc/#{@get("doc_id")}/diff?from=#{@get("from")}&to=#{@get("to")}"
|
||||
url = "/project/#{@get("project_id")}/doc/#{@get("doc_id")}/diff"
|
||||
if @get("from")? and @get("to")?
|
||||
url += "?from=#{@get("from")}&to=#{@get("to")}"
|
||||
return url
|
||||
|
||||
parse: (diff) ->
|
||||
for entry in diff.diff
|
||||
|
@ -14,3 +21,15 @@ define [
|
|||
else
|
||||
entry.meta.user = User.getAnonymousUser()
|
||||
return diff
|
||||
|
||||
restore: (callback = (error) ->) ->
|
||||
$.ajax {
|
||||
url: "/project/#{@get("project_id")}/doc/#{@get("doc_id")}/version/#{@get("from")}/restore"
|
||||
type: "POST"
|
||||
headers:
|
||||
"X-CSRF-Token": window.csrfToken
|
||||
success: () ->
|
||||
callback()
|
||||
error: (error) ->
|
||||
callback(error)
|
||||
}
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
padding: 0px 12px;
|
||||
height: 100%;
|
||||
.ace_editor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 30px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
@ -20,6 +19,30 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
.track-changes-diff-toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: -1px;
|
||||
height: 20px;
|
||||
padding: 5px 5px 5px 5px;
|
||||
margin: 0;
|
||||
background-color: #282828;
|
||||
color: white;
|
||||
border-right: 1px solid white;
|
||||
.number-of-changes, .restore {
|
||||
position: absolute;
|
||||
}
|
||||
.number-of-changes {
|
||||
left: 10px;
|
||||
bottom: 7px;
|
||||
}
|
||||
.restore {
|
||||
right: 10px;
|
||||
bottom: 5px;
|
||||
padding: 3px 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.track-changes-side-bar {
|
||||
|
@ -181,11 +204,10 @@
|
|||
li.selected-change-from {
|
||||
.change-selectors {
|
||||
.range {
|
||||
bottom: 37px;
|
||||
bottom: 10px;
|
||||
}
|
||||
.change-selector-from {
|
||||
opacity: 1;
|
||||
bottom: 32px;
|
||||
}
|
||||
}
|
||||
.restore {
|
||||
|
@ -230,12 +252,5 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
li.selected-change-from.hover-selected-from {
|
||||
.change-selectors {
|
||||
.range {
|
||||
bottom: 37px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue