diff --git a/apps/web/app/(dashboard)/_components/app-sidebar.tsx b/apps/web/app/(dashboard)/_components/app-sidebar.tsx index 619908aa8..5ace39932 100644 --- a/apps/web/app/(dashboard)/_components/app-sidebar.tsx +++ b/apps/web/app/(dashboard)/_components/app-sidebar.tsx @@ -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() { - - useModalStore.getState().open("create-issue")} - > - - - - New issue - +
+ + useSearchStore.getState().setOpen(true)} + > + + + Search workspace (⌘K) + + + useModalStore.getState().open("create-issue")} + > + + + + New issue + +
diff --git a/apps/web/features/search/components/search-command.tsx b/apps/web/features/search/components/search-command.tsx index 581839b4e..c55647e7a 100644 --- a/apps/web/features/search/components/search-command.tsx +++ b/apps/web/features/search/components/search-command.tsx @@ -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([]); 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() && ( -
- Type to search issues... +
+ Type to search issues... + Press ⌘K to open this anytime
)} diff --git a/apps/web/features/search/index.ts b/apps/web/features/search/index.ts index 6e3baea48..b6f719b68 100644 --- a/apps/web/features/search/index.ts +++ b/apps/web/features/search/index.ts @@ -1 +1,2 @@ export { SearchCommand } from "./components/search-command"; +export { useSearchStore } from "./stores/search-store"; diff --git a/apps/web/features/search/stores/search-store.ts b/apps/web/features/search/stores/search-store.ts new file mode 100644 index 000000000..341fe01d7 --- /dev/null +++ b/apps/web/features/search/stores/search-store.ts @@ -0,0 +1,15 @@ +"use client"; + +import { create } from "zustand"; + +interface SearchStore { + open: boolean; + setOpen: (open: boolean) => void; + toggle: () => void; +} + +export const useSearchStore = create((set) => ({ + open: false, + setOpen: (open) => set({ open }), + toggle: () => set((s) => ({ open: !s.open })), +})); diff --git a/turbo.json b/turbo.json index 694658b87..7a74c0b70 100644 --- a/turbo.json +++ b/turbo.json @@ -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"],