refactor: advance collapse
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
import IconFont from '@/components/icon-font';
|
||||
import LabelSelector from '@/components/label-selector';
|
||||
import ListInput from '@/components/list-input';
|
||||
import CheckboxField from '@/components/seal-form/checkbox-field';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import TooltipList from '@/components/tooltip-list';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Collapse, Form, FormInstance, Typography } from 'antd';
|
||||
import { Collapse, Form, FormInstance } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import {
|
||||
backendParamsHolderTips,
|
||||
getBackendParamsTips,
|
||||
modelCategories,
|
||||
placementStrategyOptions,
|
||||
@@ -21,9 +19,10 @@ import BackendParameters, {
|
||||
} from '../config/backend-parameters';
|
||||
import { useFormContext } from '../config/form-context';
|
||||
import { FormData } from '../config/types';
|
||||
import BackendFields from '../forms/backend-fields';
|
||||
import Backend from '../forms/backend';
|
||||
import BackendParametersList from '../forms/backend-parameters-list';
|
||||
import Performance from '../forms/performance';
|
||||
import dataformStyles from '../style/data-form.less';
|
||||
import Performance from './performance';
|
||||
|
||||
interface AdvanceConfigProps {
|
||||
isGGUF: boolean;
|
||||
@@ -44,9 +43,9 @@ const placementStrategyTips = [
|
||||
}
|
||||
];
|
||||
|
||||
const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
const { form, isGGUF, gpuOptions, source, action } = props;
|
||||
const AdvanceConfig = () => {
|
||||
const intl = useIntl();
|
||||
const form = Form.useFormInstance();
|
||||
const wokerSelector = Form.useWatch('worker_selector', form);
|
||||
const EnviromentVars = Form.useWatch('env', form);
|
||||
const scheduleType = Form.useWatch('scheduleType', form);
|
||||
@@ -57,7 +56,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
const placement_strategy = Form.useWatch('placement_strategy', form);
|
||||
const gpuSelectorIds = Form.useWatch(['gpu_selector', 'gpu_ids'], form);
|
||||
const worker_selector = Form.useWatch('worker_selector', form);
|
||||
const { onValuesChange } = useFormContext();
|
||||
const { onValuesChange, gpuOptions, source, isGGUF } = useFormContext();
|
||||
|
||||
const paramsConfig = useMemo(() => {
|
||||
return _.get(BackendParameters, backend, []);
|
||||
@@ -131,7 +130,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
options={modelCategories}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
<BackendFields></BackendFields>
|
||||
<Backend></Backend>
|
||||
{scheduleType === ScheduleValueMap.Auto && (
|
||||
<>
|
||||
<Form.Item<FormData> name="placement_strategy">
|
||||
@@ -194,57 +193,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<Form.Item<FormData> name="backend_parameters">
|
||||
<ListInput
|
||||
placeholder={
|
||||
backendParamsHolderTips[backend]
|
||||
? intl.formatMessage({
|
||||
id: backendParamsHolderTips[backend].holder
|
||||
})
|
||||
: ''
|
||||
}
|
||||
btnText={intl.formatMessage({ id: 'common.button.addParams' })}
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.backend_parameters'
|
||||
})}
|
||||
dataList={form.getFieldValue('backend_parameters') || []}
|
||||
onChange={handleBackendParametersChange}
|
||||
onBlur={handleBackendParametersOnBlur}
|
||||
onDelete={handleDeleteBackendParameters}
|
||||
options={paramsConfig}
|
||||
description={
|
||||
backendParamsTips.link && (
|
||||
<span>
|
||||
{backend === backendOptionsMap.ascendMindie && (
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'models.backend.mindie.310p' })}
|
||||
</span>
|
||||
)}
|
||||
<span style={{ marginLeft: 5 }}>
|
||||
{intl.formatMessage(
|
||||
{ id: 'models.form.backend_parameters.vllm.tips' },
|
||||
{ backend: backendParamsTips.backend || '' }
|
||||
)}{' '}
|
||||
<Typography.Link
|
||||
style={{ display: 'inline' }}
|
||||
className="flex-center"
|
||||
href={backendParamsTips.link}
|
||||
target="_blank"
|
||||
>
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'common.text.here' })}
|
||||
</span>
|
||||
<IconFont
|
||||
type="icon-external-link"
|
||||
className="font-size-14 m-l-4"
|
||||
></IconFont>
|
||||
</Typography.Link>
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
></ListInput>
|
||||
</Form.Item>
|
||||
<BackendParametersList></BackendParametersList>
|
||||
<Form.Item<FormData> name="env">
|
||||
<LabelSelector
|
||||
label={intl.formatMessage({
|
||||
@@ -313,19 +262,6 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
forceRender: true,
|
||||
children: <Performance></Performance>
|
||||
},
|
||||
// {
|
||||
// key: '3',
|
||||
// label: (
|
||||
// <span
|
||||
// style={{ fontWeight: 'var(--font-weight-medium)' }}
|
||||
// className="font-size-14"
|
||||
// >
|
||||
// Scaling
|
||||
// </span>
|
||||
// ),
|
||||
// forceRender: true,
|
||||
// children: <Scaling></Scaling>
|
||||
// },
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
|
||||
@@ -2,6 +2,7 @@ import SealInput from '@/components/seal-form/seal-input';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import useAppUtils from '@/hooks/use-app-utils';
|
||||
import CollapsePanel from '@/pages/_components/collapse-panel';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
@@ -17,10 +18,12 @@ import {
|
||||
} from '../config/types';
|
||||
import { generateGPUIds } from '../config/utils';
|
||||
import CatalogFrom from '../forms/catalog';
|
||||
import HuggingFaceForm from '../forms/hugging-face';
|
||||
import LocalPathForm from '../forms/local-path';
|
||||
import LocalPathSource from '../forms/local-path-source';
|
||||
import OnlineSource from '../forms/online-source';
|
||||
import { useGenerateGPUOptions } from '../hooks/use-form-initial-values';
|
||||
import AdvanceConfig from './advance-config';
|
||||
// import AdvanceConfig from './advance-config';
|
||||
import AdvanceConfig from '../forms/advance-config';
|
||||
import Performance from '../forms/performance';
|
||||
|
||||
interface DataFormProps {
|
||||
initialValues?: any;
|
||||
@@ -59,6 +62,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
const [form] = Form.useForm();
|
||||
const intl = useIntl();
|
||||
const [activeKey, setActiveKey] = React.useState<string[]>([]);
|
||||
|
||||
const handleSumit = () => {
|
||||
form.submit();
|
||||
@@ -118,6 +122,10 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
||||
onValuesChange?.(changedValues, allValues);
|
||||
};
|
||||
|
||||
const handleOnCollapseChange = (keys: string | string[]) => {
|
||||
setActiveKey(Array.isArray(keys) ? keys : [keys]);
|
||||
};
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
form: form,
|
||||
@@ -216,8 +224,8 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<HuggingFaceForm></HuggingFaceForm>
|
||||
<LocalPathForm></LocalPathForm>
|
||||
<OnlineSource></OnlineSource>
|
||||
<LocalPathSource></LocalPathSource>
|
||||
<Form.Item<FormData>
|
||||
name="cluster_id"
|
||||
rules={[
|
||||
@@ -245,13 +253,25 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
||||
})}
|
||||
></SealInput.TextArea>
|
||||
</Form.Item>
|
||||
<AdvanceConfig
|
||||
form={form}
|
||||
gpuOptions={gpuOptions}
|
||||
isGGUF={isGGUF}
|
||||
action={action}
|
||||
source={props.source}
|
||||
></AdvanceConfig>
|
||||
<CollapsePanel
|
||||
activeKey={activeKey}
|
||||
accordion={false}
|
||||
onChange={handleOnCollapseChange}
|
||||
items={[
|
||||
{
|
||||
key: 'performance',
|
||||
label: 'Performance',
|
||||
forceRender: true,
|
||||
children: <Performance></Performance>
|
||||
},
|
||||
{
|
||||
key: 'advance_config',
|
||||
label: 'Advanced',
|
||||
forceRender: true,
|
||||
children: <AdvanceConfig></AdvanceConfig>
|
||||
}
|
||||
]}
|
||||
></CollapsePanel>
|
||||
</Form>
|
||||
</FormContext.Provider>
|
||||
);
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { Col, Row } from 'antd';
|
||||
import React from 'react';
|
||||
import '../style/deploy-dropdown.less';
|
||||
|
||||
interface DeployDropdownProps {
|
||||
items: { label: string; value: string; key: string; icon: React.ReactNode }[];
|
||||
onSelect: (item: {
|
||||
label: string;
|
||||
value: string;
|
||||
key: string;
|
||||
icon: React.ReactNode;
|
||||
}) => void;
|
||||
}
|
||||
|
||||
const DeployDropdown: React.FC<DeployDropdownProps> = ({ items, onSelect }) => {
|
||||
return (
|
||||
<div className="deploy-dropdown">
|
||||
<Row gutter={[0, 16]}>
|
||||
{items.map((item) => (
|
||||
<Col span={8} key={item.key}>
|
||||
<div key={item.key} onClick={() => onSelect(item)} className="item">
|
||||
<span className="icon">{item.icon}</span>
|
||||
<span className="label">{item.label}</span>
|
||||
</div>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeployDropdown;
|
||||
@@ -36,10 +36,15 @@ const ModalFooterStyle = {
|
||||
justifyContent: 'flex-end'
|
||||
};
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const ColWrapper = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
maxwidth: 33.33%;
|
||||
max-width: 33.33%;
|
||||
`;
|
||||
|
||||
const FormWrapper = styled.div`
|
||||
@@ -445,31 +450,27 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
width={width}
|
||||
footer={false}
|
||||
>
|
||||
<div style={{ display: 'flex', height: '100%' }}>
|
||||
<Container>
|
||||
{SEARCH_SOURCE.includes(props.source) &&
|
||||
deploymentType === 'modelList' && (
|
||||
<>
|
||||
<ColWrapper>
|
||||
<ColumnWrapper>
|
||||
<SearchModel
|
||||
hasLinuxWorker={hasLinuxWorker}
|
||||
modelSource={props.source}
|
||||
onSelectModel={handleOnSelectModel}
|
||||
onSelectModelAfterEvaluate={
|
||||
handleOnSelectModelAfterEvaluate
|
||||
}
|
||||
clusterId={
|
||||
form.current?.getFieldValue?.('cluster_id') ||
|
||||
initClusterId()
|
||||
}
|
||||
displayEvaluateStatus={displayEvaluateStatus}
|
||||
gpuOptions={[]}
|
||||
></SearchModel>
|
||||
</ColumnWrapper>
|
||||
<SearchModel
|
||||
hasLinuxWorker={hasLinuxWorker}
|
||||
modelSource={props.source}
|
||||
onSelectModel={handleOnSelectModel}
|
||||
onSelectModelAfterEvaluate={handleOnSelectModelAfterEvaluate}
|
||||
clusterId={
|
||||
form.current?.getFieldValue?.('cluster_id') ||
|
||||
initClusterId()
|
||||
}
|
||||
displayEvaluateStatus={displayEvaluateStatus}
|
||||
gpuOptions={[]}
|
||||
></SearchModel>
|
||||
<Separator></Separator>
|
||||
</ColWrapper>
|
||||
<ColWrapper>
|
||||
<ColumnWrapper>
|
||||
<ColumnWrapper styles={{ container: { paddingTop: 0 } }}>
|
||||
<ModelCard
|
||||
selectedModel={selectedModel}
|
||||
onCollapse={setCollapsed}
|
||||
@@ -545,7 +546,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
</>
|
||||
</ColumnWrapper>
|
||||
</FormWrapper>
|
||||
</div>
|
||||
</Container>
|
||||
</GSDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
import SealCascader from '@/components/seal-form/seal-cascader';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import TooltipList from '@/components/tooltip-list';
|
||||
import useAppUtils from '@/hooks/use-app-utils';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import React from 'react';
|
||||
import { scheduleList, ScheduleValueMap } from '../config';
|
||||
import { backendOptionsMap } from '../config/backend-parameters';
|
||||
import { useCatalogFormContext, useFormContext } from '../config/form-context';
|
||||
import GPUCard from './gpu-card';
|
||||
|
||||
const scheduleTypeTips = [
|
||||
{
|
||||
title: {
|
||||
text: 'models.form.scheduletype.auto',
|
||||
locale: true
|
||||
},
|
||||
tips: 'models.form.scheduletype.auto.tips'
|
||||
},
|
||||
{
|
||||
title: {
|
||||
text: 'models.form.scheduletype.manual',
|
||||
locale: true
|
||||
},
|
||||
tips: 'models.form.scheduletype.manual.tips'
|
||||
}
|
||||
];
|
||||
|
||||
const Performance: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { onValuesChange, gpuOptions } = useFormContext();
|
||||
const { onQuantizationChange } = useCatalogFormContext();
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
const form = Form.useFormInstance();
|
||||
|
||||
const handleScheduleTypeChange = (value: string) => {
|
||||
if (value === ScheduleValueMap.Auto) {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnQuantizationChange = (val: any) => {
|
||||
onQuantizationChange?.(val);
|
||||
};
|
||||
|
||||
const handleBeforeGpuSelectorChange = (gpuIds: any[]) => {};
|
||||
|
||||
const handleGpuSelectorChange = (value: any[]) => {
|
||||
handleBeforeGpuSelectorChange(value);
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item name="scheduleType">
|
||||
<SealSelect
|
||||
onChange={handleScheduleTypeChange}
|
||||
label={intl.formatMessage({ id: 'models.form.scheduletype' })}
|
||||
description={<TooltipList list={scheduleTypeTips}></TooltipList>}
|
||||
options={scheduleList}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
{form.getFieldValue('scheduleType') ===
|
||||
ScheduleValueMap.SpecificGPUType && (
|
||||
<>
|
||||
<Form.Item name={['gpu_selector', 'gpu_type']}>
|
||||
<SealSelect
|
||||
label={intl.formatMessage({ id: 'models.form.gpuType' })}
|
||||
options={[]}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
<Form.Item name={['gpu_selector', 'gpu_count']}>
|
||||
<SealSelect
|
||||
label={intl.formatMessage({ id: 'models.form.gpuCount' })}
|
||||
options={[
|
||||
{
|
||||
label: 'Auto',
|
||||
value: 'auto'
|
||||
},
|
||||
{
|
||||
label: '1',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '2',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '4',
|
||||
value: 4
|
||||
}
|
||||
]}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{form.getFieldValue('scheduleType') === ScheduleValueMap.Manual &&
|
||||
!form.getFieldValue('fix_gpu_type') && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['gpu_selector', 'gpu_ids']}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'models.form.gpuselector')
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealCascader
|
||||
required
|
||||
showSearch
|
||||
expandTrigger="hover"
|
||||
multiple={
|
||||
form.getFieldValue('backend') !== backendOptionsMap.voxBox
|
||||
}
|
||||
classNames={{
|
||||
popup: {
|
||||
root: 'cascader-popup-wrapper gpu-selector'
|
||||
}
|
||||
}}
|
||||
maxTagCount={1}
|
||||
label={intl.formatMessage({ id: 'models.form.gpuselector' })}
|
||||
options={gpuOptions}
|
||||
showCheckedStrategy="SHOW_CHILD"
|
||||
value={form.getFieldValue(['gpu_selector', 'gpu_ids'])}
|
||||
optionNode={GPUCard}
|
||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||
onChange={handleGpuSelectorChange}
|
||||
></SealCascader>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{/* <div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="optimize_long_prompt"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
label={intl.formatMessage({ id: 'models.form.optimizeLongPrompt' })}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="enable_speculative_decoding"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.enableSpeculativeDecoding'
|
||||
})}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Performance;
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getRequestId, setRquestId } from '@/atoms/models';
|
||||
import BaseSelect from '@/components/seal-form/base/select';
|
||||
import { createAxiosToken } from '@/hooks/use-chunk-request';
|
||||
import ColumnWrapper from '@/pages/_components/column-wrapper';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Pagination } from 'antd';
|
||||
import _ from 'lodash';
|
||||
@@ -521,11 +522,11 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
|
||||
onChange={handleSearchInputChange}
|
||||
modelSource={modelSource}
|
||||
></SearchInput>
|
||||
<div className="gguf-tips">
|
||||
{/* <div className="gguf-tips">
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'models.form.search.gguftips' })}
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className={SearchStyle.filter}>
|
||||
<span className="flex-center gap-8">
|
||||
<BaseSelect
|
||||
@@ -582,18 +583,19 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ width: '100%' }}>
|
||||
<div className={SearchStyle['search-bar']}>{renderHFSearch()}</div>
|
||||
|
||||
<SearchResult
|
||||
loading={dataSource.loading}
|
||||
resultList={dataSource.dataList}
|
||||
networkError={dataSource.networkError}
|
||||
current={current}
|
||||
source={modelSource}
|
||||
isEvaluating={isEvaluating}
|
||||
onSelect={handleSelectModelManually}
|
||||
></SearchResult>
|
||||
<ColumnWrapper maxHeight={'calc(100vh - 210px)'}>
|
||||
<SearchResult
|
||||
loading={dataSource.loading}
|
||||
resultList={dataSource.dataList}
|
||||
networkError={dataSource.networkError}
|
||||
current={current}
|
||||
source={modelSource}
|
||||
isEvaluating={isEvaluating}
|
||||
onSelect={handleSelectModelManually}
|
||||
></SearchResult>
|
||||
</ColumnWrapper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import IconFont from '@/components/icon-font';
|
||||
import SimpleOverlay from '@/components/simple-overlay';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Empty, Spin } from 'antd';
|
||||
@@ -121,7 +120,7 @@ const SearchResult: React.FC<SearchResultProps> = (props) => {
|
||||
}, [networkError, source, intl]);
|
||||
|
||||
return (
|
||||
<SimpleOverlay style={{ height: 'calc(100vh - 224px)' }}>
|
||||
<>
|
||||
<div style={{ ...props.style }} className="search-result-wrap">
|
||||
<Spin spinning={props.loading}>
|
||||
<div style={{ minHeight: 200 }}>
|
||||
@@ -167,7 +166,7 @@ const SearchResult: React.FC<SearchResultProps> = (props) => {
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</SimpleOverlay>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user