mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
feat(logs): added logs structure; connecting to DB now
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Plus, Settings } from 'lucide-react'
|
||||
import { Plus, ScrollText, Settings } from 'lucide-react'
|
||||
import { AgentIcon } from '@/components/icons'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
@@ -42,7 +42,7 @@ export function Sidebar() {
|
||||
<aside className="fixed inset-y-0 left-0 z-10 hidden w-14 flex-col border-r bg-background sm:flex">
|
||||
<nav className="flex flex-col items-center gap-4 px-2 py-5">
|
||||
<Link
|
||||
href="/"
|
||||
href="/w/1"
|
||||
className="group flex h-8 w-8 items-center justify-center rounded-lg bg-[#7F2FFF]"
|
||||
>
|
||||
<AgentIcon className="text-white transition-all group-hover:scale-110 -translate-y-[0.5px] w-5 h-5" />
|
||||
@@ -79,6 +79,22 @@ export function Sidebar() {
|
||||
</nav>
|
||||
|
||||
<nav className="flex flex-col items-center gap-4 px-2 py-[18px]">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
asChild
|
||||
className="flex !h-9 !w-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:text-foreground md:h-8 md:w-8"
|
||||
>
|
||||
<Link href="/w/logs">
|
||||
<ScrollText className="!h-5 !w-5" />
|
||||
<span className="sr-only">Logs</span>
|
||||
</Link>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">Logs</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
|
||||
71
app/w/logs/components/control-bar/control-bar.tsx
Normal file
71
app/w/logs/components/control-bar/control-bar.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { RefreshCw, Search } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
|
||||
/**
|
||||
* Control bar for logs page - includes search functionality and refresh/live controls
|
||||
*/
|
||||
export function ControlBar() {
|
||||
const [isLive, setIsLive] = useState(false)
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
|
||||
const handleRefresh = () => {
|
||||
// Implement refresh functionality
|
||||
console.log('Refreshing logs')
|
||||
}
|
||||
|
||||
const toggleLive = () => {
|
||||
setIsLive(!isLive)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-16 w-full items-center justify-between bg-background px-6 border-b transition-all duration-300">
|
||||
{/* Left Section - Search */}
|
||||
<div className="relative w-[400px]">
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<Search className="h-4 w-4 text-muted-foreground" />
|
||||
</div>
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="Search logs..."
|
||||
className="pl-10 h-9"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Middle Section - Reserved for future use */}
|
||||
<div className="flex-1" />
|
||||
|
||||
{/* Right Section - Actions */}
|
||||
<div className="flex items-center gap-3">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleRefresh}
|
||||
className="hover:text-foreground"
|
||||
>
|
||||
<RefreshCw className="h-5 w-5" />
|
||||
<span className="sr-only">Refresh</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Refresh</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Button
|
||||
variant={isLive ? 'default' : 'outline'}
|
||||
className={isLive ? 'bg-[#7F2FFF] hover:bg-[#7F2FFF]/90 text-white' : ''}
|
||||
onClick={toggleLive}
|
||||
>
|
||||
Live
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useState } from 'react'
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
|
||||
|
||||
export default function FilterSection({
|
||||
title,
|
||||
defaultOpen = false,
|
||||
content,
|
||||
}: {
|
||||
title: string
|
||||
defaultOpen?: boolean
|
||||
content?: React.ReactNode
|
||||
}) {
|
||||
const [isOpen, setIsOpen] = useState(defaultOpen)
|
||||
|
||||
return (
|
||||
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="mb-3">
|
||||
<CollapsibleTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="flex w-full justify-between px-2 text-sm font-medium hover:bg-accent rounded-md"
|
||||
>
|
||||
<span>{title}</span>
|
||||
<ChevronDown
|
||||
className={`h-4 w-4 text-muted-foreground transition-transform mr-[5px] ${
|
||||
isOpen ? 'rotate-180' : ''
|
||||
}`}
|
||||
/>
|
||||
</Button>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="pt-2">
|
||||
{content || (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
Filter options for {title} will go here
|
||||
</div>
|
||||
)}
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
36
app/w/logs/components/filters/components/timeline.tsx
Normal file
36
app/w/logs/components/filters/components/timeline.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { useState } from 'react'
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
|
||||
export default function Timeline() {
|
||||
const [selectedTimeRange, setSelectedTimeRange] = useState('Past 30 minutes')
|
||||
const timeRanges = ['Past 30 minutes', 'Past hour', 'Past 24 hours', 'All time']
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="w-full justify-between text-sm font-normal">
|
||||
{selectedTimeRange}
|
||||
<ChevronDown className="h-4 w-4 ml-2 text-muted-foreground" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="overflow-y-auto">
|
||||
{timeRanges.map((range) => (
|
||||
<DropdownMenuItem
|
||||
key={range}
|
||||
onClick={() => setSelectedTimeRange(range)}
|
||||
className="flex items-start p-2 cursor-pointer text-sm"
|
||||
>
|
||||
{range}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
33
app/w/logs/components/filters/filters.tsx
Normal file
33
app/w/logs/components/filters/filters.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import FilterSection from './components/filter-section/filter-section'
|
||||
import Timeline from './components/timeline'
|
||||
|
||||
/**
|
||||
* Filters component for logs page - includes timeline and other filter options
|
||||
*/
|
||||
export function Filters() {
|
||||
return (
|
||||
<div className="p-4 w-64 border-r h-full overflow-auto">
|
||||
<h2 className="text-sm font-medium mb-4 pl-2">Filters</h2>
|
||||
|
||||
{/* Timeline Filter */}
|
||||
<FilterSection title="Timeline" defaultOpen={true} content={<Timeline />} />
|
||||
|
||||
{/* Additional filter sections */}
|
||||
<FilterSection title="Contains Level" />
|
||||
<FilterSection title="Environment" />
|
||||
<FilterSection title="Route" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
19
app/w/logs/logs.tsx
Normal file
19
app/w/logs/logs.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
'use client'
|
||||
|
||||
import { ControlBar } from './components/control-bar/control-bar'
|
||||
import { Filters } from './components/filters/filters'
|
||||
|
||||
export default function Logs() {
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<ControlBar />
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<Filters />
|
||||
<div className="flex-1 overflow-auto p-4">
|
||||
{/* Logs content will go here */}
|
||||
<div className="text-muted-foreground text-center mt-10">137 total logs found...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
3
app/w/logs/page.tsx
Normal file
3
app/w/logs/page.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import Logs from './logs'
|
||||
|
||||
export default Logs
|
||||
11
components/ui/collapsible.tsx
Normal file
11
components/ui/collapsible.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'
|
||||
|
||||
const Collapsible = CollapsiblePrimitive.Root
|
||||
|
||||
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
|
||||
|
||||
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
|
||||
|
||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
|
||||
54
package-lock.json
generated
54
package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"@cerebras/cerebras_cloud_sdk": "^1.23.0",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.5",
|
||||
"@radix-ui/react-checkbox": "^1.1.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.3",
|
||||
"@radix-ui/react-dialog": "^1.1.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
@@ -1866,6 +1867,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.3.tgz",
|
||||
"integrity": "sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
|
||||
"integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-slot": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"@cerebras/cerebras_cloud_sdk": "^1.23.0",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.5",
|
||||
"@radix-ui/react-checkbox": "^1.1.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.3",
|
||||
"@radix-ui/react-dialog": "^1.1.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
|
||||
Reference in New Issue
Block a user