| 1 | <% content_for :title, "#{@pull_request.title} (##{@pull_request.number}) · #{@repository.full_name}" %> |
| 2 | |
| 3 | <div class="border-b border-surface-600 bg-surface-800"> |
| 4 | <div class="max-w-4xl mx-auto px-4 sm:px-6 pt-6 pb-4"> |
| 5 | <div class="flex items-center gap-2 text-sm mb-4"> |
| 6 | <%= link_to "@#{@owner.username}", user_profile_path(@owner.username), class: "text-brand-500 hover:underline font-medium" %> |
| 7 | <span class="text-gray-500">/</span> |
| 8 | <%= link_to @repository.name, repository_path(@owner.username, @repository.name), class: "text-brand-500 hover:underline font-semibold" %> |
| 9 | <span class="text-gray-500">/</span> |
| 10 | <%= link_to "pulls", repository_pull_requests_path(@owner.username, @repository.name), class: "text-gray-400 hover:text-gray-200 transition-colors" %> |
| 11 | <span class="text-gray-500">/</span> |
| 12 | <span class="text-gray-400">#<%= @pull_request.number %></span> |
| 13 | </div> |
| 14 | |
| 15 | <h1 class="text-xl font-semibold text-gray-100 mb-2"><%= @pull_request.title %> |
| 16 | <span class="text-gray-500 font-normal">#<%= @pull_request.number %></span> |
| 17 | </h1> |
| 18 | |
| 19 | <div class="flex flex-wrap items-center gap-2 text-sm"> |
| 20 | <% case @pull_request.state |
| 21 | when "open" %> |
| 22 | <span class="badge-green">Open</span> |
| 23 | <% when "merged" %> |
| 24 | <span class="badge-purple">Merged</span> |
| 25 | <% else %> |
| 26 | <span class="badge-red">Closed</span> |
| 27 | <% end %> |
| 28 | <span class="text-gray-400"> |
| 29 | <span class="font-medium text-gray-300"><%= @pull_request.author.username %></span> wants to merge |
| 30 | <span class="font-mono badge-gray"><%= @pull_request.head_ref %></span> |
| 31 | into |
| 32 | <span class="font-mono badge-gray"><%= @pull_request.base_ref %></span> |
| 33 | </span> |
| 34 | </div> |
| 35 | </div> |
| 36 | </div> |
| 37 | |
| 38 | <div class="max-w-4xl mx-auto px-4 sm:px-6 py-6 space-y-6"> |
| 39 | <% if @pull_request.body.present? %> |
| 40 | <div class="card"> |
| 41 | <div class="px-6 py-6 prose-readme"><%= render_markdown(@pull_request.body) %></div> |
| 42 | </div> |
| 43 | <% end %> |
| 44 | |
| 45 | <% if @pull_request.open? && @repository.writable_by?(current_user) %> |
| 46 | <div class="card px-4 py-3 flex items-center justify-between gap-3 |
| 47 | <%= @mergeable ? 'bg-green-900/10 border-green-800/30' : 'bg-amber-900/10 border-amber-800/30' %>"> |
| 48 | <% if @mergeable %> |
| 49 | <p class="text-sm text-green-300">This branch has no conflicts with the base branch.</p> |
| 50 | <%= button_to "Merge pull request", merge_repository_pull_request_path(@owner.username, @repository.name, @pull_request.number), |
| 51 | method: :post, class: "btn-primary cursor-pointer", |
| 52 | form: { data: { turbo_confirm: "Merge ##{@pull_request.number} into #{@pull_request.base_ref}?" } } %> |
| 53 | <% else %> |
| 54 | <p class="text-sm text-amber-300">This branch has conflicts and can't be merged automatically.</p> |
| 55 | <% end %> |
| 56 | </div> |
| 57 | <% end %> |
| 58 | |
| 59 | <div> |
| 60 | <h2 class="text-sm font-medium text-gray-300 mb-2"> |
| 61 | <%= pluralize(@commits.size, "commit") %> |
| 62 | </h2> |
| 63 | <div class="card"> |
| 64 | <% @commits.each do |commit| %> |
| 65 | <div class="commit-row"> |
| 66 | <div class="min-w-0 flex-1"> |
| 67 | <p class="text-sm font-medium text-gray-100 truncate"> |
| 68 | <%= link_to commit[:subject], repository_commit_path(@owner.username, @repository.name, commit[:sha]), class: "hover:text-brand-500" %> |
| 69 | </p> |
| 70 | <p class="text-xs text-gray-400 mt-0.5"> |
| 71 | <span class="font-medium"><%= commit[:author_name] %></span> committed <%= time_ago_in_words(commit[:authored_date]) %> ago |
| 72 | </p> |
| 73 | </div> |
| 74 | <div class="shrink-0 ml-4"> |
| 75 | <%= link_to commit[:short_sha], repository_commit_path(@owner.username, @repository.name, commit[:sha]), |
| 76 | class: "font-mono text-xs badge-gray hover:bg-surface-500" %> |
| 77 | </div> |
| 78 | </div> |
| 79 | <% end %> |
| 80 | <% if @commits.empty? %> |
| 81 | <div class="px-4 py-6 text-center text-sm text-gray-400">No commits.</div> |
| 82 | <% end %> |
| 83 | </div> |
| 84 | </div> |
| 85 | |
| 86 | <div> |
| 87 | <h2 class="text-sm font-medium text-gray-300 mb-2">Files changed</h2> |
| 88 | <%= render "shared/diff", diff: @diff %> |
| 89 | </div> |
| 90 | |
| 91 | <div> |
| 92 | <h2 class="text-sm font-medium text-gray-300 mb-2"> |
| 93 | <%= pluralize(@comments.size, "comment") %> |
| 94 | </h2> |
| 95 | <div class="space-y-3"> |
| 96 | <% @comments.each do |comment| %> |
| 97 | <div class="card" id="comment-<%= comment.id %>"> |
| 98 | <div class="px-4 py-2 border-b border-surface-600 bg-surface-700 text-xs text-gray-400"> |
| 99 | <span class="font-medium text-gray-200"><%= comment.author.username %></span> |
| 100 | commented <%= time_ago_in_words(comment.created_at) %> ago |
| 101 | </div> |
| 102 | <div class="px-6 py-4 prose-readme"><%= render_markdown(comment.body) %></div> |
| 103 | </div> |
| 104 | <% end %> |
| 105 | </div> |
| 106 | |
| 107 | <% if signed_in? %> |
| 108 | <%= form_with url: repository_pull_request_comments_path(@owner.username, @repository.name, @pull_request.number), |
| 109 | method: :post, class: "mt-4 space-y-2" do |f| %> |
| 110 | <%= f.label :body, "Add a comment", class: "form-label" %> |
| 111 | <%= f.text_area :body, class: "form-input", rows: 4, placeholder: "Leave a comment", required: true %> |
| 112 | <div class="flex justify-end"> |
| 113 | <%= f.submit "Comment", class: "btn-primary cursor-pointer" %> |
| 114 | </div> |
| 115 | <% end %> |
| 116 | <% else %> |
| 117 | <p class="text-sm text-gray-400 mt-4"> |
| 118 | <%= link_to "Sign in", signin_path, class: "text-brand-500 hover:underline" %> to leave a comment. |
| 119 | </p> |
| 120 | <% end %> |
| 121 | </div> |
| 122 | |
| 123 | <% if @repository.writable_by?(current_user) || @pull_request.user_id == current_user&.id %> |
| 124 | <div class="pt-2 border-t border-surface-600 flex items-center gap-3"> |
| 125 | <% if @pull_request.open? %> |
| 126 | <%= button_to "Close pull request", close_repository_pull_request_path(@owner.username, @repository.name, @pull_request.number), |
| 127 | method: :post, class: "btn-secondary cursor-pointer" %> |
| 128 | <% elsif @pull_request.closed? %> |
| 129 | <%= button_to "Reopen pull request", reopen_repository_pull_request_path(@owner.username, @repository.name, @pull_request.number), |
| 130 | method: :post, class: "btn-secondary cursor-pointer" %> |
| 131 | <% end %> |
| 132 | </div> |
| 133 | <% end %> |
| 134 | </div> |