get-schema.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useState } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { useClickAway } from 'ahooks'
  6. import {
  7. RiAddLine,
  8. RiArrowDownSLine,
  9. } from '@remixicon/react'
  10. import Toast from '../../base/toast'
  11. import examples from './examples'
  12. import Button from '@/app/components/base/button'
  13. import Input from '@/app/components/base/input'
  14. import { importSchemaFromURL } from '@/service/tools'
  15. type Props = {
  16. onChange: (value: string) => void
  17. }
  18. const GetSchema: FC<Props> = ({
  19. onChange,
  20. }) => {
  21. const { t } = useTranslation()
  22. const [showImportFromUrl, setShowImportFromUrl] = useState(false)
  23. const [importUrl, setImportUrl] = useState('')
  24. const [isParsing, setIsParsing] = useState(false)
  25. const handleImportFromUrl = async () => {
  26. if (!importUrl.startsWith('http://') && !importUrl.startsWith('https://')) {
  27. Toast.notify({
  28. type: 'error',
  29. message: t('tools.createTool.urlError'),
  30. })
  31. return
  32. }
  33. setIsParsing(true)
  34. try {
  35. const { schema } = await importSchemaFromURL(importUrl) as any
  36. setImportUrl('')
  37. onChange(schema)
  38. }
  39. finally {
  40. setIsParsing(false)
  41. setShowImportFromUrl(false)
  42. }
  43. }
  44. const importURLRef = React.useRef(null)
  45. useClickAway(() => {
  46. setShowImportFromUrl(false)
  47. }, importURLRef)
  48. const [showExamples, setShowExamples] = useState(false)
  49. const showExamplesRef = React.useRef(null)
  50. useClickAway(() => {
  51. setShowExamples(false)
  52. }, showExamplesRef)
  53. return (
  54. <div className='flex space-x-1 justify-end relative w-[224px]'>
  55. <div ref={importURLRef}>
  56. <Button
  57. size='small'
  58. className='space-x-1 '
  59. onClick={() => { setShowImportFromUrl(!showImportFromUrl) }}
  60. >
  61. <RiAddLine className='w-3 h-3' />
  62. <div className='system-xs-medium text-text-secondary'>{t('tools.createTool.importFromUrl')}</div>
  63. </Button>
  64. {showImportFromUrl && (
  65. <div className=' absolute left-[-35px] top-[26px] p-2 rounded-lg border border-components-panel-border bg-components-panel-bg shadow-lg'>
  66. <div className='relative'>
  67. <Input
  68. type='text'
  69. className='w-[244px]'
  70. placeholder={t('tools.createTool.importFromUrlPlaceHolder')!}
  71. value={importUrl}
  72. onChange={e => setImportUrl(e.target.value)}
  73. />
  74. <Button
  75. className='absolute top-1 right-1'
  76. size='small'
  77. variant='primary'
  78. disabled={!importUrl}
  79. onClick={handleImportFromUrl}
  80. loading={isParsing}
  81. >
  82. {isParsing ? '' : t('common.operation.ok')}
  83. </Button>
  84. </div>
  85. </div>
  86. )}
  87. </div>
  88. <div className='relative -mt-0.5' ref={showExamplesRef}>
  89. <Button
  90. size='small'
  91. className='space-x-1'
  92. onClick={() => { setShowExamples(!showExamples) }}
  93. >
  94. <div className='system-xs-medium text-text-secondary'>{t('tools.createTool.examples')}</div>
  95. <RiArrowDownSLine className='w-3 h-3' />
  96. </Button>
  97. {showExamples && (
  98. <div className='absolute top-7 right-0 p-1 rounded-lg bg-components-panel-bg shadow-sm'>
  99. {examples.map(item => (
  100. <div
  101. key={item.key}
  102. onClick={() => {
  103. onChange(item.content)
  104. setShowExamples(false)
  105. }}
  106. className='px-3 py-1.5 rounded-lg hover:bg-components-panel-on-panel-item-bg-hover leading-5 system-sm-regular text-text-secondary cursor-pointer whitespace-nowrap'
  107. >
  108. {t(`tools.createTool.exampleOptions.${item.key}`)}
  109. </div>
  110. ))}
  111. </div>
  112. )}
  113. </div>
  114. </div>
  115. )
  116. }
  117. export default React.memo(GetSchema)