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>