Merge pull request #200 from EverythingMe/feature_dashboard_filters

Feature: dashboard filters
This commit is contained in:
Arik Fraimovich 2014-05-05 18:49:52 +03:00
commit 19743f387b
5 changed files with 60 additions and 5 deletions

View File

@ -0,0 +1,12 @@
from playhouse.migrate import Migrator
from redash import db
from redash import models
if __name__ == '__main__':
db.connect_db()
migrator = Migrator(db.database)
with db.database.transaction():
migrator.add_column(models.Dashboard, models.Dashboard.dashboard_filters_enabled, 'dashboard_filters_enabled')
db.close_db(None)

View File

@ -6,11 +6,40 @@
$scope.refreshRate = 60; $scope.refreshRate = 60;
$scope.dashboard = Dashboard.get({ slug: $routeParams.dashboardSlug }, function (dashboard) { $scope.dashboard = Dashboard.get({ slug: $routeParams.dashboardSlug }, function (dashboard) {
$scope.$parent.pageTitle = dashboard.name; $scope.$parent.pageTitle = dashboard.name;
var filters = {};
$scope.dashboard.widgets = _.map($scope.dashboard.widgets, function (row) { $scope.dashboard.widgets = _.map($scope.dashboard.widgets, function (row) {
return _.map(row, function (widget) { return _.map(row, function (widget) {
return new Widget(widget); var w = new Widget(widget);
if (w.visualization && dashboard.dashboard_filters_enabled) {
var queryFilters = w.getQuery().getQueryResult().getFilters();
_.each(queryFilters, function (filter) {
if (!_.has(filters, filter.name)) {
// TODO: first object should be a copy, otherwise one of the chart filters behaves different than the others.
filters[filter.name] = filter;
filters[filter.name].originFilters = [];
$scope.$watch(function() { return filter.current }, function (value) {
_.each(filter.originFilters, function(originFilter) {
originFilter.current = value;
})
});
};
// TODO: merge values.
filters[filter.name].originFilters.push(filter);
});
}
return w;
}); });
}); });
if (dashboard.dashboard_filters_enabled) {
$scope.filters = _.values(filters);
}
}); });
var autoRefresh = function() { var autoRefresh = function() {
@ -77,7 +106,7 @@
Events.record(currentUser, "view", "query", $scope.widget.visualization.query.id); Events.record(currentUser, "view", "query", $scope.widget.visualization.query.id);
Events.record(currentUser, "view", "visualization", $scope.widget.visualization.id); Events.record(currentUser, "view", "visualization", $scope.widget.visualization.id);
$scope.query = new Query($scope.widget.visualization.query); $scope.query = $scope.widget.getQuery();
$scope.queryResult = $scope.query.getQueryResult(); $scope.queryResult = $scope.query.getQueryResult();
$scope.nextUpdateTime = moment(new Date(($scope.query.updated_at + $scope.query.ttl + $scope.query.runtime + 300) * 1000)).fromNow(); $scope.nextUpdateTime = moment(new Date(($scope.query.updated_at + $scope.query.ttl + $scope.query.runtime + 300) * 1000)).fromNow();

View File

@ -357,7 +357,10 @@
var queryResult = null; var queryResult = null;
if (this.latest_query_data && ttl != 0) { if (this.latest_query_data && ttl != 0) {
queryResult = new QueryResult({'query_result': this.latest_query_data}); if (!this.queryResult) {
this.queryResult = new QueryResult({'query_result': this.latest_query_data});
}
queryResult = this.queryResult;
} else if (this.latest_query_data_id && ttl != 0) { } else if (this.latest_query_data_id && ttl != 0) {
queryResult = QueryResult.getById(this.latest_query_data_id); queryResult = QueryResult.getById(this.latest_query_data_id);
} else if (this.data_source_id) { } else if (this.data_source_id) {
@ -376,9 +379,17 @@
return DataSourceResource; return DataSourceResource;
} }
var Widget = function ($resource) { var Widget = function ($resource, Query) {
var WidgetResource = $resource('/api/widgets/:id', {id: '@id'}); var WidgetResource = $resource('/api/widgets/:id', {id: '@id'});
WidgetResource.prototype.getQuery = function () {
if (!this.query && this.visualization) {
this.query = new Query(this.visualization.query);
}
return this.query;
};
WidgetResource.prototype.getName = function () { WidgetResource.prototype.getName = function () {
if (this.visualization) { if (this.visualization) {
return this.visualization.query.name + ' (' + this.visualization.name + ')'; return this.visualization.query.name + ' (' + this.visualization.name + ')';
@ -393,5 +404,5 @@
.factory('QueryResult', ['$resource', '$timeout', QueryResult]) .factory('QueryResult', ['$resource', '$timeout', QueryResult])
.factory('Query', ['$resource', 'QueryResult', 'DataSource', Query]) .factory('Query', ['$resource', 'QueryResult', 'DataSource', Query])
.factory('DataSource', ['$resource', DataSource]) .factory('DataSource', ['$resource', DataSource])
.factory('Widget', ['$resource', Widget]); .factory('Widget', ['$resource', 'Query', Widget]);
})(); })();

View File

@ -14,6 +14,7 @@
</button> </button>
</span> </span>
</h2> </h2>
<filters></filters>
</div> </div>
<div class="container" id="dashboard"> <div class="container" id="dashboard">

View File

@ -248,6 +248,7 @@ class Dashboard(BaseModel):
user_email = peewee.CharField(max_length=360, null=True) user_email = peewee.CharField(max_length=360, null=True)
user = peewee.ForeignKeyField(User) user = peewee.ForeignKeyField(User)
layout = peewee.TextField() layout = peewee.TextField()
dashboard_filters_enabled = peewee.BooleanField(default=False)
is_archived = peewee.BooleanField(default=False, index=True) is_archived = peewee.BooleanField(default=False, index=True)
created_at = peewee.DateTimeField(default=datetime.datetime.now) created_at = peewee.DateTimeField(default=datetime.datetime.now)
@ -292,6 +293,7 @@ class Dashboard(BaseModel):
'name': self.name, 'name': self.name,
'user_id': self._data['user'], 'user_id': self._data['user'],
'layout': layout, 'layout': layout,
'dashboard_filters_enabled': self.dashboard_filters_enabled,
'widgets': widgets_layout 'widgets': widgets_layout
} }