rin
Публичный Open-source lightweight git hosting.
release_edit.html · 110 строк · 5.2 KB
Raw
1 {{define "content"}}
2 <div class="container">
3 {{template "repo_header" .}}
4
5 <section class="card mb-4">
6 <div class="card-header flex items-center justify-between flex-wrap gap-2">
7 <span class="font-semibold text-sm flex items-center gap-2">
8 {{icon "edit" "size-4"}}
9 <span>{{t .Lang "releases.edit_title"}}</span>
10 </span>
11 <a href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/tree/{{.Release.TagName}}" class="badge font-mono text-xs flex items-center gap-1">
12 {{icon "tag" "size-3"}}
13 <span>{{.Release.TagName}}</span>
14 </a>
15 </div>
16 <form method="post" action="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/releases/{{.Release.ID}}/edit" enctype="multipart/form-data" class="card-body flex flex-col gap-3">
17 <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
18
19 <div>
20 <label class="label" for="title">{{t .Lang "releases.title_ph"}}</label>
21 <input id="title" name="title" type="text" class="input" placeholder="{{t .Lang "releases.title_ph"}}" maxlength="200" value="{{.Release.Title}}" autofocus>
22 </div>
23
24 <div>
25 <label class="label" for="body">{{t .Lang "releases.body"}}</label>
26 <textarea id="body" name="body" class="textarea" rows="8" placeholder="{{t .Lang "releases.body_ph"}}" maxlength="50000">{{.Release.Body}}</textarea>
27 </div>
28
29 {{if .Assets}}
30 <div class="flex flex-col gap-1.5">
31 <div class="label" style="margin-bottom:0;">{{t .Lang "releases.current_assets"}}</div>
32 {{range .Assets}}
33 <div class="flex items-center justify-between gap-3">
34 <a href="/{{$.Repo.OwnerUsername}}/{{$.Repo.Name}}/releases/{{$.Release.ID}}/assets/{{.ID}}/download" class="flex items-center gap-2 text-xs font-mono font-medium hover:underline min-w-0" style="color:hsl(var(--primary));">
35 {{icon "file" "size-3.5"}}
36 <span class="truncate">{{.Filename}}</span>
37 </a>
38 <div class="flex items-center gap-2 flex-shrink-0">
39 <span class="text-xs text-muted">{{formatSize .Size}}</span>
40 <form method="post" action="/{{$.Repo.OwnerUsername}}/{{$.Repo.Name}}/releases/{{$.Release.ID}}/assets/{{.ID}}/delete" onsubmit="return confirm('{{t $.Lang "releases.asset_delete_confirm"}}');" style="margin:0;">
41 <input type="hidden" name="_csrf" value="{{$.CSRFToken}}">
42 <input type="hidden" name="next" value="/{{$.Repo.OwnerUsername}}/{{$.Repo.Name}}/releases/{{$.Release.ID}}/edit">
43 <button type="submit" class="btn btn-ghost btn-icon text-muted" style="width:1.6rem;height:1.6rem;" title="{{t $.Lang "releases.asset_delete"}}">
44 {{icon "trash" "size-3"}}
45 </button>
46 </form>
47 </div>
48 </div>
49 {{end}}
50 </div>
51 {{end}}
52
53 <div class="flex flex-col gap-1">
54 <label class="label" for="assets" style="margin-bottom:0;">{{t .Lang "releases.add_assets"}}</label>
55 <label class="upload-drop" id="assets-drop" for="assets">
56 {{icon "upload" "size-5"}}
57 <span class="text-sm font-medium">{{t .Lang "file.upload_pick"}}</span>
58 <span class="text-xs">{{t .Lang "releases.assets_upload_hint"}}</span>
59 <input id="assets" name="assets" type="file" multiple style="display:none;">
60 </label>
61 <div id="assets-list" class="text-xs font-mono text-muted"></div>
62 </div>
63
64 <div>
65 <label class="flex items-center gap-2 cursor-pointer text-sm">
66 <input type="checkbox" name="is_prerelease" value="true" class="switch" {{if .Release.IsPrerelease}}checked{{end}}>
67 <span>{{t .Lang "releases.is_prerelease"}}</span>
68 </label>
69 </div>
70
71 <div class="flex items-center justify-between gap-2 flex-wrap">
72 <span class="text-xs text-muted">{{t .Lang "releases.tag_locked"}}</span>
73 <div class="flex items-center gap-2">
74 <a href="/{{.Repo.OwnerUsername}}/{{.Repo.Name}}/releases#{{.Release.TagName}}" class="btn btn-ghost btn-sm">{{t .Lang "common.cancel"}}</a>
75 <button type="submit" class="btn btn-primary btn-sm">
76 {{icon "check" "size-3.5"}}
77 <span>{{t .Lang "releases.save_btn"}}</span>
78 </button>
79 </div>
80 </div>
81 </form>
82 </section>
83 </div>
84 <script>
85 (function () {
86 var input = document.getElementById('assets');
87 var drop = document.getElementById('assets-drop');
88 var list = document.getElementById('assets-list');
89 if (!input || !drop || !list) return;
90 function render() {
91 var names = [];
92 for (var i = 0; i < input.files.length; i++) names.push(input.files[i].name);
93 list.textContent = names.length ? names.join(' · ') : '';
94 }
95 input.addEventListener('change', render);
96 ['dragover', 'dragenter'].forEach(function (ev) {
97 drop.addEventListener(ev, function (e) { e.preventDefault(); drop.classList.add('drag'); });
98 });
99 ['dragleave', 'drop'].forEach(function (ev) {
100 drop.addEventListener(ev, function (e) { e.preventDefault(); drop.classList.remove('drag'); });
101 });
102 drop.addEventListener('drop', function (e) {
103 if (e.dataTransfer && e.dataTransfer.files.length) {
104 input.files = e.dataTransfer.files;
105 render();
106 }
107 });
108 })();
109 </script>
110 {{end}}