From c54fd5ab4be6e6ee17587df4953fe2065ba1d49b Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 29 Dec 2014 09:14:43 -0800 Subject: [PATCH] Moved editors from PUT to POST so that version saving behavior is preserved and admins can PUT without saving new versions. --- app/views/editor/ForkModal.coffee | 2 +- .../editor/article/ArticleEditView.coffee | 2 +- .../components/NewLevelComponentModal.coffee | 2 +- .../editor/level/modals/SaveLevelModal.coffee | 2 +- .../level/systems/NewLevelSystemModal.coffee | 2 +- app/views/editor/modal/NewModelModal.coffee | 2 +- .../editor/thang/ThangTypeEditView.coffee | 2 +- app/views/i18n/I18NEditModelView.coffee | 52 +++++++++---------- server/commons/Handler.coffee | 5 +- 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/app/views/editor/ForkModal.coffee b/app/views/editor/ForkModal.coffee index bc293c715..482f523b9 100644 --- a/app/views/editor/ForkModal.coffee +++ b/app/views/editor/ForkModal.coffee @@ -33,7 +33,7 @@ module.exports = class ForkModal extends ModalView if @model.schema().properties.permissions newModel.set 'permissions', [access: 'owner', target: me.id] newPathPrefix = "editor/#{@editorPath}/" - res = newModel.save() + res = newModel.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res res.error => @hideLoading() diff --git a/app/views/editor/article/ArticleEditView.coffee b/app/views/editor/article/ArticleEditView.coffee index 583df2891..4cfaf04e8 100644 --- a/app/views/editor/article/ArticleEditView.coffee +++ b/app/views/editor/article/ArticleEditView.coffee @@ -83,7 +83,7 @@ module.exports = class ArticleEditView extends RootView newArticle = if e.major then @article.cloneNewMajorVersion() else @article.cloneNewMinorVersion() 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 modal = @$el.find('#save-version-modal') @enableModalInProgress(modal) diff --git a/app/views/editor/level/components/NewLevelComponentModal.coffee b/app/views/editor/level/components/NewLevelComponentModal.coffee index 141a45843..85251d743 100644 --- a/app/views/editor/level/components/NewLevelComponentModal.coffee +++ b/app/views/editor/level/components/NewLevelComponentModal.coffee @@ -28,7 +28,7 @@ module.exports = class NewLevelComponentModal extends ModalView component.set 'name', 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 - res = component.save() + res = component.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res @showLoading() diff --git a/app/views/editor/level/modals/SaveLevelModal.coffee b/app/views/editor/level/modals/SaveLevelModal.coffee index 1786ad44d..d18e402d7 100644 --- a/app/views/editor/level/modals/SaveLevelModal.coffee +++ b/app/views/editor/level/modals/SaveLevelModal.coffee @@ -97,7 +97,7 @@ module.exports = class SaveLevelModal extends SaveVersionModal tuples = _.zip(modelsToSave, formsToSave) for [newModel, form] in tuples 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) => res.error => @hideLoading() diff --git a/app/views/editor/level/systems/NewLevelSystemModal.coffee b/app/views/editor/level/systems/NewLevelSystemModal.coffee index 13e6cac38..193a50c5d 100644 --- a/app/views/editor/level/systems/NewLevelSystemModal.coffee +++ b/app/views/editor/level/systems/NewLevelSystemModal.coffee @@ -22,7 +22,7 @@ module.exports = class NewLevelSystemModal extends ModalView system.set 'name', 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 - res = system.save() + res = system.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res @showLoading() diff --git a/app/views/editor/modal/NewModelModal.coffee b/app/views/editor/modal/NewModelModal.coffee index c336028a9..e0c98517b 100644 --- a/app/views/editor/modal/NewModelModal.coffee +++ b/app/views/editor/modal/NewModelModal.coffee @@ -36,7 +36,7 @@ module.exports = class NewModelModal extends ModalView onModelSubmitted: (e) -> e.preventDefault() model = @makeNewModel() - res = model.save() + res = model.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic if needed return unless res forms.clearFormAlerts @$el diff --git a/app/views/editor/thang/ThangTypeEditView.coffee b/app/views/editor/thang/ThangTypeEditView.coffee index ba8616b7f..c5b62b576 100644 --- a/app/views/editor/thang/ThangTypeEditView.coffee +++ b/app/views/editor/thang/ThangTypeEditView.coffee @@ -367,7 +367,7 @@ module.exports = class ThangTypeEditView extends RootView newThangType.set('commitMessage', e.commitMessage) 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 modal = $('#save-version-modal') @enableModalInProgress(modal) diff --git a/app/views/i18n/I18NEditModelView.coffee b/app/views/i18n/I18NEditModelView.coffee index a3fa8d14b..38c620357 100644 --- a/app/views/i18n/I18NEditModelView.coffee +++ b/app/views/i18n/I18NEditModelView.coffee @@ -10,7 +10,7 @@ require 'views/modal/RevertModal' module.exports = class I18NEditModelView extends RootView className: 'editor i18n-edit-model-view' template: template - + events: 'change .translation-input': 'onInputChanged' 'change #language-select': 'onLanguageSelectChanged' @@ -22,11 +22,11 @@ module.exports = class I18NEditModelView extends RootView @model = @supermodel.loadModel(@model, 'model').model @model.saveBackups = true @selectedLanguage = me.get('preferredLanguage', true) - + showLoading: ($el) -> $el ?= @$el.find('.outer-content') super($el) - + onLoaded: -> super() @model.markToRevert() unless @model.hasLocalChanges() @@ -36,14 +36,14 @@ module.exports = class I18NEditModelView extends RootView c.model = @model c.selectedLanguage = @selectedLanguage - + @translationList = [] if @supermodel.finished() then @buildTranslationList() else [] result.index = index for result, index in @translationList c.translationList = @translationList - + c - + afterRender: -> super() @@ -63,7 +63,7 @@ module.exports = class I18NEditModelView extends RootView toEditor.on 'change', @onEditorChange editors = editors.concat([englishEditor, toEditor]) ) - + for editor in editors session = editor.getSession() session.setTabSize 2 @@ -80,17 +80,17 @@ module.exports = class I18NEditModelView extends RootView @onTranslationChanged(rowInfo, value) wrapRow: (title, key, enValue, toValue, path, format) -> - @translationList.push { + @translationList.push { title: title, - key: key, - enValue: enValue, - toValue: toValue or '', + key: key, + enValue: enValue, + toValue: toValue or '', path: path format: format } buildTranslationList: -> [] # overwrite - + onInputChanged: (e) -> index = $(e.target).data('index') rowInfo = @translationList[index] @@ -98,10 +98,10 @@ module.exports = class I18NEditModelView extends RootView @onTranslationChanged(rowInfo, value) onTranslationChanged: (rowInfo, value) -> - + #- Navigate down to where the translation will live base = @model.attributes - + for seg in rowInfo.path base = base[seg] @@ -109,19 +109,19 @@ module.exports = class I18NEditModelView extends RootView base[@selectedLanguage] ?= {} base = base[@selectedLanguage] - + if rowInfo.key.length > 1 for seg in rowInfo.key[..-2] base[seg] ?= {} base = base[seg] - + #- Set the data in a non-kosher way - + base[rowInfo.key[rowInfo.key.length-1]] = value @model.saveBackup() - + #- Enable patch submit button - + @$el.find('#patch-submit').attr('disabled', null) onLanguageSelectChanged: (e) -> @@ -131,19 +131,19 @@ module.exports = class I18NEditModelView extends RootView me.set('preferredLanguage', @selectedLanguage) me.patch() @render() - + onSubmitPatch: (e) -> - + delta = @model.getDelta() flattened = deltasLib.flattenDelta(delta) save = _.all(flattened, (delta) -> return _.isArray(delta.o) and delta.o.length is 1 and 'i18n' in delta.dataPath ) - + if save modelToSave = @model.cloneNewMinorVersion() modelToSave.updateI18NCoverage() if modelToSave.get('i18nCoverage') - + else modelToSave = new Patch() modelToSave.set 'delta', @model.getDelta() @@ -154,13 +154,13 @@ module.exports = class I18NEditModelView extends RootView if @modelClass.schema.properties.commitMessage commitMessage = "Diplomat submission for lang #{@selectedLanguage}: #{flattened.length} change(s)." - modelToSave.set 'commitMessage', commitMessage - + modelToSave.set 'commitMessage', commitMessage + errors = modelToSave.validate() button = $(e.target) button.attr('disabled', 'disabled') 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 res.error => button.text('Error Submitting Changes') res.success => button.text('Submit Changes') diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 8b21a2bd4..ecb6ba893 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -34,7 +34,7 @@ module.exports = class Handler hasAccessToDocument: (req, document, method=null) -> 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) if @modelClass.schema.uses_coco_permissions @@ -335,8 +335,7 @@ module.exports = class Handler put: (req, res, id) -> # Client expects PATCH behavior for PUTs # 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() # New logic (from campaign editor) that breaks saving versioned documents, like in the level editor. + return @sendForbiddenError(res) if @modelClass.schema.uses_coco_versions and not req.user.isAdmin() # Campaign editor just saves over things. return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body) return @sendForbiddenError(res) unless @hasAccess(req) @getDocumentForIdOrSlug req.body._id or id, (err, document) =>