Skip to content

Commit

Permalink
[dashboards] New, tittle and slug OR filter (#9435)
Browse files Browse the repository at this point in the history
* [dashboards] New, tittle and slug OR filter

* Update requirements, because of prison bump

* Tests

* Fix tests

* Avoid like filter on empty string value

* merge master brings strict typing to the table
  • Loading branch information
dpgaspar authored Apr 9, 2020
1 parent bb80cea commit b39e78f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
3 changes: 2 additions & 1 deletion superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
DashboardUpdateFailedError,
)
from superset.dashboards.commands.update import UpdateDashboardCommand
from superset.dashboards.filters import DashboardFilter
from superset.dashboards.filters import DashboardFilter, DashboardTitleOrSlugFilter
from superset.dashboards.schemas import (
DashboardPostSchema,
DashboardPutSchema,
Expand Down Expand Up @@ -104,6 +104,7 @@ class DashboardRestApi(BaseSupersetModelRestApi):
"published",
]
search_columns = ("dashboard_title", "slug", "owners", "published")
search_filters = {"dashboard_title": [DashboardTitleOrSlugFilter]}
add_columns = edit_columns
base_order = ("changed_on", "desc")

Expand Down
17 changes: 17 additions & 0 deletions superset/dashboards/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# under the License.
from typing import Any

from flask_babel import lazy_gettext as _
from sqlalchemy import and_, or_
from sqlalchemy.orm.query import Query

Expand All @@ -26,6 +27,22 @@
from superset.views.base import BaseFilter, get_user_roles


class DashboardTitleOrSlugFilter(BaseFilter): # pylint: disable=too-few-public-methods
name = _("Title or Slug")
arg_name = "title_or_slug"

def apply(self, query: Query, value: Any) -> Query:
if not value:
return query
ilike_value = f"%{value}%"
return query.filter(
or_(
Dashboard.dashboard_title.ilike(ilike_value),
Dashboard.slug.ilike(ilike_value),
)
)


class DashboardFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
List dashboards with the following criteria:
Expand Down
37 changes: 37 additions & 0 deletions tests/dashboards/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,43 @@ def test_get_dashboards_filter(self):
db.session.delete(dashboard)
db.session.commit()

def test_get_dashboards_custom_filter(self):
"""
Dashboard API: Test get dashboards custom filter
"""
admin = self.get_user("admin")
dashboard1 = self.insert_dashboard("foo", "ZY_bar", [admin.id])
dashboard2 = self.insert_dashboard("zy_foo", "slug1", [admin.id])
dashboard3 = self.insert_dashboard("foo", "slug1zy_", [admin.id])
dashboard4 = self.insert_dashboard("bar", "foo", [admin.id])

arguments = {
"filters": [
{"col": "dashboard_title", "opr": "title_or_slug", "value": "zy_"}
]
}
self.login(username="admin")
uri = f"api/v1/dashboard/?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)

self.logout()
self.login(username="gamma")
uri = f"api/v1/dashboard/?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(dashboard1)
db.session.delete(dashboard2)
db.session.delete(dashboard3)
db.session.delete(dashboard4)
db.session.commit()

def test_get_dashboards_no_data_access(self):
"""
Dashboard API: Test get dashboards no data access
Expand Down

0 comments on commit b39e78f

Please sign in to comment.