diff --git a/internal/service/beads.go b/internal/service/beads.go index b9acd55..1a9bc66 100644 --- a/internal/service/beads.go +++ b/internal/service/beads.go @@ -51,48 +51,3 @@ func (s *BeadsService) DeleteIssues() error { } return nil } - -func (s *BeadsService) GetComments(ctx context.Context, issueID string) ([]models.Comment, error) { - query := `SELECT id, issue_id, author, text, created_at FROM comments WHERE issue_id = ? ORDER BY created_at ASC LIMIT 100` - - rows, err := s.UnderlyingDB().QueryContext(ctx, query, issueID) - if err != nil { - return nil, err - } - - if len(commentsPtr) == 0 { - return []models.Comment{}, nil - } - - comments := make([]models.Comment, 0, len(commentsPtr)) - for _, c := range commentsPtr { - if c != nil { - comments = append(comments, *c) - } - } - - return comments, nil -} - -func (s *BeadsService) AddComment(ctx context.Context, issueID, author, text string) (*models.Comment, error) { - query := `INSERT INTO comments (issue_id, author, text, created_at) VALUES (?, ?, ?, ?)` - - createdAt := time.Now().UTC() - result, err := s.UnderlyingDB().ExecContext(ctx, query, issueID, author, text, createdAt) - if err != nil { - return nil, err - } - - id, err := result.LastInsertId() - if err != nil { - return nil, err - } - - return &models.Comment{ - ID: id, - IssueID: issueID, - Author: author, - Text: text, - CreatedAt: createdAt, - }, nil -} diff --git a/pkg/web/components/comment.templ b/pkg/web/components/comment.templ index bb08ce2..7bcb184 100644 --- a/pkg/web/components/comment.templ +++ b/pkg/web/components/comment.templ @@ -7,7 +7,7 @@ import ( type CommentSectionProps struct { IssueID string - Comments []models.Comment + Comments []*models.Comment } templ CommentSection(props CommentSectionProps) { @@ -31,7 +31,7 @@ templ CommentSection(props CommentSectionProps) { } type CommentListProps struct { - Comments []models.Comment + Comments []*models.Comment } templ CommentList(props CommentListProps) { @@ -45,7 +45,7 @@ templ CommentList(props CommentListProps) { } type CommentItemProps struct { - Comment models.Comment + Comment *models.Comment } templ CommentItem(props CommentItemProps) { diff --git a/pkg/web/components/comment_templ.go b/pkg/web/components/comment_templ.go index 41f1437..1dbbe49 100644 --- a/pkg/web/components/comment_templ.go +++ b/pkg/web/components/comment_templ.go @@ -15,7 +15,7 @@ import ( type CommentSectionProps struct { IssueID string - Comments []models.Comment + Comments []*models.Comment } func CommentSection(props CommentSectionProps) templ.Component { @@ -75,7 +75,7 @@ func CommentSection(props CommentSectionProps) templ.Component { } type CommentListProps struct { - Comments []models.Comment + Comments []*models.Comment } func CommentList(props CommentListProps) templ.Component { @@ -117,7 +117,7 @@ func CommentList(props CommentListProps) templ.Component { } type CommentItemProps struct { - Comment models.Comment + Comment *models.Comment } func CommentItem(props CommentItemProps) templ.Component { @@ -247,7 +247,7 @@ func CommentForm(props CommentFormProps) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" hx-target=\"#comments-list\" hx-swap=\"beforeend\" hx-on::after-request=\"this.reset()\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" hx-target=\"#comments-list\" hx-swap=\"beforeend\" hx-on::after-success=\"this.reset()\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/web/components/issue.templ b/pkg/web/components/issue.templ index bf05365..88a113b 100644 --- a/pkg/web/components/issue.templ +++ b/pkg/web/components/issue.templ @@ -104,10 +104,22 @@ templ IssueRows(issues []models.Issue) { for _, issue := range issues { - { issue.ID } + { issue.ID } - { issue.Title } + { issue.Title } { string(issue.Status) } { string(issue.IssueType) } diff --git a/pkg/web/components/issue_templ.go b/pkg/web/components/issue_templ.go index 7e7ba72..ff040e8 100644 --- a/pkg/web/components/issue_templ.go +++ b/pkg/web/components/issue_templ.go @@ -225,53 +225,53 @@ func IssueRows(issues []models.Issue) templ.Component { } ctx = templ.ClearChildren(ctx) for _, issue := range issues { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" hx-target=\"main\" hx-swap=\"innerHTML\" hx-push-url=\"true\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(issue.ID) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 107, Col: 99} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 113, Col: 15} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" hx-target=\"main\" hx-swap=\"innerHTML\" hx-push-url=\"true\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(issue.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 110, Col: 93} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 122, Col: 18} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -284,7 +284,7 @@ func IssueRows(issues []models.Issue) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(string(issue.Status)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 112, Col: 54} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 124, Col: 54} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -297,7 +297,7 @@ func IssueRows(issues []models.Issue) templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(string(issue.IssueType)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 113, Col: 57} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 125, Col: 57} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { @@ -310,7 +310,7 @@ func IssueRows(issues []models.Issue) templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("P%d", issue.Priority)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 114, Col: 68} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 126, Col: 68} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { diff --git a/pkg/web/handler/comments.go b/pkg/web/handler/comments.go index 2970d3f..8c5db6d 100644 --- a/pkg/web/handler/comments.go +++ b/pkg/web/handler/comments.go @@ -13,7 +13,7 @@ type CommentForm struct { } func ListComments(w http.ResponseWriter, r *http.Request) { - comments := r.Context().Value(commentsKey).([]models.Comment) + comments := r.Context().Value(commentsKey).([]*models.Comment) hx := HTMX(r) if hx.IsHxRequest() { @@ -40,14 +40,14 @@ func CreateComment(w http.ResponseWriter, r *http.Request) { if err := ValidateForm(form); err != nil { if hx.IsHxRequest() { - hx.WriteString("
Please fix the form errors
") + hx.WriteString(`
Please fix the form errors
`) } else { http.Error(w, "Validation error: "+err.Error(), http.StatusUnprocessableEntity) } return } - comment, err := svc.Beads.AddComment(r.Context(), issue.ID, form.Author, form.Text) + comment, err := svc.Beads.AddIssueComment(r.Context(), issue.ID, form.Author, form.Text) if err != nil { http.Error(w, "Failed to create comment: "+err.Error(), http.StatusInternalServerError) return @@ -55,7 +55,7 @@ func CreateComment(w http.ResponseWriter, r *http.Request) { if hx.IsHxRequest() { components.CommentItem(components.CommentItemProps{ - Comment: *comment, + Comment: comment, }).Render(r.Context(), w) return } diff --git a/pkg/web/handler/index.go b/pkg/web/handler/index.go index 6cec171..677a033 100644 --- a/pkg/web/handler/index.go +++ b/pkg/web/handler/index.go @@ -9,6 +9,7 @@ import ( func IndexHandler(w http.ResponseWriter, r *http.Request) { svc := Services(r) + hx := HTMX(r) issues, err := svc.Beads.AllIssues(r.Context()) if err != nil { @@ -22,5 +23,10 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) { }, } + if hx.IsHxRequest() { + routes.IndexContent(props).Render(r.Context(), w) + return + } + routes.Index(props).Render(r.Context(), w) } diff --git a/pkg/web/handler/issues.go b/pkg/web/handler/issues.go index 6001138..d0bb77a 100644 --- a/pkg/web/handler/issues.go +++ b/pkg/web/handler/issues.go @@ -92,7 +92,7 @@ func IssueCtx(next http.Handler) http.Handler { return } - comments, err := svc.Beads.GetComments(r.Context(), issue.ID) + comments, err := svc.Beads.GetIssueComments(r.Context(), issue.ID) if err != nil { http.Error(w, "Error getting comments: "+err.Error(), http.StatusInternalServerError) return @@ -107,13 +107,10 @@ func IssueCtx(next http.Handler) http.Handler { func GetIssue(w http.ResponseWriter, r *http.Request) { issue := r.Context().Value(issueKey).(*models.Issue) - comments := r.Context().Value(commentsKey).([]models.Comment) + comments := r.Context().Value(commentsKey).([]*models.Comment) hx := HTMX(r) - acceptHeader := r.Header.Get("Accept") - wantsHTML := acceptHeader == "" || strings.Contains(acceptHeader, "text/html") - - if wantsHTML && !hx.IsHxRequest() { + if !hx.IsHxRequest() && strings.Contains(r.Header.Get("Accept"), "text/html") { routes.IssueDetail(routes.IssueDetailProps{ Issue: *issue, Comments: comments, @@ -121,6 +118,14 @@ func GetIssue(w http.ResponseWriter, r *http.Request) { return } + if hx.IsHxRequest() { + routes.IssueDetailContent(routes.IssueDetailProps{ + Issue: *issue, + Comments: comments, + }).Render(r.Context(), w) + return + } + w.Header().Set("Content-Type", "application/json") hx.WriteJSON(issue) } diff --git a/pkg/web/routes/index.templ b/pkg/web/routes/index.templ index a67be63..3d3157d 100644 --- a/pkg/web/routes/index.templ +++ b/pkg/web/routes/index.templ @@ -6,21 +6,25 @@ type IndexProps struct { IssueTable components.IssueTableProps } +templ IndexContent(props IndexProps) { +
+

Create New Issue

+ @components.IssueForm( + components.IssueFormProps{ + Action: "/issues", + Class: "mb-4", + Title: "", + Description: "", + Status: "open", + Priority: 0, + IssueType: "task", + }) + @components.IssueTable(props.IssueTable) +
+} + templ Index(props IndexProps) { @BaseLayout() { -
-

Create New Issue

- @components.IssueForm( - components.IssueFormProps{ - Action: "/issues", - Class: "mb-4", - Title: "", - Description: "", - Status: "open", - Priority: 0, - IssueType: "task", - }) - @components.IssueTable(props.IssueTable) -
+ @IndexContent(props) } } diff --git a/pkg/web/routes/index_templ.go b/pkg/web/routes/index_templ.go index 00775ef..31ab021 100644 --- a/pkg/web/routes/index_templ.go +++ b/pkg/web/routes/index_templ.go @@ -14,7 +14,7 @@ type IndexProps struct { IssueTable components.IssueTableProps } -func Index(props IndexProps) templ.Component { +func IndexContent(props IndexProps) 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 { @@ -35,7 +35,57 @@ func Index(props IndexProps) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Create New Issue

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.IssueForm( + components.IssueFormProps{ + Action: "/issues", + Class: "mb-4", + Title: "", + Description: "", + Status: "open", + Priority: 0, + IssueType: "task", + }).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.IssueTable(props.IssueTable).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func Index(props IndexProps) 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_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { @@ -47,34 +97,13 @@ func Index(props IndexProps) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Create New Issue

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = components.IssueForm( - components.IssueFormProps{ - Action: "/issues", - Class: "mb-4", - Title: "", - Description: "", - Status: "open", - Priority: 0, - IssueType: "task", - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = components.IssueTable(props.IssueTable).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") + templ_7745c5c3_Err = IndexContent(props).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) - templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/web/routes/issue_detail.templ b/pkg/web/routes/issue_detail.templ index ad6bfe8..606f006 100644 --- a/pkg/web/routes/issue_detail.templ +++ b/pkg/web/routes/issue_detail.templ @@ -8,72 +8,77 @@ import ( type IssueDetailProps struct { Issue models.Issue - Comments []models.Comment + Comments []*models.Comment +} + +templ IssueDetailContent(props IssueDetailProps) { +
+
+ + @components.IconBack() + Back to Issues + +
+
+
+
+
+ { props.Issue.ID } +

{ props.Issue.Title }

+
+
+ @StatusBadge(props.Issue.Status) + @TypeBadge(props.Issue.IssueType) + @PriorityBadge(props.Issue.Priority) +
+
+ if props.Issue.Description != "" { +
+

Description

+

{ props.Issue.Description }

+
+ } +
+
+
+ Created +

{ props.Issue.CreatedAt.Format("Jan 2, 2006") }

+
+
+ Updated +

{ props.Issue.UpdatedAt.Format("Jan 2, 2006") }

+
+ if props.Issue.Assignee != "" { +
+ Assignee +

{ props.Issue.Assignee }

+
+ } + if props.Issue.Owner != "" { +
+ Owner +

{ props.Issue.Owner }

+
+ } +
+
+
+ @components.CommentSection(components.CommentSectionProps{ + IssueID: props.Issue.ID, + Comments: props.Comments, + }) +
} templ IssueDetail(props IssueDetailProps) { @BaseLayout() { -
-
- - @components.IconBack() - Back to Issues - -
- -
-
-
-
- { props.Issue.ID } -

{ props.Issue.Title }

-
-
- @StatusBadge(props.Issue.Status) - @TypeBadge(props.Issue.IssueType) - @PriorityBadge(props.Issue.Priority) -
-
- - if props.Issue.Description != "" { -
-

Description

-

{ props.Issue.Description }

-
- } - -
- -
-
- Created -

{ props.Issue.CreatedAt.Format("Jan 2, 2006") }

-
-
- Updated -

{ props.Issue.UpdatedAt.Format("Jan 2, 2006") }

-
- if props.Issue.Assignee != "" { -
- Assignee -

{ props.Issue.Assignee }

-
- } - if props.Issue.Owner != "" { -
- Owner -

{ props.Issue.Owner }

-
- } -
-
-
- - @components.CommentSection(components.CommentSectionProps{ - IssueID: props.Issue.ID, - Comments: props.Comments, - }) -
+ @IssueDetailContent(props) } } diff --git a/pkg/web/routes/issue_detail_templ.go b/pkg/web/routes/issue_detail_templ.go index f54e695..73e3cef 100644 --- a/pkg/web/routes/issue_detail_templ.go +++ b/pkg/web/routes/issue_detail_templ.go @@ -16,10 +16,10 @@ import ( type IssueDetailProps struct { Issue models.Issue - Comments []models.Comment + Comments []*models.Comment } -func IssueDetail(props IssueDetailProps) templ.Component { +func IssueDetailContent(props IssueDetailProps) 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 { @@ -40,7 +40,188 @@ func IssueDetail(props IssueDetailProps) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.IconBack().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "Back to Issues
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.ID) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 32, Col: 66} + } + _, 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, 3, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 33, Col: 61} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = StatusBadge(props.Issue.Status).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = TypeBadge(props.Issue.IssueType).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = PriorityBadge(props.Issue.Priority).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if props.Issue.Description != "" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

Description

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Description) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 44, Col: 62} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
Created

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.CreatedAt.Format("Jan 2, 2006")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 51, Col: 74} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

Updated

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.UpdatedAt.Format("Jan 2, 2006")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 55, Col: 74} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if props.Issue.Assignee != "" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
Assignee

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Assignee) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 60, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if props.Issue.Owner != "" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
Owner

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Owner) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 66, Col: 49} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.CommentSection(components.CommentSectionProps{ + IssueID: props.Issue.ID, + Comments: props.Comments, + }).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func IssueDetail(props IssueDetailProps) 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_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { @@ -52,165 +233,13 @@ func IssueDetail(props IssueDetailProps) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = components.IconBack().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "Back to Issues
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.ID) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 28, Col: 67} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 29, Col: 62} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = StatusBadge(props.Issue.Status).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = TypeBadge(props.Issue.IssueType).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = PriorityBadge(props.Issue.Priority).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if props.Issue.Description != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

Description

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Description) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 41, Col: 63} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
Created

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.CreatedAt.Format("Jan 2, 2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 50, Col: 75} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

Updated

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.UpdatedAt.Format("Jan 2, 2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 54, Col: 75} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if props.Issue.Assignee != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
Assignee

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Assignee) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 59, Col: 53} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if props.Issue.Owner != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
Owner

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Issue.Owner) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 65, Col: 50} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = components.CommentSection(components.CommentSectionProps{ - IssueID: props.Issue.ID, - Comments: props.Comments, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + templ_7745c5c3_Err = IssueDetailContent(props).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) - templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -234,9 +263,9 @@ func StatusBadge(status models.Status) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var10 := templ.GetChildren(ctx) - if templ_7745c5c3_Var10 == nil { - templ_7745c5c3_Var10 = templ.NopComponent + templ_7745c5c3_Var11 := templ.GetChildren(ctx) + if templ_7745c5c3_Var11 == nil { + templ_7745c5c3_Var11 = templ.NopComponent } ctx = templ.ClearChildren(ctx) switch status { @@ -270,12 +299,12 @@ func StatusBadge(status models.Status) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(string(status)) + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(string(status)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 93, Col: 39} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 98, Col: 39} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -304,9 +333,9 @@ func TypeBadge(issueType models.IssueType) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var12 := templ.GetChildren(ctx) - if templ_7745c5c3_Var12 == nil { - templ_7745c5c3_Var12 = templ.NopComponent + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent } ctx = templ.ClearChildren(ctx) switch issueType { @@ -340,12 +369,12 @@ func TypeBadge(issueType models.IssueType) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(string(issueType)) + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(string(issueType)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 110, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 115, Col: 56} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -374,9 +403,9 @@ func PriorityBadge(priority int) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent } ctx = templ.ClearChildren(ctx) switch priority { @@ -410,12 +439,12 @@ func PriorityBadge(priority int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("P%d", priority)) + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("P%d", priority)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 127, Col: 53} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/routes/issue_detail.templ`, Line: 132, Col: 53} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }