text: {% autoescape None %}
  {% extends ../../../templates/base.html %}
  
  {% block title %}[{{instance.hostname}}:{{instance.pg_port}}] - Maintenance{% end %}
  
  {% block content %}
  
  {% include breadcrumb.html %}
  
  <div id="app">
    <h3>
      Table: <strong>{{ table }}</strong>
    </h3>
    <div class="text-center" v-if="loading">
      <img src="/images/ring-alt.svg" class="fa-fw fa-2x">
    </div>
    <div v-cloak v-if="!loading">
      <div class="row mb-2">
        <div class="col">
          <size-distribution-bar
            :height="'10px;'"
            :total="table.total_bytes"
            :cat1="table.table_size"
            :cat1raw="table.table_bytes"
            cat1label="Heap"
            :cat1bis="table.bloat_size"
            :cat1bisraw="table.bloat_bytes || 0"
            cat1bislabel="Heap Bloat"
            :cat2="table.index_size"
            :cat2raw="table.index_bytes"
            cat2label="Indexes"
            :cat2bis="table.index_bloat_size"
            :cat2bisraw="table.index_bloat_bytes"
            cat2bislabel="Indexes Bloat"
            :cat3="table.toast_size"
            :cat3raw="table.toast_bytes"
            cat3label="Toast"
            >
          </size-distribution-bar>
        </div>
      </div>
      <div class="row">
        <div class="col">
          <dl>
            <dt>
            Total
            </dt>
            <dd>
            {{! table.total_size }}
            <br>
            <span class="text-muted">~ {{! table.row_estimate }} rows</span>
            <small class="text-muted">(~ {{! table.n_dead_tup }} dead)</small>
            </dd>
          </dl>
        </div>
        <div class="col">
          <dl>
            <dt>
            Heap
            <span class="bg-cat1 legend fa-fw d-inline-block">&nbsp;</span>
            </dt>
            <dd>
            {{! table.table_size }}
            <br>
            <em class="text-muted">
              Bloat:
              {{! parseInt(table.bloat_bytes / table.table_bytes * 100) }}%
              <span class="small">
                ({{! table.bloat_size }})
              </span>
            </em>
            </dd>
          </dl>
        </div>
        <div class="col">
          <dl>
            <dt>
            Indexes
            <span class="bg-cat2 legend fa-fw d-inline-block">&nbsp;</span>
            </dt>
            <dd>
            {{! table.index_size }}
            <br>
            <em class="text-muted">
              Bloat:
              {{! parseInt(table.index_bloat_bytes / table.index_bytes * 100) }}%
              <span class="small">
                ({{! table.index_bloat_size }})
              </span>
            </em>
            </dd>
          </dl>
        </div>
        <div class="col">
          <dl>
            <dt>
            <span class="bg-secondary legend fa-fw d-inline-block">&nbsp;</span>
            Toast
            </dt>
            <dd>
            {{! table.toast_size }}
            </dd>
          </dl>
        </div>
        <div class="col">
          <dl>
            <dt>
            Fill Factor
            </dt>
            <dd>
            {{! table.fillfactor }}%
            </dd>
          </dl>
        </div>
      </div>
      <div class="row">
        <div class="col-4">
          Last ANALYZE:
          <em :title="getLatestAnalyze().date">
            <strong v-if="getLatestAnalyze().date">
            {{! getLatestAnalyze().date | relative_time }}
            </strong>
            <span v-else>N/A</span>
            <span v-if="getLatestAnalyze().auto">(auto)</span>
          </em>
          <span class="text-muted small" v-if="table.n_mod_since_analyze">
          (~ {{! table.n_mod_since_analyze }} rows modified since then)
          </span>
          <br>
          <small>
            {{! table.analyze_count }} analyzes - {{! table.autoanalyze_count }} auto analyzes
          </small>
        </div>
        <div class="col-4">
          Last VACUUM:
          <em :title="getLatestVacuum().date">
            <strong v-if="getLatestVacuum().date">
              {{! getLatestVacuum().date | relative_time }}
            </strong>
            <span v-else>N/A</span>
            <span v-if="getLatestVacuum().auto">(auto)</span>
          </em>
          <br>
          <small>
            {{! table.vacuum_count }} vacuums - {{! table.autovacuum_count }} auto vacuums
          </small>
        </div>
      </div>
      <div class="row">
        <div class="col-4">
          <div>
            <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#analyzeModal" v-on:click="checkSession">
              ANALYZE
            </button>
            {% include includes/analyze_modal.html %}
            {% include includes/scheduled_analyze.html %}
          </div>
        </div>
        <div class="col-4">
          <div>
            <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#vacuumModal" v-on:click="checkSession">
              VACUUM
            </button>
            {% include includes/vacuum_modal.html %}
            {% include includes/scheduled_vacuum.html %}
          </div>
        </div>
        <div class="col-4">
          <div>
            <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#reindexModal" v-on:click="reindexElementType='table';reindexElementName=table.name;checkSession($event)">
              REINDEX
            </button>
            {% include includes/reindex_modal.html %}
            {% include includes/scheduled_reindex.html %}
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col">
          <p class="text-danger" v-if="table.n_mod_since_analyze / table.n_live_tup > .5">
            <i class="fa fa-exclamation-triangle"></i>The number of modified rows since last analyze is high, you should consider lauching an ANALYZE
            <br>
            <span class="pl-4 text-muted margin-left">
              Out of date analyzes can result in stats not being accurate, which eventually leads to slow queries.
            </span>
          </p>
          <p class="text-danger" v-if="table.n_dead_tup / table.n_live_tup > .1">
            <i class="fa fa-exclamation-triangle"></i>The number of dead tuples is high, you should consider running a VACUUM.
            <br>
            <span class="pl-4 text-muted margin-left">
              Dead tuples waste space and slow down queries.
            </span>
          </p>
          <p class="text-danger" v-if="table.bloat_bytes / table.table_bytes > .5">
            <i class="fa fa-exclamation-triangle"></i>Overall table bloat is high. You should consider running a Full VACUUUM.
            <br>
            <span class="pl-4 text-muted margin-left">
              Table bloat wastes space and slows down queries.
            </span>
          </p>
          <p class="text-danger" v-if="table.index_bloat_bytes / table.index_bytes > .5">
            <i class="fa fa-exclamation-triangle"></i>Overall index bloat is high. You should consider running a Full VACUUUM or REINDEX.
            <br>
            <span class="pl-4 text-muted margin-left">
              Index bloat wastes space and slows down queries.
            </span>
          </p>
        </div>
      </div>
      <div class="d-flex">
        <h4>
          Indexes <span class="text-muted small">({{! table.indexes.length }})</span>
        </h4>
        <div class="ml-auto">
          <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Sort by {{! indexSortCriterias[indexSortCriteria][0] }}</button>
          <div class="dropdown-menu">
            <h6 class="dropdown-header">Sort by:</h6>
            <a v-for="(criteria, key) in indexSortCriterias" class="dropdown-item" href="#" v-on:click="indexSortBy(key, criteria[1])">
              <i :class="['fa fa-fw', {'fa-check': indexSortCriteria == key}]"></i>
              {{! criteria[0] }}
            </a>
          </div>
        </div>
      </div>
      {% include includes/reindex_modal.html %}
      <table class="table table-sm table-query table-striped table-bordered">
        <tbody>
          <tr v-for="index in indexesSorted">
            <td>
              <strong>{{! index.name }}</strong>
              <small>
                ({{! index.type }})
              </small>
              <span v-if="index.tablespace">
                <em class="text-muted small">in </em>
                {{! index.tablespace }}
              </span>
            </td>
            <td class="text-right align-middle">
              <span :class="[indexSortCriteria == 'total_bytes' ? 'font-weight-bold' : '']">
              {{! index.total_size }}
              </span>
              <small style="min-width: 70px;" :class="['d-inline-block', indexSortCriteria == 'bloat_ratio' ? 'font-weight-bold' : 'text-muted']">
                <template v-if="index.bloat_bytes">
                  Bloat: {{! index.bloat_ratio.toFixed(1) }}%
                </template>
              </small>
            </td>
            <td class="align-middle text-right">
              <span class="badge badge-secondary" v-if="index.scans">
                {{! index.scans }} scans
              </span>
            </td>
            <td class="query" width="80%">
              <pre><code class="sql">{{! index.def }}</code></pre>
            </td>
            <td class="align-middle" width="5%">
              <button class="btn btn-outline-secondary btn-sm py-0" data-toggle="modal" data-target="#reindexModal" v-on:click="reindexElementType='index';reindexElementName=index.name;checkSession($event)">Reindex</button>
              <ul class="list list-unstyled mb-0" v-if="scheduledReindexes.length > 0">
                <li v-for="scheduledReindex in scheduledReindexes" v-if="scheduledReindex.index == index.name">
                  <template v-if="scheduledReindex.status == 'todo'">
                    <em v-if="scheduledReindex.status == 'todo'">
                      <span class="text-muted" :title="scheduledReindex.datetime.toString()"><i class="fa fa-clock-o"></i> {{! scheduledReindex.datetime | relative_time(false) }}</span>
                    </em>
                    <button class="btn btn-link py-0" v-on:click="cancelReindex(scheduledReindex.id)" v-if="scheduledReindex.status == 'todo'">Cancel</button>
                  </template>
                  <template v-else-if="scheduledReindex.status == 'doing'">
                    <em class="text-muted">
                      <img id="loadingIndicator" src="/images/ring-alt.svg" class="fa-fw">
                      in progress
                    </em>
                  </template>
                  <template v-else-if="scheduledReindex.status == 'canceled'">
                    <em class="text-muted">canceled</em>
                  </template>
                  <template v-else>
                    <em class="text-muted">{{! scheduledReindex.status }}</em>
                  </template>
                </li>
              </ul>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  
  <script src="/js/lodash.min.js"></script>
  <script src="/js/moment.min.js"></script>
  <script src="/js/highlightjs/highlight.pack.js"></script>
  <script src="/js/vue.min.js"></script>
  <script src="/js/maintenance/vue.filter.relative-time.js"></script>
  <script src="/js/maintenance/vue.size-distribution-bar.js"></script>
  <script src="/js/daterangepicker.js"></script>
  <script src="/js/maintenance/temboard.maintenance.errors.js"></script>
  <script src="/js/maintenance/temboard.maintenance.table.js"></script>
  <script>
  var apiUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance/{{ database }}/schema/{{ schema }}/table/{{ table }}';
  var schemaApiUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance/{{ database }}/schema/{{ schema }}';
  var maintenanceBaseUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance';
  var agentLoginUrl = '/server/{{ instance.agent_address }}/{{ instance.agent_port }}/login';
  var xsession = {{ json_encode(xsession) }};
  </script>
  
  {% end %}
  