diff --git a/build.sh b/build.sh index a6e86d7dd0976eac4860debbf9ec7129d678fac2..9c107907b554c44e262ad557e9f9d3c0f0e331ef 100644 --- a/build.sh +++ b/build.sh @@ -4,7 +4,7 @@ cd $workspace ## constant OUTPUT_DIR=./output -KM_VERSION=2.3.1 +KM_VERSION=2.4.0 APP_NAME=kafka-manager APP_DIR=${APP_NAME}-${KM_VERSION} diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/bizenum/OperateEnum.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/bizenum/OperateEnum.java index 2bc874ec3367c378d6687956a9f93e21b731ee04..af69ea50fd9a80f186a5a8c3a68cca57bdc680a2 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/bizenum/OperateEnum.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/bizenum/OperateEnum.java @@ -46,7 +46,7 @@ public enum OperateEnum { public static boolean validate(Integer code) { if (code == null) { - return false; + return true; } for (OperateEnum state : OperateEnum.values()) { if (state.getCode() == code) { diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/OperateRecordDTO.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/OperateRecordDTO.java index 1837ecfcde72bbcc6dfb6782df1c7fad369cd4d4..7f1910173a11661ab1d547e230d0878d97a390f3 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/OperateRecordDTO.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/OperateRecordDTO.java @@ -81,11 +81,6 @@ public class OperateRecordDTO { } public boolean legal() { - if (!ModuleEnum.validate(moduleId) || - (!ValidateUtils.isNull(operateId) && OperateEnum.validate(operateId)) - ) { - return false; - } - return true; + return !ValidateUtils.isNull(moduleId) && ModuleEnum.validate(moduleId) && OperateEnum.validate(operateId); } } diff --git a/kafka-manager-extends/kafka-manager-openapi/src/main/java/com/xiaojukeji/kafka/manager/openapi/common/vo/TopicStatisticMetricsVO.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/vo/normal/topic/TopicStatisticMetricsVO.java similarity index 91% rename from kafka-manager-extends/kafka-manager-openapi/src/main/java/com/xiaojukeji/kafka/manager/openapi/common/vo/TopicStatisticMetricsVO.java rename to kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/vo/normal/topic/TopicStatisticMetricsVO.java index 3665b7acc79473b929d83d2ba6357bab692809aa..c83c24d2d7f5fdf15a3bec4a6acfdc11b068a69e 100644 --- a/kafka-manager-extends/kafka-manager-openapi/src/main/java/com/xiaojukeji/kafka/manager/openapi/common/vo/TopicStatisticMetricsVO.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/vo/normal/topic/TopicStatisticMetricsVO.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.openapi.common.vo; +package com.xiaojukeji.kafka.manager.common.entity.vo.normal.topic; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -14,7 +14,6 @@ public class TopicStatisticMetricsVO { public TopicStatisticMetricsVO(Double peakBytesIn) { this.peakBytesIn = peakBytesIn; - } public Double getPeakBytesIn() { diff --git a/kafka-manager-console/src/component/flow-table/index.tsx b/kafka-manager-console/src/component/flow-table/index.tsx index 1f7d9be60d055b2c23b37b3773717cea868274af..c62f7089eedba89fa7ce4021c445c8ae90c9acd7 100644 --- a/kafka-manager-console/src/component/flow-table/index.tsx +++ b/kafka-manager-console/src/component/flow-table/index.tsx @@ -68,8 +68,8 @@ export class StatusGraghCom extends React.Component { public render() { const statusData = this.getData(); const loading = this.getLoading(); - if (!statusData) return null; const data: any[] = []; + if (!statusData) return ; Object.keys(statusData).map((key) => { if (statusData[key]) { const v = key === 'byteIn' || key === 'byteOut' ? statusData[key].map(i => i && (i / 1024).toFixed(2)) : @@ -85,7 +85,7 @@ export class StatusGraghCom extends React.Component { } }); return ( -
+
); } } diff --git a/kafka-manager-console/src/component/x-form/index.less b/kafka-manager-console/src/component/x-form/index.less index 95152e60c1930c00c68c26b474bd86e345eef1eb..a08230a6e6a1ad40d11b90ac22bc43821a747ed5 100644 --- a/kafka-manager-console/src/component/x-form/index.less +++ b/kafka-manager-console/src/component/x-form/index.less @@ -1,4 +1,4 @@ -.ant-input-number { +.ant-input-number, .ant-form-item-children .ant-select { width: 314px } diff --git a/kafka-manager-console/src/constants/left-menu.ts b/kafka-manager-console/src/constants/left-menu.ts index 27fcfe0b898fcb5cdf8313c5bc7870f50d6c7eed..e74526672656bb423c27d2d3f2181e5101e557db 100644 --- a/kafka-manager-console/src/constants/left-menu.ts +++ b/kafka-manager-console/src/constants/left-menu.ts @@ -59,6 +59,10 @@ export const adminMenu = [{ href: `/admin/bill`, i: 'k-icon-renwuliebiao', title: '用户账单', +},{ + href: `/admin/operation-record`, + i: 'k-icon-operationrecord', + title: '操作记录', }] as ILeftMenu[]; export const expertMenu = [{ diff --git a/kafka-manager-console/src/container/admin/cluster-detail/cluster-topic.tsx b/kafka-manager-console/src/container/admin/cluster-detail/cluster-topic.tsx index 7b7aaae741f5cba419f672179194d7960e6d7e22..c2d3aa54667915681b9ea7a9414370c4f4a499b7 100644 --- a/kafka-manager-console/src/container/admin/cluster-detail/cluster-topic.tsx +++ b/kafka-manager-console/src/container/admin/cluster-detail/cluster-topic.tsx @@ -172,7 +172,7 @@ export class ClusterTopic extends SearchAndFilterContainer { key: 'appName', // width: '10%', render: (val: string, record: IClusterTopics) => ( - + {val} ), diff --git a/kafka-manager-console/src/container/admin/cluster-detail/exclusive-cluster.tsx b/kafka-manager-console/src/container/admin/cluster-detail/exclusive-cluster.tsx index 6aaa2e78f020da161ff19fd645b30d709711915e..efc28e683624799e27432d86ceb7354270259d04 100644 --- a/kafka-manager-console/src/container/admin/cluster-detail/exclusive-cluster.tsx +++ b/kafka-manager-console/src/container/admin/cluster-detail/exclusive-cluster.tsx @@ -314,8 +314,7 @@ export class ExclusiveCluster extends SearchAndFilterContainer { >
- 由于该Region已被逻辑集群【 {this.state.logicalClusterName} 】使用 - 请先解除Region与逻辑集群的关系 + 该Region已被逻辑集群【 {this.state.logicalClusterName} 】使用,请先解除Region与逻辑集群的关系
diff --git a/kafka-manager-console/src/container/admin/cluster-detail/index.less b/kafka-manager-console/src/container/admin/cluster-detail/index.less index 0dd4d10632f1a595d9c511010011add3e0edb503..9b5d5103262beaa4b6b2eb3ab2c00c92cef1759a 100644 --- a/kafka-manager-console/src/container/admin/cluster-detail/index.less +++ b/kafka-manager-console/src/container/admin/cluster-detail/index.less @@ -16,7 +16,7 @@ .traffic-table { margin: 10px 0; - min-height: 450px; + min-height: 330px; .traffic-header { width: 100%; height: 44px; diff --git a/kafka-manager-console/src/container/admin/cluster-list/index.tsx b/kafka-manager-console/src/container/admin/cluster-list/index.tsx index dfac45d7f37f010965ebc8e60ad436eb95a933b4..be6956d6e94cb7fb4cc8cc6e0f774e22f56aac81 100644 --- a/kafka-manager-console/src/container/admin/cluster-list/index.tsx +++ b/kafka-manager-console/src/container/admin/cluster-list/index.tsx @@ -4,6 +4,7 @@ import { wrapper } from 'store'; import { observer } from 'mobx-react'; import { IXFormWrapper, IMetaData, IRegister } from 'types/base-type'; import { admin } from 'store/admin'; +import { users } from 'store/users'; import { registerCluster, createCluster, pauseMonitoring } from 'lib/api'; import { SearchAndFilterContainer } from 'container/search-filter'; import { cluster } from 'store/cluster'; @@ -78,34 +79,34 @@ export class ClusterList extends SearchAndFilterContainer { disabled: item ? true : false, }, }, - { - key: 'idc', - label: '数据中心', - defaultValue: region.regionName, - rules: [{ required: true, message: '请输入数据中心' }], - attrs: { - placeholder: '请输入数据中心', - disabled: true, - }, - }, - { - key: 'mode', - label: '集群类型', - type: 'select', - options: cluster.clusterModes.map(ele => { - return { - label: ele.message, - value: ele.code, - }; - }), - rules: [{ - required: true, - message: '请选择集群类型', - }], - attrs: { - placeholder: '请选择集群类型', - }, - }, + // { + // key: 'idc', + // label: '数据中心', + // defaultValue: region.regionName, + // rules: [{ required: true, message: '请输入数据中心' }], + // attrs: { + // placeholder: '请输入数据中心', + // disabled: true, + // }, + // }, + // { + // key: 'mode', + // label: '集群类型', + // type: 'select', + // options: cluster.clusterModes.map(ele => { + // return { + // label: ele.message, + // value: ele.code, + // }; + // }), + // rules: [{ + // required: true, + // message: '请选择集群类型', + // }], + // attrs: { + // placeholder: '请选择集群类型', + // }, + // }, { key: 'kafkaVersion', label: 'kafka版本', @@ -148,7 +149,7 @@ export class ClusterList extends SearchAndFilterContainer { attrs: { placeholder: `请输入JMX认证,例如: { -"maxConn": 10, #KM对单台Broker对最大连接数 +"maxConn": 10, #KM对单台Broker的最大jmx连接数 "username": "xxxxx", #用户名 "password": "xxxxx", #密码 "openSSL": true, #开启SSL,true表示开启SSL,false表示关闭 @@ -276,32 +277,41 @@ export class ClusterList extends SearchAndFilterContainer { public getColumns = () => { const cols = getAdminClusterColumns(); + const role = users.currentUser.role; const col = { title: '操作', render: (value: string, item: IMetaData) => ( <> - 编辑 - - this.pauseMonitor(item)} - cancelText="取消" - okText="确认" - > - + { + role && role === 2 ? <> 编辑 + + this.pauseMonitor(item)} + cancelText="取消" + okText="确认" > - {item.status === 1 ? '暂停监控' : '开始监控'} + + + {item.status === 1 ? '暂停监控' : '开始监控'} + + + + + 删除 - - - - 删除 - + : + 编辑 + {item.status === 1 ? '暂停监控' : '开始监控'} + 删除 + + } ), }; @@ -310,6 +320,7 @@ export class ClusterList extends SearchAndFilterContainer { } public renderClusterList() { + const role = users.currentUser.role; return ( <>
@@ -318,7 +329,14 @@ export class ClusterList extends SearchAndFilterContainer { {this.renderSearch('', '请输入集群名称')}
  • 集群接入指南 - + { + role && role === 2 ? + + : + + + + }
  • diff --git a/kafka-manager-console/src/container/admin/index.tsx b/kafka-manager-console/src/container/admin/index.tsx index 8ae300f086830aae45ee8b8d9844ac38dbc9a286..29c6200aeb037ca277bf503a526c7acc6f422aae 100644 --- a/kafka-manager-console/src/container/admin/index.tsx +++ b/kafka-manager-console/src/container/admin/index.tsx @@ -11,3 +11,5 @@ export * from './operation-management/migration-detail'; export * from './configure-management'; export * from './individual-bill'; export * from './bill-detail'; +export * from './operation-record'; + diff --git a/kafka-manager-console/src/container/admin/operation-record/config.tsx b/kafka-manager-console/src/container/admin/operation-record/config.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c298e4c2f53944b87520767132c17c6fa7752b4e --- /dev/null +++ b/kafka-manager-console/src/container/admin/operation-record/config.tsx @@ -0,0 +1,134 @@ +import * as React from 'react'; +import { cellStyle } from 'constants/table'; + +import { Tooltip } from 'antd'; +import { admin } from 'store/admin'; +import moment = require('moment'); + +const moduleList = [ + { moduleId: 0, moduleName: 'Topic' }, + { moduleId: 1, moduleName: '应用' }, + { moduleId: 2, moduleName: '配额' }, + { moduleId: 3, moduleName: '权限' }, + { moduleId: 4, moduleName: '集群' }, + { moduleId: 5, moduleName: '分区' }, + { moduleId: 6, moduleName: 'Gateway配置' }, +] + +export const operateList = { + 0: '新增', + 1: '删除', + 2: '修改' +} + + +// [ +// { operate: '新增', operateId: 0 }, +// { operate: '删除', operateId: 1 }, +// { operate: '修改', operateId: 2 }, +// ] + +export const getJarFuncForm: any = (props: any) => { + const formMap = [ + { + key: 'moduleId', + label: '模块', + type: 'select', + attrs: { + style: { + width: '130px' + }, + placeholder: '请选择模块', + }, + options: moduleList.map(item => { + return { + label: item.moduleName, + value: item.moduleId + } + }), + formAttrs: { + initialvalue: 0, + }, + }, + { + key: 'operator', + label: '操作人', + type: 'input', + attrs: { + style: { + width: '170px' + }, + placeholder: '请输入操作人' + }, + getvaluefromevent: (event: any) => { + return event.target.value.replace(/\s+/g, '') + }, + }, + // { + // key: 'resource', + // label: '资源名称', + // type: 'input', + // attrs: { + // style: { + // width: '170px' + // }, + // placeholder: '请输入资源名称' + // }, + // }, + // { + // key: 'content', + // label: '操作内容', + // type: 'input', + // attrs: { + // style: { + // width: '170px' + // }, + // placeholder: '请输入操作内容' + // }, + // }, + ] + return formMap; +} +export const getOperateColumns = () => { + + const columns: any = [ + { + title: '模块', + dataIndex: 'module', + key: 'module', + align: 'center', + width: '12%' + }, + { + title: '资源名称', + dataIndex: 'resource', + key: 'resource', + align: 'center', + width: '12%' + }, + { + title: '操作内容', + dataIndex: 'content', + key: 'content', + align: 'center', + width: '25%', + onCell: () => ({ + style: { + maxWidth: 350, + ...cellStyle, + }, + }), + render: (text: string, record: any) => { + return ( + {text}); + }, + }, + { + title: '操作人', + dataIndex: 'operator', + align: 'center', + width: '12%' + }, + ]; + return columns +} \ No newline at end of file diff --git a/kafka-manager-console/src/container/admin/operation-record/index.tsx b/kafka-manager-console/src/container/admin/operation-record/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2b18458c42bfd0d69210883d6a186d19da81b5ce --- /dev/null +++ b/kafka-manager-console/src/container/admin/operation-record/index.tsx @@ -0,0 +1,130 @@ +import * as React from 'react'; +import { observer } from 'mobx-react'; +import { SearchAndFilterContainer } from 'container/search-filter'; +import { IXFormWrapper, IMetaData, IRegister } from 'types/base-type'; +import { admin } from 'store/admin'; +import { customPagination, cellStyle } from 'constants/table'; +import { Table, Tooltip } from 'component/antd'; +import { timeFormat } from 'constants/strategy'; +import { SearchFormComponent } from '../searchForm'; +import { getJarFuncForm, operateList, getOperateColumns } from './config' +import moment = require('moment'); +import { tableFilter } from 'lib/utils'; + +@observer +export class OperationRecord extends SearchAndFilterContainer { + public state: any = { + searchKey: '', + filteredInfo: null, + sortedInfo: null, + }; + + public getData(origin: T[]) { + let data: T[] = origin; + let { searchKey } = this.state; + searchKey = (searchKey + '').trim().toLowerCase(); + + data = searchKey ? origin.filter((item: IMetaData) => + (item.clusterName !== undefined && item.clusterName !== null) && item.clusterName.toLowerCase().includes(searchKey as string), + ) : origin; + return data; + }; + + public searchForm = (params: any) => { + // this.props.setFuncSubValue(params) + // getSystemFuncList(params).then(res => { + // this.props.setSysFuncList(res.data) + // this.props.setPagination(res.pagination) + // }) + const { operator, moduleId } = params || {} + operator ? admin.getOperationRecordData(params) : admin.getOperationRecordData({ moduleId }) + // getJarList(params).then(res => { + // this.props.setJarList(res.data) + // this.props.setPagination(res.pagination) + // }) + } + + public clearAll = () => { + this.setState({ + filteredInfo: null, + sortedInfo: null, + }); + }; + + public setHandleChange = (pagination: any, filters: any, sorter: any) => { + this.setState({ + filteredInfo: filters, + sortedInfo: sorter, + }); + } + + public renderOperationRecordList() { + let { sortedInfo, filteredInfo } = this.state; + sortedInfo = sortedInfo || {}; + filteredInfo = filteredInfo || {}; + const operatingTime = Object.assign({ + title: '操作时间', + dataIndex: 'modifyTime', + key: 'modifyTime', + align: 'center', + sorter: (a: any, b: any) => a.modifyTime - b.modifyTime, + render: (t: number) => moment(t).format(timeFormat), + width: '15%', + sortOrder: sortedInfo.columnKey === 'modifyTime' && sortedInfo.order, + }); + + const operatingPractice = Object.assign({ + title: '行为', + dataIndex: 'operate', + key: 'operate', + align: 'center', + width: '12%', + filters: tableFilter(this.getData(admin.oRList), 'operateId', operateList), + // filteredValue: filteredInfo.operate || null, + onFilter: (value: any, record: any) => { + return record.operateId === value + } + }, this.renderColumnsFilter('modifyTime')) + + const columns = getOperateColumns() + columns.splice(0, 0, operatingTime); + columns.splice(3, 0, operatingPractice); + return ( + <> +
    +
    + this.searchForm(params)} + clearAll={() => this.clearAll()} + isReset={true} + /> +
    +
    +
    + + + + ) + }; + + componentDidMount() { + admin.getOperationRecordData({ moduleId: 0 }); + } + + render() { + return
    + { + this.renderOperationRecordList() + } +
    + } +} \ No newline at end of file diff --git a/kafka-manager-console/src/container/admin/searchForm.tsx b/kafka-manager-console/src/container/admin/searchForm.tsx new file mode 100644 index 0000000000000000000000000000000000000000..afbff03c62c8dc3ff36c0f89b0fb64efd7812488 --- /dev/null +++ b/kafka-manager-console/src/container/admin/searchForm.tsx @@ -0,0 +1,120 @@ +import * as React from 'react'; +import { Select, Input, InputNumber, Form, Switch, Checkbox, DatePicker, Radio, Upload, Button, Icon, Tooltip } from 'component/antd'; +// import './index.less'; +const Search = Input.Search; +export interface IFormItem { + key: string; + label: string; + type: string; + value?: string; + // 内部组件属性注入 + attrs?: any; + // form属性注入 + formAttrs?: any; + defaultValue?: string | number | any[]; + rules?: any[]; + invisible?: boolean; + getvaluefromevent: Function; +} + +interface SerachFormProps { + formMap: IFormItem[]; + // formData: any; + form: any; + onSubmit: Function; + isReset?: boolean; + clearAll: Function; + layout?: 'inline' | 'horizontal' | 'vertical'; +} + +export interface IFormSelect extends IFormItem { + options: Array<{ key?: string | number, value: string | number, label: string }>; +} + +class SearchForm extends React.Component{ + public onSubmit = () => { + // this.props.onSubmit() + // + } + + public renderFormItem(item: IFormItem) { + switch (item.type) { + default: + case 'input': + return ; + case 'select': + return ( + + ); + } + } + + public theQueryClick = (value: any) => { + this.props.onSubmit(value) + this.props.clearAll() + // this.props.form.resetFields() + } + public resetClick = () => { + this.props.form.resetFields() + this.props.clearAll() + this.theQueryClick(this.props.form.getFieldsValue()) + } + + public render() { + const { form, formMap, isReset } = this.props; + const { getFieldDecorator, getFieldsValue } = form; + return ( +
    + { + formMap.map(formItem => { + // const { initialValue, valuePropName } = this.handleFormItem(formItem, formData); + // const getFieldValue = { + // initialValue, + // rules: formItem.rules || [{ required: false, message: '' }], + // valuePropName, + // }; + return ( + + {getFieldDecorator(formItem.key, { + initialValue: formItem.formAttrs?.initialvalue, + getValueFromEvent: formItem?.getvaluefromevent, + })( + this.renderFormItem(formItem), + )} + + ); + }) + } + + { + isReset && + } + + + + ); + } +} +export const SearchFormComponent = Form.create({ name: 'search-form' })(SearchForm); \ No newline at end of file diff --git a/kafka-manager-console/src/container/alarm/add-alarm/filter-form.tsx b/kafka-manager-console/src/container/alarm/add-alarm/filter-form.tsx index 3e5dd0b74546b8077cc3947cca2d43ed43adedd7..fe74e66f9e782a506f907f8b5d0e22a3036a9a73 100644 --- a/kafka-manager-console/src/container/alarm/add-alarm/filter-form.tsx +++ b/kafka-manager-console/src/container/alarm/add-alarm/filter-form.tsx @@ -149,9 +149,9 @@ export class DynamicSetFilter extends React.Component { public handleSelectChange = (e: string, type: 'topic' | 'consumerGroup' | 'location') => { switch (type) { case 'topic': - if (!this.clusterId) { - return message.info('请选择集群'); - } + // if (!this.clusterId) { + // return message.info('请选择集群'); + // } this.topicName = e; const type = this.dealMonitorType(); if (['kafka-consumer-maxLag', 'kafka-consumer-maxDelayTime', 'kafka-consumer-lag'].indexOf(type) > -1) { diff --git a/kafka-manager-console/src/container/app/app-list.tsx b/kafka-manager-console/src/container/app/app-list.tsx index ef897246e4f08cf517a1fd9338da04a3da120cbb..d49b104889aa2ab2d9646818ebda83245dfc02db 100644 --- a/kafka-manager-console/src/container/app/app-list.tsx +++ b/kafka-manager-console/src/container/app/app-list.tsx @@ -52,8 +52,7 @@ export class CommonAppList extends SearchAndFilterContainer { }, }), render: (text: string, record: IAppItem) => { - return ( - {text}); + return ({text}); }, }, { @@ -103,7 +102,7 @@ export class CommonAppList extends SearchAndFilterContainer { } public getOnlineConnect(record: IAppItem) { - modal.showOfflineAppModal(record.appId); + modal.showOfflineAppNewModal(record.appId); } public getData(origin: T[]) { @@ -114,7 +113,7 @@ export class CommonAppList extends SearchAndFilterContainer { data = searchKey ? origin.filter((item: IAppItem) => ((item.name !== undefined && item.name !== null) && item.name.toLowerCase().includes(searchKey as string)) || ((item.principals !== undefined && item.principals !== null) && item.principals.toLowerCase().includes(searchKey as string)) || - ((item.appId !== undefined && item.appId !== null) && item.appId.toLowerCase().includes(searchKey as string)) ) : origin; + ((item.appId !== undefined && item.appId !== null) && item.appId.toLowerCase().includes(searchKey as string))) : origin; return data; } diff --git a/kafka-manager-console/src/container/cluster/my-cluster.tsx b/kafka-manager-console/src/container/cluster/my-cluster.tsx index e017b0ddcaa2550cb2af0a3f9349abe9c9e0fd87..3cb6115f4245b3800031bda51f9606b952b152ac 100644 --- a/kafka-manager-console/src/container/cluster/my-cluster.tsx +++ b/kafka-manager-console/src/container/cluster/my-cluster.tsx @@ -29,16 +29,16 @@ export class MyCluster extends SearchAndFilterContainer { public applyCluster() { const xFormModal = { formMap: [ - { - key: 'idc', - label: '数据中心', - defaultValue: region.regionName, - rules: [{ required: true, message: '请输入数据中心' }], - attrs: { - placeholder: '请输入数据中心', - disabled: true, - }, - }, + // { + // key: 'idc', + // label: '数据中心', + // defaultValue: region.regionName, + // rules: [{ required: true, message: '请输入数据中心' }], + // attrs: { + // placeholder: '请输入数据中心', + // disabled: true, + // }, + // }, { key: 'appId', label: '所属应用', diff --git a/kafka-manager-console/src/container/expert/topic-governance/index.tsx b/kafka-manager-console/src/container/expert/topic-governance/index.tsx index 21bd9b1022468f2d8598691f7158ff9ac0843514..b495e2f8a590f15911282509fe820a4c7d85eae2 100644 --- a/kafka-manager-console/src/container/expert/topic-governance/index.tsx +++ b/kafka-manager-console/src/container/expert/topic-governance/index.tsx @@ -133,15 +133,15 @@ export class GovernanceTopic extends SearchAndFilterContainer { width: '30%', sorter: (a: IResource, b: IResource) => a.topicName.charCodeAt(0) - b.topicName.charCodeAt(0), render: (text: string, item: IResource) => - ( - - - {text} - - ), + ( + + + {text} + + ), }, { title: '所在集群', @@ -215,7 +215,7 @@ export class GovernanceTopic extends SearchAndFilterContainer { return ( <> - {this.pendingTopic(this.getData(expert.resourceData))} + {this.pendingTopic(this.getData(expert.resourceData))} ); } diff --git a/kafka-manager-console/src/container/header/index.less b/kafka-manager-console/src/container/header/index.less index 98aefd9988a0ea0129cee7338dfa7e692391ce2e..53301a9204fe1b90af43a81380ca88b924638867 100644 --- a/kafka-manager-console/src/container/header/index.less +++ b/kafka-manager-console/src/container/header/index.less @@ -16,6 +16,14 @@ line-height: 64px; vertical-align: middle; } + .kafka-header-version{ + display: inline-block; + vertical-align: middle; + padding-top:5px; + font-size: 12px; + margin-left:10px; + color:#a0a0a0; + } } .mid-content { diff --git a/kafka-manager-console/src/container/header/index.tsx b/kafka-manager-console/src/container/header/index.tsx index e86bcf116181a04173afe2873009906c182fdd1d..ebda97600b36a835b820ce53ea73fd6ac539b18c 100644 --- a/kafka-manager-console/src/container/header/index.tsx +++ b/kafka-manager-console/src/container/header/index.tsx @@ -145,6 +145,8 @@ export const Header = observer((props: IHeader) => {
    Kafka Manager + v2.4.0 + {/* 添加版本超链接 */}
    {headerMenu.map((item: IMenuItem, index: number) => diff --git a/kafka-manager-console/src/container/modal/admin/cluster.ts b/kafka-manager-console/src/container/modal/admin/cluster.ts index 20ed909849e5e3858c74756b57c192c65a20a9e8..ac4af3a55552bbe77f3f74e7bafe4898d54bafde 100644 --- a/kafka-manager-console/src/container/modal/admin/cluster.ts +++ b/kafka-manager-console/src/container/modal/admin/cluster.ts @@ -22,11 +22,11 @@ export const showEditClusterTopic = (item: IClusterTopics) => { }, { key: 'appId', - label: '应用ID', + label: '应用名称', type: 'select', options: app.adminAppData.map(item => { return { - label: item.appId, + label: item.name, value: item.appId, }; }), @@ -61,7 +61,7 @@ export const showEditClusterTopic = (item: IClusterTopics) => { attrs: { placeholder: '请输入保存时间', suffix: '小时', - prompttype:'修改保存时间,预计一分钟左右生效!' + prompttype: '修改保存时间,预计一分钟左右生效!' }, }, { diff --git a/kafka-manager-console/src/container/modal/admin/confirm-detail-topic.tsx b/kafka-manager-console/src/container/modal/admin/confirm-detail-topic.tsx index 41f6ed61a5b50af6a82e27a4cb160bc8f1375d0c..83d1b02d21a52f5f9d813b555688c6944297d615 100644 --- a/kafka-manager-console/src/container/modal/admin/confirm-detail-topic.tsx +++ b/kafka-manager-console/src/container/modal/admin/confirm-detail-topic.tsx @@ -35,7 +35,6 @@ class CustomForm extends React.Component { this.props.form.validateFields((err: any, values: any) => { const deleteData = this.props.formData; if (!err) { - // console.log('values', values); if (values.topicName !== this.props.formData.topicName) { notification.error({ message: 'topic名称不正确,请重新输入' }); } else { @@ -77,7 +76,6 @@ class CustomForm extends React.Component { } public render() { - // console.log('props', this.props); const { formData = {} as any, visible } = this.props; const { getFieldDecorator } = this.props.form; let metadata = [] as IBrokersMetadata[]; diff --git a/kafka-manager-console/src/container/modal/admin/expand-partition.tsx b/kafka-manager-console/src/container/modal/admin/expand-partition.tsx index dfb51ba9ed88a7cf0331df9551386238d0339137..44001081c43084a366c5109da2e40f90d010731a 100644 --- a/kafka-manager-console/src/container/modal/admin/expand-partition.tsx +++ b/kafka-manager-console/src/container/modal/admin/expand-partition.tsx @@ -111,11 +111,11 @@ class CustomForm extends React.Component { })()} - {/* */} + {/* */} {/* this.onSwitchChange(checked)} /> */} { this.onSwitchChange(e.target.value === 'region' ? true : false); }}> Region类型 - Borker类型 + Broker类型 diff --git a/kafka-manager-console/src/container/modal/admin/task.ts b/kafka-manager-console/src/container/modal/admin/task.ts index d9a609acffa66fe88e542f8f8c8c4125743c1c26..12a46d53f5bcae51dfe9929870c4af6453bf6d47 100644 --- a/kafka-manager-console/src/container/modal/admin/task.ts +++ b/kafka-manager-console/src/container/modal/admin/task.ts @@ -28,8 +28,8 @@ const updateInputModal = (status?: string) => { formMap[4].invisible = status === 'region'; formMap[5].invisible = status !== 'region'; - formMap[4].rules = [{required: status !== 'region'}]; - formMap[5].rules = [{required: status === 'region'}]; + formMap[4].rules = [{ required: status !== 'region' }]; + formMap[5].rules = [{ required: status === 'region' }]; // tslint:disable-next-line:no-unused-expression wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData); }; @@ -103,7 +103,7 @@ export const createMigrationTasks = () => { label: 'Region', value: 'region', }, { - label: 'Borker', + label: 'Broker', value: 'broker', }], rules: [{ @@ -141,7 +141,7 @@ export const createMigrationTasks = () => { placeholder: '请选择目标Region', }, }, - + { key: 'beginTime', label: '计划开始时间', diff --git a/kafka-manager-console/src/container/modal/offline-app-modal-new.tsx b/kafka-manager-console/src/container/modal/offline-app-modal-new.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2b582f7797c82965cadea2c441b5881bbcb7692b --- /dev/null +++ b/kafka-manager-console/src/container/modal/offline-app-modal-new.tsx @@ -0,0 +1,78 @@ +import * as React from 'react'; +import { Table, Modal, Tooltip, Icon, message, notification, Alert, Button } from 'component/antd'; +import { app } from 'store/app'; +import { getApplyOnlineColumns } from 'container/topic/config'; +import { observer } from 'mobx-react'; +import { modal } from 'store/modal'; +import { users } from 'store/users'; +import { urlPrefix } from 'constants/left-menu'; +import { region } from 'store'; + +@observer +export class ConnectAppNewList extends React.Component { + + public componentDidMount() { + app.getAppsConnections(modal.params); + } + + public handleCancel = () => { + app.setAppsConnections([]); + modal.close(); + } + + public handleSubmit = () => { + const connectionList = app.appsConnections; + if (connectionList && connectionList.length) { + return message.warning('存在连接信息,无法申请下线!'); + } + const offlineParams = { + type: 11, + applicant: users.currentUser.username, + description: '', + extensions: JSON.stringify({ appId: modal.params }), + }; + app.applyAppOffline(offlineParams).then((data: any) => { + notification.success({ message: '申请下线成功' }); + window.location.href = `${urlPrefix}/user/order-detail/?orderId=${data.id}®ion=${region.currentRegion}`; + }); + modal.close(); + } + + public render() { + const connectionList = app.appsConnections; + return ( + <> + 确定 + : + <> + + + + } + width={500} + > +
    + { + connectionList && connectionList.length + ? + 该应用已与Topic关联,请先解除应用与Topic之间的关系。点击查看 + : + 应用下线后,AppID、密钥将会失效,请谨慎操作! + } +
    +
    + + ); + } +} diff --git a/kafka-manager-console/src/container/modal/order.tsx b/kafka-manager-console/src/container/modal/order.tsx index c982db4c7fa700a2e7a29e46a83e711c84587853..ac2a82b7df6843b0c445e48778c81d9da100e5ae 100644 --- a/kafka-manager-console/src/container/modal/order.tsx +++ b/kafka-manager-console/src/container/modal/order.tsx @@ -4,6 +4,7 @@ import { message, Icon, notification, Modal, Table, Tooltip } from 'component/an import { IApprovalOrder, IBaseOrder, IOrderInfo } from 'types/base-type'; import { admin } from 'store/admin'; import { modal } from 'store/modal'; +import { cluster } from 'store/cluster'; import { cellStyle } from 'constants/table'; import * as React from 'react'; @@ -37,6 +38,12 @@ const renderModalTilte = (type: number, status: number) => { export const showApprovalModal = (info: IOrderInfo, status: number, from?: string) => { const { id, type } = info; const formMap = [{ + key: 'clusterId', + label: '所属集群', + type: 'input_number', + defaultValue: info.detail.logicalClusterName, + attrs: { disabled: true }, + }, { key: 'partitionNum', label: '分区数', type: 'input_number', @@ -87,7 +94,7 @@ export const showApprovalModal = (info: IOrderInfo, status: number, from?: strin label: 'Region', value: 'region', }, { - label: 'Borker', + label: 'Broker', value: 'broker', }], rules: [{ required: false, message: '请选择类型' }], diff --git a/kafka-manager-console/src/container/modal/topic.tsx b/kafka-manager-console/src/container/modal/topic.tsx index d4df03180dedbbb121da4d87fbc41a7b538c23eb..4e02664179f0d712b14f77b6a3634a0e40b4b09e 100644 --- a/kafka-manager-console/src/container/modal/topic.tsx +++ b/kafka-manager-console/src/container/modal/topic.tsx @@ -399,8 +399,8 @@ export const updateAllTopicFormModal = () => { const formMap = wrapper.xFormWrapper.formMap; if (topic.authorities) { const { consume, send, checkStatus } = judgeAccessStatus(topic.authorities.access); - formMap[3].defaultValue = checkStatus; - formMap[3].options = [{ + formMap[2].defaultValue = checkStatus; + formMap[2].options = [{ label: `消费权限${consume ? '(已拥有)' : ''}`, value: '1', disabled: consume, @@ -409,7 +409,7 @@ export const updateAllTopicFormModal = () => { value: '2', disabled: send, }]; - formMap[3].rules = [{ + formMap[2].rules = [{ required: true, validator: (rule: any, value: any, callback: any) => getPowerValidator(rule, value, callback, checkStatus, 'allTopic'), }]; @@ -476,7 +476,6 @@ export const showAllPermissionModal = (item: ITopic) => { const showAllPermission = (appId: string, item: ITopic, access: number) => { const { consume, send, checkStatus } = judgeAccessStatus(access); - const xFormModal = { formMap: [ { @@ -489,16 +488,6 @@ const showAllPermission = (appId: string, item: ITopic, access: number) => { disabled: true, }, }, - { - key: 'clusterName', - label: '集群名称', - defaultValue: item.clusterName, - rules: [{ required: true, message: '请输入集群名称' }], - attrs: { - placeholder: '请输入集群名称', - disabled: true, - }, - }, { key: 'appId', label: '绑定应用', @@ -526,6 +515,26 @@ const showAllPermission = (appId: string, item: ITopic, access: number) => { validator: (rule: any, value: any, callback: any) => getPowerValidator(rule, value, callback, checkStatus, 'allTopic'), }], }, + // { + // key: 'clusterName', + // label: '集群名称', + // defaultValue: item.clusterName, + // rules: [{ required: true, message: '请输入集群名称' }], + // attrs: { + // placeholder: '请输入集群名称', + // disabled: true, + // }, + // }, + // { + // key: 'clusterName', + // label: '集群名称', + // defaultValue: item.clusterName, + // rules: [{ required: true, message: '请输入集群名称' }], + // attrs: { + // placeholder: '请输入集群名称', + // disabled: true, + // }, + // }, { key: 'description', label: '申请原因', @@ -587,16 +596,16 @@ export const showPermissionModal = (item: ITopic) => { disabled: true, }, }, - { - key: 'clusterName', - label: '集群名称', - defaultValue: item.clusterName, - rules: [{ required: true, message: '请输入集群名称' }], - attrs: { - placeholder: '请输入集群名称', - disabled: true, - }, - }, + // { + // key: 'clusterName', + // label: '集群名称', + // defaultValue: item.clusterName, + // rules: [{ required: true, message: '请输入集群名称' }], + // attrs: { + // placeholder: '请输入集群名称', + // disabled: true, + // }, + // }, { key: 'appName', label: '绑定应用', diff --git a/kafka-manager-console/src/container/search-filter.tsx b/kafka-manager-console/src/container/search-filter.tsx index ac5d6bc1368c21f719d9a7bd5f807f5ddffb2b62..6c199ab3e045f520cfe3da3cdae2b225748f9b40 100644 --- a/kafka-manager-console/src/container/search-filter.tsx +++ b/kafka-manager-console/src/container/search-filter.tsx @@ -194,7 +194,7 @@ export class SearchAndFilterContainer extends React.Component { + public renderColumnsFilter = (type: string, params?: any) => { return { filterIcon: this.renderFilterIcon.bind(null, type), filterDropdownVisible: this.state[type] as boolean, diff --git a/kafka-manager-console/src/container/staff-select.tsx b/kafka-manager-console/src/container/staff-select.tsx index e9072569708ebe6d9378dbb30d38e8165603ca5f..f01637e9f58631f45fe03ef95106fe4a964cc4fd 100644 --- a/kafka-manager-console/src/container/staff-select.tsx +++ b/kafka-manager-console/src/container/staff-select.tsx @@ -28,7 +28,8 @@ export class StaffSelect extends React.Component { public getStaffList = () => { const { value } = this.props; const current = users.currentUser.username || getCookie('username'); - const principals = value || (current ? [current] : []); + const principals = ['']; + // const principals = value || (current ? [current] : []); const promises: any[] = []; for (const item of principals) { @@ -64,7 +65,6 @@ export class StaffSelect extends React.Component { const { value, isDisabled } = this.props; const current = users.currentUser.username || getCookie('username'); const principals = value || (current ? [current] : []); - return ( +