Commit f255dd73 authored by zhu-mingye's avatar zhu-mingye

op clusterinstance page form

parent 610bfed2
......@@ -38,7 +38,7 @@ const ClusterForm: React.FC<ClusterFormProps> = (props) => {
const submitForm = async () => {
const fieldsValue = await form.validateFields();
fieldsValue.id= formVals.id;
fieldsValue.id = formVals.id;
setFormVals(fieldsValue);
handleSubmit(fieldsValue);
};
......@@ -75,6 +75,29 @@ const ClusterForm: React.FC<ClusterFormProps> = (props) => {
<Form.Item
name="hosts"
label="JobManager HA 地址"
validateTrigger={['onChange']}
rules={[
{
required: true,
validator(_, hostsValue) {
let hostArray = [];
if (hostsValue.trim().length === 0) {
return Promise.reject(new Error('请输入 JobManager HA 地址!'));
} else {
hostArray = hostsValue.split(',')
for (let i = 0; i < hostArray.length; i++) {
if (hostArray[i].includes('/')) {
return Promise.reject(new Error('不符合规则! 不能包含/'));
}
if (parseInt(hostArray[i].split(':')[1]) >= 65535) {
return Promise.reject(new Error('不符合规则! 端口号区间[0-65535]'));
}
}
return Promise.resolve();
}
},
},
]}
>
<Input.TextArea
placeholder="添加 Flink 集群的 JobManager 的 RestApi 地址。当 HA 模式时,地址间用英文逗号分隔,例如:192.168.123.101:8081,192.168.123.102:8081,192.168.123.103:8081"
......@@ -114,7 +137,7 @@ const ClusterForm: React.FC<ClusterFormProps> = (props) => {
width={640}
bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose
title={formVals.id?"修改集群":"创建集群"}
title={formVals.id ? "修改集群" : "创建集群"}
visible={modalVisible}
footer={renderFooter()}
onCancel={() => handleModalVisible()}
......
import React from 'react';
import { Modal } from 'antd';
type CreateFormProps = {
modalVisible: boolean;
onCancel: () => void;
};
const CreateForm: React.FC<CreateFormProps> = (props) => {
const { modalVisible, onCancel } = props;
return (
<Modal
destroyOnClose
title="添加 Flink 集群"
visible={modalVisible}
onCancel={() => onCancel()}
footer={null}
>
{props.children}
</Modal>
);
};
export default CreateForm;
import React, {useEffect, useState} from 'react';
import {Form, Button, Input, Modal, Select} from 'antd';
import Switch from "antd/es/switch";
import TextArea from "antd/es/input/TextArea";
import {ClusterTableListItem} from "@/pages/Cluster/data";
import {RUN_MODE} from "@/components/Studio/conf";
export type UpdateFormProps = {
onCancel: (flag?: boolean, formVals?: Partial<ClusterTableListItem>) => void;
onSubmit: (values: Partial<ClusterTableListItem>) => void;
updateModalVisible: boolean;
values: Partial<ClusterTableListItem>;
};
const Option = Select.Option;
const formLayout = {
labelCol: {span: 7},
wrapperCol: {span: 13},
};
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const [formVals, setFormVals] = useState<Partial<ClusterTableListItem>>({
id: props.values.id,
name: props.values.name,
alias: props.values.alias,
type: props.values.type,
hosts: props.values.hosts,
note: props.values.note,
enabled: props.values.enabled,
});
const [form] = Form.useForm();
const {
onSubmit: handleUpdate,
onCancel: handleUpdateModalVisible,
updateModalVisible,
values,
} = props;
const submitForm = async () => {
const fieldsValue = await form.validateFields();
setFormVals({...formVals, ...fieldsValue});
handleUpdate({...formVals, ...fieldsValue});
};
const renderContent = (formVals) => {
return (
<>
<Form.Item
name="name"
label="名称"
rules={[{required: true, message: '请输入名称!'}]}>
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item
name="alias"
label="别名"
>
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item
name="type"
label="类型"
>
<Select defaultValue={RUN_MODE.YARN_SESSION} allowClear>
<Option value={RUN_MODE.STANDALONE}>Standalone</Option>
<Option value={RUN_MODE.YARN_SESSION}>Yarn Session</Option>
<Option value={RUN_MODE.YARN_PER_JOB}>Yarn Per-Job</Option>
<Option value={RUN_MODE.YARN_APPLICATION}>Yarn Application</Option>
<Option value={RUN_MODE.KUBERNETES_SESSION}>Kubernetes Session</Option>
<Option value={RUN_MODE.KUBERNETES_APPLICATION}>Kubernetes Application</Option>
</Select>
</Form.Item>
<Form.Item
name="hosts"
label="JobManager HA 地址"
>
<TextArea
placeholder="添加 Flink 集群的 JobManager 的 RestApi 地址。当 HA 模式时,地址间用英文逗号分隔,例如:192.168.123.101:8081,192.168.123.102:8081,192.168.123.103:8081"
allowClear
autoSize={{minRows: 3, maxRows: 10}}/>
</Form.Item>
<Form.Item
name="note"
label="注释"
>
<TextArea
placeholder="请输入"
allowClear
autoSize={{minRows: 3, maxRows: 10}}/>
</Form.Item>
<Form.Item
name="enabled"
label="是否启用"
rules={[{required: true, message: '请输入是否启用!'}]}>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
defaultChecked={formVals.enabled}/>
</Form.Item>
</>
);
};
const renderFooter = () => {
return (
<>
<Button onClick={() => handleUpdateModalVisible(false, values)}>取消</Button>
<Button type="primary" onClick={() => submitForm()}>
完成
</Button>
</>
);
};
return (
<Modal
width={640}
bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose
title="编辑集群"
visible={updateModalVisible}
footer={renderFooter()}
onCancel={() => handleUpdateModalVisible()}
>
<Form
{...formLayout}
form={form}
initialValues={{
id: formVals.id,
name: formVals.name,
alias: formVals.alias,
type: formVals.type,
hosts: formVals.hosts,
note: formVals.note,
enabled: formVals.enabled,
}}
>
{renderContent(formVals)}
</Form>
</Modal>
);
};
export default UpdateForm;
......@@ -5,8 +5,6 @@ import {FooterToolbar, PageContainer} from '@ant-design/pro-layout';
import type {ActionType, ProColumns} from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions';
import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm';
import type {ClusterTableListItem} from './data.d';
import Dropdown from "antd/es/dropdown/dropdown";
......@@ -21,13 +19,14 @@ import {
} from "@/components/Common/crud";
import {showCluster, showSessionCluster} from "@/components/Studio/StudioEvent/DDL";
import {RUN_MODE} from "@/components/Studio/conf";
import ClusterForm from "@/pages/Cluster/components/ClusterForm";
const TextArea = Input.TextArea;
const url = '/api/cluster';
const ClusterTableList: React.FC<{}> = (props: any) => {
const {dispatch} = props;
const [createModalVisible, handleModalVisible] = useState<boolean>(false);
const [modalVisible, handleModalVisible] = useState<boolean>(false);
const [updateModalVisible, handleUpdateModalVisible] = useState<boolean>(false);
const [formValues, setFormValues] = useState({});
const actionRef = useRef<ActionType>();
......@@ -303,6 +302,7 @@ const ClusterTableList: React.FC<{}> = (props: any) => {
{
title: '操作',
dataIndex: 'option',
tooltip: 'FLinkWebUI连接 当集群状态为`可用`时! 支持 SESSION | STANDALONE',
valueType: 'option',
render: (_, record) => [
<a
......@@ -313,13 +313,18 @@ const ClusterTableList: React.FC<{}> = (props: any) => {
>
配置
</a>,
<Button type="link"
href={`http://${record.jobManagerHost}/#/overview`}
target="_blank"
>
FlinkWebUI
</Button>,
<MoreBtn key="more" item={record}/>,
((record.status && (record.type === RUN_MODE.YARN_SESSION || record.type === RUN_MODE.STANDALONE )) ?
<>
<Button type="link" title={`http://${record.jobManagerHost}/#/overview`}
href={`http://${record.jobManagerHost}/#/overview`}
target="_blank"
>
FlinkWebUI
</Button>
</>
: undefined
),
],
},
];
......@@ -356,7 +361,7 @@ const ClusterTableList: React.FC<{}> = (props: any) => {
<div>
已选择 <a style={{fontWeight: 600}}>{selectedRowsState.length}</a>&nbsp;&nbsp;
<span>
被禁用的集群共 {selectedRowsState.length - selectedRowsState.reduce((pre, item) => pre + (item.enabled ? 1 : 0), 0)}
被禁用的集群共 {selectedRowsState.length - selectedRowsState.reduce((pre, item) => pre + (item.enabled ? 1 : 0), 0)}
</span>
</div>
}
......@@ -410,26 +415,26 @@ const ClusterTableList: React.FC<{}> = (props: any) => {
>批量禁用</Button>
</FooterToolbar>
)}
<CreateForm onCancel={() => handleModalVisible(false)} modalVisible={createModalVisible}>
<ProTable<ClusterTableListItem, ClusterTableListItem>
<ClusterForm
onSubmit={async (value) => {
const success = await handleAddOrUpdate(url, value);
if (success) {
handleModalVisible(false);
if (actionRef.current) {
actionRef.current.reload();
const success = await handleAddOrUpdate(url, value);
if (success) {
handleModalVisible(false);
setFormValues({});
if (actionRef.current) {
actionRef.current.reload();
}
showCluster(dispatch);
showSessionCluster(dispatch);
}
showCluster(dispatch);
showSessionCluster(dispatch);
}
}}
rowKey="id"
type="form"
columns={columns}
/>
</CreateForm>
}}
onCancel={() => handleModalVisible(false)}
modalVisible={modalVisible}
values={{}}
>
</ClusterForm>
{formValues && Object.keys(formValues).length ? (
<UpdateForm
<ClusterForm
onSubmit={async (value) => {
const success = await handleAddOrUpdate(url, value);
if (success) {
......@@ -446,10 +451,10 @@ const ClusterTableList: React.FC<{}> = (props: any) => {
handleUpdateModalVisible(false);
setFormValues({});
}}
updateModalVisible={updateModalVisible}
modalVisible={updateModalVisible}
values={formValues}
/>
) : null}
) : undefined}
<Drawer
width={600}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment