templates: Add a proper menu and navigation
This commit is contained in:
parent
0bb7f99fa3
commit
a00195be16
76 changed files with 336 additions and 233 deletions
|
|
@ -40,6 +40,7 @@ type Admin struct {
|
|||
var (
|
||||
_ component.DistilleryFetcher = (*Admin)(nil)
|
||||
_ component.Routeable = (*Admin)(nil)
|
||||
_ component.Menuable = (*Admin)(nil)
|
||||
)
|
||||
|
||||
func (admin *Admin) Routes() component.Routes {
|
||||
|
|
@ -50,6 +51,19 @@ func (admin *Admin) Routes() component.Routes {
|
|||
}
|
||||
}
|
||||
|
||||
func (admin *Admin) Menu(r *http.Request) []component.MenuItem {
|
||||
if !admin.Dependencies.Auth.Has(auth.Admin, r) {
|
||||
return nil
|
||||
}
|
||||
return []component.MenuItem{
|
||||
{
|
||||
Title: "Admin",
|
||||
Path: "/admin/",
|
||||
Priority: component.MenuAdmin,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (admin *Admin) HandleRoute(ctx context.Context, route string) (handler http.Handler, err error) {
|
||||
|
||||
router := httprouter.New()
|
||||
|
|
@ -62,17 +76,17 @@ func (admin *Admin) HandleRoute(ctx context.Context, route string) (handler http
|
|||
}
|
||||
}
|
||||
|
||||
// handle everything
|
||||
router.HandlerFunc(http.MethodGet, route, func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, route+"index", http.StatusTemporaryRedirect)
|
||||
})
|
||||
|
||||
// add a handler for the index page
|
||||
router.Handler(http.MethodGet, route+"index", httpx.HTMLHandler[indexContext]{
|
||||
router.Handler(http.MethodGet, route, httpx.HTMLHandler[indexContext]{
|
||||
Handler: admin.index,
|
||||
Template: admin.Dependencies.Custom.Template(indexTemplate),
|
||||
})
|
||||
|
||||
// fallback to the "/" page
|
||||
router.HandlerFunc(http.MethodGet, route+"index", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, route, http.StatusTemporaryRedirect)
|
||||
})
|
||||
|
||||
// add a handler for the user page
|
||||
router.Handler(http.MethodGet, route+"users", httpx.HTMLHandler[userContext]{
|
||||
Handler: admin.users,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
|
|
@ -28,7 +30,10 @@ type componentContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) components(r *http.Request) (cp componentContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&cp, r)
|
||||
admin.Dependencies.Custom.Update(&cp, r, []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Components", Path: "/admin/components/"},
|
||||
})
|
||||
|
||||
cp.Analytics = *admin.Analytics
|
||||
return
|
||||
|
|
@ -49,10 +54,15 @@ type ingredientsContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) ingredients(r *http.Request) (cp ingredientsContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&cp, r)
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
|
||||
admin.Dependencies.Custom.Update(&cp, r, []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Instance", Path: template.URL("/admin/instance/" + slug)},
|
||||
{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")},
|
||||
})
|
||||
|
||||
// find the instance itself!
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
if err == instances.ErrWissKINotFound {
|
||||
return cp, httpx.ErrNotFound
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ package admin
|
|||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
|
|
@ -38,7 +40,11 @@ type grantsContext struct {
|
|||
}
|
||||
|
||||
func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (err error) {
|
||||
admin.Dependencies.Custom.Update(gc, r)
|
||||
admin.Dependencies.Custom.Update(gc, r, []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Instance", Path: template.URL("/admin/instance/" + slug)},
|
||||
{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")},
|
||||
})
|
||||
|
||||
// find the instance itself
|
||||
gc.instance, err = admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin - Components Page{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/components">Components</a>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ template "_anal.html" .Analytics }}
|
||||
{{ end }}
|
||||
|
|
@ -1,14 +1,6 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin - {{ .Instance.Slug }} - Grants{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button" href="/admin/instance/{{ .Instance.Slug }}">Instance</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/grants/{{ .Instance.Slug }}">Grants</a>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ $csrf := .CSRF }}
|
||||
{{ $slug := .Instance.Slug }}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button pure-button-primary" href="/admin/index">Admin</a>
|
||||
</p>
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/users">Users</a>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,6 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin - {{ .Instance.Slug }} - Ingredients{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button" href="/admin/instance/{{ .Instance.Slug }}">Instance</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/ingredients/{{ .Instance.Slug }}">Ingredients</a>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ template "_anal.html" .Analytics }}
|
||||
{{ end }}
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin - {{ .Instance.Slug }}{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/instance/{{ .Instance.Slug }}">Instance</a>
|
||||
</p>
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/grants/{{ .Info.Slug }}">Grants</a>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,3 @@
|
|||
{{ define "form/title" }}Distillery Admin - Create User{{ end }}
|
||||
{{ define "form/button" }}Create{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button" href="/admin/users">Users</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/users/create">Create</a>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Distillery Admin - Users{{ end }}
|
||||
|
||||
{{ define "header"}}
|
||||
<p>
|
||||
<a class="pure-button" href="/admin/index">Admin</a> >
|
||||
<a class="pure-button pure-button-primary" href="/admin/users">Users</a>
|
||||
</p>
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/users/create">Create New</a>
|
||||
|
|
|
|||
|
|
@ -87,7 +87,9 @@ type indexContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) index(r *http.Request) (idx indexContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&idx, r)
|
||||
admin.Dependencies.Custom.Update(&idx, r, []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
})
|
||||
idx.Distillery, idx.Instances, err = admin.Status(r.Context(), true)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package admin
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
|
|
@ -28,10 +30,14 @@ type instanceContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) instance(r *http.Request) (is instanceContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&is, r)
|
||||
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)},
|
||||
})
|
||||
|
||||
// find the instance itself!
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
if err == instances.ErrWissKINotFound {
|
||||
return is, httpx.ErrNotFound
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
_ "embed"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control/static/custom"
|
||||
|
|
@ -31,7 +32,10 @@ type userContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) users(r *http.Request) (uc userContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&uc, r)
|
||||
admin.Dependencies.Custom.Update(&uc, r, []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Users", Path: "/admin/users/"},
|
||||
})
|
||||
|
||||
uc.Error = r.URL.Query().Get("error")
|
||||
uc.Users, err = admin.Dependencies.Auth.Users(r.Context())
|
||||
|
|
@ -58,6 +62,11 @@ 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"},
|
||||
}
|
||||
|
||||
return &httpx.Form[createUserResult]{
|
||||
Fields: []field.Field{
|
||||
|
|
@ -67,8 +76,10 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
|
|||
},
|
||||
FieldTemplate: field.PureCSSFieldTemplate,
|
||||
|
||||
RenderTemplate: userCreateTemplate,
|
||||
RenderTemplateContext: admin.Dependencies.Custom.RenderContext,
|
||||
RenderTemplate: userCreateTemplate,
|
||||
RenderTemplateContext: func(ctx httpx.FormContext, r *http.Request) any {
|
||||
return admin.Dependencies.Custom.NewForm(ctx, r, crumbs)
|
||||
},
|
||||
|
||||
Validate: func(r *http.Request, values map[string]string) (cu createUserResult, err error) {
|
||||
cu.User, cu.Passsword, cu.Admin = values["username"], values["password"], values["admin"] == field.CheckboxChecked
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue