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

     1  <template>
     2    <div>
     3      <v-list-item>
     4        <v-list-item-avatar>
     5          <v-icon size="28">{{avatar}}</v-icon>
     6        </v-list-item-avatar>
     7        <v-list-item-content>
     8          <v-list-item-title>{{name}}</v-list-item-title>
     9          <v-list-item-subtitle>{{repoURL}}</v-list-item-subtitle>
    10        </v-list-item-content>
    11        <v-list-item-action>
    12          <v-btn
    13            ref="activate"
    14            small
    15            v-if="!activated"
    16            :loading="loading"
    17            @click="activateRepository"
    18            class="d-none d-md-flex"
    19          >Activate</v-btn>
    20          <v-btn
    21            ref="activate"
    22            v-if="!activated"
    23            :loading="loading"
    24            @click="activateRepository"
    25            class="d-flex d-md-none align-center"
    26            icon
    27          >
    28            <v-icon>mdi-plus-box-multiple</v-icon>
    29          </v-btn>
    30          <v-btn ref="goto" icon :to="routeLink" v-if="activated">
    31            <v-icon color="grey lighten-1">mdi-chevron-right</v-icon>
    32          </v-btn>
    33        </v-list-item-action>
    34      </v-list-item>
    35      <v-snackbar v-model="showSnackbar">
    36        {{ error }}
    37        <template v-slot:action="{ attrs }">
    38          <v-btn color="pink" text v-bind="attrs" @click="showSnackbar = undefined">Close</v-btn>
    39        </template>
    40      </v-snackbar>
    41    </div>
    42  </template>
    43  
    44  <script lang="ts">
    45  import { Component, Prop, Watch } from 'vue-property-decorator';
    46  import { AxiosResponse } from 'axios';
    47  import Vue from '@/vue';
    48  
    49  @Component({
    50    name: 'repo-list-item'
    51  })
    52  export default class RepoListItem extends Vue {
    53    /**
    54     * repository to show in this item
    55     */
    56    @Prop(Object) readonly repo: Repository | undefined;
    57  
    58    protected loading = false;
    59    protected activated: boolean;
    60    protected error = '';
    61    protected showSnackbar: boolean;
    62  
    63    constructor() {
    64      super();
    65      this.activated = false;
    66      this.showSnackbar = false;
    67    }
    68  
    69    @Watch('repo')
    70    onRepoChanged() {
    71      this.setActivated();
    72    }
    73  
    74    mounted() {
    75      this.setActivated();
    76    }
    77  
    78    get avatar(): string {
    79      switch (this.repo?.SCM) {
    80        case 'github': {
    81          return 'mdi-github';
    82        }
    83        case 'gitea': {
    84          return '$vuetify.icons.gitea';
    85        }
    86        case 'gitlab': {
    87          return 'mdi-gitlab';
    88        }
    89        default: {
    90          return 'mdi-source-repository';
    91        }
    92      }
    93    }
    94  
    95    get base(): string {
    96      return this.$store.state.base;
    97    }
    98  
    99    get name(): string {
   100      return this.repo ? this.repo.Name : '';
   101    }
   102  
   103    get repoURL(): string {
   104      return this.repo ? this.repo.URL : '';
   105    }
   106  
   107    get routeLink(): string {
   108      if (
   109        this.repo === undefined ||
   110        this.repo.Name === undefined ||
   111        this.repo.NameSpace === undefined
   112      ) {
   113        return '/';
   114      }
   115      return `/report/${this.repo.SCM}/${this.repo.NameSpace}/${this.repo.Name}`;
   116    }
   117  
   118    private createRepositoryIfNotExists(): Promise<void | AxiosResponse> {
   119      if (this.repo === undefined) {
   120        return Promise.reject(new Error('repository is undefined'));
   121      }
   122      const { SCM: scm, NameSpace: namespace, Name: name, URL: url } = this.repo;
   123      return this.$http
   124        .get(`${this.base}/api/v1/repos/${scm}/${namespace}/${name}`)
   125        .catch(reason => {
   126          if (reason.response.status === 404) {
   127            return this.$http.post(`${this.base}/api/v1/repos`, {
   128              name: name,
   129              namespace: namespace,
   130              scm: scm,
   131              url: url
   132            });
   133          }
   134        });
   135    }
   136  
   137    private showError(msg: string) {
   138      this.error = msg;
   139      this.showSnackbar = true;
   140    }
   141  
   142    activateRepository() {
   143      if (this.repo !== undefined) {
   144        this.loading = true;
   145        const { SCM: scm, NameSpace: namespace, Name: name } = this.repo;
   146        this.createRepositoryIfNotExists()
   147          .then(() => {
   148            return this.$http
   149              .patch(
   150                `${this.base}/api/v1/repos/${scm}/${namespace}/${name}/report`
   151              )
   152              .then(() => {
   153                this.activated = true;
   154              });
   155          })
   156          .catch(reason => {
   157            this.showError(this.$httpError(reason).message);
   158          })
   159          .finally(() => {
   160            this.loading = false;
   161          });
   162      }
   163    }
   164  
   165    setActivated() {
   166      this.activated =
   167        this.repo !== undefined &&
   168        this.repo.ReportID !== undefined &&
   169        this.repo.ReportID !== '';
   170    }
   171  }
   172  </script>
   173  
   174  <style lang="scss" scoped>
   175  </style>>
   176  
   177  <docs>
   178  
   179  ### Examples
   180  
   181  ```[import](./__examples__/RepoListItem.vue)
   182  ```
   183  
   184  </docs>