Moved editors from PUT to POST so that version saving behavior is preserved and admins can PUT without saving new versions.

This commit is contained in:
Nick Winter 2014-12-29 09:14:43 -08:00
parent d85bf8d59a
commit c54fd5ab4b
9 changed files with 35 additions and 36 deletions

View file

@ -33,7 +33,7 @@ module.exports = class ForkModal extends ModalView
if @model.schema().properties.permissions if @model.schema().properties.permissions
newModel.set 'permissions', [access: 'owner', target: me.id] newModel.set 'permissions', [access: 'owner', target: me.id]
newPathPrefix = "editor/#{@editorPath}/" newPathPrefix = "editor/#{@editorPath}/"
res = newModel.save() res = newModel.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic
return unless res return unless res
res.error => res.error =>
@hideLoading() @hideLoading()

View file

@ -83,7 +83,7 @@ module.exports = class ArticleEditView extends RootView
newArticle = if e.major then @article.cloneNewMajorVersion() else @article.cloneNewMinorVersion() newArticle = if e.major then @article.cloneNewMajorVersion() else @article.cloneNewMinorVersion()
newArticle.set('commitMessage', e.commitMessage) newArticle.set('commitMessage', e.commitMessage)
res = newArticle.save() res = newArticle.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic
return unless res return unless res
modal = @$el.find('#save-version-modal') modal = @$el.find('#save-version-modal')
@enableModalInProgress(modal) @enableModalInProgress(modal)

View file

@ -28,7 +28,7 @@ module.exports = class NewLevelComponentModal extends ModalView
component.set 'name', name component.set 'name', name
component.set 'code', component.get('code', true).replace(/AttacksSelf/g, name) component.set 'code', component.get('code', true).replace(/AttacksSelf/g, name)
component.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level component.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level
res = component.save() res = component.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic
return unless res return unless res
@showLoading() @showLoading()

View file

@ -97,7 +97,7 @@ module.exports = class SaveLevelModal extends SaveVersionModal
tuples = _.zip(modelsToSave, formsToSave) tuples = _.zip(modelsToSave, formsToSave)
for [newModel, form] in tuples for [newModel, form] in tuples
newModel.updateI18NCoverage() if newModel.get('i18nCoverage') newModel.updateI18NCoverage() if newModel.get('i18nCoverage')
res = newModel.save() res = newModel.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic
do (newModel, form) => do (newModel, form) =>
res.error => res.error =>
@hideLoading() @hideLoading()

View file

@ -22,7 +22,7 @@ module.exports = class NewLevelSystemModal extends ModalView
system.set 'name', name system.set 'name', name
system.set 'code', system.get('code').replace(/Jitter/g, name) system.set 'code', system.get('code').replace(/Jitter/g, name)
system.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level system.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level
res = system.save() res = system.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic
return unless res return unless res
@showLoading() @showLoading()

View file

@ -36,7 +36,7 @@ module.exports = class NewModelModal extends ModalView
onModelSubmitted: (e) -> onModelSubmitted: (e) ->
e.preventDefault() e.preventDefault()
model = @makeNewModel() model = @makeNewModel()
res = model.save() res = model.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic if needed
return unless res return unless res
forms.clearFormAlerts @$el forms.clearFormAlerts @$el

View file

@ -367,7 +367,7 @@ module.exports = class ThangTypeEditView extends RootView
newThangType.set('commitMessage', e.commitMessage) newThangType.set('commitMessage', e.commitMessage)
newThangType.updateI18NCoverage() if newThangType.get('i18nCoverage') newThangType.updateI18NCoverage() if newThangType.get('i18nCoverage')
res = newThangType.save() res = newThangType.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic
return unless res return unless res
modal = $('#save-version-modal') modal = $('#save-version-modal')
@enableModalInProgress(modal) @enableModalInProgress(modal)

View file

