Merge pull request #85 from LazyBachelor/LPM-147-2

LPM-147 Assignee button in Create issue WEB
This commit is contained in:
Robin Olsen
2026-03-25 13:29:14 -07:00
committed by GitHub
4 changed files with 42 additions and 16 deletions

View File

@@ -17,6 +17,7 @@ type IssueFormProps struct {
CloseReason string // Set when status is "closed"
Priority int
IssueType string
Assignee string
Class string
Attrs templ.Attributes
Target string // Optional: if empty, server controls via HX-Target header
@@ -100,6 +101,13 @@ templ IssueForm(props IssueFormProps) {
Value: props.Priority,
Step: 1,
})
@base.Input(base.InputProps{
Name: "assignee",
Label: "Assignee",
Value: props.Assignee,
Class: "w-full",
Placeholder: "Enter Assignee",
})
if props.IssueID != "" {
<div class="mt-4 border-t pt-3 space-y-2">
<h3 class="text-sm font-semibold opacity-70">Dependencies</h3>
@@ -160,7 +168,7 @@ templ IssueForm(props IssueFormProps) {
</button>
}
if props.Target == "" {
<div id="result"></div>
<div id="result"></div>
}
</div>
}

View File

@@ -25,6 +25,7 @@ type IssueFormProps struct {
CloseReason string // Set when status is "closed"
Priority int
IssueType string
Assignee string
Class string
Attrs templ.Attributes
Target string // Optional: if empty, server controls via HX-Target header
@@ -76,7 +77,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Status)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 26, Col: 122}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 27, Col: 122}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -94,7 +95,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.PatchAction)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 30, Col: 32}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 31, Col: 32}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@@ -113,7 +114,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.PostAction)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 33, Col: 30}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 34, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
@@ -132,7 +133,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Target)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 36, Col: 28}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 37, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -240,6 +241,16 @@ func IssueForm(props IssueFormProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = base.Input(base.InputProps{
Name: "assignee",
Label: "Assignee",
Value: props.Assignee,
Class: "w-full",
Placeholder: "Enter Assignee",
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if props.IssueID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<div class=\"mt-4 border-t pt-3 space-y-2\"><h3 class=\"text-sm font-semibold opacity-70\">Dependencies</h3><div class=\"flex gap-2 items-end\"><div class=\"flex-1\"><label class=\"label\"><span class=\"label-text\">Add dependency</span></label> <select class=\"select select-bordered w-full\" name=\"depends_on_id\" id=\"dependency-select\" hx-get=\"")
if templ_7745c5c3_Err != nil {
@@ -248,7 +259,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + props.IssueID + "/dependencies/options")
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 115, Col: 69}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 123, Col: 69}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@@ -261,7 +272,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + props.IssueID + "/dependencies?container_id=edit-dependencies-list")
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 126, Col: 97}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 134, Col: 97}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@@ -274,7 +285,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + props.IssueID + "/dependencies?container_id=edit-dependencies-list")
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 136, Col: 94}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 144, Col: 94}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@@ -297,7 +308,7 @@ func IssueForm(props IssueFormProps) templ.Component {
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.DeleteAction)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 155, Col: 31}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 163, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -397,7 +408,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + issue.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 195, Col: 35}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 203, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@@ -410,7 +421,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, 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: 199, Col: 15}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 207, Col: 15}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -423,7 +434,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + issue.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 204, Col: 35}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 212, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
@@ -436,7 +447,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, 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: 208, Col: 18}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 216, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
@@ -457,7 +468,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, 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: 213, Col: 57}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 221, Col: 57}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@@ -470,7 +481,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, 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: 214, Col: 68}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 222, Col: 68}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
@@ -483,7 +494,7 @@ func IssueRows(issues []*models.Issue) templ.Component {
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs("/issues/" + issue.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 219, Col: 38}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/web/components/issue.templ`, Line: 227, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {

View File

@@ -23,6 +23,7 @@ type IssueForm struct {
Status models.Status `form:"status" validate:"required,oneof=open in_progress blocked deferred closed"`
IssueType models.IssueType `form:"issue_type" validate:"required,oneof=task bug feature chore epic"`
Priority int `form:"priority" validate:"gte=0,lte=4"`
Assignee string `form:"assignee" validate:"omitempty,max=100"`
}
type UpdateIssueForm struct {
@@ -56,6 +57,7 @@ func CreateIssue(w http.ResponseWriter, r *http.Request) {
issue := form.toIssue()
issue.CreatedBy = "Me"
issue.Assignee = strings.TrimSpace(form.Assignee)
if err := app.Issues.CreateIssue(r.Context(), issue, "Me"); err != nil {
http.Error(w, "Failed to create issue: "+err.Error(), http.StatusInternalServerError)
return
@@ -155,6 +157,9 @@ func UpdateIssue(w http.ResponseWriter, r *http.Request) {
return
}
a := strings.TrimSpace(r.FormValue("assignee"))
form.Assignee = &a
changes := form.toChanges()
if err := app.Issues.UpdateIssue(r.Context(), issue.ID, changes, ""); err != nil {

View File

@@ -23,6 +23,7 @@ func CreateIssueFormModal(w http.ResponseWriter, r *http.Request) {
Status: "open",
IssueType: "task",
Priority: 0,
Assignee: "",
})
modal := components.Modal(components.ModalProps{
@@ -65,6 +66,7 @@ func EditIssueFormModal(w http.ResponseWriter, r *http.Request) {
CloseReason: issue.CloseReason,
IssueType: string(issue.IssueType),
Priority: issue.Priority,
Assignee: issue.Assignee,
})
modal := components.Modal(components.ModalProps{