mirror of
https://github.com/pionxzh/chatgpt-exporter.git
synced 2026-07-23 09:00:51 -05:00
fix: user need to select project first to load the conversation list
This commit is contained in:
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Select Project",
|
||||
"(no project)": "(no project)",
|
||||
"Export All Limit": "Export All Limit",
|
||||
"Export All Limit Description": "Set the maximum number of conversations to load in the 'Export All' dialog."
|
||||
"Export All Limit Description": "Set the maximum number of conversations to load in the 'Export All' dialog.",
|
||||
"Select a source to load conversations": "Select a project above to load conversations."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Seleccionar proyecto",
|
||||
"(no project)": "(sin proyecto)",
|
||||
"Export All Limit": "Límite de Exportar Todos",
|
||||
"Export All Limit Description": "Establece el número máximo de conversaciones a cargar en el diálogo 'Exportar Todos'."
|
||||
"Export All Limit Description": "Establece el número máximo de conversaciones a cargar en el diálogo 'Exportar Todos'.",
|
||||
"Select a source to load conversations": "Selecciona un proyecto arriba para cargar conversaciones."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Sélectionner un projet",
|
||||
"(no project)": "(aucun projet)",
|
||||
"Export All Limit": "Limite d'Exportation Multiple",
|
||||
"Export All Limit Description": "Définit le nombre maximal de conversations à charger dans la boîte de dialogue 'Tout exporter'."
|
||||
"Export All Limit Description": "Définit le nombre maximal de conversations à charger dans la boîte de dialogue 'Tout exporter'.",
|
||||
"Select a source to load conversations": "Sélectionnez un projet ci-dessus pour charger les conversations."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Pilih Proyek",
|
||||
"(no project)": "(tidak ada proyek)",
|
||||
"Export All Limit": "Batas Ekspor Semua",
|
||||
"Export All Limit Description": "Atur jumlah maksimum percakapan yang akan dimuat dalam dialog 'Ekspor Semua'."
|
||||
"Export All Limit Description": "Atur jumlah maksimum percakapan yang akan dimuat dalam dialog 'Ekspor Semua'.",
|
||||
"Select a source to load conversations": "Pilih proyek di atas untuk memuat percakapan."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "プロジェクトを選択",
|
||||
"(no project)": "(プロジェクトなし)",
|
||||
"Export All Limit": "すべてエクスポートの上限",
|
||||
"Export All Limit Description": "「すべてエクスポート」ダイアログで読み込む会話の最大数を設定します。"
|
||||
"Export All Limit Description": "「すべてエクスポート」ダイアログで読み込む会話の最大数を設定します。",
|
||||
"Select a source to load conversations": "上からプロジェクトを選択して会話を読み込んでください。"
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Выберите проект",
|
||||
"(no project)": "(нет проекта)",
|
||||
"Export All Limit": "Лимит экспорта всех",
|
||||
"Export All Limit Description": "Установите максимальное количество бесед для загрузки в диалоге 'Экспортировать все'."
|
||||
"Export All Limit Description": "Установите максимальное количество бесед для загрузки в диалоге 'Экспортировать все'.",
|
||||
"Select a source to load conversations": "Выберите проект выше, чтобы загрузить беседы."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "Proje Seç",
|
||||
"(no project)": "(proje yok)",
|
||||
"Export All Limit": "Tümünü Dışa Aktarma Limiti",
|
||||
"Export All Limit Description": "'Tümünü Dışa Aktar' iletişim kutusunda yüklenecek maksimum konuşma sayısını ayarlayın."
|
||||
"Export All Limit Description": "'Tümünü Dışa Aktar' iletişim kutusunda yüklenecek maksimum konuşma sayısını ayarlayın.",
|
||||
"Select a source to load conversations": "Konuşmaları yüklemek için yukarıdan bir proje seçin."
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "选择项目",
|
||||
"(no project)": "(无项目)",
|
||||
"Export All Limit": "批量导出上限",
|
||||
"Export All Limit Description": "设置“批量导出”对话框中加载的最大对话数量。"
|
||||
"Export All Limit Description": "设置“批量导出”对话框中加载的最大对话数量。",
|
||||
"Select a source to load conversations": "请在上方选择一个项目以加载对话。"
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"Select Project": "選擇專案",
|
||||
"(no project)": "(無專案)",
|
||||
"Export All Limit": "批量匯出上限",
|
||||
"Export All Limit Description": "設定「批量匯出」對話方塊中載入的最大對話數量。"
|
||||
"Export All Limit Description": "設定「批量匯出」對話方塊中載入的最大對話數量。",
|
||||
"Select a source to load conversations": "請在上方選擇一個專案以載入對話。"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { exportAllToJson, exportAllToOfficialJson } from '../exporter/json'
|
||||
import { exportAllToMarkdown } from '../exporter/markdown'
|
||||
import { RequestQueue } from '../utils/queue'
|
||||
import { CheckBox } from './CheckBox'
|
||||
import { IconCross, IconUpload } from './Icons'
|
||||
import { IconCross, IconLoading, IconUpload } from './Icons'
|
||||
import { useSettingContext } from './SettingContext'
|
||||
import type { ApiConversationItem, ApiConversationWithId, ApiProjectInfo } from '../api'
|
||||
import type { FC } from '../type'
|
||||
@@ -15,7 +15,7 @@ import type { ChangeEvent } from 'preact/compat'
|
||||
|
||||
interface ProjectSelectProps {
|
||||
projects: ApiProjectInfo[]
|
||||
selected: ApiProjectInfo | null
|
||||
selected: ApiProjectInfo | null | undefined
|
||||
setSelected: (selected: ApiProjectInfo | null) => void
|
||||
disabled: boolean
|
||||
}
|
||||
@@ -23,19 +23,24 @@ interface ProjectSelectProps {
|
||||
const ProjectSelect: FC<ProjectSelectProps> = ({ projects, selected, setSelected, disabled }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const value = selected === undefined ? '__unselected__' : (selected?.id || '')
|
||||
|
||||
return (
|
||||
<div className="flex items-center text-gray-600 dark:text-gray-300 flex justify-between mb-3">
|
||||
{t('Select Project')}
|
||||
<select
|
||||
disabled={disabled}
|
||||
className="Select"
|
||||
value={selected?.id || ''}
|
||||
value={value}
|
||||
onChange={(e) => {
|
||||
const projectId = e.currentTarget.value
|
||||
const project = projects.find(p => p.id === projectId)
|
||||
setSelected(project || null)
|
||||
}}
|
||||
>
|
||||
{selected === undefined && (
|
||||
<option value="__unselected__" disabled>{t('Select Project')}...</option>
|
||||
)}
|
||||
<option value="">{t('(no project)')}</option>
|
||||
{projects.map(project => (
|
||||
<option key={project.id} value={project.id}>{project.display.name}</option>
|
||||
@@ -75,6 +80,12 @@ const ConversationSelect: FC<ConversationSelectProps> = ({
|
||||
setSelected(checked ? conversations : [])
|
||||
}}
|
||||
/>
|
||||
{loading && conversations.length > 0 && (
|
||||
<span className="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
<IconLoading className="w-3 h-3" />
|
||||
{t('Loading')}... ({conversations.length})
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<ul className="SelectList">
|
||||
{loading && conversations.length === 0 && <li className="SelectItem">{t('Loading')}...</li>}
|
||||
@@ -94,9 +105,6 @@ const ConversationSelect: FC<ConversationSelectProps> = ({
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
{loading && conversations.length > 0 && (
|
||||
<li className="SelectItem" style={{ opacity: 0.5, fontStyle: 'italic' }}>{t('Loading')}...</li>
|
||||
)}
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
@@ -129,7 +137,7 @@ const DialogContent: FC<DialogContentProps> = ({ format }) => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
const [processing, setProcessing] = useState(false)
|
||||
const [selectedProject, setSelectedProject] = useState<ApiProjectInfo | null>(null)
|
||||
const [selectedProject, setSelectedProject] = useState<ApiProjectInfo | null | undefined>(undefined)
|
||||
|
||||
const [selected, setSelected] = useState<ApiConversationItem[]>([])
|
||||
const [exportType, setExportType] = useState(exportAllOptions[0].label)
|
||||
@@ -297,10 +305,12 @@ const DialogContent: FC<DialogContentProps> = ({ format }) => {
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedProject === undefined) return
|
||||
setSelected([])
|
||||
setApiConversations([])
|
||||
setLoading(true)
|
||||
fetchAllConversations(
|
||||
selectedProject?.id,
|
||||
selectedProject?.id ?? null,
|
||||
exportAllLimit,
|
||||
batch => setApiConversations(prev => [...prev, ...batch]),
|
||||
)
|
||||
@@ -335,14 +345,22 @@ const DialogContent: FC<DialogContentProps> = ({ format }) => {
|
||||
</div>
|
||||
)}
|
||||
<ProjectSelect projects={projects} selected={selectedProject} setSelected={setSelectedProject} disabled={processing} />
|
||||
<ConversationSelect
|
||||
conversations={conversations}
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
disabled={processing}
|
||||
loading={loading}
|
||||
error={error}
|
||||
/>
|
||||
{selectedProject === undefined
|
||||
? (
|
||||
<div className="SelectList flex items-center justify-center text-gray-400 dark:text-gray-500 text-sm">
|
||||
{t('Select a source to load conversations')}
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<ConversationSelect
|
||||
conversations={conversations}
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
disabled={processing}
|
||||
loading={loading}
|
||||
error={error}
|
||||
/>
|
||||
)}
|
||||
<div className="flex mt-6" style={{ justifyContent: 'space-between' }}>
|
||||
<select className="Select" disabled={processing} value={exportType} onChange={e => setExportType(e.currentTarget.value)}>
|
||||
{exportAllOptions.map(({ label }) => (
|
||||
|
||||
Reference in New Issue
Block a user