READ ISSUES - WEB
This commit is contained in:
26
pkg/web/components/search.templ
Normal file
26
pkg/web/components/search.templ
Normal file
@@ -0,0 +1,26 @@
|
||||
package components
|
||||
|
||||
templ SearchForm(searchQuery string) {
|
||||
<form
|
||||
class="flex gap-2 items-center"
|
||||
action="/"
|
||||
method="get"
|
||||
hx-get="/"
|
||||
hx-target="main"
|
||||
hx-swap="innerHTML"
|
||||
hx-push-url="true"
|
||||
hx-trigger="submit, input changed delay:400ms from:input[name='q']"
|
||||
>
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
value={ searchQuery }
|
||||
placeholder="Search by title, description, or assignee..."
|
||||
class="input input-sm input-bordered text-base-content w-48 md:w-64"
|
||||
aria-label="Search issues"
|
||||
/>
|
||||
<button type="submit" class="btn btn-sm btn-ghost">
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
53
pkg/web/components/search_templ.go
Normal file
53
pkg/web/components/search_templ.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.977
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func SearchForm(searchQuery string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form class=\"flex gap-2 items-center\" action=\"/\" method=\"get\" hx-get=\"/\" hx-target=\"main\" hx-swap=\"innerHTML\" hx-push-url=\"true\" hx-trigger=\"submit, input changed delay:400ms from:input[name='q']\"><input type=\"search\" name=\"q\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(searchQuery)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/search.templ`, Line: 17, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" placeholder=\"Search by title, description, or assignee...\" class=\"input input-sm input-bordered text-base-content w-48 md:w-64\" aria-label=\"Search issues\"> <button type=\"submit\" class=\"btn btn-sm btn-ghost\">Search</button></form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -2,7 +2,9 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/LazyBachelor/LazyPM/internal/models"
|
||||
"github.com/LazyBachelor/LazyPM/pkg/web/components"
|
||||
"github.com/LazyBachelor/LazyPM/pkg/web/routes"
|
||||
)
|
||||
@@ -11,16 +13,20 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
svc := Services(r)
|
||||
hx := HTMX(r)
|
||||
|
||||
issues, err := svc.Beads.AllIssues(r.Context())
|
||||
query := strings.TrimSpace(r.URL.Query().Get("q"))
|
||||
filter := models.IssueFilter{Limit: 100}
|
||||
issuesPtr, err := svc.Beads.SearchIssues(r.Context(), query, filter)
|
||||
if err != nil {
|
||||
http.Error(w, "failed to retrieve issues", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
issues := models.IssuesPtrToIssues(issuesPtr)
|
||||
|
||||
props := routes.IndexProps{
|
||||
IssueTable: components.IssueTableProps{
|
||||
Issues: issues,
|
||||
},
|
||||
SearchQuery: query,
|
||||
}
|
||||
|
||||
if hx.IsHxRequest() {
|
||||
|
||||
@@ -3,7 +3,8 @@ package routes
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components"
|
||||
|
||||
type IndexProps struct {
|
||||
IssueTable components.IssueTableProps
|
||||
IssueTable components.IssueTableProps
|
||||
SearchQuery string
|
||||
}
|
||||
|
||||
templ IndexContent(props IndexProps) {
|
||||
@@ -24,7 +25,7 @@ templ IndexContent(props IndexProps) {
|
||||
}
|
||||
|
||||
templ Index(props IndexProps) {
|
||||
@BaseLayout() {
|
||||
@BaseLayout(BaseLayoutProps{SearchQuery: props.SearchQuery}) {
|
||||
@IndexContent(props)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components"
|
||||
|
||||
type IndexProps struct {
|
||||
IssueTable components.IssueTableProps
|
||||
IssueTable components.IssueTableProps
|
||||
SearchQuery string
|
||||
}
|
||||
|
||||
func IndexContent(props IndexProps) templ.Component {
|
||||
@@ -103,7 +104,7 @@ func Index(props IndexProps) templ.Component {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = BaseLayout(BaseLayoutProps{SearchQuery: props.SearchQuery}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ templ IssueDetailContent(props IssueDetailProps) {
|
||||
}
|
||||
|
||||
templ IssueDetail(props IssueDetailProps) {
|
||||
@BaseLayout() {
|
||||
@BaseLayout(BaseLayoutProps{SearchQuery: ""}) {
|
||||
@IssueDetailContent(props)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ func IssueDetail(props IssueDetailProps) templ.Component {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = BaseLayout(BaseLayoutProps{SearchQuery: ""}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -1,49 +1,44 @@
|
||||
package routes
|
||||
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components"
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components/base"
|
||||
|
||||
var baseLayout = components.LayoutProps{
|
||||
Title: "Beads Test Application",
|
||||
Description: "A sample application using Beads storage service",
|
||||
Head: components.HeadProps{
|
||||
Links: []components.Link{
|
||||
{Href: "/assets/css/styles.css", Rel: "preload", As: "style"},
|
||||
{Href: "/assets/css/styles.css", Rel: "stylesheet"},
|
||||
{Href: "/assets/manifest.json", Rel: "manifest"},
|
||||
},
|
||||
Scripts: []components.Script{
|
||||
{Src: "/assets/js/htmx.min.js", Defer: true},
|
||||
{Src: "/assets/js/ajax.min.js", Defer: true},
|
||||
},
|
||||
},
|
||||
|
||||
Routes: []components.NavRoutes{
|
||||
{Name: "Dashboard", Path: "/", Icon: components.IconDashboard()},
|
||||
{Name: "Issues", Path: "/", Icon: components.IconIssues()},
|
||||
{Name: "Agile Board", Path: "/board", Icon: components.IconAgileBoard()},
|
||||
{Name: "Backlog", Path: "/backlog", Icon: components.IconBacklog()},
|
||||
{Name: "Reports", Path: "/reports", Icon: components.IconReports()},
|
||||
{Name: "Settings", Path: "/settings", Icon: components.IconSettings()},
|
||||
},
|
||||
|
||||
Header: components.HeaderProps{
|
||||
Title: "LazyPM Dashboard",
|
||||
NavbarCenter: base.Input(base.InputProps{
|
||||
Name: "search-issue",
|
||||
Type: "search",
|
||||
Placeholder: "Search issues...",
|
||||
Class: "",
|
||||
Attrs: templ.Attributes{
|
||||
"class": "text-base-content",
|
||||
},
|
||||
}),
|
||||
NavbarEnd: components.Status(),
|
||||
},
|
||||
type BaseLayoutProps struct {
|
||||
SearchQuery string
|
||||
}
|
||||
|
||||
templ BaseLayout() {
|
||||
@components.Layout(baseLayout) {
|
||||
func buildLayoutProps(searchQuery string) components.LayoutProps {
|
||||
return components.LayoutProps{
|
||||
Title: "Beads Test Application",
|
||||
Description: "A sample application using Beads storage service",
|
||||
Head: components.HeadProps{
|
||||
Links: []components.Link{
|
||||
{Href: "/assets/css/styles.css", Rel: "preload", As: "style"},
|
||||
{Href: "/assets/css/styles.css", Rel: "stylesheet"},
|
||||
{Href: "/assets/manifest.json", Rel: "manifest"},
|
||||
},
|
||||
Scripts: []components.Script{
|
||||
{Src: "/assets/js/htmx.min.js", Defer: true},
|
||||
{Src: "/assets/js/ajax.min.js", Defer: true},
|
||||
},
|
||||
},
|
||||
Routes: []components.NavRoutes{
|
||||
{Name: "Dashboard", Path: "/", Icon: components.IconDashboard()},
|
||||
{Name: "Issues", Path: "/", Icon: components.IconIssues()},
|
||||
{Name: "Agile Board", Path: "/board", Icon: components.IconAgileBoard()},
|
||||
{Name: "Backlog", Path: "/backlog", Icon: components.IconBacklog()},
|
||||
{Name: "Reports", Path: "/reports", Icon: components.IconReports()},
|
||||
{Name: "Settings", Path: "/settings", Icon: components.IconSettings()},
|
||||
},
|
||||
Header: components.HeaderProps{
|
||||
Title: "LazyPM Dashboard",
|
||||
NavbarCenter: components.SearchForm(searchQuery),
|
||||
NavbarEnd: components.Status(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
templ BaseLayout(props BaseLayoutProps) {
|
||||
@components.Layout(buildLayoutProps(props.SearchQuery)) {
|
||||
{ children... }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,48 +9,43 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components"
|
||||
import "github.com/LazyBachelor/LazyPM/pkg/web/components/base"
|
||||
|
||||
var baseLayout = components.LayoutProps{
|
||||
Title: "Beads Test Application",
|
||||
Description: "A sample application using Beads storage service",
|
||||
Head: components.HeadProps{
|
||||
Links: []components.Link{
|
||||
{Href: "/assets/css/styles.css", Rel: "preload", As: "style"},
|
||||
{Href: "/assets/css/styles.css", Rel: "stylesheet"},
|
||||
{Href: "/assets/manifest.json", Rel: "manifest"},
|
||||
},
|
||||
Scripts: []components.Script{
|
||||
{Src: "/assets/js/htmx.min.js", Defer: true},
|
||||
{Src: "/assets/js/ajax.min.js", Defer: true},
|
||||
},
|
||||
},
|
||||
|
||||
Routes: []components.NavRoutes{
|
||||
{Name: "Dashboard", Path: "/", Icon: components.IconDashboard()},
|
||||
{Name: "Issues", Path: "/", Icon: components.IconIssues()},
|
||||
{Name: "Agile Board", Path: "/board", Icon: components.IconAgileBoard()},
|
||||
{Name: "Backlog", Path: "/backlog", Icon: components.IconBacklog()},
|
||||
{Name: "Reports", Path: "/reports", Icon: components.IconReports()},
|
||||
{Name: "Settings", Path: "/settings", Icon: components.IconSettings()},
|
||||
},
|
||||
|
||||
Header: components.HeaderProps{
|
||||
Title: "LazyPM Dashboard",
|
||||
NavbarCenter: base.Input(base.InputProps{
|
||||
Name: "search-issue",
|
||||
Type: "search",
|
||||
Placeholder: "Search issues...",
|
||||
Class: "",
|
||||
Attrs: templ.Attributes{
|
||||
"class": "text-base-content",
|
||||
},
|
||||
}),
|
||||
NavbarEnd: components.Status(),
|
||||
},
|
||||
type BaseLayoutProps struct {
|
||||
SearchQuery string
|
||||
}
|
||||
|
||||
func BaseLayout() templ.Component {
|
||||
func buildLayoutProps(searchQuery string) components.LayoutProps {
|
||||
return components.LayoutProps{
|
||||
Title: "Beads Test Application",
|
||||
Description: "A sample application using Beads storage service",
|
||||
Head: components.HeadProps{
|
||||
Links: []components.Link{
|
||||
{Href: "/assets/css/styles.css", Rel: "preload", As: "style"},
|
||||
{Href: "/assets/css/styles.css", Rel: "stylesheet"},
|
||||
{Href: "/assets/manifest.json", Rel: "manifest"},
|
||||
},
|
||||
Scripts: []components.Script{
|
||||
{Src: "/assets/js/htmx.min.js", Defer: true},
|
||||
{Src: "/assets/js/ajax.min.js", Defer: true},
|
||||
},
|
||||
},
|
||||
Routes: []components.NavRoutes{
|
||||
{Name: "Dashboard", Path: "/", Icon: components.IconDashboard()},
|
||||
{Name: "Issues", Path: "/", Icon: components.IconIssues()},
|
||||
{Name: "Agile Board", Path: "/board", Icon: components.IconAgileBoard()},
|
||||
{Name: "Backlog", Path: "/backlog", Icon: components.IconBacklog()},
|
||||
{Name: "Reports", Path: "/reports", Icon: components.IconReports()},
|
||||
{Name: "Settings", Path: "/settings", Icon: components.IconSettings()},
|
||||
},
|
||||
Header: components.HeaderProps{
|
||||
Title: "LazyPM Dashboard",
|
||||
NavbarCenter: components.SearchForm(searchQuery),
|
||||
NavbarEnd: components.Status(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func BaseLayout(props BaseLayoutProps) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -89,7 +84,7 @@ func BaseLayout() templ.Component {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.Layout(baseLayout).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = components.Layout(buildLayoutProps(props.SearchQuery)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user