| ...rest, | ...rest, | ||||
| type: type === InputVarType.textInput ? 'string' : type, | type: type === InputVarType.textInput ? 'string' : type, | ||||
| key: variable, | key: variable, | ||||
| name: label, | |||||
| name: label as string, | |||||
| } | } | ||||
| if (payload.type === InputVarType.textInput) | if (payload.type === InputVarType.textInput) |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| import I18n from '@/context/i18n' | import I18n from '@/context/i18n' | ||||
| import { FlipBackward } from '@/app/components/base/icons/src/vender/line/arrows' | |||||
| import { LanguagesSupported } from '@/i18n/language' | import { LanguagesSupported } from '@/i18n/language' | ||||
| type Props = { | type Props = { | ||||
| onReturnToSimpleMode: () => void | onReturnToSimpleMode: () => void | ||||
| onClick={onReturnToSimpleMode} | onClick={onReturnToSimpleMode} | ||||
| className='shrink-0 flex items-center h-6 px-2 bg-indigo-600 shadow-xs border border-gray-200 rounded-lg text-white text-xs font-semibold cursor-pointer space-x-1' | className='shrink-0 flex items-center h-6 px-2 bg-indigo-600 shadow-xs border border-gray-200 rounded-lg text-white text-xs font-semibold cursor-pointer space-x-1' | ||||
| > | > | ||||
| <FlipBackward className='w-3 h-3 text-white' /> | |||||
| <div className='text-xs font-semibold uppercase'>{t('appDebug.promptMode.switchBack')}</div> | <div className='text-xs font-semibold uppercase'>{t('appDebug.promptMode.switchBack')}</div> | ||||
| </div> | </div> | ||||
| <div | <div |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { XMarkIcon } from '@heroicons/react/24/outline' | import { XMarkIcon } from '@heroicons/react/24/outline' | ||||
| import NotionPageSelector from '../base' | import NotionPageSelector from '../base' | ||||
| import type { NotionPageSelectorValue } from '../base' | |||||
| import s from './index.module.css' | import s from './index.module.css' | ||||
| import type { NotionPage } from '@/models/common' | |||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| type NotionPageSelectorModalProps = { | type NotionPageSelectorModalProps = { | ||||
| isShow: boolean | isShow: boolean | ||||
| onClose: () => void | onClose: () => void | ||||
| onSave: (selectedPages: NotionPageSelectorValue[]) => void | |||||
| onSave: (selectedPages: NotionPage[]) => void | |||||
| datasetId: string | datasetId: string | ||||
| } | } | ||||
| const NotionPageSelectorModal = ({ | const NotionPageSelectorModal = ({ | ||||
| datasetId, | datasetId, | ||||
| }: NotionPageSelectorModalProps) => { | }: NotionPageSelectorModalProps) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const [selectedPages, setSelectedPages] = useState<NotionPageSelectorValue[]>([]) | |||||
| const [selectedPages, setSelectedPages] = useState<NotionPage[]>([]) | |||||
| const handleClose = () => { | const handleClose = () => { | ||||
| onClose() | onClose() | ||||
| } | } | ||||
| const handleSelectPage = (newSelectedPages: NotionPageSelectorValue[]) => { | |||||
| const handleSelectPage = (newSelectedPages: NotionPage[]) => { | |||||
| setSelectedPages(newSelectedPages) | setSelectedPages(newSelectedPages) | ||||
| } | } | ||||
| const handleSave = () => { | const handleSave = () => { |
| onClick={(e) => { | onClick={(e) => { | ||||
| e.stopPropagation() | e.stopPropagation() | ||||
| setSelectedItem(null) | setSelectedItem(null) | ||||
| onSelect({ value: null }) | |||||
| onSelect({ name: '', value: '' }) | |||||
| }} | }} | ||||
| className="h-5 w-5 text-gray-400 cursor-pointer" | className="h-5 w-5 text-gray-400 cursor-pointer" | ||||
| aria-hidden="false" | aria-hidden="false" |
| allCategoriesEn, | allCategoriesEn, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const isAllCategories = !list.includes(value) | |||||
| const isAllCategories = !list.includes(value as AppCategory) | |||||
| const itemClassName = (isSelected: boolean) => cn( | const itemClassName = (isSelected: boolean) => cn( | ||||
| 'flex items-center px-3 py-[7px] h-[32px] rounded-lg border-[0.5px] border-transparent text-gray-700 font-medium leading-[18px] cursor-pointer hover:bg-gray-200', | 'flex items-center px-3 py-[7px] h-[32px] rounded-lg border-[0.5px] border-transparent text-gray-700 font-medium leading-[18px] cursor-pointer hover:bg-gray-200', |
| secretInput = 'secret-input', | secretInput = 'secret-input', | ||||
| select = 'select', | select = 'select', | ||||
| radio = 'radio', | radio = 'radio', | ||||
| boolean = 'boolean', | |||||
| files = 'files', | files = 'files', | ||||
| } | } | ||||
| import useSWRInfinite from 'swr/infinite' | import useSWRInfinite from 'swr/infinite' | ||||
| import { flatten } from 'lodash-es' | import { flatten } from 'lodash-es' | ||||
| import Nav from '../nav' | import Nav from '../nav' | ||||
| import type { NavItem } from '../nav/nav-selector' | |||||
| import { fetchDatasetDetail, fetchDatasets } from '@/service/datasets' | import { fetchDatasetDetail, fetchDatasets } from '@/service/datasets' | ||||
| import type { DataSetListResponse } from '@/models/datasets' | import type { DataSetListResponse } from '@/models/datasets' | ||||
| datasetId, | datasetId, | ||||
| } | } | ||||
| : null, | : null, | ||||
| apiParams => fetchDatasetDetail(apiParams.datasetId)) | |||||
| apiParams => fetchDatasetDetail(apiParams.datasetId as string)) | |||||
| const { data: datasetsData, setSize } = useSWRInfinite(datasetId ? getKey : () => null, fetchDatasets, { revalidateFirstPage: false, revalidateAll: true }) | const { data: datasetsData, setSize } = useSWRInfinite(datasetId ? getKey : () => null, fetchDatasets, { revalidateFirstPage: false, revalidateAll: true }) | ||||
| const datasetItems = flatten(datasetsData?.map(datasetData => datasetData.data)) | const datasetItems = flatten(datasetsData?.map(datasetData => datasetData.data)) | ||||
| text={t('common.menus.datasets')} | text={t('common.menus.datasets')} | ||||
| activeSegment='datasets' | activeSegment='datasets' | ||||
| link='/datasets' | link='/datasets' | ||||
| curNav={currentDataset} | |||||
| curNav={currentDataset as Omit<NavItem, 'link'>} | |||||
| navs={datasetItems.map(dataset => ({ | navs={datasetItems.map(dataset => ({ | ||||
| id: dataset.id, | id: dataset.id, | ||||
| name: dataset.name, | name: dataset.name, | ||||
| link: `/datasets/${dataset.id}/documents`, | link: `/datasets/${dataset.id}/documents`, | ||||
| icon: dataset.icon, | icon: dataset.icon, | ||||
| icon_background: dataset.icon_background, | icon_background: dataset.icon_background, | ||||
| }))} | |||||
| })) as NavItem[]} | |||||
| createText={t('common.menus.newDataset')} | createText={t('common.menus.newDataset')} | ||||
| onCreate={() => router.push('/datasets/create')} | onCreate={() => router.push('/datasets/create')} | ||||
| onLoadmore={handleLoadmore} | onLoadmore={handleLoadmore} |
| link: string | link: string | ||||
| icon: string | icon: string | ||||
| icon_background: string | icon_background: string | ||||
| mode: string | |||||
| mode?: string | |||||
| } | } | ||||
| export type INavSelectorProps = { | export type INavSelectorProps = { | ||||
| navs: NavItem[] | navs: NavItem[] | ||||
| curNav?: Omit<NavItem, 'link'> | curNav?: Omit<NavItem, 'link'> | ||||
| createText: string | createText: string | ||||
| isApp: boolean | |||||
| isApp?: boolean | |||||
| onCreate: (state: string) => void | onCreate: (state: string) => void | ||||
| onLoadmore?: () => void | onLoadmore?: () => void | ||||
| } | } |
| }, [collection.labels, labelList, language]) | }, [collection.labels, labelList, language]) | ||||
| return ( | return ( | ||||
| <div className={cn('group flex col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg', active && '!border-primary-400')} onClick={onSelect}> | |||||
| <div className={cn('group col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg', active && '!border-primary-400')} onClick={onSelect}> | |||||
| <div className='flex pt-[14px] px-[14px] pb-3 h-[66px] items-center gap-3 grow-0 shrink-0'> | <div className='flex pt-[14px] px-[14px] pb-3 h-[66px] items-center gap-3 grow-0 shrink-0'> | ||||
| <div className='relative shrink-0'> | <div className='relative shrink-0'> | ||||
| {typeof collection.icon === 'string' && ( | {typeof collection.icon === 'string' && ( |
| const [customCollection, setCustomCollection] = useState<CustomCollectionBackend | WorkflowToolProviderResponse | null>(null) | const [customCollection, setCustomCollection] = useState<CustomCollectionBackend | WorkflowToolProviderResponse | null>(null) | ||||
| const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) | const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) | ||||
| const [showConfirmDelete, setShowConfirmDelete] = useState(false) | const [showConfirmDelete, setShowConfirmDelete] = useState(false) | ||||
| const [deleteAction, setDeleteAction] = useState(null) | |||||
| const [deleteAction, setDeleteAction] = useState('') | |||||
| const doUpdateCustomToolCollection = async (data: CustomCollectionBackend) => { | const doUpdateCustomToolCollection = async (data: CustomCollectionBackend) => { | ||||
| await updateCustomCollection(data) | await updateCustomCollection(data) | ||||
| onRefreshData() | onRefreshData() |
| <div> | <div> | ||||
| <div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.description')}</div> | <div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.description')}</div> | ||||
| <textarea | <textarea | ||||
| className='w-full h-10 px-3 py-2 text-sm font-normal bg-gray-100 rounded-lg border border-transparent outline-none appearance-none caret-primary-600 placeholder:text-gray-400 hover:bg-gray-50 hover:border hover:border-gray-300 focus:bg-gray-50 focus:border focus:border-gray-300 focus:shadow-xs h-[80px] resize-none' | |||||
| className='w-full px-3 py-2 text-sm font-normal bg-gray-100 rounded-lg border border-transparent outline-none appearance-none caret-primary-600 placeholder:text-gray-400 hover:bg-gray-50 hover:border hover:border-gray-300 focus:bg-gray-50 focus:border focus:border-gray-300 focus:shadow-xs h-[80px] resize-none' | |||||
| placeholder={t('tools.createTool.descriptionPlaceholder') || ''} | placeholder={t('tools.createTool.descriptionPlaceholder') || ''} | ||||
| value={description} | value={description} | ||||
| onChange={e => setDescription(e.target.value)} | onChange={e => setDescription(e.target.value)} |
| import { pinyin } from 'pinyin-pro' | import { pinyin } from 'pinyin-pro' | ||||
| import type { FC, RefObject } from 'react' | |||||
| export const groupItems = (items, getFirstChar) => { | |||||
| export const groupItems = (items: Array<any>, getFirstChar: (item: string) => string) => { | |||||
| const groups = items.reduce((acc, item) => { | const groups = items.reduce((acc, item) => { | ||||
| const firstChar = getFirstChar(item) | const firstChar = getFirstChar(item) | ||||
| if (!firstChar || firstChar.length === 0) | if (!firstChar || firstChar.length === 0) | ||||
| return { letters, groups } | return { letters, groups } | ||||
| } | } | ||||
| const IndexBar = ({ letters, itemRefs }) => { | |||||
| const handleIndexClick = (letter) => { | |||||
| const element = itemRefs.current[letter] | |||||
| type IndexBarProps = { | |||||
| letters: string[] | |||||
| itemRefs: RefObject<{ [key: string]: HTMLElement | null }> | |||||
| } | |||||
| const IndexBar: FC<IndexBarProps> = ({ letters, itemRefs }) => { | |||||
| const handleIndexClick = (letter: string) => { | |||||
| const element = itemRefs.current?.[letter] | |||||
| if (element) | if (element) | ||||
| element.scrollIntoView({ behavior: 'smooth' }) | element.scrollIntoView({ behavior: 'smooth' }) | ||||
| } | } |