Added backlite UI to the admin panel.
This commit is contained in:
parent
52f87580a0
commit
3cfcb43031
8 changed files with 99 additions and 13 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"entgo.io/ent/entc/gen"
|
||||
"entgo.io/ent/entc/load"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/mikestefanello/backlite/ui"
|
||||
"github.com/mikestefanello/pagoda/ent"
|
||||
"github.com/mikestefanello/pagoda/ent/admin"
|
||||
"github.com/mikestefanello/pagoda/pkg/context"
|
||||
|
|
@ -23,9 +24,10 @@ import (
|
|||
)
|
||||
|
||||
type Admin struct {
|
||||
orm *ent.Client
|
||||
graph *gen.Graph
|
||||
admin *admin.Handler
|
||||
orm *ent.Client
|
||||
graph *gen.Graph
|
||||
admin *admin.Handler
|
||||
backlite *ui.Handler
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -33,6 +35,7 @@ func init() {
|
|||
}
|
||||
|
||||
func (h *Admin) Init(c *services.Container) error {
|
||||
var err error
|
||||
h.graph = c.Graph
|
||||
h.orm = c.ORM
|
||||
h.admin = admin.NewHandler(h.orm, admin.HandlerConfig{
|
||||
|
|
@ -40,12 +43,19 @@ func (h *Admin) Init(c *services.Container) error {
|
|||
PageQueryKey: pager.QueryKey,
|
||||
TimeFormat: time.DateTime,
|
||||
})
|
||||
return nil
|
||||
h.backlite, err = ui.NewHandler(ui.Config{
|
||||
DB: c.Database,
|
||||
BasePath: "/admin/tasks",
|
||||
ItemsPerPage: 25,
|
||||
ReleaseAfter: c.Config.Tasks.ReleaseAfter,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *Admin) Routes(g *echo.Group) {
|
||||
entities := g.Group("/admin/entity", middleware.RequireAdmin)
|
||||
ag := g.Group("/admin", middleware.RequireAdmin)
|
||||
|
||||
entities := ag.Group("/entity")
|
||||
for _, n := range h.graph.Nodes {
|
||||
ng := entities.Group(fmt.Sprintf("/%s", strings.ToLower(n.Name)))
|
||||
ng.GET("", h.EntityList(n)).
|
||||
|
|
@ -63,6 +73,14 @@ func (h *Admin) Routes(g *echo.Group) {
|
|||
ng.POST("/:id/delete", h.EntityDeleteSubmit(n), h.middlewareEntityLoad(n)).
|
||||
Name = routenames.AdminEntityDeleteSubmit(n.Name)
|
||||
}
|
||||
|
||||
tasks := ag.Group("/tasks")
|
||||
tasks.GET("", h.Backlite(h.backlite.Running)).Name = routenames.AdminTasks
|
||||
tasks.GET("/succeeded", h.Backlite(h.backlite.Succeeded))
|
||||
tasks.GET("/failed", h.Backlite(h.backlite.Failed))
|
||||
tasks.GET("/upcoming", h.Backlite(h.backlite.Upcoming))
|
||||
tasks.GET("/task/:id", h.Backlite(h.backlite.Task))
|
||||
tasks.GET("/completed/:id", h.Backlite(h.backlite.TaskCompleted))
|
||||
}
|
||||
|
||||
// middlewareEntityLoad is middleware to extract the entity ID and attempt to load the given entity.
|
||||
|
|
@ -182,3 +200,12 @@ func (h *Admin) getEntitySchema(n *gen.Type) *load.Schema {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Admin) Backlite(handler func(http.ResponseWriter, *http.Request) error) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
if id := c.Param("id"); id != "" {
|
||||
c.Request().SetPathValue("task", id)
|
||||
}
|
||||
return handler(c.Response().Writer, c.Request())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const (
|
|||
CacheSubmit = "cache.submit"
|
||||
Files = "files"
|
||||
FilesSubmit = "files.submit"
|
||||
AdminTasks = "admin:tasks"
|
||||
)
|
||||
|
||||
func AdminEntityList(entityTypeName string) string {
|
||||
|
|
|
|||
|
|
@ -149,6 +149,20 @@ func sidebarMenu(r *ui.Request) Node {
|
|||
Class("menu-list"),
|
||||
entityTypeLinks,
|
||||
),
|
||||
P(
|
||||
Class("menu-label"),
|
||||
Text("Monitoring"),
|
||||
),
|
||||
Ul(
|
||||
Class("menu-list"),
|
||||
Li(
|
||||
A(
|
||||
Href(r.Path(routenames.AdminTasks)),
|
||||
Text("Tasks"),
|
||||
Target("_blank"),
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/mikestefanello/pagoda/pkg/ui/layouts"
|
||||
"github.com/mikestefanello/pagoda/pkg/ui/models"
|
||||
. "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/components"
|
||||
. "maragu.dev/gomponents/html"
|
||||
)
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ func Home(ctx echo.Context, posts *models.Posts) error {
|
|||
headerMsg := func() Node {
|
||||
return Group{
|
||||
Section(
|
||||
Class("hero is-info welcome is-small mb-5"),
|
||||
Class("hero is-info welcome is-small mb-3"),
|
||||
Div(
|
||||
Class("hero-body"),
|
||||
Div(
|
||||
|
|
@ -58,6 +59,28 @@ func Home(ctx echo.Context, posts *models.Posts) error {
|
|||
),
|
||||
),
|
||||
),
|
||||
Section(
|
||||
Class("hero is-light is-small mb-5"),
|
||||
Div(
|
||||
Class("hero-body"),
|
||||
Div(
|
||||
Class("container"),
|
||||
B(Text("Admin status: ")),
|
||||
Span(
|
||||
Classes{
|
||||
"tag": true,
|
||||
"is-success": r.IsAdmin,
|
||||
"is-danger": !r.IsAdmin,
|
||||
},
|
||||
Text(fmt.Sprint(r.IsAdmin)),
|
||||
),
|
||||
If(!r.IsAdmin, Span(
|
||||
Class("is-size-7 ml-3"),
|
||||
Raw(`(<a href="https://github.com/mikestefanello/pagoda#create-an-admin-account">click here</a> for instructions to make an admin account)`),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
H2(Class("title"), Text("Recent posts")),
|
||||
H3(Class("subtitle"), Text("Below is an example of both paging and AJAX fetching using HTMX")),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,19 @@ func AddTask(ctx echo.Context, form *forms.Task) error {
|
|||
"",
|
||||
Group{
|
||||
P(Raw("Submitting this form will create an <i>ExampleTask</i> in the task queue. After the specified delay, the message will be logged by the queue processor.")),
|
||||
P(Text("See pkg/tasks and the README for more information.")),
|
||||
P(Raw("See <i>pkg/tasks</i> and the README for more information.")),
|
||||
})
|
||||
}),
|
||||
form.Render(r),
|
||||
Iff(r.Htmx.Target != "task", func() Node {
|
||||
return components.Message(
|
||||
"is-warning",
|
||||
"",
|
||||
Group{
|
||||
If(!r.IsAdmin, P(Text("Log in as an admin in order to access the task and queue monitoring UI."))),
|
||||
If(r.IsAdmin, P(Text("View all queued tasks by clicking on the Tasks link in the sidebar."))),
|
||||
})
|
||||
}),
|
||||
}
|
||||
|
||||
return r.Render(layouts.Primary, g)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue