templating: Move actions into template
This commit is contained in:
parent
313af2b9e3
commit
202599aaeb
23 changed files with 153 additions and 105 deletions
|
|
@ -84,8 +84,8 @@ type userFormContext struct {
|
|||
User *models.User
|
||||
}
|
||||
|
||||
func (panel *UserPanel) UserFormContext(last component.MenuItem) func(ctx httpx.FormContext, r *http.Request) any {
|
||||
crumbs := []component.MenuItem{
|
||||
func (panel *UserPanel) UserFormContext(last component.MenuItem, gaps custom.BaseContextGaps) func(ctx httpx.FormContext, r *http.Request) any {
|
||||
gaps.Crumbs = []component.MenuItem{
|
||||
{Title: "User", Path: "/user/"},
|
||||
last,
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ func (panel *UserPanel) UserFormContext(last component.MenuItem) func(ctx httpx.
|
|||
user, err := panel.Dependencies.Auth.UserOf(r)
|
||||
|
||||
uctx := userFormContext{FormContext: ctx}
|
||||
panel.Dependencies.Custom.Update(&uctx, r, crumbs)
|
||||
panel.Dependencies.Custom.Update(&uctx, r, gaps)
|
||||
if err == nil {
|
||||
uctx.User = &user.User
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"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/pkg/httpx"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
|
||||
)
|
||||
|
|
@ -38,7 +39,7 @@ func (panel *UserPanel) routePassword(ctx context.Context) http.Handler {
|
|||
FieldTemplate: field.PureCSSFieldTemplate,
|
||||
|
||||
RenderTemplate: passwordTemplate,
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Change Password", Path: "/user/password/"}),
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Change Password", Path: "/user/password/"}, custom.BaseContextGaps{}),
|
||||
|
||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||
old, passcode, new, new2 := values["old"], values["otp"], values["new"], values["new2"]
|
||||
|
|
|
|||
|
|
@ -18,14 +18,6 @@
|
|||
{{ end }}
|
||||
</ul>
|
||||
</p>
|
||||
<div class="pure-button-group" role="group" role="Actions">
|
||||
<a class="pure-button" href="/user/password/">Change Password</a>
|
||||
{{ if .User.IsTOTPEnabled }}
|
||||
<a class="pure-button" href="/user/totp/disable/">Disable Passcode (TOTP)</a>
|
||||
{{ else }}
|
||||
<a class="pure-button" href="/user/totp/enable/">Enable Passcode (TOTP)</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
|
@ -34,14 +26,11 @@
|
|||
{{ if (not .User.IsTOTPEnabled) }}
|
||||
<div>
|
||||
<p class="error-message">
|
||||
TOTP is required to access these.
|
||||
You are an administrator, but do not have TOTP enabled.
|
||||
Please turn it on to access the admin page.
|
||||
</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="pure-button-group" role="group" role="Actions">
|
||||
<a class="pure-button" href="/admin/">Distillery Admin Page</a>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"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"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ func (panel *UserPanel) routeTOTPEnable(ctx context.Context) http.Handler {
|
|||
},
|
||||
|
||||
RenderTemplate: totpEnableTemplate,
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Enable TOTP", Path: "/user/totp/enable/"}),
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Enable TOTP", Path: "/user/totp/enable/"}, custom.BaseContextGaps{}),
|
||||
|
||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||
password := values["password"]
|
||||
|
|
@ -78,9 +79,11 @@ type totpEnrollContext struct {
|
|||
|
||||
func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
|
||||
totpEnrollTemplate := panel.Dependencies.Custom.Template(totpEnrollTemplate)
|
||||
crumbs := []component.MenuItem{
|
||||
gaps := custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "User", Path: "/user/"},
|
||||
{Title: "Enable TOTP", Path: "/user/totp/enable/"},
|
||||
},
|
||||
}
|
||||
return &httpx.Form[struct{}]{
|
||||
Fields: []field.Field{
|
||||
|
|
@ -103,7 +106,7 @@ func (panel *UserPanel) routeTOTPEnroll(ctx context.Context) http.Handler {
|
|||
FormContext: context,
|
||||
},
|
||||
}
|
||||
panel.Dependencies.Custom.Update(&ctx.userFormContext, r, crumbs)
|
||||
panel.Dependencies.Custom.Update(&ctx.userFormContext, r, gaps)
|
||||
|
||||
if err == nil && user != nil {
|
||||
ctx.userFormContext.User = &user.User
|
||||
|
|
@ -168,7 +171,7 @@ func (panel *UserPanel) routeTOTPDisable(ctx context.Context) http.Handler {
|
|||
return struct{}{}, err == nil && user != nil && !user.IsTOTPEnabled()
|
||||
},
|
||||
RenderTemplate: totpDisableTemplate,
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Disable TOTP", Path: "/user/totp/disable/"}),
|
||||
RenderTemplateContext: panel.UserFormContext(component.MenuItem{Title: "Disable TOTP", Path: "/user/totp/disable/"}, custom.BaseContextGaps{}),
|
||||
|
||||
Validate: func(r *http.Request, values map[string]string) (struct{}, error) {
|
||||
password, otp := values["password"], values["otp"]
|
||||
|
|
|
|||
|
|
@ -36,13 +36,17 @@ type GrantWithURL struct {
|
|||
|
||||
func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
||||
userTemplate := panel.Dependencies.Custom.Template(userTemplate)
|
||||
crumbs := []component.MenuItem{
|
||||
gaps := custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "User", Path: "/user/"},
|
||||
},
|
||||
Actions: []component.MenuItem{
|
||||
{Title: "Change Password", Path: "/user/password"},
|
||||
},
|
||||
}
|
||||
|
||||
return &httpx.HTMLHandler[routeUserContext]{
|
||||
Handler: func(r *http.Request) (ruc routeUserContext, err error) {
|
||||
panel.Dependencies.Custom.Update(&ruc, r, crumbs)
|
||||
|
||||
// find the user
|
||||
ruc.AuthUser, err = panel.Dependencies.Auth.UserOf(r)
|
||||
|
|
@ -50,6 +54,21 @@ func (panel *UserPanel) routeUser(ctx context.Context) http.Handler {
|
|||
return ruc, err
|
||||
}
|
||||
|
||||
// build the gaps
|
||||
gaps := gaps.Clone()
|
||||
if ruc.AuthUser.IsTOTPEnabled() {
|
||||
gaps.Actions = append(gaps.Actions, component.MenuItem{
|
||||
Title: "Disable Passcode (TOTP)",
|
||||
Path: "/user/totp/disable/",
|
||||
})
|
||||
} else {
|
||||
gaps.Actions = append(gaps.Actions, component.MenuItem{
|
||||
Title: "Enable Passcode (TOTP)",
|
||||
Path: "/user/totp/enable/",
|
||||
})
|
||||
}
|
||||
panel.Dependencies.Custom.Update(&ruc, r, gaps)
|
||||
|
||||
// find the grants
|
||||
grants, err := panel.Dependencies.Policy.User(r.Context(), ruc.AuthUser.User.User)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/control"
|
||||
"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/pkg/httpx"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
|
||||
"github.com/gorilla/sessions"
|
||||
|
|
@ -144,8 +145,10 @@ func (auth *Auth) authLogin(ctx context.Context) http.Handler {
|
|||
if context.Err != nil {
|
||||
context.Err = errLoginFailed
|
||||
}
|
||||
httpx.WriteHTML(auth.Dependencies.Custom.NewForm(context, r, []component.MenuItem{
|
||||
httpx.WriteHTML(auth.Dependencies.Custom.NewForm(context, r, custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Login", Path: template.URL(r.URL.RequestURI())},
|
||||
},
|
||||
}), nil, loginTemplate, "", w, r)
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ type componentContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) components(r *http.Request) (cp componentContext, err error) {
|
||||
admin.Dependencies.Custom.Update(&cp, r, []component.MenuItem{
|
||||
admin.Dependencies.Custom.Update(&cp, r, custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Components", Path: "/admin/components/"},
|
||||
},
|
||||
})
|
||||
|
||||
cp.Analytics = *admin.Analytics
|
||||
|
|
@ -56,10 +58,12 @@ type ingredientsContext struct {
|
|||
func (admin *Admin) ingredients(r *http.Request) (cp ingredientsContext, err error) {
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
|
||||
admin.Dependencies.Custom.Update(&cp, r, []component.MenuItem{
|
||||
admin.Dependencies.Custom.Update(&cp, r, custom.BaseContextGaps{
|
||||
Crumbs: []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!
|
||||
|
|
|
|||
|
|
@ -40,10 +40,12 @@ type grantsContext struct {
|
|||
}
|
||||
|
||||
func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (err error) {
|
||||
admin.Dependencies.Custom.Update(gc, r, []component.MenuItem{
|
||||
admin.Dependencies.Custom.Update(gc, r, custom.BaseContextGaps{
|
||||
Crumbs: []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
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Admin{{ end }}
|
||||
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/users">Users</a>
|
||||
<a class="pure-button pure-button-small" href="/admin/components">Components</a>
|
||||
</div>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="pure-u-1-1">
|
||||
<h2 id="overview">Distillery Configuration</h2>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}{{ .Instance.Slug }}{{ end }}
|
||||
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/grants/{{ .Info.Slug }}">Grants</a>
|
||||
<a class="pure-button pure-button-small" href="/admin/ingredients/{{ .Instance.Slug }}">Ingredients</a>
|
||||
</div>
|
||||
</p>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="pure-u-1-1">
|
||||
<h2 id="overview">Info & Status</h2>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,5 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Admin Users{{ end }}
|
||||
|
||||
{{ define "header" }}
|
||||
<p>
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
<a class="pure-button" href="/admin/users/create">Create New</a>
|
||||
</div>
|
||||
</p>
|
||||
{{ end }}
|
||||
{{ define "title" }}Users{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
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!
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
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{
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ type publicContext struct {
|
|||
}
|
||||
|
||||
func (home *Home) publicHandler(ctx context.Context) http.Handler {
|
||||
crumbs := []component.MenuItem{
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
legal.Dependencies.Custom.Update(&lc, r, custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Legal", Path: "/legal/"},
|
||||
},
|
||||
})
|
||||
|
||||
lc.LegalNotices = cli.LegalNotices
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type BaseContext struct {
|
|||
|
||||
// Menu and breadcrumbs
|
||||
Menu []component.MenuItem
|
||||
Crumbs []component.MenuItem
|
||||
BaseContextGaps
|
||||
|
||||
CSRF template.HTML // CSRF Field
|
||||
}
|
||||
|
|
@ -43,12 +43,24 @@ const (
|
|||
requestNilError template.HTML = errorPrefix + "<code>BaseContext.use()</code> 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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="pure-u-1-1">
|
||||
<h2 id="components">Components</h2>
|
||||
<h2 id="structs">Structs</h2>
|
||||
</div>
|
||||
|
||||
{{ range $name, $comp := .Components }}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<body>
|
||||
{{ .BaseContext.DoInitCheck }}
|
||||
<nav class="pure-menu pure-menu-horizontal">
|
||||
<ul class="pure-menu-list">
|
||||
<ul class="pure-menu-list" role="menubar">
|
||||
{{ range .BaseContext.Menu }}
|
||||
<li class="pure-menu-item{{ if .Active }} pure-menu-selected{{ end }}">
|
||||
<a href="{{ .Path }}" class="pure-menu-link">{{ .Title }}</a>
|
||||
|
|
@ -27,7 +27,13 @@
|
|||
|
||||
<header>
|
||||
<h1 id="top">{{ template "title" . }}</h1>
|
||||
{{ block "header" . }}<!-- no header by default -->{{ end }}
|
||||
{{ if .BaseContext.Actions }}
|
||||
<div class="pure-button-group" role="group" aria-label="Actions">
|
||||
{{ range .BaseContext.Actions }}
|
||||
<a href="{{ .Path }}" class="pure-button{{ if eq .Priority -1 }} pure-button-small{{end}}">{{ .Title }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</header>
|
||||
<main>
|
||||
<div class="pure-g">
|
||||
|
|
|
|||
|
|
@ -34,3 +34,7 @@ const (
|
|||
MenuAdmin
|
||||
MenuAuth
|
||||
)
|
||||
|
||||
const (
|
||||
SmallButton MenuPriority = -1
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/FAU-CDI/wdresolve"
|
||||
"github.com/FAU-CDI/wdresolve/resolvers"
|
||||
"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"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
|
|
@ -25,6 +26,7 @@ type Resolver struct {
|
|||
Dependencies struct {
|
||||
Instances *instances.Instances
|
||||
Custom *custom.Custom
|
||||
Auth *auth.Auth
|
||||
}
|
||||
|
||||
prefixes lazy.Lazy[map[string]string] // cached prefixes (from the server)
|
||||
|
|
@ -58,8 +60,10 @@ type resolverContext struct {
|
|||
|
||||
func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.Handler, error) {
|
||||
resolverTemplate := resolver.Dependencies.Custom.Template(resolverTemplate)
|
||||
crumbs := []component.MenuItem{
|
||||
gaps := custom.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Resolver", Path: "/wisski/get/"},
|
||||
},
|
||||
}
|
||||
|
||||
logger := zerolog.Ctx(ctx)
|
||||
|
|
@ -71,7 +75,11 @@ func (resolver *Resolver) HandleRoute(ctx context.Context, route string) (http.H
|
|||
ctx := resolverContext{
|
||||
IndexContext: context,
|
||||
}
|
||||
resolver.Dependencies.Custom.Update(&ctx, r, crumbs)
|
||||
resolver.Dependencies.Custom.Update(&ctx, r, gaps)
|
||||
|
||||
if !resolver.Dependencies.Auth.Has(auth.User, r) {
|
||||
ctx.IndexContext.Prefixes = nil
|
||||
}
|
||||
|
||||
httpx.WriteHTML(ctx, nil, resolverTemplate, "", w, r)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}WissKI Resolver{{ end }}
|
||||
{{ define "title" }}Resolver{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="pure-u-1">
|
||||
<h1>wdresolve</h1>
|
||||
<p>
|
||||
This page implements a resolver for the WissKI Distillery.
|
||||
This page contains the global distillery resolver.
|
||||
It takes a <b>RDF / Triplestore URI</b> that refers to a <b>WissKI Entity</b> and redirects to the page that displays the entity.
|
||||
</p>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<h2>Resolve URI</h2>
|
||||
<form action="." method="GET" class="pure-form" autocomplete="off">
|
||||
<label for="uri">Enter A URI To Resolve:</label>
|
||||
<input type="text" id="uri" name="uri" value="">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue