Skip to content

Commit

Permalink
Add archived queries section to queries list.
Browse files Browse the repository at this point in the history
  • Loading branch information
jezdez committed Oct 2, 2018
1 parent ccac41c commit bbb0467
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 68 deletions.
13 changes: 13 additions & 0 deletions client/app/assets/less/redash/redash-newstyle.less
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ body {
}
}

.btn-archived {
color: #d4d4d4;
transition: all .25s ease-in-out;

&:hover, &:focus {
color: @gray-light;
}

.fa-archive {
color: @gray-light;
}
}

.page-header--new .btn-favourite {
font-size: 19px;
}
Expand Down
16 changes: 16 additions & 0 deletions client/app/pages/queries-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class QueriesListCtrl extends ListCtrl {
this.emptyType = 'favorites';
} else if (this.currentPage === 'my') {
this.emptyType = 'my';
} else if (this.currentPage === 'archived') {
this.emptyType = 'archived';
} else {
this.emptyType = 'default';
}
Expand Down Expand Up @@ -94,6 +96,20 @@ export default function init(ngModule) {
},
route,
),
'/queries/archived': extend(
{
title: 'Archived Queries',
resolve: {
currentPage: () => 'archived',
resource: (Query) => {
'ngInject';

return Query.archived.bind(Query);
},
},
},
route,
),
// TODO: setup redirect?
// '/queries/search': _.extend(
};
Expand Down
27 changes: 25 additions & 2 deletions client/app/pages/queries-list/queries-list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<div class="container">
<page-header title="Queries"></page-header>

<div ng-switch="$ctrl.currentPage">
<div ng-switch-when="my"><page-header title="My queries"></page-header></div>
<div ng-switch-when="all"><page-header title="All queries"></page-header></div>
<div ng-switch-when="archived"><page-header title="Archived queries"></page-header></div>
<div ng-switch-when="favorites"><page-header title="Favorite queries"></page-header></div>
</div>
<div class="row">
<div class="col-md-3 list-control-t">
<div class="m-b-10">
Expand All @@ -17,10 +21,19 @@
</span>
Favorites
</a>

<a href="queries/archived" class="list-group-item" ng-class="{active: $ctrl.currentPage == 'archived'}">
<span class="btn-favourite">
<i class="fa fa-archive" aria-hidden="true"></i>
</span>
Archived
</a>

<a href="queries/my" class="list-group-item" ng-if="$ctrl.showMyQueries" ng-class="{active: $ctrl.currentPage == 'my'}">
<img ng-src="{{$ctrl.currentUser.profile_image_url}}" class="profile__image--navbar" width="13" style="margin-right: 0;"
/> My Queries
</a>

</div>

<div ng-if="$ctrl.currentPage != 'my'">
Expand Down Expand Up @@ -51,6 +64,7 @@
<a href="https://redash.io/help/user-guide/querying/writing-queries">query writing documentation</a>.
</div>

<big-message ng-switch-when="archived" message="'Archive queries to list them here.'" icon="'fa-star'" />
<big-message ng-switch-when="favorites" message="'Mark queries as Favorite to list them here.'" icon="'fa-star'" />
<big-message ng-switch-when="search" message="'Sorry, we couldn\'t find anything.'" icon="'fa-search'"></big-message>
<no-tagged-objects-found ng-switch-when="tags" object-type="'queries'" tags="$ctrl.selectedTags" />
Expand Down Expand Up @@ -129,10 +143,19 @@
</span>
Favorites
</a>

<a href="queries/archived" class="list-group-item" ng-class="{active: $ctrl.currentPage == 'archived'}">
<span class="btn-archived">
<i class="fa fa-archive" aria-hidden="true"></i>
</span>
Archived
</a>

<a href="queries/my" class="list-group-item" ng-if="$ctrl.showMyQueries" ng-class="{active: $ctrl.currentPage == 'my'}">
<img ng-src="{{$ctrl.currentUser.profile_image_url}}" class="profile__image--navbar" width="13" style="margin-right: 0;"
/> My Queries
</a>

</div>

