fix: filter invaild lora in form

This commit is contained in:
jialin
2026-05-25 13:56:44 +08:00
committed by jialin
parent 1e334903dd
commit f0a1dad48e
4 changed files with 68 additions and 74 deletions
+14 -54
View File
@@ -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<string>;
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<LoraListItemProps> = ({
item,
base,
@@ -64,40 +48,16 @@ const LoraListItem: React.FC<LoraListItemProps> = ({
}, [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<LoraListItemProps> = ({
);
}
return (
<AutoTooltip ghost maxWidth={200}>
<AutoTooltip ghost maxWidth={180}>
{data.label}
</AutoTooltip>
);
+8 -6
View File
@@ -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 (
<Form.Item<FormData> name="lora_list" trigger="">
<Form.Item<FormData> name="lora_list">
<MetadataList
label="LoRA Adapter"
dataList={itemList}
@@ -1,6 +1,7 @@
import { useQueryData } from '@gpustack/core-ui';
import { useState } from 'react';
import { queryModelLoraAdapter } from '../apis';
import { modelSourceMap } from '../config';
import { ModelLoraAdapterResult } from '../config/types';
type Parameters = {
@@ -9,6 +10,30 @@ type Parameters = {
limit?: number; // default to 40
};
export type LoraOptionChild = {
label: string;
value: string;
source: string;
isParent: false;
};
export type LoraOptionGroup = {
label: string;
value: string;
isParent: true;
children: LoraOptionChild[];
};
const sourceLabel = (source: string) => {
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<LoraOptionGroup[]>([]);
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<string, LoraOptionGroup> = {};
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));
}
});
};
+2
View File
@@ -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;
}