feat: pull request generation
This commit is contained in:
242
internal/http/handler/webui/pullrequest/pullrequest_page.go
Normal file
242
internal/http/handler/webui/pullrequest/pullrequest_page.go
Normal file
@ -0,0 +1,242 @@
|
||||
package pullrequest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
httpCtx "forge.cadoles.com/wpetit/clearcase/internal/http/context"
|
||||
"forge.cadoles.com/wpetit/clearcase/internal/http/form"
|
||||
"forge.cadoles.com/wpetit/clearcase/internal/http/handler/webui/common"
|
||||
"forge.cadoles.com/wpetit/clearcase/internal/http/handler/webui/pullrequest/component"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (h *Handler) getPullRequestPage(w http.ResponseWriter, r *http.Request) {
|
||||
vmodel, err := h.fillPullRequestPageVModel(r)
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
pr := component.PullRequestPage(*vmodel)
|
||||
templ.Handler(pr).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPageVModel(r *http.Request) (*component.PullRequestPageVModel, error) {
|
||||
vmodel := &component.PullRequestPageVModel{
|
||||
SummaryForm: component.NewPullRequestSummaryForm(),
|
||||
PullRequestForm: component.NewPullRequestForm(),
|
||||
}
|
||||
|
||||
err := common.FillViewModel(
|
||||
r.Context(), vmodel, r,
|
||||
h.fillPullRequestPageSelectedProject,
|
||||
h.fillPullRequestPagePullRequests,
|
||||
h.fillPullRequestPageProjects,
|
||||
h.fillPullRequestPageSelectedPullRequest,
|
||||
h.fillPullRequestPageSummary,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return vmodel, nil
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPageProjects(ctx context.Context, vmodel *component.PullRequestPageVModel, r *http.Request) error {
|
||||
user := httpCtx.User(ctx)
|
||||
|
||||
projects, err := h.forge.GetUserProjects(ctx, user)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
vmodel.Projects = projects
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPagePullRequests(ctx context.Context, vmodel *component.PullRequestPageVModel, r *http.Request) error {
|
||||
if vmodel.SelectedProjectID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
user := httpCtx.User(ctx)
|
||||
|
||||
pullRequests, err := h.forge.GetUserProjectOpenedPullRequests(ctx, user, vmodel.SelectedProjectID)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
vmodel.PullRequests = pullRequests
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPageSelectedProject(ctx context.Context, vmodel *component.PullRequestPageVModel, r *http.Request) error {
|
||||
project := r.URL.Query().Get("project")
|
||||
if project == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
vmodel.SelectedProjectID = project
|
||||
vmodel.SummaryForm.Field("project").Set("value", project)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPageSelectedPullRequest(ctx context.Context, vmodel *component.PullRequestPageVModel, r *http.Request) error {
|
||||
pullRequest := r.URL.Query().Get("pullrequest")
|
||||
if pullRequest == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
vmodel.SelectedPullRequestID = pullRequest
|
||||
vmodel.SummaryForm.Field("pullrequest").Set("value", pullRequest)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) fillPullRequestPageSummary(ctx context.Context, vmodel *component.PullRequestPageVModel, r *http.Request) error {
|
||||
if vmodel.SelectedProjectID == "" || vmodel.SelectedPullRequestID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
user := httpCtx.User(ctx)
|
||||
|
||||
pullRequest, err := h.forge.GetUserProjectPullRequest(ctx, user, vmodel.SelectedProjectID, vmodel.SelectedPullRequestID)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "could not retrieve selected pull request", slog.Any("error", errors.WithStack(err)))
|
||||
return nil
|
||||
}
|
||||
|
||||
vmodel.SummaryForm.Field("summary").Set("value", pullRequest.Body)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) handlePullRequestSummaryForm(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
pullRequestSummaryForm := component.NewPullRequestSummaryForm()
|
||||
|
||||
if err := pullRequestSummaryForm.Handle(r); err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
vmodel, err := h.fillPullRequestPageVModel(r)
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
vmodel.SummaryForm = pullRequestSummaryForm
|
||||
|
||||
if errs := pullRequestSummaryForm.Validate(); errs != nil {
|
||||
page := component.PullRequestPage(*vmodel)
|
||||
templ.Handler(page).ServeHTTP(w, r)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
projectID, err := form.FormFieldAttr[string](pullRequestSummaryForm, "project", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
pullRequestID, err := form.FormFieldAttr[string](pullRequestSummaryForm, "pullrequest", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
prSummary, err := form.FormFieldAttr[string](pullRequestSummaryForm, "summary", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
prTemplate, err := form.FormFieldAttr[string](pullRequestSummaryForm, "template", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
prTemplate = strings.TrimSpace(prTemplate)
|
||||
|
||||
prTitle, prBody, prTips, err := h.forge.GeneratePullRequest(ctx, httpCtx.User(ctx), projectID, pullRequestID, prSummary, prTemplate)
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
vmodel.PullRequestTips = prTips
|
||||
vmodel.PullRequestForm.Field("title").Set("value", prTitle)
|
||||
vmodel.PullRequestForm.Field("body").Set("value", prBody)
|
||||
|
||||
page := component.PullRequestPage(*vmodel)
|
||||
templ.Handler(page).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (h *Handler) handlePullRequestForm(w http.ResponseWriter, r *http.Request) {
|
||||
pullRequestForm := component.NewPullRequestForm()
|
||||
|
||||
if err := pullRequestForm.Handle(r); err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
vmodel, err := h.fillPullRequestPageVModel(r)
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
if errs := pullRequestForm.Validate(); errs != nil {
|
||||
vmodel.PullRequestForm = pullRequestForm
|
||||
|
||||
page := component.PullRequestPage(*vmodel)
|
||||
templ.Handler(page).ServeHTTP(w, r)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
projectID := r.URL.Query().Get("project")
|
||||
pullRequestID := r.URL.Query().Get("pullrequest")
|
||||
|
||||
title, err := form.FormFieldAttr[string](pullRequestForm, "title", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := form.FormFieldAttr[string](pullRequestForm, "body", "value")
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
user := httpCtx.User(ctx)
|
||||
|
||||
issueURL, err := h.forge.UpdatePullRequest(ctx, user, projectID, pullRequestID, title, body)
|
||||
if err != nil {
|
||||
h.handleError(w, r, errors.WithStack(err))
|
||||
return
|
||||
}
|
||||
|
||||
vmodel.PullRequestURL = issueURL
|
||||
|
||||
vmodel.SummaryForm.Field("summary").Set("value", "")
|
||||
vmodel.PullRequestForm.Field("title").Set("value", "")
|
||||
vmodel.PullRequestForm.Field("body").Set("value", "")
|
||||
|
||||
page := component.PullRequestPage(*vmodel)
|
||||
templ.Handler(page).ServeHTTP(w, r)
|
||||
}
|
Reference in New Issue
Block a user