'use client' import type { Placement } from '@langgenius/dify-ui/combobox' import type { ReactNode } from 'react' import type { App } from '@/types/app' import { Button } from '@langgenius/dify-ui/button' import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxInputGroup, ComboboxItem, ComboboxItemText, ComboboxList, ComboboxStatus, ComboboxTrigger, } from '@langgenius/dify-ui/combobox' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import AppIcon from '@/app/components/base/app-icon' import { AppModeEnum } from '@/types/app' type AppPickerProps = { scope?: string disabled: boolean trigger: ReactNode placement?: Placement offset?: number isShow: boolean onShowChange: (isShow: boolean) => void onSelect: (app: App) => void apps: App[] isLoading: boolean hasMore: boolean onLoadMore: () => void searchText: string onSearchChange: (text: string) => void } function getAppTypeLabel(app: App) { switch (app.mode) { case AppModeEnum.ADVANCED_CHAT: return 'chatflow' case AppModeEnum.AGENT_CHAT: return 'agent' case AppModeEnum.CHAT: return 'chat' case AppModeEnum.COMPLETION: return 'completion' case AppModeEnum.WORKFLOW: return 'workflow' default: return app.mode } } function getAppSearchText(app: App) { return `${app.name} ${app.id} ${getAppTypeLabel(app)}` } function AppPickerOption({ app, }: { app: App }) { return ( {app.name} ( {app.id.slice(0, 8)} ) {getAppTypeLabel(app)} ) } export function AppPicker({ disabled, trigger, placement = 'right-start', offset = 0, isShow, onShowChange, onSelect, apps, isLoading, hasMore, onLoadMore, searchText, onSearchChange, }: AppPickerProps) { const { t } = useTranslation() const handleValueChange = useCallback((app: App | null) => { if (!app) return onSelect(app) onShowChange(false) }, [onSelect, onShowChange]) return ( items={apps} open={isShow} inputValue={searchText} onOpenChange={onShowChange} onInputValueChange={onSearchChange} onValueChange={handleValueChange} itemToStringLabel={app => app?.name ?? ''} itemToStringValue={app => app?.id ?? ''} filter={(app, query) => getAppSearchText(app).toLowerCase().includes(query.toLowerCase())} disabled={disabled} > {trigger} {searchText && ( onSearchChange('')} > )} {isLoading && ( {t('loading', { ns: 'common' })} )} {(app: App) => ( )} {t('noData', { ns: 'common' })} {hasMore && ( onLoadMore()} > {isLoading ? t('loading', { ns: 'common' }) : t('common.loadMore', { ns: 'workflow' })} )} ) }