package issue import ( "context" "net/http" "forge.cadoles.com/wpetit/clearcase/internal/core/service" 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/issue/component" "forge.cadoles.com/wpetit/clearcase/internal/http/url" "github.com/a-h/templ" "github.com/pkg/errors" ) func (h *Handler) getIssuePage(w http.ResponseWriter, r *http.Request) { vmodel, err := h.fillIssuePageVModel(r) if err != nil { h.handleError(w, r, errors.WithStack(err)) return } issue := component.IssuePage(*vmodel) templ.Handler(issue).ServeHTTP(w, r) } func (h *Handler) fillIssuePageVModel(r *http.Request) (*component.IssuePageVModel, error) { vmodel := &component.IssuePageVModel{ SummaryForm: component.NewIssueSummaryForm(), IssueForm: component.NewIssueForm(), } err := common.FillViewModel( r.Context(), vmodel, r, h.fillIssuePageProjects, h.fillIssuePageSelectedProject, ) if err != nil { return nil, errors.WithStack(err) } return vmodel, nil } func (h *Handler) fillIssuePageProjects(ctx context.Context, vmodel *component.IssuePageVModel, r *http.Request) error { user := httpCtx.User(ctx) projects, err := h.issueManager.GetUserProjects(ctx, user) if err != nil { return errors.WithStack(err) } vmodel.Projects = projects return nil } func (h *Handler) fillIssuePageSelectedProject(ctx context.Context, vmodel *component.IssuePageVModel, 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) handleIssueSummary(w http.ResponseWriter, r *http.Request) { ctx := r.Context() issueSummaryForm := component.NewIssueSummaryForm() if err := issueSummaryForm.Handle(r); err != nil { h.handleError(w, r, errors.WithStack(err)) return } vmodel, err := h.fillIssuePageVModel(r) if err != nil { h.handleError(w, r, errors.WithStack(err)) return } vmodel.SummaryForm = issueSummaryForm if errs := issueSummaryForm.Validate(); errs != nil { page := component.IssuePage(*vmodel) templ.Handler(page).ServeHTTP(w, r) return } projectID, err := form.FormFieldAttr[string](issueSummaryForm, "project", "value") if err != nil { h.handleError(w, r, errors.WithStack(err)) return } summary, err := form.FormFieldAttr[string](issueSummaryForm, "summary", "value") if err != nil { h.handleError(w, r, errors.WithStack(err)) return } issueContent, err := h.issueManager.GenerateIssue(ctx, httpCtx.User(ctx), projectID, summary) if err != nil { h.handleError(w, r, errors.WithStack(err)) return } vmodel.IssueForm.Field("content").Set("value", issueContent) page := component.IssuePage(*vmodel) templ.Handler(page).ServeHTTP(w, r) } func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error) { if errors.Is(err, service.ErrForgeNotAvailable) { baseURL := url.Mutate(httpCtx.BaseURL(r.Context()), url.WithPath("/auth/logout")) http.Redirect(w, r, baseURL.String(), http.StatusTemporaryRedirect) return } common.HandleError(w, r, errors.WithStack(err)) }