source: vlo/branches/vlo-3.3-oeaw/vlo-solr/src/main/webapp/js/scripts/app.js @ 6753

Last change on this file since 6753 was 6753, checked in by davor.ostojic@oeaw.ac.at, 9 years ago

merged with trunk

File size: 17.3 KB
Line 
1/*
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements.  See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License.  You may obtain a copy of the License at
8
9     http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16*/
17
18var loader = {
19   
20  show : function( element )
21  {
22    $( element )
23      .addClass( 'loader' );
24  },
25   
26  hide : function( element )
27  {
28    $( element )
29      .removeClass( 'loader' );
30  }
31   
32};
33
34Number.prototype.esc = function()
35{
36  return new String( this ).esc();
37}
38
39String.prototype.esc = function()
40{
41  return this.replace( /</g, '&lt;' ).replace( />/g, '&gt;' );
42}
43
44SolrDate = function( date )
45{
46  // ["Sat Mar 03 11:00:00 CET 2012", "Sat", "Mar", "03", "11:00:00", "CET", "2012"]
47  var parts = date.match( /^(\w+)\s+(\w+)\s+(\d+)\s+(\d+\:\d+\:\d+)\s+(\w+)\s+(\d+)$/ );
48   
49  // "Sat Mar 03 2012 10:37:33"
50  return new Date( parts[1] + ' ' + parts[2] + ' ' + parts[3] + ' ' + parts[6] + ' ' + parts[4] );
51}
52
53var sammy = $.sammy
54(
55  function()
56  {
57    this.bind
58    (
59      'run',
60      function( event, config )
61      {
62        if( 0 === config.start_url.length )
63        {
64          location.href = '#/';
65          return false;
66        }
67      }
68    );
69
70    this.bind
71    (
72      'error',
73      function( message, original_error )
74      {
75        alert( original_error.message );
76      }
77    );
78       
79    // activate_core
80    this.before
81    (
82      {},
83      function( context )
84      {
85        app.clear_timeout();
86
87        var menu_wrapper = $( '#menu-wrapper' );
88
89        $( 'li[id].active', menu_wrapper )
90          .removeClass( 'active' );
91               
92        $( 'li.active', menu_wrapper )
93          .removeClass( 'active' );
94
95        // global dashboard doesn't have params.splat
96        if( !this.params.splat )
97        {
98          this.params.splat = [ '~index' ];
99        }
100
101        var selector = '~' === this.params.splat[0][0]
102                     ? '#' + this.params.splat[0].replace( /^~/, '' ) + '.global'
103                     : '#core-selector #' + this.params.splat[0].replace( /\./g, '__' );
104
105        var active_element = $( selector, menu_wrapper );
106                 
107        if( 0 === active_element.size() )
108        {
109          this.app.error( 'There exists no core with name "' + this.params.splat[0] + '"' );
110          return false;
111        }
112
113        if( active_element.hasClass( 'global' ) )
114        {
115          active_element
116            .addClass( 'active' );
117
118          if( this.params.splat[1] )
119          {
120            $( '.' + this.params.splat[1], active_element )
121              .addClass( 'active' );
122          }
123
124          $( '#core-selector option[selected]' )
125            .removeAttr( 'selected' )
126            .trigger( 'liszt:updated' );
127
128          $( '#core-selector .chzn-container > a' )
129            .addClass( 'chzn-default' );
130        }
131        else
132        {
133          active_element
134            .attr( 'selected', 'selected' )
135            .trigger( 'liszt:updated' );
136
137          if( !this.params.splat[1] )
138          {
139            this.params.splat[1] = 'overview';
140          }
141
142          $( '#core-menu .' + this.params.splat[1] )
143            .addClass( 'active' );
144
145          this.active_core = active_element;
146        }
147      }
148    );
149  }
150);
151
152var solr_admin = function( app_config )
153{
154  that = this,
155
156  menu_element = null,
157
158  is_multicore = null,
159  cores_data = null,
160  active_core = null,
161   
162  config = app_config,
163  params = null,
164  dashboard_values = null,
165  schema_browser_data = null,
166
167  plugin_data = null,
168   
169  this.menu_element = $( '#core-selector select' );
170  this.core_menu = $( '#core-menu ul' );
171
172  this.config = config;
173  this.timeout = null;
174
175  this.core_regex_base = '^#\\/([\\w\\d-\\.]+)';
176
177  browser = {
178    locale : null,
179    language : null,
180    country : null
181  };
182
183  show_global_error = function( error )
184  {
185    var main = $( '#main' );
186
187    $( 'div[id$="-wrapper"]', main )
188      .remove();
189
190    main
191      .addClass( 'error' )
192      .append( error );
193
194    var pre_tags = $( 'pre', main );
195    if( 0 !== pre_tags.size() )
196    {
197      hljs.highlightBlock( pre_tags.get(0) ); 
198    }
199  };
200
201  sort_cores_data = function sort_cores_data( cores_status )
202  {
203    // build array of core-names for sorting
204    var core_names = [];
205    for( var core_name in cores_status )
206    {
207      core_names.push( core_name );
208    }
209    core_names.sort();
210
211    var core_count = core_names.length;
212    var cores = {};
213
214    for( var i = 0; i < core_count; i++ )
215    {
216      var core_name = core_names[i];
217      cores[core_name] = cores_status[core_name];
218    }
219
220    return cores;
221  };
222
223  this.set_cores_data = function set_cores_data( cores )
224  {
225    that.cores_data = sort_cores_data( cores.status );
226   
227    that.menu_element
228      .empty();
229
230    var core_list = [];
231    core_list.push( '<option></option>' );
232
233    var core_count = 0;
234    for( var core_name in that.cores_data )
235    {
236      core_count++;
237      var core_path = config.solr_path + '/' + core_name;
238      var classes = [];
239
240      if( cores.status[core_name]['isDefaultCore'] )
241      {
242        classes.push( 'default' );
243      }
244
245      var core_tpl = '<option '
246                   + '    id="' + core_name.replace( /\./g, '__' ) + '" '
247                   + '    class="' + classes.join( ' ' ) + '"'
248                   + '    data-basepath="' + core_path + '"'
249                   + '    schema="' + cores.status[core_name]['schema'] + '"'
250                   + '    config="' + cores.status[core_name]['config'] + '"'
251                   + '    value="#/' + core_name + '"'
252                   + '    title="' + core_name + '"'
253                   + '>' 
254                   + core_name 
255                   + '</option>';
256
257      core_list.push( core_tpl );
258    }
259
260    var has_cores = 0 !== core_count;
261    if( has_cores )
262    {
263      that.menu_element
264        .append( core_list.join( "\n" ) )
265        .trigger( 'liszt:updated' );
266    }
267
268    var core_selector = $( '#core-selector' );
269    core_selector.find( '#has-cores' ).toggle( has_cores );
270    core_selector.find( '#has-no-cores' ).toggle( !has_cores );
271
272    if( has_cores )
273    {
274      var cores_element = core_selector.find( '#has-cores' );
275      var selector_width = cores_element.width();
276
277      cores_element.find( '.chzn-container' )
278        .css( 'width', selector_width + 'px' );
279     
280      cores_element.find( '.chzn-drop' )
281        .css( 'width', ( selector_width - 2 ) + 'px' );
282    }
283
284    this.check_for_init_failures( cores );
285  };
286
287  this.remove_init_failures = function remove_init_failures()
288  {
289    $( '#init-failures' )
290      .hide()
291      .find( 'ul' )
292        .empty();
293  }
294
295  this.check_for_init_failures = function check_for_init_failures( cores )
296  {
297    if( !cores.initFailures )
298    {
299      this.remove_init_failures();
300      return false;
301    }
302
303    var failures = [];
304    for( var core_name in cores.initFailures )
305    {
306      failures.push
307      (
308        '<li>' +
309          '<strong>' + core_name.esc() + ':</strong>' + "\n" +
310          cores.initFailures[core_name].esc() + "\n" +
311        '</li>'
312      );
313    }
314
315    if( 0 === failures.length )
316    {
317      this.remove_init_failures();
318      return false;
319    }
320
321    $( '#init-failures' )
322      .show()
323      .find( 'ul' )
324        .html( failures.join( "\n" ) );
325  }
326
327  this.run = function()
328  {
329    var navigator_language = navigator.userLanguage || navigator.language;
330    var language_match = navigator_language.match( /^(\w{2})([-_](\w{2}))?$/ );
331    if( language_match )
332    {
333      if( language_match[1] )
334      {
335        browser.language = language_match[1].toLowerCase();
336      }
337      if( language_match[3] )
338      {
339        browser.country = language_match[3].toUpperCase();
340      }
341      if( language_match[1] && language_match[3] )
342      {
343        browser.locale = browser.language + '_' + browser.country
344      }
345    }
346
347    $.ajax
348    (
349      {
350        url : config.solr_path + config.core_admin_path + '?wt=json&indexInfo=false',
351        dataType : 'json',
352        beforeSend : function( arr, form, options )
353        {               
354          $( '#content' )
355            .html( '<div id="index"><div class="loader">Loading ...</div></div>' );
356        },
357        success : function( response )
358        {
359          that.set_cores_data( response );
360
361          that.menu_element
362            .chosen()
363            .off( 'change' )
364            .on
365            (
366              'change',
367              function( event )
368              {
369                location.href = $( 'option:selected', this ).val();
370                return false;
371              }
372            )
373            .on
374            (
375              'liszt:updated',
376              function( event )
377              {
378                var core_name = $( 'option:selected', this ).text();
379
380                that.core_menu
381                  .html
382                  (
383                    //Keep this in alphabetical order after the overview
384                    '<li class="overview"><a href="#/' + core_name + '"><span>Overview</span></a></li>' + "\n" +
385                    '<li class="analysis"><a href="#/' + core_name + '/analysis"><span>Analysis</span></a></li>' + "\n" +
386                    '<li class="dataimport"><a href="#/' + core_name + '/dataimport"><span>Dataimport</span></a></li>' + "\n" +
387                    '<li class="documents"><a href="#/' + core_name + '/documents"><span>Documents</span></a></li>' + "\n" +
388                    '<li class="files"><a href="#/' + core_name + '/files"><span>Files</span></a></li>' + "\n" +
389                    '<li class="ping"><a rel="' + that.config.solr_path + '/' + core_name + '/admin/ping"><span>Ping</span></a></li>' + "\n" +
390                    '<li class="plugins"><a href="#/' + core_name + '/plugins"><span>Plugins / Stats</span></a></li>' + "\n" +
391                    '<li class="query"><a href="#/' + core_name + '/query"><span>Query</span></a></li>' + "\n" +
392                    '<li class="replication"><a href="#/' + core_name + '/replication"><span>Replication</span></a></li>' + "\n" +
393                    '<li class="schema-browser"><a href="#/' + core_name + '/schema-browser"><span>Schema Browser</span></a></li>'
394                  )
395                  .show();
396
397                if( !core_name )
398                {
399                  that.core_menu
400                    .hide()
401                    .empty();
402                }
403              }
404            );
405
406          var system_url = config.solr_path + '/admin/info/system?wt=json';
407          $.ajax
408          (
409            {
410              url : system_url,
411              dataType : 'json',
412              beforeSend : function( arr, form, options )
413              {
414              },
415              success : function( response )
416              {
417                that.dashboard_values = response;
418
419                var environment_args = null;
420                var cloud_args = null;
421
422                if( response.jvm && response.jvm.jmx && response.jvm.jmx.commandLineArgs )
423                {
424                  var command_line_args = response.jvm.jmx.commandLineArgs.join( ' | ' );
425
426                  environment_args = command_line_args.match( /-Dsolr.environment=((dev|test|prod)?[\w\d]*)/i );
427                }
428
429                if( response.mode )
430                {
431                  cloud_args = response.mode.match( /solrcloud/i );
432                }
433
434                // environment
435
436                var wrapper = $( '#wrapper' );
437                var environment_element = $( '#environment' );
438                if( environment_args )
439                {
440                  wrapper
441                    .addClass( 'has-environment' );
442
443                  if( environment_args[1] )
444                  {
445                    environment_element
446                      .html( environment_args[1] );
447                  }
448
449                  if( environment_args[2] )
450                  {
451                    environment_element
452                      .addClass( environment_args[2] );
453                  }
454                }
455                else
456                {
457                  wrapper
458                    .removeClass( 'has-environment' );
459                }
460
461                // cloud
462
463                var cloud_nav_element = $( '#menu #cloud' );
464                if( cloud_args )
465                {
466                  cloud_nav_element
467                    .show();
468                }
469
470                // sammy
471
472                sammy.run( location.hash );
473              },
474              error : function()
475              {
476                show_global_error
477                (
478                  '<div class="message"><p>Unable to load environment info from <code>' + system_url.esc() + '</code>.</p>' +
479                  '<p>This interface requires that you activate the admin request handlers in all SolrCores by adding the ' +
480                  'following configuration to your <code>solrconfig.xml</code>:</p></div>' + "\n" +
481
482                  '<div class="code"><pre class="syntax language-xml"><code>' +
483                  '<!-- Admin Handlers - This will register all the standard admin RequestHandlers. -->'.esc() + "\n" +
484                  '<requestHandler name="/admin/" class="solr.admin.AdminHandlers" />'.esc() +
485                  '</code></pre></div>'
486                );
487              },
488              complete : function()
489              {
490                loader.hide( this );
491              }
492            }
493          );
494        },
495        error : function()
496        {
497        },
498        complete : function()
499        {
500        }
501      }
502    );
503  };
504
505  this.convert_duration_to_seconds = function convert_duration_to_seconds( str )
506  {
507    var seconds = 0;
508    var arr = new String( str || '' ).split( '.' );
509    var parts = arr[0].split( ':' ).reverse();
510    var parts_count = parts.length;
511
512    for( var i = 0; i < parts_count; i++ )
513    {
514      seconds += ( parseInt( parts[i], 10 ) || 0 ) * Math.pow( 60, i );
515    }
516
517    // treat more or equal than .5 as additional second
518    if( arr[1] && 5 <= parseInt( arr[1][0], 10 ) )
519    {
520      seconds++;
521    }
522
523    return seconds;
524  };
525
526  this.convert_seconds_to_readable_time = function convert_seconds_to_readable_time( seconds )
527  {
528    seconds = parseInt( seconds || 0, 10 );
529    var minutes = Math.floor( seconds / 60 );
530    var hours = Math.floor( minutes / 60 );
531
532    var text = [];
533    if( 0 !== hours )
534    {
535      text.push( hours + 'h' );
536      seconds -= hours * 60 * 60;
537      minutes -= hours * 60;
538    }
539
540    if( 0 !== minutes )
541    {
542      text.push( minutes + 'm' );
543      seconds -= minutes * 60;
544    }
545
546    if( 0 !== seconds )
547    {
548      text.push( ( '0' + seconds ).substr( -2 ) + 's' );
549    }
550
551    return text.join( ' ' );
552  };
553
554  this.clear_timeout = function clear_timeout()
555  {
556    if( !app.timeout )
557    {
558      return false;
559    }
560
561    console.debug( 'Clearing Timeout #' + this.timeout );
562    clearTimeout( this.timeout );
563    this.timeout = null;
564  };
565
566  this.format_json = function format_json( json_str )
567  {
568    if( JSON.stringify && JSON.parse )
569    {
570      json_str = JSON.stringify( JSON.parse( json_str ), undefined, 2 );
571    }
572
573    return json_str.esc();
574  };
575
576  this.format_number = function format_number( number )
577  {
578    var sep = {
579      'de_CH' : '\'',
580      'de' : '.',
581      'en' : ',',
582      'es' : '.',
583      'it' : '.',
584      'ja' : ',',
585      'sv' : ' ',
586      'tr' : '.',
587      '_' : '' // fallback
588    };
589
590    return ( number || 0 ).toString().replace
591    (
592      /\B(?=(\d{3})+(?!\d))/g,
593      sep[ browser.locale ] || sep[ browser.language ] || sep['_']
594    );
595  };
596
597};
598
599var connection_check_delay = 1000;
600var connection_working = true;
601
602var connection_check = function connection_check()
603{
604  $.ajax
605  (
606    {
607      url : config.solr_path + config.core_admin_path + '?wt=json&indexInfo=false',
608      dataType : 'json',
609      context : $( '.blockUI #connection_status span' ),
610      beforeSend : function( arr, form, options )
611      {               
612        this
613          .addClass( 'loader' );
614      },
615      success : function( response )
616      {
617        connection_working = true;
618
619        this
620          .html( 'Instance is available - <a href="javascript:location.reload();">Reload the page</a>' );
621
622        this.parents( '#connection_status' )
623          .addClass( 'online' );
624
625        this.parents( '.blockUI' )
626          .css( 'borderColor', '#080' );
627      },
628      error : function()
629      {
630        connection_check_delay += connection_check_delay;
631        window.setTimeout( connection_check, connection_check_delay );
632      },
633      complete : function()
634      {
635        this
636          .removeClass( 'loader' );
637      }
638    }
639  );
640};
641
642var connection_error = function connection_error()
643{
644  connection_working = false;
645
646  $.blockUI
647  (
648    {
649      message: $( '#connection_status' ),
650      css: { width: '450px', borderColor: '#f00' }
651    }
652  );
653
654  window.setTimeout( connection_check, connection_check_delay );
655}
656
657$( document ).ajaxError
658(
659  function( event, xhr, settings, thrownError )
660  {
661    if( connection_working && 0 === xhr.status )
662    {
663      connection_error();
664    }
665  }
666);
667
668$.ajaxSetup( { cache: false } );
669var app = new solr_admin( app_config );
Note: See TracBrowser for help on using the repository browser.