mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-14 20:54:30 +08:00
refactor(web): drop per-model checkbox selection from batch actions (#18233)
This commit is contained in:
@@ -2372,11 +2372,9 @@ Example: Virtual Hosted Style`,
|
||||
'Please select at least one model before verification.',
|
||||
addCustomModel: 'Add custom model',
|
||||
addCustomModelTitle: 'Add custom model',
|
||||
batchAddModels: 'Add all visible models',
|
||||
batchRemoveModels: 'Remove all visible models',
|
||||
batchAddModels: 'Add all models',
|
||||
batchRemoveModels: 'Remove all models',
|
||||
batchVerifyModels: 'Batch verify',
|
||||
selectAllFiltered: 'Select all',
|
||||
batchVerifySelected: 'Verify {{count}} model(s)',
|
||||
editCustomModelTitle: 'Edit model',
|
||||
modelMaxTokens: 'Max tokens',
|
||||
modelFeatures: 'Model features',
|
||||
|
||||
@@ -2007,11 +2007,9 @@ NER:使用 spaCy NER 和基于规则的关键词提取来抽取 Entities 和 R
|
||||
selectModelBeforeVerify: '请至少选择一个模型后再验证。',
|
||||
addCustomModel: '添加自定义模型',
|
||||
addCustomModelTitle: '添加自定义模型',
|
||||
batchAddModels: '批量添加当前模型',
|
||||
batchRemoveModels: '批量移除当前模型',
|
||||
batchAddModels: '批量添加模型',
|
||||
batchRemoveModels: '批量移除模型',
|
||||
batchVerifyModels: '批量验证',
|
||||
selectAllFiltered: '全选',
|
||||
batchVerifySelected: '验证 {{count}} 个模型',
|
||||
editCustomModelTitle: '编辑模型',
|
||||
modelMaxTokens: '最大 Token 数',
|
||||
modelTypes: {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Minus, Plus } from 'lucide-react';
|
||||
import { ModelRowProps } from '../interface';
|
||||
import { ModelTypeBadges } from './model-type-badges';
|
||||
@@ -26,8 +25,6 @@ export function ModelRow({
|
||||
isAdded,
|
||||
verifyStatus,
|
||||
hideActions,
|
||||
isSelected,
|
||||
onToggleSelect,
|
||||
onVerify,
|
||||
onAdd,
|
||||
onRemove,
|
||||
@@ -42,13 +39,6 @@ export function ModelRow({
|
||||
>
|
||||
<div className="flex gap-1 min-w-0">
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
{onToggleSelect && (
|
||||
<Checkbox
|
||||
checked={isSelected ?? false}
|
||||
onCheckedChange={onToggleSelect}
|
||||
aria-label={`Select ${model.name}`}
|
||||
/>
|
||||
)}
|
||||
<span className="font-medium text-sm text-text-primary truncate">
|
||||
{model.name}
|
||||
</span>
|
||||
|
||||
@@ -15,20 +15,12 @@
|
||||
*/
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { SearchInput } from '@/components/ui/input';
|
||||
import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
||||
import { useFetchInstanceModels } from '@/hooks/use-llm-request';
|
||||
import { IProviderModelItem } from '@/interfaces/request/llm';
|
||||
import {
|
||||
ListMinus,
|
||||
ListPlus,
|
||||
Loader2,
|
||||
Plus,
|
||||
Search,
|
||||
ShieldCheck,
|
||||
} from 'lucide-react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Loader2, Plus, Search, ShieldCheck } from 'lucide-react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AddCustomModelDialog } from '../add-custom-model-dialog';
|
||||
import { mapModelKey } from '../available-models';
|
||||
@@ -178,50 +170,9 @@ export function ModelsSection(props: ModelsSectionProps) {
|
||||
verifyTransform,
|
||||
});
|
||||
|
||||
// 6a. Model selection for batch verify.
|
||||
const [selectedModels, setSelectedModels] = useState<Set<string>>(new Set());
|
||||
|
||||
const toggleModel = useCallback((name: string) => {
|
||||
setSelectedModels((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(name)) {
|
||||
next.delete(name);
|
||||
} else {
|
||||
next.add(name);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const toggleAllFiltered = useCallback(() => {
|
||||
setSelectedModels((prev) => {
|
||||
const allSelected = filteredModels.every((m) => prev.has(m.name));
|
||||
const next = new Set(prev);
|
||||
if (allSelected) {
|
||||
filteredModels.forEach((m) => next.delete(m.name));
|
||||
} else {
|
||||
filteredModels.forEach((m) => next.add(m.name));
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}, [filteredModels]);
|
||||
|
||||
const filteredSelectedCount = useMemo(
|
||||
() => filteredModels.filter((m) => selectedModels.has(m.name)).length,
|
||||
[filteredModels, selectedModels],
|
||||
);
|
||||
|
||||
const selectAllChecked: boolean | 'indeterminate' =
|
||||
filteredSelectedCount === 0
|
||||
? false
|
||||
: filteredSelectedCount === filteredModels.length
|
||||
? true
|
||||
: 'indeterminate';
|
||||
|
||||
const handleBatchVerifyClick = useCallback(() => {
|
||||
const selected = filteredModels.filter((m) => selectedModels.has(m.name));
|
||||
handleBatchVerify(selected);
|
||||
}, [filteredModels, selectedModels, handleBatchVerify]);
|
||||
handleBatchVerify(filteredModels);
|
||||
}, [filteredModels, handleBatchVerify]);
|
||||
|
||||
// 7. Add / remove / batch toggle / custom add.
|
||||
const {
|
||||
@@ -327,33 +278,6 @@ export function ModelsSection(props: ModelsSectionProps) {
|
||||
placeholder={t('setting.search')}
|
||||
rootClassName="flex-1"
|
||||
/>
|
||||
{!hideActions && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
onClick={handleBatchToggleModels}
|
||||
disabled={batchLoading || filteredModels.length === 0}
|
||||
data-testid="models-batch-toggle"
|
||||
aria-label={
|
||||
allFilteredAdded
|
||||
? tSetting('batchRemoveModels')
|
||||
: tSetting('batchAddModels')
|
||||
}
|
||||
title={
|
||||
allFilteredAdded
|
||||
? tSetting('batchRemoveModels')
|
||||
: tSetting('batchAddModels')
|
||||
}
|
||||
>
|
||||
{batchLoading ? (
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
) : allFilteredAdded ? (
|
||||
<ListMinus className="size-4" />
|
||||
) : (
|
||||
<ListPlus className="size-4" />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
<TagFilterButton
|
||||
@@ -377,20 +301,11 @@ export function ModelsSection(props: ModelsSectionProps) {
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
checked={selectAllChecked}
|
||||
onCheckedChange={toggleAllFiltered}
|
||||
disabled={batchVerifying || filteredModels.length === 0}
|
||||
aria-label={tSetting('selectAllFiltered')}
|
||||
/>
|
||||
<span className="text-sm text-text-secondary">
|
||||
{tSetting('selectAllFiltered')}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleBatchVerifyClick}
|
||||
disabled={selectedModels.size === 0 || batchVerifying}
|
||||
disabled={batchVerifying || filteredModels.length === 0}
|
||||
data-testid="models-batch-verify"
|
||||
className="ml-auto"
|
||||
>
|
||||
@@ -399,8 +314,22 @@ export function ModelsSection(props: ModelsSectionProps) {
|
||||
) : (
|
||||
<ShieldCheck className="size-3" />
|
||||
)}
|
||||
{tSetting('batchVerifySelected', { count: selectedModels.size })}
|
||||
{tSetting('batchVerifyModels')}
|
||||
</Button>
|
||||
{!hideActions && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleBatchToggleModels}
|
||||
disabled={batchLoading || filteredModels.length === 0}
|
||||
data-testid="models-batch-toggle"
|
||||
>
|
||||
{batchLoading && <Loader2 className="size-3 animate-spin" />}
|
||||
{allFilteredAdded
|
||||
? tSetting('batchRemoveModels')
|
||||
: tSetting('batchAddModels')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="bg-bg-card rounded-lg max-h-80 overflow-auto scrollbar-auto border border-border-button">
|
||||
@@ -418,8 +347,6 @@ export function ModelsSection(props: ModelsSectionProps) {
|
||||
isAdded={addedSet.has(model.name)}
|
||||
verifyStatus={verify[model.name] ?? 'idle'}
|
||||
hideActions={hideActions}
|
||||
isSelected={selectedModels.has(model.name)}
|
||||
onToggleSelect={() => toggleModel(model.name)}
|
||||
onVerify={() => handleVerify(model)}
|
||||
onAdd={() => handleAddModel(model)}
|
||||
onRemove={() => handleRemoveModel(model)}
|
||||
|
||||
@@ -138,10 +138,6 @@ export interface ModelRowProps {
|
||||
onRemove: () => void;
|
||||
onEdit: () => void;
|
||||
editLabel: string;
|
||||
/** Whether this row is currently selected for batch operations. */
|
||||
isSelected?: boolean;
|
||||
/** Toggle this row's selection state. */
|
||||
onToggleSelect?: () => void;
|
||||
}
|
||||
|
||||
export interface TagFilterButtonProps {
|
||||
|
||||
Reference in New Issue
Block a user