Spaces:
Paused
Paused
| 'use client' | |
| import type { FC } from 'react' | |
| import React, { useState } from 'react' | |
| import { useTranslation } from 'react-i18next' | |
| import { useClickAway } from 'ahooks' | |
| import { | |
| RiAddLine, | |
| RiArrowDownSLine, | |
| } from '@remixicon/react' | |
| import Toast from '../../base/toast' | |
| import examples from './examples' | |
| import Button from '@/app/components/base/button' | |
| import { importSchemaFromURL } from '@/service/tools' | |
| type Props = { | |
| onChange: (value: string) => void | |
| } | |
| const GetSchema: FC<Props> = ({ | |
| onChange, | |
| }) => { | |
| const { t } = useTranslation() | |
| const [showImportFromUrl, setShowImportFromUrl] = useState(false) | |
| const [importUrl, setImportUrl] = useState('') | |
| const [isParsing, setIsParsing] = useState(false) | |
| const handleImportFromUrl = async () => { | |
| if (!importUrl.startsWith('http://') && !importUrl.startsWith('https://')) { | |
| Toast.notify({ | |
| type: 'error', | |
| message: t('tools.createTool.urlError'), | |
| }) | |
| return | |
| } | |
| setIsParsing(true) | |
| try { | |
| const { schema } = await importSchemaFromURL(importUrl) as any | |
| setImportUrl('') | |
| onChange(schema) | |
| } | |
| finally { | |
| setIsParsing(false) | |
| setShowImportFromUrl(false) | |
| } | |
| } | |
| const importURLRef = React.useRef(null) | |
| useClickAway(() => { | |
| setShowImportFromUrl(false) | |
| }, importURLRef) | |
| const [showExamples, setShowExamples] = useState(false) | |
| const showExamplesRef = React.useRef(null) | |
| useClickAway(() => { | |
| setShowExamples(false) | |
| }, showExamplesRef) | |
| return ( | |
| <div className='flex space-x-1 justify-end relative w-[224px]'> | |
| <div ref={importURLRef}> | |
| <Button | |
| size='small' | |
| className='space-x-1 ' | |
| onClick={() => { setShowImportFromUrl(!showImportFromUrl) }} | |
| > | |
| <RiAddLine className='w-3 h-3' /> | |
| <div className='text-xs font-medium text-gray-700'>{t('tools.createTool.importFromUrl')}</div> | |
| </Button> | |
| {showImportFromUrl && ( | |
| <div className=' absolute left-[-35px] top-[26px] p-2 rounded-lg border border-gray-200 bg-white shadow-lg'> | |
| <div className='relative'> | |
| <input | |
| type='text' | |
| className='w-[244px] h-8 pl-1.5 pr-[44px] overflow-x-auto border border-gray-200 rounded-lg text-[13px]' | |
| placeholder={t('tools.createTool.importFromUrlPlaceHolder')!} | |
| value={importUrl} | |
| onChange={e => setImportUrl(e.target.value)} | |
| /> | |
| <Button | |
| className='absolute top-1 right-1' | |
| size='small' | |
| variant='primary' | |
| disabled={!importUrl} | |
| onClick={handleImportFromUrl} | |
| loading={isParsing} | |
| > | |
| {isParsing ? '' : t('common.operation.ok')} | |
| </Button> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| <div className='relative' ref={showExamplesRef}> | |
| <Button | |
| size='small' | |
| className='space-x-1' | |
| onClick={() => { setShowExamples(!showExamples) }} | |
| > | |
| <div className='text-xs font-medium text-gray-700'>{t('tools.createTool.examples')}</div> | |
| <RiArrowDownSLine className='w-3 h-3' /> | |
| </Button> | |
| {showExamples && ( | |
| <div className='absolute top-7 right-0 p-1 rounded-lg bg-white shadow-sm'> | |
| {examples.map(item => ( | |
| <div | |
| key={item.key} | |
| onClick={() => { | |
| onChange(item.content) | |
| setShowExamples(false) | |
| }} | |
| className='px-3 py-1.5 rounded-lg hover:bg-gray-50 leading-5 text-sm font-normal text-gray-700 cursor-pointer whitespace-nowrap' | |
| > | |
| {t(`tools.createTool.exampleOptions.${item.key}`)} | |
| </div> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| ) | |
| } | |
| export default React.memo(GetSchema) | |