Refactor: Menu

This commit is contained in:
Tom Wiesing 2023-02-03 15:46:53 +01:00
parent a7309d5268
commit 7f820224ec
No known key found for this signature in database
16 changed files with 103 additions and 92 deletions

View file

@ -53,6 +53,17 @@ func (panel *UserPanel) Menu(r *http.Request) []component.MenuItem {
} }
} }
var (
menuUser = component.MenuItem{Title: "User", Path: "/user/"}
menuChangePassword = component.MenuItem{Title: "Change Password", Path: "/user/password/"}
menuSSH = component.MenuItem{Title: "SSH Keys", Path: "/user/ssh/"}
menuSSHAdd = component.MenuItem{Title: "Add New Key", Path: "/user/ssh/add/"}
menuTOTPAction = component.DummyMenuItem()
menuTOTPDisable = component.MenuItem{Title: "Disable Passcode (TOTP)", Path: "/user/totp/disable/"}
menuTOTPEnable = component.MenuItem{Title: "Enable Passcode (TOTP)", Path: "/user/totp/enable/"}
)
func (panel *UserPanel) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (panel *UserPanel) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
router := httprouter.New() router := httprouter.New()
@ -114,9 +125,10 @@ type userFormContext struct {
func (panel *UserPanel) UserFormContext(tpl *templating.Template[userFormContext], last component.MenuItem, funcs ...templating.FlagFunc) func(ctx httpx.FormContext, r *http.Request) any { func (panel *UserPanel) UserFormContext(tpl *templating.Template[userFormContext], last component.MenuItem, funcs ...templating.FlagFunc) func(ctx httpx.FormContext, r *http.Request) any {
funcs = append(funcs, func(flags templating.Flags, r *http.Request) templating.Flags { funcs = append(funcs, func(flags templating.Flags, r *http.Request) templating.Flags {
flags.Crumbs = append(flags.Crumbs, component.MenuItem{}) // append the last menu item, and prepend the menuUser one!
flags.Crumbs = append(flags.Crumbs, last, last)
copy(flags.Crumbs[1:], flags.Crumbs) copy(flags.Crumbs[1:], flags.Crumbs)
flags.Crumbs[0] = component.MenuItem{Title: "User", Path: "/user/"} flags.Crumbs[0] = menuUser
return flags return flags
}) })

View file

@ -7,7 +7,6 @@ import (
_ "embed" _ "embed"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
"github.com/FAU-CDI/wisski-distillery/pkg/httpx" "github.com/FAU-CDI/wisski-distillery/pkg/httpx"
@ -45,7 +44,7 @@ func (panel *UserPanel) routePassword(ctx context.Context) http.Handler {
FieldTemplate: field.PureCSSFieldTemplate, FieldTemplate: field.PureCSSFieldTemplate,
RenderTemplate: tpl.Template(), RenderTemplate: tpl.Template(),
RenderTemplateContext: panel.UserFormContext(tpl, component.MenuItem{Title: "Change Password", Path: "/user/password/"}), RenderTemplateContext: panel.UserFormContext(tpl, menuChangePassword),
Validate: func(r *http.Request, values map[string]string) (struct{}, error) { Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
old, passcode, new, new2 := values["old"], values["otp"], values["new"], values["new2"] old, passcode, new, new2 := values["old"], values["otp"], values["new"], values["new2"]

View file

@ -5,7 +5,6 @@ import (
"errors" "errors"
"net/http" "net/http"
"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/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
@ -45,11 +44,11 @@ func (panel *UserPanel) sshRoute(ctx context.Context) http.Handler {
tpl := sshTemplate.Prepare( tpl := sshTemplate.Prepare(
panel.Dependencies.Templating, panel.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "User", Path: "/user/"}, menuUser,
component.MenuItem{Title: "SSH Keys", Path: "/user/ssh/"}, menuSSH,
), ),
templating.Actions( templating.Actions(
component.MenuItem{Title: "Add New Key", Path: "/user/ssh/add/"}, menuSSHAdd,
), ),
) )
@ -136,9 +135,9 @@ func (panel *UserPanel) sshAddRoute(ctx context.Context) http.Handler {
tpl := sshAddTemplate.Prepare( tpl := sshAddTemplate.Prepare(
panel.Dependencies.Templating, panel.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "User", Path: "/user/"}, menuUser,
component.MenuItem{Title: "SSH Keys", Path: "/user/ssh/"}, menuSSH,
component.MenuItem{Title: "Add New Key", Path: "/user/ssh/add/"}, menuSSHAdd,
), ),
) )

View file

@ -5,7 +5,6 @@ import (
"html/template" "html/template"
"net/http" "net/http"
"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/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
@ -39,7 +38,7 @@ func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
}, },
RenderTemplate: tpl.Template(), RenderTemplate: tpl.Template(),
RenderTemplateContext: panel.UserFormContext(tpl, component.MenuItem{Title: "Enable TOTP", Path: "/user/totp/enable/"}), RenderTemplateContext: panel.UserFormContext(tpl, menuTOTPEnable),
Validate: func(r *http.Request, values map[string]string) (struct{}, error) { Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
password := values["password"] password := values["password"]
@ -93,8 +92,8 @@ func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
tpl := totpEnrollTemplate.Prepare( tpl := totpEnrollTemplate.Prepare(
panel.Dependencies.Templating, panel.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "User", Path: "/user/"}, menuUser,
component.MenuItem{Title: "Enable TOTP", Path: "/user/totp/enable/"}, menuTOTPEnable,
), ),
) )
@ -189,7 +188,7 @@ func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled() return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled()
}, },
RenderTemplate: tpl.Template(), RenderTemplate: tpl.Template(),
RenderTemplateContext: panel.UserFormContext(tpl, component.MenuItem{Title: "Disable TOTP", Path: "/user/totp/disable/"}), RenderTemplateContext: panel.UserFormContext(tpl, menuTOTPDisable),
Validate: func(r *http.Request, values map[string]string) (struct{}, error) { Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
password, otp := values["password"], values["otp"] password, otp := values["password"], values["otp"]

View file

@ -34,21 +34,17 @@ type GrantWithURL struct {
URL template.URL URL template.URL
} }
var (
totpActionItem = component.DummyMenuItem()
)
func (panel *UserPanel) routeUser(ctx context.Context) http.Handler { func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
tpl := userTemplate.Prepare( tpl := userTemplate.Prepare(
panel.Dependencies.Templating, panel.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "User", Path: "/user/"}, menuUser,
), ),
templating.Actions( templating.Actions(
component.MenuItem{Title: "Change Password", Path: "/user/password/"}, menuChangePassword,
totpActionItem, menuTOTPAction,
component.MenuItem{Title: "SSH Keys", Path: "/user/ssh/"}, menuSSH,
), ),
) )
@ -62,18 +58,12 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
// replace the totp action in the menu // replace the totp action in the menu
var totpAction component.MenuItem var totpAction component.MenuItem
if uc.AuthUser.IsTOTPEnabled() { if uc.AuthUser.IsTOTPEnabled() {
totpAction = component.MenuItem{ totpAction = menuTOTPDisable
Title: "Disable Passcode (TOTP)",
Path: "/user/totp/disable/",
}
} else { } else {
totpAction = component.MenuItem{ totpAction = menuTOTPEnable
Title: "Enable Passcode (TOTP)",
Path: "/user/totp/enable/",
}
} }
funcs = []templating.FlagFunc{ funcs = []templating.FlagFunc{
templating.ReplaceAction(totpActionItem, totpAction), templating.ReplaceAction(menuTOTPAction, totpAction),
templating.Title(uc.AuthUser.User.User), templating.Title(uc.AuthUser.User.User),
} }

