Skip to content

Commit f5936ee

Browse files
committed
feat(search): add tables, files, knowledge bases, and jobs to cmd-k search
1 parent b0980b1 commit f5936ee

File tree

5 files changed

+156
-0
lines changed

5 files changed

+156
-0
lines changed

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/_components/command-items.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,27 @@ export const MemoizedPageItem = memo(
163163
prev.name === next.name &&
164164
prev.shortcut === next.shortcut
165165
)
166+
167+
export const MemoizedIconItem = memo(
168+
function IconItem({
169+
value,
170+
onSelect,
171+
name,
172+
icon: Icon,
173+
}: {
174+
value: string
175+
onSelect: () => void
176+
name: string
177+
icon: ComponentType<{ className?: string }>
178+
}) {
179+
return (
180+
<Command.Item value={value} onSelect={onSelect} className={COMMAND_ITEM_CLASSNAME}>
181+
<div className='relative flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center'>
182+
<Icon className='h-[14px] w-[14px] text-[var(--text-icon)]' />
183+
</div>
184+
<span className='truncate font-base text-[var(--text-body)]'>{name}</span>
185+
</Command.Item>
186+
)
187+
},
188+
(prev, next) => prev.value === next.value && prev.name === next.name && prev.icon === next.icon
189+
)

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/_components/search-groups.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
'use client'
22

