style: number selection
This commit is contained in:
@@ -64,6 +64,26 @@ const Basic: React.FC<BasicProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const renderStorageLabel = (): React.ReactNode => {
|
||||
if (page === 'instance' && onceMaxRequest?.localStorage != null) {
|
||||
return intl.formatMessage(
|
||||
{ id: 'gpuservice.instance.containerDisk.remaining' },
|
||||
{ count: onceMaxRequest.localStorage }
|
||||
);
|
||||
}
|
||||
return intl.formatMessage({ id: 'gpuservice.template.containerDisk' });
|
||||
};
|
||||
|
||||
const renderMemoryLabel = (): React.ReactNode => {
|
||||
if (page === 'instance' && onceMaxRequest?.memory != null) {
|
||||
return intl.formatMessage(
|
||||
{ id: 'gpuservice.instance.memory.remaining' },
|
||||
{ count: onceMaxRequest.memory }
|
||||
);
|
||||
}
|
||||
return intl.formatMessage({ id: 'gpuservice.template.memory' });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div data-field="template"></div>
|
||||
@@ -174,20 +194,22 @@ const Basic: React.FC<BasicProps> = ({
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Flex gap={16}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Form.Item<FormData> name={['spec', 'volumeMount']}>
|
||||
<CInput.Input
|
||||
label={intl.formatMessage({
|
||||
id: 'gpuservice.template.mountPath'
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'clusters.volume.mountPath.format'
|
||||
})}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Flex gap={12}>
|
||||
{page === 'template' && (
|
||||
<div style={{ flex: 1 }}>
|
||||
<Form.Item<FormData> name={['spec', 'volumeMount']}>
|
||||
<CInput.Input
|
||||
label={intl.formatMessage({
|
||||
id: 'gpuservice.template.mountPath'
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'clusters.volume.mountPath.format'
|
||||
})}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ flex: 1 }}>
|
||||
<Form.Item<FormData>
|
||||
name={['spec', 'resources', 'localStorage']}
|
||||
@@ -197,17 +219,14 @@ const Basic: React.FC<BasicProps> = ({
|
||||
})}
|
||||
>
|
||||
<InputNumber
|
||||
label={renderMaxLabel(
|
||||
intl.formatMessage({ id: 'gpuservice.template.containerDisk' }),
|
||||
onceMaxRequest?.localStorage
|
||||
)}
|
||||
label={renderStorageLabel()}
|
||||
max={onceMaxRequest?.localStorage ?? undefined}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</Flex>
|
||||
<Flex gap={16}>
|
||||
<Flex gap={12}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Form.Item<FormData>
|
||||
name={['spec', 'resources', 'cpu']}
|
||||
@@ -230,10 +249,7 @@ const Basic: React.FC<BasicProps> = ({
|
||||
})}
|
||||
>
|
||||
<InputNumber
|
||||
label={renderMaxLabel(
|
||||
intl.formatMessage({ id: 'gpuservice.template.memory' }),
|
||||
onceMaxRequest?.memory
|
||||
)}
|
||||
label={renderMemoryLabel()}
|
||||
max={onceMaxRequest?.memory ?? undefined}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { FormData, PortItem as PortItemType } from '../config/types';
|
||||
import styles from '../styles/template.less';
|
||||
|
||||
type PortProtocol = PortItemType['protocol'];
|
||||
|
||||
@@ -115,11 +116,16 @@ const PortNameInput: React.FC<PortNameInputProps & { disabled?: boolean }> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const PortItem: React.FC<PortItemProps & { disabled?: boolean }> = ({ item, index, disabled = false, onChange }) => {
|
||||
const PortItem: React.FC<PortItemProps & { disabled?: boolean }> = ({
|
||||
item,
|
||||
index,
|
||||
disabled = false,
|
||||
onChange
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
return (
|
||||
<div style={{ display: 'flex', gap: 12, width: '100%' }}>
|
||||
<div style={{ width: 120 }}>
|
||||
<div className={styles.portItem}>
|
||||
<div className={styles.select}>
|
||||
<SealSelect
|
||||
disabled={disabled}
|
||||
value={item.protocol}
|
||||
@@ -141,10 +147,9 @@ const PortItem: React.FC<PortItemProps & { disabled?: boolean }> = ({ item, inde
|
||||
style={{ width: '100%' }}
|
||||
></SealSelect>
|
||||
</div>
|
||||
<div style={{ width: 120 }}>
|
||||
<div className={styles.port}>
|
||||
<CInputNumber
|
||||
min={PORT_MIN}
|
||||
max={PORT_MAX}
|
||||
disabled={disabled}
|
||||
precision={0}
|
||||
value={item.port}
|
||||
@@ -166,7 +171,7 @@ const PortItem: React.FC<PortItemProps & { disabled?: boolean }> = ({ item, inde
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div className={styles.name}>
|
||||
<PortNameInput
|
||||
disabled={disabled}
|
||||
value={item.name}
|
||||
@@ -192,8 +197,6 @@ const Ports: React.FC<{ disabled?: boolean }> = ({ disabled = false }) => {
|
||||
|
||||
const updatePorts = (list: PortItemType[]) => {
|
||||
form.setFieldValue(['spec', 'ports'], list);
|
||||
// setFieldValue doesn't run validators — re-run them so users see errors live.
|
||||
form.validateFields([['spec', 'ports']]).catch(() => {});
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
@@ -231,13 +234,19 @@ const Ports: React.FC<{ disabled?: boolean }> = ({ disabled = false }) => {
|
||||
|
||||
const items = value as PortItemType[];
|
||||
|
||||
if (_.some(items, (item) => !item.protocol || !item.port)) {
|
||||
if (
|
||||
_.some(
|
||||
items,
|
||||
(item: PortItemType) =>
|
||||
!item.protocol || !item.port || !item.name
|
||||
)
|
||||
) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
intl.formatMessage(
|
||||
{ id: 'common.validate.value' },
|
||||
{ id: 'common.validate.group' },
|
||||
{
|
||||
name: intl.formatMessage({
|
||||
group: intl.formatMessage({
|
||||
id: 'gpuservice.template.ports'
|
||||
})
|
||||
}
|
||||
@@ -248,16 +257,6 @@ const Ports: React.FC<{ disabled?: boolean }> = ({ disabled = false }) => {
|
||||
|
||||
const namedItems = items.filter((item) => !!item.name);
|
||||
|
||||
if (_.some(namedItems, (item) => item.name!.length > PORT_NAME_MAX)) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
intl.formatMessage({
|
||||
id: 'gpuservice.template.ports.name.max'
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const names = namedItems.map((item) => item.name);
|
||||
if (_.uniq(names).length !== names.length) {
|
||||
return Promise.reject(
|
||||
|
||||
Reference in New Issue
Block a user