Unverified Commit 2cde200a authored by aiwenmo's avatar aiwenmo Committed by GitHub

[Feature-987][admin] ClusterConfig and jar add upload file (#988)

Co-authored-by: 's avatarwenmo <32723967+wenmo@users.noreply.github.com>
parent 4f04d9ad
...@@ -197,22 +197,9 @@ ...@@ -197,22 +197,9 @@
</dependency> </dependency>
<!-- hadoop --> <!-- hadoop -->
<dependency> <dependency>
<groupId>org.apache.hadoop</groupId> <groupId>com.dlink</groupId>
<artifactId>hadoop-hdfs</artifactId> <artifactId>dlink-client-hadoop</artifactId>
<version>3.3.2</version> <scope>${scope.runtime}</scope>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs-client</artifactId>
<version>3.3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.3.2</version>
<scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
......
...@@ -45,7 +45,7 @@ public class UploadFileConstant { ...@@ -45,7 +45,7 @@ public class UploadFileConstant {
// Upload file's dir constant---------------------------------------------------------------------------------------- // Upload file's dir constant----------------------------------------------------------------------------------------
static { static {
// Get admin jar's parent absolute path // Get admin jar's parent absolute path
DLINK_HOME_DIR = new ApplicationHome(UploadFileConstant.class).getSource().getParent(); DLINK_HOME_DIR = new ApplicationHome(UploadFileConstant.class).getSource().getParent() + "/../";
} }
public static final String DLINK_HOME_DIR; public static final String DLINK_HOME_DIR;
......
...@@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils; ...@@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RequestPart;
...@@ -55,7 +55,7 @@ public class FileUploadController { ...@@ -55,7 +55,7 @@ public class FileUploadController {
* @param fileType Please refer {@link UploadFileConstant}, default is -1. If not provide, please provide the 'dir' value * @param fileType Please refer {@link UploadFileConstant}, default is -1. If not provide, please provide the 'dir' value
* @return {@link Result} * @return {@link Result}
*/ */
@PutMapping @PostMapping
public Result upload(@RequestPart("files") MultipartFile[] files, public Result upload(@RequestPart("files") MultipartFile[] files,
@RequestParam(value = "dir", defaultValue = "", required = false) String dir, @RequestParam(value = "dir", defaultValue = "", required = false) String dir,
@RequestParam(value = "fileType", defaultValue = "-1", required = false) Byte fileType) { @RequestParam(value = "fileType", defaultValue = "-1", required = false) Byte fileType) {
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--<scope.type>provided</scope.type>--> <!--<scope.type>provided</scope.type>-->
<hadoop.version>3.1.0</hadoop.version> <hadoop.version>3.3.2</hadoop.version>
<scope.type>compile</scope.type> <scope.type>compile</scope.type>
</properties> </properties>
......
...@@ -709,7 +709,7 @@ CREATE TABLE `dlink_fragment` ( ...@@ -709,7 +709,7 @@ CREATE TABLE `dlink_fragment` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='全局变量'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='全局变量';
-- 0.7.7-SNAPSHOT 2022-08-22 -- 0.6.7-SNAPSHOT 2022-09-02
-- ----------------------- -- -----------------------
-- DROP TABLE IF EXISTS `dlink_upload_file_record`; -- DROP TABLE IF EXISTS `dlink_upload_file_record`;
CREATE TABLE `dlink_upload_file_record` ( CREATE TABLE `dlink_upload_file_record` (
......
...@@ -17,15 +17,15 @@ ...@@ -17,15 +17,15 @@
* *
*/ */
import React, {useState} from 'react'; import React, {useState} from 'react';
import {Form, Button, Input, Modal, Select,Divider,Space,Switch} from 'antd'; import {Button, Divider, Form, Input, message, Modal, Select, Space, Switch, Upload} from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; import {MinusCircleOutlined, PlusOutlined, UploadOutlined} from '@ant-design/icons';
import type {ClusterConfigurationTableListItem} from "@/pages/ClusterConfiguration/data";
import {getConfig, getConfigFormValues} from "@/pages/ClusterConfiguration/function"; import {getConfig, getConfigFormValues} from "@/pages/ClusterConfiguration/function";
import {FLINK_CONFIG_LIST, HADOOP_CONFIG_LIST, KUBERNETES_CONFIG_LIST} from "@/pages/ClusterConfiguration/conf";
import type {Config} from "@/pages/ClusterConfiguration/conf"; import type {Config} from "@/pages/ClusterConfiguration/conf";
import {FLINK_CONFIG_LIST, HADOOP_CONFIG_LIST, KUBERNETES_CONFIG_LIST} from "@/pages/ClusterConfiguration/conf";
import {testClusterConfigurationConnect} from "@/pages/ClusterConfiguration/service"; import {testClusterConfigurationConnect} from "@/pages/ClusterConfiguration/service";
import type {ClusterConfigurationTableListItem} from "@/pages/ClusterConfiguration/data";
import {CODE} from "@/components/Common/crud";
export type ClusterConfigurationFormProps = { export type ClusterConfigurationFormProps = {
onCancel: (flag?: boolean) => void; onCancel: (flag?: boolean) => void;
...@@ -47,12 +47,16 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -47,12 +47,16 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
id: props.values.id, id: props.values.id,
name: props.values.name, name: props.values.name,
alias: props.values.alias, alias: props.values.alias,
type: props.values.type?props.values.type:"Yarn", type: props.values.type ? props.values.type : "Yarn",
configJson: props.values.configJson, configJson: props.values.configJson,
note: props.values.note, note: props.values.note,
enabled: props.values.enabled, enabled: props.values.enabled,
}); });
const [hadoopConfigPath, setHadoopConfigPath] = useState<string>(getConfigFormValues(formVals)['hadoopConfigPath']);
const [flinkLibPath, setFlinkLibPath] = useState<string>(getConfigFormValues(formVals)['flinkLibPath']);
const [flinkConfigPath, setFlinkConfigPath] = useState<string>(getConfigFormValues(formVals)['flinkConfigPath']);
const { const {
onSubmit: handleSubmit, onSubmit: handleSubmit,
onCancel: handleModalVisible, onCancel: handleModalVisible,
...@@ -60,10 +64,13 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -60,10 +64,13 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
} = props; } = props;
const onValuesChange = (change: any, all: any) => { const onValuesChange = (change: any, all: any) => {
setFormVals({...formVals,...change}); setFormVals({...formVals, ...change});
setHadoopConfigPath(all['hadoopConfigPath']);
setFlinkLibPath(all['flinkLibPath']);
setFlinkConfigPath(all['flinkConfigPath']);
}; };
const buildConfig = (config: Config[]) =>{ const buildConfig = (config: Config[]) => {
const itemList: JSX.Element[] = []; const itemList: JSX.Element[] = [];
config.forEach(configItem => { config.forEach(configItem => {
itemList.push(<Form.Item itemList.push(<Form.Item
...@@ -79,18 +86,44 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -79,18 +86,44 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
const submitForm = async () => { const submitForm = async () => {
const fieldsValue = await form.validateFields(); const fieldsValue = await form.validateFields();
const formValues = { const formValues = {
id:formVals.id, id: formVals.id,
name:fieldsValue.name, name: fieldsValue.name,
alias:fieldsValue.alias, alias: fieldsValue.alias,
type:fieldsValue.type, type: fieldsValue.type,
note:fieldsValue.note, note: fieldsValue.note,
enabled:fieldsValue.enabled, enabled: fieldsValue.enabled,
configJson:JSON.stringify(getConfig(fieldsValue)), configJson: JSON.stringify(getConfig(fieldsValue)),
}; };
setFormVals(formValues); setFormVals(formValues);
handleSubmit(formValues); handleSubmit(formValues);
}; };
const getUploadProps = (dir: string) => {
return {
name: 'files',
action: '/api/fileUpload',
// accept: 'application/json',
headers: {
authorization: 'authorization-text',
},
data: {
dir
},
showUploadList: true,
onChange(info) {
if (info.file.status === 'done') {
if (info.file.response.code == CODE.SUCCESS) {
message.success(info.file.response.msg);
} else {
message.warn(info.file.response.msg);
}
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 上传失败`);
}
},
}
};
const renderContent = (formValsPara: Partial<ClusterConfigurationTableListItem>) => { const renderContent = (formValsPara: Partial<ClusterConfigurationTableListItem>) => {
return ( return (
<> <>
...@@ -103,82 +136,87 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -103,82 +136,87 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
<Option value="Kubernetes">Flink On Kubernetes</Option> <Option value="Kubernetes">Flink On Kubernetes</Option>
</Select> </Select>
</Form.Item> </Form.Item>
{formValsPara.type=='Yarn'?<> {formValsPara.type == 'Yarn' ? <>
<Divider>Hadoop 配置</Divider> <Divider>Hadoop 配置</Divider>
<Form.Item <Form.Item
name="hadoopConfigPath" name="hadoopConfigPath"
label="配置文件路径" label="配置文件路径"
rules={[{required: true, message: '请输入 hadoop 配置文件路径!'}]} rules={[{required: true, message: '请输入 hadoop 配置文件路径!'}]}
help="指定配置文件路径(末尾无/),需要包含以下文件:core-site.xml,hdfs-site.xml,yarn-site.xml" help="指定配置文件路径(末尾无/),需要包含以下文件:core-site.xml,hdfs-site.xml,yarn-site.xml"
> >
<Input placeholder="值如 /etc/hadoop/conf"/> <Input placeholder="值如 /etc/hadoop/conf" addonAfter={
</Form.Item> <Form.Item name="suffix" noStyle>
<Divider orientation="left" plain>自定义配置(高优先级)</Divider> <Upload {...getUploadProps(hadoopConfigPath)}>
{buildConfig(HADOOP_CONFIG_LIST)} <UploadOutlined/>
<Form.Item </Upload>
label="其他配置" </Form.Item>}/>
> </Form.Item>
<Form.List name="hadoopConfigList"> <Divider orientation="left" plain>自定义配置(高优先级)</Divider>
{(fields, { add, remove }) => ( {buildConfig(HADOOP_CONFIG_LIST)}
<> <Form.Item
{fields.map(({ key, name, fieldKey, ...restField }) => ( label="其他配置"
<Space key={key} style={{ display: 'flex' }} align="baseline"> >
<Form.Item <Form.List name="hadoopConfigList">
{...restField} {(fields, {add, remove}) => (
name={[name, 'name']} <>
fieldKey={[fieldKey, 'name']} {fields.map(({key, name, fieldKey, ...restField}) => (
> <Space key={key} style={{display: 'flex'}} align="baseline">
<Input placeholder="name" /> <Form.Item
</Form.Item> {...restField}
<Form.Item name={[name, 'name']}
{...restField} fieldKey={[fieldKey, 'name']}
name={[name, 'value']} >
fieldKey={[fieldKey, 'value']} <Input placeholder="name"/>
> </Form.Item>
<Input placeholder="value" /> <Form.Item
{...restField}
name={[name, 'value']}
fieldKey={[fieldKey, 'value']}
>
<Input placeholder="value"/>
</Form.Item>
<MinusCircleOutlined onClick={() => remove(name)}/>
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined/>}>
添加一个自定义项
</Button>
</Form.Item> </Form.Item>
<MinusCircleOutlined onClick={() => remove(name)} /> </>
</Space> )}
))} </Form.List>
<Form.Item> </Form.Item></> : undefined}
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}> {formValsPara.type == 'Kubernetes' ? <>
添加一个自定义项
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form.Item></>:undefined}
{formValsPara.type=='Kubernetes'?<>
<Divider>Kubernetes 配置</Divider> <Divider>Kubernetes 配置</Divider>
{buildConfig(KUBERNETES_CONFIG_LIST)} {buildConfig(KUBERNETES_CONFIG_LIST)}
<Form.Item <Form.Item
label="其他配置" label="其他配置"
> >
<Form.List name="kubernetesConfigList"> <Form.List name="kubernetesConfigList">
{(fields, { add, remove }) => ( {(fields, {add, remove}) => (
<> <>
{fields.map(({ key, name, fieldKey, ...restField }) => ( {fields.map(({key, name, fieldKey, ...restField}) => (
<Space key={key} style={{ display: 'flex' }} align="baseline"> <Space key={key} style={{display: 'flex'}} align="baseline">
<Form.Item <Form.Item
{...restField} {...restField}
name={[name, 'name']} name={[name, 'name']}
fieldKey={[fieldKey, 'name']} fieldKey={[fieldKey, 'name']}
> >
<Input placeholder="name" /> <Input placeholder="name"/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
{...restField} {...restField}
name={[name, 'value']} name={[name, 'value']}
fieldKey={[fieldKey, 'value']} fieldKey={[fieldKey, 'value']}
> >
<Input placeholder="value" /> <Input placeholder="value"/>
</Form.Item> </Form.Item>
<MinusCircleOutlined onClick={() => remove(name)} /> <MinusCircleOutlined onClick={() => remove(name)}/>
</Space> </Space>
))} ))}
<Form.Item> <Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}> <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined/>}>
添加一个自定义项 添加一个自定义项
</Button> </Button>
</Form.Item> </Form.Item>
...@@ -186,61 +224,71 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -186,61 +224,71 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
)} )}
</Form.List> </Form.List>
</Form.Item> </Form.Item>
</>:undefined} </> : undefined}
<Divider>Flink 配置</Divider> <Divider>Flink 配置</Divider>
{formValsPara.type=='Yarn'?<> {formValsPara.type == 'Yarn' ? <>
<Form.Item <Form.Item
name="flinkLibPath" name="flinkLibPath"
label="lib 路径" label="lib 路径"
rules={[{required: true, message: '请输入 lib 的 hdfs 路径!'}]} rules={[{required: true, message: '请输入 lib 的 hdfs 路径!'}]}
help="指定 lib 的 hdfs 路径(末尾无/),需要包含 Flink 运行时的依赖" help="指定 lib 的 hdfs 路径(末尾无/),需要包含 Flink 运行时的依赖"
> >
<Input placeholder="值如 hdfs:///flink/lib"/> <Input placeholder="值如 hdfs:///flink/lib" addonAfter={
</Form.Item> <Form.Item name="suffix" noStyle>
</>:undefined} <Upload {...getUploadProps(flinkLibPath)}>
<UploadOutlined/>
</Upload>
</Form.Item>}/>
</Form.Item>
</> : undefined}
<Form.Item <Form.Item
name="flinkConfigPath" name="flinkConfigPath"
label="配置文件路径" label="配置文件路径"
rules={[{required: true, message: '请输入 flink-conf.yaml 路径!'}]} rules={[{required: true, message: '请输入 flink-conf.yaml 路径!'}]}
help="指定 flink-conf.yaml 的路径(末尾无/)" help="指定 flink-conf.yaml 的路径(末尾无/)"
> >
<Input placeholder="值如 /opt/module/flink/conf"/> <Input placeholder="值如 /opt/module/flink/conf" addonAfter={
<Form.Item name="suffix" noStyle>
<Upload {...getUploadProps(flinkConfigPath)}>
<UploadOutlined/>
</Upload>
</Form.Item>}/>
</Form.Item> </Form.Item>
<Divider orientation="left" plain>自定义配置(高优先级)</Divider> <Divider orientation="left" plain>自定义配置(高优先级)</Divider>
{buildConfig(FLINK_CONFIG_LIST)} {buildConfig(FLINK_CONFIG_LIST)}
<Form.Item <Form.Item
label="其他配置" label="其他配置"
> >
<Form.List name="flinkConfigList"> <Form.List name="flinkConfigList">
{(fields, { add, remove }) => ( {(fields, {add, remove}) => (
<> <>
{fields.map(({ key, name, fieldKey, ...restField }) => ( {fields.map(({key, name, fieldKey, ...restField}) => (
<Space key={key} style={{ display: 'flex', marginBottom: 8 }} align="baseline"> <Space key={key} style={{display: 'flex', marginBottom: 8}} align="baseline">
<Form.Item <Form.Item
{...restField} {...restField}
name={[name, 'name']} name={[name, 'name']}
fieldKey={[fieldKey, 'name']} fieldKey={[fieldKey, 'name']}
> >
<Input placeholder="name" /> <Input placeholder="name"/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
{...restField} {...restField}
name={[name, 'value']} name={[name, 'value']}
fieldKey={[fieldKey, 'value']} fieldKey={[fieldKey, 'value']}
> >
<Input placeholder="value" /> <Input placeholder="value"/>
</Form.Item> </Form.Item>
<MinusCircleOutlined onClick={() => remove(name)} /> <MinusCircleOutlined onClick={() => remove(name)}/>
</Space> </Space>
))} ))}
<Form.Item> <Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}> <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined/>}>
添加一个自定义项 添加一个自定义项
</Button> </Button>
</Form.Item> </Form.Item>
</> </>
)} )}
</Form.List> </Form.List>
</Form.Item> </Form.Item>
<Divider>基本配置</Divider> <Divider>基本配置</Divider>
<Form.Item <Form.Item
...@@ -272,16 +320,16 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -272,16 +320,16 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
); );
}; };
const testForm = async ()=>{ const testForm = async () => {
const fieldsValue = await form.validateFields(); const fieldsValue = await form.validateFields();
const formValues = { const formValues = {
id :formVals.id, id: formVals.id,
name:fieldsValue.name, name: fieldsValue.name,
alias:fieldsValue.alias, alias: fieldsValue.alias,
type:fieldsValue.type, type: fieldsValue.type,
note:fieldsValue.note, note: fieldsValue.note,
enabled:fieldsValue.enabled, enabled: fieldsValue.enabled,
configJson:JSON.stringify(getConfig(fieldsValue)), configJson: JSON.stringify(getConfig(fieldsValue)),
} as ClusterConfigurationTableListItem; } as ClusterConfigurationTableListItem;
setFormVals(formValues); setFormVals(formValues);
testClusterConfigurationConnect(formValues); testClusterConfigurationConnect(formValues);
...@@ -306,7 +354,7 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props ...@@ -306,7 +354,7 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = (props
width={1200} width={1200}
bodyStyle={{padding: '32px 40px 48px'}} bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose destroyOnClose
title={formVals.id?"维护集群配置":"创建集群配置"} title={formVals.id ? "维护集群配置" : "创建集群配置"}
visible={modalVisible} visible={modalVisible}
footer={renderFooter()} footer={renderFooter()}
onCancel={() => handleModalVisible()} onCancel={() => handleModalVisible()}
......
...@@ -19,14 +19,13 @@ ...@@ -19,14 +19,13 @@
import React, {useRef, useState} from "react"; import React, {useRef, useState} from "react";
import {DownOutlined, HeartOutlined, PlusOutlined, UserOutlined} from '@ant-design/icons'; import {DownOutlined, PlusOutlined} from '@ant-design/icons';
import {ActionType, ProColumns} from "@ant-design/pro-table"; import ProTable, {ActionType, ProColumns} from "@ant-design/pro-table";
import {Button, message, Input, Drawer, Modal, Dropdown, Menu} from 'antd'; import {Button, Drawer, Dropdown, Menu, message, Modal, Upload} from 'antd';
import {PageContainer, FooterToolbar} from '@ant-design/pro-layout'; import {FooterToolbar, PageContainer} from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions'; import ProDescriptions from '@ant-design/pro-descriptions';
import {JarTableListItem} from "@/pages/Jar/data"; import {JarTableListItem} from "@/pages/Jar/data";
import {handleAddOrUpdate, handleRemove, queryData, updateEnabled} from "@/components/Common/crud"; import {CODE, handleAddOrUpdate, handleRemove, queryData, updateEnabled} from "@/components/Common/crud";
import JarForm from "@/pages/Jar/components/JarForm"; import JarForm from "@/pages/Jar/components/JarForm";
const url = '/api/jar'; const url = '/api/jar';
...@@ -57,6 +56,32 @@ const JarTableList: React.FC<{}> = (props: any) => { ...@@ -57,6 +56,32 @@ const JarTableList: React.FC<{}> = (props: any) => {
} }
}; };
const getUploadProps = (dir: string) => {
return {
name: 'files',
action: '/api/fileUpload',
accept: 'jar',
headers: {
authorization: 'authorization-text',
},
data: {
dir
},
showUploadList: true,
onChange(info) {
if (info.file.status === 'done') {
if (info.file.response.code == CODE.SUCCESS) {
message.success(info.file.response.msg);
} else {
message.warn(info.file.response.msg);
}
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 上传失败`);
}
},
}
};
const MoreBtn: React.FC<{ const MoreBtn: React.FC<{
item: JarTableListItem; item: JarTableListItem;
}> = ({item}) => ( }> = ({item}) => (
...@@ -132,7 +157,7 @@ const JarTableList: React.FC<{}> = (props: any) => { ...@@ -132,7 +157,7 @@ const JarTableList: React.FC<{}> = (props: any) => {
title: '启动类', title: '启动类',
sorter: true, sorter: true,
dataIndex: 'mainClass', dataIndex: 'mainClass',
},{ }, {
title: '执行参数', title: '执行参数',
sorter: true, sorter: true,
dataIndex: 'paras', dataIndex: 'paras',
...@@ -194,6 +219,9 @@ const JarTableList: React.FC<{}> = (props: any) => { ...@@ -194,6 +219,9 @@ const JarTableList: React.FC<{}> = (props: any) => {
> >
配置 配置
</a>, </a>,
<Upload {...getUploadProps(record.path)}>
<a>上传</a>
</Upload>,
<MoreBtn key="more" item={record}/>, <MoreBtn key="more" item={record}/>,
], ],
}, },
...@@ -206,84 +234,102 @@ const JarTableList: React.FC<{}> = (props: any) => { ...@@ -206,84 +234,102 @@ const JarTableList: React.FC<{}> = (props: any) => {
actionRef={actionRef} actionRef={actionRef}
rowKey="id" rowKey="id"
search={{ search={{
labelWidth: 120, labelWidth: 120,
}} }}
toolBarRender={() => [ toolBarRender={() => [
<Button type="primary" onClick={() => handleModalVisible(true)}> <Button type="primary" onClick={() => handleModalVisible(true)}>
<PlusOutlined/> 新建 <PlusOutlined/> 新建
</Button>, </Button>,
]} ]}
request={(params, sorter, filter) => queryData(url, {...params, sorter, filter})} request={(params, sorter, filter) => queryData(url, {...params, sorter, filter})}
columns={columns} columns={columns}
rowSelection={{ rowSelection={{
onChange: (_, selectedRows) => setSelectedRows(selectedRows), onChange: (_, selectedRows) => setSelectedRows(selectedRows),
}} }}
/> />
{selectedRowsState?.length > 0 && ( {selectedRowsState?.length > 0 && (
<FooterToolbar <FooterToolbar
extra={ extra={
<div> <div>
已选择 <a style={{fontWeight: 600}}>{selectedRowsState.length}</a>&nbsp;&nbsp; 已选择 <a style={{fontWeight: 600}}>{selectedRowsState.length}</a>&nbsp;&nbsp;
<span> <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> </span>
</div> </div>
} }
>
<Button type="primary" danger
onClick={() => {
Modal.confirm({
title: '删除Jar配置',
content: '确定删除选中的Jar配置吗?',
okText: '确认',
cancelText: '取消',
onOk: async () => {
await handleRemove(url, selectedRowsState);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}
});
}}
> >
<Button type="primary" danger 批量删除
onClick={() => { </Button>
Modal.confirm({ <Button type="primary"
title: '删除Jar配置', onClick={() => {
content: '确定删除选中的Jar配置吗?', Modal.confirm({
okText: '确认', title: '启用Jar配置',
cancelText: '取消', content: '确定启用选中的Jar配置吗?',
onOk: async () => { okText: '确认',
await handleRemove(url, selectedRowsState); cancelText: '取消',
setSelectedRows([]); onOk: async () => {
actionRef.current?.reloadAndRest?.(); await updateEnabled(url, selectedRowsState, true);
} setSelectedRows([]);
}); actionRef.current?.reloadAndRest?.();
}} }
> });
批量删除 }}
</Button> >批量启用</Button>
<Button type="primary" <Button danger
onClick={() => { onClick={() => {
Modal.confirm({ Modal.confirm({
title: '启用Jar配置', title: '禁用Jar配置',
content: '确定启用选中的Jar配置吗?', content: '确定禁用选中的Jar配置吗?',
okText: '确认', okText: '确认',
cancelText: '取消', cancelText: '取消',
onOk: async () => { onOk: async () => {
await updateEnabled(url, selectedRowsState, true); await updateEnabled(url, selectedRowsState, false);
setSelectedRows([]); setSelectedRows([]);
actionRef.current?.reloadAndRest?.(); actionRef.current?.reloadAndRest?.();
} }
}); });
}} }}
>批量启用</Button> >批量禁用</Button>
<Button danger </FooterToolbar>
onClick={() => { )}
Modal.confirm({ <JarForm
title: '禁用Jar配置', onSubmit={async (value) => {
content: '确定禁用选中的Jar配置吗?', const success = await handleAddOrUpdate(url, value);
okText: '确认', if (success) {
cancelText: '取消', handleModalVisible(false);
onOk: async () => { setFormValues({});
await updateEnabled(url, selectedRowsState, false); if (actionRef.current) {
setSelectedRows([]); actionRef.current.reload();
actionRef.current?.reloadAndRest?.(); }
} }
}); }}
}} onCancel={() => {
>批量禁用</Button> handleModalVisible(false);
</FooterToolbar> }}
)} modalVisible={modalVisible}
values={{}}
/>
{formValues && Object.keys(formValues).length ? (
<JarForm <JarForm
onSubmit={async (value) => { onSubmit={async (value) => {
const success = await handleAddOrUpdate(url, value); const success = await handleAddOrUpdate(url, value);
if (success) { if (success) {
handleModalVisible(false); handleUpdateModalVisible(false);
setFormValues({}); setFormValues({});
if (actionRef.current) { if (actionRef.current) {
actionRef.current.reload(); actionRef.current.reload();
...@@ -291,55 +337,37 @@ const JarTableList: React.FC<{}> = (props: any) => { ...@@ -291,55 +337,37 @@ const JarTableList: React.FC<{}> = (props: any) => {
} }
}} }}
onCancel={() => { onCancel={() => {
handleModalVisible(false); handleUpdateModalVisible(false);
setFormValues({});
}} }}
modalVisible={modalVisible} modalVisible={updateModalVisible}
values={{}} values={formValues}
/> />
{formValues && Object.keys(formValues).length ? ( ) : null}
<JarForm <Drawer
onSubmit={async (value) => { width={600}
const success = await handleAddOrUpdate(url, value); visible={!!row}
if (success) { onClose={() => {
handleUpdateModalVisible(false); setRow(undefined);
setFormValues({}); }}
if (actionRef.current) { closable={false}
actionRef.current.reload(); >
} {row?.name && (
} <ProDescriptions<JarTableListItem>
}} column={2}
onCancel={() => { title={row?.name}
handleUpdateModalVisible(false); request={async () => ({
setFormValues({});
}}
modalVisible={updateModalVisible}
values={formValues}
/>
): null}
<Drawer
width={600}
visible={!!row}
onClose={() => {
setRow(undefined);
}}
closable={false}
>
{row?.name && (
<ProDescriptions<JarTableListItem>
column={2}
title={row?.name}
request={async () => ({
data: row || {}, data: row || {},
})} })}
params={{ params={{
id: row?.name, id: row?.name,
}} }}
columns={columns} columns={columns}
/> />
)} )}
</Drawer> </Drawer>
</PageContainer> </PageContainer>
); );
}; };
export default JarTableList; export default JarTableList;
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