| @@ -399,6 +399,24 @@ func (s *Server) signupSubmit(w http.ResponseWriter, r *http.Request) { |
| 399 | }{basePage{Site: s.siteName(), Host: s.cfg.SiteHost()}, username, msg, s.cfg.SiteHost()}) |
399 | }{basePage{Site: s.siteName(), Host: s.cfg.SiteHost()}, username, msg, s.cfg.SiteHost()}) |
| 400 | } |
400 | } |
| 401 | |
401 | |
| |
402 | // issueNewPage is what the new-issue form renders with, whether that is a |
| |
403 | // fresh form, a Preview round trip, or a refused create — each keeps |
| |
404 | // whatever the visitor typed (#271). |
| |
405 | type issueNewPage struct { |
| |
406 | repoPage |
| |
407 | Body string |
| |
408 | Format string |
| |
409 | Title string |
| |
410 | Labels string |
| |
411 | Milestone string |
| |
412 | Assignee string |
| |
413 | Template string |
| |
414 | Templates []control.IssueTemplate |
| |
415 | Draft *draft |
| |
416 | CanWrite bool |
| |
417 | Notice string |
| |
418 | } |
| |
419 | |
| 402 | // issueCreateForm renders the new-issue form, prefilled from the repo's |
420 | // issueCreateForm renders the new-issue form, prefilled from the repo's |
| 403 | // default issue template when one exists. A Preview submit comes back |
421 | // default issue template when one exists. A Preview submit comes back |
| 404 | // here with the draft in the form, so the page returns with everything |
422 | // here with the draft in the form, so the page returns with everything |
| @@ -411,18 +429,11 @@ func (s *Server) issueCreateForm(w http.ResponseWriter, r *http.Request, u store |
| 411 | p.Tab = "issues" |
429 | p.Tab = "issues" |
| 412 | if wantsPreview(r) { |
430 | if wantsPreview(r) { |
| 413 | d := s.draftFor(r, p.Repo, "body", "body", bodyFormat(r)) |
431 | d := s.draftFor(r, p.Repo, "body", "body", bodyFormat(r)) |
| 414 | s.render(w, "issuenew.html", struct { |
432 | s.render(w, "issuenew.html", issueNewPage{ |
| 415 | repoPage |
433 | repoPage: p, Body: d.Body, Format: d.Format, Title: r.FormValue("title"), |
| 416 | Body string |
434 | Labels: r.FormValue("labels"), Milestone: r.FormValue("milestone"), Assignee: r.FormValue("assignee"), |
| 417 | Format string |
435 | Templates: control.IssueTemplates(p.Dir, p.Repo.DefaultBranch), Draft: d, CanWrite: s.canWriteRepoAs(u, p.Repo), |
| 418 | Title string |
436 | }) |
| 419 | Labels string |
| |
| 420 | Template string |
| |
| 421 | Templates []control.IssueTemplate |
| |
| 422 | Draft *draft |
| |
| 423 | CanWrite bool |
| |
| 424 | }{p, d.Body, d.Format, r.FormValue("title"), r.FormValue("labels"), |
| |
| 425 | "", control.IssueTemplates(p.Dir, p.Repo.DefaultBranch), d, s.canWriteRepoAs(u, p.Repo)}) |
| |
| 426 | return |
437 | return |
| 427 | } |
438 | } |
| 428 | templates := control.IssueTemplates(p.Dir, p.Repo.DefaultBranch) |
439 | templates := control.IssueTemplates(p.Dir, p.Repo.DefaultBranch) |
| @@ -447,17 +458,10 @@ func (s *Server) issueCreateForm(w http.ResponseWriter, r *http.Request, u store |
| 447 | if format != "org" { |
458 | if format != "org" { |
| 448 | format = "md" |
459 | format = "md" |
| 449 | } |
460 | } |
| 450 | s.render(w, "issuenew.html", struct { |
461 | s.render(w, "issuenew.html", issueNewPage{ |
| 451 | repoPage |
462 | repoPage: p, Body: body, Format: format, Template: tplName, Templates: templates, |
| 452 | Body string |
463 | CanWrite: s.canWriteRepoAs(u, p.Repo), |
| 453 | Format string |
464 | }) |
| 454 | Title string |
| |
| 455 | Labels string |
| |
| 456 | Template string |
| |
| 457 | Templates []control.IssueTemplate |
| |
| 458 | Draft *draft |
| |
| 459 | CanWrite bool |
| |
| 460 | }{p, body, format, "", "", tplName, templates, nil, s.canWriteRepoAs(u, p.Repo)}) |
| |
| 461 | } |
465 | } |
| 462 | |
466 | |
| 463 | // Issue and merge request writes run the command the CLI runs, so the |
467 | // Issue and merge request writes run the command the CLI runs, so the |
| @@ -465,13 +469,18 @@ func (s *Server) issueCreateForm(w http.ResponseWriter, r *http.Request, u store |
| 465 | // implementation. Bodies travel on stdin, the way --file - does. |
469 | // implementation. Bodies travel on stdin, the way --file - does. |
| 466 | |
470 | |
| 467 | func (s *Server) issueCreateSubmit(w http.ResponseWriter, r *http.Request, u store.User) { |
471 | func (s *Server) issueCreateSubmit(w http.ResponseWriter, r *http.Request, u store.User) { |
| 468 | repoPath := r.PathValue("owner") + "/" + r.PathValue("repo") |
472 | p, ok := s.repoFor(w, r, "") |
| |
473 | if !ok { |
| |
474 | return |
| |
475 | } |
| |
476 | repoPath := p.Repo.Path() |
| 469 | title := strings.TrimSpace(r.FormValue("title")) |
477 | title := strings.TrimSpace(r.FormValue("title")) |
| 470 | format := bodyFormat(r) |
478 | format := bodyFormat(r) |
| 471 | if wantsPreview(r) { |
479 | if wantsPreview(r) { |
| 472 | s.issueCreateForm(w, r, u) |
480 | s.issueCreateForm(w, r, u) |
| 473 | return |
481 | return |
| 474 | } |
482 | } |
| |
483 | canWrite := s.canWriteRepoAs(u, p.Repo) |
| 475 | var created control.Created |
484 | var created control.Created |
| 476 | argv := []string{"issue", "create", repoPath, "--title", title, "--format", format, "--file", "-"} |
485 | argv := []string{"issue", "create", repoPath, "--title", title, "--format", format, "--file", "-"} |
| 477 | // Labels, milestone and assignee go on the same dispatch issue create |
486 | // Labels, milestone and assignee go on the same dispatch issue create |
| @@ -480,7 +489,7 @@ func (s *Server) issueCreateSubmit(w http.ResponseWriter, r *http.Request, u sto |
| 480 | // events happen (#271). issue create refuses the whole create when any |
489 | // events happen (#271). issue create refuses the whole create when any |
| 481 | // of them is set without write access, so a reader's hand-crafted POST |
490 | // of them is set without write access, so a reader's hand-crafted POST |
| 482 | // carrying one is dropped here rather than failing the create. |
491 | // carrying one is dropped here rather than failing the create. |
| 483 | if repo, err := s.st.RepoByPath(repoPath); err == nil && s.canWriteRepoAs(u, repo) { |
492 | if canWrite { |
| 484 | argv = append(argv, fieldArgs("--label", r.FormValue("labels"))...) |
493 | argv = append(argv, fieldArgs("--label", r.FormValue("labels"))...) |
| 485 | if milestone := strings.TrimSpace(r.FormValue("milestone")); milestone != "" { |
494 | if milestone := strings.TrimSpace(r.FormValue("milestone")); milestone != "" { |
| 486 | argv = append(argv, "--milestone", milestone) |
495 | argv = append(argv, "--milestone", milestone) |
| @@ -489,7 +498,12 @@ func (s *Server) issueCreateSubmit(w http.ResponseWriter, r *http.Request, u sto |
| 489 | } |
498 | } |
| 490 | code, msg := s.dispatchIntoStdin(u, argv, r.FormValue("body"), &created) |
499 | code, msg := s.dispatchIntoStdin(u, argv, r.FormValue("body"), &created) |
| 491 | if code != protocol.ExitOK { |
500 | if code != protocol.ExitOK { |
| 492 | http.Error(w, msg, statusForExit(code)) |
501 | p.Tab = "issues" |
| |
502 | s.render(w, "issuenew.html", issueNewPage{ |
| |
503 | repoPage: p, Body: r.FormValue("body"), Format: format, Title: title, |
| |
504 | Labels: r.FormValue("labels"), Milestone: r.FormValue("milestone"), Assignee: r.FormValue("assignee"), |
| |
505 | Templates: control.IssueTemplates(p.Dir, p.Repo.DefaultBranch), CanWrite: canWrite, Notice: msg, |
| |
506 | }) |
| 493 | return |
507 | return |
| 494 | } |
508 | } |
| 495 | n := created.Number |
509 | n := created.Number |