<commit_before>/** The examiner management methods for StudentsManager.
 *
 * Note that this class depends on createRecordFromStoreRecord(),
 * onSelectNone() and loadFirstPage() from StudentsManager to be available. */
Ext.define('devilry.administrator.studentsmanager.StudentsManagerManageExaminers', {
    depends: [
        'devilry.administrator.studentsmanager.ManuallyCreateUsers'
    ],

    randomDistResultTpl: Ext.create('Ext.XTemplate',
        '<div class="section info">',
        '    <p>The selected examiners got the following number of groups:</p>',
        '    <ul>',
        '    <tpl for="result">',
        '       <li><strong>{examiner}</strong>: {groups.length}</li>',
        '    </tpl>',
        '    </ul>',
        '</div>'
    ),

    successSetExaminerTpl: Ext.create('Ext.XTemplate',
        'Examiners set successfully to: <tpl for="examiners">',
        '   {.}<tpl if="xindex &lt; xcount">, </tpl>',
        '</tpl>'
    ),

    errorSetExaminerTpl: Ext.create('Ext.XTemplate',
        'Failed to set examiners: <tpl for="examiners">',
        '   {.}<tpl if="xindex &lt; xcount">, </tpl>',
        '</tpl>. Error details: {errorDetails}'
    ),
    
    /**
     * @private
     */
    onRandomDistributeExaminers: function() {
        //this.down('studentsmanager_studentsgrid').selModel.selectAll();
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        var win = Ext.widget('window', {
            title: 'Select examiners',
            modal: true,
            width: 500,
            height: 400,
            maximizable: true,
            layout: 'fit',
            items: {
                xtype: 'setlistofusers',
                //usernames: ['donald', 'scrooge', 'daisy', 'clarabelle'],
                usernames: [],
                helptext: '<p>The username of a single examiner on each line. Example:</p>',
                listeners: {
                    scope: this,
                    saveClicked: function(setlistofusersobj, usernames) {
                        this.randomDistributeExaminersOnSelected(setlistofusersobj, usernames);
                    }
                },

                extraToolbarButtons: [{
                    xtype: 'button',
                    scale: 'large',
                    text: Ext.String.format('Import examiners registered in {0}', DevilrySettings.DEVILRY_SYNCSYSTEM),
                    listeners: {
                        scope: this,
                        click: this.onImportRelatedExaminers
                    }
                }]
            }
        });
        win.show();
    },

    /**
     * @private
     */
    randomDistributeExaminersOnSelected: function(setlistofusersobj, examiners) {
        setlistofusersobj.up('window').close();
        this.progressWindow.start('Change examiners');
        this._finishedSavingGroupCount = 0;

        this._randomDistributeTmp = {
            remainingExaminers: Ext.Array.clone(examiners),
            allExaminers: examiners,
            totExaminers: examiners.length,
            result: {}
        };
        Ext.each(examiners, function(examiner, index) {
            this._randomDistributeTmp.result[examiner] = [];
        }, this);

        this.down('studentsmanager_studentsgrid').performActionOnSelected({
            scope: this,
            callback: this.randomDistributeExaminers,
            extraArgs: []
        });
    },

    /**
     * @private
     */
    getRandomExaminer: function() {
        var numRemainingExaminers = this._randomDistributeTmp.remainingExaminers.length;
        var randomIndex = Math.floor(Math.random() * (numRemainingExaminers));
        return this._randomDistributeTmp.remainingExaminers[randomIndex];
    },

    /**
     * @private
     */
    removeExaminerIfEnoughStudents: function(examiner, totalSelectedGroups) {
        var totExaminers = this._randomDistributeTmp.totExaminers;
        var groupsPerExaminer = Math.ceil(totalSelectedGroups/totExaminers);
        if(this._randomDistributeTmp.result[examiner].length === groupsPerExaminer) {
            Ext.Array.remove(this._randomDistributeTmp.remainingExaminers, examiner);
        }
    },

    /**
     * @private
     */
    getRandomDistributeResults: function() {
        var resultArray = [];
        Ext.each(this._randomDistributeTmp.allExaminers, function(examiner, index) {
            resultArray.push({
                examiner: examiner,
                groups: this._randomDistributeTmp.result[examiner]
            });
        }, this);
        return this.randomDistResultTpl.apply({result: resultArray});
    },


    /**
     * @private
     */
    randomDistributeExaminers: function(record, index, totalSelectedGroups) {
        var msg = Ext.String.format('Random distributing examiner to group {0}/{1}', index, totalSelectedGroups);
        this.getEl().mask(msg);

        var editRecord = this.createRecordFromStoreRecord(record);
        var examiner = this.getRandomExaminer();
        this._randomDistributeTmp.result[examiner].push(editRecord);
        this.removeExaminerIfEnoughStudents(examiner, totalSelectedGroups);

        editRecord.data.fake_examiners = [examiner];
        editRecord.save({
            scope: this,
            callback: function(r, operation) {
                this.setExaminerRecordCallback(record, operation, [examiner], totalSelectedGroups);
                if(this._finishedSavingGroupCount == totalSelectedGroups) {
                    this.progressWindow.finish({
                        title: 'Result of random distribution of examiners',
                        html: this.getRandomDistributeResults()
                    });
                }
            }
        });
    },


    /**
     * @private
     */
    onSetExaminers: function(append) {
        //this.down('studentsmanager_studentsgrid').selModel.selectAll();
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        var helptext = '<p>The username of a single examiner on each line.' +
            (append? '': '<strong> Current examiners will be replaced</strong>.') +
            '</p><p>Example:</p>';
        var win = Ext.widget('window', {
            title: (append? 'Add examiners': 'Replace examiners') + ' - select examiners',
            modal: true,
            width: 500,<commit_msg>apps.administrator...StudentsManagerManageExaminers: Even random distribution.<commit_after>/** The examiner management methods for StudentsManager.
 *
 * Note that this class depends on createRecordFromStoreRecord(),
 * onSelectNone() and loadFirstPage() from StudentsManager to be available. */
Ext.define('devilry.administrator.studentsmanager.StudentsManagerManageExaminers', {
    depends: [
        'devilry.administrator.studentsmanager.ManuallyCreateUsers',
        'devilry.extjshelpers.EvenRandomSelection'
    ],

    randomDistResultTpl: Ext.create('Ext.XTemplate',
        '<div class="section info">',
        '    <p>The selected examiners got the following number of groups:</p>',
        '    <ul>',
        '    <tpl for="result">',
        '       <li><strong>{examiner}</strong>: {groups.length}</li>',
        '    </tpl>',
        '    </ul>',
        '</div>'
    ),

    successSetExaminerTpl: Ext.create('Ext.XTemplate',
        'Examiners set successfully to: <tpl for="examiners">',
        '   {.}<tpl if="xindex &lt; xcount">, </tpl>',
        '</tpl>'
    ),

    errorSetExaminerTpl: Ext.create('Ext.XTemplate',
        'Failed to set examiners: <tpl for="examiners">',
        '   {.}<tpl if="xindex &lt; xcount">, </tpl>',
        '</tpl>. Error details: {errorDetails}'
    ),
    
    /**
     * @private
     */
    onRandomDistributeExaminers: function() {
        this.down('studentsmanager_studentsgrid').selModel.selectAll();
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        var win = Ext.widget('window', {
            title: 'Select examiners',
            modal: true,
            width: 500,
            height: 400,
            maximizable: true,
            layout: 'fit',
            items: {
                xtype: 'setlistofusers',
                //usernames: ['donald', 'scrooge', 'daisy', 'clarabelle'],
                usernames: [],
                helptext: '<p>The username of a single examiner on each line. Example:</p>',
                listeners: {
                    scope: this,
                    saveClicked: function(setlistofusersobj, usernames) {
                        this.randomDistributeExaminersOnSelected(setlistofusersobj, usernames);
                    }
                },

                extraToolbarButtons: [{
                    xtype: 'button',
                    scale: 'large',
                    text: Ext.String.format('Import examiners registered in {0}', DevilrySettings.DEVILRY_SYNCSYSTEM),
                    listeners: {
                        scope: this,
                        click: this.onImportRelatedExaminers
                    }
                }]
            }
        });
        win.show();
    },

    /**
     * @private
     */
    randomDistributeExaminersOnSelected: function(setlistofusersobj, examiners) {
        setlistofusersobj.up('window').close();
        this.progressWindow.start('Change examiners');
        this._finishedSavingGroupCount = 0;

        var randomDistResult = [];
        Ext.each(examiners, function(examiner, index) {
            randomDistResult[examiner] = [];
        }, this);

        var randomExaminerPool = Ext.create('devilry.extjshelpers.EvenRandomSelection', {
            selection: examiners
        })

        this.down('studentsmanager_studentsgrid').performActionOnSelected({
            scope: this,
            callback: this.randomDistributeExaminers,
            extraArgs: [randomExaminerPool, randomDistResult]
        });
    },

    /**
     * @private
     */
    getRandomDistributeResults: function(allExaminers, randomDistResult) {
        var resultArray = [];
        Ext.each(allExaminers, function(examiner, index) {
            resultArray.push({
                examiner: examiner,
                groups: randomDistResult[examiner]
            });
        }, this);
        return this.randomDistResultTpl.apply({result: resultArray});
    },


    /**
     * @private
     */
    randomDistributeExaminers: function(record, index, totalSelectedGroups, randomExaminerPool, randomDistResult) {
        var msg = Ext.String.format('Random distributing examiner to group {0}/{1}', index, totalSelectedGroups);
        this.getEl().mask(msg);

        var editRecord = this.createRecordFromStoreRecord(record);
        var examiner = randomExaminerPool.getRandomItem();
        randomDistResult[examiner].push(editRecord);

        editRecord.data.fake_examiners = [examiner];
        editRecord.save({
            scope: this,
            callback: function(r, operation) {
                this.setExaminerRecordCallback(record, operation, [examiner], totalSelectedGroups);
                if(this._finishedSavingGroupCount == totalSelectedGroups) {
                    this.progressWindow.finish({
                        title: 'Result of random distribution of examiners',
                        html: this.getRandomDistributeResults(randomExaminerPool.selection, randomDistResult)
                    });
                }
            }
        });
    },


    /**
     * @private
     */
    onSetExaminers: function(append) {
        //this.down('studentsmanager_studentsgrid').selModel.selectAll();
        if(this.noneSelected()) {
            this.onSelectNone();
            return;
        }
        var helptext = '<p>The username of a single examiner on each line.' +
            (append? '': '<strong> Current examiners will be replaced</strong>.') +
            '</p><p>Example:</p>';
        var win = Ext.widget('window', {
            title: (append? 'Add examiners': 'Replace examiners') + ' - select examiners',
            modal: true,
            width: 500,
{'fraction_non_alphanumeric': 0.12157477715417629, 'fraction_numerical': 0.002145922746781116, 'mean_word_length': 1.9881627620221949, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '146434', 'n_tokens_mistral': 3376, 'n_tokens_neox': 3287, 'n_words': 596}