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.

Split repository settings into tabs

e189a23e457b6aa01a35a4586586713cdc2d426d · Keenan Nemetz · 23h ago · parent 87ebcc5a

Split repository settings into tabs

One page held four audiences and ten forms. Each part is now its own tab:
General for the repository's own fields, Access for the instance-admin
rules, Secrets for the values jobs read, and Danger for rename and delete.
A tab is offered only to the accounts that may use it, and a viewer with one
tab gets no row at all. The Access and Secrets tabs, and the failures on
each, keep their own URLs so a redirect and an error land where the form was;
the Access and Secrets fragments survive as deep links.

server/web/admin_access.go +8−6

@@ -1,14 +1,15 @@
1 1 package web
2 2
3 3 // The instance-admin half of a repository's Settings page: the access rules, the
4 // review policy, and which accounts' CI results count as checks.
4 // review policy, and which accounts' CI results count as checks. It is the Access
5 // tab.
5 6 //
6 7 // It is a separate file from settings.go because it is a separate rule and a
7 8 // separate audience. A repository admin owns the description, the default branch
8 9 // and whether the repository is public; an instance admin owns who may do what in
9 // it. Both halves render on one page because that is where an operator looks, but
10 // an instance admin who is not a repository admin sees only this section, and the
11 // page says so.
10 // it. Both halves are tabs of one page because that is where an operator looks; the
11 // Access tab is only in the row for an instance admin, and a page whose only tab is
12 // this one says that the repository's details stay with its admins.
12 13
13 14 import (
14 15 "net/http"
@@ -155,7 +156,7 @@ func (w *Web) SaveRepositoryAccess(rw http.ResponseWriter, r *http.Request) {
155 156 }
156 157 }
157 158 w.audit("web.admin.acl", pr.account.Name, m.Name, "")
158 http.Redirect(rw, r, "/r/"+m.Name+"/settings?saved=access#access", http.StatusSeeOther)
159 http.Redirect(rw, r, "/r/"+m.Name+"/settings?tab=access&saved=access#access", http.StatusSeeOther)
159 160 }
160 161
161 162 // AddRepositoryAccess grants one account a repository role and saves
@@ -209,13 +210,14 @@ func (w *Web) AddRepositoryAccess(rw http.ResponseWriter, r *http.Request) {
209 210 }
210 211 }
211 212 w.audit("web.admin.acl.add", pr.account.Name, m.Name, acct.Name+"="+role.String())
212 http.Redirect(rw, r, "/r/"+m.Name+"/settings?saved=added#access", http.StatusSeeOther)
213 http.Redirect(rw, r, "/r/"+m.Name+"/settings?tab=access&saved=added#access", http.StatusSeeOther)
213 214 }
214 215
215 216 // accessFailure re-renders the access form with the page's current values and a
216 217 // message, so a rejected role does not throw away the rest of the editor.
217 218 func (w *Web) accessFailure(rw http.ResponseWriter, r *http.Request, ctx *settingsContext, msg string) {
218 219 v := w.settingsView(r, ctx)
220 v.focusTab("access")
219 221 if v.Access == nil {
220 222 v.Access = &accessView{}
221 223 }