From 202599aaeb157ce4d298b7e859289b984e76ab2c Mon Sep 17 00:00:00 2001
From: Tom Wiesing
-
- -{{ end }} - {{ define "content" }}-
- -{{ end }} - {{ define "content" }}-
- -{{ end }} +{{ define "title" }}Users{{ end }} {{ define "content" }} diff --git a/internal/dis/component/control/admin/index.go b/internal/dis/component/control/admin/index.go index 0f96525..f735eff 100644 --- a/internal/dis/component/control/admin/index.go +++ b/internal/dis/component/control/admin/index.go @@ -87,8 +87,14 @@ type indexContext struct { } func (admin *Admin) index(r *http.Request) (idx indexContext, err error) { - admin.Dependencies.Custom.Update(&idx, r, []component.MenuItem{ - {Title: "Admin", Path: "/admin/"}, + admin.Dependencies.Custom.Update(&idx, r, custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "Admin", Path: "/admin/"}, + }, + Actions: []component.MenuItem{ + {Title: "Users", Path: "/admin/users/"}, + {Title: "Components", Path: "/admin/components/", Priority: component.SmallButton}, + }, }) idx.Distillery, idx.Instances, err = admin.Status(r.Context(), true) return diff --git a/internal/dis/component/control/admin/instance.go b/internal/dis/component/control/admin/instance.go index 5d688f6..1a71e03 100644 --- a/internal/dis/component/control/admin/instance.go +++ b/internal/dis/component/control/admin/instance.go @@ -32,9 +32,15 @@ type instanceContext struct { func (admin *Admin) instance(r *http.Request) (is instanceContext, err error) { slug := httprouter.ParamsFromContext(r.Context()).ByName("slug") - admin.Dependencies.Custom.Update(&is, r, []component.MenuItem{ - {Title: "Admin", Path: "/admin/"}, - {Title: "Instance", Path: template.URL("/admin/instance/" + slug)}, + admin.Dependencies.Custom.Update(&is, r, custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "Admin", Path: "/admin/"}, + {Title: "Instance", Path: template.URL("/admin/instance/" + slug)}, + }, + Actions: []component.MenuItem{ + {Title: "Grants", Path: template.URL("/admin/grants/" + slug)}, + {Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}, + }, }) // find the instance itself! diff --git a/internal/dis/component/control/admin/users.go b/internal/dis/component/control/admin/users.go index 266087e..f57ad8f 100644 --- a/internal/dis/component/control/admin/users.go +++ b/internal/dis/component/control/admin/users.go @@ -32,9 +32,11 @@ type userContext struct { } func (admin *Admin) users(r *http.Request) (uc userContext, err error) { - admin.Dependencies.Custom.Update(&uc, r, []component.MenuItem{ - {Title: "Admin", Path: "/admin/"}, - {Title: "Users", Path: "/admin/users/"}, + admin.Dependencies.Custom.Update(&uc, r, custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "Admin", Path: "/admin/"}, + {Title: "Users", Path: "/admin/users/"}, + }, }) uc.Error = r.URL.Query().Get("error") @@ -62,10 +64,15 @@ type createUserResult struct { func (admin *Admin) createUser(ctx context.Context) http.Handler { userCreateTemplate := admin.Dependencies.Custom.Template(userCreateTemplate) - crumbs := []component.MenuItem{ - {Title: "Admin", Path: "/admin/"}, - {Title: "Users", Path: "/admin/users"}, - {Title: "Create", Path: "/admin/users/create"}, + gaps := custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "Admin", Path: "/admin/"}, + {Title: "Users", Path: "/admin/users"}, + {Title: "Create", Path: "/admin/users/create"}, + }, + Actions: []component.MenuItem{ + {Title: "Create New", Path: "/admin/users/create/"}, + }, } return &httpx.Form[createUserResult]{ @@ -78,7 +85,7 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler { RenderTemplate: userCreateTemplate, RenderTemplateContext: func(ctx httpx.FormContext, r *http.Request) any { - return admin.Dependencies.Custom.NewForm(ctx, r, crumbs) + return admin.Dependencies.Custom.NewForm(ctx, r, gaps) }, Validate: func(r *http.Request, values map[string]string) (cu createUserResult, err error) { diff --git a/internal/dis/component/control/home/public.go b/internal/dis/component/control/home/public.go index bfdf910..a274a5b 100644 --- a/internal/dis/component/control/home/public.go +++ b/internal/dis/component/control/home/public.go @@ -25,8 +25,10 @@ type publicContext struct { } func (home *Home) publicHandler(ctx context.Context) http.Handler { - crumbs := []component.MenuItem{ - {Title: "WissKI Distillery", Path: "/"}, + gaps := custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "WissKI Distillery", Path: "/"}, + }, } return httpx.HTMLHandler[publicContext]{ Handler: func(r *http.Request) (pc publicContext, err error) { @@ -35,7 +37,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler { return pc, httpx.ErrNotFound } - home.Dependencies.Custom.Update(&pc, r, crumbs) + home.Dependencies.Custom.Update(&pc, r, gaps) pc.Instances = home.homeInstances.Get(nil) pc.SelfRedirect = home.Config.SelfRedirect.String() diff --git a/internal/dis/component/control/legal/legal.go b/internal/dis/component/control/legal/legal.go index 727641b..fde1f1b 100644 --- a/internal/dis/component/control/legal/legal.go +++ b/internal/dis/component/control/legal/legal.go @@ -59,8 +59,10 @@ type legalContext struct { } func (legal *Legal) context(r *http.Request) (lc legalContext, err error) { - legal.Dependencies.Custom.Update(&lc, r, []component.MenuItem{ - {Title: "Legal", Path: "/legal/"}, + legal.Dependencies.Custom.Update(&lc, r, custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "Legal", Path: "/legal/"}, + }, }) lc.LegalNotices = cli.LegalNotices diff --git a/internal/dis/component/control/news/news.go b/internal/dis/component/control/news/news.go index c270ce8..677d703 100644 --- a/internal/dis/component/control/news/news.go +++ b/internal/dis/component/control/news/news.go @@ -123,8 +123,10 @@ type newsContext struct { // HandleRoute returns the handler for the requested path func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) { - crumbs := []component.MenuItem{ - {Title: "News", Path: "/news/"}, + gaps := custom.BaseContextGaps{ + Crumbs: []component.MenuItem{ + {Title: "News", Path: "/news/"}, + }, } items, itemsErr := Items() @@ -134,7 +136,7 @@ func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, e return httpx.HTMLHandler[newsContext]{ Handler: func(r *http.Request) (nc newsContext, err error) { - news.Dependencies.Custom.Update(&nc, r, crumbs) + news.Dependencies.Custom.Update(&nc, r, gaps) nc.Items, err = items, itemsErr return diff --git a/internal/dis/component/control/static/custom/context.go b/internal/dis/component/control/static/custom/context.go index 612931e..01aa3cf 100644 --- a/internal/dis/component/control/static/custom/context.go +++ b/internal/dis/component/control/static/custom/context.go @@ -27,8 +27,8 @@ type BaseContext struct { GeneratedAt time.Time // time this page was generated at // Menu and breadcrumbs - Menu []component.MenuItem - Crumbs []component.MenuItem + Menu []component.MenuItem + BaseContextGaps CSRF template.HTML // CSRF Field } @@ -43,12 +43,24 @@ const ( requestNilError template.HTML = errorPrefix + "BaseContext.use() called with nil request" + errorSuffix
)
+type BaseContextGaps struct {
+ Crumbs []component.MenuItem
+ Actions []component.MenuItem
+}
+
+func (bcg BaseContextGaps) Clone() BaseContextGaps {
+ return BaseContextGaps{
+ Crumbs: slices.Clone(bcg.Crumbs),
+ Actions: slices.Clone(bcg.Actions),
+ }
+}
+
// Use updates this context to use the values from the given base.
//
// The given request *must not* be nil.
//
// For convenience the passed context is also returned.
-func (tc *BaseContext) use(custom *Custom, r *http.Request, crumbs []component.MenuItem) *BaseContext {
+func (tc *BaseContext) use(custom *Custom, r *http.Request, gaps BaseContextGaps) *BaseContext {
// tc.custom = custom
tc.inited = true
tc.requestWasNil = r == nil
@@ -65,7 +77,7 @@ func (tc *BaseContext) use(custom *Custom, r *http.Request, crumbs []component.M
tc.Menu = custom.BuildMenu(r)
// build the breadcrumbs
- tc.Crumbs = slices.Clone(crumbs)
+ tc.BaseContextGaps = gaps.Clone()
last := len(tc.Crumbs) - 1
for i := range tc.Crumbs {
tc.Crumbs[i].Active = i == last
@@ -86,9 +98,9 @@ func (bc BaseContext) DoInitCheck() template.HTML {
}
// NewForm is like New, but returns a new BaseFormContext
-func (custom *Custom) NewForm(context httpx.FormContext, r *http.Request, crumbs []component.MenuItem) (ctx BaseFormContext) {
+func (custom *Custom) NewForm(context httpx.FormContext, r *http.Request, bcg BaseContextGaps) (ctx BaseFormContext) {
ctx.FormContext = context
- ctx.use(custom, r, crumbs)
+ ctx.use(custom, r, bcg)
return
}
@@ -96,11 +108,11 @@ func (custom *Custom) NewForm(context httpx.FormContext, r *http.Request, crumbs
//
// Assumes that context is a pointer to a struct type.
// If this is not the case, might call panic().
-func (custom *Custom) Update(context any, r *http.Request, crumbs []component.MenuItem) *BaseContext {
+func (custom *Custom) Update(context any, r *http.Request, bcg BaseContextGaps) *BaseContext {
ctx := reflect.ValueOf(context).
Elem().FieldByName(baseContextName).Addr().
Interface().(*BaseContext)
- ctx.use(custom, r, crumbs)
+ ctx.use(custom, r, bcg)
return ctx
}
diff --git a/internal/dis/component/control/static/templates/_anal.html b/internal/dis/component/control/static/templates/_anal.html
index ec7160b..5d8af5a 100644
--- a/internal/dis/component/control/static/templates/_anal.html
+++ b/internal/dis/component/control/static/templates/_anal.html
@@ -1,5 +1,5 @@