Merge pull request #583 from multica-ai/NevilleQingNY/sidebar-search-btn

feat(web): add search button to sidebar header
This commit is contained in:
Naiyuan Qing
2026-04-09 18:39:55 +08:00
committed by GitHub
5 changed files with 58 additions and 14 deletions

View File

@@ -17,6 +17,7 @@ import {
SquarePen,
CircleUser,
FolderKanban,
Search,
} from "lucide-react";
import { WorkspaceAvatar } from "@multica/views/workspace/workspace-avatar";
import { useIssueDraftStore } from "@multica/core/issues/stores/draft-store";
@@ -49,6 +50,7 @@ import { inboxKeys, deduplicateInboxItems } from "@multica/core/inbox/queries";
import { api } from "@/platform/api";
import { useModalStore } from "@multica/core/modals";
import { useMyRuntimesNeedUpdate } from "@multica/core/runtimes/hooks";
import { useSearchStore } from "@/features/search";
const primaryNav = [
{ href: "/inbox", label: "Inbox", icon: Inbox },
@@ -172,16 +174,27 @@ export function AppSidebar() {
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
<Tooltip>
<TooltipTrigger
className="relative flex h-7 w-7 items-center justify-center rounded-lg bg-background text-foreground shadow-sm hover:bg-accent"
onClick={() => useModalStore.getState().open("create-issue")}
>
<SquarePen className="size-3.5" />
<DraftDot />
</TooltipTrigger>
<TooltipContent side="bottom">New issue</TooltipContent>
</Tooltip>
<div className="flex items-center gap-1">
<Tooltip>
<TooltipTrigger
className="flex h-7 w-7 items-center justify-center rounded-lg bg-secondary text-muted-foreground hover:bg-secondary/80 hover:text-secondary-foreground"
onClick={() => useSearchStore.getState().setOpen(true)}
>
<Search className="size-3.5" />
</TooltipTrigger>
<TooltipContent side="bottom">Search workspace (K)</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger
className="relative flex h-7 w-7 items-center justify-center rounded-lg bg-background text-foreground shadow-sm hover:bg-accent"
onClick={() => useModalStore.getState().open("create-issue")}
>
<SquarePen className="size-3.5" />
<DraftDot />
</TooltipTrigger>
<TooltipContent side="bottom">New issue</TooltipContent>
</Tooltip>
</div>
</div>
</SidebarHeader>

View File

@@ -15,10 +15,12 @@ import {
DialogTitle,
DialogDescription,
} from "@multica/ui/components/ui/dialog";
import { useSearchStore } from "../stores/search-store";
export function SearchCommand() {
const router = useRouter();
const [open, setOpen] = useState(false);
const open = useSearchStore((s) => s.open);
const setOpen = useSearchStore((s) => s.setOpen);
const [query, setQuery] = useState("");
const [results, setResults] = useState<SearchIssueResult[]>([]);
const [isLoading, setIsLoading] = useState(false);
@@ -30,7 +32,7 @@ export function SearchCommand() {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
setOpen((prev) => !prev);
useSearchStore.getState().toggle();
}
};
document.addEventListener("keydown", handleKeyDown);
@@ -186,8 +188,9 @@ export function SearchCommand() {
)}
{!isLoading && !query.trim() && (
<div className="py-10 text-center text-sm text-muted-foreground">
Type to search issues...
<div className="flex flex-col items-center gap-2 py-10 text-sm text-muted-foreground">
<span>Type to search issues...</span>
<span className="text-xs">Press <kbd className="rounded bg-muted px-1.5 py-0.5 font-medium">K</kbd> to open this anytime</span>
</div>
)}
</CommandPrimitive.List>

View File

@@ -1 +1,2 @@
export { SearchCommand } from "./components/search-command";
export { useSearchStore } from "./stores/search-store";

View File

@@ -0,0 +1,15 @@
"use client";
import { create } from "zustand";
interface SearchStore {
open: boolean;
setOpen: (open: boolean) => void;
toggle: () => void;
}
export const useSearchStore = create<SearchStore>((set) => ({
open: false,
setOpen: (open) => set({ open }),
toggle: () => set((s) => ({ open: !s.open })),
}));

View File

@@ -1,5 +1,17 @@
{
"$schema": "https://turbo.build/schema.json",
"globalEnv": [
"DATABASE_URL",
"PORT",
"FRONTEND_PORT",
"FRONTEND_ORIGIN",
"NEXT_PUBLIC_API_URL",
"NEXT_PUBLIC_WS_URL",
"MULTICA_SERVER_URL",
"COMPOSE_PROJECT_NAME",
"POSTGRES_DB",
"POSTGRES_PORT"
],
"tasks": {
"build": {
"dependsOn": ["^build"],