fix: target model text overflow
This commit is contained in:
@@ -35,7 +35,7 @@ const renderTag = (props: any) => {
|
|||||||
const OptionNodes = (props: {
|
const OptionNodes = (props: {
|
||||||
data: any;
|
data: any;
|
||||||
notFoundContent?: React.ReactNode;
|
notFoundContent?: React.ReactNode;
|
||||||
optionNode: React.FC<{ data: any }>;
|
optionNode?: React.FC<{ data: any }>;
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data, optionNode: OptionNode, notFoundContent } = props;
|
const { data, optionNode: OptionNode, notFoundContent } = props;
|
||||||
@@ -68,11 +68,17 @@ const OptionNodes = (props: {
|
|||||||
if (data.parent) {
|
if (data.parent) {
|
||||||
return (
|
return (
|
||||||
<AutoTooltip ghost {...width}>
|
<AutoTooltip ghost {...width}>
|
||||||
{data.label}
|
<span>{data.label}</span>
|
||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return OptionNode ? <OptionNode data={data}></OptionNode> : data.label;
|
return OptionNode ? (
|
||||||
|
<OptionNode data={data}></OptionNode>
|
||||||
|
) : (
|
||||||
|
<AutoTooltip ghost>
|
||||||
|
<span>{data.label}</span>
|
||||||
|
</AutoTooltip>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SealCascader: React.FC<
|
const SealCascader: React.FC<
|
||||||
@@ -183,17 +189,13 @@ const SealCascader: React.FC<
|
|||||||
{...rest}
|
{...rest}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
suffixIcon={<IconFont type="icon-down"></IconFont>}
|
suffixIcon={<IconFont type="icon-down"></IconFont>}
|
||||||
optionRender={
|
optionRender={(data) => (
|
||||||
optionNode
|
<OptionNodes
|
||||||
? (data) => (
|
data={data}
|
||||||
<OptionNodes
|
notFoundContent={notFoundContent}
|
||||||
data={data}
|
optionNode={optionNode}
|
||||||
notFoundContent={notFoundContent}
|
></OptionNodes>
|
||||||
optionNode={optionNode}
|
)}
|
||||||
></OptionNodes>
|
|
||||||
)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
tagRender={tagRender ?? renderTag}
|
tagRender={tagRender ?? renderTag}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
options={children ? null : _options}
|
options={children ? null : _options}
|
||||||
|
|||||||
@@ -1,54 +1,87 @@
|
|||||||
export default `# This is a template for worker_config.
|
export const dockerConfig = `# This is a template for worker_config.
|
||||||
|
|
||||||
# debug: false
|
# debug: false
|
||||||
|
|
||||||
# ========= directories ===========
|
# ========= directories ===========
|
||||||
|
|
||||||
# cache_dir: "/var/lib/gpustack/cache"
|
# cache_dir: "/var/lib/gpustack/cache"
|
||||||
# log_dir: "/var/lib/gpustack/log"
|
# log_dir: "/var/lib/gpustack/log"
|
||||||
# bin_dir: "/var/lib/gpustack/bin"
|
|
||||||
|
|
||||||
# ========= container & image ===========
|
# ========= container & image ===========
|
||||||
|
|
||||||
# system_default_container_registry: "docker.io"
|
# system_default_container_registry: "docker.io"
|
||||||
# image_name_override: "gpustack/gpustack:main"
|
# image_name_override: "gpustack/gpustack:dev"
|
||||||
# image_repo: "gpustack/gpustack"
|
# image_repo: "gpustack/gpustack"
|
||||||
|
|
||||||
# ========= gateway ===========
|
|
||||||
|
|
||||||
# gateway_mode: "auto"
|
|
||||||
# gateway_concurrency: 16
|
|
||||||
# gateway_kubeconfig: "/var/lib/gpustack/higress/kubeconfig"
|
|
||||||
|
|
||||||
# ========= service & networking ===========
|
# ========= service & networking ===========
|
||||||
|
|
||||||
|
|
||||||
|
# worker_port: 10150
|
||||||
|
# worker_metrics_port: 10150
|
||||||
|
# service_port_range: "40000-40063"
|
||||||
|
# ray_port_range: "41000-41999"
|
||||||
|
|
||||||
|
# ========= resources ===========
|
||||||
|
|
||||||
|
# system_reserved:
|
||||||
|
# ram: 2
|
||||||
|
# vram: 1
|
||||||
|
|
||||||
|
# ========= huggingface ===========
|
||||||
|
|
||||||
|
# huggingface_token:
|
||||||
|
# enable_hf_transfer: false
|
||||||
|
# enable_hf_xet: false
|
||||||
|
|
||||||
|
# ========= metrics ===========
|
||||||
|
|
||||||
|
# disable_worker_metrics: false
|
||||||
|
|
||||||
|
# ========= proxy ===========
|
||||||
|
|
||||||
|
# proxy_mode: worker
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const kubernetesConfig = `# This is a template for worker_config.
|
||||||
|
|
||||||
|
# debug: false
|
||||||
|
|
||||||
|
# ========= directories ===========
|
||||||
|
|
||||||
|
# cache_dir: "/var/lib/gpustack/cache"
|
||||||
|
# log_dir: "/var/lib/gpustack/log"
|
||||||
|
|
||||||
|
# ========= container & image ===========
|
||||||
|
|
||||||
|
# system_default_container_registry: "docker.io"
|
||||||
|
# image_name_override: "gpustack/gpustack:dev"
|
||||||
|
# image_repo: "gpustack/gpustack"
|
||||||
|
|
||||||
|
# ========= service & networking ===========
|
||||||
|
|
||||||
# service_discovery_name: "worker"
|
# service_discovery_name: "worker"
|
||||||
# namespace: "gpustack-system"
|
# namespace: "gpustack-system"
|
||||||
# worker_port: 10150
|
# worker_port: 10150
|
||||||
# worker_metrics_port: 10150
|
# worker_metrics_port: 10150
|
||||||
# service_port_range: "40000-40063"
|
# service_port_range: "40000-40063"
|
||||||
# ray_port_range: "41000-41999"
|
# ray_port_range: "41000-41999"
|
||||||
|
|
||||||
# ========= resources ===========
|
# ========= resources ===========
|
||||||
|
|
||||||
# resources:
|
# system_reserved:
|
||||||
|
# ram: 2
|
||||||
|
# vram: 1
|
||||||
|
|
||||||
# ========= huggingface ===========
|
# ========= huggingface ===========
|
||||||
|
|
||||||
# huggingface_token:
|
# huggingface_token:
|
||||||
# enable_hf_transfer: false
|
# enable_hf_transfer: false
|
||||||
# enable_hf_xet: false
|
# enable_hf_xet: false
|
||||||
|
|
||||||
# ========= metrics ===========
|
# ========= metrics ===========
|
||||||
|
|
||||||
# disable_worker_metrics: false
|
# disable_worker_metrics: false
|
||||||
|
|
||||||
# ========= tools & runtime ===========
|
|
||||||
|
|
||||||
# pipx_path: "/usr/local/bin/pipx"
|
|
||||||
# tools_download_base_url:
|
|
||||||
|
|
||||||
# ========= proxy ===========
|
# ========= proxy ===========
|
||||||
|
|
||||||
# proxy_mode: worker
|
# proxy_mode: worker`;
|
||||||
`;
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
import IconFont from '@/components/icon-font';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import { PageAction } from '@/config';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import YamlEditor from '@/pages/_components/yaml-editor';
|
import YamlEditor from '@/pages/_components/yaml-editor';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Form } from 'antd';
|
import { Button, Form } from 'antd';
|
||||||
import React, { forwardRef, useImperativeHandle } from 'react';
|
import React, { forwardRef, useEffect, useImperativeHandle } from 'react';
|
||||||
import { ProviderType } from '../config';
|
import { ProviderType, ProviderValueMap } from '../config';
|
||||||
import { ClusterFormData as FormData } from '../config/types';
|
import { ClusterFormData as FormData } from '../config/types';
|
||||||
import schema from '../config/worker-config.json';
|
import schema from '../config/worker-config.json';
|
||||||
import yamlTemplate from '../config/yaml-template';
|
import { dockerConfig, kubernetesConfig } from '../config/yaml-template';
|
||||||
|
|
||||||
const ClusterAdvanceConfig: React.FC<{
|
const ClusterAdvanceConfig: React.FC<{
|
||||||
action: PageActionType;
|
action: PageActionType;
|
||||||
@@ -18,18 +19,32 @@ const ClusterAdvanceConfig: React.FC<{
|
|||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const editorRef = React.useRef<any>(null);
|
const editorRef = React.useRef<any>(null);
|
||||||
const [fileContent, setFileContent] = React.useState<string>(yamlTemplate);
|
const [fileContent, setFileContent] = React.useState<string>('');
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
getYamlValue: () => {
|
getYamlValue: () => {
|
||||||
return editorRef.current?.getValue();
|
return editorRef.current?.getValue();
|
||||||
},
|
},
|
||||||
setYamlValue: (values: any) => {
|
setYamlValue: (values: any) => {
|
||||||
console.log('setYamlValue:', values);
|
editorRef.current?.setValue(
|
||||||
editorRef.current?.setValue(values || yamlTemplate);
|
values ||
|
||||||
|
(provider === ProviderValueMap.Kubernetes
|
||||||
|
? kubernetesConfig
|
||||||
|
: dockerConfig)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (action === PageAction.CREATE) {
|
||||||
|
setFileContent(
|
||||||
|
provider === ProviderValueMap.Kubernetes
|
||||||
|
? kubernetesConfig
|
||||||
|
: dockerConfig
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [provider, action]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ const ProviderModels: React.FC<ProviderModelProps> = ({ dataList }) => {
|
|||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const head12Items = dataList.slice(0, 8);
|
const head12Items = dataList.slice(0, 4);
|
||||||
const restItems = dataList.slice(8);
|
const restItems = dataList.slice(4);
|
||||||
|
|
||||||
const renderModels = (dataList: ProviderModel[]) => {
|
const renderModels = (dataList: ProviderModel[]) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -161,14 +161,14 @@ const MaasProvider: React.FC = () => {
|
|||||||
<ConfigProvider renderEmpty={renderEmpty}>
|
<ConfigProvider renderEmpty={renderEmpty}>
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
tableLayout="auto"
|
tableLayout="fixed"
|
||||||
sortDirections={TABLE_SORT_DIRECTIONS}
|
sortDirections={TABLE_SORT_DIRECTIONS}
|
||||||
showSorterTooltip={false}
|
showSorterTooltip={false}
|
||||||
dataSource={dataSource.dataList}
|
dataSource={dataSource.dataList}
|
||||||
loading={dataSource.loading}
|
loading={dataSource.loading}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
scroll={{ x: true }}
|
scroll={{ x: 900 }}
|
||||||
pagination={{
|
pagination={{
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
pageSize: queryParams.perPage,
|
pageSize: queryParams.perPage,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
import AutoTooltip from '@/components/auto-tooltip';
|
||||||
import MetadataList from '@/components/metadata-list';
|
import MetadataList from '@/components/metadata-list';
|
||||||
import SealCascader from '@/components/seal-form/seal-cascader';
|
import SealCascader from '@/components/seal-form/seal-cascader';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
|
import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -13,10 +15,23 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
import { useFormContext } from '../config/form-context';
|
import { useFormContext } from '../config/form-context';
|
||||||
import { FormData } from '../config/types';
|
import { FormData } from '../config/types';
|
||||||
import useTargetSourceModels from '../hooks/use-target-source-models';
|
import useTargetSourceModels from '../hooks/use-target-source-models';
|
||||||
|
|
||||||
|
const OptionWrapper = styled.span`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const LabelWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
const TargetsForm = forwardRef((props, ref) => {
|
const TargetsForm = forwardRef((props, ref) => {
|
||||||
const { onFallbackChange, action } = useFormContext();
|
const { onFallbackChange, action } = useFormContext();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -162,7 +177,6 @@ const TargetsForm = forwardRef((props, ref) => {
|
|||||||
|
|
||||||
return !selectedKeys.has(key) || key === currKey;
|
return !selectedKeys.has(key) || key === currKey;
|
||||||
});
|
});
|
||||||
console.log('children', children);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...model,
|
...model,
|
||||||
@@ -172,13 +186,52 @@ const TargetsForm = forwardRef((props, ref) => {
|
|||||||
.filter((model) => model.children && model.children.length > 0);
|
.filter((model) => model.children && model.children.length > 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const displayRender = (labels: any[]) => {
|
const displayRender = (labels: any[], option: any) => {
|
||||||
return (
|
return (
|
||||||
<span className="flex-center gap-4">
|
<LabelWrapper>
|
||||||
{labels[0]}
|
<ProviderLogo provider={_.get(option, '0.providerType') as string} />
|
||||||
<span>/</span>
|
<AutoTooltip
|
||||||
<span>{labels[1]}</span>
|
ghost
|
||||||
</span>
|
maxWidth={300}
|
||||||
|
title={
|
||||||
|
<span>
|
||||||
|
{labels[0]} / {labels[1]}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{labels[0]} / {labels[1]}
|
||||||
|
</span>
|
||||||
|
</AutoTooltip>
|
||||||
|
</LabelWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const optionRender = (option: any) => {
|
||||||
|
const { data } = option;
|
||||||
|
|
||||||
|
if (!data.isParent) {
|
||||||
|
return <AutoTooltip ghost>{data.label}</AutoTooltip>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.providerType === 'deployments') {
|
||||||
|
return (
|
||||||
|
<AutoTooltip ghost maxWidth={140}>
|
||||||
|
<OptionWrapper>
|
||||||
|
<ProviderLogo provider={data.providerType as string} />
|
||||||
|
{intl.formatMessage({ id: 'menu.models.deployment' })}
|
||||||
|
</OptionWrapper>
|
||||||
|
</AutoTooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AutoTooltip ghost maxWidth={140}>
|
||||||
|
<OptionWrapper>
|
||||||
|
<ProviderLogo provider={data.providerType as string} />
|
||||||
|
<span>{data.label}</span>
|
||||||
|
</OptionWrapper>
|
||||||
|
</AutoTooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -269,6 +322,7 @@ const TargetsForm = forwardRef((props, ref) => {
|
|||||||
options={filterOptions(item.value)}
|
options={filterOptions(item.value)}
|
||||||
showCheckedStrategy="SHOW_CHILD"
|
showCheckedStrategy="SHOW_CHILD"
|
||||||
displayRender={displayRender}
|
displayRender={displayRender}
|
||||||
|
optionNode={optionRender}
|
||||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||||
></SealCascader>
|
></SealCascader>
|
||||||
<span className="seprator">:</span>
|
<span className="seprator">:</span>
|
||||||
@@ -320,6 +374,7 @@ const TargetsForm = forwardRef((props, ref) => {
|
|||||||
onChange={(value, options) => handleFallbackChange(value, options)}
|
onChange={(value, options) => handleFallbackChange(value, options)}
|
||||||
showCheckedStrategy="SHOW_CHILD"
|
showCheckedStrategy="SHOW_CHILD"
|
||||||
displayRender={displayRender}
|
displayRender={displayRender}
|
||||||
|
optionNode={optionRender}
|
||||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||||
></SealCascader>
|
></SealCascader>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import GPUStackLogo from '@/assets/images/small-logo-200x200.png';
|
|
||||||
import { queryModelsList } from '@/pages/llmodels/apis';
|
import { queryModelsList } from '@/pages/llmodels/apis';
|
||||||
import { ListItem as ModelListItem } from '@/pages/llmodels/config/types';
|
import { ListItem as ModelListItem } from '@/pages/llmodels/config/types';
|
||||||
import { queryMaasProviders } from '@/pages/maas-provider/apis';
|
import { queryMaasProviders } from '@/pages/maas-provider/apis';
|
||||||
import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
|
|
||||||
import { MaasProviderItem } from '@/pages/maas-provider/config/types';
|
import { MaasProviderItem } from '@/pages/maas-provider/config/types';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -44,15 +42,11 @@ const useTargetSourceModels = () => {
|
|||||||
|
|
||||||
const modelsList = [
|
const modelsList = [
|
||||||
{
|
{
|
||||||
label: (
|
label: intl.formatMessage({ id: 'menu.models.deployment' }),
|
||||||
<OptionWrapper>
|
|
||||||
<img src={GPUStackLogo} alt="GPUStack" width={16} height={16} />
|
|
||||||
{intl.formatMessage({ id: 'menu.models.deployment' })}
|
|
||||||
</OptionWrapper>
|
|
||||||
),
|
|
||||||
value: 'deployments',
|
value: 'deployments',
|
||||||
providerType: 'deployments',
|
providerType: 'deployments',
|
||||||
parent: true,
|
parent: false,
|
||||||
|
isParent: true,
|
||||||
children: _.uniqBy(
|
children: _.uniqBy(
|
||||||
models.items?.map?.((model: ModelListItem) => ({
|
models.items?.map?.((model: ModelListItem) => ({
|
||||||
label: model.name,
|
label: model.name,
|
||||||
@@ -82,14 +76,10 @@ const useTargetSourceModels = () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: (
|
label: provider.name,
|
||||||
<OptionWrapper>
|
|
||||||
<ProviderLogo provider={provider.config?.type as string} />
|
|
||||||
<span>{provider.name}</span>
|
|
||||||
</OptionWrapper>
|
|
||||||
),
|
|
||||||
value: provider.id,
|
value: provider.id,
|
||||||
parent: true,
|
parent: false,
|
||||||
|
isParent: true,
|
||||||
providerType: provider.config?.type,
|
providerType: provider.config?.type,
|
||||||
children: _.uniqBy(children, 'value')
|
children: _.uniqBy(children, 'value')
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user