<div ng-if="$ctrl.currentPage != 'my'" class="m-b-10">
Expand Down
5 changes: 5 additions & 0 deletions client/app/services/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ function QueryResource(
isArray: true,
url: 'api/queries/recent',
},
archived: {
method: 'get',
isArray: false,
url: 'api/queries/archived',
},
query: {
isArray: false,
},
Expand Down
5 changes: 3 additions & 2 deletions redash/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
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.dashboards import DashboardListResource, DashboardResource, DashboardShareResource, PublicDashboardResource
from redash.handlers.data_sources import DataSourceTypeListResource, DataSourceListResource, DataSourceSchemaResource, DataSourceResource, DataSourcePauseResource, DataSourceTestResource
from redash.handlers.events import EventsResource
from redash.handlers.queries import QueryForkResource, QueryRefreshResource, QueryListResource, QueryRecentResource, QuerySearchResource, QueryResource, MyQueriesResource
from redash.handlers.queries import QueryArchivedResource, QueryForkResource, QueryRefreshResource, QueryListResource, QueryRecentResource, QuerySearchResource, QueryResource, MyQueriesResource
from redash.handlers.query_results import QueryResultListResource, QueryResultResource, JobResource
from redash.handlers.users import UserResource, UserListResource, UserInviteResource, UserResetPasswordResource, UserDisableResource
from redash.handlers.visualizations import VisualizationListResource
Expand Down Expand Up @@ -79,6 +79,7 @@ def json_representation(data, code, headers=None):

api.add_org_resource(QuerySearchResource, '/api/queries/search', endpoint='queries_search')
api.add_org_resource(QueryRecentResource, '/api/queries/recent', endpoint='recent_queries')
api.add_org_resource(QueryArchivedResource, '/api/queries/archived', endpoint='archived_queries')
api.add_org_resource(QueryListResource, '/api/queries', endpoint='queries')
api.add_org_resource(MyQueriesResource, '/api/queries/my', endpoint='my_queries')
api.add_org_resource(QueryRefreshResource, '/api/queries/<query_id>/refresh', endpoint='query_refresh')
Expand Down
2 changes: 1 addition & 1 deletion redash/handlers/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def organization_status(org_slug=None):
'users': models.User.all_not_disabled(current_org).count(),
'alerts': models.Alert.all(group_ids=current_user.group_ids).count(),
'data_sources': models.DataSource.all(current_org, group_ids=current_user.group_ids).count(),
'queries': models.Query.all_queries(current_user.group_ids, current_user.id, drafts=True).count(),
'queries': models.Query.all_queries(current_user.group_ids, current_user.id, include_drafts=True).count(),
'dashboards': models.Dashboard.query.filter(models.Dashboard.org==current_org, models.Dashboard.is_archived==False).count(),
}

Expand Down
125 changes: 76 additions & 49 deletions redash/handlers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,74 @@ def get(self):
return QuerySerializer(results, with_last_modified_by=False, with_user=False).serialize()


class QueryListResource(BaseResource):
class BaseQueryListResource(BaseResource):

def get_queries(self, search_term):
if search_term:
results = models.Query.search(
search_term,
self.current_user.group_ids,
self.current_user.id,
include_drafts=True,
)
else:
results = models.Query.all_queries(
self.current_user.group_ids,
self.current_user.id,
include_drafts=True,
)
return filter_by_tags(results, models.Query.tags)

@require_permission('view_query')
def get(self):
"""
Retrieve a list of queries.
:qparam number page_size: Number of queries to return per page
:qparam number page: Page number to retrieve
:qparam number order: Name of column to order by
:qparam number q: Full text search term
Responds with an array of :ref:`query <query-response-label>` objects.
"""
# See if we want to do full-text search or just regular queries
search_term = request.args.get('q', '')

queries = self.get_queries(search_term)

results = filter_by_tags(queries, models.Query.tags)

# order results according to passed order parameter
ordered_results = order_results(results)

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)

response = paginate(
ordered_results,
page=page,
page_size=page_size,
serializer=QuerySerializer,
with_stats=True,
with_last_modified_by=False
)

if search_term:
self.record_event({
'action': 'search',
'object_type': 'query',
'term': search_term,
})
else:
self.record_event({
'action': 'list',
'object_type': 'query',
})

return response


class QueryListResource(BaseQueryListResource):
@require_permission('create_query')
def post(self):
"""
Expand Down Expand Up @@ -157,66 +224,26 @@ def post(self):

return QuerySerializer(query).serialize()

@require_permission('view_query')
def get(self):
"""
Retrieve a list of queries.

