Files
LazyPM/pkg/web/routes/dashboard.templ

166 lines
4.1 KiB
Plaintext

package routes
import (
"github.com/LazyBachelor/LazyPM/internal/models"
"github.com/LazyBachelor/LazyPM/pkg/web/components"
"github.com/LazyBachelor/LazyPM/pkg/web/components/base"
)
type DashboardProps struct {
Issues []*models.Issue
SelectedIssue *models.Issue
BaseURL string
QueryParam string
EmptyText string
}
templ Dashboard(props DashboardProps) {
@BaseLayout() {
@DashboardContent(props)
}
}
templ DashboardContent(props DashboardProps) {
<div class="flex flex-col h-full">
<div class="flex flex-col border-b border-base-200">
<div class="flex p-2 border-b border-base-200 items-center gap-2">
@components.SearchForm(components.SearchFormProps{
RootURL: props.BaseURL,
SearchQuery: props.QueryParam,
Target: "#issue-list-container",
})
</div>
<div class="flex p-2 justify-between items-center gap-2">
<div class="flex gap-2">
<div class="join">
<button class="btn btn-sm join-item btn-active btn-primary">List</button>
<button
class="btn btn-sm join-item"
hx-get="/?board=true"
hx-target="main"
hx-swap="innerHTML"
hx-push-url="true"
>Board</button>
</div>
<button
class="btn btn-primary btn-sm"
hx-get="/issues/create"
hx-target="#modal-container"
hx-swap="innerHTML"
>
New Issue
</button>
</div>
<div class="flex gap-2">
if props.SelectedIssue != nil {
<button
type="button"
class="btn btn-primary btn-sm"
hx-get={ "/issues/" + props.SelectedIssue.ID + "/edit" }
hx-target="#modal-container"
hx-swap="innerHTML"
>
Edit
</button>
if props.SelectedIssue.Status != "closed" {
<button
type="button"
class="btn btn-warning btn-sm btn-outline"
hx-get={ "/issues/" + props.SelectedIssue.ID + "/close" }
hx-target="#modal-container"
hx-swap="innerHTML"
>
Close issue
</button>
}
<button
class="btn btn-sm"
hx-get={ "/issues/" + props.SelectedIssue.ID }
hx-target="main"
hx-swap="innerHTML"
hx-push-url="true"
>Details</button>
}
</div>
</div>
</div>
<div class="flex flex-row flex-1 overflow-hidden">
<div class="w-full flex flex-col border-r border-base-200 overflow-auto">
<div id="issue-list-container" class="p-2">
@DashboardIssueList(props.Issues, props.SelectedIssue.ID)
</div>
</div>
<div class="w-full p-2 overflow-auto max-[770px]:hidden">
if props.SelectedIssue != nil {
<div id="issue-detail-container">
@components.IssueDetail(components.IssueDetailProps{
Issue: props.SelectedIssue,
})
</div>
}
</div>
</div>
</div>
}
templ DashboardIssueList(issues []*models.Issue, selectedID string) {
<section class="flex">
@base.Table(
[]templ.Component{
base.PlainText("ID"),
base.PlainText("Title"),
base.PlainText("Status"),
base.PlainText("Type"),
base.PlainText("Priority"),
},
[]templ.Component{
DashboardIssueRows(issues, selectedID),
},
templ.Attributes{},
)
</section>
}
templ DashboardIssueRows(issues []*models.Issue, selectedID string) {
if len(issues) == 0 {
<tr><td colspan="5" class="text-center py-4">No issues</td></tr>
}
for _, issue := range issues {
{{
var active string
if selectedID == issue.ID {
active = "bg-primary/10"
}
}}
<tr
hx-get="/"
class={ "hover cursor-pointer min-h-full w-full", active }
hx-target="main"
hx-vals={ `{"selected-issue": "` + issue.ID + `"}` }
hx-swap="innerHTML"
data-issue-id={ issue.ID }
>
<button
type="button"
class="hidden"
hx-get={ "/issues/" + issue.ID + "/edit" }
hx-target="#modal-container"
hx-swap="innerHTML"
hx-trigger="dblclick from:closest tr"
></button>
<td class="min-w-20 truncate">{ issue.ID }</td>
<td class="truncate max-w-60">{ issue.Title }</td>
<td>
@components.StatusBadge(issue.Status)
</td>
<td>
@components.TypeBadge(issue.IssueType)
</td>
<td>
@components.PriorityBadge(issue.Priority)
</td>
</tr>
}
}