Browse Source

Fix copy as json feature

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
ryjiang 1 year ago
parent
commit
02ce1ab007

+ 3 - 3
client/src/components/grid/Table.tsx

@@ -243,7 +243,7 @@ const EnhancedTable: FC<TableType> = props => {
                                       }}
                                       }}
                                     >
                                     >
                                       {colDef.formatter ? (
                                       {colDef.formatter ? (
-                                        colDef.formatter(row)
+                                        colDef.formatter(row, row[colDef.id], i)
                                       ) : (
                                       ) : (
                                         <Typography title={row[colDef.id]}>
                                         <Typography title={row[colDef.id]}>
                                           {row[colDef.id]}
                                           {row[colDef.id]}
@@ -251,8 +251,8 @@ const EnhancedTable: FC<TableType> = props => {
                                       )}
                                       )}
                                     </Button>
                                     </Button>
                                   ) : colDef.formatter ? (
                                   ) : colDef.formatter ? (
-                                    colDef.formatter(row)
-                                  ) : (
+                                    colDef.formatter(row, row[colDef.id], i)
+                                    ) : (
                                     <Typography title={row[colDef.id]}>
                                     <Typography title={row[colDef.id]}>
                                       {row[colDef.id]}
                                       {row[colDef.id]}
                                     </Typography>
                                     </Typography>

+ 1 - 1
client/src/components/grid/Types.ts

@@ -111,7 +111,7 @@ export type ColDefinitionsType = {
     data?: any
     data?: any
   ) => void;
   ) => void;
   getStyle?: (data: any) => {};
   getStyle?: (data: any) => {};
-  formatter?: (data: any) => any;
+  formatter?: (data: any, cellData?: any, cellIndex?: number) => any;
 
 
   onConnect?: (
   onConnect?: (
     e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
     e: React.MouseEvent<HTMLButtonElement, MouseEvent>,

+ 2 - 0
client/src/hooks/Query.ts

@@ -13,6 +13,7 @@ export const useQuery = (params: {
     fields: [],
     fields: [],
     primaryKey: { value: '', type: DataTypeStringEnum.Int64 },
     primaryKey: { value: '', type: DataTypeStringEnum.Int64 },
     loaded: false,
     loaded: false,
+    data: null
   });
   });
   const [consistencyLevel, setConsistencyLevel] = useState<string>('Bounded');
   const [consistencyLevel, setConsistencyLevel] = useState<string>('Bounded');
   const [currentPage, setCurrentPage] = useState<number>(0);
   const [currentPage, setCurrentPage] = useState<number>(0);
@@ -136,6 +137,7 @@ export const useQuery = (params: {
       fields: nameList as any[],
       fields: nameList as any[],
       primaryKey: { value: primaryKey['name'], type: primaryKey['fieldType'] },
       primaryKey: { value: primaryKey['name'], type: primaryKey['fieldType'] },
       loaded: collection.state === LOAD_STATE.LoadStateLoaded,
       loaded: collection.state === LOAD_STATE.LoadStateLoaded,
+      data: collection
     });
     });
   };
   };
 
 

+ 30 - 16
client/src/pages/query/Query.tsx

@@ -1,10 +1,10 @@
 import { useState, useEffect, useRef, useContext } from 'react';
 import { useState, useEffect, useRef, useContext } from 'react';
-import { TextField } from '@material-ui/core';
+import { TextField, Typography } from '@material-ui/core';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { useParams } from 'react-router-dom';
 import { useParams } from 'react-router-dom';
 import { rootContext } from '@/context';
 import { rootContext } from '@/context';
 import { DataService } from '@/http';
 import { DataService } from '@/http';
-import { useQuery, useSearchResult } from '@/hooks';
+import { useQuery } from '@/hooks';
 import { saveCsvAs } from '@/utils';
 import { saveCsvAs } from '@/utils';
 import icons from '@/components/icons/Icons';
 import icons from '@/components/icons/Icons';
 import CustomButton from '@/components/customButton/CustomButton';
 import CustomButton from '@/components/customButton/CustomButton';
@@ -25,6 +25,7 @@ import {
 import CustomSelector from '@/components/customSelector/CustomSelector';
 import CustomSelector from '@/components/customSelector/CustomSelector';
 import EmptyDataDialog from '../dialogs/EmptyDataDialog';
 import EmptyDataDialog from '../dialogs/EmptyDataDialog';
 import ImportSampleDialog from '../dialogs/ImportSampleDialog';
 import ImportSampleDialog from '../dialogs/ImportSampleDialog';
+import { detectItemType } from '@/utils';
 
 
 const Query = () => {
 const Query = () => {
   // get collection name from url
   // get collection name from url
@@ -110,6 +111,7 @@ const Query = () => {
     expr,
     expr,
     queryResult,
     queryResult,
     setPageSize,
     setPageSize,
+    consistencyLevel,
     setConsistencyLevel,
     setConsistencyLevel,
     setCurrentPage,
     setCurrentPage,
     setExpr,
     setExpr,
@@ -130,9 +132,6 @@ const Query = () => {
     },
     },
   });
   });
 
 