3+
import type { ComponentType } from 'react'
34
import { memo } from 'react'
45
import { Command } from 'cmdk'
6+
import { Calendar, Database, File, Table } from '@/components/emcn/icons'
57
import type {
68
SearchBlockItem,
79
SearchDocItem,
@@ -11,6 +13,7 @@ import type { PageItem, TaskItem, WorkflowItem, WorkspaceItem } from '../utils'
1113
import { GROUP_HEADING_CLASSNAME } from '../utils'
1214
import {
1315
MemoizedCommandItem,
16+
MemoizedIconItem,
1417
MemoizedPageItem,
1518
MemoizedTaskItem,
1619
MemoizedWorkflowItem,
@@ -239,3 +242,37 @@ export const PagesGroup = memo(function PagesGroup({
239242
</Command.Group>
240243
)
241244
})
245+
246+
export const TablesGroup = createIconGroup('Tables', 'table', Table)
247+
export const FilesGroup = createIconGroup('Files', 'file', File)
248+
export const KnowledgeBasesGroup = createIconGroup('Knowledge Bases', 'knowledge-base', Database)
249+
export const JobsGroup = createIconGroup('Jobs', 'job', Calendar)
250+
251+
function createIconGroup(
252+
heading: string,
253+
prefix: string,
254+
icon: ComponentType<{ className?: string }>
255+
) {
256+
return memo(function IconGroup({
257+
items,
258+
onSelect,
259+
}: {
260+
items: TaskItem[]
261+
onSelect: (item: TaskItem) => void
262+
}) {
263+
if (items.length === 0) return null
264+
return (
265+
<Command.Group heading={heading} className={GROUP_HEADING_CLASSNAME}>
266+
{items.map((item) => (
267+
<MemoizedIconItem
268+
key={item.id}
269+
value={`${item.name} ${prefix}-${item.id}`}
270+
onSelect={() => onSelect(item)}
271+
name={item.name}
272+
icon={icon}
273+
/>
274+
))}
275+
</Command.Group>
276+
)
277+
})
278+
}

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ import type {
2121
import {
2222
BlocksGroup,
2323
DocsGroup,
24+
FilesGroup,
25+
JobsGroup,
26+
KnowledgeBasesGroup,
2427
PagesGroup,
28+
TablesGroup,
2529
TasksGroup,
2630
ToolOpsGroup,
2731
ToolsGroup,
@@ -40,6 +44,10 @@ export function SearchModal({
4044
workflows = [],
4145
workspaces = [],
4246
tasks = [],
47+
tables = [],
48+
files = [],
49+
knowledgeBases = [],
50+
jobs = [],
4351
isOnWorkflowPage = false,
4452
}: SearchModalProps) {
4553
const params = useParams()
@@ -284,6 +292,24 @@ export function SearchModal({
284292
return filterAndSort(docs, (d) => `${d.name} docs documentation doc-${d.id}`, deferredSearch)
285293
}, [isOnWorkflowPage, docs, deferredSearch])
286294

295+
const filteredTables = useMemo(
296+
() => filterAndSort(tables, (t) => `${t.name} table-${t.id}`, deferredSearch),
297+
[tables, deferredSearch]
298+
)
299+
const filteredFiles = useMemo(
300+
() => filterAndSort(files, (f) => `${f.name} file-${f.id}`, deferredSearch),
301+
[files, deferredSearch]
302+
)
303+
const filteredKnowledgeBases = useMemo(
304+
() =>
305+
filterAndSort(knowledgeBases, (kb) => `${kb.name} knowledge-base-${kb.id}`, deferredSearch),
306+
[knowledgeBases, deferredSearch]
307+
)
308+
const filteredJobs = useMemo(
309+
() => filterAndSort(jobs, (j) => `${j.name} job-${j.id}`, deferredSearch),
310+
[jobs, deferredSearch]
311+
)
312+
287313
const filteredWorkflows = useMemo(
288314
() => filterAndSort(workflows, (w) => `${w.name} workflow-${w.id}`, deferredSearch),
289315
[workflows, deferredSearch]
@@ -346,6 +372,10 @@ export function SearchModal({
346372
<TriggersGroup items={filteredTriggers} onSelect={handleBlockSelectAsTrigger} />
347373
<WorkflowsGroup items={filteredWorkflows} onSelect={handleWorkflowSelect} />
348374
<TasksGroup items={filteredTasks} onSelect={handleTaskSelect} />
375+
<TablesGroup items={filteredTables} onSelect={handleTaskSelect} />
376+
<FilesGroup items={filteredFiles} onSelect={handleTaskSelect} />
377+
<KnowledgeBasesGroup items={filteredKnowledgeBases} onSelect={handleTaskSelect} />
378+
<JobsGroup items={filteredJobs} onSelect={handleTaskSelect} />
349379
<ToolOpsGroup items={filteredToolOps} onSelect={handleToolOperationSelect} />
350380
<WorkspacesGroup items={filteredWorkspaces} onSelect={handleWorkspaceSelect} />
351381
<DocsGroup items={filteredDocs} onSelect={handleDocSelect} />

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export interface SearchModalProps {
3737
workflows?: WorkflowItem[]
3838
workspaces?: WorkspaceItem[]
3939
tasks?: TaskItem[]
40+
tables?: TaskItem[]
41+
files?: TaskItem[]
42+
knowledgeBases?: TaskItem[]
43+
jobs?: TaskItem[]
4044
isOnWorkflowPage?: boolean
4145
}
4246

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ import {
7777
} from '@/app/workspace/[workspaceId]/w/hooks'
7878
import { getBrandConfig } from '@/ee/whitelabeling'
7979
import { useFolders } from '@/hooks/queries/folders'
80+
import { useKnowledgeBasesQuery } from '@/hooks/queries/kb/knowledge'
81+
import { useWorkspaceSchedules } from '@/hooks/queries/schedules'
82+
import { useTablesList } from '@/hooks/queries/tables'
8083
import {
8184
useDeleteTask,
8285
useDeleteTasks,
@@ -85,6 +88,7 @@ import {
8588
useRenameTask,
8689
useTasks,
8790
} from '@/hooks/queries/tasks'
91+
import { useWorkspaceFiles } from '@/hooks/queries/workspace-files'
8892
import { usePermissionConfig } from '@/hooks/use-permission-config'
8993
import { useSettingsNavigation } from '@/hooks/use-settings-navigation'
9094
import { useTaskEvents } from '@/hooks/use-task-events'
@@ -745,6 +749,59 @@ export const Sidebar = memo(function Sidebar() {
745749
[fetchedTasks, workspaceId]
746750
)
747751

752+
const { data: fetchedTables = [] } = useTablesList(workspaceId)
753+
const { data: fetchedFiles = [] } = useWorkspaceFiles(workspaceId as string)
754+
const { data: fetchedKnowledgeBases = [] } = useKnowledgeBasesQuery(workspaceId)
755+
const { data: fetchedSchedules = [] } = useWorkspaceSchedules(workspaceId)
756+
757+
const searchModalTables = useMemo(
758+
() =>
759+
permissionConfig.hideTablesTab
760+
? []
761+
: fetchedTables.map((t) => ({
762+
id: t.id,
763+
name: t.name,
764+
href: `/workspace/${workspaceId}/tables/${t.id}`,
765+
})),
766+
[fetchedTables, workspaceId, permissionConfig.hideTablesTab]
767+
)
768+
769+
const searchModalFiles = useMemo(
770+
() =>
771+
permissionConfig.hideFilesTab
772+
? []
773+
: fetchedFiles.map((f) => ({
774+
id: f.id,
775+
name: f.name,
776+
href: `/workspace/${workspaceId}/files`,
777+
})),
778+
[fetchedFiles, workspaceId, permissionConfig.hideFilesTab]
779+
)
780+
781+
const searchModalKnowledgeBases = useMemo(
782+
() =>
783+
permissionConfig.hideKnowledgeBaseTab
784+
? []
785+
: fetchedKnowledgeBases.map((kb) => ({
786+
id: kb.id,
787+
name: kb.name,
788+
href: `/workspace/${workspaceId}/knowledge/${kb.id}`,
789+
})),
790+
[fetchedKnowledgeBases, workspaceId, permissionConfig.hideKnowledgeBaseTab]
791+
)
792+
793+
const searchModalJobs = useMemo(
794+
() =>
795+
fetchedSchedules
796+
.filter((s) => s.sourceType === 'job')
797+
.map((s) => ({
798+
id: s.id,
799+
name: s.jobTitle || 'Untitled Job',
800+
href: `/workspace/${workspaceId}/scheduled-tasks`,
801+
})),
802+
[fetchedSchedules, workspaceId]
803+
)
804+
748805
const taskIds = useMemo(() => tasks.map((t) => t.id).filter((id) => id !== 'new'), [tasks])
749806

750807
const { selectedTasks, handleTaskClick } = useTaskSelection({ taskIds })
@@ -1671,6 +1728,10 @@ export const Sidebar = memo(function Sidebar() {
16711728
workflows={searchModalWorkflows}
16721729
workspaces={searchModalWorkspaces}
16731730
tasks={tasks}
1731+
tables={searchModalTables}
1732+
files={searchModalFiles}
1733+
knowledgeBases={searchModalKnowledgeBases}
1734+
jobs={searchModalJobs}
16741735
isOnWorkflowPage={!!workflowId}
16751736
/>
16761737

0 commit comments

Comments
 (0)