fix(style): k8s form
This commit is contained in:
@@ -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 />
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user