Refactor html templates
This commit entirely refactors the use of html templates. Instead of inheriting from a shared template, we insert the results into a base template.
This commit is contained in:
parent
6ede99d7c6
commit
d235ee4e5c
59 changed files with 869 additions and 777 deletions
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/exporter/logger"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances/purger"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ type Admin struct {
|
|||
|
||||
Policy *policy.Policy
|
||||
|
||||
Templating *templates.Templating
|
||||
Templating *templating.Templating
|
||||
|
||||
Purger *purger.Purger
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,75 +10,71 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"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/lazy"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
//go:embed "html/components.html"
|
||||
var componentsHTML []byte
|
||||
var componentsTemplate = templates.Parse[componentContext]("components.html", componentsHTML, assets.AssetsAdmin)
|
||||
//go:embed "html/anal.html"
|
||||
var analHTML []byte
|
||||
var analTemplate = templating.Parse[analContext](
|
||||
"anal.html", analHTML, nil,
|
||||
|
||||
type componentContext struct {
|
||||
templates.BaseContext
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
type analContext struct {
|
||||
templating.RuntimeFlags
|
||||
|
||||
Analytics lazy.PoolAnalytics
|
||||
}
|
||||
|
||||
func (admin *Admin) components(ctx context.Context) http.Handler {
|
||||
tpl := componentsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Components", Path: "/admin/components/"},
|
||||
},
|
||||
})
|
||||
tpl := analTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.MenuItem{Title: "Components", Path: "/admin/components/"},
|
||||
),
|
||||
templating.Title("Components"),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandler(func(r *http.Request) (cp componentContext, err error) {
|
||||
cp.Analytics = *admin.Analytics
|
||||
return tpl.HTMLHandler(func(r *http.Request) (ac analContext, err error) {
|
||||
ac.Analytics = *admin.Analytics
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed "html/ingredients.html"
|
||||
var ingredientsHTML []byte
|
||||
var ingredientsTemplate = templates.Parse[ingredientsContext]("ingredients.html", ingredientsHTML, assets.AssetsAdmin)
|
||||
|
||||
type ingredientsContext struct {
|
||||
templates.BaseContext
|
||||
|
||||
Instance models.Instance
|
||||
Analytics *lazy.PoolAnalytics
|
||||
}
|
||||
|
||||
func (admin *Admin) ingredients(ctx context.Context) http.Handler {
|
||||
tpl := ingredientsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Instance", Path: "* to be updated *"},
|
||||
{Title: "Ingredients", Path: "* to be updated *"},
|
||||
},
|
||||
})
|
||||
tpl := analTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.DummyMenuItem,
|
||||
component.DummyMenuItem,
|
||||
),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (ic ingredientsContext, err error) {
|
||||
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (ac analContext, funcs []templating.FlagFunc, err error) {
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
|
||||
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}
|
||||
gaps.Crumbs[2] = component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")}
|
||||
|
||||
// find the instance itself!
|
||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
if err == instances.ErrWissKINotFound {
|
||||
return ic, httpx.ErrNotFound
|
||||
return ac, nil, httpx.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return ic, err
|
||||
return ac, nil, err
|
||||
}
|
||||
funcs = []templating.FlagFunc{
|
||||
templating.ReplaceCrumb(1, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
||||
templating.ReplaceCrumb(2, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/instance/" + slug + "/ingredients/")}),
|
||||
templating.Title(instance.Name() + " - Ingredients"),
|
||||
}
|
||||
ic.Instance = instance.Instance
|
||||
|
||||
// and get the components
|
||||
ic.Analytics = instance.Info().Analytics
|
||||
ac.Analytics = *instance.Info().Analytics
|
||||
|
||||
return
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||
|
|
@ -22,10 +22,14 @@ import (
|
|||
|
||||
//go:embed "html/grants.html"
|
||||
var grantsHTML []byte
|
||||
var grantsTemplate = templates.Parse[grantsContext]("grants.html", grantsHTML, assets.AssetsAdmin)
|
||||
var grantsTemplate = templating.Parse[grantsContext](
|
||||
"grants.html", grantsHTML, nil,
|
||||
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
type grantsContext struct {
|
||||
templates.BaseContext
|
||||
templating.RuntimeFlags
|
||||
|
||||
Error string
|
||||
|
||||
|
|
@ -38,40 +42,43 @@ type grantsContext struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) grants(ctx context.Context) http.Handler {
|
||||
tpl := grantsTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Instance", Path: "*to be updated*"},
|
||||
{Title: "Grants", Path: "*to be updated*"},
|
||||
},
|
||||
})
|
||||
tpl := grantsTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.DummyMenuItem,
|
||||
component.DummyMenuItem,
|
||||
),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (grantsContext, error) {
|
||||
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (grantsContext, []templating.FlagFunc, error) {
|
||||
if r.Method == http.MethodGet {
|
||||
return admin.getGrants(r, gaps)
|
||||
return admin.getGrants(r)
|
||||
} else {
|
||||
return admin.postGrants(r, gaps)
|
||||
return admin.postGrants(r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (admin *Admin) getGrants(r *http.Request, gaps *templates.BaseContextGaps) (gc grantsContext, err error) {
|
||||
func (admin *Admin) getGrants(r *http.Request) (gc grantsContext, funcs []templating.FlagFunc, err error) {
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
if err := gc.use(r, gaps, slug, admin); err != nil {
|
||||
return gc, err
|
||||
|
||||
funcs, err = gc.use(r, slug, admin)
|
||||
if err != nil {
|
||||
return gc, nil, err
|
||||
}
|
||||
|
||||
if err := gc.useGrants(r, admin); err != nil {
|
||||
return gc, err
|
||||
return gc, nil, err
|
||||
}
|
||||
|
||||
return gc, nil
|
||||
return gc, funcs, nil
|
||||
}
|
||||
|
||||
func (admin *Admin) postGrants(r *http.Request, gaps *templates.BaseContextGaps) (gc grantsContext, err error) {
|
||||
func (admin *Admin) postGrants(r *http.Request) (gc grantsContext, funcs []templating.FlagFunc, err error) {
|
||||
// parse the form
|
||||
if err := r.ParseForm(); err != nil {
|
||||
return gc, err
|
||||
return gc, nil, err
|
||||
}
|
||||
|
||||
// read out the form values
|
||||
|
|
@ -84,15 +91,16 @@ func (admin *Admin) postGrants(r *http.Request, gaps *templates.BaseContextGaps)
|
|||
)
|
||||
|
||||
// set the common fields
|
||||
if err := gc.use(r, gaps, slug, admin); err != nil {
|
||||
return gc, err
|
||||
funcs, err = gc.use(r, slug, admin)
|
||||
if err != nil {
|
||||
return gc, nil, err
|
||||
}
|
||||
|
||||
if delete {
|
||||
// delete the user grant
|
||||
err := admin.Dependencies.Policy.Remove(r.Context(), distilleryUser, slug)
|
||||
if err != nil {
|
||||
return gc, err
|
||||
return gc, nil, err
|
||||
}
|
||||
} else {
|
||||
// update the grant
|
||||
|
|
@ -110,26 +118,29 @@ func (admin *Admin) postGrants(r *http.Request, gaps *templates.BaseContextGaps)
|
|||
|
||||
// fetch the grants for the instance
|
||||
if err := gc.useGrants(r, admin); err != nil {
|
||||
return gc, err
|
||||
return gc, nil, err
|
||||
}
|
||||
return gc, nil
|
||||
return gc, funcs, nil
|
||||
}
|
||||
|
||||
func (gc *grantsContext) use(r *http.Request, gaps *templates.BaseContextGaps, slug string, admin *Admin) (err error) {
|
||||
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}
|
||||
gaps.Crumbs[2] = component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")}
|
||||
|
||||
func (gc *grantsContext) use(r *http.Request, slug string, admin *Admin) (funcs []templating.FlagFunc, err error) {
|
||||
// find the instance itself
|
||||
gc.instance, err = admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
if err == instances.ErrWissKINotFound {
|
||||
return httpx.ErrNotFound
|
||||
return nil, httpx.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
gc.Instance = gc.instance.Instance
|
||||
|
||||
return nil
|
||||
// replace the functions
|
||||
funcs = []templating.FlagFunc{
|
||||
templating.ReplaceCrumb(1, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
||||
templating.ReplaceCrumb(2, component.MenuItem{Title: "Grants", Path: template.URL("/admin/instance/" + slug + "/grants/")}),
|
||||
templating.Title(gc.Instance.Slug + " - Grants"),
|
||||
}
|
||||
return funcs, nil
|
||||
}
|
||||
|
||||
func (gc *grantsContext) useGrants(r *http.Request, admin *Admin) (err error) {
|
||||
|
|
|
|||
139
internal/dis/component/server/admin/html/anal.html
Normal file
139
internal/dis/component/server/admin/html/anal.html
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<div class="pure-u-1-1">
|
||||
<h2 id="structs">Structs</h2>
|
||||
</div>
|
||||
|
||||
{{ range $name, $comp := .Components }}
|
||||
<div class="pure-u-1-1" id="{{ $name }}">
|
||||
<div class="padding">
|
||||
<div class="overflow">
|
||||
<table class="pure-table pure-table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3">
|
||||
{{ $name }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .Groups }}
|
||||
<tr>
|
||||
<td>
|
||||
Implements
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<code><a href="#{{.}}">{{ . }}</a></code><br />
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $name, $comp := .CFields }}
|
||||
<tr>
|
||||
<td>Component Pointer</td>
|
||||
<td>
|
||||
<code>{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code><a href="#{{ $comp }}">{{ $comp }}</a></code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $name, $comp := .DCFields }}
|
||||
<tr>
|
||||
<td>Component Pointer</td>
|
||||
<td>
|
||||
<code>Dependencies/{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code><a href="#{{ $comp }}">{{ $comp }}</a></code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $name, $iface := .IFields }}
|
||||
<tr>
|
||||
<td>Interface Slice</td>
|
||||
<td>
|
||||
<code>{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code><a href="#{{ $iface }}">[]{{ $iface }}</a></code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $name, $iface := .DIFields }}
|
||||
<tr>
|
||||
<td>Interface Slice</td>
|
||||
<td>
|
||||
<code>Dependencies/{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code><a href="#{{ $iface }}">[]{{ $iface }}</a></code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $name, $sig := $comp.Methods }}
|
||||
<tr>
|
||||
<td>
|
||||
Method
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ $sig }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="pure-u-1-1">
|
||||
<h2 id="interfaces">Interfaces</h2>
|
||||
</div>
|
||||
|
||||
{{ range $name, $group := .Groups }}
|
||||
<div class="pure-u-1-1" id="{{ $name }}">
|
||||
<div class="padding">
|
||||
|
||||
<div class="overflow">
|
||||
<table class="pure-table pure-table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3">
|
||||
{{ $name }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $name, $sig := $group.Methods }}
|
||||
<tr>
|
||||
<td>
|
||||
Method
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ $name }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ $sig }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range $group.Components }}
|
||||
<tr>
|
||||
<td>
|
||||
Implemented By
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<code><a href="#{{.}}">{{ . }}</a></code>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Components{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ template "_anal.html" .Analytics }}
|
||||
{{ end }}
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}{{ .Instance.Slug }} - Grants{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ $csrf := .CSRF }}
|
||||
{{ $slug := .Instance.Slug }}
|
||||
<div class="pure-u-1-1">
|
||||
|
|
@ -123,5 +119,4 @@
|
|||
{{ range $unused, $drupal := .Drupals }}
|
||||
<option value="{{ $drupal }}">
|
||||
{{ end }}
|
||||
</datalist>
|
||||
{{ end }}
|
||||
</datalist>
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Admin{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="pure-u-1-1">
|
||||
<h2 id="overview">Distillery Configuration</h2>
|
||||
</div>
|
||||
|
|
@ -256,5 +252,4 @@
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{ end }}
|
||||
{{end}}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}{{ .Instance.Slug }} - Ingredients{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{ template "_anal.html" .Analytics }}
|
||||
{{ end }}
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}{{ .Instance.Slug }}{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="pure-u-1-1">
|
||||
<h2 id="overview">Info & Status</h2>
|
||||
</div>
|
||||
|
|
@ -484,5 +480,4 @@
|
|||
<button class="remote-action pure-button pure-button-danger" data-action="purge" data-param="{{ .Instance.Slug }}" data-confirm-param="#purge-confirm-slug" data-buffer="1000" data-force-reload="/admin/">Purge Instance</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
|
@ -1,4 +1,2 @@
|
|||
{{ template "_form.html" . }}
|
||||
{{ define "form/title" }}Create User{{ end }}
|
||||
{{ template "form.html" . }}
|
||||
{{ define "form/button" }}Create{{ end }}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
{{ template "_base.html" . }}
|
||||
{{ define "title" }}Users{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
|
||||
<div class="pure-u-1">
|
||||
<div class="padding">
|
||||
<div class="overflow">
|
||||
|
|
@ -105,5 +100,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"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/templates"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
|
@ -80,27 +80,33 @@ func (admin *Admin) Fetch(flags component.FetcherFlags, target *status.Distiller
|
|||
|
||||
//go:embed "html/index.html"
|
||||
var indexHTML []byte
|
||||
var indexTemplate = templates.Parse[indexContext]("index.html", indexHTML, assets.AssetsAdmin)
|
||||
var indexTemplate = templating.Parse[indexContext](
|
||||
"index.html", indexHTML, nil,
|
||||
|
||||
templating.Title("Admin"),
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
type indexContext struct {
|
||||
templates.BaseContext
|
||||
templating.RuntimeFlags
|
||||
|
||||
status.Distillery
|
||||
Instances []status.WissKI
|
||||
}
|
||||
|
||||
func (admin *Admin) index(ctx context.Context) http.Handler {
|
||||
tpl := indexTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
},
|
||||
Actions: []component.MenuItem{
|
||||
{Title: "Users", Path: "/admin/users/"},
|
||||
{Title: "Components", Path: "/admin/components/", Priority: component.SmallButton},
|
||||
},
|
||||
})
|
||||
tpl := indexTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
),
|
||||
templating.Actions(
|
||||
component.MenuItem{Title: "Users", Path: "/admin/users/"},
|
||||
component.MenuItem{Title: "Components", Path: "/admin/components/", Priority: component.SmallButton},
|
||||
),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (idx indexContext, err error) {
|
||||
return tpl.HTMLHandler(func(r *http.Request) (idx indexContext, err error) {
|
||||
idx.Distillery, idx.Instances, err = admin.Status(r.Context(), true)
|
||||
return
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||
|
|
@ -18,49 +18,57 @@ import (
|
|||
|
||||
//go:embed "html/instance.html"
|
||||
var instanceHTML []byte
|
||||
var instanceTemplate = templates.Parse[instanceContext]("instance.html", instanceHTML, assets.AssetsAdmin)
|
||||
var instanceTemplate = templating.Parse[instanceContext](
|
||||
"instance.html", instanceHTML, nil,
|
||||
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
type instanceContext struct {
|
||||
templates.BaseContext
|
||||
templating.RuntimeFlags
|
||||
|
||||
Instance models.Instance
|
||||
Info status.WissKI
|
||||
}
|
||||
|
||||
func (admin *Admin) instance(ctx context.Context) http.Handler {
|
||||
tpl := instanceTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Instance", Path: "*to be replaced*"},
|
||||
},
|
||||
Actions: []component.MenuItem{
|
||||
{Title: "Grants", Path: "*to be replaced*"},
|
||||
{Title: "Ingredients", Path: "*to be replaced*", Priority: component.SmallButton},
|
||||
},
|
||||
})
|
||||
tpl := instanceTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.DummyMenuItem,
|
||||
),
|
||||
templating.Actions(
|
||||
component.DummyMenuItem,
|
||||
component.DummyMenuItem,
|
||||
),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandlerWithGaps(func(r *http.Request, gaps *templates.BaseContextGaps) (ic instanceContext, err error) {
|
||||
return tpl.HTMLHandlerWithFlags(func(r *http.Request) (ic instanceContext, funcs []templating.FlagFunc, err error) {
|
||||
slug := httprouter.ParamsFromContext(r.Context()).ByName("slug")
|
||||
|
||||
gaps.Crumbs[1] = component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}
|
||||
|
||||
gaps.Actions[0] = component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}
|
||||
gaps.Actions[1] = component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}
|
||||
|
||||
// find the instance itself!
|
||||
instance, err := admin.Dependencies.Instances.WissKI(r.Context(), slug)
|
||||
if err == instances.ErrWissKINotFound {
|
||||
return ic, httpx.ErrNotFound
|
||||
return ic, nil, httpx.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return ic, err
|
||||
return ic, nil, err
|
||||
}
|
||||
ic.Instance = instance.Instance
|
||||
|
||||
// get some more info about the wisski
|
||||
ic.Info, err = instance.Info().Information(r.Context(), false)
|
||||
if err != nil {
|
||||
return ic, err
|
||||
return ic, nil, err
|
||||
}
|
||||
|
||||
funcs = []templating.FlagFunc{
|
||||
templating.ReplaceCrumb(1, component.MenuItem{Title: "Instance", Path: template.URL("/admin/instance/" + slug)}),
|
||||
templating.ReplaceAction(0, component.MenuItem{Title: "Grants", Path: template.URL("/admin/grants/" + slug)}),
|
||||
templating.ReplaceAction(1, component.MenuItem{Title: "Ingredients", Path: template.URL("/admin/ingredients/" + slug), Priority: component.SmallButton}),
|
||||
|
||||
templating.Title(instance.Name()),
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -11,7 +11,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/server/assets"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templates"
|
||||
"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/field"
|
||||
"github.com/rs/zerolog"
|
||||
|
|
@ -19,25 +19,30 @@ import (
|
|||
|
||||
//go:embed "html/users.html"
|
||||
var usersHTML []byte
|
||||
var usersTemplate = templates.Parse[usersContext]("user.html", usersHTML, assets.AssetsAdmin)
|
||||
var usersTemplate = templating.Parse[usersContext](
|
||||
"users.html", usersHTML, nil,
|
||||
|
||||
templating.Title("Users"),
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
type usersContext struct {
|
||||
templates.BaseContext
|
||||
|
||||
templating.RuntimeFlags
|
||||
Error string
|
||||
Users []*auth.AuthUser
|
||||
}
|
||||
|
||||
func (admin *Admin) users(ctx context.Context) http.Handler {
|
||||
tpl := usersTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Users", Path: "/admin/users/"},
|
||||
},
|
||||
Actions: []component.MenuItem{
|
||||
{Title: "Create New", Path: "/admin/users/create/"},
|
||||
},
|
||||
})
|
||||
tpl := usersTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.MenuItem{Title: "Users", Path: "/admin/users/"},
|
||||
),
|
||||
templating.Actions(
|
||||
component.MenuItem{Title: "Create New", Path: "/admin/users/create/"},
|
||||
),
|
||||
)
|
||||
|
||||
return tpl.HTMLHandler(func(r *http.Request) (uc usersContext, err error) {
|
||||
uc.Error = r.URL.Query().Get("error")
|
||||
|
|
@ -48,7 +53,12 @@ func (admin *Admin) users(ctx context.Context) http.Handler {
|
|||
|
||||
//go:embed "html/user_create.html"
|
||||
var userCreateHTML []byte
|
||||
var userCreateTemplate = templates.ParseForm("user_create.html", userCreateHTML, assets.AssetsAdmin)
|
||||
var userCreateTemplate = templating.ParseForm(
|
||||
"user_create.html", userCreateHTML, httpx.FormTemplate,
|
||||
|
||||
templating.Title("Create User"),
|
||||
templating.Assets(assets.AssetsAdmin),
|
||||
)
|
||||
|
||||
var (
|
||||
errCreateInvalidUsername = errors.New("invalid username")
|
||||
|
|
@ -62,13 +72,14 @@ type createUserResult struct {
|
|||
}
|
||||
|
||||
func (admin *Admin) createUser(ctx context.Context) http.Handler {
|
||||
tpl := userCreateTemplate.Prepare(admin.Dependencies.Templating, templates.BaseContextGaps{
|
||||
Crumbs: []component.MenuItem{
|
||||
{Title: "Admin", Path: "/admin/"},
|
||||
{Title: "Users", Path: "/admin/users"},
|
||||
{Title: "Create", Path: "/admin/users/create"},
|
||||
},
|
||||
})
|
||||
tpl := userCreateTemplate.Prepare(
|
||||
admin.Dependencies.Templating,
|
||||
templating.Crumbs(
|
||||
component.MenuItem{Title: "Admin", Path: "/admin/"},
|
||||
component.MenuItem{Title: "Users", Path: "/admin/users"},
|
||||
component.MenuItem{Title: "Create", Path: "/admin/users/create"},
|
||||
),
|
||||
)
|
||||
|
||||
return &httpx.Form[createUserResult]{
|
||||
Fields: []field.Field{
|
||||
|
|
@ -79,7 +90,7 @@ func (admin *Admin) createUser(ctx context.Context) http.Handler {
|
|||
FieldTemplate: field.PureCSSFieldTemplate,
|
||||
|
||||
RenderTemplate: tpl.Template(),
|
||||
RenderTemplateContext: templates.FormTemplateContext(tpl),
|
||||
RenderTemplateContext: templating.FormTemplateContext(tpl),
|
||||
|
||||
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