{"version":3,"file":"grading_panel.min.js","sources":["../src/grading_panel.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript controller for the \"Grading\" panel at the right of the page.\n *\n * @module     mod_assign/grading_panel\n * @package    mod_assign\n * @class      GradingPanel\n * @copyright  2016 Damyon Wiese <damyon@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since      3.1\n */\ndefine(['jquery', 'core/yui', 'core/notification', 'core/templates', 'core/fragment',\n        'core/ajax', 'core/str', 'mod_assign/grading_form_change_checker',\n        'mod_assign/grading_events', 'core/event'],\n       function($, Y, notification, templates, fragment, ajax, str, checker, GradingEvents, Event) {\n\n    /**\n     * GradingPanel class.\n     *\n     * @class GradingPanel\n     * @param {String} selector The selector for the page region containing the user navigation.\n     */\n    var GradingPanel = function(selector) {\n        this._regionSelector = selector;\n        this._region = $(selector);\n        this._userCache = [];\n\n        this.registerEventListeners();\n    };\n\n    /** @type {String} Selector for the page region containing the user navigation. */\n    GradingPanel.prototype._regionSelector = null;\n\n    /** @type {Integer} Remember the last user id to prevent unnessecary reloads. */\n    GradingPanel.prototype._lastUserId = 0;\n\n    /** @type {Integer} Remember the last attempt number to prevent unnessecary reloads. */\n    GradingPanel.prototype._lastAttemptNumber = -1;\n\n    /** @type {JQuery} JQuery node for the page region containing the user navigation. */\n    GradingPanel.prototype._region = null;\n\n     /** @type {Integer} The id of the next user in the grading list */\n    GradingPanel.prototype.nextUserId = null;\n\n     /** @type {Boolean} Next user exists in the grading list */\n    GradingPanel.prototype.nextUser = false;\n\n    /**\n     * Fade the dom node out, update it, and fade it back.\n     *\n     * @private\n     * @method _niceReplaceNodeContents\n     * @param {JQuery} node\n     * @param {String} html\n     * @param {String} js\n     * @return {Deferred} promise resolved when the animations are complete.\n     */\n    GradingPanel.prototype._niceReplaceNodeContents = function(node, html, js) {\n        var promise = $.Deferred();\n\n        node.fadeOut(\"fast\", function() {\n            templates.replaceNodeContents(node, html, js);\n            node.fadeIn(\"fast\", function() {\n                promise.resolve();\n            });\n        });\n\n        return promise.promise();\n    };\n\n    /**\n     * Make sure all form fields have the latest saved state.\n     * @private\n     * @method _saveFormState\n     */\n    GradingPanel.prototype._saveFormState = function() {\n        // Copy data from notify students checkbox which was moved out of the form.\n        var checked = $('[data-region=\"grading-actions-form\"] [name=\"sendstudentnotifications\"]').prop(\"checked\");\n        $('.gradeform [name=\"sendstudentnotifications\"]').val(checked);\n    };\n\n    /**\n     * Make form submit via ajax.\n     *\n     * @private\n     * @param {Object} event\n     * @param {Integer} nextUserId\n     * @param {Boolean} nextUser optional. Load next user in the grading list.\n     * @method _submitForm\n     */\n    GradingPanel.prototype._submitForm = function(event, nextUserId, nextUser) {\n        // The form was submitted - send it via ajax instead.\n        var form = $(this._region.find('form.gradeform'));\n\n        $('[data-region=\"overlay\"]').show();\n\n        // We call this, so other modules can update the form with the latest state.\n        form.trigger('save-form-state');\n\n        // Tell all form fields we are about to submit the form.\n        Event.notifyFormSubmitAjax(form[0]);\n\n        // Now we get all the current values from the form.\n        var data = form.serialize();\n        var assignmentid = this._region.attr('data-assignmentid');\n\n        // Now we can continue...\n        ajax.call([{\n            methodname: 'mod_assign_submit_grading_form',\n            args: {assignmentid: assignmentid, userid: this._lastUserId, jsonformdata: JSON.stringify(data)},\n            done: this._handleFormSubmissionResponse.bind(this, data, nextUserId, nextUser),\n            fail: notification.exception\n        }]);\n    };\n\n    /**\n     * Handle form submission response.\n     *\n     * @private\n     * @method _handleFormSubmissionResponse\n     * @param {Array} formdata - submitted values\n     * @param {Integer} nextUserId - optional. The id of the user to load after the form is saved.\n     * @param {Array} response List of errors.\n     * @param {Boolean} nextUser - optional. If true, switch to next user in the grading list.\n     */\n    GradingPanel.prototype._handleFormSubmissionResponse = function(formdata, nextUserId, nextUser, response) {\n        if (typeof nextUserId === \"undefined\") {\n            nextUserId = this._lastUserId;\n        }\n        if (response.length) {\n            // There was an error saving the grade. Re-render the form using the submitted data so we can show\n            // validation errors.\n            $(document).trigger('reset', [this._lastUserId, formdata]);\n        } else {\n            str.get_strings([\n                {key: 'changessaved', component: 'core'},\n                {key: 'gradechangessaveddetail', component: 'mod_assign'},\n            ]).done(function(strs) {\n                notification.alert(strs[0], strs[1]);\n            }).fail(notification.exception);\n            Y.use('moodle-core-formchangechecker', function() {\n                M.core_formchangechecker.reset_form_dirty_state();\n            });\n            if (nextUserId == this._lastUserId) {\n                $(document).trigger('reset', nextUserId);\n            } else if (nextUser) {\n                $(document).trigger('done-saving-show-next', true);\n            } else {\n                $(document).trigger('user-changed', nextUserId);\n            }\n        }\n        $('[data-region=\"overlay\"]').hide();\n    };\n\n    /**\n     * Refresh form with default values.\n     *\n     * @private\n     * @method _resetForm\n     * @param {Event} e\n     * @param {Integer} userid\n     * @param {Array} formdata\n     */\n    GradingPanel.prototype._resetForm = function(e, userid, formdata) {\n        // The form was cancelled - refresh with default values.\n        var event = $.Event(\"custom\");\n        if (typeof userid == \"undefined\") {\n            userid = this._lastUserId;\n        }\n        this._lastUserId = 0;\n        this._refreshGradingPanel(event, userid, formdata);\n    };\n\n    /**\n     * Open a picker to choose an older attempt.\n     *\n     * @private\n     * @param {Object} e\n     * @method _chooseAttempt\n     */\n    GradingPanel.prototype._chooseAttempt = function(e) {\n        // Show a dialog.\n\n        // The form is in the element pointed to by data-submissions.\n        var link = $(e.target);\n        var submissionsId = link.data('submissions');\n        var submissionsform = $(document.getElementById(submissionsId));\n        var formcopy = submissionsform.clone();\n        var formhtml = formcopy.wrap($('<form/>')).html();\n\n        str.get_strings([\n            {key: 'viewadifferentattempt', component: 'mod_assign'},\n            {key: 'view', component: 'core'},\n            {key: 'cancel', component: 'core'},\n        ]).done(function(strs) {\n            notification.confirm(strs[0], formhtml, strs[1], strs[2], function() {\n                var attemptnumber = $(\"input:radio[name='select-attemptnumber']:checked\").val();\n\n                this._refreshGradingPanel(null, this._lastUserId, '', attemptnumber);\n            }.bind(this));\n        }.bind(this)).fail(notification.exception);\n    };\n\n    /**\n     * Add popout buttons\n     *\n     * @private\n     * @method _addPopoutButtons\n     * @param {JQuery} selector The region selector to add popout buttons to.\n     */\n    GradingPanel.prototype._addPopoutButtons = function(selector) {\n        var region = $(selector);\n\n        templates.render('mod_assign/popout_button', {}).done(function(html) {\n            var parents = region.find('[data-fieldtype=\"filemanager\"],[data-fieldtype=\"editor\"],[data-fieldtype=\"grading\"]')\n                    .closest('.fitem');\n            parents.addClass('has-popout').find('label').parent().append(html);\n\n            region.on('click', '[data-region=\"popout-button\"]', this._togglePopout.bind(this));\n        }.bind(this)).fail(notification.exception);\n    };\n\n    /**\n     * Make a div \"popout\" or \"popback\".\n     *\n     * @private\n     * @method _togglePopout\n     * @param {Event} event\n     */\n    GradingPanel.prototype._togglePopout = function(event) {\n        event.preventDefault();\n        var container = $(event.target).closest('.fitem');\n        if (container.hasClass('popout')) {\n            $('.popout').removeClass('popout');\n        } else {\n            $('.popout').removeClass('popout');\n            container.addClass('popout');\n            container.addClass('moodle-has-zindex');\n        }\n    };\n\n    /**\n     * Get the user context - re-render the template in the page.\n     *\n     * @private\n     * @method _refreshGradingPanel\n     * @param {Event} event\n     * @param {Number} userid\n     * @param {String} submissiondata serialised submission data.\n     * @param {Integer} attemptnumber\n     */\n    GradingPanel.prototype._refreshGradingPanel = function(event, userid, submissiondata, attemptnumber) {\n        var contextid = this._region.attr('data-contextid');\n        if (typeof submissiondata === 'undefined') {\n            submissiondata = '';\n        }\n        if (typeof attemptnumber === 'undefined') {\n            attemptnumber = -1;\n        }\n        // Skip reloading if it is the same user.\n        if (this._lastUserId == userid && this._lastAttemptNumber == attemptnumber && submissiondata === '') {\n            return;\n        }\n        this._lastUserId = userid;\n        this._lastAttemptNumber = attemptnumber;\n        $(document).trigger('start-loading-user');\n        // Tell behat to back off too.\n        window.M.util.js_pending('mod-assign-loading-user');\n        // First insert the loading template.\n        templates.render('mod_assign/loading', {}).done(function(html, js) {\n            // Update the page.\n            this._niceReplaceNodeContents(this._region, html, js).done(function() {\n                if (userid > 0) {\n                    this._region.show();\n                    // Reload the grading form \"fragment\" for this user.\n                    var params = {userid: userid, attemptnumber: attemptnumber, jsonformdata: JSON.stringify(submissiondata)};\n                    fragment.loadFragment('mod_assign', 'gradingpanel', contextid, params).done(function(html, js) {\n                        this._niceReplaceNodeContents(this._region, html, js)\n                        .done(function() {\n                            checker.saveFormState('[data-region=\"grade-panel\"] .gradeform');\n                            $(document).on('editor-content-restored', function() {\n                                // If the editor has some content that has been restored\n                                // then save the form state again for comparison.\n                                checker.saveFormState('[data-region=\"grade-panel\"] .gradeform');\n                            });\n                            $('[data-region=\"attempt-chooser\"]').on('click', this._chooseAttempt.bind(this));\n                            this._addPopoutButtons('[data-region=\"grade-panel\"] .gradeform');\n                            $(document).trigger('finish-loading-user');\n                            // Tell behat we are friends again.\n                            window.M.util.js_complete('mod-assign-loading-user');\n                        }.bind(this))\n                        .fail(notification.exception);\n                    }.bind(this)).fail(notification.exception);\n                    $('[data-region=\"review-panel\"]').show();\n                } else {\n                    this._region.hide();\n                    $('[data-region=\"review-panel\"]').hide();\n                    $(document).trigger('finish-loading-user');\n                    // Tell behat we are friends again.\n                    window.M.util.js_complete('mod-assign-loading-user');\n                }\n            }.bind(this));\n        }.bind(this)).fail(notification.exception);\n    };\n\n    /**\n     * Get next user data and store it in global variables\n     *\n     * @private\n     * @method _getNextUser\n     * @param {Event} event\n     * @param {Object} data Next user's data\n     */\n    GradingPanel.prototype._getNextUser = function(event, data) {\n        this.nextUserId = data.nextUserId;\n        this.nextUser = data.nextUser;\n    };\n\n    /**\n     * Handle the save-and-show-next event\n     *\n     * @private\n     * @method _handleSaveAndShowNext\n     */\n    GradingPanel.prototype._handleSaveAndShowNext = function() {\n        this._submitForm(null, this.nextUserId, this.nextUser);\n    };\n\n    /**\n     * Get the grade panel element.\n     *\n     * @method getPanelElement\n     * @return {jQuery}\n     */\n    GradingPanel.prototype.getPanelElement = function() {\n        return $('[data-region=\"grade-panel\"]');\n    };\n\n    /**\n     * Hide the grade panel.\n     *\n     * @method collapsePanel\n     */\n    GradingPanel.prototype.collapsePanel = function() {\n        this.getPanelElement().addClass('collapsed');\n    };\n\n    /**\n     * Show the grade panel.\n     *\n     * @method expandPanel\n     */\n    GradingPanel.prototype.expandPanel = function() {\n        this.getPanelElement().removeClass('collapsed');\n    };\n\n    /**\n     * Register event listeners for the grade panel.\n     *\n     * @method registerEventListeners\n     */\n    GradingPanel.prototype.registerEventListeners = function() {\n        var docElement = $(document);\n        var region = $(this._region);\n        // Add an event listener to prevent form submission when pressing enter key.\n        region.on('submit', 'form', function(e) {\n            e.preventDefault();\n        });\n\n        docElement.on('next-user', this._getNextUser.bind(this));\n        docElement.on('user-changed', this._refreshGradingPanel.bind(this));\n        docElement.on('save-changes', this._submitForm.bind(this));\n        docElement.on('save-and-show-next', this._handleSaveAndShowNext.bind(this));\n        docElement.on('reset', this._resetForm.bind(this));\n\n        docElement.on('save-form-state', this._saveFormState.bind(this));\n\n        docElement.on(GradingEvents.COLLAPSE_GRADE_PANEL, function() {\n            this.collapsePanel();\n        }.bind(this));\n\n        // We should expand if the review panel is collapsed.\n        docElement.on(GradingEvents.COLLAPSE_REVIEW_PANEL, function() {\n            this.expandPanel();\n        }.bind(this));\n\n        docElement.on(GradingEvents.EXPAND_GRADE_PANEL, function() {\n            this.expandPanel();\n        }.bind(this));\n    };\n\n    return GradingPanel;\n});\n"],"names":["define","$","Y","notification","templates","fragment","ajax","str","checker","GradingEvents","Event","GradingPanel","selector","_regionSelector","_region","_userCache","registerEventListeners","prototype","_lastUserId","_lastAttemptNumber","nextUserId","nextUser","_niceReplaceNodeContents","node","html","js","promise","Deferred","fadeOut","replaceNodeContents","fadeIn","resolve","_saveFormState","checked","prop","val","_submitForm","event","form","this","find","show","trigger","notifyFormSubmitAjax","data","serialize","assignmentid","attr","call","methodname","args","userid","jsonformdata","JSON","stringify","done","_handleFormSubmissionResponse","bind","fail","exception","formdata","response","length","document","get_strings","key","component","strs","alert","use","M","core_formchangechecker","reset_form_dirty_state","hide","_resetForm","e","_refreshGradingPanel","_chooseAttempt","submissionsId","target","formhtml","getElementById","clone","wrap","confirm","attemptnumber","_addPopoutButtons","region","render","closest","addClass","parent","append","on","_togglePopout","preventDefault","container","hasClass","removeClass","submissiondata","contextid","window","util","js_pending","params","loadFragment","saveFormState","js_complete","_getNextUser","_handleSaveAndShowNext","getPanelElement","collapsePanel","expandPanel","docElement","COLLAPSE_GRADE_PANEL","COLLAPSE_REVIEW_PANEL","EXPAND_GRADE_PANEL"],"mappings":"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"}