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 Jan 25, 2019
1 parent b0b4d5e commit 914f827
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 77 deletions.
21 changes: 17 additions & 4 deletions client/app/assets/less/redash/redash-newstyle.less
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ body {
cursor: pointer;
}

.btn-favourite {
.btn-favourite, .btn-archive {
font-size: 15px;
}
}
Expand All @@ -194,7 +194,7 @@ body {
}
}

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

Expand All @@ -207,7 +207,20 @@ body {
}
}

.page-header--new .btn-favourite {
.btn-archive {
color: #d4d4d4;
transition: all .25s ease-in-out;

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

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

.page-header--new .btn-favourite, .page-header--new .btn-archive {
font-size: 19px;
}

Expand Down Expand Up @@ -243,7 +256,7 @@ body {
}
}

.navbar li a .btn-favourite .fa {
.navbar li a .btn-favourite .fa, .navbar li a .btn-archive .fa {
font-size: 100%;
}

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 === 'archive') {
this.emptyType = 'archive';
} else {
this.emptyType = 'default';
}
Expand Down Expand Up @@ -94,6 +96,20 @@ export default function init(ngModule) {
},
route,
),
'/queries/archive': extend(
{
title: 'Archived Queries',
resolve: {
currentPage: () => 'archive',
resource: (Query) => {
'ngInject';

return Query.archive.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="archive"><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/archive" class="list-group-item" ng-class="{active: $ctrl.currentPage == 'archive'}">
<span class="btn-archive">
<i class="fa fa-archive" aria-hidden="true"></i>
</span>
Archive
</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="archive" message="'Archived queries will be listed here.'" icon="'fa-archive'" />
<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 @@ -127,10 +141,19 @@
</span>
Favorites
</a>

<a href="queries/archive" class="list-group-item" ng-class="{active: $ctrl.currentPage == 'archive'}">
<span class="btn-archive">
<i class="fa fa-archive" aria-hidden="true"></i>
</span>
Archive
</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 @@ -334,6 +334,11 @@ function QueryResource(
isArray: true,
url: 'api/queries/recent',
},
archive: {
method: 'get',
isArray: false,
url: 'api/queries/archive',
},
query: {
isArray: false,
},
Expand Down
3 changes: 2 additions & 1 deletion redash/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
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 QueryArchiveResource, 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, UserRegenerateApiKeyResource
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(QueryArchiveResource, '/api/queries/archive', endpoint='queries_archive')
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(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
129 changes: 78 additions & 51 deletions redash/handlers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,76 @@ 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,
# special-casing search queries where the database
# provides an order by search rank
ordered_results = order_results(results, 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_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 @@ -161,68 +230,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 QueryArchiveResource(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,
# special-casing search queries where the database
# provides an order by search rank
ordered_results = order_results(results, 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_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
Loading

0 comments on commit 914f827

Please sign in to comment.