Skip to content

Commit

Permalink
feat: filter with created_by for charts and dashboards (#21199)
Browse files Browse the repository at this point in the history
* feat: filter with created_by for charts and dashboards

* add tests

* update tests

* update tests
  • Loading branch information
lilykuang committed Aug 30, 2022
1 parent 1aa1864 commit 05354a9
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 2 deletions.
2 changes: 2 additions & 0 deletions superset-frontend/src/components/ListView/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ export enum FilterOperator {
chartIsCertified = 'chart_is_certified',
dashboardIsCertified = 'dashboard_is_certified',
datasetIsCertified = 'dataset_is_certified',
dashboardHasCreatedBy = 'dashboard_has_created_by',
chartHasCreatedBy = 'chart_has_created_by',
}
2 changes: 2 additions & 0 deletions superset/charts/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
ChartCertifiedFilter,
ChartFavoriteFilter,
ChartFilter,
ChartHasCreatedByFilter,
)
from superset.charts.schemas import (
CHART_SCHEMAS,
Expand Down Expand Up @@ -205,6 +206,7 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]:
search_filters = {
"id": [ChartFavoriteFilter, ChartCertifiedFilter],
"slice_name": [ChartAllTextFilter],
"created_by": [ChartHasCreatedByFilter],
}

# Will just affect _info endpoint
Expand Down
16 changes: 16 additions & 0 deletions superset/charts/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,19 @@ def apply(self, query: Query, value: Any) -> Query:
models.SqlaTable.id.in_(owner_ids_query),
)
)


class ChartHasCreatedByFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
Custom filter for the GET list that filters all charts created by user
"""

name = _("Has created by")
arg_name = "chart_has_created_by"

def apply(self, query: Query, value: Any) -> Query:
if value is True:
return query.filter(and_(Slice.created_by_fk.isnot(None)))
if value is False:
return query.filter(and_(Slice.created_by_fk.is_(None)))
return query
3 changes: 2 additions & 1 deletion superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
DashboardCertifiedFilter,
DashboardCreatedByMeFilter,
DashboardFavoriteFilter,
DashboardHasCreatedByFilter,
DashboardTitleOrSlugFilter,
FilterRelatedRoles,
)
Expand Down Expand Up @@ -218,7 +219,7 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]:
search_filters = {
"dashboard_title": [DashboardTitleOrSlugFilter],
"id": [DashboardFavoriteFilter, DashboardCertifiedFilter],
"created_by": [DashboardCreatedByMeFilter],
"created_by": [DashboardCreatedByMeFilter, DashboardHasCreatedByFilter],
}
base_order = ("changed_on", "desc")

Expand Down
17 changes: 16 additions & 1 deletion superset/dashboards/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ def apply(self, query: Query, value: Any) -> Query:
if is_feature_enabled("EMBEDDED_SUPERSET") and security_manager.is_guest_user(
g.user
):

guest_user: GuestUser = g.user
embedded_dashboard_ids = [
r["id"]
Expand Down Expand Up @@ -233,3 +232,19 @@ def apply(self, query: Query, value: Any) -> Query:
)
)
return query


class DashboardHasCreatedByFilter(BaseFilter): # pylint: disable=too-few-public-methods
"""
Custom filter for the GET list that filters all dashboards created by user
"""

name = _("Has created by")
arg_name = "dashboard_has_created_by"

def apply(self, query: Query, value: Any) -> Query:
if value is True:
return query.filter(and_(Dashboard.created_by_fk.isnot(None)))
if value is False:
return query.filter(and_(Dashboard.created_by_fk.is_(None)))
return query
28 changes: 28 additions & 0 deletions tests/integration_tests/charts/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1357,3 +1357,31 @@ def test_import_chart_invalid(self):
}
]
}

def test_gets_created_by_user_charts_filter(self):
arguments = {
"filters": [{"col": "id", "opr": "chart_has_created_by", "value": True}],
"keys": ["none"],
"columns": ["slice_name"],
}
self.login(username="admin")

uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 8)

def test_gets_not_created_by_user_charts_filter(self):
arguments = {
"filters": [{"col": "id", "opr": "chart_has_created_by", "value": False}],
"keys": ["none"],
"columns": ["slice_name"],
}
self.login(username="admin")

uri = f"api/v1/chart/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 8)
36 changes: 36 additions & 0 deletions tests/integration_tests/dashboards/api_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1836,3 +1836,39 @@ def test_embedded_dashboards(self):
# get returns 404
resp = self.get_assert_metric(uri, "get_embedded")
self.assertEqual(resp.status_code, 404)

@pytest.mark.usefixtures("create_created_by_admin_dashboards")
def test_gets_created_by_user_dashboards_filter(self):
arguments = {
"filters": [
{"col": "id", "opr": "dashboard_has_created_by", "value": True}
],
"keys": ["none"],
"columns": ["dashboard_title"],
}
self.login(username="admin")

uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 7)

def test_gets_not_created_by_user_dashboards_filter(self):
arguments = {
"filters": [
{"col": "id", "opr": "dashboard_has_created_by", "value": False}
],
"keys": ["none"],
"columns": ["dashboard_title"],
}
dashboard = self.insert_dashboard(f"title", f"slug", [])
self.login(username="admin")

uri = f"api/v1/dashboard/?q={prison.dumps(arguments)}"
rv = self.get_assert_metric(uri, "get_list")
self.assertEqual(rv.status_code, 200)
data = json.loads(rv.data.decode("utf-8"))
self.assertEqual(data["count"], 6)
db.session.delete(dashboard)
db.session.commit()

0 comments on commit 05354a9

Please sign in to comment.