From 447a575f4f64bc19851484deda8e506f98343899 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Sat, 19 Dec 2020 00:40:52 +0800 Subject: [PATCH] v2.1 fe --- kafka-manager-console/package.json | 6 + kafka-manager-console/pom.xml | 5 +- .../src/component/antd/index.tsx | 7 + .../src/component/editor/editor.tsx | 68 +++++++ .../src/component/editor/index.less | 31 ++++ .../src/component/editor/index.tsx | 50 +++++ .../src/component/editor/monacoEditor.tsx | 77 ++++++++ .../src/component/x-form-wrapper/index.tsx | 16 +- .../src/component/x-form/index.tsx | 8 +- .../src/constants/strategy.ts | 5 +- .../admin/cluster-detail/cluster-broker.tsx | 2 + .../admin/cluster-detail/cluster-consumer.tsx | 56 +++--- .../cluster-detail/cluster-controller.tsx | 20 +- .../admin/cluster-detail/cluster-overview.tsx | 10 +- .../admin/cluster-detail/cluster-topic.tsx | 100 ++++++++-- .../cluster-detail/exclusive-cluster.tsx | 78 ++++++-- .../container/admin/cluster-detail/index.less | 13 ++ .../admin/cluster-detail/logical-cluster.tsx | 77 ++++++-- .../container/admin/cluster-list/index.tsx | 24 ++- .../src/container/admin/config.tsx | 50 ++--- .../container/admin/configure-management.tsx | 8 +- .../admin/operation-detail/essential-info.tsx | 4 +- .../admin/operation-detail/index.tsx | 6 + .../operation-detail/taskStatus-details.tsx | 4 +- .../operation-management/cluster-task.tsx | 6 +- .../admin/operation-management/config.tsx | 4 + .../operation-management/migration-detail.tsx | 2 +- .../container/admin/version-management.tsx | 4 +- .../src/container/alarm/add-alarm/config.tsx | 14 +- .../container/alarm/add-alarm/filter-form.tsx | 2 +- .../src/container/alarm/add-alarm/index.less | 13 +- .../alarm/alarm-detail/shield-history.tsx | 2 + .../src/container/app-select.tsx | 16 +- .../src/container/app/app-detail.tsx | 61 +++--- .../cluster-detail/cluster-overview.tsx | 39 ++-- .../cluster/cluster-detail/cluster-topic.tsx | 1 + .../src/container/cluster/config.tsx | 43 ++++- .../src/container/header/index.less | 21 ++- .../src/container/header/index.tsx | 38 ++-- .../src/container/modal/admin/cluster.ts | 99 +++++++--- .../modal/admin/confirm-detail-topic.tsx | 173 ++++++++++++++++++ .../modal/admin/expand-partition.tsx | 37 +++- .../modal/admin/leader-rebalance.tsx | 52 ++++-- .../src/container/modal/admin/migration.ts | 82 +++++---- .../src/container/modal/admin/task.ts | 49 ++--- .../src/container/modal/admin/user.ts | 3 + .../src/container/modal/admin/version.ts | 18 +- .../src/container/modal/app.tsx | 39 ++-- .../modal/cancel-topic-permission.tsx | 4 +- .../container/modal/connect-topic-list.tsx | 5 +- .../src/container/modal/offline-app-modal.tsx | 5 +- .../container/modal/offline-cluster-modal.tsx | 2 +- .../src/container/modal/order.tsx | 49 ++--- .../modal/render-order-op-result.tsx | 2 +- .../src/container/modal/topic.tsx | 44 +++-- .../src/container/network-flow.tsx | 26 +-- .../src/container/search-filter.tsx | 34 ++-- .../src/container/topic/config.tsx | 13 +- .../src/container/topic/peak-flow.tsx | 3 +- .../src/container/topic/topic-all.tsx | 2 +- .../topic/topic-detail/appid-information.tsx | 35 +++- .../topic/topic-detail/base-information.tsx | 23 ++- .../topic/topic-detail/common-detail.tsx | 46 ++--- .../topic-detail/connect-information.tsx | 4 +- .../container/topic/topic-detail/index.less | 10 + .../container/topic/topic-detail/index.tsx | 62 ++++--- .../topic/topic-detail/status-chart.tsx | 4 +- .../src/container/user-center/my-approval.tsx | 78 +++++--- .../src/container/user-center/order-list.tsx | 13 +- kafka-manager-console/src/lib/api.ts | 26 +-- .../src/lib/bar-pie-config.ts | 3 +- kafka-manager-console/src/routers/index.tsx | 1 + .../src/routers/page/index.less | 7 + kafka-manager-console/src/store/admin.ts | 4 +- kafka-manager-console/src/store/order.ts | 12 ++ kafka-manager-console/src/store/region.ts | 4 +- kafka-manager-console/src/store/topic.ts | 6 +- kafka-manager-console/src/store/version.ts | 5 +- kafka-manager-console/src/store/wrapper.ts | 1 + kafka-manager-console/src/styles/style.less | 15 ++ .../src/styles/table-filter.less | 2 +- kafka-manager-console/src/types/base-type.ts | 8 +- kafka-manager-console/webpack.config.js | 36 ++-- 83 files changed, 1578 insertions(+), 559 deletions(-) create mode 100644 kafka-manager-console/src/component/editor/editor.tsx create mode 100644 kafka-manager-console/src/component/editor/index.less create mode 100644 kafka-manager-console/src/component/editor/index.tsx create mode 100644 kafka-manager-console/src/component/editor/monacoEditor.tsx create mode 100644 kafka-manager-console/src/container/modal/admin/confirm-detail-topic.tsx create mode 100644 kafka-manager-console/src/styles/style.less diff --git a/kafka-manager-console/package.json b/kafka-manager-console/package.json index b823bf3d..f06c4120 100644 --- a/kafka-manager-console/package.json +++ b/kafka-manager-console/package.json @@ -33,6 +33,8 @@ "mobx": "^5.9.4", "mobx-react": "^5.4.3", "moment": "^2.24.0", + "monaco-editor": "^0.20.0", + "monaco-editor-webpack-plugin": "^1.9.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "react": "^16.8.4", "react-hot-loader": "^4.8.4", @@ -45,9 +47,13 @@ "tslint": "^5.13.1", "tslint-react": "^3.6.0", "typescript": "^3.3.3333", + "url-loader": "^4.1.1", "webpack": "^4.29.6", "webpack-cli": "^3.2.3", "webpack-dev-server": "^3.2.1", "xlsx": "^0.16.1" + }, + "dependencies": { + "format-to-json": "^1.0.4" } } diff --git a/kafka-manager-console/pom.xml b/kafka-manager-console/pom.xml index 81b4e933..e8f6295b 100644 --- a/kafka-manager-console/pom.xml +++ b/kafka-manager-console/pom.xml @@ -28,9 +28,10 @@ install-node-and-npm - v8.12.0 - 6.4.1 + v12.20.0 + 6.14.8 http://npm.taobao.org/mirrors/node/ + https://registry.npm.taobao.org/npm/-/ diff --git a/kafka-manager-console/src/component/antd/index.tsx b/kafka-manager-console/src/component/antd/index.tsx index 41efdea5..2d771efe 100644 --- a/kafka-manager-console/src/component/antd/index.tsx +++ b/kafka-manager-console/src/component/antd/index.tsx @@ -48,6 +48,9 @@ import 'antd/es/notification/style'; import Tooltip from 'antd/es/tooltip'; import 'antd/es/tooltip/style'; +import Popover from 'antd/es/popover'; +import 'antd/es/popover/style'; + import Radio from 'antd/es/radio'; import 'antd/es/radio'; import { RadioChangeEvent } from 'antd/es/radio'; @@ -97,6 +100,9 @@ import 'antd/es/time-picker/style'; import Badge from 'antd/es/badge'; import 'antd/es/badge/style'; +import Progress from 'antd/es/progress'; +import 'antd/es/progress/style'; + import { RangePickerValue } from 'antd/es/date-picker/interface'; export { @@ -136,4 +142,5 @@ export { TimePicker, RangePickerValue, Badge, + Popover }; diff --git a/kafka-manager-console/src/component/editor/editor.tsx b/kafka-manager-console/src/component/editor/editor.tsx new file mode 100644 index 00000000..cf86f2c7 --- /dev/null +++ b/kafka-manager-console/src/component/editor/editor.tsx @@ -0,0 +1,68 @@ +// import * as React from 'react'; +// import CodeMirror from 'codemirror/lib/codemirror'; +// import 'codemirror/lib/codemirror.css'; +// import 'codemirror/mode/sql/sql'; +// import 'codemirror/mode/javascript/javascript'; +// import 'codemirror/addon/hint/show-hint.js'; +// import 'codemirror/addon/hint/sql-hint.js'; +// import 'codemirror/addon/hint/show-hint.css'; +// import './index.less'; +// import { indexStore } from 'store/my-index'; + +// interface IProps { +// value?: string; +// placeholder?: string; +// readOnly?: boolean; +// } +// export class CodeMirrorEditor extends React.Component { + +// public editor = null as any; + +// public handleCodeFocus = () => { +// // tslint:disable-next-line:no-unused-expression +// this.editor && this.editor.focus(); +// } + +// public componentDidMount() { +// const { value, placeholder, readOnly } = this.props; +// const code = document.querySelector('.codemirror'); +// code.innerHTML = ''; +// const editor = CodeMirror(document.querySelector('.codemirror'), { +// mode: 'application/json', +// indentWithTabs: true, +// smartIndent: true, +// lineNumbers: true, +// matchBrackets: true, +// autoCloseBrackets: true, +// styleSelectedText: true, +// foldGutter: true, +// readOnly, +// extraKeys: readOnly ? {} : { +// 'Ctrl-Enter': 'autocomplete', +// 'Tab': (cm) => { +// const spaces = Array(cm.getOption('indentUnit') + 1).join(' '); +// cm.replaceSelection(spaces); +// }, +// }, +// placeholder, +// }); +// editor.setValue(value || ''); +// indexStore.setCodeEditorValue(value || ''); +// editor.on('changes', (a: any) => { +// const data = a.getValue(); +// indexStore.setCodeEditorValue(data); +// }); +// this.editor = editor; +// } + +// public render() { +// return ( +//
+//
+//
+// ); +// } +// } diff --git a/kafka-manager-console/src/component/editor/index.less b/kafka-manager-console/src/component/editor/index.less new file mode 100644 index 00000000..4ff05854 --- /dev/null +++ b/kafka-manager-console/src/component/editor/index.less @@ -0,0 +1,31 @@ +.editor { + height: 100%; +} + +.CodeMirror-placeholder { + color:#999; + font-size: 12px; + line-height: 14px; + font-family: -apple-system,BlinkMacSystemFont,Neue Haas Grotesk Text Pro,Arial Nova,Segoe UI,Helvetica Neue,\.PingFang SC,PingFang SC,Microsoft YaHei,Microsoft JhengHei,Source Han Sans SC,Noto Sans CJK SC,Source Han Sans CN,Noto Sans SC,Source Han Sans TC,Noto Sans CJK TC,Hiragino Sans GB,sans-serif; +} +.editor-wrap { + max-height: 100%; +} + +.CodeMirror { + height: 100vh; +} + +.monacoEditor{ + height: 150px; + position: relative; + overflow: hidden; + border: 1px solid #cccccc; + border-radius: 4px; + .editor{ + height: 100%; + position: absolute; + left: -14%; + width: 120%; + } +} diff --git a/kafka-manager-console/src/component/editor/index.tsx b/kafka-manager-console/src/component/editor/index.tsx new file mode 100644 index 00000000..6f605b9c --- /dev/null +++ b/kafka-manager-console/src/component/editor/index.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import * as monaco from 'monaco-editor'; + +import './index.less'; + +export interface IEditorProps { + style?: React.CSSProperties; + options: monaco.editor.IStandaloneEditorConstructionOptions; + uri?: monaco.Uri; + autoUnmount?: boolean; + customMount?: (editor: monaco.editor.IStandaloneCodeEditor, monaco: any) => any; + placeholder?: string; +} + +export class EditorCom extends React.Component { + public ref: HTMLElement = null; + public editor: monaco.editor.IStandaloneCodeEditor; + public state = { + placeholder: this.props.placeholder ?? '', + }; + + public componentWillUnmount() { + if (this.props.autoUnmount === false) return; + const model = this.editor.getModel(); + model.dispose(); + this.editor.dispose(); + } + + public componentDidMount() { + const { customMount, options, uri } = this.props; + const { value, language } = options; + if (uri) { + options.model = monaco.editor.createModel(value, language, uri); + } + + this.editor = monaco.editor.create(this.ref, + options, + ); + if (customMount) customMount(this.editor, monaco); + } + + public render() { + const { style } = this.props; + return ( + <> +
{ this.ref = id; }} /> + + ); + } +} diff --git a/kafka-manager-console/src/component/editor/monacoEditor.tsx b/kafka-manager-console/src/component/editor/monacoEditor.tsx new file mode 100644 index 00000000..7a0dd44c --- /dev/null +++ b/kafka-manager-console/src/component/editor/monacoEditor.tsx @@ -0,0 +1,77 @@ +import * as React from 'react'; +import * as monaco from 'monaco-editor'; +import format2json from 'format-to-json'; +import { Input } from 'component/antd'; +import './index.less'; + +export interface IEditorProps { + style?: React.CSSProperties; + options: monaco.editor.IStandaloneEditorConstructionOptions; + uri?: monaco.Uri; + autoUnmount?: boolean; + customMount?: (editor: monaco.editor.IStandaloneCodeEditor, monaco: any) => any; + placeholder?: string; + value: ''; + onChange?: any; +} + +class Monacoeditor extends React.Component { + public ref: HTMLElement = null; + public editor: monaco.editor.IStandaloneCodeEditor; + public state = { + placeholder: '', + }; + // public arr = '{"clusterId":95,"startId":37397856,"step":100,"topicName":"kmo_topic_metrics_tempory_zq"}'; + // public Ars(a: string) { + // const obj = JSON.parse(a); + // const newobj: any = {}; + // for (const item in obj) { + // if (typeof obj[item] === 'object') { + // this.Ars(obj[item]); + // } else { + // newobj[item] = obj[item]; + // } + // } + // return JSON.stringify(newobj); + // } + public async componentDidMount() { + const { value, onChange } = this.props; + const format: any = await format2json(value); + this.editor = monaco.editor.create(this.ref, { + value: format.result, + language: 'json', + lineNumbers: 'off', + scrollBeyondLastLine: false, + // selectOnLineNumbers: true, + // roundedSelection: false, + // readOnly: true, + minimap: { + enabled: false, + }, + // automaticLayout: true, // 自动布局 + glyphMargin: true, // 字形边缘 {},[] + // useTabStops: false, + // formatOnPaste: true, + // mode: 'application/json', + // indentWithTabs: true, + // smartIndent: true, + // matchBrackets: 'always', + // autoCloseBrackets: true, + // styleSelectedText: true, + // foldGutter: true, + }); + this.editor.onDidChangeModelContent((e) => { + const newValue = this.editor.getValue(); + onChange(newValue); + }); + } + public render() { + return ( +
+ +
{ this.ref = id; }} /> +
+ ); + } +} +export default Monacoeditor; diff --git a/kafka-manager-console/src/component/x-form-wrapper/index.tsx b/kafka-manager-console/src/component/x-form-wrapper/index.tsx index 3fbaee5e..e39f3ef4 100755 --- a/kafka-manager-console/src/component/x-form-wrapper/index.tsx +++ b/kafka-manager-console/src/component/x-form-wrapper/index.tsx @@ -2,13 +2,13 @@ import * as React from 'react'; import { Drawer, Modal, Button, message } from 'component/antd'; import { XFormComponent } from 'component/x-form'; import { IXFormWrapper } from 'types/base-type'; +import { wrapper } from 'store'; export class XFormWrapper extends React.Component { - public state = { confirmLoading: false, formMap: this.props.formMap || [] as any, - formData: this.props.formData || {}, + formData: this.props.formData || {} }; private $formRef: any; @@ -108,7 +108,7 @@ export class XFormWrapper extends React.Component { if (error) { return; } - const { onSubmit, isWaitting } = this.props; + const { onSubmit, isWaitting, onSubmitFaild } = this.props; if (typeof onSubmit === 'function') { if (isWaitting) { @@ -116,12 +116,16 @@ export class XFormWrapper extends React.Component { confirmLoading: true, }); onSubmit(result).then(() => { - this.setState({ - confirmLoading: false, - }); message.success('操作成功'); this.resetForm(); this.closeModalWrapper(); + }).catch((err: any) => { + const { formMap, formData } = wrapper.xFormWrapper; + onSubmitFaild(err, this.$formRef, formData, formMap); + }).finally(() => { + this.setState({ + confirmLoading: false, + }); }); return; } diff --git a/kafka-manager-console/src/component/x-form/index.tsx b/kafka-manager-console/src/component/x-form/index.tsx index 0e4047f4..20b7c421 100755 --- a/kafka-manager-console/src/component/x-form/index.tsx +++ b/kafka-manager-console/src/component/x-form/index.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Select, Input, InputNumber, Form, Switch, Checkbox, DatePicker, Radio, Upload, Button, Icon, Tooltip } from 'component/antd'; +import Monacoeditor from 'component/editor/monacoEditor'; import { searchProps } from 'constants/table'; import './index.less'; @@ -19,6 +20,7 @@ export enum FormItemType { rangePicker = 'range_picker', radioGroup = 'radio_group', upload = 'upload', + monacoEditor = 'monaco_editor', } export interface IFormItem { @@ -105,13 +107,11 @@ class XForm extends React.Component {
({})}> {formMap.map(formItem => { const { initialValue, valuePropName } = this.handleFormItem(formItem, formData); - const getFieldValue = { initialValue, rules: formItem.rules || [{ required: false, message: '' }], valuePropName, }; - if (formItem.type === FormItemType.upload) { Object.assign(getFieldValue, { getValueFromEvent: this.onUploadFileChange, @@ -137,7 +137,6 @@ class XForm extends React.Component { } public renderFormItem(item: IFormItem) { - switch (item.type) { default: case FormItemType.input: @@ -148,6 +147,9 @@ class XForm extends React.Component { return ; case FormItemType.textArea: return