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 · 1d 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/secrets.go +4−3

@@ -92,12 +92,12 @@ func (w *Web) DeleteSecret(rw http.ResponseWriter, r *http.Request) {
92 92 }
93 93
94 94 func (w *Web) redirectSecrets(rw http.ResponseWriter, r *http.Request, ctx *settingsContext, saved, deleted string) {
95 target := "/r/" + ctx.m.Name + "/settings#secrets"
95 target := "/r/" + ctx.m.Name + "/settings?tab=secrets#secrets"
96 96 switch {
97 97 case saved != "":
98 target = "/r/" + ctx.m.Name + "/settings?secret_saved=" + url.QueryEscape(saved) + "#secrets"
98 target = "/r/" + ctx.m.Name + "/settings?tab=secrets&secret_saved=" + url.QueryEscape(saved) + "#secrets"
99 99 case deleted != "":
100 target = "/r/" + ctx.m.Name + "/settings?secret_deleted=" + url.QueryEscape(deleted) + "#secrets"
100 target = "/r/" + ctx.m.Name + "/settings?tab=secrets&secret_deleted=" + url.QueryEscape(deleted) + "#secrets"
101 101 }
102 102 http.Redirect(rw, r, target, http.StatusSeeOther)
103 103 }
@@ -106,6 +106,7 @@ func (w *Web) redirectSecrets(rw http.ResponseWriter, r *http.Request, ctx *sett
106 106 // not echoed back: a refused value is not put into the page that just refused it.
107 107 func (w *Web) secretFailure(rw http.ResponseWriter, r *http.Request, ctx *settingsContext, msg string) {
108 108 v := w.settingsView(r, ctx)
109 v.focusTab("secrets")
109 110 v.SecretError = msg
110 111 w.render(rw, "settings", v, http.StatusBadRequest)
111 112 }