Skip to content

Commit 6432d75

Browse files
authored
Merge pull request #5 from bitloops/cli-1331-add-query-explorer-mode-toggle-in-dashboard
CLI-1331: Add query explorer mode to dashboard sidebar
2 parents f665fb5 + 66ec2fd commit 6432d75

6 files changed

Lines changed: 100 additions & 2 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "local-dashboard",
33
"private": true,
4-
"version": "0.0.1",
4+
"version": "0.0.2",
55
"type": "module",
66
"scripts": {
77
"open-api-codegen": "curl -o ./swagger.json http://127.0.0.1:5667/api/openapi.json && npx openapi-typescript-codegen --input ./swagger.json --output ./src/api/types/schema --name BitloopsCli --useOptions",

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'
66
import { AppSidebar } from '@/components/layout/app-sidebar'
77
import { SkipToMain } from '@/components/skip-to-main'
88
import { Dashboard } from '@/features/dashboard'
9+
import { QueryExplorer } from '@/features/query-explorer'
910
import { SettingsPage } from '@/features/settings/page'
1011
import { ComingSoon } from '@/components/coming-soon'
1112

1213
function PageRouter() {
1314
const { pathname } = useLocation()
1415

1516
if (pathname === '/' || pathname === '') return <Dashboard />
17+
if (pathname === '/explorer') return <QueryExplorer />
1618
if (pathname.startsWith('/settings')) return <SettingsPage />
1719
if (pathname === '/help-center') return <ComingSoon />
1820

src/components/layout/data/sidebar-data.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { LayoutDashboard, Settings, HelpCircle, Command } from 'lucide-react'
1+
import {
2+
LayoutDashboard,
3+
Search,
4+
Settings,
5+
HelpCircle,
6+
Command,
7+
} from 'lucide-react'
28
import { type SidebarData } from '../types'
39

410
export const sidebarData: SidebarData = {
@@ -18,6 +24,11 @@ export const sidebarData: SidebarData = {
1824
url: '/',
1925
icon: LayoutDashboard,
2026
},
27+
{
28+
title: 'Query Explorer',
29+
url: '/explorer',
30+
icon: Search,
31+
},
2132
],
2233
},
2334
{
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Header } from '@/components/layout/header'
2+
import { Main } from '@/components/layout/main'
3+
import { ThemeSwitch } from '@/components/theme-switch'
4+
5+
export function QueryExplorer() {
6+
return (
7+
<>
8+
<Header className='pe-8'>
9+
<div className='ms-auto flex items-center space-x-4'>
10+
<ThemeSwitch />
11+
</div>
12+
</Header>
13+
<Main>
14+
<div className='mb-4'>
15+
<h1 className='text-2xl font-bold tracking-tight'>Query Explorer</h1>
16+
<p className='mt-1 text-sm text-muted-foreground'>
17+
Query and explore your code intelligence data.
18+
</p>
19+
</div>
20+
<div className='rounded-lg border border-dashed bg-muted/20 px-4 py-8 text-center text-sm text-muted-foreground'>
21+
Query Explorer UI.
22+
</div>
23+
</Main>
24+
</>
25+
)
26+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { render, screen } from '@testing-library/react'
3+
import { SidebarProvider } from '@/components/ui/sidebar'
4+
import { QueryExplorer } from './index'
5+
6+
function Wrapper({ children }: { children: React.ReactNode }) {
7+
return <SidebarProvider>{children}</SidebarProvider>
8+
}
9+
10+
describe('QueryExplorer', () => {
11+
it('renders Query Explorer heading', () => {
12+
render(<QueryExplorer />, { wrapper: Wrapper })
13+
expect(
14+
screen.getByRole('heading', { name: 'Query Explorer' }),
15+
).toBeInTheDocument()
16+
})
17+
18+
it('renders tagline about schema-driven queries', () => {
19+
render(<QueryExplorer />, { wrapper: Wrapper })
20+
expect(
21+
screen.getByText('Query and explore your code intelligence data.'),
22+
).toBeInTheDocument()
23+
})
24+
25+
it('renders placeholder for Query Explorer UI', () => {
26+
render(<QueryExplorer />, { wrapper: Wrapper })
27+
expect(screen.getByText('Query Explorer UI.')).toBeInTheDocument()
28+
})
29+
})

tests/integration/app-routing.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,34 @@ describe('App routing integration', () => {
5858
screen.getByRole('heading', { name: 'Dashboard' }),
5959
).toBeInTheDocument()
6060
})
61+
62+
it('renders Query Explorer link in sidebar', () => {
63+
renderApp()
64+
expect(
65+
screen.getByRole('link', { name: /Query Explorer/i }),
66+
).toBeInTheDocument()
67+
})
68+
69+
it('navigates to Query Explorer when Query Explorer link is clicked', async () => {
70+
renderApp()
71+
await userEvent.click(screen.getByRole('link', { name: /Query Explorer/i }))
72+
expect(
73+
screen.getByRole('heading', { name: 'Query Explorer' }),
74+
).toBeInTheDocument()
75+
expect(
76+
screen.getByText('Query and explore your code intelligence data.'),
77+
).toBeInTheDocument()
78+
})
79+
80+
it('navigates back to Dashboard from Query Explorer when Dashboard link is clicked', async () => {
81+
renderApp()
82+
await userEvent.click(screen.getByRole('link', { name: /Query Explorer/i }))
83+
expect(
84+
screen.getByRole('heading', { name: 'Query Explorer' }),
85+
).toBeInTheDocument()
86+
await userEvent.click(screen.getByRole('link', { name: /Dashboard/i }))
87+
expect(
88+
screen.getByRole('heading', { name: 'Dashboard' }),
89+
).toBeInTheDocument()
90+
})
6191
})

0 commit comments

Comments
 (0)