fix(style): k8s form

This commit is contained in:
jialin
2026-06-01 21:06:56 +08:00
committed by jialin
parent e314f25a77
commit 95ffe0350e
12 changed files with 328 additions and 249 deletions
@@ -1,20 +1,11 @@
import { PageActionType } from '@/config/types';
import {
MinusOutlined,
PlusOutlined,
QuestionCircleOutlined
} from '@ant-design/icons';
import {
Input as CInput,
LabelSelector,
SwitchCard,
useAppUtils
} from '@gpustack/core-ui';
import { Input as CInput, LabelSelector, SwitchCard } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Button, Form, Tooltip } from 'antd';
import { Form } from 'antd';
import React, { useState } from 'react';
import styled from 'styled-components';
import { GpuInstanceOptions } from '../config/types';
import ImageCredential from './image-credential';
import K8SVolumeMount from './k8s-volume-mount';
const Title = styled.div`
@@ -32,151 +23,21 @@ const SectionWrap = styled.div`
margin-bottom: 16px;
`;
const ImageCredentialsForm: React.FC = () => {
const intl = useIntl();
const { getRuleMessage } = useAppUtils();
return (
<SectionWrap>
<Form.List name={['k8s_options', 'imageCredentials']}>
{(fields, { add, remove }) => (
<>
<Title>
<div className="flex-center gap-8">
<span>
{intl.formatMessage({
id: 'clusters.imageCredentials.title'
})}
</span>
<Button
type="link"
onClick={() =>
add({ registry: '', username: '', password: '' })
}
>
<PlusOutlined />{' '}
{intl.formatMessage({
id: 'clusters.imageCredentials.add'
})}
</Button>
</div>
</Title>
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{fields.map(({ key, name }) => (
<div
key={key}
style={{
display: 'flex',
alignItems: 'flex-start',
gap: 8,
padding: 12,
border: '1px solid var(--ant-color-split)',
borderRadius: 'var(--ant-border-radius-lg)'
}}
>
<div
style={{
flex: 1,
display: 'flex',
flexDirection: 'column',
gap: 12
}}
>
<Form.Item
name={[name, 'registry']}
rules={[
{
required: true,
message: getRuleMessage(
'input',
'clusters.imageCredentials.registry'
)
}
]}
style={{ marginBottom: 0 }}
>
<CInput.Input
required
label={intl.formatMessage({
id: 'clusters.imageCredentials.registry'
})}
></CInput.Input>
</Form.Item>
<div style={{ display: 'flex', gap: 12 }}>
<div style={{ flex: 1 }}>
<Form.Item
name={[name, 'username']}
style={{ marginBottom: 0 }}
>
<CInput.Input
label={intl.formatMessage({
id: 'clusters.imageCredentials.username'
})}
></CInput.Input>
</Form.Item>
</div>
<div style={{ flex: 1 }}>
<Form.Item
name={[name, 'password']}
style={{ marginBottom: 0 }}
>
<CInput.Password
label={intl.formatMessage({
id: 'clusters.imageCredentials.password'
})}
></CInput.Password>
</Form.Item>
</div>
</div>
</div>
<Button
size="small"
shape="circle"
style={{ marginTop: 8 }}
onClick={() => remove(name)}
>
<MinusOutlined />
</Button>
</div>
))}
</div>
</>
)}
</Form.List>
</SectionWrap>
);
};
const NodeSelectorForm: React.FC = () => {
const intl = useIntl();
return (
<SectionWrap>
<Title>
<span className="flex-center gap-4">
<span>
{intl.formatMessage({ id: 'clusters.nodeSelector.title' })}
</span>
<Tooltip
title={intl.formatMessage({ id: 'clusters.nodeSelector.tip' })}
>
<QuestionCircleOutlined
style={{ color: 'var(--ant-color-text-secondary)' }}
/>
</Tooltip>
</span>
</Title>
<Form.Item name={['k8s_options', 'nodeSelector']}>
<LabelSelector
label={intl.formatMessage({ id: 'clusters.nodeSelector.title' })}
description={intl.formatMessage({ id: 'clusters.nodeSelector.tip' })}
></LabelSelector>
</Form.Item>
</SectionWrap>
);
};
// Render namespace. Kept as the first field of the section so the most
// fundamental K8s deployment knob is set before the rest.
const NamespaceForm: React.FC = () => {
const intl = useIntl();
@@ -197,8 +58,6 @@ const NamespaceForm: React.FC = () => {
);
};
// Operator-image override. A plain string knob that used to ride along inside
// worker_config; it now lives directly on k8s_options.
const OperatorImageForm: React.FC = () => {
const intl = useIntl();
@@ -273,7 +132,7 @@ const K8sPodSpec: React.FC<{
<GpuInstanceOptionsForm initialValue={initialGpuInstanceOptions} />
<NamespaceForm />
<K8SVolumeMount action={action}></K8SVolumeMount>
<ImageCredentialsForm />
<ImageCredential />
<NodeSelectorForm />
<OperatorImageForm />
</>