diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go
index 921dd9973..d46e1756c 100644
--- a/models/issues/issue_search.go
+++ b/models/issues/issue_search.go
@@ -36,6 +36,7 @@ type IssuesOptions struct { //nolint
ProjectBoardID int64
IsClosed optional.Option[bool]
IsPull optional.Option[bool]
+ IsDiscussion optional.Option[bool]
LabelIDs []int64
IncludedLabelNames []string
ExcludedLabelNames []string
diff --git a/modules/indexer/issues/dboptions.go b/modules/indexer/issues/dboptions.go
index 8f9408874..25e1c36d7 100644
--- a/modules/indexer/issues/dboptions.go
+++ b/modules/indexer/issues/dboptions.go
@@ -10,12 +10,14 @@ import (
)
func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOptions {
+
searchOpt := &SearchOptions{
- Keyword: keyword,
- RepoIDs: opts.RepoIDs,
- AllPublic: opts.AllPublic,
- IsPull: opts.IsPull,
- IsClosed: opts.IsClosed,
+ Keyword: keyword,
+ RepoIDs: opts.RepoIDs,
+ AllPublic: opts.AllPublic,
+ IsPull: opts.IsPull,
+ IsDiscussion: opts.IsDiscussion,
+ IsClosed: opts.IsClosed,
}
if len(opts.LabelIDs) == 1 && opts.LabelIDs[0] == 0 {
diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go
index e9c4eca55..aa00633d4 100644
--- a/modules/indexer/issues/internal/model.go
+++ b/modules/indexer/issues/internal/model.go
@@ -79,8 +79,9 @@ type SearchOptions struct {
RepoIDs []int64 // repository IDs which the issues belong to
AllPublic bool // if include all public repositories
- IsPull optional.Option[bool] // if the issues is a pull request
- IsClosed optional.Option[bool] // if the issues is closed
+ IsPull optional.Option[bool] // if the issues is a pull request
+ IsDiscussion optional.Option[bool] // if the issues is a discussion
+ IsClosed optional.Option[bool] // if the issues is closed
IncludedLabelIDs []int64 // labels the issues have
ExcludedLabelIDs []int64 // labels the issues don't have
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index afb860cfc..dba8cc8e1 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1214,6 +1214,7 @@ find_tag = Find tag
branches = Branches
tags = Tags
issues = Issues
+discussions=Discussions
pulls = Pull Requests
project_board = Projects
packages = Packages
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 0c8363a16..eaa98f40c 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -141,7 +141,17 @@ func MustAllowPulls(ctx *context.Context) {
}
}
-func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption optional.Option[bool]) {
+func MustAllowDiscussions(ctx *context.Context) {
+ // var repositoryId = ctx.Repo.Repository.ID
+ // TODO: check enable discussions && check enable Read
+ var check = true
+ if !check {
+ ctx.NotFound("MustAllowDiscussions", nil)
+ return
+ }
+}
+
+func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption optional.Option[bool], isDiscussionOption optional.Option[bool]) {
var err error
viewType := ctx.FormString("type")
sortType := ctx.FormString("sort")
@@ -213,6 +223,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ReviewRequestedID: reviewRequestedID,
ReviewedID: reviewedID,
IsPull: isPullOption,
+ IsDiscussion: isDiscussionOption,
IssueIDs: nil,
}
if keyword != "" {
@@ -299,6 +310,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ProjectID: projectID,
IsClosed: isShowClosed,
IsPull: isPullOption,
+ IsDiscussion: isDiscussionOption,
LabelIDs: labelIDs,
SortType: sortType,
})
@@ -310,6 +322,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.Data["IssueIndexerUnavailable"] = true
return
}
+
+ // TODO: GetIssuesByIDs를 디스커션도 조회하도록 만들기
issues, err = issues_model.GetIssuesByIDs(ctx, ids, true)
if err != nil {
ctx.ServerError("GetIssuesByIDs", err)
@@ -486,9 +500,19 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
}
func issueIDsFromSearch(ctx *context.Context, keyword string, opts *issues_model.IssuesOptions) ([]int64, error) {
- ids, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
- if err != nil {
- return nil, fmt.Errorf("SearchIssues: %w", err)
+
+ var searchOptions = issue_indexer.ToSearchOptions(keyword, opts)
+ var ids []int64
+ var err error
+
+ if !searchOptions.IsDiscussion.ValueOrDefault(false) {
+ ids, _, err = issue_indexer.SearchIssues(ctx, searchOptions)
+ if err != nil {
+ return nil, fmt.Errorf("SearchIssues: %w", err)
+ }
+ } else {
+ ids = []int64{1, 2}
+ // TODO: 특정 레포지토리의 디스커션의 아이디들을 반환할수 있도록 로직 작성
}
return ids, nil
}
@@ -496,14 +520,26 @@ func issueIDsFromSearch(ctx *context.Context, keyword string, opts *issues_model
// Issues render issues page
func Issues(ctx *context.Context) {
isPullList := ctx.Params(":type") == "pulls"
+ isDiscussion := ctx.Params(":type") == "discussions"
+
if isPullList {
+ // handle pull requests
MustAllowPulls(ctx)
if ctx.Written() {
return
}
ctx.Data["Title"] = ctx.Tr("repo.pulls")
ctx.Data["PageIsPullList"] = true
+ } else if isDiscussion {
+ // handle discussions
+ MustAllowDiscussions(ctx)
+ if ctx.Written() {
+ return
+ }
+ ctx.Data["Title"] = ctx.Tr("repo.discussions")
+ ctx.Data["PageIsDiscussionList"] = true
} else {
+ // handle issuses
MustEnableIssues(ctx)
if ctx.Written() {
return
@@ -513,7 +549,7 @@ func Issues(ctx *context.Context) {
ctx.Data["NewIssueChooseTemplate"] = issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo)
}
- issues(ctx, ctx.FormInt64("milestone"), ctx.FormInt64("project"), optional.Some(isPullList))
+ issues(ctx, ctx.FormInt64("milestone"), ctx.FormInt64("project"), optional.Some(isPullList), optional.Some(isDiscussion))
if ctx.Written() {
return
}
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index 95a4fe60c..2d63df95c 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -292,7 +292,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
ctx.Data["Title"] = milestone.Name
ctx.Data["Milestone"] = milestone
- issues(ctx, milestoneID, projectID, optional.None[bool]())
+ issues(ctx, milestoneID, projectID, optional.None[bool](), optional.None[bool]())
ret := issue.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["NewIssueChooseTemplate"] = len(ret.IssueTemplates) > 0
diff --git a/routers/web/web.go b/routers/web/web.go
index 194a67bf0..82ce369d4 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1162,7 +1162,7 @@ func registerRoutes(m *web.Route) {
// end "/{username}/{reponame}": view milestone, label, issue, pull, etc
m.Group("/{username}/{reponame}", func() {
- m.Group("/{type:issues|pulls}", func() {
+ m.Group("/{type:issues|pulls|discussions}", func() {
m.Get("", repo.Issues)
m.Group("/{index}", func() {
m.Get("", repo.ViewIssue)
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index 34f47b7d8..5cee28860 100644
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -152,6 +152,11 @@
{{svg "octicon-link-external"}} {{ctx.Locale.Tr "repo.issues"}}
{{end}}
+
+
+
+ {{ svg "octicon-comment-discussion" }} {{ctx.Locale.Tr "repo.discussions"}}
+
{{if and .Repository.CanEnablePulls (.Permission.CanRead ctx.Consts.RepoUnitTypePullRequests)}}
diff --git a/templates/repo/issue/openclose.tmpl b/templates/repo/issue/openclose.tmpl
index eb2d6e09e..44d8007ed 100644
--- a/templates/repo/issue/openclose.tmpl
+++ b/templates/repo/issue/openclose.tmpl
@@ -4,6 +4,8 @@
{{svg "octicon-milestone" 16 "tw-mr-2"}}
{{else if .PageIsPullList}}
{{svg "octicon-git-pull-request" 16 "tw-mr-2"}}
+ {{else if .PageIsDiscussionList}}
+ {{svg "octicon-comment-discussion" 16 "tw-mr-2"}}
{{else}}
{{svg "octicon-issue-opened" 16 "tw-mr-2"}}
{{end}}