Skip to content

Commit

Permalink
Fix: order dashboard favorites (#3552)
Browse files Browse the repository at this point in the history
## What type of PR is this? (check all applicable)

- [x] Refactor
- [x] Bug Fix

## Description

Move favorites list handlers to their relevant modules (`redash.handlers.queries` and `redash.handlers.dashboards`) and applied `order_results` to dashboards.
  • Loading branch information
arikfr authored and jezdez committed Mar 7, 2019
1 parent e4c933a commit dfa48ca
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 96 deletions.
67 changes: 48 additions & 19 deletions redash/handlers/api.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,64 @@
from flask import make_response
from flask_restful import Api
from werkzeug.wrappers import Response
from flask import make_response

from redash.utils import json_dumps
from redash.handlers.alerts import (AlertListResource, AlertResource,
AlertSubscriptionListResource,
AlertSubscriptionResource)
from redash.handlers.base import org_scoped_rule
from redash.handlers.permissions import ObjectPermissionsListResource, CheckPermissionResource
from redash.handlers.alerts import AlertResource, AlertListResource, AlertSubscriptionListResource, AlertSubscriptionResource
from redash.handlers.dashboards import DashboardListResource, DashboardResource, DashboardShareResource, PublicDashboardResource
from redash.handlers.data_sources import DataSourceTypeListResource, DataSourceListResource, DataSourceSchemaResource, DataSourceResource, DataSourcePauseResource, DataSourceTestResource
from redash.handlers.dashboards import (DashboardFavoriteListResource,
DashboardListResource,
DashboardResource,
DashboardShareResource,
DashboardTagsResource,
PublicDashboardResource)
from redash.handlers.data_sources import (DataSourceListResource,
DataSourcePauseResource,
DataSourceResource,
DataSourceSchemaResource,
DataSourceTestResource,
DataSourceTypeListResource)
from redash.handlers.destinations import (DestinationListResource,
DestinationResource,
DestinationTypeListResource)
from redash.handlers.events import EventsResource
from redash.handlers.queries import QueryArchiveResource, QueryForkResource, QueryRefreshResource, QueryListResource, QueryRecentResource, QuerySearchResource, QueryResource, MyQueriesResource
from redash.handlers.query_results import QueryResultListResource, QueryResultDropdownResource, QueryResultResource, JobResource
from redash.handlers.users import UserResource, UserListResource, UserInviteResource, UserResetPasswordResource, UserDisableResource, UserRegenerateApiKeyResource
from redash.handlers.visualizations import VisualizationListResource
from redash.handlers.visualizations import VisualizationResource
from redash.handlers.widgets import WidgetResource, WidgetListResource
from redash.handlers.groups import GroupListResource, GroupResource, GroupMemberListResource, GroupMemberResource, \
GroupDataSourceListResource, GroupDataSourceResource
from redash.handlers.destinations import DestinationTypeListResource, DestinationResource, DestinationListResource
from redash.handlers.query_snippets import QuerySnippetListResource, QuerySnippetResource
from redash.handlers.favorites import (DashboardFavoriteResource,
QueryFavoriteResource)
from redash.handlers.groups import (GroupDataSourceListResource,
GroupDataSourceResource, GroupListResource,
GroupMemberListResource,
GroupMemberResource, GroupResource)
from redash.handlers.permissions import (CheckPermissionResource,
ObjectPermissionsListResource)
from redash.handlers.queries import (MyQueriesResource, QueryArchiveResource,
QueryFavoriteListResource,
QueryForkResource, QueryListResource,
QueryRecentResource, QueryRefreshResource,
QueryResource, QuerySearchResource,
QueryTagsResource)
from redash.handlers.query_results import (JobResource,
QueryResultDropdownResource,
QueryResultListResource,
QueryResultResource)
from redash.handlers.query_snippets import (QuerySnippetListResource,
QuerySnippetResource)
from redash.handlers.settings import OrganizationSettings
from redash.handlers.favorites import QueryFavoriteListResource, QueryFavoriteResource, DashboardFavoriteListResource, DashboardFavoriteResource
from redash.handlers.queries import QueryTagsResource
from redash.handlers.dashboards import DashboardTagsResource
from redash.handlers.users import (UserDisableResource, UserInviteResource,
UserListResource,
UserRegenerateApiKeyResource,
UserResetPasswordResource, UserResource)
from redash.handlers.visualizations import (VisualizationListResource,
VisualizationResource)
from redash.handlers.widgets import WidgetListResource, WidgetResource
from redash.utils import json_dumps


class ApiExt(Api):
def add_org_resource(self, resource, *urls, **kwargs):
urls = [org_scoped_rule(url) for url in urls]
return self.add_resource(resource, *urls, **kwargs)


api = ApiExt()


Expand Down
34 changes: 34 additions & 0 deletions redash/handlers/dashboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,37 @@ def get(self):
for name, count in tags
]
}


class DashboardFavoriteListResource(BaseResource):
def get(self):
search_term = request.args.get('q')

