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,