mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-22 02:07:13 +00:00
fix(wizard): prevent duplicate model additions in scan page
- Track added model names in state - Disable already-added models with 'Added' badge - Clear selection after successful add - Add Next button at bottom when models have been added
This commit is contained in:
+56
-23
@@ -1155,6 +1155,9 @@ function WizardModelScan({
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [manualModelName, setManualModelName] = useState('');
|
||||
const [manualAdding, setManualAdding] = useState(false);
|
||||
const [addedModelNames, setAddedModelNames] = useState<Set<string>>(
|
||||
new Set(initialSelectedModels),
|
||||
);
|
||||
|
||||
// Auto-scan on mount
|
||||
useEffect(() => {
|
||||
@@ -1216,7 +1219,13 @@ function WizardModelScan({
|
||||
toast.success(
|
||||
t('wizard.provider.modelsAdded', { count: selectedModels.size }),
|
||||
);
|
||||
onModelsAdded();
|
||||
setAddedModelNames((prev) => {
|
||||
const next = new Set(prev);
|
||||
for (const name of selectedModels) next.add(name);
|
||||
return next;
|
||||
});
|
||||
setSelectedModels(new Set());
|
||||
onSelectedModelsChange(new Set());
|
||||
} catch {
|
||||
toast.error(t('wizard.provider.modelsAddError'));
|
||||
} finally {
|
||||
@@ -1238,8 +1247,8 @@ function WizardModelScan({
|
||||
extra_args: {},
|
||||
} as never);
|
||||
toast.success(t('wizard.provider.modelsAdded', { count: 1 }));
|
||||
setAddedModelNames((prev) => new Set(prev).add(name));
|
||||
setManualModelName('');
|
||||
onModelsAdded();
|
||||
} catch {
|
||||
toast.error(t('wizard.provider.modelsAddError'));
|
||||
} finally {
|
||||
@@ -1282,29 +1291,43 @@ function WizardModelScan({
|
||||
{scannedModels.length > 0 ? (
|
||||
<>
|
||||
<div className="max-h-48 overflow-y-auto space-y-2">
|
||||
{filteredModels.map((model) => (
|
||||
<label
|
||||
key={model.name}
|
||||
className="flex items-center gap-3 p-3 rounded-lg border cursor-pointer hover:bg-accent transition-colors"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedModels.has(model.name)}
|
||||
onChange={() => toggleModel(model.name)}
|
||||
className="w-4 h-4 rounded"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<span className="text-sm font-medium truncate block">
|
||||
{model.name}
|
||||
</span>
|
||||
{model.context_length && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
ctx: {model.context_length.toLocaleString()}
|
||||
{filteredModels.map((model) => {
|
||||
const isAdded = addedModelNames.has(model.name);
|
||||
return (
|
||||
<label
|
||||
key={model.name}
|
||||
className={cn(
|
||||
'flex items-center gap-3 p-3 rounded-lg border transition-colors',
|
||||
isAdded
|
||||
? 'opacity-50 cursor-not-allowed bg-muted/50'
|
||||
: 'cursor-pointer hover:bg-accent',
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedModels.has(model.name) || isAdded}
|
||||
disabled={isAdded}
|
||||
onChange={() => toggleModel(model.name)}
|
||||
className="w-4 h-4 rounded"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<span className="text-sm font-medium truncate block">
|
||||
{model.name}
|
||||
</span>
|
||||
{model.context_length && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
ctx: {model.context_length.toLocaleString()}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{isAdded && (
|
||||
<span className="text-xs text-green-600 font-medium shrink-0">
|
||||
{t('wizard.provider.alreadyAdded')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</label>
|
||||
))}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
{filteredModels.length === 0 && (
|
||||
<p className="text-sm text-muted-foreground text-center py-4">
|
||||
{t('wizard.provider.noMatch')}
|
||||
@@ -1365,6 +1388,16 @@ function WizardModelScan({
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Next button when models have been added */}
|
||||
{addedModelNames.size > 0 && (
|
||||
<div className="flex justify-end pt-2 border-t">
|
||||
<Button onClick={onModelsAdded}>
|
||||
{t('wizard.next')}
|
||||
<ArrowRight className="w-4 h-4 ml-1.5" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1873,6 +1873,7 @@ const enUS = {
|
||||
manualModelPlaceholder: 'Enter model name to add manually',
|
||||
addManual: 'Add',
|
||||
saveAndNext: 'Save & Next',
|
||||
alreadyAdded: 'Added',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'Choose Model Source',
|
||||
|
||||
@@ -1731,6 +1731,7 @@ const esES = {
|
||||
manualModelPlaceholder: 'Ingresa el nombre del modelo para agregar manualmente',
|
||||
addManual: 'Agregar',
|
||||
saveAndNext: 'Guardar y siguiente',
|
||||
alreadyAdded: 'Agregado',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'Elegir fuente del modelo',
|
||||
|
||||
@@ -1792,6 +1792,7 @@ const jaJP = {
|
||||
manualModelPlaceholder: 'モデル名を入力して手動追加',
|
||||
addManual: '追加',
|
||||
saveAndNext: '保存して次へ',
|
||||
alreadyAdded: '追加済み',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'モデルソースを選択',
|
||||
|
||||
@@ -1701,6 +1701,7 @@ const ruRU = {
|
||||
manualModelPlaceholder: 'Введите имя модели для ручного добавления',
|
||||
addManual: 'Добавить',
|
||||
saveAndNext: 'Сохранить и далее',
|
||||
alreadyAdded: 'Добавлено',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'Выберите источник модели',
|
||||
|
||||
@@ -1665,6 +1665,7 @@ const thTH = {
|
||||
manualModelPlaceholder: 'กรอกชื่อโมเดลเพื่อเพิ่มด้วยตนเอง',
|
||||
addManual: 'เพิ่ม',
|
||||
saveAndNext: 'บันทึกและถัดไป',
|
||||
alreadyAdded: 'เพิ่มแล้ว',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'เลือกแหล่งโมเดล',
|
||||
|
||||
@@ -1691,6 +1691,7 @@ const viVN = {
|
||||
manualModelPlaceholder: 'Nhập tên mô hình để thêm thủ công',
|
||||
addManual: 'Thêm',
|
||||
saveAndNext: 'Lưu & Tiếp theo',
|
||||
alreadyAdded: 'Đã thêm',
|
||||
},
|
||||
modelSource: {
|
||||
title: 'Chọn nguồn mô hình',
|
||||
|
||||
@@ -1789,6 +1789,7 @@ const zhHans = {
|
||||
manualModelPlaceholder: '输入模型名称手动添加',
|
||||
addManual: '添加',
|
||||
saveAndNext: '保存并下一步',
|
||||
alreadyAdded: '已添加',
|
||||
},
|
||||
modelSource: {
|
||||
title: '选择模型来源',
|
||||
|
||||
@@ -1612,6 +1612,7 @@ const zhHant = {
|
||||
manualModelPlaceholder: '輸入模型名稱手動新增',
|
||||
addManual: '新增',
|
||||
saveAndNext: '儲存並下一步',
|
||||
alreadyAdded: '已新增',
|
||||
},
|
||||
modelSource: {
|
||||
title: '選擇模型來源',
|
||||
|
||||
Reference in New Issue
Block a user