if search_term:
base_query = models.Dashboard.search(self.current_org, self.current_user.group_ids, self.current_user.id, search_term)
favorites = models.Dashboard.favorites(self.current_user, base_query=base_query)
else:
favorites = models.Dashboard.favorites(self.current_user)

favorites = filter_by_tags(favorites, models.Dashboard.tags)

# order results according to passed order parameter,
# special-casing search queries where the database
# provides an order by search rank
favorites = order_results(favorites, fallback=bool(search_term))

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)
response = paginate(favorites, page, page_size, serialize_dashboard)

self.record_event({
'action': 'load_favorites',
'object_type': 'dashboard',
'params': {
'q': search_term,
'tags': request.args.getlist('tags'),
'page': page
}
})

return response
83 changes: 6 additions & 77 deletions redash/handlers/favorites.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,10 @@
from flask import request
from redash import models
from redash.permissions import require_access, view_only
from redash.handlers.base import BaseResource, get_object_or_404, filter_by_tags, paginate
from redash.handlers.queries import order_results
from redash.serializers import QuerySerializer, serialize_dashboard

from sqlalchemy.exc import IntegrityError


class QueryFavoriteListResource(BaseResource):
def get(self):
search_term = request.args.get('q')

if search_term:
base_query = models.Query.search(search_term, self.current_user.group_ids, include_drafts=True, limit=None)
favorites = models.Query.favorites(self.current_user, base_query=base_query)
else:
favorites = models.Query.favorites(self.current_user)

favorites = filter_by_tags(favorites, models.Query.tags)

# order results according to passed order parameter,
# special-casing search queries where the database
# provides an order by search rank
ordered_favorites = order_results(favorites, fallback=bool(search_term))

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)
response = paginate(
ordered_favorites,
page,
page_size,
QuerySerializer,
with_stats=True,
with_last_modified_by=False,
)

self.record_event({
'action': 'load_favorites',
'object_type': 'query',
'params': {
'q': search_term,
'tags': request.args.getlist('tags'),
'page': page
}
})

return response
from redash import models
from redash.handlers.base import (BaseResource,
get_object_or_404, paginate)
from redash.permissions import require_access, view_only


class QueryFavoriteResource(BaseResource):
Expand Down Expand Up @@ -78,7 +36,7 @@ def delete(self, query_id):
models.Favorite.query.filter(
models.Favorite.object_id == query_id,
models.Favorite.object_type == u'Query',
models.Favorite.user==self.current_user,
models.Favorite.user == self.current_user,
).delete()
models.db.session.commit()

Expand All @@ -89,35 +47,6 @@ def delete(self, query_id):
})


class DashboardFavoriteListResource(BaseResource):
def get(self):
search_term = request.args.get('q')

if search_term:
base_query = models.Dashboard.search(self.current_org, self.current_user.group_ids, self.current_user.id, search_term)
favorites = models.Dashboard.favorites(self.current_user, base_query=base_query)
else:
favorites = models.Dashboard.favorites(self.current_user)

favorites = filter_by_tags(favorites, models.Dashboard.tags)

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)
response = paginate(favorites, page, page_size, serialize_dashboard)

self.record_event({
'action': 'load_favorites',
'object_type': 'dashboard',
'params': {
'q': search_term,
'tags': request.args.getlist('tags'),
'page': page
}
})

return response


class DashboardFavoriteResource(BaseResource):
def post(self, object_id):
dashboard = get_object_or_404(models.Dashboard.get_by_slug_and_org, object_id, self.current_org)
Expand All @@ -140,7 +69,7 @@ def post(self, object_id):

def delete(self, object_id):
dashboard = get_object_or_404(models.Dashboard.get_by_slug_and_org, object_id, self.current_org)
models.Favorite.query.filter(models.Favorite.object==dashboard, models.Favorite.user==self.current_user).delete()
models.Favorite.query.filter(models.Favorite.object == dashboard, models.Favorite.user == self.current_user).delete()
models.db.session.commit()
self.record_event({
'action': 'unfavorite',
Expand Down
41 changes: 41 additions & 0 deletions redash/handlers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,44 @@ def get(self):
for name, count in tags
]
}


class QueryFavoriteListResource(BaseResource):
def get(self):
search_term = request.args.get('q')

if search_term:
base_query = models.Query.search(search_term, self.current_user.group_ids, include_drafts=True, limit=None)
favorites = models.Query.favorites(self.current_user, base_query=base_query)
else:
favorites = models.Query.favorites(self.current_user)

favorites = filter_by_tags(favorites, models.Query.tags)

# order results according to passed order parameter,
# special-casing search queries where the database
# provides an order by search rank
ordered_favorites = order_results(favorites, fallback=bool(search_term))

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)
response = paginate(
ordered_favorites,
page,
page_size,
QuerySerializer,
with_stats=True,
with_last_modified_by=False,
)

self.record_event({
'action': 'load_favorites',
'object_type': 'query',
'params': {
'q': search_term,
'tags': request.args.getlist('tags'),
'page': page
}
})

return response

0 comments on commit dfa48ca

Please sign in to comment.