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

dpgaspar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 622561f  [charts] New, custom filter for name OR description (#9492)
622561f is described below

commit 622561f7568a209327f6f16f93ac8b40f6bc1937
Author: Daniel Vaz Gaspar <[email protected]>
AuthorDate: Sat Apr 11 07:25:54 2020 +0100

    [charts] New, custom filter for name OR description (#9492)
    
    * [charts] New, custom filter for name OR description
    
    * Improve test
---
 superset/charts/api.py     |  3 ++-
 superset/charts/filters.py | 20 +++++++++++++++++++
 tests/charts/api_tests.py  | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/superset/charts/api.py b/superset/charts/api.py
index fb78cd9..74776c1 100644
--- a/superset/charts/api.py
+++ b/superset/charts/api.py
@@ -36,7 +36,7 @@ from superset.charts.commands.exceptions import (
     ChartUpdateFailedError,
 )
 from superset.charts.commands.update import UpdateChartCommand
-from superset.charts.filters import ChartFilter
+from superset.charts.filters import ChartFilter, ChartNameOrDescriptionFilter
 from superset.charts.schemas import (
     ChartPostSchema,
     ChartPutSchema,
@@ -111,6 +111,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
     )
     base_order = ("changed_on", "desc")
     base_filters = [["id", ChartFilter, lambda: []]]
+    search_filters = {"slice_name": [ChartNameOrDescriptionFilter]}
 
     # Will just affect _info endpoint
     edit_columns = ["slice_name"]
diff --git a/superset/charts/filters.py b/superset/charts/filters.py
index a35ba29..94ae2ad 100644
--- a/superset/charts/filters.py
+++ b/superset/charts/filters.py
@@ -16,13 +16,33 @@
 # under the License.
 from typing import Any
 
+from flask_babel import lazy_gettext as _
 from sqlalchemy import or_
 from sqlalchemy.orm.query import Query
 
 from superset import security_manager
+from superset.models.slice import Slice
 from superset.views.base import BaseFilter
 
 
+class ChartNameOrDescriptionFilter(
+    BaseFilter
+):  # pylint: disable=too-few-public-methods
+    name = _("Name or Description")
+    arg_name = "name_or_description"
+
+    def apply(self, query: Query, value: Any) -> Query:
+        if not value:
+            return query
+        ilike_value = f"%{value}%"
+        return query.filter(
+            or_(
+                Slice.slice_name.ilike(ilike_value),
+                Slice.description.ilike(ilike_value),
+            )
+        )
+
+
 class ChartFilter(BaseFilter):  # pylint: disable=too-few-public-methods
     def apply(self, query: Query, value: Any) -> Query:
         if security_manager.all_datasource_access():
diff --git a/tests/charts/api_tests.py b/tests/charts/api_tests.py
index 450e993..257b89b 100644
--- a/tests/charts/api_tests.py
+++ b/tests/charts/api_tests.py
@@ -566,6 +566,56 @@ class ChartApiTests(SupersetTestCase, 
ApiOwnersTestCaseMixin):
         data = json.loads(rv.data.decode("utf-8"))
         self.assertEqual(data["count"], 5)
 
+    def test_get_charts_custom_filter(self):
+        """
+            Chart API: Test get charts custom filter
+        """
+        admin = self.get_user("admin")
+        chart1 = self.insert_chart("foo", [admin.id], 1, description="ZY_bar")
+        chart2 = self.insert_chart("zy_foo", [admin.id], 1, 
description="desc1")
+        chart3 = self.insert_chart("foo", [admin.id], 1, 
description="desc1zy_")
+        chart4 = self.insert_chart("bar", [admin.id], 1, description="foo")
+
+        arguments = {
+            "filters": [
+                {"col": "slice_name", "opr": "name_or_description", "value": 
"zy_"}
+            ],
+            "order_column": "slice_name",
+            "order_direction": "asc",
+        }
+        self.login(username="admin")
+        uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
+        rv = self.client.get(uri)
+        self.assertEqual(rv.status_code, 200)
+        data = json.loads(rv.data.decode("utf-8"))
+        self.assertEqual(data["count"], 3)
+
+        expected_response = [
+            {"description": "ZY_bar", "slice_name": "foo",},
+            {"description": "desc1zy_", "slice_name": "foo",},
+            {"description": "desc1", "slice_name": "zy_foo",},
+        ]
+        for index, item in enumerate(data["result"]):
+            self.assertEqual(
+                item["description"], expected_response[index]["description"]
+            )
+            self.assertEqual(item["slice_name"], 
expected_response[index]["slice_name"])
+
+        self.logout()
+        self.login(username="gamma")
+        uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
+        rv = self.client.get(uri)
+        self.assertEqual(rv.status_code, 200)
+        data = json.loads(rv.data.decode("utf-8"))
+        self.assertEqual(data["count"], 0)
+
+        # rollback changes
+        db.session.delete(chart1)
+        db.session.delete(chart2)
+        db.session.delete(chart3)
+        db.session.delete(chart4)
+        db.session.commit()
+
     def test_get_charts_page(self):
         """
             Chart API: Test get charts filter

Reply via email to