View file

@ -63,12 +63,16 @@ type resolverContext struct {
wdresolve.IndexContext wdresolve.IndexContext
} }
var (
menuResolver = component.MenuItem{Title: "Resolver", Path: "/wisski/get/"}
)
func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
// get the resolver template // get the resolver template
tpl := resolverTemplate.Prepare( tpl := resolverTemplate.Prepare(
resolver.Dependencies.Templating, resolver.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Resolver", Path: "/wisski/get/"}, menuResolver,
), ),
) )
t := tpl.Template() t := tpl.Template()

View file

@ -63,6 +63,19 @@ func (admin *Admin) Menu(r *http.Request) []component.MenuItem {
} }
} }
var (
menuAdmin = component.MenuItem{Title: "Admin", Path: "/admin/"}
menuComponents = component.MenuItem{Title: "Components", Path: "/admin/components/", Priority: component.SmallButton}
menuUsers = component.MenuItem{Title: "Users", Path: "/admin/users/"}
menuUserCreate = component.MenuItem{Title: "Create User", Path: "/admin/users/create/"}
menuInstances = component.MenuItem{Title: "Instances", Path: "/admin/instance/"}
menuInstance = component.DummyMenuItem()
menuGrants = component.DummyMenuItem()
menuIngredients = component.DummyMenuItem()
)
func (admin *Admin) HandleRoute(ctx context.Context, route string) (handler http.Handler, err error) { func (admin *Admin) HandleRoute(ctx context.Context, route string) (handler http.Handler, err error) {
router := httprouter.New() router := httprouter.New()

View file

@ -34,9 +34,9 @@ func (admin *Admin) components(ctx context.Context) http.Handler {
tpl := analTemplate.Prepare( tpl := analTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
component.MenuItem{Title: "Components", Path: "/admin/components/"}, menuComponents,
), ),
templating.Title("Components"), templating.Title("Components"),
) )
@ -47,19 +47,14 @@ func (admin *Admin) components(ctx context.Context) http.Handler {
}) })
} }
var (
instanceCrumb = component.DummyMenuItem()
ingredientsCrumb = component.DummyMenuItem()
)
func (admin *Admin) ingredients(ctx context.Context) http.Handler { func (admin *Admin) ingredients(ctx context.Context) http.Handler {
tpl := analTemplate.Prepare( tpl := analTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
instanceCrumb, menuInstance,
ingredientsCrumb, menuIngredients,
), ),
) )
@ -75,8 +70,8 @@ func (admin *Admin) ingredients(ctx context.Context) http.Handler {
return ac, nil, err return ac, nil, err
} }
funcs = []templating.FlagFunc{ funcs = []templating.FlagFunc{
templating.ReplaceCrumb(instanceCrumb, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}), templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
templating.ReplaceCrumb(ingredientsCrumb, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")}), templating.ReplaceCrumb(menuIngredients, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")}),
templating.Title(instance.Name() + " - Ingredients"), templating.Title(instance.Name() + " - Ingredients"),
} }

