You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by yj...@apache.org on 2021/01/28 01:49:36 UTC
[superset] branch master updated: chore(explore): Reorder dataset
search results based on property relevance (#12770)
This is an automated email from the ASF dual-hosted git repository.
yjc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new c475f6b chore(explore): Reorder dataset search results based on property relevance (#12770)
c475f6b is described below
commit c475f6b17318eb66170e853651b5e59f489c1b0a
Author: Nikola Gigić <ni...@gmail.com>
AuthorDate: Thu Jan 28 02:49:02 2021 +0100
chore(explore): Reorder dataset search results based on property relevance (#12770)
---
.../spec/javascripts/datasource/fixtures.tsx | 93 ++++++++++++++++++++++
.../explore/components/DatasourcePanel_spec.jsx | 58 +++++++++++++-
.../src/explore/components/DatasourcePanel.tsx | 28 +++++--
3 files changed, 168 insertions(+), 11 deletions(-)
diff --git a/superset-frontend/spec/javascripts/datasource/fixtures.tsx b/superset-frontend/spec/javascripts/datasource/fixtures.tsx
new file mode 100644
index 0000000..115b571
--- /dev/null
+++ b/superset-frontend/spec/javascripts/datasource/fixtures.tsx
@@ -0,0 +1,93 @@
+/**
+ * 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.
+ */
+export const columns = [
+ {
+ column_name: 'bootcamp_attend',
+ description: null,
+ expression: null,
+ filterable: true,
+ groupby: true,
+ id: 516,
+ is_dttm: false,
+ python_date_format: null,
+ type: 'DOUBLE PRECISION',
+ verbose_name: null,
+ },
+ {
+ column_name: 'calc_first_time_dev',
+ description: null,
+ expression:
+ 'CASE WHEN is_first_dev_job = 0 THEN "No" WHEN is_first_dev_job = 1 THEN "Yes" END',
+ filterable: true,
+ groupby: true,
+ id: 477,
+ is_dttm: false,
+ python_date_format: null,
+ type: 'STRING',
+ verbose_name: null,
+ },
+ {
+ column_name: 'aaaaaaaaaaa',
+ description: null,
+ expression: null,
+ filterable: true,
+ groupby: true,
+ id: 516,
+ is_dttm: false,
+ python_date_format: null,
+ type: 'DOUBLE PRECISION',
+ verbose_name: null,
+ },
+];
+
+const metricsFiltered = {
+ certified: [
+ {
+ certification_details: null,
+ certified_by: 'user',
+ d3format: null,
+ description: null,
+ expression: '',
+ id: 56,
+ is_certified: true,
+ metric_name: 'metric_end_certified',
+ verbose_name: '',
+ warning_text: null,
+ },
+ ],
+ uncertified: [
+ {
+ certification_details: null,
+ certified_by: null,
+ d3format: null,
+ description: null,
+ expression: '',
+ id: 57,
+ is_certified: false,
+ metric_name: 'metric_end',
+ verbose_name: '',
+ warning_text: null,
+ },
+ ],
+};
+
+export const metrics = [
+ ...metricsFiltered.certified,
+ ...metricsFiltered.uncertified,
+];
diff --git a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx b/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
index 784e105..f9c0960 100644
--- a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
@@ -17,9 +17,11 @@
* under the License.
*/
import React from 'react';
-import { render, screen } from '@testing-library/react';
+import { Simulate } from 'react-dom/test-utils';
+import { render, screen, fireEvent } from '@testing-library/react';
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
import DatasourcePanel from 'src/explore/components/DatasourcePanel';
+import { columns, metrics } from 'spec/javascripts/datasource/fixtures';
describe('datasourcepanel', () => {
const datasource = {
@@ -27,8 +29,8 @@ describe('datasourcepanel', () => {
type: 'table',
uid: '1__table',
id: 1,
- columns: [],
- metrics: [],
+ columns,
+ metrics,
database: {
backend: 'mysql',
name: 'main',
@@ -47,6 +49,14 @@ describe('datasourcepanel', () => {
},
actions: {},
};
+
+ function search(value, input) {
+ fireEvent.change(input, {
+ target: { value },
+ });
+ Simulate.change(input);
+ }
+
it('should render', () => {
const { container } = render(
<ThemeProvider theme={supersetTheme}>
@@ -66,4 +76,46 @@ describe('datasourcepanel', () => {
expect(screen.getByText('Columns')).toBeTruthy();
expect(screen.getByText('Metrics')).toBeTruthy();
});
+
+ it('should render search results', () => {
+ const { container } = render(
+ <ThemeProvider theme={supersetTheme}>
+ <DatasourcePanel {...props} />
+ </ThemeProvider>,
+ );
+ const c = container.getElementsByClassName('option-label');
+
+ expect(c).toHaveLength(5);
+ });
+
+ it('should render 0 search results', () => {
+ const { container } = render(
+ <ThemeProvider theme={supersetTheme}>
+ <DatasourcePanel {...props} />
+ </ThemeProvider>,
+ );
+ const c = container.getElementsByClassName('option-label');
+ const searchInput = screen.getByPlaceholderText('Search Metrics & Columns');
+
+ search('sssssssss', searchInput);
+ setTimeout(() => {
+ expect(c).toHaveLength(0);
+ }, 201);
+ });
+
+ it('should render and sort search results', () => {
+ const { container } = render(
+ <ThemeProvider theme={supersetTheme}>
+ <DatasourcePanel {...props} />
+ </ThemeProvider>,
+ );
+ const c = container.getElementsByClassName('option-label');
+ const searchInput = screen.getByPlaceholderText('Search Metrics & Columns');
+
+ search('end', searchInput);
+ setTimeout(() => {
+ expect(c).toHaveLength(4);
+ expect(c[0].value).toBe('metric_end_certified');
+ }, 201);
+ });
});
diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index 7beebd2..143550c 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -117,30 +117,42 @@ export default function DataSourcePanel({
setList({
columns: matchSorter(columns, value, {
keys: [
- 'verbose_name',
- 'column_name',
{
- key: 'description',
+ key: 'verbose_name',
threshold: rankings.CONTAINS,
},
{
- key: 'expression',
+ key: 'column_name',
threshold: rankings.CONTAINS,
},
+ {
+ key: item =>
+ [item.description, item.expression].map(
+ x => x?.replace(/[_\n\s]+/g, ' ') || '',
+ ),
+ threshold: rankings.CONTAINS,
+ maxRanking: rankings.CONTAINS,
+ },
],
keepDiacritics: true,
}),
metrics: matchSorter(metrics, value, {
keys: [
- 'verbose_name',
- 'metric_name',
{
- key: 'description',
+ key: 'verbose_name',
+ threshold: rankings.CONTAINS,
+ },
+ {
+ key: 'metric_name',
threshold: rankings.CONTAINS,
},
{
- key: 'expression',
+ key: item =>
+ [item.description, item.expression].map(
+ x => x?.replace(/[_\n\s]+/g, ' ') || '',
+ ),
threshold: rankings.CONTAINS,
+ maxRanking: rankings.CONTAINS,
},
],
keepDiacritics: true,