Set up the versions modal to display changes between versions when you select two of them.

This commit is contained in:
Scott Erickson 2014-05-08 10:54:39 -07:00
parent ed222338e7
commit e9fc3df7c1
7 changed files with 97 additions and 7 deletions

View file

@ -712,3 +712,14 @@
files: "Files"
top_simulators: "Top Simulators"
source_document: "Source Document"
document: "Document" # note to diplomats: not a physical document, a document in MongoDB, ie a record in a database
delta:
added: "Added"
modified: "Modified"
deleted: "Deleted"
moved_index: "Moved Index"
text_diff: "Text Diff"
merge_conflict_with: "MERGE CONFLICT WITH"
no_changes: "No Changes"

View file

@ -162,6 +162,10 @@ class CocoModel extends Backbone.Model
getDelta: ->
differ = deltasLib.makeJSONDiffer()
differ.diff @_revertAttributes, @attributes
getDeltaWith: (otherModel) ->
differ = deltasLib.makeJSONDiffer()
differ.diff @attributes, otherModel.attributes
applyDelta: (delta) ->
newAttributes = $.extend(true, {}, @attributes)
@ -172,6 +176,10 @@ class CocoModel extends Backbone.Model
delta = @getDelta()
deltasLib.expandDelta(delta, @_revertAttributes, @schema())
getExpandedDeltaWith: (otherModel) ->
delta = @getDeltaWith(otherModel)
deltasLib.expandDelta(delta, @attributes, @schema())
watch: (doWatch=true) ->
$.ajax("#{@urlRoot}/#{@id}/watch", {type:'PUT', data:{on:doWatch}})
@watching = -> doWatch

View file

@ -31,8 +31,9 @@ module.exports = class SuperModel extends Backbone.Model
else
@registerModel(model)
console.debug 'Registering model', model.getURL()
return @addModelResource(model, name, fetchOptions, value).load()
res = @addModelResource(model, name, fetchOptions, value)
if not res.isLoaded then res.load()
return res
loadCollection: (collection, name, fetchOptions, value=1) ->
url = collection.getURL()
@ -52,7 +53,9 @@ module.exports = class SuperModel extends Backbone.Model
@listenToOnce collection, 'sync', (c) ->
console.debug 'Registering collection', url
@registerCollection c
return @addModelResource(collection, name, fetchOptions, value).load()
res = @addModelResource(collection, name, fetchOptions, value)
res.load() if not (res.isLoading or res.isLoaded)
return res
# replace or overwrite
shouldSaveBackups: (model) -> false

View file

@ -37,10 +37,12 @@ mixin deltaPanel(delta, conflict)
if delta.conflict && !conflict
.panel-body
strong MERGE CONFLICT WITH
strong(data-i18n="delta.merge_conflict_with") MERGE CONFLICT WITH
+deltaPanel(delta.conflict, true)
.panel-group(id='delta-accordion-'+(counter))
for delta in deltas
+deltaPanel(delta)
if !deltas.length
alert.alert-warning(data-i18n="delta.no_changes") No changes

View file

@ -10,15 +10,21 @@ block modal-body-content
if dataList
table.table.table-condensed
tr
th
th(data-i18n="general.name") Name
th(data-i18n="general.version") Version
th(data-i18n="general.commit_msg") Commit Message
for data in dataList
tr
td
input(type="checkbox", value=data._id).select
td
a(href="/editor/#{page}/#{data.slug || data._id}")
| #{data.name}
td #{data.version.major}.#{data.version.minor}
td #{data.commitMessage}
div.delta-container
div.delta-view
block modal-footer-content

View file

@ -9,19 +9,63 @@ TEXTDIFF_OPTIONS =
viewType: 1
module.exports = class DeltaView extends CocoView
###
Takes a CocoModel instance (model) and displays changes since the
last save (attributes vs _revertAttributes).
* If headModel is included, will look for and display conflicts with the changes in model.
* If comparisonModel is included, will show deltas between model and comparisonModel instead
of changes within model itself.
###
@deltaCounter: 0
className: "delta-view"
template: template
constructor: (options) ->
super(options)
@model = options.model
@headModel = options.headModel
@expandedDeltas = @model.getExpandedDelta()
@expandedDeltas = []
@skipPaths = options.skipPaths
for modelName in ['model', 'headModel', 'comparisonModel']
continue unless m = options[modelName]
@[modelName] = @supermodel.loadModel(m, 'document').model
@buildDeltas() if @supermodel.finished()
console.log 'done constructing'
onLoaded: ->
@buildDeltas()
super()
buildDeltas: ->
if @comparisonModel
@expandedDeltas = @model.getExpandedDeltaWith(@comparisonModel)
else
@expandedDeltas = @model.getExpandedDelta()
@filterExpandedDeltas()
if @headModel
@headDeltas = @headModel.getExpandedDelta()
@conflicts = deltasLib.getConflicts(@headDeltas, @expandedDeltas)
filterExpandedDeltas: ->
return unless @skipPaths
for path, i in @skipPaths
@skipPaths[i] = [path] if _.isString(path)
newDeltas = []
for delta in @expandedDeltas
skip = false
for skipPath in @skipPaths
if _.isEqual _.first(delta.dataPath, skipPath.length), skipPath
skip = true
break
newDeltas.push delta unless skip
@expandedDeltas = newDeltas
getRenderData: ->
c = super()
c.deltas = @expandedDeltas

View file

@ -1,6 +1,7 @@
ModalView = require 'views/kinds/ModalView'
template = require 'templates/modal/versions'
tableTemplate = require 'templates/kinds/table'
DeltaView = require 'views/editor/delta'
class VersionsViewCollection extends Backbone.Collection
url: ""
@ -20,6 +21,9 @@ module.exports = class VersionsModalView extends ModalView
id: ""
url: ""
page: ""
events:
'change input.select': 'onSelectionChanged'
constructor: (options, @ID, @model) ->
super options
@ -36,6 +40,18 @@ module.exports = class VersionsModalView extends ModalView
@startsLoading = false
@render()
onSelectionChanged: ->
rows = @$el.find 'input.select:checked'
deltaEl = @$el.find '.delta-view'
@deltaView?.destroy()
deltaEl.empty()
if rows.length isnt 2 then return
laterVersion = new @model(_id:$(rows[0]).val())
earlierVersion = new @model(_id:$(rows[1]).val())
@deltaView = new DeltaView({model:earlierVersion, comparisonModel:laterVersion, skipPaths:['_id','version', 'commitMessage', 'parent', 'created', 'slug', 'index']})
@insertSubView(@deltaView, deltaEl)
getRenderData: (context={}) ->
context = super(context)
context.page = @page