From b28bac6bb742080f48b94924c9130c76d3c7e161 Mon Sep 17 00:00:00 2001
From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com>
Date: Wed, 1 Apr 2026 22:24:35 +0800
Subject: [PATCH] Revert "feat: add global issue search"
---
.../(dashboard)/_components/app-sidebar.tsx | 32 ++--
apps/web/features/modals/registry.tsx | 3 -
apps/web/features/modals/search-issues.tsx | 143 ------------------
apps/web/features/modals/store.ts | 2 +-
apps/web/shared/api/client.ts | 1 -
apps/web/shared/types/api.ts | 1 -
server/internal/handler/issue.go | 5 -
server/pkg/db/generated/issue.sql.go | 3 -
server/pkg/db/queries/issue.sql | 1 -
9 files changed, 11 insertions(+), 180 deletions(-)
delete mode 100644 apps/web/features/modals/search-issues.tsx
diff --git a/apps/web/app/(dashboard)/_components/app-sidebar.tsx b/apps/web/app/(dashboard)/_components/app-sidebar.tsx
index 123c1466..7657d039 100644
--- a/apps/web/app/(dashboard)/_components/app-sidebar.tsx
+++ b/apps/web/app/(dashboard)/_components/app-sidebar.tsx
@@ -15,7 +15,6 @@ import {
BookOpenText,
SquarePen,
CircleUser,
- Search,
} from "lucide-react";
import { WorkspaceAvatar } from "@/features/workspace";
import { useIssueDraftStore } from "@/features/issues/stores/draft-store";
@@ -156,27 +155,16 @@ export function AppSidebar() {
-
-
- useModalStore.getState().open("search-issues")}
- >
-
-
- Search issues
-
-
- useModalStore.getState().open("create-issue")}
- >
-
-
-
- New issue
-
-
+
+ useModalStore.getState().open("create-issue")}
+ >
+
+
+
+ New issue
+
diff --git a/apps/web/features/modals/registry.tsx b/apps/web/features/modals/registry.tsx
index 02b60c3d..faf2e63a 100644
--- a/apps/web/features/modals/registry.tsx
+++ b/apps/web/features/modals/registry.tsx
@@ -3,7 +3,6 @@
import { useModalStore } from "./store";
import { CreateWorkspaceModal } from "./create-workspace";
import { CreateIssueModal } from "./create-issue";
-import { SearchIssuesModal } from "./search-issues";
export function ModalRegistry() {
const modal = useModalStore((s) => s.modal);
@@ -15,8 +14,6 @@ export function ModalRegistry() {
return ;
case "create-issue":
return ;
- case "search-issues":
- return ;
default:
return null;
}
diff --git a/apps/web/features/modals/search-issues.tsx b/apps/web/features/modals/search-issues.tsx
deleted file mode 100644
index d8740591..00000000
--- a/apps/web/features/modals/search-issues.tsx
+++ /dev/null
@@ -1,143 +0,0 @@
-"use client";
-
-import { useState, useEffect, useRef, useCallback } from "react";
-import { useRouter } from "next/navigation";
-import {
- CommandDialog,
- Command,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
-} from "@/components/ui/command";
-import { Skeleton } from "@/components/ui/skeleton";
-import { StatusIcon } from "@/features/issues/components";
-import { api } from "@/shared/api";
-import type { Issue } from "@/shared/types";
-
-function SearchSkeleton() {
- return (
-
- {Array.from({ length: 5 }, (_, i) => (
-
-
-
-
-
- ))}
-
- );
-}
-
-export function SearchIssuesModal({ onClose }: { onClose: () => void }) {
- const router = useRouter();
- const [query, setQuery] = useState("");
- const [results, setResults] = useState([]);
- const [loading, setLoading] = useState(false);
- const debounceRef = useRef>(null);
- const composingRef = useRef(false);
-
- const search = useCallback(async (q: string) => {
- if (!q.trim()) {
- setResults([]);
- setLoading(false);
- return;
- }
- setLoading(true);
- try {
- const res = await api.listIssues({ search: q.trim(), limit: 20 });
- setResults(res.issues);
- } catch {
- setResults([]);
- } finally {
- setLoading(false);
- }
- }, []);
-
- const scheduleSearch = useCallback(
- (q: string) => {
- if (debounceRef.current) clearTimeout(debounceRef.current);
- if (q.trim()) setLoading(true);
- debounceRef.current = setTimeout(() => search(q), 300);
- },
- [search]
- );
-
- useEffect(() => {
- return () => {
- if (debounceRef.current) clearTimeout(debounceRef.current);
- };
- }, []);
-
- const handleValueChange = (value: string) => {
- setQuery(value);
- if (!composingRef.current) {
- scheduleSearch(value);
- }
- };
-
- const handleCompositionStart = () => {
- composingRef.current = true;
- };
-
- const handleCompositionEnd = (e: React.CompositionEvent) => {
- composingRef.current = false;
- scheduleSearch((e.target as HTMLInputElement).value);
- };
-
- const handleSelect = (issue: Issue) => {
- onClose();
- router.push(`/issues/${issue.id}`);
- };
-
- return (
- {
- if (!open) onClose();
- }}
- title="Search Issues"
- description="Search issues by title"
- className="top-[min(33%,12rem)]"
- >
-
-
-
- {!query.trim() ? (
-
- Type to search issues by title
-
- ) : loading ? (
-
- ) : (
- <>
- No issues found
-
- {results.map((issue) => (
- handleSelect(issue)}
- >
-
- {issue.title}
-
- {issue.identifier}
-
-
- ))}
-
- >
- )}
-
-
-
- );
-}
diff --git a/apps/web/features/modals/store.ts b/apps/web/features/modals/store.ts
index 0a5a946d..f720be43 100644
--- a/apps/web/features/modals/store.ts
+++ b/apps/web/features/modals/store.ts
@@ -2,7 +2,7 @@
import { create } from "zustand";
-type ModalType = "create-workspace" | "create-issue" | "search-issues" | null;
+type ModalType = "create-workspace" | "create-issue" | null;
interface ModalStore {
modal: ModalType;
diff --git a/apps/web/shared/api/client.ts b/apps/web/shared/api/client.ts
index 603be220..65004b34 100644
--- a/apps/web/shared/api/client.ts
+++ b/apps/web/shared/api/client.ts
@@ -163,7 +163,6 @@ export class ApiClient {
if (params?.status) search.set("status", params.status);
if (params?.priority) search.set("priority", params.priority);
if (params?.assignee_id) search.set("assignee_id", params.assignee_id);
- if (params?.search) search.set("search", params.search);
return this.fetch(`/api/issues?${search}`);
}
diff --git a/apps/web/shared/types/api.ts b/apps/web/shared/types/api.ts
index a06b3fdb..cdeeae4e 100644
--- a/apps/web/shared/types/api.ts
+++ b/apps/web/shared/types/api.ts
@@ -31,7 +31,6 @@ export interface ListIssuesParams {
status?: IssueStatus;
priority?: IssuePriority;
assignee_id?: string;
- search?: string;
}
export interface ListIssuesResponse {
diff --git a/server/internal/handler/issue.go b/server/internal/handler/issue.go
index 64123151..0c5a0d6a 100644
--- a/server/internal/handler/issue.go
+++ b/server/internal/handler/issue.go
@@ -99,10 +99,6 @@ func (h *Handler) ListIssues(w http.ResponseWriter, r *http.Request) {
if a := r.URL.Query().Get("assignee_id"); a != "" {
assigneeFilter = parseUUID(a)
}
- var searchFilter pgtype.Text
- if s := r.URL.Query().Get("search"); s != "" {
- searchFilter = pgtype.Text{String: s, Valid: true}
- }
issues, err := h.Queries.ListIssues(ctx, db.ListIssuesParams{
WorkspaceID: parseUUID(workspaceID),
@@ -111,7 +107,6 @@ func (h *Handler) ListIssues(w http.ResponseWriter, r *http.Request) {
Status: statusFilter,
Priority: priorityFilter,
AssigneeID: assigneeFilter,
- Search: searchFilter,
})
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to list issues")
diff --git a/server/pkg/db/generated/issue.sql.go b/server/pkg/db/generated/issue.sql.go
index 208a3800..f899eb6e 100644
--- a/server/pkg/db/generated/issue.sql.go
+++ b/server/pkg/db/generated/issue.sql.go
@@ -195,7 +195,6 @@ WHERE workspace_id = $1
AND ($4::text IS NULL OR status = $4)
AND ($5::text IS NULL OR priority = $5)
AND ($6::uuid IS NULL OR assignee_id = $6)
- AND ($7::text IS NULL OR title ILIKE '%' || $7 || '%')
ORDER BY position ASC, created_at DESC
LIMIT $2 OFFSET $3
`
@@ -207,7 +206,6 @@ type ListIssuesParams struct {
Status pgtype.Text `json:"status"`
Priority pgtype.Text `json:"priority"`
AssigneeID pgtype.UUID `json:"assignee_id"`
- Search pgtype.Text `json:"search"`
}
func (q *Queries) ListIssues(ctx context.Context, arg ListIssuesParams) ([]Issue, error) {
@@ -218,7 +216,6 @@ func (q *Queries) ListIssues(ctx context.Context, arg ListIssuesParams) ([]Issue
arg.Status,
arg.Priority,
arg.AssigneeID,
- arg.Search,
)
if err != nil {
return nil, err
diff --git a/server/pkg/db/queries/issue.sql b/server/pkg/db/queries/issue.sql
index 3082abab..edc229c3 100644
--- a/server/pkg/db/queries/issue.sql
+++ b/server/pkg/db/queries/issue.sql
@@ -4,7 +4,6 @@ WHERE workspace_id = $1
AND (sqlc.narg('status')::text IS NULL OR status = sqlc.narg('status'))
AND (sqlc.narg('priority')::text IS NULL OR priority = sqlc.narg('priority'))
AND (sqlc.narg('assignee_id')::uuid IS NULL OR assignee_id = sqlc.narg('assignee_id'))
- AND (sqlc.narg('search')::text IS NULL OR title ILIKE '%' || sqlc.narg('search') || '%')
ORDER BY position ASC, created_at DESC
LIMIT $2 OFFSET $3;