7
7
>
8
8
<div class =" status" >
9
9
<p :class =" build.build.status" >{{ build.build.status | formatStatus }}</p >
10
+ <span v-if =" build.status == 'running'" >
11
+ {{ build.build.started*1000 | formatTimeAgo }} ago
12
+ </span >
13
+ <span v-else-if =" build.status != 'pending' " >
14
+ {{ formatBuildDuration(build) }}
15
+ </span >
16
+ <span v-else >
17
+ {{ build.build.created*1000 | formatTimeAgo }} ago
18
+ </span >
10
19
</div >
11
20
<div class =" info" >
12
- <p class =" build-name" ><a :href =" build.git_http_url" target =" _blank" >{{ build.name }}</a ></p >
13
- <p class =" build-desc" >
14
- <a :href =" build.baseurl + '/' + build.slug + '/' +build.build.number" target =" _blank" >{{ build.build.number }}</a >
15
- <template v-if =" build .event == ' pull_request' " >
16
- <a :href =" build.build.link" target =" _blank" class =" droneci-extra-info" >#{{ formatPrId(build.build.link) }}</a > to <span class =" droneci-info-link" >{{ build.build.target }}</span >
17
- </template >
18
- <template v-if =" build .event == ' push' " >
19
- <a :href =" build.build.link" target =" _blank" class =" droneci-extra-info" >push</a > to <span class =" droneci-extra-info" >{{ build.build.target }}</span >
20
- </template >
21
- <template v-else >
22
- <span class =" droneci-extra-info" >{{ build.build.target }}</span >
23
- </template >
24
- <span v-if =" build.status == 'running'" >{{ build.build.started*1000 | formatTimeAgo }}</span >
25
- <span v-else-if =" build.status != 'running' || build.status != 'pending' " >{{ formatBuildDuration(build) }}</span >
26
- <span v-else >Missing Time</span >
27
- </p >
21
+ <div class =" build-name" >
22
+ {{ build.name }}
23
+ <a
24
+ class =" droneci-build-number"
25
+ :href =" build.baseurl + '/' + build.slug + '/' +build.build.number"
26
+ target =" _blank"
27
+ >{{ build.build.number }}</a >
28
+ </div >
29
+ <div class =" build-desc" >
30
+ <span class =" droneci-extra" >
31
+ <template v-if =" build .build .event == ' pull_request' " >
32
+ <a
33
+ :href =" build.build.link"
34
+ target =" _blank"
35
+ class =" droneci-extra-info"
36
+ >#{{ formatPrId(build.build.link) }}</a > to
37
+ </template >
38
+ <template v-else-if =" build .build .event == ' push' " >
39
+ <a
40
+ :href =" build.build.link"
41
+ target =" _blank"
42
+ class =" droneci-extra-info"
43
+ >push</a > to
44
+ </template >
45
+ <a
46
+ :href =" build.git_http_url"
47
+ target =" _blank"
48
+ class =" droneci-extra-info"
49
+ >
50
+ {{ build.build.target }}
51
+ </a >
52
+ </span >
53
+ </div >
28
54
</div >
29
55
</div >
30
56
</div >
@@ -60,9 +86,21 @@ export default {
60
86
},
61
87
computed: {
62
88
/* API endpoint, either for self-hosted or managed instance */
63
- endpoint () {
64
- if (this .options .host ) return ` ${ this .options .host } /api/user/builds` ;
65
- this .error (' Drone CI Host is required' );
89
+ endpointBuilds () {
90
+ if (! this .options .host ) this .error (' drone.ci Host is required' );
91
+ return ` ${ this .options .host } /api/user/builds` ;
92
+ },
93
+ endpointRepoInfo () {
94
+ if (! this .options .host ) this .error (' drone.ci Host is required' );
95
+ return ` ${ this .options .host } /api/repos/${ this .options .repo } ` ;
96
+ },
97
+ endpointRepoBuilds () {
98
+ if (! this .options .host ) this .error (' drone.ci Host is required' );
99
+ return ` ${ this .options .host } /api/repos/${ this .options .repo } /builds` ;
100
+ },
101
+ repo () {
102
+ if (this .options .repo ) return this .options .repo ;
103
+ return false ;
66
104
},
67
105
apiKey () {
68
106
if (! this .options .apiKey ) {
@@ -80,32 +118,47 @@ export default {
80
118
},
81
119
/* Make GET request to Drone CI API endpoint */
82
120
fetchData () {
83
- this .overrideProxyChoice = true ;
84
- const authHeaders = { ' Authorization' : ` Bearer ${ this .apiKey } ` };
85
- this .makeRequest (this .endpoint , authHeaders).then (
86
- (response ) => { this .processData (response); },
87
- );
121
+ const authHeaders = { Authorization: ` Bearer ${ this .apiKey } ` };
122
+ if (this .repo !== false ) {
123
+ this .makeRequest (this .endpointRepoInfo , authHeaders).then (
124
+ (repoInfo ) => {
125
+ this .makeRequest (this .endpointRepoBuilds , authHeaders).then (
126
+ (buildInfo ) => {
127
+ this .processRepoBuilds (repoInfo, buildInfo);
128
+ },
129
+ );
130
+ },
131
+ );
132
+ } else {
133
+ this .makeRequest (this .endpointBuilds , authHeaders).then (
134
+ (response ) => { this .processBuilds (response); },
135
+ );
136
+ }
88
137
},
89
138
/* Assign data variables to the returned data */
90
- processData (data ) {
91
- const results = data .slice (0 , this .options .limit ).map (obj => {
92
- return {... obj, baseurl: this .options .host };
93
- });
139
+ processBuilds (data ) {
140
+ const results = data .slice (0 , this .options .limit )
141
+ .map ((obj ) => ({ ... obj, baseurl: this .options .host }));
142
+ this .builds = results;
143
+ },
144
+ processRepoBuilds (repo , builds ) {
145
+ const results = builds .slice (0 , this .options .limit )
146
+ .map ((obj ) => ({ build: { ... obj }, baseurl: this .options .host , ... repo }));
94
147
this .builds = results;
95
148
},
96
149
infoTooltip (build ) {
97
150
const content = ` <b>Trigger:</b> ${ build .build .event } by ${ build .build .trigger } <br>`
98
151
+ ` <b>Repo:</b> ${ build .slug } <br>`
99
- + ` <b>Branch:</b> ${ build .build .target } <br>`
152
+ + ` <b>Branch:</b> ${ build .build .target } <br>` ;
100
153
return {
101
154
content, html: true , trigger: ' hover focus' , delay: 250 , classes: ' build-info-tt' ,
102
155
};
103
156
},
104
157
formatPrId (link ) {
105
158
return link .split (' /' ).pop ();
106
159
},
107
- formatBuildDuration (build ){
108
- return getTimeDifference (build .build .started * 1000 , build .build .finished * 1000 );
160
+ formatBuildDuration (build ) {
161
+ return getTimeDifference (build .build .started * 1000 , build .build .finished * 1000 );
109
162
},
110
163
},
111
164
};
@@ -115,12 +168,12 @@ export default {
115
168
.droneci-builds-wrapper {
116
169
color : var (--widget-text-color );
117
170
.build-row {
118
- display : flex ;
171
+ display : grid ;
172
+ grid-template-columns : 1fr 2.5fr ;
119
173
justify-content : left ;
120
174
align-items : center ;
121
175
padding : 0.25rem 0 ;
122
176
.status {
123
- min-width : 5rem ;
124
177
font-size : 1rem ;
125
178
font-weight : bold ;
126
179
p {
@@ -131,35 +184,43 @@ export default {
131
184
& .error { color : var (--danger ); }
132
185
& .running { color : var (--neutral ); }
133
186
}
187
+ span {
188
+ font-size : 0.75rem ;
189
+ color : var (--secondary );
190
+ }
134
191
}
135
192
.info {
136
- p .build-name {
193
+ div .build-name {
137
194
margin : 0.25rem 0 ;
138
195
font-weight : bold ;
139
196
color : var (--widget-text-color );
140
197
a , a :hover , a :visited , a :active {
141
198
color : inherit ;
142
199
text-decoration : none ;
143
200
}
201
+ .droneci-build-number ::before {
202
+ content : " #" ;
203
+ }
144
204
}
145
- p .build-desc {
205
+ div .build-desc {
146
206
margin : 0 ;
207
+ font-size : 0.85rem ;
147
208
color : var (--widget-text-color );
148
209
opacity : var (--dimming-factor );
149
210
a , a :hover , a :visited , a :active {
150
211
color : inherit ;
151
212
text-decoration : none ;
152
213
}
153
- .droneci-extra-info {
154
- margin : 0.25em ;
155
- padding : 0.25em ;
156
- background : var (--item-background );
157
- border : 1px solid var (--primary );
158
- border-radius : 5px ;
214
+ .droneci-extra {
215
+ .droneci-extra-info {
216
+ margin : 0.25em ;
217
+ padding : 0em 0.25em ;
218
+ background : var (--item-background );
219
+ border : 1px solid var (--primary );
220
+ border-radius : 5px ;
221
+ }
159
222
}
160
- }
161
- p .build-desc ::before {
162
- content : " #" ;
223
+
163
224
}
164
225
}
165
226
& :not (:last-child ) {
0 commit comments