fix: filter invaild lora in form
This commit is contained in:
@@ -5,34 +5,18 @@ import {
|
|||||||
} from '@gpustack/core-ui';
|
} from '@gpustack/core-ui';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { modelSourceMap } from '../config';
|
import useQueryModelLoraList, {
|
||||||
import useQueryModelLoraList from '../services/use-query-lora-list';
|
LoraOptionGroup
|
||||||
|
} from '../services/use-query-lora-list';
|
||||||
type LoraDataItem = {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
lora_repo_name: string;
|
|
||||||
source: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface LoraListItemProps {
|
interface LoraListItemProps {
|
||||||
item: { value: any[]; lora_name: string };
|
item: { value: any[]; lora_name: string };
|
||||||
base: string;
|
base: string;
|
||||||
defaultDataList: LoraDataItem[];
|
defaultDataList: LoraOptionGroup[];
|
||||||
selectedRepoNames: Set<string>;
|
selectedRepoNames: Set<string>;
|
||||||
onChange: (partial: { value?: any[]; lora_name?: string }) => void;
|
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> = ({
|
const LoraListItem: React.FC<LoraListItemProps> = ({
|
||||||
item,
|
item,
|
||||||
base,
|
base,
|
||||||
@@ -64,40 +48,16 @@ const LoraListItem: React.FC<LoraListItemProps> = ({
|
|||||||
}, [base]);
|
}, [base]);
|
||||||
|
|
||||||
const groupedOptions = useMemo(() => {
|
const groupedOptions = useMemo(() => {
|
||||||
const groups: Record<
|
|
||||||
string,
|
|
||||||
{
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
isParent: boolean;
|
|
||||||
children: any[];
|
|
||||||
}
|
|
||||||
> = {};
|
|
||||||
const currentRepo = item.value?.[1];
|
const currentRepo = item.value?.[1];
|
||||||
|
return itemDataList
|
||||||
itemDataList.forEach((it) => {
|
.map((group) => ({
|
||||||
if (!groups[it.source]) {
|
...group,
|
||||||
groups[it.source] = {
|
children: group.children.filter(
|
||||||
label: sourceLabel(it.source),
|
(child) =>
|
||||||
value: it.source,
|
!selectedRepoNames.has(child.value) || child.value === currentRepo
|
||||||
isParent: true,
|
)
|
||||||
children: []
|
}))
|
||||||
};
|
.filter((group) => group.children.length > 0);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}, [itemDataList, selectedRepoNames, item.value]);
|
}, [itemDataList, selectedRepoNames, item.value]);
|
||||||
|
|
||||||
const handleSearch = (q: string) => {
|
const handleSearch = (q: string) => {
|
||||||
@@ -153,7 +113,7 @@ const LoraListItem: React.FC<LoraListItemProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<AutoTooltip ghost maxWidth={200}>
|
<AutoTooltip ghost maxWidth={180}>
|
||||||
{data.label}
|
{data.label}
|
||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -60,11 +60,13 @@ const ModelLoraList = () => {
|
|||||||
}, [itemList]);
|
}, [itemList]);
|
||||||
|
|
||||||
const syncFormField = (newItemList: ItemValue[]) => {
|
const syncFormField = (newItemList: ItemValue[]) => {
|
||||||
const newFormList = newItemList.map((it) => ({
|
const newFormList = newItemList
|
||||||
source: (it.value?.[0] || '') as 'huggingface' | 'model_scope',
|
.map((it) => ({
|
||||||
lora_repo_name: it.value?.[1] || '',
|
source: (it.value?.[0] || '') as 'huggingface' | 'model_scope',
|
||||||
lora_name: it.lora_name || ''
|
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);
|
form.setFieldValue('lora_list', newFormList);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,7 +93,7 @@ const ModelLoraList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item<FormData> name="lora_list" trigger="">
|
<Form.Item<FormData> name="lora_list">
|
||||||
<MetadataList
|
<MetadataList
|
||||||
label="LoRA Adapter"
|
label="LoRA Adapter"
|
||||||
dataList={itemList}
|
dataList={itemList}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useQueryData } from '@gpustack/core-ui';
|
import { useQueryData } from '@gpustack/core-ui';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { queryModelLoraAdapter } from '../apis';
|
import { queryModelLoraAdapter } from '../apis';
|
||||||
|
import { modelSourceMap } from '../config';
|
||||||
import { ModelLoraAdapterResult } from '../config/types';
|
import { ModelLoraAdapterResult } from '../config/types';
|
||||||
|
|
||||||
type Parameters = {
|
type Parameters = {
|
||||||
@@ -9,6 +10,30 @@ type Parameters = {
|
|||||||
limit?: number; // default to 40
|
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 = () => {
|
export const useQueryModelLoraList = () => {
|
||||||
const { detailData, loading, fetchData, cancelRequest } = useQueryData<
|
const { detailData, loading, fetchData, cancelRequest } = useQueryData<
|
||||||
ModelLoraAdapterResult,
|
ModelLoraAdapterResult,
|
||||||
@@ -18,24 +43,29 @@ export const useQueryModelLoraList = () => {
|
|||||||
fetchDetail: queryModelLoraAdapter
|
fetchDetail: queryModelLoraAdapter
|
||||||
});
|
});
|
||||||
|
|
||||||
const [dataList, setDataList] = useState<
|
const [dataList, setDataList] = useState<LoraOptionGroup[]>([]);
|
||||||
{
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
lora_repo_name: string;
|
|
||||||
source: string;
|
|
||||||
}[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
const getData = (params: Parameters) => {
|
const getData = (params: Parameters) => {
|
||||||
fetchData(params).then((result) => {
|
fetchData(params).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
const formattedData = result.lora_list.map((item) => ({
|
const groups: Record<string, LoraOptionGroup> = {};
|
||||||
...item,
|
result.lora_list.forEach((item) => {
|
||||||
label: item.lora_repo_name,
|
if (!groups[item.source]) {
|
||||||
value: item.lora_repo_name
|
groups[item.source] = {
|
||||||
}));
|
label: sourceLabel(item.source),
|
||||||
setDataList(formattedData);
|
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));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ export interface ModelFile {
|
|||||||
id: number;
|
id: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
|
is_lora: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModelFileFormData {
|
export interface ModelFileFormData {
|
||||||
@@ -135,4 +136,5 @@ export interface ModelFileFormData {
|
|||||||
model_scope_file_path: string;
|
model_scope_file_path: string;
|
||||||
local_path: string;
|
local_path: string;
|
||||||
local_dir: string;
|
local_dir: string;
|
||||||
|
is_lora: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user