Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,27 @@ export const MemoizedPageItem = memo(
prev.name === next.name &&
prev.shortcut === next.shortcut
)

export const MemoizedIconItem = memo(
function IconItem({
value,
onSelect,
name,
icon: Icon,
}: {
value: string
onSelect: () => void
name: string
icon: ComponentType<{ className?: string }>
}) {
return (
<Command.Item value={value} onSelect={onSelect} className={COMMAND_ITEM_CLASSNAME}>
<div className='relative flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center'>
<Icon className='h-[14px] w-[14px] text-[var(--text-icon)]' />
</div>
<span className='truncate font-base text-[var(--text-body)]'>{name}</span>
</Command.Item>
)
},
(prev, next) => prev.value === next.value && prev.name === next.name && prev.icon === next.icon
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
'use client'

import type { ComponentType } from 'react'
import { memo } from 'react'
import { Command } from 'cmdk'
import { Database, File, Table } from '@/components/emcn/icons'
import type {
SearchBlockItem,
SearchDocItem,
Expand All @@ -11,6 +13,7 @@ import type { PageItem, TaskItem, WorkflowItem, WorkspaceItem } from '../utils'
import { GROUP_HEADING_CLASSNAME } from '../utils'
import {
MemoizedCommandItem,
MemoizedIconItem,
MemoizedPageItem,
MemoizedTaskItem,
MemoizedWorkflowItem,
Expand Down Expand Up @@ -239,3 +242,36 @@ export const PagesGroup = memo(function PagesGroup({
</Command.Group>
)
})

export const TablesGroup = createIconGroup('Tables', 'table', Table)
export const FilesGroup = createIconGroup('Files', 'file', File)
export const KnowledgeBasesGroup = createIconGroup('Knowledge Bases', 'knowledge-base', Database)

function createIconGroup(
heading: string,
prefix: string,
icon: ComponentType<{ className?: string }>
) {
return memo(function IconGroup({
items,
onSelect,
}: {
items: TaskItem[]
onSelect: (item: TaskItem) => void
}) {
if (items.length === 0) return null
return (
<Command.Group heading={heading} className={GROUP_HEADING_CLASSNAME}>
{items.map((item) => (
<MemoizedIconItem
key={item.id}
value={`${item.name} ${prefix}-${item.id}`}
onSelect={() => onSelect(item)}
name={item.name}
icon={icon}
/>
))}
</Command.Group>
)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import type {
import {
BlocksGroup,
DocsGroup,
FilesGroup,
KnowledgeBasesGroup,
PagesGroup,
TablesGroup,
TasksGroup,
ToolOpsGroup,
ToolsGroup,
Expand All @@ -40,6 +43,9 @@ export function SearchModal({
workflows = [],
workspaces = [],
tasks = [],
tables = [],
files = [],
knowledgeBases = [],
isOnWorkflowPage = false,
}: SearchModalProps) {
const params = useParams()
Expand Down Expand Up @@ -284,6 +290,20 @@ export function SearchModal({
return filterAndSort(docs, (d) => `${d.name} docs documentation doc-${d.id}`, deferredSearch)
}, [isOnWorkflowPage, docs, deferredSearch])

const filteredTables = useMemo(
() => filterAndSort(tables, (t) => `${t.name} table-${t.id}`, deferredSearch),
[tables, deferredSearch]
)
const filteredFiles = useMemo(
() => filterAndSort(files, (f) => `${f.name} file-${f.id}`, deferredSearch),
[files, deferredSearch]
)
const filteredKnowledgeBases = useMemo(
() =>
filterAndSort(knowledgeBases, (kb) => `${kb.name} knowledge-base-${kb.id}`, deferredSearch),
[knowledgeBases, deferredSearch]
)

const filteredWorkflows = useMemo(
() => filterAndSort(workflows, (w) => `${w.name} workflow-${w.id}`, deferredSearch),
[workflows, deferredSearch]
Expand Down Expand Up @@ -346,6 +366,9 @@ export function SearchModal({
<TriggersGroup items={filteredTriggers} onSelect={handleBlockSelectAsTrigger} />
<WorkflowsGroup items={filteredWorkflows} onSelect={handleWorkflowSelect} />
<TasksGroup items={filteredTasks} onSelect={handleTaskSelect} />
<TablesGroup items={filteredTables} onSelect={handleTaskSelect} />
<FilesGroup items={filteredFiles} onSelect={handleTaskSelect} />
<KnowledgeBasesGroup items={filteredKnowledgeBases} onSelect={handleTaskSelect} />
<ToolOpsGroup items={filteredToolOps} onSelect={handleToolOperationSelect} />
<WorkspacesGroup items={filteredWorkspaces} onSelect={handleWorkspaceSelect} />
<DocsGroup items={filteredDocs} onSelect={handleDocSelect} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export interface SearchModalProps {
workflows?: WorkflowItem[]
workspaces?: WorkspaceItem[]
tasks?: TaskItem[]
tables?: TaskItem[]
files?: TaskItem[]
knowledgeBases?: TaskItem[]
isOnWorkflowPage?: boolean
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ import {
} from '@/app/workspace/[workspaceId]/w/hooks'
import { getBrandConfig } from '@/ee/whitelabeling'
import { useFolders } from '@/hooks/queries/folders'
import { useKnowledgeBasesQuery } from '@/hooks/queries/kb/knowledge'
import { useTablesList } from '@/hooks/queries/tables'
import {
useDeleteTask,
useDeleteTasks,
Expand All @@ -85,6 +87,7 @@ import {
useRenameTask,
useTasks,
} from '@/hooks/queries/tasks'
import { useWorkspaceFiles } from '@/hooks/queries/workspace-files'
import { usePermissionConfig } from '@/hooks/use-permission-config'
import { useSettingsNavigation } from '@/hooks/use-settings-navigation'
import { useTaskEvents } from '@/hooks/use-task-events'
Expand Down Expand Up @@ -745,6 +748,46 @@ export const Sidebar = memo(function Sidebar() {
[fetchedTasks, workspaceId]
)

const { data: fetchedTables = [] } = useTablesList(workspaceId)
const { data: fetchedFiles = [] } = useWorkspaceFiles(workspaceId)
const { data: fetchedKnowledgeBases = [] } = useKnowledgeBasesQuery(workspaceId)

const searchModalTables = useMemo(
() =>
permissionConfig.hideTablesTab
? []
: fetchedTables.map((t) => ({
id: t.id,
name: t.name,
href: `/workspace/${workspaceId}/tables/${t.id}`,
})),
[fetchedTables, workspaceId, permissionConfig.hideTablesTab]
)

const searchModalFiles = useMemo(
() =>
permissionConfig.hideFilesTab
? []
: fetchedFiles.map((f) => ({
id: f.id,
name: f.name,
href: `/workspace/${workspaceId}/files/${f.id}`,
})),
[fetchedFiles, workspaceId, permissionConfig.hideFilesTab]
)

const searchModalKnowledgeBases = useMemo(
() =>
permissionConfig.hideKnowledgeBaseTab
? []
: fetchedKnowledgeBases.map((kb) => ({
id: kb.id,
name: kb.name,
href: `/workspace/${workspaceId}/knowledge/${kb.id}`,
})),
[fetchedKnowledgeBases, workspaceId, permissionConfig.hideKnowledgeBaseTab]
)

const taskIds = useMemo(() => tasks.map((t) => t.id).filter((id) => id !== 'new'), [tasks])

const { selectedTasks, handleTaskClick } = useTaskSelection({ taskIds })
Expand Down Expand Up @@ -1671,6 +1714,9 @@ export const Sidebar = memo(function Sidebar() {
workflows={searchModalWorkflows}
workspaces={searchModalWorkspaces}
tasks={tasks}
tables={searchModalTables}
files={searchModalFiles}
knowledgeBases={searchModalKnowledgeBases}
isOnWorkflowPage={!!workflowId}
/>

Expand Down
Loading