View file

@ -41,19 +41,14 @@ type grantsContext struct {
Drupals []string // unusued drupal usernames Drupals []string // unusued drupal usernames
} }
var (
instancePageCrumb = component.DummyMenuItem()
grantsPageCrumb = component.DummyMenuItem()
)
func (admin *Admin) grants(ctx context.Context) http.Handler { func (admin *Admin) grants(ctx context.Context) http.Handler {
tpl := grantsTemplate.Prepare( tpl := grantsTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
instancePageCrumb, menuInstance,
grantsPageCrumb, menuGrants,
), ),
) )
@ -142,8 +137,8 @@ func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (funcs
// replace the functions // replace the functions
funcs = []templating.FlagFunc{ funcs = []templating.FlagFunc{
templating.ReplaceCrumb(instancePageCrumb, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}), templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
templating.ReplaceCrumb(grantsPageCrumb, component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")}), templating.ReplaceCrumb(menuGrants, component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")}),
templating.Title(gc.Instance.Slug + " - Grants"), templating.Title(gc.Instance.Slug + " - Grants"),
} }
return funcs, nil return funcs, nil

View file

@ -85,6 +85,10 @@ var indexTemplate = templating.Parse[indexContext](
templating.Title("Admin"), templating.Title("Admin"),
templating.Assets(assets.AssetsAdmin), templating.Assets(assets.AssetsAdmin),
templating.Crumbs(
menuAdmin,
),
) )
//go:embed "html/instances.html" //go:embed "html/instances.html"
@ -106,13 +110,10 @@ type indexContext struct {
func (admin *Admin) index(ctx context.Context) http.Handler { func (admin *Admin) index(ctx context.Context) http.Handler {
tpl := indexTemplate.Prepare( tpl := indexTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"},
),
templating.Actions( templating.Actions(
component.MenuItem{Title: "Users", Path: "/admin/users/"}, menuUsers,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
component.MenuItem{Title: "Components", Path: "/admin/components/", Priority: component.SmallButton}, menuComponents,
), ),
) )
@ -126,8 +127,8 @@ func (admin *Admin) instances(ctx context.Context) http.Handler {
tpl := instancesTemplate.Prepare( tpl := instancesTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
), ),
) )

