feat: allow fill inputs from url params (#20630)

This commit is contained in:
非法操作
2025-06-05 09:44:41 +08:00
committed by GitHub
parent 5ccfb1f4ba
commit f2dcfc976d
18 changed files with 55 additions and 5 deletions

View File

@@ -16,7 +16,7 @@ import type {
Feedback,
} from '../types'
import { CONVERSATION_ID_INFO } from '../constants'
import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams } from '../utils'
import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams, getRawInputsFromUrlParams } from '../utils'
import { addFileInfos, sortAgentSorts } from '../../../tools/utils'
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
import {
@@ -195,6 +195,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const { t } = useTranslation()
const newConversationInputsRef = useRef<Record<string, any>>({})
const [newConversationInputs, setNewConversationInputs] = useState<Record<string, any>>({})
const [initInputs, setInitInputs] = useState<Record<string, any>>({})
const handleNewConversationInputsChange = useCallback((newInputs: Record<string, any>) => {
newConversationInputsRef.current = newInputs
setNewConversationInputs(newInputs)
@@ -202,20 +203,29 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const inputsForms = useMemo(() => {
return (appParams?.user_input_form || []).filter((item: any) => !item.external_data_tool).map((item: any) => {
if (item.paragraph) {
let value = initInputs[item.paragraph.variable]
if (value && item.paragraph.max_length && value.length > item.paragraph.max_length)
value = value.slice(0, item.paragraph.max_length)
return {
...item.paragraph,
default: value || item.default,
type: 'paragraph',
}
}
if (item.number) {
const convertedNumber = Number(initInputs[item.number.variable]) ?? undefined
return {
...item.number,
default: convertedNumber || item.default,
type: 'number',
}
}
if (item.select) {
const isInputInOptions = item.select.options.includes(initInputs[item.select.variable])
return {
...item.select,
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.default,
type: 'select',
}
}
@@ -234,17 +244,30 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
}
}
let value = initInputs[item['text-input'].variable]
if (value && item['text-input'].max_length && value.length > item['text-input'].max_length)
value = value.slice(0, item['text-input'].max_length)
return {
...item['text-input'],
default: value || item.default,
type: 'text-input',
}
})
}, [appParams])
}, [initInputs, appParams])
const allInputsHidden = useMemo(() => {
return inputsForms.length > 0 && inputsForms.every(item => item.hide === true)
}, [inputsForms])
useEffect(() => {
// init inputs from url params
(async () => {
const inputs = await getRawInputsFromUrlParams()
setInitInputs(inputs)
})()
}, [])
useEffect(() => {
const conversationInputs: Record<string, any> = {}
@@ -362,11 +385,11 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
if (conversationId)
setClearChatList(false)
}, [handleConversationIdInfoChange, setClearChatList])
const handleNewConversation = useCallback(() => {
const handleNewConversation = useCallback(async () => {
currentChatInstanceRef.current.handleStop()
setShowNewConversationItemInList(true)
handleChangeConversation('')
handleNewConversationInputsChange({})
handleNewConversationInputsChange(await getRawInputsFromUrlParams())
setClearChatList(true)
}, [handleChangeConversation, setShowNewConversationItemInList, handleNewConversationInputsChange, setClearChatList])
const handleUpdateConversationList = useCallback(() => {

View File

@@ -15,6 +15,17 @@ async function decodeBase64AndDecompress(base64String: string) {
}
}
async function getRawInputsFromUrlParams(): Promise<Record<string, any>> {
const urlParams = new URLSearchParams(window.location.search)
const inputs: Record<string, any> = {}
const entriesArray = Array.from(urlParams.entries())
entriesArray.forEach(([key, value]) => {
if (!key.startsWith('sys.'))
inputs[key] = decodeURIComponent(value)
})
return inputs
}
async function getProcessedInputsFromUrlParams(): Promise<Record<string, any>> {
const urlParams = new URLSearchParams(window.location.search)
const inputs: Record<string, any> = {}
@@ -184,6 +195,7 @@ function getThreadMessages(tree: ChatItemInTree[], targetMessageId?: string): Ch
}
export {
getRawInputsFromUrlParams,
getProcessedInputsFromUrlParams,
getProcessedSystemVariablesFromUrlParams,
isValidGeneratedAnswer,

View File

@@ -280,6 +280,7 @@ const translation = {
'inputPlaceholder': 'Por favor ingresa',
'content': 'Contenido',
'required': 'Requerido',
'hide': 'Ocultar',
'errorMsg': {
varNameRequired: 'Nombre de la variable es requerido',
labelNameRequired: 'Nombre de la etiqueta es requerido',

View File

@@ -315,6 +315,7 @@ const translation = {
'inputPlaceholder': 'لطفاً وارد کنید',
'content': 'محتوا',
'required': 'مورد نیاز',
'hide': 'مخفی کردن',
'errorMsg': {
varNameRequired: 'نام متغیر مورد نیاز است',
labelNameRequired: 'نام برچسب مورد نیاز است',

View File

@@ -268,6 +268,7 @@ const translation = {
'labelName': 'Label Name',
'inputPlaceholder': 'Please input',
'required': 'Required',
'hide': 'Caché',
'errorMsg': {
varNameRequired: 'Variable name is required',
labelNameRequired: 'Label name is required',

View File

@@ -312,6 +312,7 @@ const translation = {
'inputPlaceholder': 'कृपया इनपुट करें',
'content': 'सामग्री',
'required': 'आवश्यक',
'hide': 'छुपाएँ',
'errorMsg': {
varNameRequired: 'वेरिएबल नाम आवश्यक है',
labelNameRequired: 'लेबल नाम आवश्यक है',

View File

@@ -314,6 +314,7 @@ const translation = {
'inputPlaceholder': 'Per favore inserisci',
'content': 'Contenuto',
'required': 'Richiesto',
'hide': 'Nascondi',
'errorMsg': {
varNameRequired: 'Il nome della variabile è richiesto',
labelNameRequired: 'Il nome dell\'etichetta è richiesto',

View File

@@ -359,6 +359,7 @@ const translation = {
'labelName': 'ラベル名',
'inputPlaceholder': '入力してください',
'required': '必須',
'hide': '非表示',
'file': {
supportFileTypes: 'サポートされたファイルタイプ',
image: {

View File

@@ -279,6 +279,7 @@ const translation = {
'labelName': '레이블명',
'inputPlaceholder': '입력하세요',
'required': '필수',
'hide': '숨기기',
'errorMsg': {
varNameRequired: '변수명은 필수입니다',
labelNameRequired: '레이블명은 필수입니다',

View File

@@ -309,6 +309,7 @@ const translation = {
'labelName': 'Nazwa etykiety',
'inputPlaceholder': 'Proszę wpisać',
'required': 'Wymagane',
'hide': 'Ukryj',
'errorMsg': {
varNameRequired: 'Wymagana nazwa zmiennej',
labelNameRequired: 'Wymagana nazwa etykiety',

View File

@@ -285,6 +285,7 @@ const translation = {
'labelName': 'Nome do Rótulo',
'inputPlaceholder': 'Por favor, insira',
'required': 'Obrigatório',
'hide': 'Ocultar',
'errorMsg': {
varNameRequired: 'O nome da variável é obrigatório',
labelNameRequired: 'O nome do rótulo é obrigatório',

View File

@@ -285,6 +285,7 @@ const translation = {
'labelName': 'Nume etichetă',
'inputPlaceholder': 'Vă rugăm să introduceți',
'required': 'Obligatoriu',
'hide': 'Ascundeți',
'errorMsg': {
varNameRequired: 'Numele variabilei este obligatoriu',
labelNameRequired: 'Numele etichetei este obligatoriu',

View File

@@ -322,6 +322,7 @@ const translation = {
'inputPlaceholder': 'Пожалуйста, введите',
'content': 'Содержимое',
'required': 'Обязательно',
'hide': 'Скрыть',
'errorMsg': {
labelNameRequired: 'Имя метки обязательно',
varNameCanBeRepeat: 'Имя переменной не может повторяться',

View File

@@ -239,4 +239,4 @@ const translation = {
},
}
module.exports = translation
export default translation

View File

@@ -279,6 +279,7 @@ const translation = {
'labelName': 'Назва мітки',
'inputPlaceholder': 'Будь ласка, введіть',
'required': 'Обов\'язково',
'hide': 'Приховати',
'errorMsg': {
varNameRequired: 'Потрібно вказати назву змінної',
labelNameRequired: 'Потрібно вказати назву мітки',

View File

@@ -279,6 +279,7 @@ const translation = {
'labelName': 'Tên nhãn',
'inputPlaceholder': 'Vui lòng nhập',
'required': 'Bắt buộc',
'hide': 'Ẩn',
'errorMsg': {
varNameRequired: 'Tên biến là bắt buộc',
labelNameRequired: 'Tên nhãn là bắt buộc',

View File

@@ -361,6 +361,7 @@ const translation = {
'inputPlaceholder': '请输入',
'labelName': '显示名称',
'required': '必填',
'hide': '隐藏',
'file': {
supportFileTypes: '支持的文件类型',
image: {

View File

@@ -264,6 +264,7 @@ const translation = {
'inputPlaceholder': '請輸入',
'labelName': '顯示名稱',
'required': '必填',
'hide': '隱藏',
'errorMsg': {
varNameRequired: '變數名稱必填',
labelNameRequired: '顯示名稱必填',