wwf
2025-05-20 938c3e5a587ce950a94964ea509b9e7f8834dfae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'use client'
 
import { useEffect, useState } from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import { useStore as useTagStore } from './store'
import TagItemEditor from './tag-item-editor'
import Modal from '@/app/components/base/modal'
import { ToastContext } from '@/app/components/base/toast'
import {
  createTag,
  fetchTagList,
} from '@/service/tag'
 
type TagManagementModalProps = {
  type: 'knowledge' | 'app'
  show: boolean
}
 
const TagManagementModal = ({ show, type }: TagManagementModalProps) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const tagList = useTagStore(s => s.tagList)
  const setTagList = useTagStore(s => s.setTagList)
  const setShowTagManagementModal = useTagStore(s => s.setShowTagManagementModal)
 
  const getTagList = async (type: 'knowledge' | 'app') => {
    const res = await fetchTagList(type)
    setTagList(res)
  }
 
  const [pending, setPending] = useState<boolean>(false)
  const [name, setName] = useState<string>('')
  const createNewTag = async () => {
    if (!name)
      return
    if (pending)
      return
    try {
      setPending(true)
      const newTag = await createTag(name, type)
      notify({ type: 'success', message: t('common.tag.created') })
      setTagList([
        newTag,
        ...tagList,
      ])
      setName('')
      setPending(false)
    }
    catch {
      notify({ type: 'error', message: t('common.tag.failed') })
      setPending(false)
    }
  }
 
  useEffect(() => {
    getTagList(type)
  }, [type])
 
  return (
    <Modal
      className='!w-[600px] !max-w-[600px] rounded-xl px-8 py-6'
      isShow={show}
      onClose={() => setShowTagManagementModal(false)}
    >
      <div className='relative pb-2 text-xl font-semibold leading-[30px] text-text-primary'>{t('common.tag.manageTags')}</div>
      <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={() => setShowTagManagementModal(false)}>
        <RiCloseLine className='h-4 w-4 text-text-tertiary' />
      </div>
      <div className='mt-3 flex flex-wrap gap-2'>
        <input
          className='w-[100px] shrink-0 appearance-none rounded-lg border border-dashed border-divider-regular bg-transparent px-2 py-1 text-sm leading-5 text-text-secondary caret-primary-600  outline-none placeholder:text-text-quaternary focus:border-solid'
          placeholder={t('common.tag.addNew') || ''}
          autoFocus
          value={name}
          onChange={e => setName(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && !e.nativeEvent.isComposing && createNewTag()}
          onBlur={createNewTag}
        />
        {tagList.map(tag => (
          <TagItemEditor
            key={tag.id}
            tag={tag}
          />
        ))}
      </div>
    </Modal>
  )
}
 
export default TagManagementModal