fix: filter modelInstance by cluster in benchmark form
This commit is contained in:
@@ -48,6 +48,15 @@ const BasicForm: React.FC = () => {
|
|||||||
);
|
);
|
||||||
}, [orgScoped, scopedClusterList, clusterList, scopeOrgId]);
|
}, [orgScoped, scopedClusterList, clusterList, scopeOrgId]);
|
||||||
|
|
||||||
|
const handleOnOrgChange = (value: any) => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
model_name: undefined,
|
||||||
|
model_id: undefined,
|
||||||
|
model_instance_name: undefined,
|
||||||
|
model_instance: undefined
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (action === PageAction.CREATE && orgScoped) {
|
if (action === PageAction.CREATE && orgScoped) {
|
||||||
fetchScopedClusters({ page: -1 });
|
fetchScopedClusters({ page: -1 });
|
||||||
@@ -108,7 +117,10 @@ const BasicForm: React.FC = () => {
|
|||||||
required
|
required
|
||||||
></CInput.Input>
|
></CInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<PluginExtraFields name="CreateOrgScopeField" context={{ action }} />
|
<PluginExtraFields
|
||||||
|
name="CreateOrgScopeField"
|
||||||
|
context={{ action, onChange: handleOnOrgChange }}
|
||||||
|
/>
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="cluster_id"
|
name="cluster_id"
|
||||||
rules={[
|
rules={[
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import { useQueryModelInstancesList } from '@/pages/llmodels/services/use-query-
|
|||||||
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
||||||
import { Cascader as SealCascader, useAppUtils } from '@gpustack/core-ui';
|
import { Cascader as SealCascader, useAppUtils } from '@gpustack/core-ui';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Form, Tooltip } from 'antd';
|
import { Form, Tooltip } from 'antd';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useFormContext } from '../config/form-context';
|
import { useFormContext } from '../config/form-context';
|
||||||
import { FormData } from '../config/types';
|
import { FormData } from '../config/types';
|
||||||
|
|
||||||
@@ -45,11 +46,7 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const { action, open } = useFormContext();
|
const { action, open } = useFormContext();
|
||||||
// Owned by the create-scope picker slot (admin "All" view). The model list
|
const clusterId = Form.useWatch('cluster_id', form);
|
||||||
// is tenant-scoped by the request header, so refetch it when the org
|
|
||||||
// changes so only the chosen org's models/instances are offered.
|
|
||||||
const scopeOrgId = Form.useWatch('organization_id', form);
|
|
||||||
const prevScopeRef = useRef<number | null | undefined>(undefined);
|
|
||||||
const [modelList, setModelList] = React.useState<any[]>([]);
|
const [modelList, setModelList] = React.useState<any[]>([]);
|
||||||
const {
|
const {
|
||||||
loading: modelLoading,
|
loading: modelLoading,
|
||||||
@@ -84,6 +81,16 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearModelInstance = () => {
|
||||||
|
setModelList([]);
|
||||||
|
form.setFieldsValue({
|
||||||
|
model_name: '',
|
||||||
|
model_id: '',
|
||||||
|
model_instance_name: '',
|
||||||
|
model_instance: ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const loadInstances = async (selectedOptions: any[]) => {
|
const loadInstances = async (selectedOptions: any[]) => {
|
||||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||||
if (targetOption && targetOption.children.length === 0) {
|
if (targetOption && targetOption.children.length === 0) {
|
||||||
@@ -107,10 +114,12 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const initModelInstance = useMemoizedFn(async () => {
|
||||||
const initModelInstance = async () => {
|
if (!clusterId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// fetch model list when dropdown is opened
|
// fetch model list when dropdown is opened
|
||||||
const list = await fetchModelList({ page: -1 });
|
const list = await fetchModelList({ page: -1, cluster_id: clusterId });
|
||||||
const modelOptions = list
|
const modelOptions = list
|
||||||
.filter((model: any) => model.replicas > 0)
|
.filter((model: any) => model.replicas > 0)
|
||||||
.map((model: any) => ({
|
.map((model: any) => ({
|
||||||
@@ -124,6 +133,7 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if (modelOptions.length === 0) {
|
if (modelOptions.length === 0) {
|
||||||
|
clearModelInstance();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +143,12 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
);
|
);
|
||||||
if (!selectedllmModel) {
|
if (!selectedllmModel) {
|
||||||
setModelList(modelOptions);
|
setModelList(modelOptions);
|
||||||
|
form.setFieldsValue({
|
||||||
|
model_name: '',
|
||||||
|
model_id: '',
|
||||||
|
model_instance_name: '',
|
||||||
|
model_instance: ''
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const instanceList = await fetchInstanceList({ id: selectedllmModel.id });
|
const instanceList = await fetchInstanceList({ id: selectedllmModel.id });
|
||||||
@@ -159,33 +175,18 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setModelList(modelOptions);
|
setModelList(modelOptions);
|
||||||
};
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && action === PageAction.CREATE) {
|
if (open && action === PageAction.CREATE) {
|
||||||
// On a genuine org change, clear the stale (possibly cross-org) target
|
|
||||||
// so the refetched list re-selects within the new org.
|
|
||||||
if (
|
|
||||||
prevScopeRef.current !== undefined &&
|
|
||||||
prevScopeRef.current !== scopeOrgId
|
|
||||||
) {
|
|
||||||
form.setFieldsValue({
|
|
||||||
model_name: undefined,
|
|
||||||
model_id: undefined,
|
|
||||||
model_instance_name: undefined,
|
|
||||||
model_instance: undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
prevScopeRef.current = scopeOrgId;
|
|
||||||
initModelInstance();
|
initModelInstance();
|
||||||
}
|
}
|
||||||
if (!open) {
|
if (!open) {
|
||||||
prevScopeRef.current = undefined;
|
|
||||||
cancelModelRequest();
|
cancelModelRequest();
|
||||||
cancelInstanceRequest();
|
cancelInstanceRequest();
|
||||||
clearBenchmarkTargetInstance();
|
clearBenchmarkTargetInstance();
|
||||||
}
|
}
|
||||||
}, [open, benchmarkTargetInstance, action, scopeOrgId]);
|
}, [open, action, clusterId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
<div key={item.uid} className="input-item" data-uid={item.uid}>
|
<div key={item.uid} className="input-item" data-uid={item.uid}>
|
||||||
<div className="input-wrap">
|
<div className="input-wrap">
|
||||||
<RowTextarea
|
<RowTextarea
|
||||||
|
showUpload={false}
|
||||||
height={height}
|
height={height}
|
||||||
label={showLabel ? `${index + 1}` : null}
|
label={showLabel ? `${index + 1}` : null}
|
||||||
data={item}
|
data={item}
|
||||||
|
|||||||
Reference in New Issue
Block a user