-
Notifications
You must be signed in to change notification settings - Fork 3.3k
feat(timeout): add API block timeout configuration #3053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
06ce137
64f7b84
e2023dc
d57fa9f
7b0a911
afae856
bad68f9
d442ab7
8104f29
927fc8e
dbb04ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,10 +6,10 @@ import { Database, HelpCircle, Layout, Settings } from 'lucide-react' | |
| import { useParams, useRouter } from 'next/navigation' | ||
| import { createPortal } from 'react-dom' | ||
| import { Library } from '@/components/emcn' | ||
| import { useBrandConfig } from '@/lib/branding/branding' | ||
| import { cn } from '@/lib/core/utils/cn' | ||
| import { hasTriggerCapability } from '@/lib/workflows/triggers/trigger-utils' | ||
| import { SIDEBAR_SCROLL_EVENT } from '@/app/workspace/[workspaceId]/w/components/sidebar/sidebar' | ||
| import { usePermissionConfig } from '@/hooks/use-permission-config' | ||
| import { useSearchModalStore } from '@/stores/modals/search/store' | ||
| import type { | ||
| SearchBlockItem, | ||
|
|
@@ -18,6 +18,23 @@ import type { | |
| } from '@/stores/modals/search/types' | ||
| import { useSettingsModalStore } from '@/stores/modals/settings/store' | ||
|
|
||
| function customFilter(value: string, search: string): number { | ||
| const searchLower = search.toLowerCase() | ||
| const valueLower = value.toLowerCase() | ||
|
|
||
| if (valueLower === searchLower) return 1 | ||
| if (valueLower.startsWith(searchLower)) return 0.9 | ||
| if (valueLower.includes(searchLower)) return 0.7 | ||
|
|
||
| const searchWords = searchLower.split(/\s+/).filter(Boolean) | ||
| if (searchWords.length > 1) { | ||
| const allWordsMatch = searchWords.every((word) => valueLower.includes(word)) | ||
| if (allWordsMatch) return 0.5 | ||
| } | ||
|
|
||
| return 0 | ||
| } | ||
waleedlatif1 marked this conversation as resolved.
Show resolved
Hide resolved
waleedlatif1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| interface SearchModalProps { | ||
| open: boolean | ||
| onOpenChange: (open: boolean) => void | ||
|
|
@@ -48,6 +65,7 @@ interface PageItem { | |
| href?: string | ||
| onClick?: () => void | ||
| shortcut?: string | ||
| hidden?: boolean | ||
| } | ||
|
|
||
| export function SearchModal({ | ||
|
|
@@ -60,11 +78,10 @@ export function SearchModal({ | |
| const params = useParams() | ||
| const router = useRouter() | ||
| const workspaceId = params.workspaceId as string | ||
| const brand = useBrandConfig() | ||
| const inputRef = useRef<HTMLInputElement>(null) | ||
| const [search, setSearch] = useState('') | ||
| const [mounted, setMounted] = useState(false) | ||
| const openSettingsModal = useSettingsModalStore((state) => state.openModal) | ||
| const { config: permissionConfig } = usePermissionConfig() | ||
|
|
||
| useEffect(() => { | ||
| setMounted(true) | ||
|
|
@@ -79,54 +96,66 @@ export function SearchModal({ | |
| }, []) | ||
|
|
||
| const pages = useMemo( | ||
| (): PageItem[] => [ | ||
| { | ||
| id: 'logs', | ||
| name: 'Logs', | ||
| icon: Library, | ||
| href: `/workspace/${workspaceId}/logs`, | ||
| shortcut: '⌘⇧L', | ||
| }, | ||
| { | ||
| id: 'templates', | ||
| name: 'Templates', | ||
| icon: Layout, | ||
| href: `/workspace/${workspaceId}/templates`, | ||
| }, | ||
| { | ||
| id: 'knowledge-base', | ||
| name: 'Knowledge Base', | ||
| icon: Database, | ||
| href: `/workspace/${workspaceId}/knowledge`, | ||
| }, | ||
| { | ||
| id: 'help', | ||
| name: 'Help', | ||
| icon: HelpCircle, | ||
| onClick: openHelpModal, | ||
| }, | ||
| { | ||
| id: 'settings', | ||
| name: 'Settings', | ||
| icon: Settings, | ||
| onClick: openSettingsModal, | ||
| shortcut: '⌘,', | ||
| }, | ||
| ], | ||
| [workspaceId, openHelpModal, openSettingsModal] | ||
| (): PageItem[] => | ||
| [ | ||
| { | ||
| id: 'logs', | ||
| name: 'Logs', | ||
| icon: Library, | ||
| href: `/workspace/${workspaceId}/logs`, | ||
| shortcut: '⌘⇧L', | ||
| }, | ||
| { | ||
| id: 'templates', | ||
| name: 'Templates', | ||
| icon: Layout, | ||
| href: `/workspace/${workspaceId}/templates`, | ||
| hidden: permissionConfig.hideTemplates, | ||
| }, | ||
| { | ||
| id: 'knowledge-base', | ||
| name: 'Knowledge Base', | ||
| icon: Database, | ||
| href: `/workspace/${workspaceId}/knowledge`, | ||
| hidden: permissionConfig.hideKnowledgeBaseTab, | ||
| }, | ||
| { | ||
| id: 'help', | ||
| name: 'Help', | ||
| icon: HelpCircle, | ||
| onClick: openHelpModal, | ||
| }, | ||
| { | ||
| id: 'settings', | ||
| name: 'Settings', | ||
| icon: Settings, | ||
| onClick: openSettingsModal, | ||
| }, | ||
| ].filter((page) => !page.hidden), | ||
| [ | ||
| workspaceId, | ||
| openHelpModal, | ||
| openSettingsModal, | ||
| permissionConfig.hideTemplates, | ||
| permissionConfig.hideKnowledgeBaseTab, | ||
| ] | ||
| ) | ||
|
|
||
| useEffect(() => { | ||
| if (open) { | ||
| setSearch('') | ||
| requestAnimationFrame(() => { | ||
| inputRef.current?.focus() | ||
| }) | ||
| if (open && inputRef.current) { | ||
| const nativeInputValueSetter = Object.getOwnPropertyDescriptor( | ||
| window.HTMLInputElement.prototype, | ||
| 'value' | ||
| )?.set | ||
| if (nativeInputValueSetter) { | ||
| nativeInputValueSetter.call(inputRef.current, '') | ||
| inputRef.current.dispatchEvent(new Event('input', { bubbles: true })) | ||
| } | ||
| inputRef.current.focus() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overly complex DOM manipulation to clear inputLow Severity The new approach uses |
||
| } | ||
| }, [open]) | ||
|
|
||
| const handleSearchChange = useCallback((value: string) => { | ||
| setSearch(value) | ||
| const handleSearchChange = useCallback(() => { | ||
| requestAnimationFrame(() => { | ||
| const list = document.querySelector('[cmdk-list]') | ||
| if (list) { | ||
|
|
@@ -228,28 +257,6 @@ export function SearchModal({ | |
| const showToolOperations = isOnWorkflowPage && toolOperations.length > 0 | ||
| const showDocs = isOnWorkflowPage && docs.length > 0 | ||
|
|
||
| const customFilter = useCallback((value: string, search: string, keywords?: string[]) => { | ||
| const searchLower = search.toLowerCase() | ||
| const valueLower = value.toLowerCase() | ||
|
|
||
| if (valueLower === searchLower) return 1 | ||
| if (valueLower.startsWith(searchLower)) return 0.8 | ||
| if (valueLower.includes(searchLower)) return 0.6 | ||
|
|
||
| const searchWords = searchLower.split(/\s+/).filter(Boolean) | ||
| const allWordsMatch = searchWords.every((word) => valueLower.includes(word)) | ||
| if (allWordsMatch && searchWords.length > 0) return 0.4 | ||
|
|
||
| if (keywords?.length) { | ||
| const keywordsLower = keywords.join(' ').toLowerCase() | ||
| if (keywordsLower.includes(searchLower)) return 0.3 | ||
| const keywordWordsMatch = searchWords.every((word) => keywordsLower.includes(word)) | ||
| if (keywordWordsMatch && searchWords.length > 0) return 0.2 | ||
| } | ||
|
|
||
| return 0 | ||
| }, []) | ||
|
|
||
| if (!mounted) return null | ||
|
|
||
| return createPortal( | ||
|
|
@@ -278,7 +285,6 @@ export function SearchModal({ | |
| <Command label='Search' filter={customFilter}> | ||
| <Command.Input | ||
| ref={inputRef} | ||
| value={search} | ||
| autoFocus | ||
| onValueChange={handleSearchChange} | ||
| placeholder='Search anything...' | ||
|
|
@@ -295,7 +301,6 @@ export function SearchModal({ | |
| <CommandItem | ||
| key={block.id} | ||
| value={`${block.name} block-${block.id}`} | ||
| keywords={[block.description]} | ||
| onSelect={() => handleBlockSelect(block, 'block')} | ||
| icon={block.icon} | ||
| bgColor={block.bgColor} | ||
|
|
@@ -313,7 +318,6 @@ export function SearchModal({ | |
| <CommandItem | ||
| key={tool.id} | ||
| value={`${tool.name} tool-${tool.id}`} | ||
| keywords={[tool.description]} | ||
| onSelect={() => handleBlockSelect(tool, 'tool')} | ||
| icon={tool.icon} | ||
| bgColor={tool.bgColor} | ||
|
|
@@ -331,7 +335,6 @@ export function SearchModal({ | |
| <CommandItem | ||
| key={trigger.id} | ||
| value={`${trigger.name} trigger-${trigger.id}`} | ||
| keywords={[trigger.description]} | ||
| onSelect={() => handleBlockSelect(trigger, 'trigger')} | ||
| icon={trigger.icon} | ||
| bgColor={trigger.bgColor} | ||
|
|
@@ -371,7 +374,6 @@ export function SearchModal({ | |
| <CommandItem | ||
| key={op.id} | ||
| value={`${op.searchValue} operation-${op.id}`} | ||
| keywords={op.keywords} | ||
| onSelect={() => handleToolOperationSelect(op)} | ||
| icon={op.icon} | ||
| bgColor={op.bgColor} | ||
|
|
@@ -458,7 +460,6 @@ const groupHeadingClassName = | |
|
|
||
| interface CommandItemProps { | ||
| value: string | ||
| keywords?: string[] | ||
| onSelect: () => void | ||
| icon: React.ComponentType<{ className?: string }> | ||
| bgColor: string | ||
|
|
@@ -468,7 +469,6 @@ interface CommandItemProps { | |
|
|
||
| function CommandItem({ | ||
| value, | ||
| keywords, | ||
| onSelect, | ||
| icon: Icon, | ||
| bgColor, | ||
|
|
@@ -478,7 +478,6 @@ function CommandItem({ | |
| return ( | ||
| <Command.Item | ||
| value={value} | ||
| keywords={keywords} | ||
| onSelect={onSelect} | ||
| className='group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50' | ||
| > | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.