mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 01:25:42 -05:00
Added a delta subview for displaying deltas of schema'd data.
This commit is contained in:
parent
721648dadf
commit
f2d21b960f
6 changed files with 211 additions and 1 deletions
89
app/lib/deltas.coffee
Normal file
89
app/lib/deltas.coffee
Normal file
|
@ -0,0 +1,89 @@
|
|||
# path: an array of indexes to navigate into a JSON object
|
||||
# left:
|
||||
|
||||
module.exports.interpretDelta = (delta, path, left, schema) ->
|
||||
# takes a single delta and converts into an object that can be
|
||||
# easily formatted into something human readable.
|
||||
|
||||
betterDelta = { action:'???', delta: delta }
|
||||
|
||||
betterPath = []
|
||||
parentLeft = left
|
||||
parentSchema = schema
|
||||
for key in path
|
||||
# TODO: A smarter way of getting child schemas
|
||||
childSchema = parentSchema?.items or parentSchema?.properties?[key] or {}
|
||||
childLeft = parentLeft?[key]
|
||||
betterKey = null
|
||||
betterKey ?= childLeft.name or childLeft.id if childLeft
|
||||
betterKey ?= "#{childSchema.title} ##{key+1}" if childSchema.title and _.isNumber(key)
|
||||
betterKey ?= "#{childSchema.title}" if childSchema.title
|
||||
betterKey ?= _.string.titleize key
|
||||
betterPath.push betterKey
|
||||
parentLeft = childLeft
|
||||
parentSchema = childSchema
|
||||
|
||||
betterDelta.path = betterPath.join(' :: ')
|
||||
betterDelta.schema = childSchema
|
||||
betterDelta.left = childLeft
|
||||
betterDelta.right = jsondiffpatch.patch childLeft, delta
|
||||
|
||||
if _.isArray(delta) and delta.length is 1
|
||||
betterDelta.action = 'added'
|
||||
betterDelta.newValue = delta[0]
|
||||
|
||||
if _.isArray(delta) and delta.length is 2
|
||||
betterDelta.action = 'modified'
|
||||
betterDelta.oldValue = delta[0]
|
||||
betterDelta.newValue = delta[1]
|
||||
|
||||
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 0
|
||||
betterDelta.action = 'deleted'
|
||||
betterDelta.oldValue = delta[0]
|
||||
|
||||
if _.isPlainObject(delta) and delta._t is 'a'
|
||||
betterDelta.action = 'modified-array'
|
||||
|
||||
if _.isPlainObject(delta) and delta._t isnt 'a'
|
||||
betterDelta.action = 'modified-object'
|
||||
|
||||
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 3
|
||||
betterDelta.action = 'moved-index'
|
||||
betterDelta.destinationIndex = delta[1]
|
||||
|
||||
if _.isArray(delta) and delta.length is 3 and delta[1] is 0 and delta[2] is 2
|
||||
betterDelta.action = 'text-diff'
|
||||
betterDelta.unidiff = delta[0]
|
||||
left = betterDelta.left.trim().split('\n')
|
||||
right = betterDelta.right.trim().split('\n')
|
||||
shifted = popped = false
|
||||
while left.length > 5 and right.length > 5 and left[0] is right[0] and left[1] is right[1]
|
||||
left.shift()
|
||||
right.shift()
|
||||
shifted = true
|
||||
while left.length > 5 and right.length > 5 and left[left.length-1] is right[right.length-1] and left[left.length-2] is right[right.length-2]
|
||||
left.pop()
|
||||
right.pop()
|
||||
popped = true
|
||||
left.push('...') and right.push('...') if popped
|
||||
left.unshift('...') and right.unshift('...') if shifted
|
||||
betterDelta.trimmedLeft = left.join('\n')
|
||||
betterDelta.trimmedRight = right.join('\n')
|
||||
|
||||
|
||||
betterDelta
|
||||
|
||||
module.exports.flattenDelta = flattenDelta = (delta, path=null) ->
|
||||
# takes a single delta and returns an array of deltas
|
||||
|
||||
path ?= []
|
||||
|
||||
return [{path:path, delta:delta}] if _.isArray delta
|
||||
|
||||
results = []
|
||||
affectingArray = delta._t is 'a'
|
||||
for index, childDelta of delta
|
||||
continue if index is '_t'
|
||||
index = parseInt(index.replace('_', '')) if affectingArray
|
||||
results = results.concat flattenDelta(childDelta, path.concat([index]))
|
||||
results
|
|
@ -215,6 +215,11 @@ class CocoModel extends Backbone.Model
|
|||
return true if permission.access in ['owner', 'write']
|
||||
|
||||
return false
|
||||
|
||||
|
||||
getDelta: ->
|
||||
jsd = jsondiffpatch.create({
|
||||
objectHash: (obj) -> obj.name || obj.id || obj._id || JSON.stringify(_.keys(obj))
|
||||
})
|
||||
jsd.diff @_revertAttributes, @attributes
|
||||
|
||||
module.exports = CocoModel
|
||||
|
|
35
app/styles/editor/delta.sass
Normal file
35
app/styles/editor/delta.sass
Normal file
|
@ -0,0 +1,35 @@
|
|||
#delta-list-view
|
||||
width: 600px
|
||||
.panel-heading
|
||||
font-size: 13px
|
||||
padding: 4px
|
||||
.row
|
||||
padding: 5px 10px
|
||||
|
||||
.delta-added
|
||||
border-color: green
|
||||
strong
|
||||
color: green
|
||||
.panel-heading
|
||||
background-color: lighten(green, 70%)
|
||||
|
||||
.delta-modified
|
||||
border-color: darkgoldenrod
|
||||
strong
|
||||
color: darkgoldenrod
|
||||
.panel-heading
|
||||
background-color: lighten(darkgoldenrod, 40%)
|
||||
|
||||
.delta-text-diff
|
||||
border-color: blue
|
||||
strong
|
||||
color: blue
|
||||
.panel-heading
|
||||
background-color: lighten(blue, 45%)
|
||||
|
||||
.delta-deleted
|
||||
border-color: red
|
||||
strong
|
||||
color: red
|
||||
.panel-heading
|
||||
background-color: lighten(red, 42%)
|
35
app/templates/editor/delta.jade
Normal file
35
app/templates/editor/delta.jade
Normal file
|
@ -0,0 +1,35 @@
|
|||
- var i = 0
|
||||
.panel-group#accordion
|
||||
for delta in deltas
|
||||
.delta.panel.panel-default(class='delta-'+delta.action)
|
||||
.panel-heading
|
||||
if delta.action === 'added'
|
||||
strong(data-i18n="delta.added") Added
|
||||
if delta.action === 'modified'
|
||||
strong(data-i18n="delta.modified") Modified
|
||||
if delta.action === 'deleted'
|
||||
strong(data-i18n="delta.deleted") Deleted
|
||||
if delta.action === 'moved-index'
|
||||
strong(data-i18n="delta.modified_array") Moved Index
|
||||
if delta.action === 'text-diff'
|
||||
strong(data-i18n="delta.text_diff") Text Diff
|
||||
span
|
||||
a(data-toggle="collapse" data-parent="#accordion" href="#collapse-"+i)
|
||||
span= delta.path
|
||||
|
||||
.panel-collapse.collapse(id="collapse-"+i)
|
||||
.panel-body.row
|
||||
if delta.action === 'added'
|
||||
.new-value.col-md-12= delta.right
|
||||
if delta.action === 'modified'
|
||||
.old-value.col-md-6= delta.left
|
||||
.new-value.col-md-6= delta.right
|
||||
if delta.action === 'deleted'
|
||||
.col-md-12
|
||||
div.old-value= delta.left
|
||||
if delta.action === 'text-diff'
|
||||
.col-md-6
|
||||
pre= delta.trimmedLeft
|
||||
.col-md-6
|
||||
pre= delta.trimmedRight
|
||||
- i += 1
|
43
app/views/editor/delta.coffee
Normal file
43
app/views/editor/delta.coffee
Normal file
|
@ -0,0 +1,43 @@
|
|||
CocoView = require 'views/kinds/CocoView'
|
||||
template = require 'templates/editor/delta'
|
||||
deltaLib = require 'lib/deltas'
|
||||
|
||||
module.exports = class DeltaListView extends CocoView
|
||||
id: "delta-list-view"
|
||||
template: template
|
||||
|
||||
constructor: (options) ->
|
||||
super(options)
|
||||
@delta = options.delta
|
||||
@schema = options.schema or {}
|
||||
@left = options.left
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
deltas = deltaLib.flattenDelta @delta
|
||||
deltas = (deltaLib.interpretDelta(d.delta, d.path, @left, @schema) for d in deltas)
|
||||
c.deltas = deltas
|
||||
@processedDeltas = deltas
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
deltas = @$el.find('.delta')
|
||||
for delta, i in deltas
|
||||
deltaEl = $(delta)
|
||||
deltaData = @processedDeltas[i]
|
||||
console.log 'delta', deltaEl, deltaData
|
||||
if _.isObject(deltaData.left) and leftEl = deltaEl.find('.old-value')
|
||||
options =
|
||||
data: deltaData.left
|
||||
schema: deltaData.schema
|
||||
readOnly: true
|
||||
treema = TreemaNode.make(leftEl, options)
|
||||
treema.build()
|
||||
|
||||
if _.isObject(deltaData.right) and rightEl = deltaEl.find('.old-value')
|
||||
options =
|
||||
data: deltaData.right
|
||||
schema: deltaData.schema
|
||||
readOnly: true
|
||||
treema = TreemaNode.make(rightEl, options)
|
||||
treema.build()
|
|
@ -52,6 +52,9 @@
|
|||
},
|
||||
"underscore.string": {
|
||||
"main": "lib/underscore.string.js"
|
||||
},
|
||||
"jsondiffpatch": {
|
||||
"main": ["build/bundle-full.js", "build/formatters.js", "src/formatters/html.css"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue