From 2a5c2020cac68e1b3f0e4a6a384d7f53230f1faf Mon Sep 17 00:00:00 2001 From: Ruben Vereecken Date: Mon, 9 Jun 2014 00:33:06 +0200 Subject: [PATCH] Added recalculation button to the achievement editor --- app/styles/editor/achievement/edit.sass | 12 +++++++ app/templates/editor/achievement/edit.jade | 18 +++++----- app/templates/modal/confirm.jade | 11 +++++++ app/templates/modal/modal_base.jade | 2 +- app/views/editor/achievement/edit.coffee | 33 +++++++++++++++++++ app/views/modal/confirm.coffee | 30 +++++++++++++++++ .../earned_achievement_handler.coffee | 20 +++++++---- 7 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 app/styles/editor/achievement/edit.sass create mode 100644 app/templates/modal/confirm.jade create mode 100644 app/views/modal/confirm.coffee diff --git a/app/styles/editor/achievement/edit.sass b/app/styles/editor/achievement/edit.sass new file mode 100644 index 000000000..7177978d3 --- /dev/null +++ b/app/styles/editor/achievement/edit.sass @@ -0,0 +1,12 @@ +#editor-achievement-edit-view + .treema-root + margin: 28px 0px 20px + + button + float: right + margin-top: 15px + margin-left: 10px + + textarea + width: 92% + height: 300px diff --git a/app/templates/editor/achievement/edit.jade b/app/templates/editor/achievement/edit.jade index 2cee658bc..42b59de17 100644 --- a/app/templates/editor/achievement/edit.jade +++ b/app/templates/editor/achievement/edit.jade @@ -11,19 +11,21 @@ block content li.active | #{achievement.attributes.name} - button(data-i18n="common.save", disabled=authorized === true ? undefined : "true").btn.btn-primary#save-button Save + button(data-i18n="", disabled=me.isAdmin() === true ? undefined : "true").btn.btn-primary#recalculate-button Recalculate + button(data-i18n="common.save", disabled=me.isAdmin() === true ? undefined : "true").btn.btn-primary#save-button Save - h3(data-i18n="achievement.edit_achievement_title") Edit Achievement - span - |: "#{achievement.attributes.name}" + h3(data-i18n="achievement.edit_achievement_title") Edit Achievement + span + |: "#{achievement.attributes.name}" - #achievement-treema + #achievement-treema - #achievement-view + #achievement-view - hr + hr + + div#error-view - div#error-view else .alert.alert-danger span Admin only. Turn around. diff --git a/app/templates/modal/confirm.jade b/app/templates/modal/confirm.jade new file mode 100644 index 000000000..f7d746de4 --- /dev/null +++ b/app/templates/modal/confirm.jade @@ -0,0 +1,11 @@ +extends /templates/modal/modal_base + +block modal-header-content + h3 #{confirmTitle} + +block modal-body-content + p #{confirmBody} + +block modal-footer-content + button.btn.btn-secondary#decline-button(type="button", data-dismiss="modal") #{confirmDecline} + button.btn.btn-primary#confirm-button(type="button", data-dismiss=closeOnConfirm === true ? "modal" : undefined) #{confirmConfirm} diff --git a/app/templates/modal/modal_base.jade b/app/templates/modal/modal_base.jade index e2c2d527f..c8374033e 100644 --- a/app/templates/modal/modal_base.jade +++ b/app/templates/modal/modal_base.jade @@ -24,4 +24,4 @@ block modal-footer .modal-footer block modal-footer-content - button.btn.btn-primary(type="button", data-dismiss="modal", aria-hidden="true", data-i18n="modal.okay") Okay \ No newline at end of file + button.btn.btn-primary(type="button", data-dismiss="modal", aria-hidden="true", data-i18n="modal.okay") Okay diff --git a/app/views/editor/achievement/edit.coffee b/app/views/editor/achievement/edit.coffee index 186eb206d..76988a586 100644 --- a/app/views/editor/achievement/edit.coffee +++ b/app/views/editor/achievement/edit.coffee @@ -1,6 +1,7 @@ View = require 'views/kinds/RootView' template = require 'templates/editor/achievement/edit' Achievement = require 'models/Achievement' +ConfirmModal = require 'views/modal/confirm' module.exports = class AchievementEditView extends View id: "editor-achievement-edit-view" @@ -9,6 +10,7 @@ module.exports = class AchievementEditView extends View events: 'click #save-button': 'saveAchievement' + 'click #recalculate-button': 'confirmRecalculation' subscriptions: 'save-new': 'saveAchievement' @@ -72,3 +74,34 @@ module.exports = class AchievementEditView extends View res.success => url = "/editor/achievement/#{@achievement.get('slug') or @achievement.id}" document.location.href = url + + confirmRecalculation: (e) -> + renderData = + 'confirmTitle': "Are you really sure?" + 'confirmBody': "This will trigger recalculation of the achievement for all users. Are you really sure you want to go down this path?" + 'confirmDecline': "Not really" + 'confirmConfirm': "Definitely" + + confirmModal = new ConfirmModal(renderData) + confirmModal.onConfirm @recalculateAchievement + @openModalView confirmModal + + recalculateAchievement: => + $.ajax + data: JSON.stringify(achievements: [@achievement.get('slug') or @achievement.get('_id')]) + success: (data, status, jqXHR) -> + noty + timeout: 5000 + text: 'Recalculation process started' + type: 'success' + layout: 'topCenter' + error: (jqXHR, status, error) -> + console.error jqXHR + noty + timeout: 5000 + text: "Starting recalculation process failed with error code #{jqXHR.status}" + type: 'error' + layout: 'topCenter' + url: '/admin/earned.achievement/recalculate' + type: 'POST' + contentType: 'application/json' diff --git a/app/views/modal/confirm.coffee b/app/views/modal/confirm.coffee new file mode 100644 index 000000000..18ded9ed6 --- /dev/null +++ b/app/views/modal/confirm.coffee @@ -0,0 +1,30 @@ +ModalView = require '../kinds/ModalView' +template = require 'templates/modal/confirm' + +module.exports = class ConfirmModal extends ModalView + id: "confirm-modal" + template: template + closeButton: true + closeOnConfirm: true + + events: + 'click #decline-button': 'doDecline' + 'click #confirm-button': 'doConfirm' + + constructor: (@renderData={}, options={}) -> + super(options) + + getRenderData: -> + context = super() + context.closeOnConfirm = @closeOnConfirm + _.extend context, @renderData + + setRenderData: (@renderData) -> + + onDecline: (@decline) -> + + onConfirm: (@confirm) -> + + doConfirm: -> @confirm() if @confirm + + doDecline: -> @decline() if @decline diff --git a/server/achievements/earned_achievement_handler.coffee b/server/achievements/earned_achievement_handler.coffee index 0fefc5842..24615054d 100644 --- a/server/achievements/earned_achievement_handler.coffee +++ b/server/achievements/earned_achievement_handler.coffee @@ -15,21 +15,22 @@ class EarnedAchievementHandler extends Handler req.method is 'GET' # or req.user.isAdmin() recalculate: (req, res) -> - onSuccess = (data) => @sendSuccess(res, data) - if 'achievements' of req.query # Support both slugs and IDs separated by commas - achievementSlugsOrIDs = req.query.achievements.split(',') + onSuccess = (data) => log.debug "Finished recalculating achievements" + if 'achievements' of req.body # Support both slugs and IDs separated by commas + achievementSlugsOrIDs = req.body.achievements EarnedAchievementHandler.recalculate achievementSlugsOrIDs, onSuccess else EarnedAchievementHandler.recalculate onSuccess - @sendSuccess res + @sendSuccess res, {} # Returns success: boolean - @recalculate: (callbackOrSlugsOrIDs, callback) -> + # TODO call onFinished + @recalculate: (callbackOrSlugsOrIDs, onFinished) -> if _.isArray callbackOrSlugsOrIDs achievementSlugs = (thing for thing in callbackOrSlugsOrIDs when not Handler.isID(thing)) achievementIDs = (thing for thing in callbackOrSlugsOrIDs when Handler.isID(thing)) else - callback = callbackOrSlugsOrIDs + onFinished = callbackOrSlugsOrIDs filter = {} filter.$or = [ @@ -37,12 +38,17 @@ class EarnedAchievementHandler extends Handler {slug: $in: achievementSlugs} ] if achievementSlugs? or achievementIDs? + # Fetch all relevant achievements Achievement.find filter, (err, achievements) -> - return false and log.error err if err? + return log.error err if err? + + # Fetch every single user User.find {}, (err, users) -> _.each users, (user) -> # Keep track of a user's already achieved in order to set the notified values correctly userID = user.get('_id').toHexString() + + # Fetch all of a user's earned achievements EarnedAchievement.find {user: userID}, (err, alreadyEarned) -> alreadyEarnedIDs = [] previousPoints = 0