Spaces:
Running
Running
import { fetchDefaultQePrompt, fetchQePromptById } from '@/api/qePrompts/qePromptApi'; | |
import { QePrompt } from '@/api/qePrompts/types'; | |
import { useQuery } from '@tanstack/react-query'; | |
import React from 'react'; | |
import { GoX } from 'react-icons/go'; | |
import Modal from 'react-modal'; | |
import './QePromptModal.scss'; | |
interface QePromptModalProps { | |
isOpen: boolean; | |
onRequestClose: () => void; | |
prompt: QePrompt | null; | |
onSave: (prompt: QePrompt | Omit<QePrompt, 'id' | 'created_at'>) => Promise<void>; | |
isEditMode: boolean; | |
} | |
const customStyles = { | |
content: { | |
top: '40%', | |
left: '50%', | |
right: 'auto', | |
bottom: 'auto', | |
transform: 'translate(-50%, -50%)', | |
borderRadius: '15px', | |
maxWidth: '100%', | |
overflow: 'hidden', | |
}, | |
}; | |
const QePromptModal: React.FC<QePromptModalProps> = ({ | |
isOpen, | |
onRequestClose, | |
prompt, | |
onSave, | |
isEditMode, | |
}) => { | |
const [formData, setFormData] = React.useState<QePrompt | Omit<QePrompt, 'id' | 'created_at'>>(() => ({ | |
is_default: false, | |
name: 'Промпт ' + Date.now().toLocaleString(), | |
text: "", | |
type: 'query_expansion' | |
})); | |
// Запрос промпта для редактирования | |
const { data: serverPrompt, isLoading: isPromptLoading } = useQuery({ | |
queryKey: ['qePrompt', prompt?.id], | |
queryFn: () => fetchQePromptById(prompt!.id), | |
enabled: isOpen && isEditMode && !!prompt?.id, | |
}); | |
// Запрос дефолтного промпта для создания | |
const { data: defaultPrompt, isLoading: isDefaultLoading } = useQuery({ | |
queryKey: ['defaultQePrompt'], | |
queryFn: fetchDefaultQePrompt, | |
enabled: isOpen && !isEditMode, // Запрашиваем только при создании | |
}); | |
React.useEffect(() => { | |
if (isOpen) { | |
if (isEditMode && serverPrompt) { | |
setFormData(serverPrompt); // Данные с сервера для редактирования | |
} else if (!isEditMode && defaultPrompt) { | |
setFormData(defaultPrompt); // Дефолтная запись с сервера для создания | |
} else if (!isEditMode && !defaultPrompt && !isDefaultLoading) { | |
setFormData({ // Если дефолтной записи нет и загрузка завершена | |
is_default: true, | |
name: 'Промпт ' + Date.now().toLocaleString(), | |
text: "", | |
type: 'query_expansion' | |
}); | |
} | |
} | |
}, [isOpen, isEditMode, serverPrompt, defaultPrompt, isDefaultLoading]); | |
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { | |
const { name, value } = e.target; | |
setFormData(prev => ({ | |
...prev, | |
[name]: | |
name === 'is_default' ? (e.target as HTMLInputElement).checked : | |
name === 'text' || name === 'name' ? value : | |
parseFloat(value) || 0, | |
})); | |
}; | |
const handleSubmit = async (e: React.FormEvent) => { | |
e.preventDefault(); | |
try { | |
await onSave(formData); | |
onRequestClose(); | |
} catch (err) { | |
console.error('Save failed:', err); | |
} | |
}; | |
if (isPromptLoading && isEditMode) { | |
return <div>Loading prompt...</div>; | |
} | |
if (isDefaultLoading && !isEditMode) { | |
return <div>Loading default prompt...</div>; | |
} | |
return ( | |
<Modal | |
isOpen={isOpen} | |
onRequestClose={onRequestClose} | |
style={customStyles} | |
overlayClassName="modal-overlay" | |
> | |
<div className="modal-content"> | |
<div className="label"> | |
<h3 className="name">{isEditMode ? 'Редактирование промпта' : 'Новый промпт'}</h3> | |
<button className="close-button" onClick={onRequestClose}> | |
<GoX style={{ height: '25px', width: '25px' }} /> | |
</button> | |
</div> | |
<form onSubmit={handleSubmit}> | |
{isEditMode && 'id' in formData && ( | |
<label> | |
<span className='title'>ID:</span> | |
<input type="text" value={formData.id} disabled /> | |
</label> | |
)} | |
<label> | |
<span className='title'>Задать по-умолчанию:</span> | |
<input | |
type="checkbox" | |
name="is_default" | |
checked={formData.is_default} | |
onChange={handleChange} | |
/> | |
</label> | |
<label> | |
<span className='title'>Название:</span> | |
<input | |
type="text" | |
name="name" | |
value={formData.name} | |
onChange={handleChange} | |
/> | |
</label> | |
<label> | |
<span className='title'>Текст:</span> | |
<textarea | |
name="text" | |
value={formData.text || ''} | |
onChange={handleChange} | |
/> | |
</label> | |
<div className="button-group"> | |
<button type="submit">{isEditMode ? 'Сохранить' : 'Создать'}</button> | |
</div> | |
</form> | |
</div> | |
</Modal> | |
); | |
}; | |
export default QePromptModal; |