11'use client'
22
3- import { useEffect , useState } from 'react'
3+ import { useState } from 'react'
44import { ChevronDown , Info , Plus , X } from 'lucide-react'
55import {
66 Badge ,
@@ -25,7 +25,12 @@ import {
2525 TooltipProvider ,
2626 TooltipTrigger ,
2727} from '@/components/ui'
28- import { MAX_TAG_SLOTS , type TagSlot } from '@/lib/knowledge/consts'
28+ import {
29+ FIELD_TYPE_METADATA ,
30+ MAX_TAG_SLOTS ,
31+ SUPPORTED_FIELD_TYPES ,
32+ type TagSlot ,
33+ } from '@/lib/knowledge/consts'
2934import { createLogger } from '@/lib/logs/console/logger'
3035import { useKnowledgeBaseTagDefinitions } from '@/hooks/use-knowledge-base-tag-definitions'
3136import { useNextAvailableSlot } from '@/hooks/use-next-available-slot'
@@ -67,44 +72,13 @@ export function DocumentTagEntry({
6772 const { saveTagDefinitions } = documentTagHook
6873 const { tagDefinitions : kbTagDefinitions , fetchTagDefinitions : refreshTagDefinitions } = kbTagHook
6974
70- // State for field types
71- const [ fieldTypes , setFieldTypes ] = useState <
72- Array < {
73- value : string
74- label : string
75- description : string
76- placeholder : string
77- } >
78- > ( [
79- {
80- value : 'text' ,
81- label : 'Text' ,
82- description : 'Free-form text content' ,
83- placeholder : 'Enter text' ,
84- } ,
85- ] )
86-
87- // Fetch field types on component mount
88- useEffect ( ( ) => {
89- const fetchFieldTypes = async ( ) => {
90- try {
91- const response = await fetch ( '/api/knowledge/field-types' )
92- if ( response . ok ) {
93- const result = await response . json ( )
94- if ( result . success ) {
95- setFieldTypes ( result . data . fieldTypes )
96- }
97- }
98- } catch ( error ) {
99- logger . error ( 'Error fetching field types:' , error )
100- // Keep the default fallback
101- }
102- }
103-
104- fetchFieldTypes ( )
105- } , [ ] )
75+ const fieldTypes = SUPPORTED_FIELD_TYPES . map ( ( fieldType ) => ( {
76+ value : fieldType ,
77+ label : FIELD_TYPE_METADATA [ fieldType ] . label ,
78+ description : FIELD_TYPE_METADATA [ fieldType ] . description ,
79+ placeholder : FIELD_TYPE_METADATA [ fieldType ] . placeholder ,
80+ } ) )
10681
107- // Modal state for tag editing
10882 const [ editingTagIndex , setEditingTagIndex ] = useState < number | null > ( null )
10983 const [ modalOpen , setModalOpen ] = useState ( false )
11084 const [ editForm , setEditForm ] = useState ( {
@@ -117,18 +91,13 @@ export function DocumentTagEntry({
11791 const updatedTags = tags . filter ( ( _ , i ) => i !== index )
11892 onTagsChange ( updatedTags )
11993
120- // Persist the changes if onSave is provided
12194 if ( onSave ) {
12295 try {
12396 await onSave ( updatedTags )
124- } catch ( error ) {
125- // Handle error silently - the UI will show the optimistic update
126- // but the user can retry if needed
127- }
97+ } catch ( error ) { }
12898 }
12999 }
130100
131- // Open modal to edit tag
132101 const openTagModal = ( index : number ) => {
133102 const tag = tags [ index ]
134103 setEditingTagIndex ( index )
@@ -140,7 +109,6 @@ export function DocumentTagEntry({
140109 setModalOpen ( true )
141110 }
142111
143- // Open modal to create new tag
144112 const openNewTagModal = ( ) => {
145113 setEditingTagIndex ( null )
146114 setEditForm ( {
@@ -151,7 +119,6 @@ export function DocumentTagEntry({
151119 setModalOpen ( true )
152120 }
153121
154- // Save tag from modal
155122 const saveTagFromModal = async ( ) => {
156123 if ( ! editForm . displayName . trim ( ) || ! editForm . value . trim ( ) ) return
157124
@@ -450,12 +417,12 @@ export function DocumentTagEntry({
450417 value = { editForm . fieldType }
451418 onValueChange = { ( value ) => setEditForm ( { ...editForm , fieldType : value } ) }
452419 disabled = {
453- editingTagIndex !== null || // Disable in edit mode
420+ editingTagIndex !== null ||
454421 ( editingTagIndex === null &&
455422 kbTagDefinitions . some (
456423 ( def ) => def . displayName . toLowerCase ( ) === editForm . displayName . toLowerCase ( )
457424 ) )
458- } // Also disable when using existing definition in create mode
425+ }
459426 >
460427 < SelectTrigger className = 'h-8 w-full justify-between rounded-[10px] border-[#E5E5E5] bg-[#FFFFFF] text-sm dark:border-[#414141] dark:bg-[var(--surface-elevated)]' >
461428 < SelectValue placeholder = 'Select type' />
@@ -483,11 +450,7 @@ export function DocumentTagEntry({
483450 }
484451 showInlineError = { true }
485452 onValidityChange = { ( valid ) => {
486- // Disable save when invalid
487- // We just store validity in state via a refactor-free approach by toggling a hidden flag on form
488- // Use a no-op set to trigger re-render when invalid so button disabled reflects it
489453 if ( ! valid ) {
490- // noop – re-render by updating same state value
491454 setEditForm ( ( prev ) => ( { ...prev } ) )
492455 }
493456 } }
@@ -517,18 +480,14 @@ export function DocumentTagEntry({
517480 disabled = { ( ( ) => {
518481 if ( ! editForm . displayName . trim ( ) ) return true
519482
520- // In edit mode, always allow
521483 if ( editingTagIndex !== null ) return false
522484
523- // In create mode, check if we're creating a new definition at max slots
524485 const existingDefinition = kbTagDefinitions . find (
525486 ( def ) => def . displayName . toLowerCase ( ) === editForm . displayName . toLowerCase ( )
526487 )
527488
528- // If using existing definition, allow
529489 if ( existingDefinition ) return false
530490
531- // If creating new definition and at max slots, disable
532491 return kbTagDefinitions . length >= MAX_TAG_SLOTS
533492 } ) ( ) }
534493 >
0 commit comments