From f0a1dad48ee06af48fbfff734df2e21b46a29fb2 Mon Sep 17 00:00:00 2001 From: jialin Date: Thu, 30 Apr 2026 19:33:35 +0800 Subject: [PATCH] fix: filter invaild lora in form --- src/pages/llmodels/forms/lora-list-item.tsx | 68 ++++--------------- src/pages/llmodels/forms/model-lora-list.tsx | 14 ++-- .../llmodels/services/use-query-lora-list.ts | 58 ++++++++++++---- src/pages/resources/config/types.ts | 2 + 4 files changed, 68 insertions(+), 74 deletions(-) diff --git a/src/pages/llmodels/forms/lora-list-item.tsx b/src/pages/llmodels/forms/lora-list-item.tsx index 65dff244..b177451b 100644 --- a/src/pages/llmodels/forms/lora-list-item.tsx +++ b/src/pages/llmodels/forms/lora-list-item.tsx @@ -5,34 +5,18 @@ import { } from '@gpustack/core-ui'; import _ from 'lodash'; import { useEffect, useMemo, useState } from 'react'; -import { modelSourceMap } from '../config'; -import useQueryModelLoraList from '../services/use-query-lora-list'; - -type LoraDataItem = { - label: string; - value: string; - lora_repo_name: string; - source: string; -}; +import useQueryModelLoraList, { + LoraOptionGroup +} from '../services/use-query-lora-list'; interface LoraListItemProps { item: { value: any[]; lora_name: string }; base: string; - defaultDataList: LoraDataItem[]; + defaultDataList: LoraOptionGroup[]; selectedRepoNames: Set; onChange: (partial: { value?: any[]; lora_name?: string }) => void; } -const sourceLabel = (source: string) => { - if (source === modelSourceMap.huggingface_value) { - return modelSourceMap.huggingface; - } - if (source === modelSourceMap.modelscope_value) { - return modelSourceMap.modelScope; - } - return source; -}; - const LoraListItem: React.FC = ({ item, base, @@ -64,40 +48,16 @@ const LoraListItem: React.FC = ({ }, [base]); const groupedOptions = useMemo(() => { - const groups: Record< - string, - { - label: string; - value: string; - isParent: boolean; - children: any[]; - } - > = {}; const currentRepo = item.value?.[1]; - - itemDataList.forEach((it) => { - if (!groups[it.source]) { - groups[it.source] = { - label: sourceLabel(it.source), - value: it.source, - isParent: true, - children: [] - }; - } - const isSelectedByOther = - selectedRepoNames.has(it.lora_repo_name) && - it.lora_repo_name !== currentRepo; - if (!isSelectedByOther) { - groups[it.source].children.push({ - label: it.lora_repo_name, - value: it.lora_repo_name, - source: it.source, - isParent: false - }); - } - }); - - return Object.values(groups).filter((g) => g.children.length > 0); + return itemDataList + .map((group) => ({ + ...group, + children: group.children.filter( + (child) => + !selectedRepoNames.has(child.value) || child.value === currentRepo + ) + })) + .filter((group) => group.children.length > 0); }, [itemDataList, selectedRepoNames, item.value]); const handleSearch = (q: string) => { @@ -153,7 +113,7 @@ const LoraListItem: React.FC = ({ ); } return ( - + {data.label} ); diff --git a/src/pages/llmodels/forms/model-lora-list.tsx b/src/pages/llmodels/forms/model-lora-list.tsx index 13813715..9120ce55 100644 --- a/src/pages/llmodels/forms/model-lora-list.tsx +++ b/src/pages/llmodels/forms/model-lora-list.tsx @@ -60,11 +60,13 @@ const ModelLoraList = () => { }, [itemList]); const syncFormField = (newItemList: ItemValue[]) => { - const newFormList = newItemList.map((it) => ({ - source: (it.value?.[0] || '') as 'huggingface' | 'model_scope', - lora_repo_name: it.value?.[1] || '', - lora_name: it.lora_name || '' - })); + const newFormList = newItemList + .map((it) => ({ + source: (it.value?.[0] || '') as 'huggingface' | 'model_scope', + lora_repo_name: it.value?.[1] || '', + lora_name: it.lora_name || '' + })) + .filter((it) => it.lora_repo_name?.trim() && it.lora_name?.trim()); form.setFieldValue('lora_list', newFormList); }; @@ -91,7 +93,7 @@ const ModelLoraList = () => { }; return ( - name="lora_list" trigger=""> + name="lora_list"> { + if (source === modelSourceMap.huggingface_value) { + return modelSourceMap.huggingface; + } + if (source === modelSourceMap.modelscope_value) { + return modelSourceMap.modelScope; + } + return source; +}; + export const useQueryModelLoraList = () => { const { detailData, loading, fetchData, cancelRequest } = useQueryData< ModelLoraAdapterResult, @@ -18,24 +43,29 @@ export const useQueryModelLoraList = () => { fetchDetail: queryModelLoraAdapter }); - const [dataList, setDataList] = useState< - { - label: string; - value: string; - lora_repo_name: string; - source: string; - }[] - >([]); + const [dataList, setDataList] = useState([]); const getData = (params: Parameters) => { fetchData(params).then((result) => { if (result) { - const formattedData = result.lora_list.map((item) => ({ - ...item, - label: item.lora_repo_name, - value: item.lora_repo_name - })); - setDataList(formattedData); + const groups: Record = {}; + result.lora_list.forEach((item) => { + if (!groups[item.source]) { + groups[item.source] = { + label: sourceLabel(item.source), + value: item.source, + isParent: true, + children: [] + }; + } + groups[item.source].children.push({ + label: item.lora_repo_name, + value: item.lora_repo_name, + source: item.source, + isParent: false + }); + }); + setDataList(Object.values(groups)); } }); }; diff --git a/src/pages/resources/config/types.ts b/src/pages/resources/config/types.ts index 01f58142..63186ed3 100644 --- a/src/pages/resources/config/types.ts +++ b/src/pages/resources/config/types.ts @@ -124,6 +124,7 @@ export interface ModelFile { id: number; created_at: string; updated_at: string; + is_lora: boolean; } export interface ModelFileFormData { @@ -135,4 +136,5 @@ export interface ModelFileFormData { model_scope_file_path: string; local_path: string; local_dir: string; + is_lora: boolean; }