<commit_before>/**
 * @fileoverview Component that shows Variants and controls for display.
 */


gd.VariantsTableComponent = Backbone.View.extend({

  /** Override. */
  initialize: function() {
    // Populate model with attributes.
    if ('filterString' in this.options) {
      this.model.set('filterString', this.options['filterString']);
    }
    if (!this.model.get('filterString')) {
      this.model.set('filterString', '');
    }

    // Whether filter bar is disabled.
    this.model.set('filterDisabled', 'filterDisabled' in this.options ?
        this.options['filterDisabled'] : false);

    // List of variants currently being displayed.
    this.variantList = null;

    // Config that describes the schema for the visible table.
    this.fieldConfig = null;

    this.render();
  },

  /** @override */
  render: function() {
    this.renderDatatable();
  },

  /** @override */
  renderDatatable: function() {
    // Always start this flow by checking whether the materialized view
    // is valid. Then do the rest of the create after.
    this.prepareMaterializedView(
        _.bind(this.afterMaterializedViewReady, this));
  },

  /** @override */
  decorateControls: function() {
    var filterEl = $('#gd-new-filter-input');
    var applyFilterBtnEl = $('#gd-filter-box-apply-btn');

    // Decorate the filter element.
    filterEl.val(this.model.get('filterString'));
    if (this.model.get('filterDisabled')) {
      filterEl.prop('disabled', true);
      applyFilterBtnEl.hide();
    } else {
      // Listen to click on the button.
      $('#gd-filter-box-apply-btn').click(
          _.bind(this.handleApplyFilterClick, this));
      $('#gd-new-filter-input').keypress(
          _.bind(this.handleFilterInputKeypress, this));
    }

    // Advanced filter dropdown box.
    $('#gd-snp-filter-advanced-dropdown-button').click(
        this.handleAdvancedDropdownClick);
    $('#gd-snp-filter-advanced-dropdown-box-close-btn').click(
        this.handleCloseAdvancedDropdown);
    $('.gd-snp-filter-advanced-saved-filter-text').click(
        _.bind(this.handleSavedFilterSelect, this));
    $('#gd-snp-filter-advanced-dropdown-box-save-btn').click(
        _.bind(this.handleSaveCurrentFilter, this));
    $('.gd-snp-filter-advanced-saved-filter-delete').click(
        _.bind(this.handleSavedFilterDelete, this));

    // Decorate the cast/melt toggle.
    if (this.model.get('isMelted')) {
      $('#gd-snp-filter-melt-toggle-melt').addClass('active');
    } else {
      $('#gd-snp-filter-melt-toggle-cast').addClass('active');
    }
    $('.gd-snp-filter-melt-toggle').click(
        _.bind(this.handleMeltedToggleClick, this));

    // Decorate show field select.
    $('#gd-filter-field-select-btn').click(
            _.bind(this.handleShowFieldSelect, this));

    // Manually handle error alert close.
    $('#gd-snp-filter-error-close-btn').click(
        _.bind(this.handleErrorAlertClose, this));
  },

  afterMaterializedViewReady: function() {
    // Recreate the initial DataTable.
    this.createDatatableComponent();

    // Kick off request to update the Variant data being displayed.
    this.updateVariantList();
  },

  /**
   * Checks if the underlying materialized view needs to be updated
   * and kick off a whole ui affordance to manage that.
   */
  prepareMaterializedView: function(callback) {
    // First make a request to check if needs to be refreshed.
    var requestData = {
      'refGenomeUid': this.model.get('refGenomeUid'),
    };
    $.get('/_/variants/is_materialized_view_valid', requestData,
        _.bind(function(responseData) {
          if (responseData.isValid) {
            callback.call();
          } else {
            this.handleRefreshMaterializedView(callback);
          }
        }, this));
  },

  /** Redraws the datatable based on the selection. */
  createDatatableComponent: function() {
    this.datatableComponent = new gd.ServerSideDataTableComponent({
        el: $('#gd-datatable-hook'),
        serverTarget: '/_/variants',
        controlsTemplate: '/_/templates/variant_filter_controls',
        requestData: {'refGenomeUid': this.model.get('refGenomeUid')},
        serverParamsInjector: _.bind(
            this.addFilterDataServerSideRequest, this)
    });

    // Listen to events from the DataTable to provide appropriate UI affordance.
    this.listenTo(this.datatableComponent, 'START_LOADING',
        _.bind(this.setUIStartLoadingState, this));
    this.listenTo(this.datatableComponent, 'DONE_LOADING',
        _.bind(this.setUIDoneLoadingState, this));
    this.listenTo(this.datatableComponent, 'DONE_CONTROLS_REDRAW',
        _.bind(this.decorateControls, this));
  },

  /** Provide affordance while doing Variant query. */
  setUIStartLoadingState: function() {
    $('#gd-datatable-hook-datatable_wrapper').css('opacity', 0.5);

    this.loadingSpinner = new gd.Spinner();
    this.loadingSpinner.spin()
  },

  /** Reset UI changes after loading complete.. */
  setUIDoneLoadingState: function() {
    $('#gd-datatable-hook-datatable_wrapper').css('opacity', 1);
    if (this.loadingSpinner) {
      this.loadingSpinner.stop();
    }

    // HACK: Reset master checkbox.
    // Is there a better place to do this?
    this.datatableComponent.resetAllSelectedState();
  },

  /** Handles the server response containing Variants data. */
  handleGetVariantListResponse: function(response) {
    if ('error' in response) {
      this.handleGetVariantListError(response.error);
      return;
    }

    // Parse Variant data.
    var variantListData = JSON.parse(response.variant_list_json);
    if (variantListData.obj_list.length) {
      this.variantList = variantListData.obj_list;
      this.fieldConfig = variantListData.field_config;
    } else {
      this.variantList = [];
      this.fieldConfig = {};<commit_msg>Fix #449: Fix first load of materialized view.<commit_after>/**
 * @fileoverview Component that shows Variants and controls for display.
 */


gd.VariantsTableComponent = Backbone.View.extend({

  /** Override. */
  initialize: function() {
    // Populate model with attributes.
    if ('filterString' in this.options) {
      this.model.set('filterString', this.options['filterString']);
    }
    if (!this.model.get('filterString')) {
      this.model.set('filterString', '');
    }

    // Whether filter bar is disabled.
    this.model.set('filterDisabled', 'filterDisabled' in this.options ?
        this.options['filterDisabled'] : false);

    // List of variants currently being displayed.
    this.variantList = null;

    // Config that describes the schema for the visible table.
    this.fieldConfig = null;

    this.render();
  },

  /** @override */
  render: function() {
    this.renderDatatable();
  },

  /** @override */
  renderDatatable: function() {
    // Always start this flow by checking whether the materialized view
    // is valid. Then do the rest of the create after.
    this.prepareMaterializedView(
        _.bind(this.afterMaterializedViewReady, this));
  },

  /** @override */
  decorateControls: function() {
    var filterEl = $('#gd-new-filter-input');
    var applyFilterBtnEl = $('#gd-filter-box-apply-btn');

    // Decorate the filter element.
    filterEl.val(this.model.get('filterString'));
    if (this.model.get('filterDisabled')) {
      filterEl.prop('disabled', true);
      applyFilterBtnEl.hide();
    } else {
      // Listen to click on the button.
      $('#gd-filter-box-apply-btn').click(
          _.bind(this.handleApplyFilterClick, this));
      $('#gd-new-filter-input').keypress(
          _.bind(this.handleFilterInputKeypress, this));
    }

    // Advanced filter dropdown box.
    $('#gd-snp-filter-advanced-dropdown-button').click(
        this.handleAdvancedDropdownClick);
    $('#gd-snp-filter-advanced-dropdown-box-close-btn').click(
        this.handleCloseAdvancedDropdown);
    $('.gd-snp-filter-advanced-saved-filter-text').click(
        _.bind(this.handleSavedFilterSelect, this));
    $('#gd-snp-filter-advanced-dropdown-box-save-btn').click(
        _.bind(this.handleSaveCurrentFilter, this));
    $('.gd-snp-filter-advanced-saved-filter-delete').click(
        _.bind(this.handleSavedFilterDelete, this));

    // Decorate the cast/melt toggle.
    if (this.model.get('isMelted')) {
      $('#gd-snp-filter-melt-toggle-melt').addClass('active');
    } else {
      $('#gd-snp-filter-melt-toggle-cast').addClass('active');
    }
    $('.gd-snp-filter-melt-toggle').click(
        _.bind(this.handleMeltedToggleClick, this));

    // Decorate show field select.
    $('#gd-filter-field-select-btn').click(
            _.bind(this.handleShowFieldSelect, this));

    // Manually handle error alert close.
    $('#gd-snp-filter-error-close-btn').click(
        _.bind(this.handleErrorAlertClose, this));
  },

  afterMaterializedViewReady: function() {
    // Recreate the initial DataTable.
    this.createDatatableComponent();

    // Kick off request to update the Variant data being displayed.
    this.updateVariantList();
  },

  /**
   * Checks if the underlying materialized view needs to be updated
   * and kick off a whole ui affordance to manage that.
   */
  prepareMaterializedView: function(callback) {
    // First make a request to check if needs to be refreshed.
    var requestData = {
      'refGenomeUid': this.model.get('refGenomeUid'),
    };
    $.get('/_/variants/is_materialized_view_valid', requestData,
        _.bind(function(responseData) {
          if (responseData.isValid) {
            callback.call();
          } else {
            this.handleRefreshMaterializedView(callback);
          }
        }, this));
  },

  /** Redraws the datatable based on the selection. */
  createDatatableComponent: function() {
    this.datatableComponent = new gd.ServerSideDataTableComponent({
        el: $('#gd-datatable-hook'),
        serverTarget: '/_/variants',
        controlsTemplate: '/_/templates/variant_filter_controls',
        requestData: {'refGenomeUid': this.model.get('refGenomeUid')},
        serverParamsInjector: _.bind(
            this.addFilterDataServerSideRequest, this)
    });

    // Listen to events from the DataTable to provide appropriate UI affordance.
    this.listenTo(this.datatableComponent, 'START_LOADING',
        _.bind(this.setUIStartLoadingState, this));
    this.listenTo(this.datatableComponent, 'DONE_LOADING',
        _.bind(this.setUIDoneLoadingState, this));
    this.listenTo(this.datatableComponent, 'DONE_CONTROLS_REDRAW',
        _.bind(this.decorateControls, this));
  },

  /** Provide affordance while doing Variant query. */
  setUIStartLoadingState: function() {
    $('#gd-datatable-hook-datatable_wrapper').css('opacity', 0.5);

    this.loadingSpinner = new gd.Spinner();
    this.loadingSpinner.spin()
  },

  /** Reset UI changes after loading complete.. */
  setUIDoneLoadingState: function() {
    $('#gd-datatable-hook-datatable_wrapper').css('opacity', 1);
    if (this.loadingSpinner) {
      this.loadingSpinner.stop();
    }

    // HACK: Reset master checkbox.
    // Is there a better place to do this?
    if (this.datatableComponent) {
      this.datatableComponent.resetAllSelectedState();
    }
  },

  /** Handles the server response containing Variants data. */
  handleGetVariantListResponse: function(response) {
    if ('error' in response) {
      this.handleGetVariantListError(response.error);
      return;
    }

    // Parse Variant data.
    var variantListData = JSON.parse(response.variant_list_json);
    if (variantListData.obj_list.length) {
      this.variantList = variantListData.obj_list;
      this.fieldConfig = variantListData.field_config;
    } else {
      this.variantList = [];
      this.fieldConfig = {};
{'fraction_non_alphanumeric': 0.13981969722741963, 'fraction_numerical': 0.0007654362986902534, 'mean_word_length': 3.024298425735797, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '4438931', 'n_tokens_mistral': 3493, 'n_tokens_neox': 3428, 'n_words': 703}