-  // Format result list
-  const queryResultMemo = useSearchResult(queryResult.data);
-
   // Toolbar settings
   // Toolbar settings
   const toolbarConfigs: ToolBarConfig[] = [
   const toolbarConfigs: ToolBarConfig[] = [
     {
     {
@@ -152,6 +151,7 @@ const Query = () => {
                 defaultSelectedCollection={collectionName}
                 defaultSelectedCollection={collectionName}
                 // user can't select partition on collection page, so default value is ''
                 // user can't select partition on collection page, so default value is ''
                 defaultSelectedPartition={''}
                 defaultSelectedPartition={''}
+                collections={[collection.data]}
                 onInsert={() => {}}
                 onInsert={() => {}}
               />
               />
             ),
             ),
@@ -223,7 +223,7 @@ const Query = () => {
       type: 'button',
       type: 'button',
       btnVariant: 'text',
       btnVariant: 'text',
       onClick: async () => {
       onClick: async () => {
-        const json = JSON.stringify(selectedData);
+        let json = JSON.stringify(selectedData);
         try {
         try {
           await navigator.clipboard.writeText(json);
           await navigator.clipboard.writeText(json);
           alert(`${selectedData.length} rows copied to clipboard`);
           alert(`${selectedData.length} rows copied to clipboard`);
@@ -324,7 +324,7 @@ const Query = () => {
           {/* </div> */}
           {/* </div> */}
           <CustomSelector
           <CustomSelector
             options={CONSISTENCY_LEVEL_OPTIONS}
             options={CONSISTENCY_LEVEL_OPTIONS}
-            value={collection.consistencyLevel}
+            value={consistencyLevel}
             label={collectionTrans('consistency')}
             label={collectionTrans('consistency')}
             wrapperClass={classes.selector}
             wrapperClass={classes.selector}
             disabled={!collection.loaded}
             disabled={!collection.loaded}
@@ -363,18 +363,32 @@ const Query = () => {
       </div>
       </div>
       <AttuGrid
       <AttuGrid
         toolbarConfigs={[]}
         toolbarConfigs={[]}
-        colDefinitions={collection.fields.map((i: any) => ({
-          id: i.name,
-          align: 'left',
-          disablePadding: false,
-          needCopy: true,
-          label:
-            i.name === DYNAMIC_FIELD ? searchTrans('dynamicFields') : i.name,
-        }))}
+        colDefinitions={collection.fields.map((i: any) => {
+          return {
+            id: i.name,
+            align: 'left',
+            disablePadding: false,
+            needCopy: true,
+            formatter(_: any, cellData: any) {
+              const itemType = detectItemType(cellData);
+              switch (itemType) {
+                case 'json':
+                case 'array':
+                case 'bool':
+                  const res = JSON.stringify(cellData);
+                  return <Typography title={res}>{res}</Typography>;
+                default:
+                  return cellData;
+              }
+            },
+            label:
+              i.name === DYNAMIC_FIELD ? searchTrans('dynamicFields') : i.name,
+          };
+        })}
         primaryKey={collection.primaryKey.value}
         primaryKey={collection.primaryKey.value}
         openCheckBox={true}
         openCheckBox={true}
         isLoading={!!tableLoading}
         isLoading={!!tableLoading}
-        rows={queryResultMemo}
+        rows={queryResult.data}
         rowCount={total}
         rowCount={total}
         selected={selectedData}
         selected={selectedData}
         setSelected={onSelectChange}
         setSelected={onSelectChange}

+ 7 - 2
client/src/utils/Common.ts

@@ -1,5 +1,6 @@
 import { saveAs } from 'file-saver';
 import { saveAs } from 'file-saver';
 import { Parser } from '@json2csv/plainjs';
 import { Parser } from '@json2csv/plainjs';
+import { csv } from 'd3';
 
 
 export const copyToCommand = (
 export const copyToCommand = (
   value: string,
   value: string,
@@ -80,10 +81,14 @@ export const sleep = (ms: number) => {
 export const detectItemType = (item: unknown) => {
 export const detectItemType = (item: unknown) => {
   if (Array.isArray(item)) {
   if (Array.isArray(item)) {
     return 'array';
     return 'array';
-  } else if (typeof item === 'object' && item !== null) {
-    return 'json';
+  } else if (typeof item === 'string') {
+    return 'string';
+  } else if (typeof item === 'number') {
+    return 'number';
   } else if (typeof item === 'boolean') {
   } else if (typeof item === 'boolean') {
     return 'bool';
     return 'bool';
+  } else if (typeof item === 'object' && item !== null) {
+    return 'json';
   } else {
   } else {
     return 'unknown';
     return 'unknown';
   }
   }