diff --git a/.babelrc b/.babelrc index 4e907cb9..e058a20b 100644 --- a/.babelrc +++ b/.babelrc @@ -28,12 +28,8 @@ "legacy": true } ], - ["@babel/plugin-proposal-class-properties", - { - "loose": true - } - ], + "@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", - "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-syntax-dynamic-import" ] } diff --git a/.eslintrc.js b/.eslintrc.js index 6d9c20c2..ee6ddf35 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,49 +1,317 @@ module.exports = { - extends: ['airbnb', 'prettier', 'prettier/react'], - parser: 'babel-eslint', - root: true, env: { browser: true, - es6: true + es6: true, + node: true + }, + extends: [ + 'plugin:react/recommended', + 'prettier', + 'prettier/@typescript-eslint', + ], + ignorePatterns: [ + 'coverage', + 'coverage', + 'coverage' + ], + parser: '@typescript-eslint/parser', + parserOptions: { + 'project': ['./tsconfig.json'], + 'tsconfigRootDir': __dirname, + 'sourceType': 'module' + }, + plugins: [ + 'eslint-plugin-react', + 'eslint-plugin-import', + 'eslint-plugin-jsdoc', + 'eslint-plugin-prefer-arrow', + '@typescript-eslint', + 'prettier', + ], + settings: { + react: { + version: 'detect' + } }, - plugins: ['react', 'import', 'prettier'], rules: { - 'jsx-a11y/anchor-is-valid': [ - 'error', - { - components: ['Link'], - specialLink: ['to'] - } - ], // 允许正常使用 Link - 'jsx-a11y/interactive-supports-focus': 0, - 'jsx-a11y/click-events-have-key-events': 0, - 'no-static-element-interactions': 0, - 'react/jsx-filename-extension': [1, { - extensions: ['.js', '.jsx'] - }], //允许在 .js 后缀文件中写 jsx - 'react/destructuring-assignment': 0, // 不强制对 state props 使用解构赋值 - 'react/forbid-prop-types': 0, // 不禁止使用一些指定的 propTypes - 'react/no-multi-comp': 0, // 可以在一个文件里写多个 react component - 'prefer-destructuring': ['error', { - object: true, - array: false - }], // 不强制要求使用数组解构赋值 - 'no-console': 0, //可以 console - semi: 0, //禁止在语句末尾使用分号 - 'no-unused-expressions': 0, // 支持 func && func() 的写法 - 'no-param-reassign': 0, // 允许修改函数参数 - 'no-plusplus': ['error', { - allowForLoopAfterthoughts: true - }], //允许在循环中使用 i++ / i-- - 'comma-dangle': ['error', 'only-multiline'], // 对象的最后一个元素后不需要逗号 - 'import/extensions': ['off', 'never'], // import 的时候可以不带文件后缀 - 'import/no-unresolved': 0, //import 路径 - 'import/no-extraneous-dependencies': ['error', { - packageDir: './' + 'arrow-spacing':[ + 'error', + { + before: true, + after: true, + } + ], + 'comma-dangle': ['error', 'only-multiline'], + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': [ + 'error', + { + default: 'array' + } + ], + '@typescript-eslint/ban-types': [ + 'error', + { + types: { + Object: { + message: 'Avoid using the `Object` type. Did you mean `object`?' + }, + Function: { + message: 'Avoid using the `Function` type. Prefer a specific function type, like `() => void`.' + }, + Boolean: { + message: 'Avoid using the `Boolean` type. Did you mean `boolean`?' + }, + Number: { + message: 'Avoid using the `Number` type. Did you mean `number`?' + }, + String: { + message: 'Avoid using the `String` type. Did you mean `string`?' + }, + Symbol: { + message: 'Avoid using the `Symbol` type. Did you mean `symbol`?' + }, + object: false + } + } + ], + '@typescript-eslint/consistent-type-assertions': 'off', + '@typescript-eslint/dot-notation': 'error', + '@typescript-eslint/explicit-member-accessibility': [ + 'off', + { + accessibility: 'explicit' + } + ], + '@typescript-eslint/indent': [ + 'error', + 2, + { + SwitchCase: 1, + ArrayExpression: 1, + CallExpression: { 'arguments': 1 }, + ObjectExpression: 1, + ImportDeclaration: 1, + flatTernaryExpressions: false, + } + ], + '@typescript-eslint/member-delimiter-style': [ + 'off', + { + multiline: { + delimiter: 'none', + requireLast: true + }, + singleline: { + delimiter: 'semi', + requireLast: false + } + } + ], + '@typescript-eslint/member-ordering': 'error', + '@typescript-eslint/naming-convention': [ + 'error', + { selector: 'typeLike', format: ['PascalCase', 'UPPER_CASE'], filter: { 'regex': '^(__String|[A-Za-z]+_[A-Za-z]+)$', match: false } }, + { selector: 'interface', format: ['PascalCase'], 'custom': { 'regex': '^I[A-Z][a-zA-Z0-9]*', match: true }, filter: { 'regex': '^I(Arguments|TextWriter|O([A-Z][a-z]+[A-Za-z]*)?)$', match: false } }, + { selector: 'variable', format: ['camelCase', 'PascalCase', 'UPPER_CASE'], 'leadingUnderscore': 'allow', filter: { 'regex': '^(_{1,2}filename|_{1,2}dirname|_+|[A-Za-z]+_[A-Za-z]+)$', match: false } }, + { selector: 'function', format: ['camelCase', 'PascalCase'], 'leadingUnderscore': 'allow', filter: { 'regex': '^[A-Za-z]+_[A-Za-z]+$', match: false } }, + { selector: 'parameter', format: ['camelCase', 'PascalCase'], 'leadingUnderscore': 'allow', filter: { 'regex': '^(_+|[A-Za-z]+_[A-Z][a-z]+)$', match: false } }, + { selector: 'method', format: ['camelCase', 'PascalCase'], 'leadingUnderscore': 'allow', filter: { 'regex': '^[A-Za-z]+_[A-Za-z]+$', match: false } }, + { selector: 'memberLike', format: ['camelCase'], 'leadingUnderscore': 'allow', filter: { 'regex': '^[A-Za-z]+_[A-Za-z]+$', match: false } }, + { selector: 'enumMember', format: ['camelCase', 'PascalCase', 'UPPER_CASE'], 'leadingUnderscore': 'allow', filter: { 'regex': '^[A-Za-z]+_[A-Za-z]+$', match: false } }, + { selector: 'property', format: null } + ], + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-parameter-properties': 'off', + '@typescript-eslint/no-unused-expressions': ['error', { "allowTernary": true, "allowShortCircuit": true }], + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/quotes': [ + 'error', + 'single', + { allowTemplateLiterals: true } + ], + '@typescript-eslint/semi': [ + 'off', + null + ], + '@typescript-eslint/triple-slash-reference': [ + 'error', + { + path: 'always', + types: 'prefer-import', + lib: 'always' + } + ], + '@typescript-eslint/unified-signatures': 'error', + 'arrow-parens': [ + 'off', + 'always' + ], + 'brace-style': [ + 'error', + '1tbs' + ], + complexity: 'off', + 'constructor-super': 'error', + eqeqeq: [ + 'error', + 'smart' + ], + 'guard-for-in': 'error', + 'id-blacklist': 'error', + 'id-match': 'error', + 'import/no-internal-modules': 'off', + 'sort-imports': 'error', + 'jsdoc/check-alignment': 'error', + 'jsdoc/check-indentation': 'error', + 'jsdoc/newline-after-description': 'error', + 'max-classes-per-file': [ + 'error', + 10 + ], + 'no-bitwise': 'error', + 'no-caller': 'error', + 'no-cond-assign': 'error', + 'no-console': [ + 'off', + { + allow: [ + 'time', + 'timeEnd', + 'timeLog', + 'trace', + 'assert', + 'clear', + 'count', + 'countReset', + 'group', + 'groupEnd', + 'table', + 'debug', + 'info', + 'dirxml', + 'groupCollapsed', + 'Console', + 'profile', + 'profileEnd', + 'timeStamp', + 'context' + ] + } + ], + 'no-debugger': 'error', + 'no-duplicate-case': 'error', + 'no-duplicate-imports': 'error', + 'no-empty': 'error', + 'no-eval': 'error', + 'no-extra-bind': 'error', + 'no-fallthrough': 'off', + 'no-invalid-this': 'off', + 'no-irregular-whitespace': 'off', + 'no-new-func': 'error', + 'no-new-wrappers': 'error', + 'no-redeclare': 'error', + 'no-return-await': 'error', + 'no-sequences': 'error', + 'no-shadow': [ + 'off', + { + hoist: 'all' + } + ], + 'no-sparse-arrays': 'error', + 'no-template-curly-in-string': 'error', + 'no-throw-literal': 'error', + 'no-undef-init': 'error', + 'no-unsafe-finally': 'error', + 'no-unused-labels': 'error', + 'no-var': 'error', + 'object-shorthand': 'error', + 'one-var': [ + 'error', + 'never' + ], + "no-multi-spaces": ["error", { ignoreEOLComments: true }], + "comma-spacing": ["error"], + 'prefer-const': 'error', + 'prefer-object-spread': 'error', + 'radix': 'error', + 'react/display-name': 'error', + 'react/jsx-boolean-value': [ + 'error', + 'always' + ], + 'react/jsx-curly-spacing': 'off', + 'react/jsx-equals-spacing': 'off', + 'react/jsx-key': 'error', + 'react/jsx-no-bind': [ + 'error', + { + allowArrowFunctions: true + } + ], + 'react/jsx-no-comment-textnodes': 'error', + 'react/jsx-no-duplicate-props': 'error', + 'react/jsx-no-target-blank': 'error', + 'react/jsx-no-undef': 'error', + 'react/jsx-uses-react': 'error', + 'react/jsx-uses-vars': 'error', + 'react/jsx-wrap-multilines': 'off', + 'react/no-children-prop': 'off', + 'react/no-danger-with-children': 'error', + 'react/no-deprecated': 'error', + 'react/no-direct-mutation-state': 'error', + 'react/no-find-dom-node': 'error', + 'react/no-is-mounted': 'error', + 'react/no-render-return-value': 'error', + 'react/no-string-refs': 'error', + 'react/no-unescaped-entities': 'error', + 'react/no-unknown-property': 'error', + 'react/no-unsafe': 'off', + 'react/prop-types': 'error', + 'react/react-in-jsx-scope': 'error', + 'react/require-render-return': 'error', + 'react/self-closing-comp': ['error'], + 'space-in-parens': [ + 'error', + 'never' + ], + 'spaced-comment': [ + 'error', + 'always', + { + markers: [ + '/' + ] + } + ], + 'key-spacing': ["error", { + "beforeColon": false, + "afterColon": true }], - 'prettier/prettier': ['error', { - singleQuote: true, - semi: false + 'object-property-newline': ["error", { "allowAllPropertiesOnSameLine": true }], + "space-infix-ops": "error", + semi: 1, + 'block-spacing': "error", + 'space-before-blocks': "error", + 'space-before-function-paren': ["error", "never"], + 'object-curly-spacing': ['error','always'], + 'use-isnan': 'error', + 'valid-typeof': 'off', + 'jsx-quotes': ['error', 'prefer-double'], + 'sort-imports': ['error', { + ignoreCase: false, + ignoreDeclarationSort: true, + ignoreMemberSort: false, + memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'] }] } -} +}; diff --git a/.stylelintrc.json b/.stylelintrc.json index ab66a496..32a70920 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -8,6 +8,6 @@ "except": ["value"] }], "max-empty-lines": 2, - "unit-whitelist": ["em", "rem", "%", "s", "px", "deg"] + "unit-allowed-list": ["em", "rem", "%", "s", "px", "deg", "vw", "vh"] } } \ No newline at end of file diff --git a/app/App.tsx b/app/App.tsx index 7a807737..93d38fa1 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -1,4 +1,4 @@ -import { Dropdown, Icon, Layout, Menu, Select, Spin } from 'antd'; +import { Dropdown, Layout, Menu, Select, Spin } from 'antd'; import cookies from 'js-cookie'; import React from 'react'; import { hot } from 'react-hot-loader/root'; @@ -13,8 +13,11 @@ import { withRouter, } from 'react-router-dom'; +import { BranchesOutlined, CodeOutlined, CompassOutlined, DownOutlined, ImportOutlined, LogoutOutlined, QuestionCircleOutlined, StarOutlined, TagsOutlined } from '@ant-design/icons'; +import ConfigServer from './modules/ConfigServer'; +import PrivateRoute from './PrivateRoute'; import IconFont from '#app/components/Icon'; -import { INTL_LOCALE_SELECT, INTL_LOCALES } from '#app/config'; +import { INTL_LOCALES, INTL_LOCALE_SELECT } from '#app/config'; import service from '#app/config/service'; import { LanguageContext } from '#app/context'; import Console from '#app/modules/Console'; @@ -29,8 +32,6 @@ import { IDispatch, IRootState } from '#app/store'; import { updateQueryStringParameter } from '#app/utils'; import './App.less'; -import ConfigServer from './modules/ConfigServer'; -import PrivateRoute from './PrivateRoute'; import { handleTrackEvent, trackEvent, trackPageView } from './utils/stat'; const { Header, Content } = Layout; @@ -52,8 +53,8 @@ const mapState = (state: IRootState) => ({ interface IProps extends RouteComponentProps, - ReturnType, - ReturnType {} + ReturnType, + ReturnType {} class App extends React.Component { currentLocale; @@ -108,7 +109,7 @@ class App extends React.Component { }); }; - componentWillMount() { + UNSAFE_componentWillMount() { // Initialize the import task service.handleImportAction({ taskAction: 'actionStopAll' }); } @@ -198,7 +199,7 @@ class App extends React.Component { data-track-action="view_import" data-track-label="from_navigation" > - + {intl.get('common.import')} @@ -209,7 +210,7 @@ class App extends React.Component { data-track-action="view_explore" data-track-label="from_navigation" > - + {intl.get('common.explore')} @@ -220,7 +221,7 @@ class App extends React.Component { data-track-action="view_console" data-track-label="from_navigation" > - + {intl.get('common.console')} @@ -247,7 +248,7 @@ class App extends React.Component { - + {intl.get('configServer.clear')} @@ -255,7 +256,7 @@ class App extends React.Component { } > - {intl.get('common.setting')} + {intl.get('common.setting')} { overlay={ trackPageView('/user-mannual')}> - - + + {intl.get('common.use')} trackPageView('/nebula-doc')}> - - + + nGQL - - + + {intl.get('common.forum')} @@ -284,7 +285,7 @@ class App extends React.Component { } > - {intl.get('common.help')} + {intl.get('common.help')}
{ data-track-category="navigation" data-track-action="view_changelog" href={versionLogHref} - target="_blank" + target="_blank" rel="noreferrer" > - + {intl.get('common.release')} @@ -324,7 +325,7 @@ class App extends React.Component { > v{appVersion} - + )} diff --git a/app/PrivateRoute.tsx b/app/PrivateRoute.tsx index 616be22f..04917da0 100644 --- a/app/PrivateRoute.tsx +++ b/app/PrivateRoute.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { connect } from 'react-redux'; import { Redirect, Route } from 'react-router-dom'; - +import { RouteProps } from 'react-router'; import { IRootState } from './store'; const mapState = (state: IRootState) => ({ @@ -11,7 +11,14 @@ const mapState = (state: IRootState) => ({ const mapDispatch = () => ({}); -const PrivateRoute = ({ component: Component, render, ...rest }) => { +interface IProps extends RouteProps, ReturnType, + ReturnType{ + component?: any; + render?: any +} + +const PrivateRoute = (props: IProps) => { + const { component: Component, render, ...rest } = props; if (rest.host && rest.username) { return Component ? ( } /> @@ -19,7 +26,7 @@ const PrivateRoute = ({ component: Component, render, ...rest }) => { ); } else { - return ; + return ; } }; diff --git a/app/components/Button/index.tsx b/app/components/Button/index.tsx index b02c3a64..8ddb6aa9 100644 --- a/app/components/Button/index.tsx +++ b/app/components/Button/index.tsx @@ -1,4 +1,4 @@ -import { Icon, Tooltip } from 'antd'; +import { Tooltip } from 'antd'; import classnames from 'classnames'; import React from 'react'; @@ -8,7 +8,6 @@ import './index.less'; interface IBtnProps { disabled?: boolean; action?: () => void; - icon?: string; iconfont?: string; title?: string; className?: string; @@ -24,7 +23,6 @@ interface IMenuButton extends IBtnProps { } const CustomizeButton = (props: IBtnProps) => { const { - icon, iconfont, action, disabled, @@ -49,15 +47,6 @@ const CustomizeButton = (props: IBtnProps) => { data-track-action={trackAction} data-track-label={trackLabel} > - {icon && ( - - )} {iconfont && ( { // antd Tooltip can't wrap custom component const CustomizeTooltipBtn = (props: IMenuButton) => { const { - icon, iconfont, action, disabled, @@ -89,19 +77,7 @@ const CustomizeTooltipBtn = (props: IMenuButton) => { } = props; return ( - {icon ? ( - - ) : iconfont ? ( + {iconfont ? ( { const { content } = this.props.file; const columns = content.length ? content[0].map((_, index) => { - const textIndex = index; - return { - title: onMapping ? ( - <> - - - - - - ) : ( - `column ${textIndex}` - ), - dataIndex: index, - }; - }) + const textIndex = index; + return { + title: onMapping ? ( + <> + + + + + + ) : ( + `column ${textIndex}` + ), + dataIndex: index, + }; + }) : []; return ( @@ -75,7 +76,7 @@ class CSVPreviewLink extends React.PureComponent { dataSource={content} columns={columns} pagination={false} - rowKey={(_, index) => index.toString()} + rowKey={(_, index) => index!.toString()} />
{onMapping && ( diff --git a/app/components/CodeMirror.tsx b/app/components/CodeMirror.tsx index 4a030d79..b5160bae 100644 --- a/app/components/CodeMirror.tsx +++ b/app/components/CodeMirror.tsx @@ -147,7 +147,7 @@ export default class ReactCodeMirror extends React.PureComponent { } }; - async componentWillReceiveProps(nextProps) { + async UNSAFE_componentWillReceiveProps(nextProps) { const { options, value } = nextProps; await this.setOptions(options); if (value !== this.editor.getValue()) { diff --git a/app/components/ConfigServerForm/index.tsx b/app/components/ConfigServerForm/index.tsx index 69f380aa..6f1609dc 100644 --- a/app/components/ConfigServerForm/index.tsx +++ b/app/components/ConfigServerForm/index.tsx @@ -1,6 +1,4 @@ import { Button, Form, Input } from 'antd'; -import { FormComponentProps } from 'antd/lib/form'; -import { WrappedFormUtils } from 'antd/lib/form/Form'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; @@ -23,37 +21,33 @@ const fomrItemLayout = { const mapState = (state: IRootState) => ({ loading: state.loading.effects.nebula.asyncConfigServer, }); -interface IProps extends ReturnType, FormComponentProps { - onConfig: (form: WrappedFormUtils) => void; +interface IProps extends ReturnType { + onConfig: (form) => void; } -const ConfigServerForm = Form.create()((props: IProps) => { +const ConfigServerForm = ((props: IProps) => { const { onConfig, loading } = props; - const { getFieldDecorator } = props.form; + const [form] = Form.useForm(); return (
- - {getFieldDecorator('host', { - rules: hostRulesFn(intl), - })()} + + - - {getFieldDecorator('username', { - rules: usernameRulesFn(intl), - })()} + + - - {getFieldDecorator('password', { - rules: passwordRulesFn(intl), - })()} + +
{expandedAll && ( diff --git a/app/components/DisplayPanel/SelectedGraphDetailShowModal/index.tsx b/app/components/DisplayPanel/SelectedGraphDetailShowModal/index.tsx index 2a44849b..cb70c259 100644 --- a/app/components/DisplayPanel/SelectedGraphDetailShowModal/index.tsx +++ b/app/components/DisplayPanel/SelectedGraphDetailShowModal/index.tsx @@ -1,4 +1,4 @@ -import { Button, Input, message, Table, Tabs, Tooltip } from 'antd'; +import { Button, Input, Table, Tabs, Tooltip, message } from 'antd'; import JSONBigint from 'json-bigint'; import _ from 'lodash'; import React from 'react'; @@ -55,7 +55,7 @@ class SelectedGraphDetailShowModal extends React.PureComponent { } }; - handleChangeType = async (key: string) => { + handleChangeType = async(key: string) => { const { vertexes, edges } = this.props; this.setState({ tagType: key, @@ -155,87 +155,87 @@ class SelectedGraphDetailShowModal extends React.PureComponent { const columns = tagType === 'vertex' ? [ - { - title: 'vid', - dataIndex: 'vid', - align: 'center' as const, + { + title: 'vid', + dataIndex: 'vid', + align: 'center' as const, + }, + { + title: 'attributes', + dataIndex: 'attributes', + ellipsis: true, + align: 'center' as const, + render: record => { + return ( + + {JSONBigint.stringify( + JSONBigint.parse(record), + (_, value) => { + if (typeof value === 'string') { + return value.replace(/\u0000+$/, ''); + } + return value; + }, + 2, + )} + + } + > + {record} + + ); }, - { - title: 'attributes', - dataIndex: 'attributes', - ellipsis: true, - align: 'center' as const, - render: record => { - return ( - - {JSONBigint.stringify( - JSONBigint.parse(record), - (_, value) => { - if (typeof value === 'string') { - return value.replace(/\u0000+$/, ''); - } - return value; - }, - 2, - )} - - } - > - {record} - - ); - }, - }, - ] + }, + ] : [ - { - title: 'type', - dataIndex: 'type', - align: 'center' as const, - }, - { - title: 'rank', - dataIndex: 'rank', - align: 'center' as const, - }, - { - title: 'srcId', - dataIndex: 'srcId', - align: 'center' as const, - }, - { - title: 'dstId', - dataIndex: 'dstId', - align: 'center' as const, - }, - { - title: 'attributes', - dataIndex: 'attributes', - ellipsis: true, - align: 'center' as const, - render: record => { - return ( - - {JSONBigint.stringify( - JSONBigint.parse(record), - null, - 2, - )} - - } - > - {record} - - ); - }, + { + title: 'type', + dataIndex: 'type', + align: 'center' as const, + }, + { + title: 'rank', + dataIndex: 'rank', + align: 'center' as const, + }, + { + title: 'srcId', + dataIndex: 'srcId', + align: 'center' as const, + }, + { + title: 'dstId', + dataIndex: 'dstId', + align: 'center' as const, + }, + { + title: 'attributes', + dataIndex: 'attributes', + ellipsis: true, + align: 'center' as const, + render: record => { + return ( + + {JSONBigint.stringify( + JSONBigint.parse(record), + null, + 2, + )} + + } + > + {record} + + ); }, - ]; + }, + ]; return ( { index.toString()} + rowKey={(_, index) => index!.toString()} /> ); diff --git a/app/components/DisplayPanel/index.tsx b/app/components/DisplayPanel/index.tsx index 31e84908..ca99e426 100644 --- a/app/components/DisplayPanel/index.tsx +++ b/app/components/DisplayPanel/index.tsx @@ -3,10 +3,10 @@ import _ from 'lodash'; import React from 'react'; import { connect } from 'react-redux'; +import Expand from './ExpandForm'; import IconFont from '#app/components/Icon'; import { IDispatch, IRootState } from '#app/store'; -import Expand from './ExpandForm'; import './index.less'; const mapState = (state: IRootState) => ({ @@ -22,7 +22,7 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType { + ReturnType { showTitle?: boolean; } diff --git a/app/components/Expand/AddFilterForm/index.tsx b/app/components/Expand/AddFilterForm/index.tsx index 72c263c1..f34db5e0 100644 --- a/app/components/Expand/AddFilterForm/index.tsx +++ b/app/components/Expand/AddFilterForm/index.tsx @@ -1,54 +1,34 @@ import { Button, Form, Input } from 'antd'; -import { FormComponentProps } from 'antd/lib/form'; import React from 'react'; import intl from 'react-intl-universal'; +import { FormInstance } from 'antd/es/form'; import './index.less'; -interface IProps extends FormComponentProps { +interface IProps { onConfirm: (values) => void; onCancel: () => void; } class AddFilterForm extends React.PureComponent { + formRef = React.createRef(); handleAddFilters = () => { - this.props.form.validateFields((err, values) => { - if (!err) { - this.props.onConfirm(values); - } - }); + this.formRef.current!.validateFields().then(values => { + this.props.onConfirm(values); + }).catch(err => console.log('err', err)); }; render() { - const { getFieldDecorator } = this.props.form; return (
- - - {getFieldDecorator(`field`, { - rules: [ - { - required: true, - }, - ], - })()} + + + - - {getFieldDecorator(`operator`, { - rules: [ - { - required: true, - }, - ], - })()} + + - - {getFieldDecorator(`value`, { - rules: [ - { - required: true, - }, - ], - })()} + +
@@ -64,15 +44,4 @@ class AddFilterForm extends React.PureComponent { } } -export default Form.create({ - mapPropsToFields(_props: IProps) { - return { - onConfirm: Form.createFormField({ - onConfirm: _props.onConfirm, - }), - onCancel: Form.createFormField({ - onCancel: _props.onCancel, - }), - }; - }, -})(AddFilterForm); +export default AddFilterForm; diff --git a/app/components/Expand/ExpandForm/index.tsx b/app/components/Expand/ExpandForm/index.tsx index 2385f4b7..5b9ad7fc 100644 --- a/app/components/Expand/ExpandForm/index.tsx +++ b/app/components/Expand/ExpandForm/index.tsx @@ -2,17 +2,18 @@ import { Button, Form, Input, - message, Popover, Radio, Select, Tag, + message, } from 'antd'; -import { FormComponentProps } from 'antd/lib/form'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; +import { FormInstance } from 'antd/es/form'; +import AddFilterForm from '../AddFilterForm'; import { Instruction } from '#app/components'; import GQLModal from '#app/components/GQLModal'; import IconFont from '#app/components/Icon'; @@ -23,7 +24,6 @@ import { RELATION_OPERATORS } from '#app/utils/constant'; import { getExploreMatchGQL } from '#app/utils/gql'; import { trackEvent } from '#app/utils/stat'; -import AddFilterForm from '../AddFilterForm'; import './index.less'; const Option = Select.Option; @@ -46,9 +46,8 @@ const mapDispatch = (dispatch: IDispatch) => ({ }); interface IProps - extends FormComponentProps, - ReturnType, - ReturnType { + extends ReturnType, + ReturnType { close: () => void; } @@ -66,6 +65,7 @@ interface IState { class Expand extends React.Component { gqlRef; + formRef = React.createRef() constructor(props: IProps) { super(props); this.state = { @@ -142,12 +142,8 @@ class Expand extends React.Component { handleExpand = () => { const { selectVertexes, edgesFields } = this.props; - const { getFieldsValue } = this.props.form; const { filters, customColor, customIcon } = this.state; - this.props.form.validateFields(async err => { - if (err) { - return; - } + this.formRef.current!.validateFields().then(async() => { const { edgeTypes, edgeDirection, @@ -157,7 +153,7 @@ class Expand extends React.Component { maxStep, vertexStyle, quantityLimit, - } = getFieldsValue(); + } = this.formRef.current!.getFieldsValue(); (this.props.asyncGetExpand({ filters, selectVertexes, @@ -173,7 +169,7 @@ class Expand extends React.Component { customColor, customIcon, }) as any).then( - async () => { + async() => { message.success(intl.get('common.success')); trackEvent('explore', 'expand', 'ajax success'); }, @@ -197,9 +193,9 @@ class Expand extends React.Component { filters.length === 0 ? { expression } : { - relation: 'AND', - expression, - }; + relation: 'AND', + expression, + }; this.setState( { filters: [...filters, newFilter], @@ -247,7 +243,6 @@ class Expand extends React.Component { }; handleUpdateRules = () => { - const { getFieldsValue } = this.props.form; const { filters, customColor, customIcon } = this.state; setTimeout(() => { const { @@ -259,7 +254,7 @@ class Expand extends React.Component { maxStep, vertexStyle, quantityLimit, - } = getFieldsValue(); + } = this.formRef.current!.getFieldsValue(); this.props.updateExploreRules({ edgeTypes, edgeDirection, @@ -284,7 +279,6 @@ class Expand extends React.Component { spaceVidType, close, } = this.props; - const { getFieldDecorator, getFieldsValue } = this.props.form; const { filters, customColor, customIcon } = this.state; const { edgeTypes: selectEdgeTypes, @@ -294,182 +288,123 @@ class Expand extends React.Component { minStep, maxStep, quantityLimit, - } = getFieldsValue(); + } = this.formRef.current!.getFieldsValue(); const currentGQL = selectEdgeTypes && selectEdgeTypes.length ? getExploreMatchGQL({ - selectVertexes, - edgeTypes: selectEdgeTypes, - filters, - edgeDirection, - quantityLimit, - spaceVidType, - stepsType, - step, - minStep, - maxStep, - }) + selectVertexes, + edgeTypes: selectEdgeTypes, + filters, + edgeDirection, + quantityLimit, + spaceVidType, + stepsType, + step, + minStep, + maxStep, + }) : ''; const fieldTable = this.renderFilters(); return (
-
- - {getFieldDecorator('edgeTypes', { - initialValue: - rules.edgeTypes && rules.edgeTypes.length > 0 - ? rules.edgeTypes - : edgeTypes, - rules: [ - { - required: true, - message: 'Edge Type is required', - }, - ], - })( - , - )} - - - {getFieldDecorator('edgeDirection', { - initialValue: rules.edgeDirection || 'outgoing', - rules: [ - { - required: true, - }, - ], - })( - + {edgeTypes.map(e => ( + - , - )} + ))} + + + + - {getFieldDecorator('stepsType', { - initialValue: rules.stepsType || 'single', - rules: [ - { - required: true, - }, - ], - })( - - {intl.get('explore.singleStep')} - {intl.get('explore.rangeStep')} - , - )} + + {intl.get('explore.singleStep')} + {intl.get('explore.rangeStep')} + {stepsType === 'single' && ( - - {getFieldDecorator('step', { - initialValue: rules.step || '1', - rules: [ - { - message: intl.get('formRules.positiveIntegerRequired'), - pattern: /^\d+$/, - transform(value) { - if (value) { - return Number(value); - } - }, - }, - { - required: true, - }, - ], - })()} + + ) )} {stepsType === 'range' && (
- - {getFieldDecorator('minStep', { - initialValue: rules.minStep || '', - rules: [ - { - message: intl.get('formRules.positiveIntegerRequired'), - pattern: /^\d+$/, - transform(value) { - if (value) { - return Number(value); - } - }, - }, - { - required: true, - }, - ], - })()} - - - - - {getFieldDecorator('maxStep', { - initialValue: rules.maxStep || '', - rules: [ - { - message: intl.get('formRules.positiveIntegerRequired'), - pattern: /^\d+$/, - transform(value) { - if (value) { - return Number(value); - } - }, - }, - { - required: true, - }, - ], - })()} - -
- )} - - {getFieldDecorator('vertexStyle', { - initialValue: rules.vertexStyle || 'colorGroupByTag', - rules: [ + - - {intl.get('explore.colorGroupByTag')} - - - {intl.get('explore.customStyle')} - - - , - )} - - - {getFieldDecorator('quantityLimit', { - initialValue: rules.quantityLimit || 100, - rules: [ + ]}> + + + - + { } }, }, - ], - })()} + { + required: true, + }, + ]}> + + +
+ )} + + + + {intl.get('explore.colorGroupByTag')} + + + {intl.get('explore.customStyle')} + + + + + +
@@ -565,4 +534,4 @@ class Expand extends React.Component { } } -export default connect(mapState, mapDispatch)(Form.create()(Expand)); +export default connect(mapState, mapDispatch)(Expand); diff --git a/app/components/Expand/index.tsx b/app/components/Expand/index.tsx index 5b54025a..7887d19f 100644 --- a/app/components/Expand/index.tsx +++ b/app/components/Expand/index.tsx @@ -4,10 +4,10 @@ import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; +import Expand from './ExpandForm'; import IconFont from '#app/components/Icon'; import { IDispatch, IRootState } from '#app/store'; -import Expand from './ExpandForm'; import './index.less'; const mapState = (state: IRootState) => ({ @@ -22,7 +22,7 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType { + ReturnType { showTitle?: boolean; } diff --git a/app/components/GQLModal/index.tsx b/app/components/GQLModal/index.tsx index 6fbbbab8..1091c478 100644 --- a/app/components/GQLModal/index.tsx +++ b/app/components/GQLModal/index.tsx @@ -3,9 +3,9 @@ import React from 'react'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import intl from 'react-intl-universal'; +import { Modal } from '..'; import { CodeMirror } from '#app/components'; -import { Modal } from '..'; import './index.less'; interface IModalHandler { show: (callback?: any) => void; diff --git a/app/components/IconPicker/index.tsx b/app/components/IconPicker/index.tsx index cc8e47ad..e8d11ea4 100644 --- a/app/components/IconPicker/index.tsx +++ b/app/components/IconPicker/index.tsx @@ -2,9 +2,9 @@ import { Carousel, Popover } from 'antd'; import { chunk } from 'lodash'; import React from 'react'; +import IconCfg from './iconCfg'; import Icon from '#app/components/Icon'; -import IconCfg from './iconCfg'; import './index.less'; interface IIcon { diff --git a/app/components/Instruction/index.tsx b/app/components/Instruction/index.tsx index 1fc2443b..bd282ae1 100644 --- a/app/components/Instruction/index.tsx +++ b/app/components/Instruction/index.tsx @@ -1,13 +1,13 @@ -import { Icon, Tooltip } from 'antd'; +import { Tooltip } from 'antd'; import React from 'react'; +import { QuestionCircleOutlined } from '@ant-design/icons'; import './index.less'; const Instruction = (props: { description: string; onClick?: () => void }) => { return ( - diff --git a/app/components/NebulaD3/Links.tsx b/app/components/NebulaD3/Links.tsx index d193a170..d4bbb801 100644 --- a/app/components/NebulaD3/Links.tsx +++ b/app/components/NebulaD3/Links.tsx @@ -12,7 +12,7 @@ interface IProps { onMouseOut: () => void; } -export default class Links extends React.Component { +export default class Links extends React.Component> { ref: SVGGElement; componentDidMount() { diff --git a/app/components/NebulaD3/NodeTexts.tsx b/app/components/NebulaD3/NodeTexts.tsx index 162e68a3..ca4c7463 100644 --- a/app/components/NebulaD3/NodeTexts.tsx +++ b/app/components/NebulaD3/NodeTexts.tsx @@ -9,7 +9,7 @@ interface IProps { onUpDataNodeTexts: () => void; } -export default class NodeTexts extends React.Component { +export default class NodeTexts extends React.Component> { ref: SVGGElement; componentDidMount() { diff --git a/app/components/NebulaD3/SelectIds.tsx b/app/components/NebulaD3/SelectIds.tsx index b5315c89..fcc2cb49 100644 --- a/app/components/NebulaD3/SelectIds.tsx +++ b/app/components/NebulaD3/SelectIds.tsx @@ -15,6 +15,7 @@ interface IProps { } /** * Test line and line acrosses + * * @method isIntersectedLines * @param a1 - The start point of the first line * @param a2 - The end point of the first line @@ -40,7 +41,7 @@ function isIntersectedLines(a1, a2, b1, b2) { return false; } -export default class SelectIds extends React.Component { +export default class SelectIds extends React.Component> { componentDidMount() { const { nodes, links } = this.props; if (nodes.length !== 0 || links.length !== 0) { diff --git a/app/components/NebulaD3/index.tsx b/app/components/NebulaD3/index.tsx index b19f55d9..edc1d25f 100644 --- a/app/components/NebulaD3/index.tsx +++ b/app/components/NebulaD3/index.tsx @@ -2,15 +2,15 @@ import * as d3 from 'd3'; import * as React from 'react'; import { connect } from 'react-redux'; +import SelectIds from './SelectIds'; +import Labels from './NodeTexts'; +import Links from './Links'; import IconCfg from '#app/components/IconPicker/iconCfg'; import Menu from '#app/modules/Explore/NebulaGraph/Menu'; import { IRootState } from '#app/store'; import { INode, IPath } from '#app/utils/interface'; import './index.less'; -import Links from './Links'; -import Labels from './NodeTexts'; -import SelectIds from './SelectIds'; const mapState = (state: IRootState) => ({ offsetX: state.d3Graph.canvasOffsetX, diff --git a/app/components/OutputBox/Export.tsx b/app/components/OutputBox/Export.tsx index 36da86c4..578a1905 100644 --- a/app/components/OutputBox/Export.tsx +++ b/app/components/OutputBox/Export.tsx @@ -1,21 +1,19 @@ import { Button, Form, Input, Radio, Select } from 'antd'; -import { FormComponentProps } from 'antd/lib/form/Form'; import _ from 'lodash'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { FormInstance } from 'antd/es/form'; import { IDispatch } from '#app/store'; import { trackEvent } from '#app/utils/stat'; - import './Export.less'; const Option = Select.Option; interface IProps extends ReturnType, - FormComponentProps, - RouteComponentProps { + RouteComponentProps { data: any; } @@ -29,35 +27,36 @@ const mapDispatch = (dispatch: IDispatch) => ({ }); class Export extends React.Component { + formRef = React.createRef() handleExport = () => { - const { getFieldsValue } = this.props.form; + const { getFieldsValue } = this.formRef.current!; const { type, vertexId, srcId, dstId, edgeType, rank } = getFieldsValue(); const { tables } = this.props.data; const vertexes = type === 'vertex' ? tables - .map(vertex => { - if (vertex.type === 'vertex') { - return vertex.vid; - } else { - return vertex[vertexId].toString(); - } - }) - .filter(vertexId => vertexId !== '') + .map(vertex => { + if (vertex.type === 'vertex') { + return vertex.vid; + } else { + return vertex[vertexId].toString(); + } + }) + .filter(vertexId => vertexId !== '') : tables - .map(edge => [edge[srcId], edge[dstId]]) - .flat() - .filter(id => id !== ''); + .map(edge => [edge[srcId], edge[dstId]]) + .flat() + .filter(id => id !== ''); const edges = type === 'edge' ? tables - .map(edge => ({ - srcId: edge[srcId], - dstId: edge[dstId], - rank: rank !== '' && rank !== undefined ? edge[rank] : 0, - edgeType, - })) - .filter(edge => edge.srcId !== '' && edge.dstId !== '') + .map(edge => ({ + srcId: edge[srcId], + dstId: edge[dstId], + rank: rank !== '' && rank !== undefined ? edge[rank] : 0, + edgeType, + })) + .filter(edge => edge.srcId !== '' && edge.dstId !== '') : []; this.props.updatePreloadData({ vertexes, @@ -69,7 +68,7 @@ class Export extends React.Component { render() { const { headers } = this.props.data; - const { getFieldDecorator, getFieldsValue } = this.props.form; + const { getFieldsValue } = this.formRef.current!; const { type = 'vertex', vertexId, @@ -86,10 +85,11 @@ class Export extends React.Component { }; return (
- - {getFieldDecorator('type', { - initialValue: 'vertex', - })( + + {intl.get('import.vertexText')} @@ -97,86 +97,54 @@ class Export extends React.Component { {intl.get('common.edge')} - , - )} + + {type === 'vertex' && ( <>

{intl.get('console.exportVertex')}

- - {getFieldDecorator('vertexId', { - rules: [ - { - required: true, - }, - ], - })( - , - )} + + )} {type === 'edge' && ( <>

{intl.get('console.exportEdge')}

- - {getFieldDecorator('edgeType', { - rules: [ - { - required: true, - }, - ], - })()} + + - - {getFieldDecorator('srcId', { - rules: [ - { - required: true, - }, - ], - })( - , - )} + + - - {getFieldDecorator('dstId', { - rules: [ - { - required: true, - }, - ], - })( - , - )} + + - - {getFieldDecorator('rank')( - , - )} + + )} @@ -199,4 +167,4 @@ class Export extends React.Component { export default connect( mapState, mapDispatch, -)(withRouter(Form.create()(Export))); +)(withRouter(Export)); diff --git a/app/components/OutputBox/Graphviz.tsx b/app/components/OutputBox/Graphviz.tsx index f0523111..ef3cadb3 100644 --- a/app/components/OutputBox/Graphviz.tsx +++ b/app/components/OutputBox/Graphviz.tsx @@ -1,4 +1,4 @@ -import { graphviz, GraphvizOptions } from 'd3-graphviz'; +import { GraphvizOptions, graphviz } from 'd3-graphviz'; import _ from 'lodash'; import * as React from 'react'; diff --git a/app/components/OutputBox/index.tsx b/app/components/OutputBox/index.tsx index 3eb26b5d..947269ef 100644 --- a/app/components/OutputBox/index.tsx +++ b/app/components/OutputBox/index.tsx @@ -1,24 +1,25 @@ -import { Alert, Button, Icon, Table, Tabs } from 'antd'; +import { Alert, Button, Table, Tabs } from 'antd'; import { BigNumber } from 'bignumber.js'; import _ from 'lodash'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { AlertOutlined, ShareAltOutlined, TableOutlined } from '@ant-design/icons'; +import Export from './Export'; +import Graphviz from './Graphviz'; import { Modal, OutputCsv } from '#app/components'; import { IDispatch, IRootState } from '#app/store'; import { parseSubGraph } from '#app/utils/parseData'; import { trackEvent } from '#app/utils/stat'; -import Export from './Export'; -import Graphviz from './Graphviz'; import './index.less'; interface IProps extends ReturnType, - ReturnType, - RouteComponentProps { + ReturnType, + RouteComponentProps { value: string; result: any; onHistoryItem: (value: string) => void; @@ -173,7 +174,7 @@ class OutputBox extends React.Component { - + {intl.get('common.table')} } @@ -204,7 +205,7 @@ class OutputBox extends React.Component { showTotal: () => `${intl.get('common.total')} ${dataSource.length}`, }} - rowKey={(_, index) => index.toString()} + rowKey={(_, index) => index!.toString()} /> )} @@ -212,7 +213,7 @@ class OutputBox extends React.Component { - + {intl.get('common.graph')} } @@ -225,7 +226,7 @@ class OutputBox extends React.Component { - + {intl.get('common.log')} } diff --git a/app/components/OutputCsv/index.tsx b/app/components/OutputCsv/index.tsx index c2ca6d6f..d254702c 100644 --- a/app/components/OutputCsv/index.tsx +++ b/app/components/OutputCsv/index.tsx @@ -30,6 +30,7 @@ export default class OutputCsv extends React.PureComponent { } const _utf = '\uFEFF'; + // @ts-ignore if (window.Blob && window.URL && window.URL.createObjectURL) { const csvBlob = new Blob([_utf + csv], { type: 'text/csv', diff --git a/app/config/explore.ts b/app/config/explore.ts index 33b483aa..e7461073 100644 --- a/app/config/explore.ts +++ b/app/config/explore.ts @@ -166,6 +166,7 @@ export const downloadCSVFiles = ({ headers, tables, title }) => { // IE10 or Edge browsers const BOM = '\uFEFF'; const csvData = new Blob([BOM + result], { type: 'text/csv' }); + // @ts-ignore navigator.msSaveBlob(csvData, `test.csv`); } else { // Non-Internet Explorer diff --git a/app/index.tsx b/app/index.tsx index 37c2a8d6..02cf0d5e 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -3,9 +3,19 @@ import React from 'react'; import ReactDom from 'react-dom'; import { Provider } from 'react-redux'; import { BrowserRouter as Router } from 'react-router-dom'; +import Cookie from 'js-cookie'; +import intl from 'react-intl-universal'; +import { INTL_LOCALES } from '#app/config/constants'; import App from './App'; import { store } from './store'; + +const defaultLanguage = Cookie.get('lang') || document.documentElement.getAttribute('lang'); +intl.init({ + currentLocale: defaultLanguage || 'EN_US', + locales: INTL_LOCALES, +}); + message.config({ maxCount: 1, }); diff --git a/app/modules/ConfigServer/index.tsx b/app/modules/ConfigServer/index.tsx index 78bed497..b19cc55f 100644 --- a/app/modules/ConfigServer/index.tsx +++ b/app/modules/ConfigServer/index.tsx @@ -1,4 +1,3 @@ -import { WrappedFormUtils } from 'antd/lib/form/Form'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; @@ -18,23 +17,19 @@ const mapState = () => ({}); interface IProps extends ReturnType, - ReturnType, - RouteComponentProps {} + ReturnType, + RouteComponentProps {} class ConfigServer extends React.Component { componentDidMount() { trackPageView('/connect-server'); } - handleConfigServer = (form: WrappedFormUtils) => { - form.validateFields(async (err, data) => { - if (!err) { - const ok = await this.props.asyncConfigServer(data); - if (ok) { - this.props.history.replace('/'); - } - } - }); + handleConfigServer = async(values: any) => { + const ok = await this.props.asyncConfigServer(values); + if (ok) { + this.props.history.replace('/'); + } }; render() { return ( diff --git a/app/modules/Console/SpaceSearchInput.tsx b/app/modules/Console/SpaceSearchInput.tsx index 64be2d28..20f6a68e 100644 --- a/app/modules/Console/SpaceSearchInput.tsx +++ b/app/modules/Console/SpaceSearchInput.tsx @@ -17,7 +17,7 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType { + ReturnType { onSpaceChange: (value: string) => void; value: string; } diff --git a/app/modules/Console/index.tsx b/app/modules/Console/index.tsx index 60afad67..73e2a174 100644 --- a/app/modules/Console/index.tsx +++ b/app/modules/Console/index.tsx @@ -1,16 +1,17 @@ -import { Button, Icon, List, message, Modal, Tooltip } from 'antd'; +import { Button, List, Modal, Tooltip, message } from 'antd'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; import { RouteComponentProps } from 'react-router-dom'; +import { DeleteOutlined, FileSearchOutlined, HistoryOutlined, LoadingOutlined, PlayCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons'; +import SpaceSearchInput from './SpaceSearchInput'; import { CodeMirror, OutputBox } from '#app/components'; import { maxLineNum } from '#app/config/nebulaQL'; import { IDispatch, IRootState } from '#app/store'; import { trackPageView } from '#app/utils/stat'; import './index.less'; -import SpaceSearchInput from './SpaceSearchInput'; interface IState { isUpDown: boolean; @@ -41,8 +42,8 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType, - RouteComponentProps {} + ReturnType, + RouteComponentProps {} // split from semicolon out of quotation marks const SEMICOLON_REG = /((?:[^;'"]*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*')[^;'"]*)+)|;/; @@ -88,7 +89,7 @@ class Console extends React.Component { return intl.get('common.disablesUseToSwitchSpace'); } }; - handleRun = async () => { + handleRun = async() => { const query = this.editor.getValue(); if (!query) { message.error(intl.get('common.sorryNGQLCannotBeEmpty')); @@ -185,18 +186,17 @@ class Console extends React.Component { value={currentSpace} /> - +
- + - { this.setState({ history: true }); }} @@ -204,11 +204,9 @@ class Console extends React.Component { {!!runGQLLoading ? ( - + ) : ( - this.handleRun()} /> )} @@ -220,9 +218,7 @@ class Console extends React.Component { title={intl.get('console.parameterDisplay')} placement="right" > - diff --git a/app/modules/Explore/Control/AlgorithmQuery/index.tsx b/app/modules/Explore/Control/AlgorithmQuery/index.tsx index 321d5a59..7dc03fbb 100644 --- a/app/modules/Explore/Control/AlgorithmQuery/index.tsx +++ b/app/modules/Explore/Control/AlgorithmQuery/index.tsx @@ -1,10 +1,10 @@ import { Button, Divider, Form, Input, Select } from 'antd'; -import { FormComponentProps } from 'antd/lib/form/Form'; import _ from 'lodash'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; +import { FormInstance } from 'antd/es/form'; import { Instruction } from '#app/components'; import GQLCodeMirror from '#app/components/GQLCodeMirror'; import { GRAPH_ALOGORITHM } from '#app/config/explore'; @@ -28,12 +28,12 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType, - FormComponentProps { + ReturnType { closeHandler: any; } class AlgorithmQuery extends React.Component { + formRef = React.createRef() componentDidMount() { this.props.asyncGetEdges(); } @@ -42,8 +42,7 @@ class AlgorithmQuery extends React.Component { window.open(intl.get('explore.docForFindPath'), '_blank'); }; - handleInquiry = async () => { - const { getFieldsValue } = this.props.form; + handleInquiry = async(data) => { const { spaceVidType } = this.props; const { type, @@ -53,26 +52,22 @@ class AlgorithmQuery extends React.Component { direction, stepLimit, quantityLimit, - } = getFieldsValue(); - this.props.form.validateFields(async err => { - if (!err) { - await this.props.asyncGetPathResult({ - spaceVidType, - type, - srcId, - dstId, - relation, - direction, - stepLimit, - quantityLimit, - }); - this.props.closeHandler(); - } + } = data; + await this.props.asyncGetPathResult({ + spaceVidType, + type, + srcId, + dstId, + relation, + direction, + stepLimit, + quantityLimit, }); + this.props.closeHandler(); }; render() { - const { getFieldDecorator, getFieldsValue } = this.props.form; + const { getFieldsValue } = this.formRef.current!; const { edgeTypes, spaceVidType, loading } = this.props; const formItemLayout = { labelCol: { @@ -94,38 +89,32 @@ class AlgorithmQuery extends React.Component { const currentGQL = type && srcId && dstId ? getPathGQL({ - spaceVidType, - type, - srcId, - dstId, - relation, - direction, - stepLimit, - quantityLimit, - }) + spaceVidType, + type, + srcId, + dstId, + relation, + direction, + stepLimit, + quantityLimit, + }) : ''; return (
- + - {getFieldDecorator('type', { - rules: [ - { - required: true, - }, - ], - })( - , - )} + { {intl.get('explore.algorithmParams')} - - {getFieldDecorator('srcId', { - rules: [ - { - required: true, - message: 'Src ID is required', - }, - ], - })( - - {getFieldDecorator('dstId', { - rules: [ - { - required: true, - message: 'Dst ID is required', - }, - ], - })( - - {getFieldDecorator('relation')( - , - )} + + - - {getFieldDecorator('direction')( - + - + - , - )} + + - - {getFieldDecorator('stepLimit', { - rules: [ - { - message: intl.get('formRules.positiveIntegerRequired'), - pattern: /^\d+$/, - transform(value) { - if (value) { - return Number(value); - } - }, - }, - ], - })()} + + - - {getFieldDecorator('quantityLimit', { - rules: [ - { - message: intl.get('formRules.positiveIntegerRequired'), - pattern: /^\d+$/, - transform(value) { - if (value) { - return Number(value); - } - }, - }, - ], - })()} + + - + + +
); } } -export default connect(mapState, mapDispatch)(Form.create()(AlgorithmQuery)); +export default connect(mapState, mapDispatch)(AlgorithmQuery); diff --git a/app/modules/Explore/Control/IdQuery/index.tsx b/app/modules/Explore/Control/IdQuery/index.tsx index 4d7615b7..022daca9 100644 --- a/app/modules/Explore/Control/IdQuery/index.tsx +++ b/app/modules/Explore/Control/IdQuery/index.tsx @@ -1,10 +1,10 @@ import { Button, Form, Input, Spin, Upload } from 'antd'; -import { FormComponentProps } from 'antd/lib/form/Form'; import _ from 'lodash'; import React from 'react'; import intl from 'react-intl-universal'; import { connect } from 'react-redux'; +import { FormInstance } from 'antd/es/form'; import { nodeIdRulesFn } from '#app/config/rules'; import { IDispatch, IRootState } from '#app/store'; import readFileContent from '#app/utils/file'; @@ -22,8 +22,7 @@ const mapDispatch = (dispatch: IDispatch) => ({ interface IProps extends ReturnType, - ReturnType, - FormComponentProps { + ReturnType { closeHandler: any; } @@ -32,6 +31,7 @@ interface IState { } class IdQuery extends React.Component { + formRef = React.createRef() constructor(props: IProps) { super(props); @@ -39,18 +39,14 @@ class IdQuery extends React.Component { loading: false, }; } - handleImport = () => { - this.props.form.validateFields(async (err, data) => { - if (!err) { - const { ids } = data; - const _ids = ids.trim().split('\n'); - this.props.asyncImportNodes({ ids: _ids }); - this.props.closeHandler(); - } - }); + handleImport = data => { + const { ids } = data; + const _ids = ids.trim().split('\n'); + this.props.asyncImportNodes({ ids: _ids }); + this.props.closeHandler(); }; - handleFileImport = async ({ file }) => { + handleFileImport = async({ file }) => { this.setState({ loading: true, }); @@ -58,18 +54,18 @@ class IdQuery extends React.Component { this.setState({ loading: false, }); - this.props.form.setFieldsValue({ + this.formRef.current!.setFieldsValue({ ids, }); }; resetValidator = () => { - const ids = this.props.form.getFieldValue('ids'); - this.props.form.resetFields(['ids']); - this.props.form.setFieldsValue({ ids }); + const ids = this.formRef.current!.getFieldValue('ids'); + this.formRef.current!.resetFields(['ids']); + this.formRef.current!.setFieldsValue({ ids }); }; - handleImportSample = async () => { + handleImportSample = async() => { const { asyncGetSampleVertic, closeHandler } = this.props; const { code } = await asyncGetSampleVertic(); if (code === 0) { @@ -77,7 +73,6 @@ class IdQuery extends React.Component { } }; render() { - const { getFieldDecorator } = this.props.form; const { loading } = this.state; const { sampleLoading } = this.props; return ( @@ -98,23 +93,19 @@ class IdQuery extends React.Component {
-
- - {getFieldDecorator('ids', { - rules: nodeIdRulesFn(intl), - })( -