<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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. -->
<template>
  <div class="rk-trace-t flex-v">
    <div class="rk-trace-t-tool flex-h">
      <RkPage
        :currentSize="15"
        :currentPage="rocketTrace.traceForm.paging.pageNum"
        @changePage="page"
        :total="rocketTrace.traceTotal"
      />
      <select class="grey" @change="changeSort" :value="rocketTrace.traceForm.queryOrder">
        <option value="BY_START_TIME">{{ $t('startTime') }}</option>
        <option value="BY_DURATION">{{ $t('duration') }}</option>
      </select>
    </div>
    <div class="rk-trace-t-loading" v-show="loading">
      <svg class="icon loading">
        <use xlink:href="#spinner"></use>
      </svg>
    </div>
    <div class="rk-trace-t-wrapper scroll_hide">
      <table class="rk-trace-t">
        <tr class="rk-trace-tr cp" v-for="(i, index) in rocketTrace.traceList" @click="selectTrace(i)" :key="index">
          <td
            class="rk-trace-td"
            :class="{
              'rk-trace-success': !i.isError,
              'rk-trace-error': i.isError,
              selected: selectedKey == i.key,
            }"
          >
            <div
              class="ell mb-5"
              :class="{
                blue: !i.isError,
                red: i.isError,
              }"
            >
              <span class="b">{{ i.endpointNames[0] }}</span>
            </div>
            <div class="grey ell sm">
              <span class="rk-tag mr-10 sm">{{ i.duration }} ms</span>{{ parseInt(i.start) | dateformat }}
            </div>
          </td>
        </tr>
      </table>
    </div>
  </div>
</template>

<script lang="ts">
  import { Component, Vue, Watch } from 'vue-property-decorator';
  import { Action, Mutation, State } from 'vuex-class';
  import { State as traceState } from '@/store/modules/trace/index';

  @Component
  export default class TraceTable extends Vue {
    @State('rocketTrace') private rocketTrace!: traceState;
    @Mutation('rocketTrace/SET_TRACE_FORM_ITEM')
    private SET_TRACE_FORM_ITEM: any;
    @Mutation('rocketTrace/SET_CURRENT_TRACE') private SET_CURRENT_TRACE: any;
    @Mutation('rocketTrace/SET_DEFAULT_EMPTY_TRACE')
    private SET_DEFAULT_EMPTY_TRACE: any;
    @Action('rocketTrace/GET_TRACELIST') private GET_TRACELIST: any;
    @Action('rocketTrace/GET_TRACE_SPANS') private GET_TRACE_SPANS: any;
    private loading: boolean = false;
    private selectedKey: string = '';
    @Watch('rocketTrace.traceList')
    private onTraceListChange() {
      if (this.rocketTrace.traceList && this.rocketTrace.traceList.length > 0) {
        this.selectTrace(this.rocketTrace.traceList[0]);
      }
      if (this.rocketTrace.traceList && this.rocketTrace.traceList.length === 0) {
        this.SET_DEFAULT_EMPTY_TRACE();
      }
    }
    private selectTrace(i: any) {
      this.SET_CURRENT_TRACE(i);
      this.selectedKey = i.key;
      this.$eventBus.$emit('TRACE-TABLE-LOADING');
      this.$eventBus.$emit('TRACE-LIST-LOADING');
      if (i.traceIds.length) {
        this.GET_TRACE_SPANS({ traceId: i.traceIds[0] });
      }
    }
    private changeSort(e: any) {
      this.SET_TRACE_FORM_ITEM({
        type: 'queryOrder',
        data: e.target.options[e.target.selectedIndex].value,
      });
      this.SET_TRACE_FORM_ITEM({
        type: 'paging',
        data: { pageNum: 1, pageSize: 15, needTotal: true },
      });
      this.GET_TRACELIST();
    }
    private page(p: number) {
      this.loading = true;
      this.SET_TRACE_FORM_ITEM({
        type: 'paging',
        data: { pageNum: p, pageSize: 15, needTotal: true },
      });
      this.GET_TRACELIST().then(() => {
        this.loading = false;
      });
    }
    private created() {
      this.$eventBus.$on('SET_LOADING_TRUE', this, (cb: any) => {
        this.loading = true;
        if (cb) {
          cb();
        }
      });
      this.$eventBus.$on('SET_LOADING_FALSE', this, () => {
        this.loading = false;
      });
    }
  }
</script>
<style lang="scss">
  .rk-trace-t-tool {
    flex-shrink: 0;
    background-color: rgba(196, 200, 225, 0.2);
    justify-content: space-between;
    padding-right: 5px;
    select {
      background-color: rgba(0, 0, 0, 0);
      outline: 0;
      border-style: unset;
      margin: 0 10px;
    }
    padding-top: 1px;
    border-bottom: 1px solid #c1c5ca41;
    border-right: 1px solid #c1c5ca41;
    height: 35px;
  }
  .rk-trace-t-wrapper {
    overflow: auto;
    flex-grow: 1;
    border-right: 1px solid rgba(0, 0, 0, 0.1);
  }
  .rk-trace-t-loading {
    text-align: center;
    position: absolute;
    width: 100%;
    height: 70px;
    margin-top: 40px;
    line-height: 88px;
    overflow: hidden;
    .icon {
      width: 30px;
      height: 30px;
    }
  }
  .rk-trace-t {
    width: 100%;
    border-spacing: 0;
    table-layout: fixed;
    flex-grow: 1;
    position: relative;
  }
  .rk-trace-tr {
    &:hover {
      background-color: rgba(0, 0, 0, 0.04);
    }
  }
  .rk-trace-td {
    padding: 8px 10px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    &.selected {
      background-color: #ededed;
    }
  }
  .rk-trace-success {
    border-left: 4px solid rgba(46, 47, 51, 0.1);
  }
  .rk-trace-warning {
    border-left: 4px solid #fbb03b;
  }
  .rk-trace-error {
    border-left: 4px solid #e54c17;
  }
  .rk-tag {
    border-radius: 4px;
    padding-right: 5px;
    padding-left: 5px;
    background-color: #40454e;
    color: #eee;
  }
</style>