View file

@ -31,23 +31,17 @@ type instanceContext struct {
Info status.WissKI Info status.WissKI
} }
var (
instancesPageCrumb = component.DummyMenuItem()
grantsAction = component.DummyMenuItem()
ingredientsAction = component.DummyMenuItem()
)
func (admin *Admin) instance(ctx context.Context) http.Handler { func (admin *Admin) instance(ctx context.Context) http.Handler {
tpl := instanceTemplate.Prepare( tpl := instanceTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Instances", Path: "/admin/instance/"}, menuInstances,
instancesPageCrumb, menuInstance,
), ),
templating.Actions( templating.Actions(
grantsAction, menuGrants,
ingredientsAction, menuIngredients,
), ),
) )
@ -71,9 +65,9 @@ func (admin *Admin) instance(ctx context.Context) http.Handler {
} }
funcs = []templating.FlagFunc{ funcs = []templating.FlagFunc{
templating.ReplaceCrumb(instancesPageCrumb, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}), templating.ReplaceCrumb(menuInstance, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
templating.ReplaceAction(grantsAction, component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}), templating.ReplaceAction(menuGrants, component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}),
templating.ReplaceAction(ingredientsAction, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}), templating.ReplaceAction(menuIngredients, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}),
templating.Title(instance.Slug), templating.Title(instance.Slug),
} }

View file

@ -8,7 +8,6 @@ import (
_ "embed" _ "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/auth"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
@ -36,11 +35,11 @@ func (admin *Admin) users(ctx context.Context) http.Handler {
tpl := usersTemplate.Prepare( tpl := usersTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Users", Path: "/admin/users/"}, menuUsers,
), ),
templating.Actions( templating.Actions(
component.MenuItem{Title: "Create New", Path: "/admin/users/create/"}, menuUserCreate,
), ),
) )
@ -75,9 +74,9 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
tpl := userCreateTemplate.Prepare( tpl := userCreateTemplate.Prepare(
admin.Dependencies.Templating, admin.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Admin", Path: "/admin/"}, menuAdmin,
component.MenuItem{Title: "Users", Path: "/admin/users"}, menuUsers,
component.MenuItem{Title: "Create", Path: "/admin/users/create"}, menuUserCreate,
), ),
) )

View file

@ -38,6 +38,10 @@ func (*Home) Routes() component.Routes {
} }
} }
var (
menuHome = component.MenuItem{Title: "WissKI Distillery", Path: "/"}
)
func (home *Home) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (home *Home) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
// generate a default handler // generate a default handler
dflt, err := home.loadRedirect(ctx) dflt, err := home.loadRedirect(ctx)

View file

@ -7,7 +7,6 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating" "github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
"github.com/FAU-CDI/wisski-distillery/internal/status" "github.com/FAU-CDI/wisski-distillery/internal/status"
@ -47,7 +46,7 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
tpl := publicTemplate.Prepare( tpl := publicTemplate.Prepare(
home.Dependencies.Templating, home.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "WissKI Distillery", Path: "/"}, menuHome,
), ),
) )

View file

@ -53,11 +53,15 @@ func (legal *Legal) Routes() component.Routes {
} }
} }
var (
menuLegal = component.MenuItem{Title: "Legal", Path: "/legal/"}
)
func (legal *Legal) HandleRoute(ctx context.Context, route string) (http.Handler, error) { func (legal *Legal) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
tpl := legalTemplate.Prepare( tpl := legalTemplate.Prepare(
legal.Dependencies.Templating, legal.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "Legal", Path: "/legal/"}, menuLegal,
), ),
) )

View file

@ -127,12 +127,16 @@ type newsContext struct {
Items []Item Items []Item
} }
var (
menuNews = component.MenuItem{Title: "News", Path: "/news/"}
)
// HandleRoute returns the handler for the requested path // HandleRoute returns the handler for the requested path
func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) { func (news *News) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
tpl := newsTemplate.Prepare( tpl := newsTemplate.Prepare(
news.Dependencies.Templating, news.Dependencies.Templating,
templating.Crumbs( templating.Crumbs(
component.MenuItem{Title: "News", Path: "/news/"}, menuNews,
), ),
) )