From 678afa7e4c7d8934c54ea38cc46aa6f14b02ba17 Mon Sep 17 00:00:00 2001 From: Duyet Le Date: Tue, 21 Nov 2023 17:56:30 +0700 Subject: [PATCH] feat: update menu, add /api, update tests --- .github/workflows/ci.yml | 1 + app/api/version/route.ts | 24 +++++++ app/healthz/route.ts | 19 +----- app/overview/page.tsx | 1 - components/menu.tsx | 119 +++++++++++++++++++++++++++++++---- cypress/e2e/navigation.cy.js | 6 +- yarn.lock | 17 +++++ 7 files changed, 152 insertions(+), 35 deletions(-) create mode 100644 app/api/version/route.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccb0a92f..64bdb454 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,3 +125,4 @@ jobs: - name: Test image run: | curl -sSf http://localhost:3000/healthz || exit 1 + curl -sSf http://localhost:3000/api/version || exit 1 diff --git a/app/api/version/route.ts b/app/api/version/route.ts new file mode 100644 index 00000000..4244ee94 --- /dev/null +++ b/app/api/version/route.ts @@ -0,0 +1,24 @@ +import { NextResponse } from 'next/server' +import packageInfo from '@/package.json' + +import { fetchData } from '@/lib/clickhouse' + +export const dynamic = 'force-dynamic' + +export async function GET() { + try { + const clickhouse = await fetchData('SELECT version()') + return NextResponse.json({ + ui: packageInfo.version, + clickhouse, + }) + } catch { + return NextResponse.json( + { + ui: packageInfo.version, + clickhouse: false, + }, + { status: 500 } + ) + } +} diff --git a/app/healthz/route.ts b/app/healthz/route.ts index 78de8f24..b8b9869e 100644 --- a/app/healthz/route.ts +++ b/app/healthz/route.ts @@ -1,24 +1,7 @@ import { NextResponse } from 'next/server' -import packageInfo from '@/package.json' - -import { fetchData } from '@/lib/clickhouse' export const dynamic = 'force-dynamic' export async function GET() { - try { - const clickhouse = await fetchData('SELECT version()') - return NextResponse.json({ - ui: packageInfo.version, - clickhouse, - }) - } catch { - return NextResponse.json( - { - ui: packageInfo.version, - clikckhouse: false, - }, - { status: 500 } - ) - } + return NextResponse.json({ ok: true }) } diff --git a/app/overview/page.tsx b/app/overview/page.tsx index 9509ef1e..9ce605fc 100644 --- a/app/overview/page.tsx +++ b/app/overview/page.tsx @@ -13,7 +13,6 @@ export const revalidate = 5 export default async function Overview() { noStore() - x return (
diff --git a/components/menu.tsx b/components/menu.tsx index 5d3da299..80ac6a23 100644 --- a/components/menu.tsx +++ b/components/menu.tsx @@ -1,22 +1,28 @@ +import React from 'react' import Link from 'next/link' import { fetchData, QUERY_COMMENT } from '@/lib/clickhouse' +import { cn } from '@/lib/utils' import { Badge } from '@/components/ui/badge' import { NavigationMenu, + NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, + NavigationMenuTrigger, navigationMenuTriggerClasses, } from '@/components/ui/navigation-menu' +interface MenuProps { + items?: MenuItem[] +} + interface MenuItem { title: string href: string + description?: string countSql?: string -} - -interface MenuProps { items?: MenuItem[] } @@ -26,9 +32,23 @@ const defaultItems = [ href: '/overview', }, { - title: 'Running Queries', - href: '/running-queries', + title: 'Queries Monitor', + href: '', countSql: `SELECT COUNT() FROM system.processes WHERE is_cancelled = 0 AND query NOT LIKE '%${QUERY_COMMENT}%'`, + items: [ + { + title: 'Running Queries', + href: '/running-queries', + description: 'Queries that are currently running', + countSql: `SELECT COUNT() FROM system.processes WHERE is_cancelled = 0 AND query NOT LIKE '%${QUERY_COMMENT}%'`, + }, + { + title: 'History Queries', + href: '/history-queries', + description: + 'Queries that have been run including successed, failed queries with resourses usage details', + }, + ], }, { title: 'Tables', @@ -51,14 +71,7 @@ export function Menu({ items = defaultItems }: MenuProps) { {items.map((item) => ( - - - - {item.title} - - - - + ))} @@ -80,3 +93,83 @@ async function MenuCounter({ sql }: { sql?: string }) { ) } + +function MenuItem({ item }: { item: MenuItem }) { + if (item.items) { + return + } + + return +} + +function SingleItem({ item }: { item: MenuItem }) { + return ( + + + + {item.title} + + + + + ) +} + +function HasChildItems({ item }: { item: MenuItem }) { + return ( + + + {item.title} + + +
    + {item.items?.map((childItem) => ( + + {childItem.title} + + } + href={childItem.href} + description={childItem.description} + /> + ))} +
+
+
+ ) +} + +function ListItem({ + className, + title, + href, + description, + ...props +}: { + className?: string + title: React.ReactNode + href: string + description: React.ReactNode +}) { + return ( +
  • + + +
    {title}
    +

    + {description} +

    +
    +
    +
  • + ) +} diff --git a/cypress/e2e/navigation.cy.js b/cypress/e2e/navigation.cy.js index f193ae40..473ca2f8 100644 --- a/cypress/e2e/navigation.cy.js +++ b/cypress/e2e/navigation.cy.js @@ -1,9 +1,9 @@ describe('Navigation', () => { - it('should navigate to the running queries page', () => { - cy.visitAndValidate('/overview', 'a[href*="running-queries"]', '/running-queries', 'Running Queries') + it('should navigate to the /tables page', () => { + cy.visitAndValidate('/overview', 'a[href*="running-queries"]', '/tables', 'Tables') }) - it('should navigate to the settings page', () => { + it('should navigate to the /settings page', () => { cy.visitAndValidate('/overview', 'a[href*="settings"]', '/settings', 'Settings') }) }) diff --git a/yarn.lock b/yarn.lock index b20232a1..43f153aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -853,6 +853,23 @@ aria-hidden "^1.1.1" react-remove-scroll "2.5.5" +"@radix-ui/react-menubar@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.0.4.tgz#7d46ababfec63db3868d9ed79366686634c1201a" + integrity sha512-bHgUo9gayKZfaQcWSSLr++LyS0rgh+MvD89DE4fJ6TkGHvjHgPaBZf44hdka7ogOxIOdj9163J+5xL2Dn4qzzg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-menu" "2.0.6" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-navigation-menu@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz#654151310c3f9a29afd19fb60ddc7977e54b8a3d"