@ -10,7 +10,7 @@ require 'views/modal/RevertModal'
module.exports = class I18NEditModelView extends RootView module.exports = class I18NEditModelView extends RootView
className: 'editor i18n-edit-model-view' className: 'editor i18n-edit-model-view'
template: template template: template
events: events:
'change .translation-input': 'onInputChanged' 'change .translation-input': 'onInputChanged'
'change #language-select': 'onLanguageSelectChanged' 'change #language-select': 'onLanguageSelectChanged'
@ -22,11 +22,11 @@ module.exports = class I18NEditModelView extends RootView
@model = @supermodel.loadModel(@model, 'model').model @model = @supermodel.loadModel(@model, 'model').model
@model.saveBackups = true @model.saveBackups = true
@selectedLanguage = me.get('preferredLanguage', true) @selectedLanguage = me.get('preferredLanguage', true)
showLoading: ($el) -> showLoading: ($el) ->
$el ?= @$el.find('.outer-content') $el ?= @$el.find('.outer-content')
super($el) super($el)
onLoaded: -> onLoaded: ->
super() super()
@model.markToRevert() unless @model.hasLocalChanges() @model.markToRevert() unless @model.hasLocalChanges()
@ -36,14 +36,14 @@ module.exports = class I18NEditModelView extends RootView
c.model = @model c.model = @model
c.selectedLanguage = @selectedLanguage c.selectedLanguage = @selectedLanguage
@translationList = [] @translationList = []
if @supermodel.finished() then @buildTranslationList() else [] if @supermodel.finished() then @buildTranslationList() else []
result.index = index for result, index in @translationList result.index = index for result, index in @translationList
c.translationList = @translationList c.translationList = @translationList
c c
afterRender: -> afterRender: ->
super() super()
@ -63,7 +63,7 @@ module.exports = class I18NEditModelView extends RootView
toEditor.on 'change', @onEditorChange toEditor.on 'change', @onEditorChange
editors = editors.concat([englishEditor, toEditor]) editors = editors.concat([englishEditor, toEditor])
) )
for editor in editors for editor in editors
session = editor.getSession() session = editor.getSession()
session.setTabSize 2 session.setTabSize 2
@ -80,17 +80,17 @@ module.exports = class I18NEditModelView extends RootView
@onTranslationChanged(rowInfo, value) @onTranslationChanged(rowInfo, value)
wrapRow: (title, key, enValue, toValue, path, format) -> wrapRow: (title, key, enValue, toValue, path, format) ->
@translationList.push { @translationList.push {
title: title, title: title,
key: key, key: key,
enValue: enValue, enValue: enValue,
toValue: toValue or '', toValue: toValue or '',
path: path path: path
format: format format: format
} }
buildTranslationList: -> [] # overwrite buildTranslationList: -> [] # overwrite
onInputChanged: (e) -> onInputChanged: (e) ->
index = $(e.target).data('index') index = $(e.target).data('index')
rowInfo = @translationList[index] rowInfo = @translationList[index]
@ -98,10 +98,10 @@ module.exports = class I18NEditModelView extends RootView
@onTranslationChanged(rowInfo, value) @onTranslationChanged(rowInfo, value)
onTranslationChanged: (rowInfo, value) -> onTranslationChanged: (rowInfo, value) ->
#- Navigate down to where the translation will live #- Navigate down to where the translation will live
base = @model.attributes base = @model.attributes
for seg in rowInfo.path for seg in rowInfo.path
base = base[seg] base = base[seg]
@ -109,19 +109,19 @@ module.exports = class I18NEditModelView extends RootView
base[@selectedLanguage] ?= {} base[@selectedLanguage] ?= {}
base = base[@selectedLanguage] base = base[@selectedLanguage]
if rowInfo.key.length > 1 if rowInfo.key.length > 1
for seg in rowInfo.key[..-2] for seg in rowInfo.key[..-2]
base[seg] ?= {} base[seg] ?= {}
base = base[seg] base = base[seg]
#- Set the data in a non-kosher way #- Set the data in a non-kosher way
base[rowInfo.key[rowInfo.key.length-1]] = value base[rowInfo.key[rowInfo.key.length-1]] = value
@model.saveBackup() @model.saveBackup()
#- Enable patch submit button #- Enable patch submit button
@$el.find('#patch-submit').attr('disabled', null) @$el.find('#patch-submit').attr('disabled', null)
onLanguageSelectChanged: (e) -> onLanguageSelectChanged: (e) ->
@ -131,19 +131,19 @@ module.exports = class I18NEditModelView extends RootView
me.set('preferredLanguage', @selectedLanguage) me.set('preferredLanguage', @selectedLanguage)
me.patch() me.patch()
@render() @render()
onSubmitPatch: (e) -> onSubmitPatch: (e) ->
delta = @model.getDelta() delta = @model.getDelta()
flattened = deltasLib.flattenDelta(delta) flattened = deltasLib.flattenDelta(delta)
save = _.all(flattened, (delta) -> save = _.all(flattened, (delta) ->
return _.isArray(delta.o) and delta.o.length is 1 and 'i18n' in delta.dataPath return _.isArray(delta.o) and delta.o.length is 1 and 'i18n' in delta.dataPath
) )
if save if save
modelToSave = @model.cloneNewMinorVersion() modelToSave = @model.cloneNewMinorVersion()
modelToSave.updateI18NCoverage() if modelToSave.get('i18nCoverage') modelToSave.updateI18NCoverage() if modelToSave.get('i18nCoverage')
else else
modelToSave = new Patch() modelToSave = new Patch()
modelToSave.set 'delta', @model.getDelta() modelToSave.set 'delta', @model.getDelta()
@ -154,13 +154,13 @@ module.exports = class I18NEditModelView extends RootView
if @modelClass.schema.properties.commitMessage if @modelClass.schema.properties.commitMessage
commitMessage = "Diplomat submission for lang #{@selectedLanguage}: #{flattened.length} change(s)." commitMessage = "Diplomat submission for lang #{@selectedLanguage}: #{flattened.length} change(s)."
modelToSave.set 'commitMessage', commitMessage modelToSave.set 'commitMessage', commitMessage
errors = modelToSave.validate() errors = modelToSave.validate()
button = $(e.target) button = $(e.target)
button.attr('disabled', 'disabled') button.attr('disabled', 'disabled')
return button.text('Failed to Submit Changes') if errors return button.text('Failed to Submit Changes') if errors
res = modelToSave.save() res = modelToSave.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic
return button.text('Failed to Submit Changes') unless res return button.text('Failed to Submit Changes') unless res
res.error => button.text('Error Submitting Changes') res.error => button.text('Error Submitting Changes')
res.success => button.text('Submit Changes') res.success => button.text('Submit Changes')

