Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -245,19 +245,25 @@ require (
github.com/prometheus/common v0.63.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rhysd/actionlint v1.7.7 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/tiendc/go-deepcopy v1.6.0 // indirect
github.com/unknwon/com v1.0.1 // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xuri/efp v0.0.1 // indirect
github.com/xuri/excelize/v2 v2.9.1 // indirect
github.com/xuri/nfp v0.0.1 // indirect
github.com/zeebo/assert v1.3.0 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
go.etcd.io/bbolt v1.4.0 // indirect
Expand Down
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,11 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhysd/actionlint v1.7.7 h1:0KgkoNTrYY7vmOCs9BW2AHxLvvpoY9nEUzgBHiPUr0k=
github.com/rhysd/actionlint v1.7.7/go.mod h1:AE6I6vJEkNaIfWqC2GNE5spIJNhxf8NCtLEKU4NnUXg=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand Down Expand Up @@ -678,6 +683,8 @@ github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08Yu
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tiendc/go-deepcopy v1.6.0 h1:0UtfV/imoCwlLxVsyfUd4hNHnB3drXsfle+wzSCA5Wo=
github.com/tiendc/go-deepcopy v1.6.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
Expand Down Expand Up @@ -711,6 +718,12 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8=
github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.9.1 h1:VdSGk+rraGmgLHGFaGG9/9IWu1nj4ufjJ7uwMDtj8Qw=
github.com/xuri/excelize/v2 v2.9.1/go.mod h1:x7L6pKz2dvo9ejrRuD8Lnl98z4JLt0TGAwjhW+EiP8s=
github.com/xuri/nfp v0.0.1 h1:MDamSGatIvp8uOmDP8FnmjuQpu90NzdJxo7242ANR9Q=
github.com/xuri/nfp v0.0.1/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3539,6 +3539,7 @@ review_dismissed_reason = Reason:
create_branch = created branch <a href="%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a>
starred_repo = starred <a href="%[1]s">%[2]s</a>
watched_repo = started watching <a href="%[1]s">%[2]s</a>
export_to_excel = Export to Excel
[tool]
now = now
Expand Down
39 changes: 30 additions & 9 deletions routers/web/repo/issue_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
shared_user "code.gitea.io/gitea/routers/web/shared/user"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/export"
issue_service "code.gitea.io/gitea/services/issue"
pull_service "code.gitea.io/gitea/services/pull"
)
Expand Down Expand Up @@ -258,14 +259,13 @@
return user.ID
}

// SearchRepoIssuesJSON lists the issues of a repository
// This function was copied from API (decouple the web and API routes),
// it is only used by frontend to search some dependency or related issues
func SearchRepoIssuesJSON(ctx *context.Context) {
func SearchRepoIssues(ctx *context.Context) (issues_model.IssueList, int64) {
before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil {
ctx.HTTPError(http.StatusUnprocessableEntity, err.Error())
return
return nil, 0
}

var isClosed optional.Option[bool]
Expand Down Expand Up @@ -295,7 +295,7 @@
}
if !issues_model.IsErrMilestoneNotExist(err) {
ctx.HTTPError(http.StatusInternalServerError, err.Error())
return
return nil, 0
}
id, err := strconv.ParseInt(part[i], 10, 64)
if err != nil {
Expand Down Expand Up @@ -329,15 +329,15 @@
// FIXME: we should be more efficient here
createdByID := getUserIDForFilter(ctx, "created_by")
if ctx.Written() {
return
return nil, 0
}
assignedByID := getUserIDForFilter(ctx, "assigned_by")
if ctx.Written() {
return
return nil, 0
}
mentionedByID := getUserIDForFilter(ctx, "mentioned_by")
if ctx.Written() {
return
return nil, 0
}

searchOpt := &issue_indexer.SearchOptions{
Expand Down Expand Up @@ -380,18 +380,39 @@
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt)
if err != nil {
ctx.HTTPError(http.StatusInternalServerError, "SearchIssues", err.Error())
return
return nil, 0
}
issues, err := issues_model.GetIssuesByIDs(ctx, ids, true)
if err != nil {
ctx.HTTPError(http.StatusInternalServerError, "FindIssuesByIDs", err.Error())
return
return nil, 0
}

return issues, total
}

// SearchRepoIssuesJSON lists the issues of a repository
func SearchRepoIssuesJSON(ctx *context.Context) {
issues, total := SearchRepoIssues(ctx)

ctx.SetTotalCountHeader(total)
ctx.JSON(http.StatusOK, convert.ToIssueList(ctx, ctx.Doer, issues))
}

func ExportIssues(ctx *context.Context) {
issues, total := SearchRepoIssues(ctx)

if total == 0 {
return
}

f := export.IssuesToExcel(ctx, issues)

ctx.Resp.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

Check failure on line 411 in routers/web/repo/issue_list.go

View workflow job for this annotation

GitHub Actions / lint-backend

File is not properly formatted (gofmt)

Check failure on line 411 in routers/web/repo/issue_list.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

File is not properly formatted (gofmt)

Check failure on line 411 in routers/web/repo/issue_list.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

File is not properly formatted (gofmt)
ctx.Resp.Header().Set("Content-Disposition", `attachment; filename="issues.xlsx"`)
_ = f.Write(ctx.Resp)
}

func BatchDeleteIssues(ctx *context.Context) {
issues := getActionIssues(ctx)
if ctx.Written() {
Expand Down
1 change: 1 addition & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ func registerWebRoutes(m *web.Router) {
m.Get("/choose", repo.NewIssueChooseTemplate)
})
m.Get("/search", repo.SearchRepoIssuesJSON)
m.Get("/export", reqRepoAdmin, repo.ExportIssues)
}, reqUnitIssuesReader)

