github.com/covergates/covergates@v0.2.2-0.20201009050117-42ef8a19fb95/web/src/components/ReportFiles.vue (about)

     1  <template>
     2    <v-container>
     3      <v-sheet>
     4        <v-text-field
     5          v-model="searchText"
     6          append-icon="mdi-magnify"
     7          label="Search"
     8          single-line
     9          outlined
    10          dense
    11          :rounded="false"
    12          color="accent"
    13          hide-details
    14        ></v-text-field>
    15        <v-data-table
    16          class="rounded-t"
    17          :items="fileInfos"
    18          item-key="name"
    19          :headers="headers"
    20          :header-props="{sortIcon: 'mdi-chevron-up'}"
    21          :fixed-header="true"
    22          sort-by="coverage"
    23          :sort-desc="true"
    24          :search="searchText"
    25        >
    26          <template v-slot:item.name="{ item }">
    27            <span class="file-icon fiv-viv mr-5" :class="[fileIcon(item.name)]"></span>
    28            <router-link :append="true" :to="fileLink(item)">{{item.name}}</router-link>
    29          </template>
    30        </v-data-table>
    31      </v-sheet>
    32    </v-container>
    33  </template>
    34  
    35  <script lang="ts">
    36  import { Component, Mixins } from 'vue-property-decorator';
    37  import { Location } from 'vue-router';
    38  import Vue from '@/vue';
    39  import ReportMixin from '@/mixins/report';
    40  
    41  type FileInfo = {
    42    name: string;
    43    coverage: number;
    44    hits: number;
    45  };
    46  
    47  @Component
    48  export default class ReportFiles extends ((Mixins(ReportMixin) as typeof Vue) &&
    49    ReportMixin) {
    50    /**
    51     * Table Headers
    52     */
    53    headerClass = 'text-subtitle-1 align-center accent white--text';
    54    headers = [
    55      {
    56        text: 'File Path',
    57        align: 'start',
    58        value: 'name',
    59        class: this.headerClass
    60      },
    61      {
    62        text: 'Hit Lines',
    63        value: 'hits',
    64        width: '150px',
    65        class: this.headerClass
    66      },
    67      {
    68        text: 'Coverage',
    69        value: 'coverage',
    70        width: '150px',
    71        class: this.headerClass
    72      }
    73    ];
    74  
    75    searchText = '';
    76  
    77    get report(): Report | undefined {
    78      return this.$store.state.report.current;
    79    }
    80  
    81    get fileInfos(): FileInfo[] {
    82      if (!this.report) {
    83        return [];
    84      }
    85      const info = {} as { [key: string]: FileInfo };
    86      if (this.report.files) {
    87        for (const file of this.report.files) {
    88          info[file] = {
    89            name: file,
    90            coverage: 0,
    91            hits: 0
    92          };
    93        }
    94      }
    95      for (const name in this.$sourceFiles) {
    96        const file = this.$sourceFiles[name];
    97        const coverage = Math.round(file.StatementCoverage * 10000) / 100;
    98        const hitLine = file.StatementHits.filter(hit => {
    99          return hit.Hits > 0;
   100        }).length;
   101        if (info[file.Name]) {
   102          info[file.Name].coverage = coverage;
   103          info[file.Name].hits = hitLine;
   104        } else {
   105          info[file.Name] = {
   106            name: file.Name,
   107            coverage: coverage,
   108            hits: hitLine
   109          };
   110        }
   111      }
   112      return Object.values(info).sort((a, b) => {
   113        return a.name > b.name ? 1 : -1;
   114      });
   115    }
   116  
   117    fileIcon(name: string): string {
   118      const ext = name.split('.').pop();
   119      return `fiv-icon-${ext}`;
   120    }
   121  
   122    fileLink(file: FileInfo): Location {
   123      return {
   124        path: file.name,
   125        query: this.$route.query
   126      };
   127    }
   128  }
   129  </script>
   130  
   131  <style lang="scss" scoped>
   132  @import '@/assets/styles/variables';
   133  
   134  ::v-deep table {
   135    border-collapse: collapse !important;
   136  }
   137  
   138  .file-icon {
   139    font-size: 20px;
   140  }
   141  </style>