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

This commit is contained in:
Henry Oswald 2014-03-21 17:49:25 +00:00
commit af659e7690
8 changed files with 115 additions and 62 deletions

View file

@ -22,7 +22,7 @@
script(type="text/template")#tabTemplate script(type="text/template")#tabTemplate
li(id="{{ id }}-tab-li") 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 }} .content {{ name }}
script(type="text/template")#tabContentTemplate script(type="text/template")#tabContentTemplate
@ -436,6 +436,12 @@
.change-list-area .change-list-area
.track-changes-diff .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 script(type='text/template')#changeListItemTemplate
div(class='change-selectors') div(class='change-selectors')
div.range div.range
@ -447,9 +453,6 @@
div.change-date {{date}} div.change-date {{date}}
div {{{users}}} div {{{users}}}
div(class='restore')
a(href="#") Restore to here
script(type='text/template')#changeListItemUserTemplate script(type='text/template')#changeListItemUserTemplate
div(class='change-name') div(class='change-name')
div.color-square(style="background-color: hsl({{hue}}, 100%, 70%);") div.color-square(style="background-color: hsl({{hue}}, 100%, 70%);")

View file

@ -97,7 +97,7 @@ define [
@views[@selected_entity_id].deselect() @views[@selected_entity_id].deselect()
@selected_entity_id = entity_id @selected_entity_id = entity_id
@ide.sideBarView.deselectAll() @ide.sideBarView.deselectAll()
@views[entity_id].select() @views[entity_id]?.select()
getEntity: (entity_id) -> getEntity: (entity_id) ->
@views[entity_id]?.model @views[entity_id]?.model

View file

@ -17,8 +17,9 @@ define [
addTab: (options) -> addTab: (options) ->
@tabs.push options @tabs.push options
options.show ||= options.id
tabEl = $(Mustache.to_html @templates.tab, options) tabEl = $(Mustache.to_html @templates.tab, options)
tabEl.find("a").attr("href", "#" + options.id) tabEl.find("a").attr("href", "#" + options.show)
if options.content? if options.content?
contentEl = $(Mustache.to_html @templates.content, options) contentEl = $(Mustache.to_html @templates.content, options)
@ -53,6 +54,8 @@ define [
if options.contract if options.contract
@contract() @contract()
show: (tab) ->
$("##{tab}-tab-li > a").tab("show")
lockOpen: () -> lockOpen: () ->
@locked_open = true @locked_open = true

View file

@ -75,9 +75,6 @@ define [
delete @hoverFromIndex delete @hoverFromIndex
@resetHoverStates() @resetHoverStates()
view.on "click:restore", (e) =>
@trigger "restore", view.model
view.resetSelector(index, @selectedFromIndex, @selectedToIndex) view.resetSelector(index, @selectedFromIndex, @selectedToIndex)
setSelectionRange: (fromIndex, toIndex) -> setSelectionRange: (fromIndex, toIndex) ->
@ -173,8 +170,6 @@ define [
@trigger "mouseenter:from", args... @trigger "mouseenter:from", args...
"mouseleave .change-selector-from": (args...) -> "mouseleave .change-selector-from": (args...) ->
@trigger "mouseleave:from", args... @trigger "mouseleave:from", args...
"click .restore a": "onRestoreClick"
templates: templates:
item: $("#changeListItemTemplate").html() item: $("#changeListItemTemplate").html()
@ -214,10 +209,6 @@ define [
onFromSelectorClick: (e) -> onFromSelectorClick: (e) ->
@trigger "selected:from", e, @ @trigger "selected:from", e, @
onRestoreClick: (e) ->
e.preventDefault()
@trigger "click:restore", e, @
isSelectedFrom: () -> isSelectedFrom: () ->
@$(".change-selector-from").is(":checked") @$(".change-selector-from").is(":checked")

View file

@ -4,15 +4,33 @@ define [
"ace/range" "ace/range"
"moment" "moment"
"libs/backbone" "libs/backbone"
"libs/mustache"
], (Ace, LatexMode, Range, moment)-> ], (Ace, LatexMode, Range, moment)->
DiffView = Backbone.View.extend DiffView = Backbone.View.extend
template: $("#trackChangesDiffTemplate").html()
events:
"click .restore": () ->
console.log "click"
@trigger "restore"
initialize: () -> initialize: () ->
@model.on "change:diff", () => @render() @model.on "change:diff", () => @render()
@render()
render: -> render: ->
diff = @model.get("diff") diff = @model.get("diff")
return unless 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() @createAceEditor()
@aceEditor.setValue(@getPlainDiffContent()) @aceEditor.setValue(@getPlainDiffContent())
@aceEditor.clearSelection() @aceEditor.clearSelection()
@ -24,12 +42,12 @@ define [
@scrollToFirstChange() @scrollToFirstChange()
return @ return @
destroy: () -> remove: () ->
@$editor?.remove() @$editor?.remove()
@undelegateEvents()
createAceEditor: () -> createAceEditor: () ->
@$el.empty() @$editor = @$(".track-changes-diff-editor")
@$editor = $("<div/>")
@$el.append(@$editor) @$el.append(@$editor)
@aceEditor = Ace.edit(@$editor[0]) @aceEditor = Ace.edit(@$editor[0])
@aceEditor.setTheme("ace/theme/#{window.userSettings.theme}") @aceEditor.setTheme("ace/theme/#{window.userSettings.theme}")
@ -54,6 +72,12 @@ define [
content += entry.u or entry.i or entry.d or "" content += entry.u or entry.i or entry.d or ""
return content return content
getNumberOfChanges: () ->
changes = 0
for entry in @model.get("diff") or []
changes += 1 if entry.i? or entry.d?
return changes
insertMarkers: () -> insertMarkers: () ->
row = 0 row = 0
column = 0 column = 0

View file

@ -20,6 +20,7 @@ define [
@ide.tabManager.addTab @ide.tabManager.addTab
id: "history" id: "history"
name: "History" name: "History"
show: "code"
after: "code" after: "code"
contract: true contract: true
onShown: () => @show() onShown: () => @show()
@ -56,11 +57,8 @@ define [
@changeListView.on "change_diff", (fromIndex, toIndex) => @changeListView.on "change_diff", (fromIndex, toIndex) =>
@selectDocAndUpdateDiff(fromIndex, toIndex) @selectDocAndUpdateDiff(fromIndex, toIndex)
@changeListView.on "restore", (change) =>
@restore(change)
if @diffView? if @diffView?
@diffView.destroy() @diffView.remove()
@ide.mainAreaManager.change "trackChanges" @ide.mainAreaManager.change "trackChanges"
@ide.editor.disable() @ide.editor.disable()
@ -72,7 +70,7 @@ define [
@ide.fileViewManager.enable() @ide.fileViewManager.enable()
@disable() @disable()
@ide.fileTreeManager.openDoc(@doc_id) @ide.fileTreeManager.openDoc(@doc_id)
@ide.mainAreaManager.change "editor" @ide.tabManager.show "code"
autoSelectDiff: () -> autoSelectDiff: () ->
if @changes.models.length == 0 if @changes.models.length == 0
@ -113,33 +111,41 @@ define [
console.log "No selection - what should we do!?" console.log "No selection - what should we do!?"
return return
{from, to} = @_findDocVersionsRangeInSelection(@doc_id, fromIndex, toIndex) {from, to, start_ts, end_ts} = @_findDocVersionsRangeInSelection(@doc_id, fromIndex, toIndex)
if !from? or !to?
console.log "No diff, should probably just show latest version"
return
@diff = new Diff({ @diff = new Diff({
project_id: @project_id project_id: @project_id
doc_id: @doc_id doc_id: @doc_id
from: from from: from
to: to to: to
start_ts: start_ts
end_ts: end_ts
}, {
ide: @ide
}) })
if @diffView? 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( @diffView = new DiffView(
model: @diff model: @diff
el: @$el.find(".track-changes-diff") el: @$el.find(".track-changes-diff")
) )
@diffView.on "restore", () =>
@restoreDiff(@diff)
@diff.fetch() @diff.fetch()
@ide.fileTreeManager.selectEntity(@doc_id) @ide.fileTreeManager.selectEntity(@doc_id)
_findDocVersionsRangeInSelection: (doc_id, fromIndex, toIndex) -> _findDocVersionsRangeInSelection: (doc_id, fromIndex, toIndex) ->
from = null from = to = start_ts = end_ts = null
to = null
for change in @changes.models.slice(toIndex, fromIndex + 1) for change in @changes.models.slice(toIndex, fromIndex + 1)
for doc in change.get("docs") for doc in change.get("docs")
@ -147,16 +153,20 @@ define [
if from? and to? if from? and to?
from = Math.min(from, doc.fromV) from = Math.min(from, doc.fromV)
to = Math.max(to, doc.toV) 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 else
from = doc.fromV from = doc.fromV
to = doc.toV to = doc.toV
start_ts = change.get("start_ts")
end_ts = change.get("end_ts")
break break
return {from, to} return {from, to, start_ts, end_ts}
restore: (change) -> restoreDiff: (diff) ->
name = @ide.fileTreeManager.getNameOfEntityId(@doc_id) name = diff.get("doc")?.get("name")
date = moment(change.get("start_ts")).format("Do MMM YYYY, h:mm:ss a") date = moment(diff.get("start_ts")).format("Do MMM YYYY, h:mm:ss a")
modal = new Modal({ modal = new Modal({
title: "Restore document" title: "Restore document"
message: "Are you sure you want to restore <strong>#{name}</strong> to before the changes on #{date}?" message: "Are you sure you want to restore <strong>#{name}</strong> to before the changes on #{date}?"
@ -169,24 +179,12 @@ define [
callback: ($button) => callback: ($button) =>
$button.text("Restoring...") $button.text("Restoring...")
$button.prop("disabled", true) $button.prop("disabled", true)
@doRestore change.get("version"), (error) => diff.restore (error) =>
modal.remove() modal.remove()
@hide() @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: () -> enable: () ->
@enabled = true @enabled = true

View file

@ -3,8 +3,15 @@ define [
"libs/backbone" "libs/backbone"
], (User) -> ], (User) ->
Diff = Backbone.Model.extend Diff = Backbone.Model.extend
initialize: (attributes, options) ->
@ide = options.ide
@set "doc", @ide.fileTreeManager.getEntity(@get("doc_id"))
url: () -> 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) -> parse: (diff) ->
for entry in diff.diff for entry in diff.diff
@ -14,3 +21,15 @@ define [
else else
entry.meta.user = User.getAnonymousUser() entry.meta.user = User.getAnonymousUser()
return diff 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)
}

View file

@ -8,11 +8,10 @@
left: 0; left: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
padding: 0px 12px;
height: 100%; height: 100%;
.ace_editor { .ace_editor {
position: absolute; position: absolute;
top: 0; top: 30px;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
@ -20,6 +19,30 @@
display: none; 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 { .track-changes-side-bar {
@ -181,11 +204,10 @@
li.selected-change-from { li.selected-change-from {
.change-selectors { .change-selectors {
.range { .range {
bottom: 37px; bottom: 10px;
} }
.change-selector-from { .change-selector-from {
opacity: 1; opacity: 1;
bottom: 32px;
} }
} }
.restore { .restore {
@ -230,12 +252,5 @@
} }
} }
} }
li.selected-change-from.hover-selected-from {
.change-selectors {
.range {
bottom: 37px;
}
}
}
} }
} }