import { ExclamationCircleFilled } from '@ant-design/icons'; import { AlertBlockInfo as AlertInfoBlock } from '@gpustack/core-ui'; import { useIntl } from '@umijs/max'; import { Input, Switch, Typography } from 'antd'; import React, { useEffect } from 'react'; import styled from 'styled-components'; import { useAddWorkerContext } from './add-worker-context'; import { AddWorkerStepProps, StepNamesMap } from './config'; import { NotesWrapper, SwitchWrapper, Title } from './constainers'; import StepCollapse from './step-collapse'; const ButtonWrapper = styled.div` display: flex; align-items: center; justify-content: space-between; `; const SwitchSetting: React.FC<{ label: React.ReactNode; checked: boolean; value?: string; placeholder?: string; tips?: React.ReactNode; errorMessage?: React.ReactNode; extra?: React.ReactNode; showSwitch?: boolean; onInputChange?: (value: string) => void; onChange: (checked: boolean) => void; }> = ({ showSwitch = true, label, checked, onChange, value, placeholder, tips, extra, errorMessage, onInputChange }) => { return ( {label} {showSwitch && } {tips && (
)} {checked && (
onInputChange?.(e.target.value)} /> {errorMessage && ( {errorMessage} )}
)} {extra}
); }; const SpecifyArguments: React.FC = ({ disabled }) => { const intl = useIntl(); const { stepList, summary, updateField, registerField } = useAddWorkerContext(); const stepIndex = stepList.indexOf(StepNamesMap.SpecifyArgs) + 1; const workerIPConfig = summary.get('workerIPConfig') || { enable: false, ip: '', required: false }; const externalWorkerIPConfig = summary.get('externalWorkerIPConfig') || { enable: false, ip: '', required: false }; const modelDirConfig = summary.get('modelDirConfig') || { enable: false, path: '' }; const cacheDirConfig = summary.get('cacheDirConfig') || { enable: false, path: '' }; const containerNameConfig = summary.get('containerNameConfig') || { enable: true, name: 'gpustack-worker' }; const gpustackDataVolumeConfig = summary.get('gpustackDataVolumeConfig') || { enable: true, path: 'gpustack-data' }; const setWorkerIPConfig = (config: { enable: boolean; ip?: string; required?: boolean; }) => { updateField('workerIPConfig', { ...workerIPConfig, ...config }); }; const setModelDirConfig = (config: { enable: boolean; path?: string }) => { updateField('modelDirConfig', { ...modelDirConfig, ...config }); }; const setCacheDirConfig = (config: { enable: boolean; path?: string }) => { updateField('cacheDirConfig', { ...cacheDirConfig, ...config }); }; const beforeNext = async () => { if (workerIPConfig.enable && !workerIPConfig.ip) { setWorkerIPConfig({ ...workerIPConfig, required: true }); return false; } if (externalWorkerIPConfig.enable && !externalWorkerIPConfig.ip) { updateField('externalWorkerIPConfig', { ...externalWorkerIPConfig, required: true }); return false; } return true; }; useEffect(() => { const unregisterWorkerIP = registerField('workerIPConfig'); const unregisterModelDir = registerField('modelDirConfig'); const unregisterCacheDir = registerField('cacheDirConfig'); const unregisterContainerName = registerField('containerNameConfig'); const unregisterGpustackDataVolume = registerField( 'gpustackDataVolumeConfig' ); return () => { unregisterWorkerIP(); unregisterModelDir(); unregisterCacheDir(); unregisterContainerName(); unregisterGpustackDataVolume(); }; }, []); useEffect(() => { updateField('workerIPConfig', { enable: true, ip: '', required: false }); updateField('modelDirConfig', { enable: false, path: '' }); updateField('cacheDirConfig', { enable: false, path: '' }); updateField('containerNameConfig', { enable: true, name: 'gpustack-worker' }); updateField('gpustackDataVolumeConfig', { enable: true, path: 'gpustack-data' }); updateField('externalWorkerIPConfig', { enable: false, ip: '', required: false }); }, []); return ( {stepIndex}.{' '} {intl.formatMessage({ id: 'clusters.addworker.specifyArgs' })} } >
{/* worker IP config */} } placeholder={intl.formatMessage({ id: 'clusters.addworker.enterWorkerIP' })} value={workerIPConfig.ip} checked={workerIPConfig.enable} errorMessage={ workerIPConfig.required && !workerIPConfig.ip && intl.formatMessage({ id: 'clusters.addworker.enterWorkerIP.error' }) } onChange={(checked) => setWorkerIPConfig({ ...workerIPConfig, enable: checked, required: false }) } onInputChange={(value) => setWorkerIPConfig({ ...workerIPConfig, ip: value }) } extra={ !workerIPConfig.enable && ( } message={
  • } >
    ) } >
    {/* external worker ip config */} } tips={intl.formatMessage({ id: 'clusters.addworker.detectWorkerAddress.tips' })} placeholder={intl.formatMessage({ id: 'clusters.addworker.enterWorkerAddress' })} value={externalWorkerIPConfig.ip} checked={externalWorkerIPConfig.enable} errorMessage={ externalWorkerIPConfig.required && !externalWorkerIPConfig.ip && intl.formatMessage({ id: 'clusters.addworker.enterWorkerAddress.error' }) } onChange={(checked) => updateField('externalWorkerIPConfig', { ...externalWorkerIPConfig, enable: checked, required: false }) } onInputChange={(value) => updateField('externalWorkerIPConfig', { ...externalWorkerIPConfig, ip: value }) } extra={ externalWorkerIPConfig.enable && ( } message={
  • {intl.formatMessage({ id: 'clusters.addworker.externalIP.tips' })}
  • } >
    ) } >
    {/* cache directory config */} setCacheDirConfig({ ...cacheDirConfig, enable: checked }) } onInputChange={(value) => setCacheDirConfig({ ...cacheDirConfig, path: value }) } > {/* model directory config */} setModelDirConfig({ ...modelDirConfig, enable: checked }) } onInputChange={(value) => setModelDirConfig({ ...modelDirConfig, path: value }) } > {/* gpustack data volume config */} updateField('gpustackDataVolumeConfig', { ...gpustackDataVolumeConfig, enable: checked }) } onInputChange={(value) => updateField('gpustackDataVolumeConfig', { ...gpustackDataVolumeConfig, path: value }) } > {/* container name config */} updateField('containerNameConfig', { ...containerNameConfig, enable: checked }) } onInputChange={(value) => updateField('containerNameConfig', { ...containerNameConfig, name: value }) } >
    ); }; export default SpecifyArguments;