diff --git a/ui/prettier.config.js b/ui/prettier.config.js new file mode 100644 index 0000000000..839c4cccd9 --- /dev/null +++ b/ui/prettier.config.js @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** @type {import('prettier').Config} */ +module.exports = { + endOfLine: "lf", + semi: true, + singleQuote: true, + tabWidth: 4, + trailingComma: "es5", + importOrder: [ + "^Licensed to the Apache Software Foundation (ASF)", + "^(react/(.*)$)|^(react$)", + "^(next/(.*)$)|^(next$)", + "", + "", + "^types$", + "^@/types/(.*)$", + "^@/config/(.*)$", + "^@/lib/(.*)$", + "^@/hooks/(.*)$", + "^@/components/ui/(.*)$", + "^@/components/(.*)$", + "^@/styles/(.*)$", + "^@/app/(.*)$", + "", + "^[./]", + ], + importOrderSeparation: false, + importOrderSortSpecifiers: true, + importOrderBuiltinModulesToTop: true, + importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"], + importOrderMergeDuplicateImports: true, + importOrderCombineTypeAndValueImports: true, +} diff --git a/ui/public/locales/en-us.json b/ui/public/locales/en-us.json index bbcc98fe6c..8690d71fec 100644 --- a/ui/public/locales/en-us.json +++ b/ui/public/locales/en-us.json @@ -50,5 +50,6 @@ "executionTime": "Execution Time", "search":"Search", "executionFailed":"Execution failed", - "loading":"loading" + "loading":"loading", + "Download": "Download" } diff --git a/ui/public/locales/zh-cn.json b/ui/public/locales/zh-cn.json index 90dfdd340a..f593f707b7 100644 --- a/ui/public/locales/zh-cn.json +++ b/ui/public/locales/zh-cn.json @@ -50,5 +50,6 @@ "executionTime": "执行时间", "search":"查询", "executionFailed": "执行失败", - "loading":"加载中" + "loading":"加载中", + "Download": "下载" } diff --git a/ui/src/pages/query-profile/index.tsx b/ui/src/pages/query-profile/index.tsx index 5590ce9085..a5bb13b204 100644 --- a/ui/src/pages/query-profile/index.tsx +++ b/ui/src/pages/query-profile/index.tsx @@ -17,45 +17,94 @@ * under the License. */ -import React, {useEffect, useRef, useState} from 'react'; -import {Button, Col, Row, Typography, Space} from 'antd'; -import {queryProfile} from 'Src/api/api'; +import React, { useEffect, useRef, useState } from 'react'; +import { Button, Col, Row, Typography, Space } from 'antd'; +import { queryProfile } from 'Src/api/api'; import Table from 'Src/components/table'; -import {useHistory} from 'react-router-dom'; -import {Result} from '@src/interfaces/http.interface'; -import {replaceToTxt} from 'Src/utils/utils'; +import { useHistory } from 'react-router-dom'; +import { Result } from '@src/interfaces/http.interface'; +import { replaceToTxt } from 'Src/utils/utils'; +import { useTranslation } from 'react-i18next'; +import SyntaxHighlighter from 'react-syntax-highlighter'; +import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs'; -const {Text, Title} = Typography; +const { Text, Title } = Typography; export default function QueryProfile(params: any) { // const [parentUrl, setParentUrl] = useState(''); const container = useRef(null); - const [allTableData, setAllTableData] = useState({column_names: [], rows: []}); + let { t } = useTranslation(); + const [allTableData, setAllTableData] = useState({ + column_names: [], + rows: [], + }); const [profile, setProfile] = useState(); const history = useHistory(); const doQueryProfile = function (ac?: AbortController) { const param = { path: getLastPath(), - signal: ac?.signal + signal: ac?.signal, }; - queryProfile(param).then((res: Result) => { - if (res && res.msg === 'success') { - if (!res.data.column_names) { - setProfile(res.data); - if (container.current !== null) { - container.current.innerHTML = res.data; + queryProfile(param) + .then((res: Result) => { + if (res && res.msg === 'success') { + if (!res.data.column_names) { + setProfile(res.data); + if (container.current !== null) { + container.current.innerHTML = res.data; + } + } else { + setProfile(''); + res.data.column_names.push('Action'); + res.data.rows = res.data.rows.map((row) => { + row['Sql Statement'] = ( +
+ + {row['Sql Statement']} + +
+ ); + row.Action = ( + + ); + return row; + }); + setAllTableData(res.data); } } else { - setProfile(''); - setAllTableData(res.data); + setAllTableData({ + column_names: [], + rows: [], + }); } - } else { - setAllTableData({ - column_names: [], - rows: [], - }); - } - }).catch(err => { - }); + }) + .catch((err) => {}); }; useEffect(() => { const ac = new AbortController(); @@ -79,11 +128,11 @@ export default function QueryProfile(params: any) { function download(profile: string) { const profileTxt = replaceToTxt(profile); const blob = new Blob([profileTxt], { - type: "text/plain", + type: 'text/plain', }); - const tagA = document.createElement("a"); + const tagA = document.createElement('a'); tagA.download = `profile_${new Date().valueOf()}.txt`; - tagA.style.display = "none"; + tagA.style.display = 'none'; tagA.href = URL.createObjectURL(blob); document.body.appendChild(tagA); tagA.click(); @@ -92,7 +141,7 @@ export default function QueryProfile(params: any) { } function copyToClipboard(profile: string) { const profileTxt = replaceToTxt(profile); - const textarea = document.createElement("textarea"); + const textarea = document.createElement('textarea'); textarea.value = profileTxt; document.body.appendChild(textarea); textarea.select(); @@ -101,38 +150,57 @@ export default function QueryProfile(params: any) { } return ( - + Finished Queries - - This table lists the latest 100 queries - - {profile ? - - - - : ''} + + + + This table lists the latest 100 queries + + + + {profile ? ( + + + + + + ) : ( + '' + )} - { - profile - ?
- {/* {profile} */} -
- : record['Query ID']} - isSort={true} - isFilter={true} - isInner={'/QueryProfile'} - allTableData={allTableData} - /> - } - + {profile ? ( +
+ {/* {profile} */} +
+ ) : ( +
record['Profile ID']} + isSort={true} + isFilter={true} + isInner={'/QueryProfile'} + allTableData={allTableData} + /> + )} ); } -