<commit_before>var SGN;
if( ! SGN ) SGN = {};
if( ! SGN.Feature ) SGN.Feature = {};

SGN.Feature.Search = {

    set_up_feature_search: function( args ) {
        var maximum_export_size = args.maximum_export_size || 10000;

        Ext.Loader.setConfig({enabled: true});

        Ext.require([
            'Ext.grid.*',
            'Ext.data.*',
            'Ext.util.*',
            'Ext.grid.PagingScroller'
        ]);

        // make the feature grid
        Ext.onReady(function(){

            var page_size = 100;

            Ext.define('Feature', {
                extend: 'Ext.data.Model',
                fields: [
                    'feature_id',
                    'organism',
                    'name',
                    'type',
                    'seqlen',
                    'locations',
                    'description'
                ],
                idProperty: 'feature_id'
            });

            function get_search_query( store ) {
                // get the filtering data from the store
                var post_vars = Ext.clone( store.proxy.extraParams );

                // filter out any form fields that are empty or just whitespace
                for( var name in post_vars ) {
                    var value = post_vars[name];
                    if( value == null || typeof value == 'string' && ! value.match(/[^\s]/) ) {
                        delete post_vars[name];
                    }
                }

                // get the sort settings from the store
                var sorter = store.sorters.first();
                post_vars.sort = sorter.property;
                post_vars.dir = sorter.direction;

                return post_vars;
            }

            // create the Data Store
            var feature_store = Ext.create('Ext.data.Store', {
                id:           'feature_store',
                pageSize:     page_size,
                model:        'Feature',
                remoteSort:   true,
                autoLoad:     true,

                listeners: {
                        // enable or disable the export and save
                        // toolbar based on how many features matched
                        datachanged: function( store ) {
                            var toolbar = Ext.getCmp('feature_export_toolbar');
                            var label = Ext.getCmp('feature_export_toolbar_disabled_label');
                            if( store.getTotalCount() <= maximum_export_size ) {
                                // enable the export toolbar
                                toolbar.enable();
                                label.hide();
                            } else {
                                // disable the export toolbar
                                toolbar.disable();
                                label.show();
                            }
                        }
                },

                proxy: {
                    type: 'ajax',
                    url: '/search/features/search_service',
                    timeout: 60000,
                    reader: {
                        root: 'data',
                        totalProperty: 'totalCount',
                        successProperty: 'success'
                    },
                    // sends single sort as multi parameter
                    simpleSortMode: true
                },
                sorters: [{
                     property: 'feature_id',
                     direction: 'ASC'
                }]
            });

            function hyphen_if_empty( value ) {
                return value.length > 0 ? value : '-';
            }

            var feature_grid = Ext.create('Ext.grid.Panel', {
                width:    700,
                height:   400,
                //title:    'Matching Features',
                store:    feature_store,
                loadMask: true,

                dockedItems: [
                   {
                    xtype: 'toolbar',
                    dock: 'top',
                    id: 'feature_export_toolbar',
                    items: [
                        '->',
                        { xtype: 'label',
                          id: 'feature_export_toolbar_disabled_label',
                          text: 'Exporting limited to '+ Ext.util.Format.number( maximum_export_size, '0,000' )+' features.',
                          hidden: true
                        },
                        {
                            xtype: 'button',
                            text: 'Save as',
                            icon: '/img/icons/oxygen/16x16/media-floppy.png',
                            menu: {
                                items: [
                                    {
                                        text: 'CSV',
                                        icon: '/img/icons/oxygen/16x16/text-csv.png',
                                        handler: function() {
                                            var search_query_vars = get_search_query( feature_store );
                                            var csv_url = '/search/features/export_csv?' + Ext.Object.toQueryString( search_query_vars );
                                            location.href = csv_url;
                                        }
                                    }
                                ]
                            }
                        },{
                            xtype: 'button',
                            text: 'Send to',
                            icon: '/img/icons/oxygen/16x16/document-export.png',
                            menu: {
                                items: [
                                    {
                                        text: 'SGN bulk download',
                                        icon: '/img/icons/oxygen/16x16/document-export-table.png',
                                        handler: function() {
                                            var search_query = get_search_query( feature_store );
                                            search_query.fields = 'name';
                                            Ext.Ajax.request({
                                                url: '/search/features/search_service',
                                                method: 'GET',
                                                params: search_query,
                                                success: function(response) {
                                                    // make a bulk-download URL populated with these IDs
                                                    var features = Ext.JSON.decode( response.responseText ).data;
                                                    var names = [];
                                                    for( var i = 0; i < features.length; i++ ) {
                                                        names.push( features[i].name );
                                                    }
                                                    names = names.join("\n");

                                                    Ext.create( 'Ext.form.Panel', {
                                                      url: '/bulk/feature',
                                                      standardSubmit: true,
                                                      defaultType: 'textfield',
                                                      hidden: true,
                                                      items: [{ name: 'ids', value: names }]
                                                    }).submit();
                                                }
                                             });
                                        }
                                    }
                                ]<commit_msg>add bulk gene download to the feature search export menu<commit_after>var SGN;
if( ! SGN ) SGN = {};
if( ! SGN.Feature ) SGN.Feature = {};

SGN.Feature.Search = {

    set_up_feature_search: function( args ) {
        var maximum_export_size = args.maximum_export_size || 10000;

        Ext.Loader.setConfig({enabled: true});

        Ext.require([
            'Ext.grid.*',
            'Ext.data.*',
            'Ext.util.*',
            'Ext.grid.PagingScroller'
        ]);

        // make the feature grid
        Ext.onReady(function(){

            var page_size = 100;

            Ext.define('Feature', {
                extend: 'Ext.data.Model',
                fields: [
                    'feature_id',
                    'organism',
                    'name',
                    'type',
                    'seqlen',
                    'locations',
                    'description'
                ],
                idProperty: 'feature_id'
            });

            function get_search_query( store ) {
                // get the filtering data from the store
                var post_vars = Ext.clone( store.proxy.extraParams );

                // filter out any form fields that are empty or just whitespace
                for( var name in post_vars ) {
                    var value = post_vars[name];
                    if( value == null || typeof value == 'string' && ! value.match(/[^\s]/) ) {
                        delete post_vars[name];
                    }
                }

                // get the sort settings from the store
                var sorter = store.sorters.first();
                post_vars.sort = sorter.property;
                post_vars.dir = sorter.direction;

                return post_vars;
            }

            // create the Data Store
            var feature_store = Ext.create('Ext.data.Store', {
                id:           'feature_store',
                pageSize:     page_size,
                model:        'Feature',
                remoteSort:   true,
                autoLoad:     true,

                listeners: {
                        // enable or disable the export and save
                        // toolbar based on how many features matched
                        datachanged: function( store ) {
                            var toolbar = Ext.getCmp('feature_export_toolbar');
                            var label = Ext.getCmp('feature_export_toolbar_disabled_label');
                            if( store.getTotalCount() <= maximum_export_size ) {
                                // enable the export toolbar
                                toolbar.enable();
                                label.hide();
                            } else {
                                // disable the export toolbar
                                toolbar.disable();
                                label.show();
                            }
                        }
                },

                proxy: {
                    type: 'ajax',
                    url: '/search/features/search_service',
                    timeout: 60000,
                    reader: {
                        root: 'data',
                        totalProperty: 'totalCount',
                        successProperty: 'success'
                    },
                    // sends single sort as multi parameter
                    simpleSortMode: true
                },
                sorters: [{
                     property: 'feature_id',
                     direction: 'ASC'
                }]
            });

            function hyphen_if_empty( value ) {
                return value.length > 0 ? value : '-';
            }

            function export_to_bulk( bulk_url ) {
                var search_query = get_search_query( feature_store );
                search_query.fields = 'name';
                Ext.Ajax.request({
                    url: '/search/features/search_service',
                    method: 'GET',
                    params: search_query,
                    success: function( response ) {
                        // make a bulk-download URL populated with these IDs
                        var features = Ext.JSON.decode( response.responseText ).data;
                        var names = [];
                        for( var i = 0; i < features.length; i++ ) {
                            names.push( features[i].name );
                        }
                        names = names.join("\n");

                        Ext.create( 'Ext.form.Panel', {
                          url: bulk_url,
                          standardSubmit: true,
                          defaultType: 'textfield',
                          hidden: true,
                          items: [{ name: 'ids', value: names }]
                        }).submit();
                    }
                 });
            }

            var feature_grid = Ext.create('Ext.grid.Panel', {
                width:    700,
                height:   400,
                //title:    'Matching Features',
                store:    feature_store,
                loadMask: true,

                dockedItems: [
                   {
                    xtype: 'toolbar',
                    dock: 'top',
                    id: 'feature_export_toolbar',
                    items: [
                        '->',
                        { xtype: 'label',
                          id: 'feature_export_toolbar_disabled_label',
                          text: 'Exporting limited to '+ Ext.util.Format.number( maximum_export_size, '0,000' )+' features.',
                          hidden: true
                        },{
                            xtype: 'button',
                            text: 'Save as',
                            icon: '/img/icons/oxygen/16x16/media-floppy.png',
                            menu: {
                                items: [
                                    {
                                        text: 'CSV',
                                        icon: '/img/icons/oxygen/16x16/text-csv.png',
                                        handler: function() {
                                            var search_query_vars = get_search_query( feature_store );
                                            var csv_url = '/search/features/export_csv?' + Ext.Object.toQueryString( search_query_vars );
                                            location.href = csv_url;
                                        }
                                    }
                                ]
                            }
                        },{
                            xtype: 'button',
                            text: 'Send to',
                            icon: '/img/icons/oxygen/16x16/document-export.png',
                            menu: {
                                items: [
                                    {
                                        text: 'bulk feature download',
                                        icon: '/img/icons/oxygen/16x16/document-export-table.png',
                                        handler: function() {
                                            export_to_bulk( '/bulk/feature' );
                                        }
                                    },{
                                        text: 'bulk gene download',
                                        icon: '/img/icons/oxygen/16x16/document-export-table.png',
                                        handler: function() {
                                            export_to_bulk( '/bulk/gene' );
                                        }
                                    }
                                ]
{'fraction_non_alphanumeric': 0.08414446721311475, 'fraction_numerical': 0.005507172131147541, 'mean_word_length': 0.7058438012015292, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 101, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1274035', 'n_tokens_mistral': 3314, 'n_tokens_neox': 2999, 'n_words': 683}