fix: cluster worker config issues
This commit is contained in:
@@ -95,7 +95,7 @@ const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => {
|
|||||||
|
|
||||||
const createChunkConnection = async () => {
|
const createChunkConnection = async () => {
|
||||||
chunkRequedtRef.current?.current?.cancel?.();
|
chunkRequedtRef.current?.current?.cancel?.();
|
||||||
chunkRequedtRef.current = await setChunkRequest({
|
chunkRequedtRef.current = setChunkRequest({
|
||||||
url,
|
url,
|
||||||
params: {
|
params: {
|
||||||
...props.params,
|
...props.params,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
|||||||
import { Modal, type ModalProps } from 'antd';
|
import { Modal, type ModalProps } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { ScrollerContext } from './use-scroller-context';
|
||||||
|
|
||||||
const Wrapper = styled.div<{ $maxHeight?: number | string }>`
|
const Wrapper = styled.div<{ $maxHeight?: number | string }>`
|
||||||
max-height: ${({ $maxHeight }) =>
|
max-height: ${({ $maxHeight }) =>
|
||||||
@@ -16,7 +17,7 @@ const ScrollerModal = (
|
|||||||
) => {
|
) => {
|
||||||
const scroller = React.useRef<any>(null);
|
const scroller = React.useRef<any>(null);
|
||||||
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||||
const { initialize, destroyInstance } = useOverlayScroller();
|
const { initialize, destroyInstance, scrollToBottom } = useOverlayScroller();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (props.open) {
|
if (props.open) {
|
||||||
@@ -68,16 +69,18 @@ const ScrollerModal = (
|
|||||||
: {}
|
: {}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Wrapper
|
<ScrollerContext.Provider value={{ scrollToBottom }}>
|
||||||
ref={scroller}
|
<Wrapper
|
||||||
data-overlayscrollbars-initialize
|
ref={scroller}
|
||||||
className="overlay-scroller-wrapper"
|
data-overlayscrollbars-initialize
|
||||||
$maxHeight={props.maxContentHeight || 500}
|
className="overlay-scroller-wrapper"
|
||||||
hidden={false}
|
$maxHeight={props.maxContentHeight || 500}
|
||||||
style={{ paddingInline: 24, paddingBlockEnd: 0 }}
|
hidden={false}
|
||||||
>
|
style={{ paddingInline: 24, paddingBlockEnd: 0 }}
|
||||||
{props.children}
|
>
|
||||||
</Wrapper>
|
{props.children}
|
||||||
|
</Wrapper>
|
||||||
|
</ScrollerContext.Provider>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
interface ScrollerContextProps {
|
||||||
|
scrollToBottom: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ScrollerContext = createContext<ScrollerContextProps>({
|
||||||
|
scrollToBottom: () => {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useScrollerContext = () => useContext(ScrollerContext);
|
||||||
@@ -166,11 +166,11 @@ const useSetChunkRequest = () => {
|
|||||||
return axiosToken.current;
|
return axiosToken.current;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setChunkRequest = async (config: RequestConfig) => {
|
const setChunkRequest = (config: RequestConfig) => {
|
||||||
requestConfig.current = { ...particalConfig, ...config };
|
requestConfig.current = { ...particalConfig, ...config };
|
||||||
retryCount.current = totalCount;
|
retryCount.current = totalCount;
|
||||||
clearTimeout(timer.current);
|
clearTimeout(timer.current);
|
||||||
await axiosChunkRequest(requestConfig.current);
|
axiosChunkRequest(requestConfig.current);
|
||||||
return axiosToken;
|
return axiosToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export default function useTableFetch<T>(
|
|||||||
try {
|
try {
|
||||||
const query = _.omit(params || queryParams, ['page', 'perPage']);
|
const query = _.omit(params || queryParams, ['page', 'perPage']);
|
||||||
|
|
||||||
chunkRequedtRef.current = await setChunkRequest({
|
chunkRequedtRef.current = setChunkRequest({
|
||||||
url: `${API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
|
url: `${API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
|
||||||
handler: updateHandler
|
handler: updateHandler
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export default function useWatchList<T = Record<string, any>>(API: string) {
|
|||||||
const createWatchChunkRequest = useMemoizedFn(async () => {
|
const createWatchChunkRequest = useMemoizedFn(async () => {
|
||||||
chunkRequestRef.current?.current?.cancel?.();
|
chunkRequestRef.current?.current?.cancel?.();
|
||||||
try {
|
try {
|
||||||
chunkRequestRef.current = await setChunkRequest({
|
chunkRequestRef.current = setChunkRequest({
|
||||||
url: `${watchAPI}`,
|
url: `${watchAPI}`,
|
||||||
params: {},
|
params: {},
|
||||||
handler: updateWatchDataListHandler
|
handler: updateWatchDataListHandler
|
||||||
|
|||||||
@@ -100,5 +100,7 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
|||||||
'clusters.addworker.dataVolume.tips':
|
'clusters.addworker.dataVolume.tips':
|
||||||
'Specify a data storage path for GPUStack.',
|
'Specify a data storage path for GPUStack.',
|
||||||
'clusters.table.ip.internal': 'Internal',
|
'clusters.table.ip.internal': 'Internal',
|
||||||
'clusters.table.ip.external': 'External'
|
'clusters.table.ip.external': 'External',
|
||||||
|
'clusters.form.serverUrl.tips':
|
||||||
|
'Specify the server URL accessible from your cloud provider.'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
|||||||
'clusters.addworker.dataVolume.tips':
|
'clusters.addworker.dataVolume.tips':
|
||||||
'Specify a data storage path for GPUStack.',
|
'Specify a data storage path for GPUStack.',
|
||||||
'clusters.table.ip.internal': 'Internal',
|
'clusters.table.ip.internal': 'Internal',
|
||||||
'clusters.table.ip.external': 'External'
|
'clusters.table.ip.external': 'External',
|
||||||
|
'clusters.form.serverUrl.tips':
|
||||||
|
'Specify the server URL accessible from your cloud provider.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -185,5 +187,6 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
|||||||
// 77. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
// 77. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||||
// 78. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
// 78. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
||||||
// 79. 'clusters.table.ip.internal': 'Internal',
|
// 79. 'clusters.table.ip.internal': 'Internal',
|
||||||
// 80. 'clusters.table.ip.external': 'External'
|
// 80. 'clusters.table.ip.external': 'External',
|
||||||
|
// 81. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ export default {
|
|||||||
'clusters.addworker.dataVolume.tips':
|
'clusters.addworker.dataVolume.tips':
|
||||||
'Specify a data storage path for GPUStack.',
|
'Specify a data storage path for GPUStack.',
|
||||||
'clusters.table.ip.internal': 'Internal',
|
'clusters.table.ip.internal': 'Internal',
|
||||||
'clusters.table.ip.external': 'External'
|
'clusters.table.ip.external': 'External',
|
||||||
|
'clusters.form.serverUrl.tips':
|
||||||
|
'Specify the server URL accessible from your cloud provider.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -116,5 +118,6 @@ export default {
|
|||||||
// 8. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
// 8. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||||
// 9. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
// 9. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
||||||
// 10. 'clusters.table.ip.internal': 'Internal',
|
// 10. 'clusters.table.ip.internal': 'Internal',
|
||||||
// 11. 'clusters.table.ip.external': 'External'
|
// 11. 'clusters.table.ip.external': 'External',
|
||||||
|
// 12. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.'
|
||||||
// ================================================================
|
// ================================================================
|
||||||
|
|||||||
@@ -96,5 +96,6 @@ export default {
|
|||||||
'clusters.addworker.dataVolume': 'GPUStack 数据卷',
|
'clusters.addworker.dataVolume': 'GPUStack 数据卷',
|
||||||
'clusters.addworker.dataVolume.tips': '为 GPUStack 指定数据存储路径。',
|
'clusters.addworker.dataVolume.tips': '为 GPUStack 指定数据存储路径。',
|
||||||
'clusters.table.ip.internal': '内',
|
'clusters.table.ip.internal': '内',
|
||||||
'clusters.table.ip.external': '外'
|
'clusters.table.ip.external': '外',
|
||||||
|
'clusters.form.serverUrl.tips': '指定可从您的云服务提供商访问的服务器地址。'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ const { Text } = Typography;
|
|||||||
|
|
||||||
loader.config({ monaco });
|
loader.config({ monaco });
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div<{ $minHeight: string | number }>`
|
||||||
|
min-height: ${({ $minHeight }) =>
|
||||||
|
typeof $minHeight === 'number' ? `${$minHeight}px` : $minHeight};
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid var(--ant-color-border);
|
border: 1px solid var(--ant-color-border);
|
||||||
border-radius: var(--ant-border-radius);
|
border-radius: var(--ant-border-radius);
|
||||||
@@ -151,7 +153,7 @@ const YamlEditor: React.FC<ViewerProps> = forwardRef((props, ref) => {
|
|||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container $minHeight={height}>
|
||||||
<EditorInner
|
<EditorInner
|
||||||
ref={editorRef}
|
ref={editorRef}
|
||||||
header={renderHeader()}
|
header={renderHeader()}
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ const ClusterCreate = () => {
|
|||||||
return ModuleComponent ? (
|
return ModuleComponent ? (
|
||||||
<ModuleComponent
|
<ModuleComponent
|
||||||
key={key}
|
key={key}
|
||||||
|
actionSource={'page'}
|
||||||
stepList={
|
stepList={
|
||||||
extraData.provider === ProviderValueMap.Docker
|
extraData.provider === ProviderValueMap.Docker
|
||||||
? DockerStepsFromCluster
|
? DockerStepsFromCluster
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const AddCluster: React.FC<AddModalProps> = ({
|
|||||||
closeIcon={true}
|
closeIcon={true}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
keyboard={false}
|
keyboard={false}
|
||||||
|
centered={true}
|
||||||
width={680}
|
width={680}
|
||||||
footer={
|
footer={
|
||||||
<ModalFooter onOk={handleSubmit} onCancel={onCancel}></ModalFooter>
|
<ModalFooter onOk={handleSubmit} onCancel={onCancel}></ModalFooter>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const Container = styled.div`
|
|||||||
* clusterList and onClusterChange are only required when from worker page.
|
* clusterList and onClusterChange are only required when from worker page.
|
||||||
*/
|
*/
|
||||||
type AddWorkerProps = {
|
type AddWorkerProps = {
|
||||||
isModal?: boolean;
|
actionSource?: 'modal' | 'page';
|
||||||
provider: ProviderType;
|
provider: ProviderType;
|
||||||
clusterList?: Global.BaseOption<number, ClusterListItem>[];
|
clusterList?: Global.BaseOption<number, ClusterListItem>[];
|
||||||
clusterLoading?: boolean;
|
clusterLoading?: boolean;
|
||||||
@@ -51,7 +51,7 @@ type AddWorkerProps = {
|
|||||||
*/
|
*/
|
||||||
const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
isModal = false,
|
actionSource,
|
||||||
registrationInfo,
|
registrationInfo,
|
||||||
provider,
|
provider,
|
||||||
clusterList,
|
clusterList,
|
||||||
@@ -81,10 +81,12 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
|||||||
}, [stepList]);
|
}, [stepList]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!isModal) {
|
// this effect is only triggered when used in cluster create page
|
||||||
|
console.log('actionSource:', actionSource);
|
||||||
|
if (actionSource === 'page') {
|
||||||
createModelsChunkRequest();
|
createModelsChunkRequest();
|
||||||
}
|
}
|
||||||
}, [isModal]);
|
}, [actionSource]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AddWorkerContext.Provider
|
<AddWorkerContext.Provider
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<AddWorkerStep
|
<AddWorkerStep
|
||||||
isModal={true}
|
actionSource={'modal'}
|
||||||
stepList={stepList}
|
stepList={stepList}
|
||||||
provider={provider}
|
provider={provider}
|
||||||
clusterList={clusterList}
|
clusterList={clusterList}
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ const CloudProvider: React.FC<CloudProviderProps> = (props) => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
|
description={intl.formatMessage({
|
||||||
|
id: 'clusters.form.serverUrl.tips'
|
||||||
|
})}
|
||||||
label={intl.formatMessage({ id: 'clusters.create.serverUrl' })}
|
label={intl.formatMessage({ id: 'clusters.create.serverUrl' })}
|
||||||
required={true}
|
required={true}
|
||||||
trim={true}
|
trim={true}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useScrollerContext } from '@/components/scroller-modal/use-scroller-context';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
import SealTextArea from '@/components/seal-form/seal-textarea';
|
import SealTextArea from '@/components/seal-form/seal-textarea';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
@@ -24,21 +25,41 @@ type AddModalProps = {
|
|||||||
};
|
};
|
||||||
const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
||||||
({ action, provider, currentData, credentialList, onFinish }, ref) => {
|
({ action, provider, currentData, credentialList, onFinish }, ref) => {
|
||||||
|
const { scrollToBottom } = useScrollerContext();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [activeKey, setActiveKey] = React.useState<string[]>([]);
|
const [activeKey, setActiveKey] = React.useState<string[]>([]);
|
||||||
const advanceConfigRef = React.useRef<any>(null);
|
const advanceConfigRef = React.useRef<any>(null);
|
||||||
|
|
||||||
const handleOnCollapseChange = (keys: string | string[]) => {
|
const handleOnCollapseChange = async (keys: string | string[]) => {
|
||||||
setActiveKey(Array.isArray(keys) ? keys : [keys]);
|
setActiveKey(Array.isArray(keys) ? keys : [keys]);
|
||||||
if (currentData && advanceConfigRef.current) {
|
if (keys?.includes?.('advanceConfig')) {
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 500);
|
||||||
|
});
|
||||||
|
scrollToBottom();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOnFinish = (values: FormData) => {
|
||||||
|
const workerConfig = yaml2Json(advanceConfigRef.current?.getYamlValue());
|
||||||
|
|
||||||
|
onFinish({
|
||||||
|
...values,
|
||||||
|
worker_config: {
|
||||||
|
...workerConfig
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentData) {
|
if (currentData) {
|
||||||
form.setFieldsValue(currentData);
|
form.setFieldsValue(currentData);
|
||||||
|
}
|
||||||
|
}, [currentData]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentData) {
|
||||||
if (advanceConfigRef.current) {
|
if (advanceConfigRef.current) {
|
||||||
const workerConfigYaml = json2Yaml(currentData.worker_config || {});
|
const workerConfigYaml = json2Yaml(currentData.worker_config || {});
|
||||||
advanceConfigRef.current?.setYamlValue(workerConfigYaml);
|
advanceConfigRef.current?.setYamlValue(workerConfigYaml);
|
||||||
@@ -78,7 +99,7 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
<Form
|
<Form
|
||||||
name="clusterForm"
|
name="clusterForm"
|
||||||
form={form}
|
form={form}
|
||||||
onFinish={onFinish}
|
onFinish={handleOnFinish}
|
||||||
preserve={false}
|
preserve={false}
|
||||||
scrollToFirstError={true}
|
scrollToFirstError={true}
|
||||||
initialValues={currentData}
|
initialValues={currentData}
|
||||||
@@ -113,7 +134,7 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
)}
|
)}
|
||||||
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
||||||
<SealTextArea
|
<SealTextArea
|
||||||
autoSize={{ minRows: 4, maxRows: 6 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||||
></SealTextArea>
|
></SealTextArea>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export default function useAddWorkerMessage() {
|
|||||||
onCreate: (newItems: any) => {
|
onCreate: (newItems: any) => {
|
||||||
if (startWatchRef.current) {
|
if (startWatchRef.current) {
|
||||||
newItemsRef.current = newItemsRef.current.concat(newItems);
|
newItemsRef.current = newItemsRef.current.concat(newItems);
|
||||||
console.log('newItemsRef.current:', newItemsRef.current);
|
|
||||||
showAddWorkerMessage();
|
showAddWorkerMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,13 +47,13 @@ export default function useAddWorkerMessage() {
|
|||||||
chunkRequestRef.current?.current?.cancel?.();
|
chunkRequestRef.current?.current?.cancel?.();
|
||||||
resetAddedCount();
|
resetAddedCount();
|
||||||
try {
|
try {
|
||||||
chunkRequestRef.current = await setChunkRequest({
|
chunkRequestRef.current = setChunkRequest({
|
||||||
url: WORKERS_API,
|
url: WORKERS_API,
|
||||||
handler: updateHandler
|
handler: updateHandler
|
||||||
});
|
});
|
||||||
timerRef.current = setTimeout(() => {
|
timerRef.current = setTimeout(() => {
|
||||||
startWatchRef.current = true;
|
startWatchRef.current = true;
|
||||||
}, 1000);
|
}, 5000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import IconFont from '@/components/icon-font';
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
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 { Form } from 'antd';
|
import { Button, Form } from 'antd';
|
||||||
import React, { forwardRef, useImperativeHandle } from 'react';
|
import React, { forwardRef, useImperativeHandle } from 'react';
|
||||||
import { ProviderType, ProviderValueMap } from '../config';
|
import { ProviderType, ProviderValueMap } from '../config';
|
||||||
import { ClusterFormData as FormData } from '../config/types';
|
import { ClusterFormData as FormData } from '../config/types';
|
||||||
@@ -24,7 +25,6 @@ const ClusterAdvanceConfig: React.FC<{
|
|||||||
return editorRef.current?.getValue();
|
return editorRef.current?.getValue();
|
||||||
},
|
},
|
||||||
setYamlValue: (values: any) => {
|
setYamlValue: (values: any) => {
|
||||||
console.log('setYamlValue:', values, editorRef.current);
|
|
||||||
editorRef.current?.setValue(values);
|
editorRef.current?.setValue(values);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -42,6 +42,9 @@ const ClusterAdvanceConfig: React.FC<{
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
|
description={intl.formatMessage({
|
||||||
|
id: 'clusters.form.serverUrl.tips'
|
||||||
|
})}
|
||||||
label={intl.formatMessage({ id: 'clusters.create.serverUrl' })}
|
label={intl.formatMessage({ id: 'clusters.create.serverUrl' })}
|
||||||
required={false}
|
required={false}
|
||||||
trim={true}
|
trim={true}
|
||||||
@@ -62,7 +65,23 @@ const ClusterAdvanceConfig: React.FC<{
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
<YamlEditor
|
<YamlEditor
|
||||||
ref={editorRef}
|
ref={editorRef}
|
||||||
title={`${intl.formatMessage({ id: 'clusters.create.workerConfig' })} YAML`}
|
title={
|
||||||
|
<span className="flex-center">
|
||||||
|
<span>{`${intl.formatMessage({ id: 'clusters.create.workerConfig' })} YAML`}</span>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
target="_blank"
|
||||||
|
href="https://docs.gpustack.ai/latest/cli-reference/start/#config-file"
|
||||||
|
>
|
||||||
|
{intl.formatMessage({ id: 'playground.audio.enablemic.doc' })}{' '}
|
||||||
|
<IconFont
|
||||||
|
type="icon-external-link"
|
||||||
|
className="font-size-14"
|
||||||
|
></IconFont>
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
value={fileContent}
|
value={fileContent}
|
||||||
height={300}
|
height={300}
|
||||||
onUpload={(content) => {
|
onUpload={(content) => {
|
||||||
|
|||||||
@@ -72,11 +72,9 @@ const ViewLogsModal: React.FC<ViewModalProps> = (props) => {
|
|||||||
if (!props.id) return;
|
if (!props.id) return;
|
||||||
if (open) {
|
if (open) {
|
||||||
requestRef.current?.current?.cancel?.();
|
requestRef.current?.current?.cancel?.();
|
||||||
setChunkRequest({
|
requestRef.current = setChunkRequest({
|
||||||
url: `${MODELS_API}/${props.modelId}/instances`,
|
url: `${MODELS_API}/${props.modelId}/instances`,
|
||||||
handler: updateHandler
|
handler: updateHandler
|
||||||
}).then((res) => {
|
|
||||||
requestRef.current = res;
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logsViewerRef.current?.abort();
|
logsViewerRef.current?.abort();
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ const Models: React.FC = () => {
|
|||||||
search: search,
|
search: search,
|
||||||
categories: categories
|
categories: categories
|
||||||
};
|
};
|
||||||
chunkRequedtRef.current = await setChunkRequest({
|
chunkRequedtRef.current = setChunkRequest({
|
||||||
url: `${MODELS_API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
|
url: `${MODELS_API}?${qs.stringify(_.pickBy(query, (val: any) => !!val))}`,
|
||||||
handler: updateHandler
|
handler: updateHandler
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user