rin
Public Open-source lightweight git hosting.
repo_settings.html · 267 lines · 13.3 KB
Raw
1 {{define "content"}}
2 {{$repoBg := imageURL .Repo.BackgroundURL}}
3 <div class="container">
4 {{template "repo_header" .}}
5
6 <!-- General Settings -->
7 <section class="card mb-4">
8 <div class="card-header">
9 <span class="font-semibold flex items-center gap-2">{{icon "settings" "size-4"}} {{t .Lang "repo.tab.settings"}}</span>
10 </div>
11 <form method="post" action="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/settings" enctype="multipart/form-data" class="card-body flex flex-col gap-3">
12 <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
13 <input type="hidden" id="repo-avatar-data-input" name="avatar_data" value="">
14 <input type="hidden" id="remove-repo-avatar-input" name="remove_avatar" value="false">
15 <input type="hidden" id="repo-background-data-input" name="background_data" value="">
16 <input type="hidden" id="remove-repo-background-input" name="remove_background" value="false">
17
18 <div class="flex items-center gap-4 flex-wrap pb-3" style="border-bottom:1px solid hsl(var(--border));">
19 <div id="repo-avatar-preview-wrap">
20 {{avatar .Repo.OwnerUsername (or .Repo.AvatarURL .Repo.OwnerAvatarURL) "avatar-xl"}}
21 </div>
22 <div class="flex flex-col gap-1.5">
23 <div class="text-sm font-medium">{{t .Lang "repo.avatar"}}</div>
24 <div class="flex items-center gap-2 flex-wrap">
25 <label class="btn btn-outline btn-sm" style="cursor:pointer;">
26 {{icon "image" "size-3.5"}}
27 <span>{{t .Lang "repo.avatar_upload"}}</span>
28 <input id="repo-avatar-file-input" name="avatar_file" type="file" accept="image/png,image/jpeg,image/webp,image/gif" style="display:none;">
29 </label>
30 {{if .Repo.AvatarURL}}
31 <button type="button" id="remove-repo-avatar-btn" class="btn btn-ghost btn-sm text-destructive">
32 {{icon "trash" "size-3.5"}}
33 <span>{{t .Lang "repo.avatar_remove"}}</span>
34 </button>
35 {{end}}
36 </div>
37 <div class="field-hint" style="margin:0;">{{t .Lang "repo.avatar_hint"}}</div>
38 </div>
39 </div>
40
41 <div class="flex flex-col gap-2 pb-3" style="border-bottom:1px solid hsl(var(--border));">
42 <div class="flex items-center justify-between gap-2 flex-wrap">
43 <div>
44 <div class="text-sm font-medium">{{t .Lang "repo.background"}}</div>
45 <div class="field-hint" style="margin:0;">{{t .Lang "repo.background_hint"}}</div>
46 </div>
47 <div class="flex items-center gap-2 flex-wrap">
48 <label class="btn btn-outline btn-sm" style="cursor:pointer;">
49 {{icon "image" "size-3.5"}}
50 <span>{{t .Lang "repo.background_upload"}}</span>
51 <input id="repo-background-file-input" name="background_file" type="file" accept="image/png,image/jpeg,image/webp,image/gif" style="display:none;">
52 </label>
53 {{if $repoBg}}
54 <button type="button" id="remove-repo-background-btn" class="btn btn-ghost btn-sm text-destructive">
55 {{icon "trash" "size-3.5"}}
56 <span>{{t .Lang "repo.background_remove"}}</span>
57 </button>
58 {{end}}
59 </div>
60 </div>
61 <div id="repo-background-preview" class="background-preview{{if not $repoBg}} is-empty{{end}}">
62 {{if $repoBg}}
63 <img src="{{$repoBg}}" alt="">
64 {{else}}
65 <span class="background-preview-placeholder">{{icon "image" "size-5"}}</span>
66 {{end}}
67 </div>
68 </div>
69
70 <div>
71 <label class="label" for="description">{{t .Lang "repo.description"}}</label>
72 <input id="description" name="description" type="text" class="input" value="{{.Repo.Description}}" maxlength="500" placeholder="{{t .Lang "repo.description_ph"}}">
73 </div>
74
75 <div class="grid-2">
76 <div>
77 <label class="label" for="default_branch">{{t .Lang "repo.default_branch"}}</label>
78 <select id="default_branch" name="default_branch" class="select font-mono">
79 {{if .Branches}}
80 {{range .Branches}}
81 <option value="{{.}}" {{if eq . $.Repo.DefaultBranch}}selected{{end}}>{{.}}</option>
82 {{end}}
83 {{else}}
84 <option value="{{.Repo.DefaultBranch}}" selected>{{.Repo.DefaultBranch}}</option>
85 {{end}}
86 </select>
87 </div>
88
89 <div>
90 <label class="label" for="visibility">{{t .Lang "repo.visibility"}}</label>
91 <select id="visibility" name="visibility" class="select">
92 <option value="public" {{if not .Repo.IsPrivate}}selected{{end}}>{{t .Lang "repo.public"}}</option>
93 <option value="private" {{if .Repo.IsPrivate}}selected{{end}}>{{t .Lang "repo.private"}}</option>
94 </select>
95 </div>
96 </div>
97
98 <!-- Feature Toggles for Repository -->
99 <div class="card p-3 mt-1" style="background:hsl(var(--muted));">
100 <div class="font-semibold text-xs text-muted mb-2 uppercase" style="letter-spacing:0.04em;">{{t .Lang "repo.features"}}</div>
101 <div class="flex flex-col gap-2.5">
102 <label class="flex items-center justify-between cursor-pointer">
103 <span class="flex items-center gap-2 text-sm font-medium">
104 {{icon "issue" "size-4"}}
105 <span>{{t .Lang "repo.tab.issues"}}</span>
106 </span>
107 <input type="checkbox" name="enable_issues" value="true" class="switch" {{if .Repo.EnableIssues}}checked{{end}}>
108 </label>
109 <label class="flex items-center justify-between cursor-pointer">
110 <span class="flex items-center gap-2 text-sm font-medium">
111 {{icon "git-pull-request" "size-4"}}
112 <span>{{t .Lang "repo.tab.pulls"}}</span>
113 </span>
114 <input type="checkbox" name="enable_pulls" value="true" class="switch" {{if .Repo.EnablePulls}}checked{{end}}>
115 </label>
116 <label class="flex items-center justify-between cursor-pointer">
117 <span class="flex items-center gap-2 text-sm font-medium">
118 {{icon "tag" "size-4"}}
119 <span>{{t .Lang "repo.tab.releases"}}</span>
120 </span>
121 <input type="checkbox" name="enable_releases" value="true" class="switch" {{if .Repo.EnableReleases}}checked{{end}}>
122 </label>
123 <label class="flex items-center justify-between cursor-pointer">
124 <span class="flex items-center gap-2 text-sm font-medium">
125 {{icon "activity" "size-4"}}
126 <span>{{t .Lang "repo.tab.activity"}}</span>
127 </span>
128 <input type="checkbox" name="enable_activity" value="true" class="switch" {{if .Repo.EnableActivity}}checked{{end}}>
129 </label>
130 </div>
131 </div>
132
133 <div class="flex items-center justify-end">
134 <button type="submit" class="btn btn-primary btn-sm">{{t .Lang "repo.save"}}</button>
135 </div>
136 </form>
137 </section>
138
139 <!-- Collaborators -->
140 <section class="card mb-4" id="collaborators">
141 <div class="card-header">
142 <span class="font-semibold flex items-center gap-2">{{icon "users" "size-4"}} {{t .Lang "collab.title"}}</span>
143 <span class="text-xs text-muted">{{t .Lang "collab.desc"}}</span>
144 </div>
145
146 <div class="dense-list" style="border-bottom:1px solid hsl(var(--border));">
147 <div class="dense-row" style="min-height:2.6rem;padding:0.45rem 0.85rem;">
148 <div class="flex items-center gap-2.5 min-w-0">
149 {{avatar .Repo.OwnerUsername .Repo.OwnerAvatarURL}}
150 <div class="min-w-0">
151 <a href="/{{.Repo.OwnerUsername}}" class="font-semibold text-sm">{{.Repo.OwnerUsername}}</a>
152 </div>
153 </div>
154 <span class="badge badge-outline">{{t .Lang "collab.owner"}}</span>
155 </div>
156 {{range .Collaborators}}
157 <div class="dense-row" style="min-height:2.6rem;padding:0.45rem 0.85rem;">
158 <div class="flex items-center gap-2.5 min-w-0">
159 {{avatar .Username .AvatarURL}}
160 <div class="min-w-0">
161 <a href="/{{.Username}}" class="font-semibold text-sm">{{.Username}}</a>
162 {{if .FullName}}<div class="text-xs text-muted truncate">{{.FullName}}</div>{{end}}
163 </div>
164 </div>
165 <div class="flex items-center gap-2">
166 <span class="badge badge-outline font-mono">{{if eq .Role "read"}}{{t $.Lang "collab.role_read"}}{{else}}{{t $.Lang "collab.role_write"}}{{end}}</span>
167 {{if $.CanManageCollab}}
168 <form method="post" action="/{{$.Repo.OwnerUsername}}/{{$.Repo.Name}}/settings/collaborators/remove" style="margin:0;">
169 <input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
170 <input type="hidden" name="user_id" value="{{.UserID}}">
171 <button type="submit" class="btn btn-ghost btn-icon" style="width:1.75rem;height:1.75rem;" title="{{t $.Lang "collab.remove"}}">
172 {{icon "close" "size-3.5"}}
173 </button>
174 </form>
175 {{end}}
176 </div>
177 </div>
178 {{else}}
179 <div class="card-body text-xs text-muted">{{t .Lang "collab.empty"}}</div>
180 {{end}}
181 </div>
182
183 {{if .CanManageCollab}}
184 <form method="post" action="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/settings/collaborators/add" class="card-body flex items-end gap-2 flex-wrap">
185 <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
186 <div style="flex:1 1 12rem;">
187 <label class="label" for="collab_username">{{t .Lang "collab.username"}}</label>
188 <input id="collab_username" name="username" type="text" class="input font-mono" placeholder="{{t .Lang "collab.username_ph"}}" required>
189 </div>
190 <div>
191 <label class="label" for="collab_role">{{t .Lang "collab.role"}}</label>
192 <select id="collab_role" name="role" class="select">
193 <option value="write">{{t .Lang "collab.role_write"}}</option>
194 <option value="read">{{t .Lang "collab.role_read"}}</option>
195 </select>
196 </div>
197 <button type="submit" class="btn btn-primary btn-sm">
198 {{icon "plus" "size-3.5"}}
199 <span>{{t .Lang "collab.add"}}</span>
200 </button>
201 </form>
202 {{end}}
203 </section>
204
205 <!-- Rename Repository --> <section class="card mb-4">
206 <div class="card-header">
207 <span class="font-semibold flex items-center gap-2">{{icon "edit" "size-4"}} {{t .Lang "repo.rename"}}</span>
208 </div>
209 <form method="post" action="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/settings/rename" class="card-body flex items-center gap-2">
210 <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
211 <input name="new_name" type="text" class="input font-mono" value="{{.Repo.Name}}" required pattern="^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$">
212 <button type="submit" class="btn btn-outline">{{t .Lang "repo.rename"}}</button>
213 </form>
214 </section>
215
216 <!-- Danger Zone -->
217 <section class="card" style="border-color:hsl(var(--destructive) / 0.45);">
218 <div class="card-header" style="border-bottom-color:hsl(var(--destructive) / 0.2);">
219 <span class="font-semibold text-destructive flex items-center gap-2">{{icon "alert-circle" "size-4"}} {{t .Lang "repo.danger_zone"}}</span>
220 </div>
221 <div class="card-body flex items-center justify-between flex-wrap gap-3">
222 <div>
223 <div class="font-medium text-sm">{{t .Lang "repo.delete"}}</div>
224 <div class="text-xs text-muted">{{t .Lang "repo.delete_desc"}}</div>
225 </div>
226 <button type="button" class="btn btn-destructive btn-sm" data-dialog-open="delete-repo-dialog">
227 {{icon "trash" "size-3.5"}}
228 <span>{{t .Lang "repo.delete"}}</span>
229 </button>
230 </div>
231 </section>
232 </div>
233
234 <!-- Delete Confirmation Modal -->
235 <div id="delete-repo-dialog" class="backdrop" role="dialog" aria-modal="true" aria-label="{{t .Lang "repo.delete"}}" aria-hidden="true">
236 <div class="dialog-box">
237 <div class="card-header">
238 <span class="font-semibold text-destructive flex items-center gap-2">{{icon "trash" "size-4"}} {{t .Lang "repo.delete"}}</span>
239 <button type="button" class="btn btn-ghost btn-icon" data-dialog-close aria-label="{{t .Lang "common.close"}}">{{icon "close" "size-4"}}</button>
240 </div>
241 <form method="post" action="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/settings/delete">
242 <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
243 <div class="card-body flex flex-col gap-3">
244 <p class="text-sm text-muted" style="margin:0;">
245 {{t .Lang "repo.delete_confirm"}}: <strong class="font-mono" style="color:hsl(var(--foreground));">{{.Repo.Name}}</strong>
246 </p>
247 <input
248 type="text"
249 name="confirm_name"
250 class="input font-mono"
251 placeholder="{{.Repo.Name}}"
252 autocomplete="off"
253 required
254 data-confirm-input="{{.Repo.Name}}"
255 data-confirm-button="confirm-delete-btn">
256 </div>
257 <div class="card-footer flex items-center justify-end gap-2">
258 <button type="button" class="btn btn-outline btn-sm" data-dialog-close>{{t .Lang "common.cancel"}}</button>
259 <button id="confirm-delete-btn" type="submit" class="btn btn-destructive btn-sm" disabled>
260 {{icon "trash" "size-3.5"}}
261 <span>{{t .Lang "repo.delete"}}</span>
262 </button>
263 </div>
264 </form>
265 </div>
266 </div>
267 {{end}}