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