Signed-off-by: Seongmin Lee boltlessengineer@proton.me
+57
appview/db/issues.go
+57
appview/db/issues.go
···
267
267
return &issue, nil
268
268
}
269
269
270
+
// GetIssueIDs gets list of all existing issue's IDs
271
+
func GetIssueIDs(e Execer, opts models.IssueSearchOptions) ([]int64, error) {
272
+
var ids []int64
273
+
274
+
var filters []filter
275
+
openValue := 0
276
+
if opts.IsOpen {
277
+
openValue = 1
278
+
}
279
+
filters = append(filters, FilterEq("open", openValue))
280
+
if opts.RepoAt != "" {
281
+
filters = append(filters, FilterEq("repo_at", opts.RepoAt))
282
+
}
283
+
284
+
var conditions []string
285
+
var args []any
286
+
287
+
for _, filter := range filters {
288
+
conditions = append(conditions, filter.Condition())
289
+
args = append(args, filter.Arg()...)
290
+
}
291
+
292
+
whereClause := ""
293
+
if conditions != nil {
294
+
whereClause = " where " + strings.Join(conditions, " and ")
295
+
}
296
+
query := fmt.Sprintf(
297
+
`
298
+
select
299
+
id
300
+
from
301
+
issues
302
+
%s
303
+
limit ? offset ?`,
304
+
whereClause,
305
+
)
306
+
args = append(args, opts.Page.Limit, opts.Page.Offset)
307
+
rows, err := e.Query(query, args...)
308
+
if err != nil {
309
+
return nil, err
310
+
}
311
+
defer rows.Close()
312
+
313
+
for rows.Next() {
314
+
var id int64
315
+
err := rows.Scan(&id)
316
+
if err != nil {
317
+
return nil, err
318
+
}
319
+
320
+
ids = append(ids, id)
321
+
}
322
+
323
+
return ids, nil
324
+
}
325
+
326
+
270
327
func AddIssueComment(e Execer, c models.IssueComment) (int64, error) {
271
328
result, err := e.Exec(
272
329
`insert into issue_comments (
+27
-5
appview/issues/issues.go
+27
-5
appview/issues/issues.go
···
787
787
return
788
788
}
789
789
790
-
openVal := 0
791
-
if isOpen {
792
-
openVal = 1
790
+
keyword := params.Get("q")
791
+
792
+
var ids []int64
793
+
searchOpts := models.IssueSearchOptions{
794
+
Keyword: keyword,
795
+
RepoAt: f.RepoAt().String(),
796
+
IsOpen: isOpen,
797
+
Page: page,
798
+
}
799
+
if keyword != "" {
800
+
res, err := rp.indexer.Search(r.Context(), searchOpts)
801
+
if err != nil {
802
+
l.Error("failed to search for issues", "err", err)
803
+
return
804
+
}
805
+
l.Debug("searched issues with indexer", "res.Hits", res.Hits)
806
+
ids = res.Hits
807
+
} else {
808
+
ids, err = db.GetIssueIDs(rp.db, searchOpts)
809
+
if err != nil {
810
+
l.Error("failed to search for issues", "err", err)
811
+
return
812
+
}
813
+
l.Debug("indexed all issues from the db", "ids", ids)
793
814
}
815
+
794
816
issues, err := db.GetIssuesPaginated(
795
817
rp.db,
796
818
page,
797
-
db.FilterEq("repo_at", f.RepoAt()),
798
-
db.FilterEq("open", openVal),
819
+
db.FilterIn("id", ids),
799
820
)
800
821
if err != nil {
801
822
l.Error("failed to get issues", "err", err)
···
825
846
Issues: issues,
826
847
LabelDefs: defs,
827
848
FilteringByOpen: isOpen,
849
+
FilterQuery: keyword,
828
850
Page: page,
829
851
})
830
852
}
+9
-2
appview/pages/templates/repo/issues/issues.html
+9
-2
appview/pages/templates/repo/issues/issues.html
···
24
24
{{ i "ban" "w-4 h-4" }}
25
25
<span>{{ .RepoInfo.Stats.IssueCount.Closed }} closed</span>
26
26
</a>
27
+
<form class="flex gap-4" method="GET">
28
+
<input type="hidden" name="state" value="{{ if .FilteringByOpen }}open{{ else }}closed{{ end }}">
29
+
<input class="" type="text" name="q" value="{{ .FilterQuery }}">
30
+
<button class="btn" type="submit">
31
+
search
32
+
</button>
33
+
</form>
27
34
</div>
28
35
<a
29
36
href="/{{ .RepoInfo.FullName }}/issues/new"
···
55
62
<a
56
63
class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"
57
64
hx-boost="true"
58
-
href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $prev.Offset }}&limit={{ $prev.Limit }}"
65
+
href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&q={{ .FilterQuery }}&offset={{ $prev.Offset }}&limit={{ $prev.Limit }}"
59
66
>
60
67
{{ i "chevron-left" "w-4 h-4" }}
61
68
previous
···
69
76
<a
70
77
class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"
71
78
hx-boost="true"
72
-
href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&offset={{ $next.Offset }}&limit={{ $next.Limit }}"
79
+
href = "/{{ $.RepoInfo.FullName }}/issues?state={{ $currentState }}&q={{ .FilterQuery }}&offset={{ $next.Offset }}&limit={{ $next.Limit }}"
73
80
>
74
81
next
75
82
{{ i "chevron-right" "w-4 h-4" }}