Add the tag list page to the release page (#12096)

* Add the tag list page to the release page

* Add the tags list view
* Add the delete tag way on ui
* Not delete tag and clear message when delete a release

Signed-off-by: a1012112796 <1012112796@qq.com>

* Apply suggestions from code review

Co-authored-by: Cirno the Strongest <1447794+CirnoT@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: zeripath <art27@cantab.net>

* fix ui

* Add to header

* ui

* permission

* ui

* Update options/locale/locale_en-US.ini

Co-authored-by: Lauris BH <lauris@nix.lv>

* tweaks

* monospace commit hashes

* Add read permission check

* fix permission

* fix nit

* Update web_src/less/_base.less

Co-authored-by: silverwind <me@silverwind.io>

* ui fixes

* title tweaks

* fix lint

* fix test

* fix test and some ui nits

* Apply suggestions from code review

Co-authored-by: silverwind <me@silverwind.io>

Co-authored-by: Cirno the Strongest <1447794+CirnoT@users.noreply.github.com>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
a1012112796 2020-11-03 07:10:22 +08:00 committed by GitHub
parent bcb94ed589
commit b687707014
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 213 additions and 65 deletions

View File

@ -52,7 +52,7 @@ func checkLatestReleaseAndCount(t *testing.T, session *TestSession, repoURL, ver
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
labelText := htmlDoc.doc.Find("#release-list > li .meta .label").First().Text() labelText := htmlDoc.doc.Find("#release-list > li .meta .label").First().Text()
assert.EqualValues(t, label, labelText) assert.EqualValues(t, label, labelText)
titleText := htmlDoc.doc.Find("#release-list > li .detail h3 a").First().Text() titleText := htmlDoc.doc.Find("#release-list > li .detail h4 a").First().Text()
assert.EqualValues(t, version, titleText) assert.EqualValues(t, version, titleText)
releaseList := htmlDoc.doc.Find("#release-list > li") releaseList := htmlDoc.doc.Find("#release-list > li")
@ -83,7 +83,7 @@ func TestCreateRelease(t *testing.T) {
session := loginUser(t, "user2") session := loginUser(t, "user2")
createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, false) createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, false)
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.stable"), 3) checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.stable"), 2)
} }
func TestCreateReleasePreRelease(t *testing.T) { func TestCreateReleasePreRelease(t *testing.T) {
@ -92,7 +92,7 @@ func TestCreateReleasePreRelease(t *testing.T) {
session := loginUser(t, "user2") session := loginUser(t, "user2")
createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", true, false) createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", true, false)
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.prerelease"), 3) checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.prerelease"), 2)
} }
func TestCreateReleaseDraft(t *testing.T) { func TestCreateReleaseDraft(t *testing.T) {
@ -101,7 +101,7 @@ func TestCreateReleaseDraft(t *testing.T) {
session := loginUser(t, "user2") session := loginUser(t, "user2")
createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, true) createNewRelease(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", false, true)
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.draft"), 3) checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", i18n.Tr("en", "repo.release.draft"), 2)
} }
func TestCreateReleasePaging(t *testing.T) { func TestCreateReleasePaging(t *testing.T) {

View File

@ -53,7 +53,11 @@ func (r *Release) loadAttributes(e Engine) error {
if r.Publisher == nil { if r.Publisher == nil {
r.Publisher, err = getUserByID(e, r.PublisherID) r.Publisher, err = getUserByID(e, r.PublisherID)
if err != nil { if err != nil {
return err if IsErrUserNotExist(err) {
r.Publisher = NewGhostUser()
} else {
return err
}
} }
} }
return getReleaseAttachments(e, r) return getReleaseAttachments(e, r)

View File

@ -808,7 +808,9 @@ org_labels_desc_manage = manage
milestones = Milestones milestones = Milestones
commits = Commits commits = Commits
commit = Commit commit = Commit
release = Release
releases = Releases releases = Releases
released_this = released this
file_raw = Raw file_raw = Raw
file_history = History file_history = History
file_view_raw = View Raw file_view_raw = View Raw
@ -1796,6 +1798,8 @@ diff.protected = Protected
releases.desc = Track project versions and downloads. releases.desc = Track project versions and downloads.
release.releases = Releases release.releases = Releases
release.detail = Release details
release.tags = Tags
release.new_release = New Release release.new_release = New Release
release.draft = Draft release.draft = Draft
release.prerelease = Pre-Release release.prerelease = Pre-Release
@ -1818,11 +1822,15 @@ release.publish = Publish Release
release.save_draft = Save Draft release.save_draft = Save Draft
release.edit_release = Update Release release.edit_release = Update Release
release.delete_release = Delete Release release.delete_release = Delete Release
release.delete_tag = Delete Tag
release.deletion = Delete Release release.deletion = Delete Release
release.deletion_desc = Deleting a release removes its Git tag from the repository. Repository contents and history remain unchanged. Continue? release.deletion_desc = Deleting a release only removes it from Gitea. Git tag, repository contents and history remain unchanged. Continue?
release.deletion_success = The release has been deleted. release.deletion_success = The release has been deleted.
release.deletion_tag_desc = Will delete this tag from repository. Repository contents and history remain unchanged. Continue?
release.deletion_tag_success = The tag has been deleted.
release.tag_name_already_exist = A release with this tag name already exists. release.tag_name_already_exist = A release with this tag name already exists.
release.tag_name_invalid = The tag name is not valid. release.tag_name_invalid = The tag name is not valid.
release.tag_already_exist = This tag name already exists.
release.downloads = Downloads release.downloads = Downloads
release.download_count = Downloads: %s release.download_count = Downloads: %s

View File

@ -55,10 +55,26 @@ func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *models.Rel
// Releases render releases list page // Releases render releases list page
func Releases(ctx *context.Context) { func Releases(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.release.releases") releasesOrTags(ctx, false)
}
// TagsList render tags list page
func TagsList(ctx *context.Context) {
releasesOrTags(ctx, true)
}
func releasesOrTags(ctx *context.Context, isTagList bool) {
ctx.Data["PageIsReleaseList"] = true ctx.Data["PageIsReleaseList"] = true
ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch
if isTagList {
ctx.Data["Title"] = ctx.Tr("repo.release.tags")
ctx.Data["PageIsTagList"] = true
} else {
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
ctx.Data["PageIsTagList"] = false
}
writeAccess := ctx.Repo.CanWrite(models.UnitTypeReleases) writeAccess := ctx.Repo.CanWrite(models.UnitTypeReleases)
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
@ -68,7 +84,7 @@ func Releases(ctx *context.Context) {
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")), PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
}, },
IncludeDrafts: writeAccess, IncludeDrafts: writeAccess,
IncludeTags: true, IncludeTags: isTagList,
} }
releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts)
@ -83,8 +99,7 @@ func Releases(ctx *context.Context) {
return return
} }
err = models.GetReleaseAttachments(releases...) if err = models.GetReleaseAttachments(releases...); err != nil {
if err != nil {
ctx.ServerError("GetReleaseAttachments", err) ctx.ServerError("GetReleaseAttachments", err)
return return
} }
@ -118,6 +133,7 @@ func Releases(ctx *context.Context) {
} }
ctx.Data["Releases"] = releases ctx.Data["Releases"] = releases
ctx.Data["ReleasesNum"] = len(releases)
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5) pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)
@ -194,6 +210,20 @@ func NewRelease(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.release.new_release") ctx.Data["Title"] = ctx.Tr("repo.release.new_release")
ctx.Data["PageIsReleaseList"] = true ctx.Data["PageIsReleaseList"] = true
ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch
if tagName := ctx.Query("tag"); len(tagName) > 0 {
rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
if err != nil && !models.IsErrReleaseNotExist(err) {
ctx.ServerError("GetRelease", err)
return
}
if rel != nil {
ctx.Data["tag_name"] = rel.TagName
ctx.Data["tag_target"] = rel.Target
ctx.Data["title"] = rel.Title
ctx.Data["content"] = rel.Note
}
}
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
upload.AddUploadContext(ctx, "release") upload.AddUploadContext(ctx, "release")
ctx.HTML(200, tplReleaseNew) ctx.HTML(200, tplReleaseNew)
@ -354,10 +384,30 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
// DeleteRelease delete a release // DeleteRelease delete a release
func DeleteRelease(ctx *context.Context) { func DeleteRelease(ctx *context.Context) {
if err := releaseservice.DeleteReleaseByID(ctx.QueryInt64("id"), ctx.User, true); err != nil { deleteReleaseOrTag(ctx, false)
}
// DeleteTag delete a tag
func DeleteTag(ctx *context.Context) {
deleteReleaseOrTag(ctx, true)
}
func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
if err := releaseservice.DeleteReleaseByID(ctx.QueryInt64("id"), ctx.User, isDelTag); err != nil {
ctx.Flash.Error("DeleteReleaseByID: " + err.Error()) ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
} else { } else {
ctx.Flash.Success(ctx.Tr("repo.release.deletion_success")) if isDelTag {
ctx.Flash.Success(ctx.Tr("repo.release.deletion_tag_success"))
} else {
ctx.Flash.Success(ctx.Tr("repo.release.deletion_success"))
}
}
if isDelTag {
ctx.JSON(200, map[string]interface{}{
"redirect": ctx.Repo.RepoLink + "/tags",
})
return
} }
ctx.JSON(200, map[string]interface{}{ ctx.JSON(200, map[string]interface{}{

View File

@ -896,12 +896,14 @@ func RegisterRoutes(m *macaron.Macaron) {
// Releases // Releases
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Get("/tags", repo.TagsList, repo.MustBeNotEmpty,
reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag))
m.Group("/releases", func() { m.Group("/releases", func() {
m.Get("/", repo.Releases) m.Get("/", repo.Releases)
m.Get("/tag/*", repo.SingleRelease) m.Get("/tag/*", repo.SingleRelease)
m.Get("/latest", repo.LatestRelease) m.Get("/latest", repo.LatestRelease)
m.Get("/attachments/:uuid", repo.GetAttachment) m.Get("/attachments/:uuid", repo.GetAttachment)
}, repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag)) }, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag))
m.Group("/releases", func() { m.Group("/releases", func() {
m.Get("/new", repo.NewRelease) m.Get("/new", repo.NewRelease)
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
@ -909,6 +911,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/attachments", repo.UploadReleaseAttachment) m.Post("/attachments", repo.UploadReleaseAttachment)
m.Post("/attachments/remove", repo.DeleteAttachment) m.Post("/attachments/remove", repo.DeleteAttachment)
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef()) }, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
m.Post("/tags/delete", repo.DeleteTag, reqSignIn,
repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoCodeWriter, context.RepoRef())
m.Group("/releases", func() { m.Group("/releases", func() {
m.Get("/edit/*", repo.EditRelease) m.Get("/edit/*", repo.EditRelease)
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)

View File

@ -157,10 +157,6 @@ func DeleteReleaseByID(id int64, doer *models.User, delTag bool) error {
} }
} else { } else {
rel.IsTag = true rel.IsTag = true
rel.IsDraft = false
rel.IsPrerelease = false
rel.Title = ""
rel.Note = ""
if err = models.UpdateRelease(models.DefaultDBContext(), rel); err != nil { if err = models.UpdateRelease(models.DefaultDBContext(), rel); err != nil {
return fmt.Errorf("Update: %v", err) return fmt.Errorf("Update: %v", err)

View File

@ -3,20 +3,67 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
{{template "base/alert" .}} {{template "base/alert" .}}
<h2 class="ui header"> <h2 class="ui compact small menu header">
{{.i18n.Tr "repo.release.releases"}} {{if .Permission.CanRead $.UnitTypeReleases}}
{{if .CanCreateRelease}} <a class="{{if (not .PageIsTagList)}}active{{end}} item" href="{{.RepoLink}}/releases">{{.i18n.Tr "repo.release.releases"}}</a>
<div class="ui right"> {{end}}
<a class="ui small green button" href="{{$.RepoLink}}/releases/new"> {{if .Permission.CanRead $.UnitTypeCode}}
{{.i18n.Tr "repo.release.new_release"}} <a class="{{if .PageIsTagList}}active{{end}} item" href="{{.RepoLink}}/tags">{{.i18n.Tr "repo.release.tags"}}</a>
</a>
</div>
{{end}} {{end}}
</h2> </h2>
{{if (and .CanCreateRelease (not .PageIsTagList))}}
<a class="ui right small green button" href="{{$.RepoLink}}/releases/new">
{{.i18n.Tr "repo.release.new_release"}}
</a>
{{end}}
{{if .PageIsTagList}}
<div class="ui divider"></div>
{{if gt .ReleasesNum 0}}
<h4 class="ui top attached header">
<div class="five wide column df ac">
{{svg "octicon-tag" 16 "mr-2"}}{{.i18n.Tr "repo.release.tags"}}
</div>
</h4>
<div class="ui attached table segment">
<table class="ui very basic striped fixed table single line" id="tags-table">
<thead></thead>
<tbody class="tag-list">
{{range $idx, $release := .Releases}}
<tr>
<td class="tag">
<h3 class="release-tag-name mb-3">
<a class="df ac" href="{{$.RepoLink}}/src/tag/{{.TagName | EscapePound}}" rel="nofollow">{{.TagName}}</a>
</h3>
<div class="download df ac">
{{if $.Permission.CanRead $.UnitTypeCode}}
<a class="mr-3 mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "mr-2"}}{{ShortSha .Sha1}}</a>
<a class="mr-3" href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.zip" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-2"}}ZIP</a>
<a class="mr-3" href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.tar.gz">{{svg "octicon-file-zip" 16 "mr-2"}}TAR.GZ</a>
{{if (and $.CanCreateRelease $release.IsTag)}}
<a class="mr-3" href="{{$.RepoLink}}/releases/new?tag={{.TagName | EscapePound}}">{{svg "octicon-tag" 16 "mr-2"}}{{$.i18n.Tr "repo.release.new_release"}}</a>
{{end}}
{{if (and ($.Permission.CanWrite $.UnitTypeCode) $release.IsTag)}}
<a class="ui red delete-button mr-3" data-url="{{$.RepoLink}}/tags/delete" data-id="{{.ID}}">
{{svg "octicon-trashcan" 16 "mr-2"}}{{$.i18n.Tr "repo.release.delete_tag"}}
</a>
{{end}}
{{if (not $release.IsTag)}}
<a class="mr-3" href="{{$.RepoLink}}/releases/tag/{{.TagName | EscapePound}}">{{svg "octicon-tag" 16 "mr-2"}}{{$.i18n.Tr "repo.release.detail"}}</a>
{{end}}
{{end}}
</div>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{else}}
<ul id="release-list"> <ul id="release-list">
{{range $idx, $release := .Releases}} {{range $idx, $release := .Releases}}
<li class="ui grid"> <li class="ui grid">
<div class="ui four wide column meta"> <div class="ui four wide column meta mt-2">
{{if .IsTag}} {{if .IsTag}}
{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}} {{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}}
{{else}} {{else}}
@ -28,7 +75,7 @@
<span class="ui green label">{{$.i18n.Tr "repo.release.stable"}}</span> <span class="ui green label">{{$.i18n.Tr "repo.release.stable"}}</span>
{{end}} {{end}}
<span class="tag text blue"> <span class="tag text blue">
<a href="{{$.RepoLink}}/src/tag/{{.TagName | EscapePound}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a> <a class="df ac je" href="{{$.RepoLink}}/src/tag/{{.TagName | EscapePound}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a>
</span> </span>
<span class="commit"> <span class="commit">
<a class="mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "mr-2"}}{{ShortSha .Sha1}}</a> <a class="mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "mr-2"}}{{ShortSha .Sha1}}</a>
@ -57,15 +104,18 @@
{{end}} {{end}}
</div> </div>
{{else}} {{else}}
<h3> <h4 class="release-list-title df ac">
<a href="{{$.RepoLink}}/releases/tag/{{.TagName | EscapePound}}">{{.Title}}</a> <a href="{{$.RepoLink}}/releases/tag/{{.TagName | EscapePound}}">{{.Title}}</a>
{{if $.CanCreateRelease}}<small>(<a href="{{$.RepoLink}}/releases/edit/{{.TagName | EscapePound}}" rel="nofollow">{{$.i18n.Tr "repo.release.edit"}}</a>)</small>{{end}} {{if $.CanCreateRelease}}
</h3> <small class="ml-2">
(<a href="{{$.RepoLink}}/releases/edit/{{.TagName | EscapePound}}" rel="nofollow">{{$.i18n.Tr "repo.release.edit"}}</a>)
</small>
{{end}}
</h4>
<p class="text grey"> <p class="text grey">
<span class="author"> <span class="author">
{{if .OriginalAuthor}} {{if .OriginalAuthor}}
{{svg "octicon-mark-github"}} {{svg "octicon-mark-github" 16 "mr-2"}}{{.OriginalAuthor}}
{{.OriginalAuthor}}
{{else if .Publisher}} {{else if .Publisher}}
<img class="img-10" src="{{.Publisher.RelAvatarLink}}"> <img class="img-10" src="{{.Publisher.RelAvatarLink}}">
<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a> <a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a>
@ -73,41 +123,44 @@
Ghost Ghost
{{end}} {{end}}
</span> </span>
{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span> | {{end}} <span class="released">
{{$.i18n.Tr "repo.released_this"}}
</span>
{{if .CreatedUnix}}
<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span> |
{{end}}
<span class="ahead"><a href="{{$.RepoLink}}/compare/{{.TagName | EscapePound}}...{{.Target}}">{{$.i18n.Tr "repo.release.ahead.commits" .NumCommitsBehind | Str2html}}</a> {{$.i18n.Tr "repo.release.ahead.target" .Target}}</span> <span class="ahead"><a href="{{$.RepoLink}}/compare/{{.TagName | EscapePound}}...{{.Target}}">{{$.i18n.Tr "repo.release.ahead.commits" .NumCommitsBehind | Str2html}}</a> {{$.i18n.Tr "repo.release.ahead.target" .Target}}</span>
</p> </p>
<div class="markdown desc"> <div class="markdown desc">
{{Str2html .Note}} {{Str2html .Note}}
</div> </div>
<div class="download"> <div class="ui accordion download">
<div class="ui accordion"> <h2 class="title {{if eq $idx 0}}active{{end}} df ac mb-0">
<h2 class="title {{if eq $idx 0}}active{{end}}"> {{svg "octicon-triangle-right" 14 "dropdown icon"}}
{{svg "octicon-triangle-down" 14 "dropdown icon"}} {{$.i18n.Tr "repo.release.downloads"}}
{{$.i18n.Tr "repo.release.downloads"}} </h2>
</h2> <div class="content {{if eq $idx 0}}active{{end}}">
<div class="content {{if eq $idx 0}}active{{end}}"> <ul class="list">
<ul class="list"> {{if $.Permission.CanRead $.UnitTypeCode}}
{{if $.Permission.CanRead $.UnitTypeCode}} <li>
<a href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.zip" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "mr-2"}}{{$.i18n.Tr "repo.release.source_code"}} (ZIP)</strong></a>
</li>
<li>
<a href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.tar.gz"><strong>{{svg "octicon-file-zip" 16 "mr-2"}}{{$.i18n.Tr "repo.release.source_code"}} (TAR.GZ)</strong></a>
</li>
{{end}}
{{if .Attachments}}
{{range .Attachments}}
<li> <li>
<a href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.zip" rel="nofollow"><strong>{{svg "octicon-file-zip"}} {{$.i18n.Tr "repo.release.source_code"}} (ZIP)</strong></a> <span class="ui text right" data-tooltip="{{$.i18n.Tr "repo.release.download_count" (.DownloadCount | PrettyNumber)}}" data-position="bottom right">{{svg "octicon-info"}}</span>
</li> <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
<li> <strong><span class="ui image" title='{{.Name}}'>{{svg "octicon-package" 16 "mr-2"}}</span>{{.Name}}</strong>
<a href="{{$.RepoLink}}/archive/{{.TagName | EscapePound}}.tar.gz"><strong>{{svg "octicon-file-zip"}} {{$.i18n.Tr "repo.release.source_code"}} (TAR.GZ)</strong></a> <span class="ui text grey right">{{.Size | FileSize}}</span>
</a>
</li> </li>
{{end}} {{end}}
{{if .Attachments}} {{end}}
{{range .Attachments}} </ul>
<li>
<span class="ui text right" data-tooltip="{{$.i18n.Tr "repo.release.download_count" (.DownloadCount | PrettyNumber)}}" data-position="bottom right">{{svg "octicon-info"}}</span>
<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
<strong><span class="ui image" title='{{.Name}}'>{{svg "octicon-package"}}</span> {{.Name}}</strong>
<span class="ui text grey right">{{.Size | FileSize}}</span>
</a>
</li>
{{end}}
{{end}}
</ul>
</div>
</div> </div>
</div> </div>
{{end}} {{end}}
@ -116,7 +169,22 @@
</li> </li>
{{end}} {{end}}
</ul> </ul>
{{end}}
{{template "base/paginate" .}} {{template "base/paginate" .}}
</div> </div>
</div> </div>
{{if (and ($.Permission.CanWrite $.UnitTypeCode) .PageIsTagList)}}
<div class="ui small basic delete modal">
<div class="ui header">
{{svg "octicon-trashcan" 16 "mr-2"}}
{{.i18n.Tr "repo.release.delete_tag"}}
</div>
<div class="content">
<p>{{.i18n.Tr "repo.release.deletion_tag_desc"}}</p>
</div>
{{template "base/delete_modal_actions" .}}
</div>
{{end}}
{{template "base/footer" .}} {{template "base/footer" .}}

View File

@ -5,11 +5,14 @@
<div class="item{{if .PageIsCommits}} active{{end}}"> <div class="item{{if .PageIsCommits}} active{{end}}">
<a class="ui" href="{{.RepoLink}}/commits{{if .IsViewBranch}}/branch{{else if .IsViewTag}}/tag{{else if .IsViewCommit}}/commit{{end}}/{{EscapePound .BranchName}}">{{svg "octicon-history"}} <b>{{.CommitsCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }}</a> <a class="ui" href="{{.RepoLink}}/commits{{if .IsViewBranch}}/branch{{else if .IsViewTag}}/tag{{else if .IsViewCommit}}/commit{{end}}/{{EscapePound .BranchName}}">{{svg "octicon-history"}} <b>{{.CommitsCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }}</a>
</div> </div>
{{end}}
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo) }}
<div class="item{{if .PageIsBranches}} active{{end}}"> <div class="item{{if .PageIsBranches}} active{{end}}">
<a class="ui" href="{{.RepoLink}}/branches/">{{svg "octicon-git-branch"}} <b>{{.BranchesCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .BranchesCount "repo.branch" "repo.branches") }}</a> <a class="ui" href="{{.RepoLink}}/branches/">{{svg "octicon-git-branch"}} <b>{{.BranchesCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .BranchesCount "repo.branch" "repo.branches") }}</a>
</div> </div>
{{if $.Permission.CanRead $.UnitTypeCode}}
<div class="item">
<a class="ui" href="{{.RepoLink}}/tags">{{svg "octicon-tag"}} <b>{{.NumReleases}}</b> {{.i18n.Tr (TrN .i18n.Lang .NumReleases "repo.release" "repo.releases") }}</a>
</div>
{{end}}
<div class="item"> <div class="item">
<span class="ui">{{svg "octicon-database"}} <b>{{SizeFmt .Repository.Size}}</b></span> <span class="ui">{{svg "octicon-database"}} <b>{{SizeFmt .Repository.Size}}</b></span>
</div> </div>

View File

@ -1901,6 +1901,12 @@
margin-top: 20px; margin-top: 20px;
padding-top: 15px; padding-top: 15px;
.release-list-title {
font-size: 2rem;
font-weight: normal;
margin-top: -6px;
}
> li { > li {
list-style: none; list-style: none;
@ -1926,7 +1932,7 @@
} }
.detail { .detail {
border-left: 1px solid #dddddd; border-left: 2px solid #dddddd;
.author { .author {
img { img {
@ -1965,7 +1971,7 @@
.dot { .dot {
width: 9px; width: 9px;
height: 9px; height: 9px;
background-color: #cccccc; background-color: #ddd;
z-index: 999; z-index: 999;
position: absolute; position: absolute;
display: block; display: block;
@ -1977,6 +1983,13 @@
} }
} }
} }
#tags-table {
.release-tag-name {
font-size: 1.5rem;
font-weight: normal;
}
}
} }
&.new.release { &.new.release {

View File

@ -1,6 +1,8 @@
.df { display: flex; } .df { display: flex; }
.ac { align-items: center; } .ac { align-items: center; }
.jc { justify-content: center; } .jc { justify-content: center; }
.js { justify-content: flex-start; }
.je { justify-content: flex-end; }
.sb { justify-content: space-between; } .sb { justify-content: space-between; }
.m-0 { margin: 0 !important; } .m-0 { margin: 0 !important; }

View File

@ -1510,7 +1510,7 @@ input {
.ui.radio.checkbox label::after, .ui.radio.checkbox label::after,
.ui.radio.checkbox input:checked ~ label::after, .ui.radio.checkbox input:checked ~ label::after,
.ui.radio.checkbox input:focus ~ label::after, .ui.radio.checkbox input:focus ~ label::after,
.ui.radio.checkbox input:focus:checked ~ label::after, { .ui.radio.checkbox input:focus:checked ~ label::after {
background: #dbdbdb; background: #dbdbdb;
} }
@ -2075,7 +2075,7 @@ footer .container .links > * {
} }
.repository.release #release-list > li .detail .dot { .repository.release #release-list > li .detail .dot {
background-color: #888; background-color: #505667;
border-color: #383c4a; border-color: #383c4a;
} }