main
erb 206 lines 12.5 KB
Raw
1 <% content_for :title, @repository.full_name %>
2 <%= render "shared/repository_social", repository: @repository %>
3 <% content_for :structured_data, repository_structured_data(@repository) %>
4
5 <div class="border-b border-surface-600 bg-surface-800">
6 <div class="max-w-6xl mx-auto px-4 sm:px-6 pt-6 pb-0">
7
8 <div class="flex items-center gap-2 text-sm mb-4">
9 <svg class="w-4 h-4 text-gray-500" viewBox="0 0 16 16" fill="currentColor">
10 <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8Z"/>
11 </svg>
12 <%= link_to "@#{@owner.username}", user_profile_path(@owner.username),
13 class: "text-brand-500 hover:underline font-medium" %>
14 <span class="text-gray-500">/</span>
15 <%= link_to @repository.name, repository_path(@owner.username, @repository.name),
16 class: "text-brand-500 hover:underline font-semibold" %>
17 <% if @repository.is_private %>
18 <span class="badge-gray ml-1">Private</span>
19 <% end %>
20 <% if @repository.mirror? %>
21 <span class="badge-gray ml-1">Mirror · read-only</span>
22 <% end %>
23 </div>
24
25 <% if @repository.mirror? %>
26 <div class="border border-surface-500 bg-surface-700/40 rounded px-4 py-3 mb-4 flex flex-wrap items-center justify-between gap-3">
27 <div class="min-w-0">
28 <p class="text-sm text-gray-200">
29 Mirrored from <span class="text-gray-100 break-all"><%= @repository.upstream_url %></span>
30 </p>
31 <p class="text-xs <%= @repository.mirror_status == 'failed' ? 'text-red-400' : 'text-gray-500' %>">
32 <%= @repository.mirror_state_label %><%= " — #{@repository.mirror_error}" if @repository.mirror_status == 'failed' && @repository.mirror_error.present? %>
33 </p>
34 </div>
35 <% if signed_in? && current_user == @owner %>
36 <div class="flex items-center gap-2 shrink-0">
37 <%= button_to "Sync now", repository_mirror_sync_path(@owner.username, @repository.name),
38 method: :post, class: "btn-ghost text-xs py-1 px-2 cursor-pointer" %>
39 <%= button_to "Detach", repository_mirror_detach_path(@owner.username, @repository.name),
40 method: :post, class: "btn-secondary text-xs py-1 px-2 cursor-pointer",
41 form: { data: { turbo_confirm: "Detach this mirror? It becomes a normal writable repo and stops syncing from upstream." } } %>
42 </div>
43 <% end %>
44 </div>
45 <% end %>
46
47 <% if @repository.description.present? %>
48 <p class="text-sm text-gray-400 mb-4"><%= @repository.description %></p>
49 <% end %>
50
51 <div class="flex items-center gap-0 -mb-px">
52 <%= link_to repository_path(@owner.username, @repository.name),
53 class: "tab-item active flex items-center gap-1.5" do %>
54 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
55 <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8Z"/>
56 </svg>
57 Code
58 <% end %>
59 <% if @repository.initialized? %>
60 <%= link_to repository_commits_path(@owner.username, @repository.name,
61 @branch || @repository.default_branch),
62 class: "tab-item flex items-center gap-1.5" do %>
63 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
64 <path d="M11.93 8.5a4.002 4.002 0 0 1-7.86 0H.75a.75.75 0 0 1 0-1.5h3.32a4.002 4.002 0 0 1 7.86 0h3.32a.75.75 0 0 1 0 1.5Zm-1.43-.75a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"/>
65 </svg>
66 Commits
67 <% if @commit_count&.> 0 %>
68 <span class="badge-gray text-xs"><%= number_with_delimiter(@commit_count) %></span>
69 <% end %>
70 <% end %>
71 <% end %>
72 <%= link_to repository_pull_requests_path(@owner.username, @repository.name),
73 class: "tab-item flex items-center gap-1.5" do %>
74 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
75 <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM12 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"/>
76 </svg>
77 Pulls
78 <% if @repository.open_pull_requests_count > 0 %>
79 <span class="badge-gray text-xs"><%= number_with_delimiter(@repository.open_pull_requests_count) %></span>
80 <% end %>
81 <% end %>
82 <%= link_to repository_cicd_path(@owner.username, @repository.name),
83 class: "tab-item flex items-center gap-1.5" do %>
84 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
85 <path d="M4.75 4.5C2.679 4.5 1 5.958 1 7.75S2.679 11 4.75 11c1.028 0 1.948-.36 2.75-1.242l.652-.716.696.672C10.023 10.849 10.956 11 11.25 11 13.321 11 15 9.542 15 7.75S13.321 4.5 11.25 4.5c-1.028 0-1.948.36-2.75 1.242l-.652.716-.696-.672C5.977 4.651 5.044 4.5 4.75 4.5Zm0 1.5c.483 0 .943.152 1.36.556l.562.541-.562.618C5.693 8.119 5.233 8.5 4.75 8.5c-1.241 0-2.25-.672-2.25-1.5S3.509 6 4.75 6Zm6.5 0c1.241 0 2.25.672 2.25 1.5S12.491 9 11.25 9c-.483 0-.943-.152-1.36-.556l-.562-.541.562-.618c.417-.404.877-.785 1.36-.785Z"/>
86 </svg>
87 CI/CD
88 <% if @commit_count&.> 0 %>
89 <span class="badge-gray text-xs"><%= number_with_delimiter(@commit_count) %></span>
90 <% end %>
91 <% end %>
92 </div>
93 </div>
94 </div>
95
96 <div class="max-w-6xl mx-auto px-4 sm:px-6 py-6">
97 <% if @empty %>
98 <div class="card p-8 text-center max-w-2xl mx-auto">
99 <svg class="w-16 h-16 mx-auto text-gray-600 mb-5" viewBox="0 0 24 24"
100 fill="none" stroke="currentColor" stroke-width="1"
101 stroke-linecap="round" stroke-linejoin="round">
102 <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/>
103 </svg>
104 <h2 class="text-lg font-semibold text-gray-100 mb-2">This repository is empty</h2>
105 <p class="text-sm text-gray-400 mb-6">Push something and it'll show up here.</p>
106 <div class="code-container text-left p-4 max-w-lg mx-auto text-xs font-mono space-y-0.5">
107 <p class="text-gray-500 mb-1"># Clone and push</p>
108 <p class="text-gray-300">git clone git@sigitsi.com:<%= @owner.username %>/<%= @repository.name %></p>
109 <p class="text-gray-300">cd <%= @repository.name %></p>
110 <p class="text-gray-300">echo "# <%= @repository.name %>" &gt; README.md</p>
111 <p class="text-gray-300">git add . &amp;&amp; git commit -m "Initial commit"</p>
112 <p class="text-gray-300">git push origin main</p>
113 </div>
114 </div>
115 <% else %>
116
117 <div class="card rounded-b-none border-b-0 px-4 py-2.5
118 flex items-center justify-between gap-4 bg-surface-600">
119 <div class="flex items-center gap-3">
120 <%= render "shared/branch_switcher",
121 branches: @branches,
122 current_branch: @branch,
123 branch_url: ->(b) { repository_path(@owner.username, @repository.name, branch: b) } %>
124 <% if @recent_commits.first %>
125 <% commit = @recent_commits.first %>
126 <span class="text-xs text-gray-400">
127 <%= link_to commit[:short_sha],
128 repository_commit_path(@owner.username, @repository.name, commit[:sha]),
129 class: "font-mono text-brand-500 hover:underline" %>
130 &middot; <%= commit[:subject] %>
131 &middot; <span class="text-gray-500"><%= time_ago_in_words(commit[:authored_date]) %> ago</span>
132 </span>
133 <% end %>
134 </div>
135 <div class="flex items-center gap-3 text-xs text-gray-400">
136 <%= link_to repository_commits_path(@owner.username, @repository.name, @branch),
137 class: "flex items-center gap-1 hover:text-gray-200" do %>
138 <svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
139 <path d="M11.93 8.5a4.002 4.002 0 0 1-7.86 0H.75a.75.75 0 0 1 0-1.5h3.32a4.002 4.002 0 0 1 7.86 0h3.32a.75.75 0 0 1 0 1.5Zm-1.43-.75a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"/>
140 </svg>
141 <%= number_with_delimiter(@commit_count) %> commits
142 <% end %>
143
144 <details class="clone-menu relative">
145 <summary class="btn-secondary py-1 px-3 text-xs flex items-center gap-1.5 cursor-pointer list-none">
146 <svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
147 <path d="M2.75 2.5a.75.75 0 0 0-.75.75v9.5c0 .414.336.75.75.75h10.5a.75.75 0 0 0 .75-.75v-9.5a.75.75 0 0 0-.75-.75ZM4 6.25A.75.75 0 0 1 4.75 5.5h6.5a.75.75 0 0 1 0 1.5h-6.5A.75.75 0 0 1 4 6.25Zm.75 2.25a.75.75 0 0 0 0 1.5h4.5a.75.75 0 0 0 0-1.5Z"/>
148 </svg>
149 Clone
150 </summary>
151 <div class="absolute right-0 mt-2 w-80 z-10 card p-3 space-y-3 text-left">
152 <% [["HTTPS", @clone_https_url], ["SSH", @clone_ssh_url]].each do |label, url| %>
153 <div data-controller="clipboard" data-clipboard-text-value="<%= url %>">
154 <div class="text-[11px] uppercase tracking-wide text-gray-500 mb-1"><%= label %></div>
155 <div class="flex items-center gap-2">
156 <input type="text" readonly value="<%= url %>"
157 class="flex-1 bg-surface-800 border border-surface-600 rounded px-2 py-1 text-xs font-mono text-gray-200 focus:outline-none"
158 onclick="this.select()">
159 <button type="button" data-action="clipboard#copy"
160 class="btn-ghost text-xs py-1 px-2.5 shrink-0">Copy</button>
161 </div>
162 </div>
163 <% end %>
164 </div>
165 </details>
166 </div>
167 </div>
168
169 <div class="card rounded-t-none">
170 <% @tree.each do |entry| %>
171 <div class="file-row">
172 <% if entry[:type] == "tree" %>
173 <svg class="w-4 h-4 text-brand-400 shrink-0" viewBox="0 0 16 16" fill="currentColor">
174 <path d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1Z"/>
175 </svg>
176 <%= link_to entry[:name],
177 repository_tree_path(@owner.username, @repository.name, @branch, entry[:path]),
178 class: "text-brand-500 hover:underline font-medium flex-1" %>
179 <% else %>
180 <svg class="w-4 h-4 text-gray-500 shrink-0" viewBox="0 0 16 16" fill="currentColor">
181 <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688Z"/>
182 </svg>
183 <%= link_to entry[:name],
184 repository_blob_path(@owner.username, @repository.name, @branch, entry[:path]),
185 class: "text-gray-200 hover:text-brand-500 hover:underline flex-1" %>
186 <% end %>
187 </div>
188 <% end %>
189 </div>
190
191 <% if @readme_html %>
192 <div class="card mt-6">
193 <div class="px-4 py-3 border-b border-surface-600 flex items-center gap-2 bg-surface-600">
194 <svg class="w-4 h-4 text-gray-500" viewBox="0 0 16 16" fill="currentColor">
195 <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"/>
196 </svg>
197 <span class="text-xs font-medium text-gray-400"><%= @readme_filename %></span>
198 </div>
199 <div class="px-6 py-6 prose-readme" data-controller="code-copy">
200 <%= @readme_html %>
201 </div>
202 </div>
203 <% end %>
204
205 <% end %>
206 </div>