changed search for folders and workflows in logs (#1327)

Co-authored-by: Adam Gough <adamgough@Mac.attlocal.net>
This commit is contained in:
Adam Gough
2025-09-13 12:38:50 -07:00
committed by GitHub
parent 172d51e061
commit 3e5d3735dc
2 changed files with 120 additions and 100 deletions

View File

@@ -1,14 +1,21 @@
import { useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { Check, ChevronDown } from 'lucide-react'
import { useParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from '@/components/ui/command'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { createLogger } from '@/lib/logs/console/logger'
import { useFolderStore } from '@/stores/folders/store'
import { useFilterStore } from '@/stores/logs/filters/store'
@@ -26,6 +33,8 @@ export default function FolderFilter() {
const workspaceId = params.workspaceId as string
const [folders, setFolders] = useState<FolderOption[]>([])
const [loading, setLoading] = useState(true)
const [search, setSearch] = useState('')
const logger = useMemo(() => createLogger('LogsFolderFilter'), [])
// Fetch all available folders from the API
useEffect(() => {
@@ -62,7 +71,7 @@ export default function FolderFilter() {
setFolders(folderOptions)
}
} catch (error) {
console.error('Failed to fetch folders:', error)
logger.error('Failed to fetch folders', { error })
} finally {
setLoading(false)
}
@@ -105,49 +114,53 @@ export default function FolderFilter() {
</DropdownMenuTrigger>
<DropdownMenuContent
align='start'
className='max-h-[300px] w-[200px] overflow-y-auto rounded-lg border-[#E5E5E5] bg-[#FFFFFF] shadow-xs dark:border-[#414141] dark:bg-[var(--surface-elevated)]'
className='w-[200px] rounded-lg border-[#E5E5E5] bg-[#FFFFFF] p-0 shadow-xs dark:border-[#414141] dark:bg-[var(--surface-elevated)]'
>
<DropdownMenuItem
key='all'
onSelect={(e) => {
e.preventDefault()
clearSelections()
}}
className='flex cursor-pointer items-center justify-between rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
>
<span>All folders</span>
{folderIds.length === 0 && <Check className='h-4 w-4 text-muted-foreground' />}
</DropdownMenuItem>
{!loading && folders.length > 0 && <DropdownMenuSeparator />}
{!loading &&
folders.map((folder) => (
<DropdownMenuItem
key={folder.id}
onSelect={(e) => {
e.preventDefault()
toggleFolderId(folder.id)
}}
className='flex cursor-pointer items-center justify-between rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
>
<div className='flex items-center'>
<span className='truncate' title={folder.path}>
{folder.path}
</span>
</div>
{isFolderSelected(folder.id) && <Check className='h-4 w-4 text-muted-foreground' />}
</DropdownMenuItem>
))}
{loading && (
<DropdownMenuItem
disabled
className='rounded-md px-3 py-2 font-[380] text-muted-foreground text-sm'
>
Loading folders...
</DropdownMenuItem>
)}
<Command>
<CommandInput placeholder='Search folders...' onValueChange={(v) => setSearch(v)} />
<CommandList>
<CommandEmpty>{loading ? 'Loading folders...' : 'No folders found.'}</CommandEmpty>
<CommandGroup>
<CommandItem
value='all-folders'
onSelect={() => {
clearSelections()
}}
className='cursor-pointer'
>
<span>All folders</span>
{folderIds.length === 0 && (
<Check className='ml-auto h-4 w-4 text-muted-foreground' />
)}
</CommandItem>
{useMemo(() => {
const q = search.trim().toLowerCase()
const filtered = q
? folders.filter((f) => (f.path || f.name).toLowerCase().includes(q))
: folders
return filtered.map((folder) => (
<CommandItem
key={folder.id}
value={`${folder.path || folder.name}`}
onSelect={() => {
toggleFolderId(folder.id)
}}
className='cursor-pointer'
>
<div className='flex items-center'>
<span className='truncate' title={folder.path}>
{folder.path}
</span>
</div>
{isFolderSelected(folder.id) && (
<Check className='ml-auto h-4 w-4 text-muted-foreground' />
)}
</CommandItem>
))
}, [folders, search, folderIds])}
</CommandGroup>
</CommandList>
</Command>
</DropdownMenuContent>
</DropdownMenu>
)

View File

@@ -1,13 +1,20 @@
import { useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { Check, ChevronDown } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from '@/components/ui/command'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { createLogger } from '@/lib/logs/console/logger'
import { useFilterStore } from '@/stores/logs/filters/store'
interface WorkflowOption {
@@ -20,6 +27,8 @@ export default function Workflow() {
const { workflowIds, toggleWorkflowId, setWorkflowIds } = useFilterStore()
const [workflows, setWorkflows] = useState<WorkflowOption[]>([])
const [loading, setLoading] = useState(true)
const [search, setSearch] = useState('')
const logger = useMemo(() => createLogger('LogsWorkflowFilter'), [])
// Fetch all available workflows from the API
useEffect(() => {
@@ -37,7 +46,7 @@ export default function Workflow() {
setWorkflows(workflowOptions)
}
} catch (error) {
console.error('Failed to fetch workflows:', error)
logger.error('Failed to fetch workflows', { error })
} finally {
setLoading(false)
}
@@ -80,57 +89,55 @@ export default function Workflow() {
</DropdownMenuTrigger>
<DropdownMenuContent
align='start'
className='max-h-[300px] w-[180px] overflow-y-auto rounded-lg border-[#E5E5E5] bg-[#FFFFFF] shadow-xs dark:border-[#414141] dark:bg-[var(--surface-elevated)]'
style={{
scrollbarWidth: 'none',
msOverflowStyle: 'none',
}}
className='w-[180px] rounded-lg border-[#E5E5E5] bg-[#FFFFFF] p-0 shadow-xs dark:border-[#414141] dark:bg-[var(--surface-elevated)]'
>
<DropdownMenuItem
key='all'
onSelect={(e) => {
e.preventDefault()
clearSelections()
}}
className='flex cursor-pointer items-center justify-between rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
>
<span>All workflows</span>
{workflowIds.length === 0 && <Check className='h-4 w-4 text-muted-foreground' />}
</DropdownMenuItem>
{!loading && workflows.length > 0 && <DropdownMenuSeparator />}
{!loading &&
workflows.map((workflow) => (
<DropdownMenuItem
key={workflow.id}
onSelect={(e) => {
e.preventDefault()
toggleWorkflowId(workflow.id)
}}
className='flex cursor-pointer items-center justify-between rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
>
<div className='flex items-center'>
<div
className='mr-2 h-2 w-2 rounded-full'
style={{ backgroundColor: workflow.color }}
/>
{workflow.name}
</div>
{isWorkflowSelected(workflow.id) && (
<Check className='h-4 w-4 text-muted-foreground' />
)}
</DropdownMenuItem>
))}
{loading && (
<DropdownMenuItem
disabled
className='rounded-md px-3 py-2 font-[380] text-muted-foreground text-sm'
>
Loading workflows...
</DropdownMenuItem>
)}
<Command>
<CommandInput placeholder='Search workflows...' onValueChange={(v) => setSearch(v)} />
<CommandList>
<CommandEmpty>{loading ? 'Loading workflows...' : 'No workflows found.'}</CommandEmpty>
<CommandGroup>
<CommandItem
value='all-workflows'
onSelect={() => {
clearSelections()
}}
className='cursor-pointer'
>
<span>All workflows</span>
{workflowIds.length === 0 && (
<Check className='ml-auto h-4 w-4 text-muted-foreground' />
)}
</CommandItem>
{useMemo(() => {
const q = search.trim().toLowerCase()
const filtered = q
? workflows.filter((w) => w.name.toLowerCase().includes(q))
: workflows
return filtered.map((workflow) => (
<CommandItem
key={workflow.id}
value={`${workflow.name}`}
onSelect={() => {
toggleWorkflowId(workflow.id)
}}
className='cursor-pointer'
>
<div className='flex items-center'>
<div
className='mr-2 h-2 w-2 rounded-full'
style={{ backgroundColor: workflow.color }}
/>
{workflow.name}
</div>
{isWorkflowSelected(workflow.id) && (
<Check className='ml-auto h-4 w-4 text-muted-foreground' />
)}
</CommandItem>
))
}, [workflows, search, workflowIds])}
</CommandGroup>
</CommandList>
</Command>
</DropdownMenuContent>
</DropdownMenu>
)