View file

@ -34,7 +34,7 @@ module.exports = class Handler
hasAccessToDocument: (req, document, method=null) -> hasAccessToDocument: (req, document, method=null) ->
return true if req.user?.isAdmin() return true if req.user?.isAdmin()
if @modelClass.schema.uses_coco_translation_coverage and (method or req.method).toLowerCase() is 'put' if @modelClass.schema.uses_coco_translation_coverage and (method or req.method).toLowerCase() is 'post'
return true if @isJustFillingTranslations(req, document) return true if @isJustFillingTranslations(req, document)
if @modelClass.schema.uses_coco_permissions if @modelClass.schema.uses_coco_permissions
@ -335,8 +335,7 @@ module.exports = class Handler
put: (req, res, id) -> put: (req, res, id) ->
# Client expects PATCH behavior for PUTs # Client expects PATCH behavior for PUTs
# Real PATCHs return incorrect HTTP responses in some environments (e.g. Browserstack, schools) # Real PATCHs return incorrect HTTP responses in some environments (e.g. Browserstack, schools)
return @postNewVersion(req, res) if @modelClass.schema.uses_coco_versions # Old logic - https://github.com/codecombat/codecombat/commit/0bdec68cfc2997a1d03458e516ecedd7c7f389a9#diff-859d2856438fffa609001ae3b7b74c27R331 return @sendForbiddenError(res) if @modelClass.schema.uses_coco_versions and not req.user.isAdmin() # Campaign editor just saves over things.
#return @sendForbiddenError(res) if @modelClass.schema.uses_coco_versions and not req.user.isAdmin() # New logic (from campaign editor) that breaks saving versioned documents, like in the level editor.
return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body) return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body)
return @sendForbiddenError(res) unless @hasAccess(req) return @sendForbiddenError(res) unless @hasAccess(req)
@getDocumentForIdOrSlug req.body._id or id, (err, document) => @getDocumentForIdOrSlug req.body._id or id, (err, document) =>