<commit_before>/**
   Copyright 2011 Couchbase, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 **/
var ServersSection = {
  hostnameComparator: mkComparatorByProp('hostname', naturalSort),
  pendingEject: [], // nodes to eject on next rebalance
  pending: [], // nodes for pending tab
  active: [], // nodes for active tab
  allNodes: [], // all known nodes

  visitTab: function (tabName) {
    if (ThePage.currentSection != 'servers') {
      $('html, body').animate({scrollTop: 0}, 250);
    }
    ThePage.ensureSection('servers');
    this.tabs.setValue(tabName);
  },
  updateData: function () {
    var self = this;
    var serversValue = self.serversCell.value || {};

    _.each("pendingEject pending active allNodes".split(' '), function (attr) {
      self[attr] = serversValue[attr] || [];
    });
  },
  renderEverything: function () {
    this.detailsWidget.prepareDrawing();

    var details = this.poolDetails.value;
    var rebalancing = details && details.rebalanceStatus != 'none';

    var pending = this.pending;
    var active = this.active;

    this.serversQ.find('.add_button').toggle(!!(details && !rebalancing));
    this.serversQ.find('.stop_rebalance_button').toggle(!!rebalancing);

    var mayRebalance = !rebalancing && pending.length !=0;

    if (details && !rebalancing && !details.balanced)
      mayRebalance = true;

    var unhealthyActive = _.detect(active, function (n) {
      return n.clusterMembership == 'active'
        && !n.pendingEject
        && n.status === 'unhealthy'
    })

    if (unhealthyActive)
      mayRebalance = false;

    var rebalanceButton = this.serversQ.find('.rebalance_button').toggle(!!details);
    rebalanceButton.toggleClass('disabled', !mayRebalance);

    if (details && !rebalancing) {
      $('#rebalance_tab .badge span').text(pending.length);
      $('#rebalance_tab').toggleClass('badge_display', !!pending.length);
    } else {
      $('#rebalance_tab').toggleClass('badge_display', false);
    }

    this.serversQ.toggleClass('rebalancing', !!rebalancing);

    if (!details)
      return;

    if (active.length) {
      renderTemplate('manage_server_list', {
        rows: active,
        expandingAllowed: !IOCenter.staleness.value
      }, $i('active_server_list_container'));
      renderTemplate('manage_server_list', {
        rows: pending,
        expandingAllowed: false
      }, $i('pending_server_list_container'));
    }

    if (rebalancing) {
      $('#servers .add_button').hide();
      this.renderRebalance(details);
    }

    if (IOCenter.staleness.value) {
      $('#servers .staleness-notice').show();
      $('#servers').find('.add_button, .rebalance_button').hide();
      $('#active_server_list_container, #pending_server_list_container').find('.re_add_button, .eject_server, .failover_server, .remove_from_list').addClass('disabled');
    } else {
      $('#servers .staleness-notice').hide();
      $('#servers').find('.rebalance_button').show();
      $('#servers .add_button')[rebalancing ? 'hide' : 'show']();
    }

    $('#active_server_list_container .last-active').find('.eject_server').addClass('disabled').end()
      .find('.failover_server').addClass('disabled');

    $('#active_server_list_container .server_down .eject_server').addClass('disabled');
    $('.failed_over .eject_server, .failed_over .failover_server').hide();
  },
  renderServerDetails: function (item) {
    return this.detailsWidget.renderItemDetails(item);
  },
  renderRebalance: function (details) {
    var progress = this.rebalanceProgress.value;
    if (progress) {
      progress = progress.perNode;
    }
    if (!progress) {
      progress = {};
    }
    nodes = _.clone(details.nodes);
    nodes.sort(this.hostnameComparator);
    var emptyProgress = {progress: 0};
    _.each(nodes, function (n) {
      var p = progress[n.otpNode];
      if (!p)
        p = emptyProgress;
      n.progress = p.progress;
      n.percent = truncateTo3Digits(n.progress);
      $($i(n.otpNode.replace('@', '-'))).find('.actions').html('<span class="usage_info">' + escapeHTML(n.percent) + '% Complete</span><span class="server_usage"><span style="width: ' + escapeHTML(n.percent) + '%;"></span></span>');
    });
  },
  refreshEverything: function () {
    this.updateData();
    this.renderEverything();
    // It displays the status of auto-failover, hence we need to refresh
    // it to get the current values
    AutoFailoverSection.refreshStatus();
  },
  onRebalanceProgress: function () {
    var value = this.rebalanceProgress.value;
    if (this.sawRebalanceRunning && value.status !== 'running') {
      if (value.errorMessage) {
        this.sawRebalanceRunning = false;
        displayNotice(value.errorMessage, true);
      }
      return
    }
    this.sawRebalanceRunning = true;

    this.renderRebalance(this.poolDetails.value);
  },
  init: function () {
    var self = this;

    self.poolDetails = DAL.cells.currentPoolDetailsCell;

    self.tabs = new TabsCell("serversTab",
                             "#servers .tabs",
                             "#servers .panes > div",
                             ["active", "pending"]);

    var detailsWidget = self.detailsWidget = new MultiDrawersWidget({
      hashFragmentParam: 'openedServers',
      template: 'server_details',
      elementKey: 'otpNode',
      placeholderCSS: '#servers .settings-placeholder',
      actionLink: 'openServer',
      actionLinkCallback: function () {
        ThePage.ensureSection('servers');
      },
      uriExtractor: function (nodeInfo) {
        return "/nodes/" + encodeURIComponent(nodeInfo.otpNode);
      },
      valueTransformer: function (nodeInfo, nodeSettings) {
        return _.extend({}, nodeInfo, nodeSettings);<commit_msg>don't do renderRebalance when rebalance is not running.MB-4719<commit_after>/**
   Copyright 2011 Couchbase, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 **/
var ServersSection = {
  hostnameComparator: mkComparatorByProp('hostname', naturalSort),
  pendingEject: [], // nodes to eject on next rebalance
  pending: [], // nodes for pending tab
  active: [], // nodes for active tab
  allNodes: [], // all known nodes

  visitTab: function (tabName) {
    if (ThePage.currentSection != 'servers') {
      $('html, body').animate({scrollTop: 0}, 250);
    }
    ThePage.ensureSection('servers');
    this.tabs.setValue(tabName);
  },
  updateData: function () {
    var self = this;
    var serversValue = self.serversCell.value || {};

    _.each("pendingEject pending active allNodes".split(' '), function (attr) {
      self[attr] = serversValue[attr] || [];
    });
  },
  renderEverything: function () {
    this.detailsWidget.prepareDrawing();

    var details = this.poolDetails.value;
    var rebalancing = details && details.rebalanceStatus != 'none';

    var pending = this.pending;
    var active = this.active;

    this.serversQ.find('.add_button').toggle(!!(details && !rebalancing));
    this.serversQ.find('.stop_rebalance_button').toggle(!!rebalancing);

    var mayRebalance = !rebalancing && pending.length !=0;

    if (details && !rebalancing && !details.balanced)
      mayRebalance = true;

    var unhealthyActive = _.detect(active, function (n) {
      return n.clusterMembership == 'active'
        && !n.pendingEject
        && n.status === 'unhealthy'
    })

    if (unhealthyActive)
      mayRebalance = false;

    var rebalanceButton = this.serversQ.find('.rebalance_button').toggle(!!details);
    rebalanceButton.toggleClass('disabled', !mayRebalance);

    if (details && !rebalancing) {
      $('#rebalance_tab .badge span').text(pending.length);
      $('#rebalance_tab').toggleClass('badge_display', !!pending.length);
    } else {
      $('#rebalance_tab').toggleClass('badge_display', false);
    }

    this.serversQ.toggleClass('rebalancing', !!rebalancing);

    if (!details)
      return;

    if (active.length) {
      renderTemplate('manage_server_list', {
        rows: active,
        expandingAllowed: !IOCenter.staleness.value
      }, $i('active_server_list_container'));
      renderTemplate('manage_server_list', {
        rows: pending,
        expandingAllowed: false
      }, $i('pending_server_list_container'));
    }

    if (rebalancing) {
      $('#servers .add_button').hide();
      this.renderRebalance(details);
    }

    if (IOCenter.staleness.value) {
      $('#servers .staleness-notice').show();
      $('#servers').find('.add_button, .rebalance_button').hide();
      $('#active_server_list_container, #pending_server_list_container').find('.re_add_button, .eject_server, .failover_server, .remove_from_list').addClass('disabled');
    } else {
      $('#servers .staleness-notice').hide();
      $('#servers').find('.rebalance_button').show();
      $('#servers .add_button')[rebalancing ? 'hide' : 'show']();
    }

    $('#active_server_list_container .last-active').find('.eject_server').addClass('disabled').end()
      .find('.failover_server').addClass('disabled');

    $('#active_server_list_container .server_down .eject_server').addClass('disabled');
    $('.failed_over .eject_server, .failed_over .failover_server').hide();
  },
  renderServerDetails: function (item) {
    return this.detailsWidget.renderItemDetails(item);
  },
  renderRebalance: function (details) {
    var progress = this.rebalanceProgress.value;
    if (progress) {
      progress = progress.perNode;
    }
    if (!progress) {
      progress = {};
    }
    nodes = _.clone(details.nodes);
    nodes.sort(this.hostnameComparator);
    var emptyProgress = {progress: 0};
    _.each(nodes, function (n) {
      var p = progress[n.otpNode];
      if (!p)
        p = emptyProgress;
      n.progress = p.progress;
      n.percent = truncateTo3Digits(n.progress);
      $($i(n.otpNode.replace('@', '-'))).find('.actions').html('<span class="usage_info">' + escapeHTML(n.percent) + '% Complete</span><span class="server_usage"><span style="width: ' + escapeHTML(n.percent) + '%;"></span></span>');
    });
  },
  refreshEverything: function () {
    this.updateData();
    this.renderEverything();
    // It displays the status of auto-failover, hence we need to refresh
    // it to get the current values
    AutoFailoverSection.refreshStatus();
  },
  onRebalanceProgress: function () {
    var value = this.rebalanceProgress.value;
    if (value.status !== 'running') {
      // if state is not running due to error message and we started
      // that past rebalance
      if (this.sawRebalanceRunning && value.errorMessage) {
        // display message
        this.sawRebalanceRunning = false;
        displayNotice(value.errorMessage, true);
      }
      // and regardless of displaying that error message, exit if not
      // rebalancing
      return;
    }
    this.sawRebalanceRunning = true;

    this.renderRebalance(this.poolDetails.value);
  },
  init: function () {
    var self = this;

    self.poolDetails = DAL.cells.currentPoolDetailsCell;

    self.tabs = new TabsCell("serversTab",
                             "#servers .tabs",
                             "#servers .panes > div",
                             ["active", "pending"]);

    var detailsWidget = self.detailsWidget = new MultiDrawersWidget({
      hashFragmentParam: 'openedServers',
      template: 'server_details',
      elementKey: 'otpNode',
      placeholderCSS: '#servers .settings-placeholder',
      actionLink: 'openServer',
      actionLinkCallback: function () {
        ThePage.ensureSection('servers');
      },
      uriExtractor: function (nodeInfo) {
        return "/nodes/" + encodeURIComponent(nodeInfo.otpNode);
      },
      valueTransformer: function (nodeInfo, nodeSettings) {
        return _.extend({}, nodeInfo, nodeSettings);
{'fraction_non_alphanumeric': 0.1432491767288694, 'fraction_numerical': 0.0026658303277403168, 'mean_word_length': 3.208182118112834, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1429511', 'n_tokens_mistral': 3722, 'n_tokens_neox': 3702, 'n_words': 816}