:qparam number page_size: Number of queries to return per page
:qparam number page: Page number to retrieve
:qparam number order: Name of column to order by
:qparam number q: Full text search term
Responds with an array of :ref:`query <query-response-label>` objects.
"""
# See if we want to do full-text search or just regular queries
search_term = request.args.get('q', '')
class QueryArchivedResource(BaseQueryListResource):

def get_queries(self, search_term):
if search_term:
results = models.Query.search(
return models.Query.search(
search_term,
self.current_user.group_ids,
self.current_user.id,
include_drafts=True,
include_drafts=False,
include_archived=True,
)
else:
results = models.Query.all_queries(
return models.Query.all_queries(
self.current_user.group_ids,
self.current_user.id,
drafts=True,
include_drafts=False,
include_archived=True,
)

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

# order results according to passed order parameter
ordered_results = order_results(results)

page = request.args.get('page', 1, type=int)
page_size = request.args.get('page_size', 25, type=int)

response = paginate(
ordered_results,
page=page,
page_size=page_size,
serializer=QuerySerializer,
with_stats=True,
with_last_modified_by=False
)

if search_term:
self.record_event({
'action': 'search',
'object_type': 'query',
'term': search_term,
})
else:
self.record_event({
'action': 'list',
'object_type': 'query',
})

return response


class MyQueriesResource(BaseResource):
@require_permission('view_query')
Expand Down
36 changes: 22 additions & 14 deletions redash/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -923,18 +923,18 @@ def create(cls, **kwargs):
return query

@classmethod
def all_queries(cls, group_ids, user_id=None, drafts=False):
def all_queries(cls, group_ids, user_id=None, include_drafts=False, include_archived=False):
query_ids = (
db.session
.query(distinct(cls.id))
.join(
DataSourceGroup,
Query.data_source_id == DataSourceGroup.data_source_id
)
.filter(Query.is_archived == False)
.filter(Query.is_archived.is_(include_archived))
.filter(DataSourceGroup.group_id.in_(group_ids))
)
q = (
queries = (
cls
.query
.options(
Expand All @@ -960,19 +960,19 @@ def all_queries(cls, group_ids, user_id=None, drafts=False):
.order_by(Query.created_at.desc())
)

if not drafts:
q = q.filter(
if not include_drafts:
queries = queries.filter(
or_(
Query.is_draft == False,
Query.is_draft.is_(False),
Query.user_id == user_id
)
)
return q
return queries

@classmethod
def favorites(cls, user, base_query=None):
if base_query == None:
base_query = cls.all_queries(user.group_ids, user.id, drafts=True)
base_query = cls.all_queries(user.group_ids, user.id, include_drafts=True)
return base_query.join((Favorite, and_(Favorite.object_type==u'Query', Favorite.object_id==Query.id))).filter(Favorite.user_id==user.id)

@classmethod
Expand All @@ -998,10 +998,12 @@ def by_user(cls, user):

@classmethod
def outdated_queries(cls):
queries = (db.session.query(Query)
.options(joinedload(Query.latest_query_data).load_only('retrieved_at'))
.filter(Query.schedule != None)
.order_by(Query.id))
queries = (
db.session.query(Query)
.options(joinedload(Query.latest_query_data).load_only('retrieved_at'))
.filter(Query.schedule != None)
.order_by(Query.id)
)

now = utils.utcnow()
outdated_queries = {}
Expand All @@ -1022,8 +1024,14 @@ def outdated_queries(cls):
return outdated_queries.values()

@classmethod
def search(cls, term, group_ids, user_id=None, include_drafts=False, limit=None):
all_queries = cls.all_queries(group_ids, user_id=user_id, drafts=include_drafts)
def search(cls, term, group_ids, user_id=None, include_drafts=False,
limit=None, include_archived=False):
all_queries = cls.all_queries(
group_ids,
user_id=user_id,
include_drafts=include_drafts,
include_archived=include_archived,
)
# sort the result using the weight as defined in the search vector column
return all_queries.search(term, sort=True).limit(limit)

Expand Down

0 comments on commit bbb0467

Please sign in to comment.