You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/01/25 13:12:11 UTC

[superset] 35/38: feat(explore): better search for dataset pane (#12675)

This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 8d80262bed8fdd7b76fb8d819bf20be150b18bb7
Author: Jesse Yang <je...@airbnb.com>
AuthorDate: Fri Jan 22 14:26:55 2021 -0800

    feat(explore): better search for dataset pane (#12675)
    
    1. Upgrade match-sorter from 4.1.0 to 6.1.0
    2. Add a debounce delay of 200 milliseconds to reduce excessive rendering (and searching)
    3. Set keepDiacritics to true to improve performance
    4. Display count of filtered results in "Showing x of xx", instead of the total results
    5. Rank certified metrics to the top
---
 superset-frontend/package-lock.json                | 25 ++++++++--
 superset-frontend/package.json                     |  2 +-
 .../src/explore/components/DatasourcePanel.tsx     | 58 ++++++++++++++++------
 superset-frontend/tsconfig.json                    |  2 +-
 4 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 779c3ac..2428175 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -19063,10 +19063,27 @@
         "xss": "^1.0.6"
       },
       "dependencies": {
+        "@babel/runtime": {
+          "version": "7.12.5",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
+          "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
         "d3-array": {
           "version": "2.9.1",
           "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
           "integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
+        },
+        "match-sorter": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
+          "integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
+          "requires": {
+            "@babel/runtime": "^7.10.5",
+            "remove-accents": "0.4.2"
+          }
         }
       }
     },
@@ -39439,11 +39456,11 @@
       }
     },
     "match-sorter": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
-      "integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.1.0.tgz",
+      "integrity": "sha512-sKPMf4kbF7Dm5Crx0bbfLpokK68PUJ/0STUIOPa1ZmTZEA3lCaPK3gapQR573oLmvdkTfGojzySkIwuq6Z6xRQ==",
       "requires": {
-        "@babel/runtime": "^7.10.5",
+        "@babel/runtime": "^7.12.5",
         "remove-accents": "0.4.2"
       },
       "dependencies": {
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 16b83d0..26cc5e7 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -120,7 +120,7 @@
     "json-stringify-pretty-compact": "^2.0.0",
     "lodash": "^4.17.20",
     "lodash-es": "^4.17.14",
-    "match-sorter": "^4.1.0",
+    "match-sorter": "^6.1.0",
     "mathjs": "^8.0.1",
     "memoize-one": "^5.1.1",
     "moment": "^2.26.0",
diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index 37ab1e9..dd81ce0 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -24,7 +24,8 @@ import {
   MetricOption,
   ControlType,
 } from '@superset-ui/chart-controls';
-import matchSorter from 'match-sorter';
+import { debounce } from 'lodash';
+import { matchSorter, rankings } from 'match-sorter';
 import { ExploreActions } from '../actions/exploreActions';
 import Control from './Control';
 
@@ -164,36 +165,65 @@ const LabelContainer = styled.div`
   }
 `;
 
-const DataSourcePanel = ({
+export default function DataSourcePanel({
   datasource,
   controls: { datasource: datasourceControl },
   actions,
-}: Props) => {
+}: Props) {
   const { columns, metrics } = datasource;
   const [lists, setList] = useState({
     columns,
     metrics,
   });
-  const search = ({ target: { value } }: { target: { value: string } }) => {
+
+  const search = debounce((value: string) => {
     if (value === '') {
       setList({ columns, metrics });
       return;
     }
     setList({
       columns: matchSorter(columns, value, {
-        keys: ['column_name', 'expression', 'description', 'verbose_name'],
+        keys: [
+          'verbose_name',
+          'column_name',
+          {
+            key: 'description',
+            threshold: rankings.CONTAINS,
+          },
+          {
+            key: 'expression',
+            threshold: rankings.CONTAINS,
+          },
+        ],
+        keepDiacritics: true,
       }),
       metrics: matchSorter(metrics, value, {
-        keys: ['metric_name', 'expression', 'description', 'verbose_name'],
+        keys: [
+          'verbose_name',
+          'metric_name',
+          {
+            key: 'description',
+            threshold: rankings.CONTAINS,
+          },
+          {
+            key: 'expression',
+            threshold: rankings.CONTAINS,
+          },
+        ],
+        keepDiacritics: true,
+        baseSort: (a, b) =>
+          Number(b.item.is_certified) - Number(a.item.is_certified) ||
+          String(a.rankedValue).localeCompare(b.rankedValue),
       }),
     });
-  };
+  }, 200);
+
   useEffect(() => {
     setList({
       columns,
       metrics,
     });
-  }, [datasource]);
+  }, [columns, datasource, metrics]);
 
   const metricSlice = lists.metrics.slice(0, 50);
   const columnSlice = lists.columns.slice(0, 50);
@@ -209,7 +239,9 @@ const DataSourcePanel = ({
       />
       <input
         type="text"
-        onChange={search}
+        onChange={evt => {
+          search(evt.target.value);
+        }}
         className="form-control input-md"
         placeholder={t('Search Metrics & Columns')}
       />
@@ -224,7 +256,7 @@ const DataSourcePanel = ({
             key="metrics"
           >
             <div className="field-length">
-              {t(`Showing %s of %s`, metricSlice.length, metrics.length)}
+              {t(`Showing %s of %s`, metricSlice.length, lists.metrics.length)}
             </div>
             {metricSlice.map(m => (
               <LabelContainer key={m.metric_name} className="column">
@@ -237,7 +269,7 @@ const DataSourcePanel = ({
             key="column"
           >
             <div className="field-length">
-              {t(`Showing %s of %s`, columnSlice.length, columns.length)}
+              {t(`Showing %s of %s`, columnSlice.length, lists.columns.length)}
             </div>
             {columnSlice.map(col => (
               <LabelContainer key={col.column_name} className="column">
@@ -249,6 +281,4 @@ const DataSourcePanel = ({
       </div>
     </DatasourceContainer>
   );
-};
-
-export default DataSourcePanel;
+}
diff --git a/superset-frontend/tsconfig.json b/superset-frontend/tsconfig.json
index af1fc29..ff43496 100644
--- a/superset-frontend/tsconfig.json
+++ b/superset-frontend/tsconfig.json
@@ -27,7 +27,7 @@
       ],
       // for supressing errors caused by incompatible @types/react when `npm link`
       // Ref: https://github.com/Microsoft/typescript/issues/6496#issuecomment-384786222
-      "*": ["./node_modules/@types/*", "*"]
+      "react": ["./node_modules/@types/react"]
     },
     "skipLibCheck": true,
     "sourceMap": true,