import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { Alert, Button, Checkbox, Divider, Drawer, Form, Input, InputNumber, Modal, notification, Select, Utils } from 'knowdesign'; import { PlusOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; import Api from '@src/api/index'; const CheckboxGroup = Checkbox.Group; interface DefaultConfig { name: string; defaultValue: string; readOnly: boolean; } const { Option } = Select; const { TextArea } = Input; const timeUnitMap = { ms: 1, min: 60 * 1000, h: 60 * 60 * 1000, day: 24 * 60 * 60 * 1000, }; const customDefaultFields = ['retention.ms', 'cleanup.policy', 'max.message.bytes']; function sizeof(str: string, charset?: string) { let total = 0, charCode, i, len; charset = charset ? charset.toLowerCase() : ''; if (charset === 'utf-16' || charset === 'utf16') { for (i = 0, len = str.length; i < len; i++) { charCode = str.charCodeAt(i); if (charCode <= 0xffff) { total += 2; } else { total += 4; } } } else { for (i = 0, len = str.length; i < len; i++) { charCode = str.charCodeAt(i); if (charCode <= 0x007f) { total += 1; } else if (charCode <= 0x07ff) { total += 2; } else if (charCode <= 0xffff) { total += 3; } else { total += 4; } } } return total; } export default (props: any) => { const { onConfirm } = props; const [retentionTime, setRetentionTime] = useState(0); const [retentionTimeUnit, setRetentionTimeUnit] = useState<'ms' | 'min' | 'h' | 'day'>('ms'); const [addTopicVisible, setAddTopicVisible] = useState(false); const [testMessageSizeModalVisible, setTestMessageSizeModalVisible] = useState(false); const [testMessage, setTestMessage] = useState(''); const [moreConfigOpenStatus, setMoreConfigOpenStatus] = useState('close'); const [defaultConfigs, setDefaultConfigs] = useState>([]); const [form] = Form.useForm(); const [originDefaultConfigs, setOriginDefaultConfigs] = useState({}); const routeParams = useParams<{ clusterId: string; }>(); const confirm = () => { form.validateFields().then((e) => { const formVal = JSON.parse(JSON.stringify(form.getFieldsValue())); formVal.clusterId = Number(routeParams.clusterId); formVal.properties['retention.ms'] = retentionTime * timeUnitMap[retentionTimeUnit]; Object.keys(originDefaultConfigs).forEach((k) => { if (formVal.properties[k] === originDefaultConfigs[k]) { delete formVal.properties[k]; } }); Object.keys(formVal.properties).forEach((k) => { if (Array.isArray(formVal.properties[k])) { formVal.properties[k] = formVal.properties[k].join(','); } }); Utils.post(Api.addTopic(), formVal).then((res: any) => { if (res === null) { notification.success({ message: '创建成功', }); onConfirm && onConfirm(); form.resetFields(); setAddTopicVisible(false); } else { notification.error({ message: '创建失败', }); } }); }); }; useEffect(() => { addTopicVisible && Utils.request(Api.getDefaultTopicConfig(Number(routeParams.clusterId))).then((res: Array) => { setDefaultConfigs(res); const defaultConfigValue = res.map((item) => { let res: any; try { res = item.name === 'cleanup.policy' ? item.defaultValue .replace(/\[|\]|\s+/g, '') .split(',') .filter((_) => _) : item.defaultValue; } catch (e) { res = []; } return { name: ['properties', item.name], value: res, }; }); setOriginDefaultConfigs( res.reduce((acc, cur) => { acc[cur.name] = cur.defaultValue; return acc; }, originDefaultConfigs) ); const newRetentionTime: any = Utils.transUnitTimePro(Number(res.find((item) => item.name === 'retention.ms').defaultValue), 2) || ''; setRetentionTime(newRetentionTime?.value); setRetentionTimeUnit(newRetentionTime?.unit); form.setFieldsValue({ saveTime: newRetentionTime?.value, saveTimeUnit: newRetentionTime?.unit }); form.setFields([...defaultConfigValue]); }); }, [addTopicVisible]); return ( <> } onClose={(_) => { setAddTopicVisible(false); }} >
({ validator(_, value) { if (!value) { return Promise.reject(`Topic名称不能为空`); } else if (!/[\u4e00-\u9fa5\w\-]+/.test(value)) { return Promise.reject(`Topic名称只能由中英文、下划线、短划线(-)组成`); } else if (!/^[a-zA-Z]/.test(value)) { return Promise.reject('Topic名称须以字母开头'); } else if (value.length < 3 || value.length > 128) { return Promise.reject('Topic名称长度限制为3~128字符'); } else { const validPromise = new Promise((resolve, reject) => { Utils.request(Api.getTopicMetadata(Number(routeParams.clusterId), value)) .then((res: any) => { if (res.exist) { reject(`Topic名称重复`); } else { resolve(''); } }) .catch((e) => { resolve(''); }); }); return validPromise; } }, }), ]} >
{ setRetentionTime(time); }} /> { if (!v) { return Promise.reject(`请选择时间格式`); } return Promise.resolve(''); }, }, ]} >
delete compact
更多配置
{/*
*/}
{ setMoreConfigOpenStatus(moreConfigOpenStatus === 'open' ? 'close' : 'open'); }} > {moreConfigOpenStatus === 'open' ? '收起' : '展开'} {moreConfigOpenStatus === 'open' ? : }
{ setTestMessageSizeModalVisible(true); }} > 立即测试
} />
`${value}KB`} // @ts-ignore parser={(value) => value.replace('KB', '')} /> {defaultConfigs .filter((dc) => !customDefaultFields.includes(dc.name)) .map((configItem, i) => ( ))}
{ setTestMessageSizeModalVisible(false); }} >
在下方输入框内输入消息样例即可计算出消息大小