Browse Source

fix query experience

Signed-off-by: shanghaikid <jiangruiyi@gmail.com>
shanghaikid 2 years ago
parent
commit
0da0ba397f

+ 3 - 3
client/package.json

@@ -7,7 +7,7 @@
   "private": true,
   "private": true,
   "dependencies": {
   "dependencies": {
     "@date-io/dayjs": "1.x",
     "@date-io/dayjs": "1.x",
-    "@loadable/component": "^5.15.0",
+    "@json2csv/plainjs": "^7.0.1",
     "@material-ui/core": "4.11.4",
     "@material-ui/core": "4.11.4",
     "@material-ui/icons": "^4.11.3",
     "@material-ui/icons": "^4.11.3",
     "@material-ui/lab": "4.0.0-alpha.58",
     "@material-ui/lab": "4.0.0-alpha.58",
@@ -26,7 +26,6 @@
     "react-router-dom": "^6.4.3",
     "react-router-dom": "^6.4.3",
     "react-syntax-highlighter": "^15.4.4",
     "react-syntax-highlighter": "^15.4.4",
     "socket.io-client": "^4.1.3",
     "socket.io-client": "^4.1.3",
-    "typescript": "^4.1.2",
     "vite": "^3.2.2",
     "vite": "^3.2.2",
     "vite-plugin-svgr": "^0.3.0",
     "vite-plugin-svgr": "^0.3.0",
     "web-vitals": "^1.0.1"
     "web-vitals": "^1.0.1"
@@ -52,7 +51,8 @@
     "@vitest/coverage-c8": "^0.25.0",
     "@vitest/coverage-c8": "^0.25.0",
     "jsdom": "^20.0.2",
     "jsdom": "^20.0.2",
     "prettier": "2.3.2",
     "prettier": "2.3.2",
-    "vitest": "^0.24.5"
+    "vitest": "^0.24.5",
+    "typescript": "^4.1.2"
   },
   },
   "homepage": "./",
   "homepage": "./",
   "scripts": {
   "scripts": {

+ 8 - 8
client/src/consts/Util.ts

@@ -6,14 +6,6 @@ export const BYTE_UNITS: { [x: string]: number } = {
 };
 };
 
 
 export const LOGICAL_OPERATORS = [
 export const LOGICAL_OPERATORS = [
-  {
-    value: '<',
-    label: '<',
-  },
-  {
-    value: '<=',
-    label: '<=',
-  },
   {
   {
     value: '>',
     value: '>',
     label: '>',
     label: '>',
@@ -30,6 +22,14 @@ export const LOGICAL_OPERATORS = [
     value: '!=',
     value: '!=',
     label: '!=',
     label: '!=',
   },
   },
+  {
+    value: '<',
+    label: '<',
+  },
+  {
+    value: '<=',
+    label: '<=',
+  },
   {
   {
     value: 'in',
     value: 'in',
     label: 'in',
     label: 'in',

+ 1 - 1
client/src/i18n/en/collection.ts

@@ -84,7 +84,7 @@ const collectionTrans = {
   queryTab: 'Data Query',
   queryTab: 'Data Query',
   previewTab: 'Data Preview',
   previewTab: 'Data Preview',
   startTip: 'Start your data query',
   startTip: 'Start your data query',
-  exprPlaceHolder: 'Please enter your query by using advanced filter ->',
+  exprPlaceHolder: 'Please enter your data query, for example id > 0',
 
 
   // alias dialog
   // alias dialog
   aliasCreatePlaceholder: 'Alias name',
   aliasCreatePlaceholder: 'Alias name',

+ 44 - 12
client/src/pages/query/Query.tsx

@@ -1,8 +1,15 @@
-import { FC, useEffect, useState, useRef, useMemo, useContext } from 'react';
+import {
+  FC,
+  useEffect,
+  useState,
+  useRef,
+  useMemo,
+  useContext,
+  useCallback,
+} from 'react';
+import { TextField } from '@material-ui/core';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
-
 import { rootContext } from '../../context/Root';
 import { rootContext } from '../../context/Root';
-
 import EmptyCard from '../../components/cards/EmptyCard';
 import EmptyCard from '../../components/cards/EmptyCard';
 import icons from '../../components/icons/Icons';
 import icons from '../../components/icons/Icons';
 import CustomButton from '../../components/customButton/CustomButton';
 import CustomButton from '../../components/customButton/CustomButton';
@@ -14,7 +21,6 @@ import { CollectionHttp } from '../../http/Collection';
 import { FieldHttp } from '../../http/Field';
 import { FieldHttp } from '../../http/Field';
 import { usePaginationHook } from '../../hooks/Pagination';
 import { usePaginationHook } from '../../hooks/Pagination';
 // import { useTimeTravelHook } from '../../hooks/TimeTravel';
 // import { useTimeTravelHook } from '../../hooks/TimeTravel';
-
 import CopyButton from '../../components/advancedSearch/CopyButton';
 import CopyButton from '../../components/advancedSearch/CopyButton';
 import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate';
 import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate';
 import CustomToolBar from '../../components/grid/ToolBar';
 import CustomToolBar from '../../components/grid/ToolBar';
@@ -32,7 +38,6 @@ const Query: FC<{
   const [queryResult, setQueryResult] = useState<any>();
   const [queryResult, setQueryResult] = useState<any>();
   const [selectedData, setSelectedData] = useState<any[]>([]);
   const [selectedData, setSelectedData] = useState<any[]>([]);
   const [primaryKey, setPrimaryKey] = useState<string>('');
   const [primaryKey, setPrimaryKey] = useState<string>('');
-
   const { setDialog, handleCloseDialog, openSnackBar } =
   const { setDialog, handleCloseDialog, openSnackBar } =
     useContext(rootContext);
     useContext(rootContext);
   const VectorSearchIcon = icons.vectorSearch;
   const VectorSearchIcon = icons.vectorSearch;
@@ -142,14 +147,18 @@ const Query: FC<{
 
 
   const handleFilterSubmit = (expression: string) => {
   const handleFilterSubmit = (expression: string) => {
     setExpression(expression);
     setExpression(expression);
-    setQueryResult(null);
+    handleQuery(expression);
   };
   };
 
 
-  const handleQuery = async () => {
+  const handleQuery = async (expr: string = '') => {
     setTableLoading(true);
     setTableLoading(true);
+    if (expr === '') {
+      handleFilterReset();
+      return;
+    }
     try {
     try {
       const res = await CollectionHttp.queryData(collectionName, {
       const res = await CollectionHttp.queryData(collectionName, {
-        expr: expression,
+        expr: expr,
         output_fields: fields.map(i => i.name),
         output_fields: fields.map(i => i.name),
         // travel_timestamp: timeTravelInfo.timestamp,
         // travel_timestamp: timeTravelInfo.timestamp,
       });
       });
@@ -225,8 +234,27 @@ const Query: FC<{
       <CustomToolBar toolbarConfigs={toolbarConfigs} />
       <CustomToolBar toolbarConfigs={toolbarConfigs} />
       <div className={classes.toolbar}>
       <div className={classes.toolbar}>
         <div className="left">
         <div className="left">
-          {/* <div className="expression"> */}
-          <div>{`${expression || collectionTrans('exprPlaceHolder')}`}</div>
+          <TextField
+            className="textarea"
+            InputProps={{
+              classes: {
+                root: 'textfield',
+                multiline: 'multiline',
+              },
+            }}
+            placeholder={collectionTrans('exprPlaceHolder')}
+            value={expression}
+            onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
+              setExpression(e.target.value as string);
+            }}
+            onKeyDown={e => {
+              if (e.key === 'Enter') {
+                // Do code here
+                handleQuery(expression);
+                e.preventDefault();
+              }
+            }}
+          />
           <Filter
           <Filter
             ref={filterRef}
             ref={filterRef}
             title="Advanced Filter"
             title="Advanced Filter"
@@ -250,14 +278,18 @@ const Query: FC<{
           /> */}
           /> */}
         </div>
         </div>
         <div className="right">
         <div className="right">
-          <CustomButton className="btn" onClick={handleFilterReset}>
+          <CustomButton
+            className="btn"
+            onClick={handleFilterReset}
+            disabled={!expression}
+          >
             <ResetIcon classes={{ root: 'icon' }} />
             <ResetIcon classes={{ root: 'icon' }} />
             {btnTrans('reset')}
             {btnTrans('reset')}
           </CustomButton>
           </CustomButton>
           <CustomButton
           <CustomButton
             variant="contained"
             variant="contained"
             disabled={!expression}
             disabled={!expression}
-            onClick={() => handleQuery()}
+            onClick={() => handleQuery(expression)}
           >
           >
             {btnTrans('query')}
             {btnTrans('query')}
           </CustomButton>
           </CustomButton>

+ 11 - 1
client/src/pages/query/Styles.ts

@@ -37,6 +37,16 @@ export const getQueryStyles = makeStyles((theme: Theme) => ({
         padding: theme.spacing(0, 1.5),
         padding: theme.spacing(0, 1.5),
         backgroundColor: '#F9F9F9',
         backgroundColor: '#F9F9F9',
       },
       },
+      '& .textarea': {
+        width: '100%',
+        '& .MuiInput-underline:before': {
+          borderWidth: 1,
+          borderColor: '#F9F9F9',
+        },
+        '& .MuiInput-underline:after': {
+          borderWidth: 1,
+        },
+      },
     },
     },
 
 
     '& .right': {
     '& .right': {
@@ -61,6 +71,6 @@ export const getQueryStyles = makeStyles((theme: Theme) => ({
     width: '16px',
     width: '16px',
     height: '16px',
     height: '16px',
     position: 'relative',
     position: 'relative',
-    top: '-3px'
+    top: '-3px',
   },
   },
 }));
 }));

+ 25 - 10
client/yarn.lock

@@ -378,7 +378,7 @@
     "@babel/plugin-syntax-jsx" "^7.18.6"
     "@babel/plugin-syntax-jsx" "^7.18.6"
     "@babel/types" "^7.19.0"
     "@babel/types" "^7.19.0"
 
 
-"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7":
+"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7":
   version "7.16.0"
   version "7.16.0"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b"
   integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==
   integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==
@@ -568,14 +568,19 @@
     "@jridgewell/resolve-uri" "3.1.0"
     "@jridgewell/resolve-uri" "3.1.0"
     "@jridgewell/sourcemap-codec" "1.4.14"
     "@jridgewell/sourcemap-codec" "1.4.14"
 
 
-"@loadable/component@^5.15.0":
-  version "5.15.0"
-  resolved "https://registry.yarnpkg.com/@loadable/component/-/component-5.15.0.tgz#48b9524237be553f48b158f8c9152593f3f3fded"
-  integrity sha512-g63rQzypPOZi0BeGsK4ST2MYhsFR+i7bhL8k/McUoWDNMDuTTdUlQ2GACKxqh5sI/dNC/6nVoPrycMnSylnAgQ==
+"@json2csv/formatters@^7.0.1":
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/@json2csv/formatters/-/formatters-7.0.1.tgz#c025f0795f9bbab480de77e2248ab593987296b9"
+  integrity sha512-eCmYKIIoFDXUB0Fotet2RmcoFTtNLXLmSV7j6aEQH/D2GiO749Uan3ts03PtAhXpE11QghxBjS0toXom8VQNBw==
+
+"@json2csv/plainjs@^7.0.1":
+  version "7.0.1"
+  resolved "https://registry.yarnpkg.com/@json2csv/plainjs/-/plainjs-7.0.1.tgz#361d849f04a2a5013c7880738f08b6bc193c24eb"
+  integrity sha512-UAdaZwahrUeYhMYYilJwDsRfE7wDRsmGMsszYH67j8FLD5gZitqG38RXpUgHEH0s6YjsY8iKYWeEQ19WILncFA==
   dependencies:
   dependencies:
-    "@babel/runtime" "^7.7.7"
-    hoist-non-react-statics "^3.3.1"
-    react-is "^16.12.0"
+    "@json2csv/formatters" "^7.0.1"
+    "@streamparser/json" "^0.0.15"
+    lodash.get "^4.4.2"
 
 
 "@material-ui/core@4.11.4":
 "@material-ui/core@4.11.4":
   version "4.11.4"
   version "4.11.4"
@@ -715,6 +720,11 @@
   resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz#8863915676f837d9dad7b76f50cb500c1e9422e9"
   resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz#8863915676f837d9dad7b76f50cb500c1e9422e9"
   integrity sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==
   integrity sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==
 
 
+"@streamparser/json@^0.0.15":
+  version "0.0.15"
+  resolved "https://registry.yarnpkg.com/@streamparser/json/-/json-0.0.15.tgz#405fbe94877ce0cbd3cf650b4d9186a0ec6acd0a"
+  integrity sha512-6oikjkMTYAHGqKmcC9leE4+kY4Ch4eiTImXUN/N4d2bNGBYs0LJ/tfxmpvF5eExSU7iiPlV9jYlADqvj3NWA3Q==
+
 "@svgr/babel-plugin-add-jsx-attribute@^5.4.0":
 "@svgr/babel-plugin-add-jsx-attribute@^5.4.0":
   version "5.4.0"
   version "5.4.0"
   resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906"
   resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906"
@@ -2527,7 +2537,7 @@ highlight.js@^10.4.1, highlight.js@~10.7.0:
   resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
   resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
   integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
   integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
 
 
-hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
+hoist-non-react-statics@^3.3.2:
   version "3.3.2"
   version "3.3.2"
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
   integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
   integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -3011,6 +3021,11 @@ locate-path@^6.0.0:
   dependencies:
   dependencies:
     p-locate "^5.0.0"
     p-locate "^5.0.0"
 
 
+lodash.get@^4.4.2:
+  version "4.4.2"
+  resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+  integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
+
 lodash@^4.17.15:
 lodash@^4.17.15:
   version "4.17.21"
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -3391,7 +3406,7 @@ react-i18next@^12.0.0:
     "@babel/runtime" "^7.14.5"
     "@babel/runtime" "^7.14.5"
     html-parse-stringify "^3.0.1"
     html-parse-stringify "^3.0.1"
 
 
-react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
+react-is@^16.7.0, react-is@^16.8.1:
   version "16.13.1"
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==