<commit_before>Ext.define('SlateAdmin.controller.progress.interims.Email', {
    extend: 'Ext.app.Controller',
    requires: [
        'Ext.window.MessageBox',

        /* global Slate:false */
        'Slate.API'
    ],


    views: [
        'progress.interims.email.Container'
    ],

    stores: [
        'Terms',
        '<EMAIL>',
        'progress.interims.Authors',
        'progress.interims.Emails'
    ],

    refs: {
        progressNavPanel: 'progress-navpanel',

        container: {
            selector: 'progress-interims-email-container',
            autoCreate: true,

            xtype: 'progress-interims-email-container'
        },
        optionsForm: 'progress-interims-email-container form#optionsForm',
        emailsGrid: 'progress-interims-email-grid',
        emailsTotalCmp: 'progress-interims-email-grid #emailsTotal',
        sendEmailsBtn: 'progress-interims-email-grid button[action=send-emails]',
        emailPreviewCmp: 'progress-interims-email-container #emailPreview'
    },

    routes: {
        'progress/interims/email': 'showContainer'
    },

    control: {
        'progress-interims-email-container button[action=load-emails]': {
            click: 'onLoadEmailsClick'
        },
        'progress-interims-email-container button[action=reset-options]': {
            click: 'onResetOptionsClick'
        },
        emailsGrid: {
            select: 'onEmailsGridSelect'
        },
        sendEmailsBtn: {
            click: 'onSendEmailsClick'
        }
    },

    listen: {
        store: {
            '#progress.interims.Emails': {
                load: 'onEmailsStoreLoad'
            }
        }
    },


    // route handlers
    showContainer: function () {
        var me = this,
            navPanel = me.getProgressNavPanel();

        Ext.suspendLayouts();

        Ext.util.History.suspendState();
        navPanel.setActiveLink('progress/interims/email');
        navPanel.expand();
        Ext.util.History.resumeState(false); // false to discard any changes to state

        me.application.getController('Viewport').loadCard(me.getContainer());

        Ext.resumeLayouts(true);
    },


    // event handlers
    onLoadEmailsClick: function() {
        var me = this,
            emailsStore = me.getProgressInterimsEmailsStore();

        me.resetPreview();

        emailsStore.load({
            params: me.getOptionsForm().getValues()
        });
    },

    onResetOptionsClick: function() {
        this.getOptionsForm().reset();
    },

    onEmailsStoreLoad: function(emailsStore) {
        var me = this,
            count = emailsStore.getCount();

        if (count) {
            me.getEmailsTotalCmp().setText(count + ' report email' + (count == 1 ? '' : 's') + ' ready');
            me.getSendEmailsBtn().enable();
        } else {
            me.resetEmails();
            me.resetPreview();
        }
    },

    onEmailsGridSelect: function(emailsGrid, emailRecord) {
        var me = this,
            emailPreviewCmp = me.getEmailPreviewCmp(),
            reportIds = emailRecord.get('reports');

        if (!reportIds.length) {
            me.resetPreview();
            return;
        }

        emailPreviewCmp.setLoading('Downloading reports&hellip;');
        emailPreviewCmp.iframeEl.dom.src = Slate.API.buildUrl('/progress/section-interim-reports/*email-preview?reports='+reportIds.join(','));
    },

    onSendEmailsClick: function(sendEmailsBtn) {
        var me = this,
            emailsStore = me.getProgressInterimsEmailsStore(),
            emailsCount = emailsStore.getCount(),
            i = 0, email,
            emails = [];

        sendEmailsBtn.disable();

        for (; i < emailsCount; i++) {
            email = emailsStore.getAt(0);

            emails.push({
                reports: email.get('reports'),<commit_msg>Fix sending same interim email multiple times<commit_after>Ext.define('SlateAdmin.controller.progress.interims.Email', {
    extend: 'Ext.app.Controller',
    requires: [
        'Ext.window.MessageBox',

        /* global Slate:false */
        'Slate.API'
    ],


    views: [
        'progress.interims.email.Container'
    ],

    stores: [
        'Terms',
        '<EMAIL>',
        'progress.interims.Authors',
        'progress.interims.Emails'
    ],

    refs: {
        progressNavPanel: 'progress-navpanel',

        container: {
            selector: 'progress-interims-email-container',
            autoCreate: true,

            xtype: 'progress-interims-email-container'
        },
        optionsForm: 'progress-interims-email-container form#optionsForm',
        emailsGrid: 'progress-interims-email-grid',
        emailsTotalCmp: 'progress-interims-email-grid #emailsTotal',
        sendEmailsBtn: 'progress-interims-email-grid button[action=send-emails]',
        emailPreviewCmp: 'progress-interims-email-container #emailPreview'
    },

    routes: {
        'progress/interims/email': 'showContainer'
    },

    control: {
        'progress-interims-email-container button[action=load-emails]': {
            click: 'onLoadEmailsClick'
        },
        'progress-interims-email-container button[action=reset-options]': {
            click: 'onResetOptionsClick'
        },
        emailsGrid: {
            select: 'onEmailsGridSelect'
        },
        sendEmailsBtn: {
            click: 'onSendEmailsClick'
        }
    },

    listen: {
        store: {
            '#progress.interims.Emails': {
                load: 'onEmailsStoreLoad'
            }
        }
    },


    // route handlers
    showContainer: function () {
        var me = this,
            navPanel = me.getProgressNavPanel();

        Ext.suspendLayouts();

        Ext.util.History.suspendState();
        navPanel.setActiveLink('progress/interims/email');
        navPanel.expand();
        Ext.util.History.resumeState(false); // false to discard any changes to state

        me.application.getController('Viewport').loadCard(me.getContainer());

        Ext.resumeLayouts(true);
    },


    // event handlers
    onLoadEmailsClick: function() {
        var me = this,
            emailsStore = me.getProgressInterimsEmailsStore();

        me.resetPreview();

        emailsStore.load({
            params: me.getOptionsForm().getValues()
        });
    },

    onResetOptionsClick: function() {
        this.getOptionsForm().reset();
    },

    onEmailsStoreLoad: function(emailsStore) {
        var me = this,
            count = emailsStore.getCount();

        if (count) {
            me.getEmailsTotalCmp().setText(count + ' report email' + (count == 1 ? '' : 's') + ' ready');
            me.getSendEmailsBtn().enable();
        } else {
            me.resetEmails();
            me.resetPreview();
        }
    },

    onEmailsGridSelect: function(emailsGrid, emailRecord) {
        var me = this,
            emailPreviewCmp = me.getEmailPreviewCmp(),
            reportIds = emailRecord.get('reports');

        if (!reportIds.length) {
            me.resetPreview();
            return;
        }

        emailPreviewCmp.setLoading('Downloading reports&hellip;');
        emailPreviewCmp.iframeEl.dom.src = Slate.API.buildUrl('/progress/section-interim-reports/*email-preview?reports='+reportIds.join(','));
    },

    onSendEmailsClick: function(sendEmailsBtn) {
        var me = this,
            emailsStore = me.getProgressInterimsEmailsStore(),
            emailsCount = emailsStore.getCount(),
            i = 0, email,
            emails = [];

        sendEmailsBtn.disable();

        for (; i < emailsCount; i++) {
            email = emailsStore.getAt(i);

            emails.push({
                reports: email.get('reports'),
{'fraction_non_alphanumeric': 0.12850467289719625, 'fraction_numerical': 0.0006490134994807892, 'mean_word_length': 2.0227540211847783, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2144407', 'n_tokens_mistral': 2234, 'n_tokens_neox': 2178, 'n_words': 329}