Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Say what each change is waiting for in the list

7cc36ba0f4ba96d3f4938b13758b2cc20c22375a · Keenan Nemetz · 4d ago · parent 946d2fd4

Say what each change is waiting for in the list

A change spends most of its life in states "open" cannot describe: held for a
maintainer to allow CI, running its checks, failed, waiting for a reviewer,
conflicting with its base. The list now says which of those it is, in one
column, with a tooltip that explains the label.

The answer comes from facts a list can afford: the approvals it already counts,
one batched run-queue query for every head on the page, the contributor
allowance (one ref listing, not one per row), and — only for a change that would
otherwise read as ready — whether it still merges into its base. The full
landing plan stays on the detail page.

The rest of the row follows the issue list: the author and opening moved under
the title, the comment count sits at the end of that line, and the last column
is "Updated", the newest commit over the request's directory. The list sorts by
it. The separate Author, Approvals and Age columns are gone.

Closes #194

server/web/requests.go +27−2

@@ -36,9 +36,12 @@ type requestRow struct {
36 36 Head string
37 37 HeadRef string
38 38 Created time.Time
39 Updated time.Time
39 40 CommentCount int
40 41 Number int
41 42 Current int
43 Required int
44 Status changeStatus
42 45 }
43 46
44 47 // requestFormData is shared by the list page's New change button and the
@@ -176,6 +179,11 @@ func (w *Web) requestList(r *http.Request, m *repo.Meta, state, query string) ([
176 179 return nil, counts, err
177 180 }
178 181 rows := make([]requestRow, 0, len(list))
182 acl, _ := m.ACL()
183 required := 0
184 if acl != nil {
185 required = acl.RequiredApprovals()
186 }
179 187 for _, req := range list {
180 188 switch req.State {
181 189 case "open":
@@ -189,10 +197,17 @@ func (w *Web) requestList(r *http.Request, m *repo.Meta, state, query string) ([
189 197 if query != "" && !strings.Contains(strings.ToLower(req.Title+"\n"+req.Description+"\n"+req.Author), strings.ToLower(query)) {
190 198 continue
191 199 }
200 current := 0
201 for _, a := range req.Approvals {
202 if a.Head == req.Head && a.Base == req.Base && acl != nil && acl.EligibleApprover(a.Principal) {
203 current++
204 }
205 }
192 206 rows = append(rows, requestRow{
193 207 ID: req.ID, Title: req.Title, State: req.State, Author: req.Author,
194 208 Base: req.Base, Head: req.Head, HeadRef: req.HeadRef, Created: req.Created,
195 CommentCount: len(req.Comments),
209 Updated: req.Created, CommentCount: len(req.Comments),
210 Current: current, Required: required,
196 211 })
197 212 }
198 213 counts[2] = len(list) - counts[0] - counts[1]
@@ -201,8 +216,12 @@ func (w *Web) requestList(r *http.Request, m *repo.Meta, state, query string) ([
201 216 if (rows[i].State == "open") != (rows[j].State == "open") {
202 217 return rows[i].State == "open"
203 218 }
219 if !rows[i].Updated.Equal(rows[j].Updated) {
220 return rows[i].Updated.After(rows[j].Updated)
221 }
204 222 return rows[i].ID > rows[j].ID
205 223 })
224 w.decorateChangeStatuses(m, rows)
206 225 return rows, counts, nil
207 226 }
208 227
@@ -227,6 +246,10 @@ func (w *Web) requestList(r *http.Request, m *repo.Meta, state, query string) ([
227 246 return nil, counts, err
228 247 }
229 248 acl, _ := m.ACL()
249 required := 0
250 if acl != nil {
251 required = acl.RequiredApprovals()
252 }
230 253 rows := make([]requestRow, 0, len(list))
231 254 for _, row := range list {
232 255 current := 0
@@ -238,9 +261,11 @@ func (w *Web) requestList(r *http.Request, m *repo.Meta, state, query string) ([
238 261 rows = append(rows, requestRow{
239 262 ID: row.ID, Title: row.Title, State: row.State, Author: row.Author,
240 263 Base: row.Base, Head: row.Head, HeadRef: row.HeadRef, Created: row.Created,
241 CommentCount: row.CommentCount, Number: row.Number, Current: current,
264 Updated: row.Updated, CommentCount: row.CommentCount, Number: row.Number,
265 Current: current, Required: required,
242 266 })
243 267 }
268 w.decorateChangeStatuses(m, rows)
244 269 return rows, counts, nil
245 270 }
246 271