addIssuesPullsUpdateRoutes := func() {
Expand Down
62 changes: 62 additions & 0 deletions services/export/excel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package export

import (
"fmt"

Check failure on line 7 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

File is not properly formatted (gofumpt)

Check failure on line 7 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

File is not properly formatted (gofumpt)

Check failure on line 7 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

File is not properly formatted (gofumpt)
"github.com/xuri/excelize/v2"

issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/services/context"
)

func IssuesToExcel(ctx *context.Context, issues issues_model.IssueList) *excelize.File {
f := excelize.NewFile()
sheet := f.GetSheetName(f.GetActiveSheetIndex())

headers := []string{"ID", "Title", "Status", "Assignee(s)", "Label(s)", "Created At"}
for col, h := range headers {
cell, _ := excelize.CoordinatesToCellName(col+1, 1)
f.SetCellValue(sheet, cell, h)

Check failure on line 21 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 21 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 21 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
}

for i, issue := range issues {

Check failure on line 24 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

empty-lines: extra empty line at the start of a block (revive)

Check failure on line 24 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

empty-lines: extra empty line at the start of a block (revive)

Check failure on line 24 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

empty-lines: extra empty line at the start of a block (revive)

assignees := ""
if err := issue.LoadAssignees(ctx); err == nil {
if len(issue.Assignees) > 0 {
for _, assignee := range issue.Assignees {
if assignees != "" {
assignees += ", "
}
if assignee.FullName != "" {
assignees += assignee.FullName
} else {
assignees += assignee.Name
}
}
}
}

labels := ""
if err := issue.LoadLabels(ctx); err == nil {
if len(issue.Labels) > 0 {
for _, label := range issue.Labels {
if labels != "" {
labels += ", "
}
labels += label.Name
}
}
}

f.SetCellValue(sheet, fmt.Sprintf("A%d", i+2), issue.Index)

Check failure on line 54 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 54 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 54 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
f.SetCellValue(sheet, fmt.Sprintf("B%d", i+2), issue.Title)

Check failure on line 55 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 55 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 55 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
f.SetCellValue(sheet, fmt.Sprintf("C%d", i+2), issue.State())

Check failure on line 56 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 56 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 56 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
f.SetCellValue(sheet, fmt.Sprintf("D%d", i+2), assignees)

Check failure on line 57 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 57 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 57 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
f.SetCellValue(sheet, fmt.Sprintf("E%d", i+2), labels)

Check failure on line 58 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 58 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 58 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
f.SetCellValue(sheet, fmt.Sprintf("F%d", i+2), issue.CreatedUnix.AsTime()) // .Format("2006-01-02"))

Check failure on line 59 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-backend

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 59 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-windows

Error return value of `f.SetCellValue` is not checked (errcheck)

Check failure on line 59 in services/export/excel.go

View workflow job for this annotation

GitHub Actions / lint-go-gogit

Error return value of `f.SetCellValue` is not checked (errcheck)
}
return f
}
1 change: 1 addition & 0 deletions templates/repo/issue/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<a class="ui small primary small button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.PullRequestCtx.BaseRepo.Link}}/compare/{{.PullRequestCtx.BaseRepo.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{ctx.Locale.Tr "action.compare_commits_general"}}</a>
{{end}}
{{end}}
<a class="ui small primary button issue-list-export" href="{{.RepoLink}}/issues/export?{{.Page.GetParams}}">{{ctx.Locale.Tr "action.export_to_excel"}}</a>
</div>

{{template "repo/issue/filters" .}}
Expand Down
Loading