This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new a5320a0  [add] Save filters to dashboard (#3183)
a5320a0 is described below

commit a5320a0f3729f0513cf88a548d5fbd1bf59aa506
Author: Rogan <quang...@gmail.com>
AuthorDate: Fri Aug 11 11:49:49 2017 +0800

    [add] Save filters to dashboard (#3183)
    
    * [add] Save filters to dashboard
    
    * format code
    
    * fix CI error
    
    * add semicolon  semi
    
    * fix none object
    
    * add test data
    optimize the js code
    fix the compatibility issue
    
    * fix urllib to urllib.parse
    
    * add space
    
    * update test case
    
    * remove  'return'
    
    * fix error
    
    * update test case
---
 .../assets/javascripts/dashboard/Dashboard.jsx     | 35 ++++++++++++---------
 .../javascripts/dashboard/components/SaveModal.jsx |  1 +
 superset/assets/visualizations/filter_box.jsx      | 18 +++++++++++
 superset/models/core.py                            |  8 +++++
 superset/views/core.py                             |  1 +
 tests/core_tests.py                                | 36 ++++++++++++++++++++++
 6 files changed, 85 insertions(+), 14 deletions(-)

diff --git a/superset/assets/javascripts/dashboard/Dashboard.jsx 
b/superset/assets/javascripts/dashboard/Dashboard.jsx
index b6c97b6..283475a 100644
--- a/superset/assets/javascripts/dashboard/Dashboard.jsx
+++ b/superset/assets/javascripts/dashboard/Dashboard.jsx
@@ -166,6 +166,10 @@ export function dashboardContainer(dashboard, datasources, 
userid) {
       }
     },
     effectiveExtraFilters(sliceId) {
+      // Don't filter the filter_box itself by preselect_filters
+      if (this.getSlice(sliceId).formData.viz_type === 'filter_box') {
+        return [];
+      }
       const f = [];
       const immuneSlices = this.metadata.filter_immune_slices || [];
       if (sliceId && immuneSlices.includes(sliceId)) {
@@ -195,21 +199,24 @@ export function dashboardContainer(dashboard, 
datasources, userid) {
       return f;
     },
     addFilter(sliceId, col, vals, merge = true, refresh = true) {
-      if (!(sliceId in this.filters)) {
-        this.filters[sliceId] = {};
-      }
-      if (!(col in this.filters[sliceId]) || !merge) {
-        this.filters[sliceId][col] = vals;
+      if (this.getSlice(sliceId) && (col === '__from' || col === '__to' ||
+          this.getSlice(sliceId).formData.groupby.indexOf(col) !== -1)) {
+        if (!(sliceId in this.filters)) {
+          this.filters[sliceId] = {};
+        }
+        if (!(col in this.filters[sliceId]) || !merge) {
+          this.filters[sliceId][col] = vals;
 
-        // d3.merge pass in array of arrays while some value form filter 
components
-        // from and to filter box require string to be process and return
-      } else if (this.filters[sliceId][col] instanceof Array) {
-        this.filters[sliceId][col] = d3.merge([this.filters[sliceId][col], 
vals]);
-      } else {
-        this.filters[sliceId][col] = d3.merge([[this.filters[sliceId][col]], 
vals])[0] || '';
-      }
-      if (refresh) {
-        this.refreshExcept(sliceId);
+          // d3.merge pass in array of arrays while some value form filter 
components
+          // from and to filter box require string to be process and return
+        } else if (this.filters[sliceId][col] instanceof Array) {
+          this.filters[sliceId][col] = d3.merge([this.filters[sliceId][col], 
vals]);
+        } else {
+          this.filters[sliceId][col] = d3.merge([[this.filters[sliceId][col]], 
vals])[0] || '';
+        }
+        if (refresh) {
+          this.refreshExcept(sliceId);
+        }
       }
       this.updateFilterParamsInUrl();
     },
diff --git a/superset/assets/javascripts/dashboard/components/SaveModal.jsx 
b/superset/assets/javascripts/dashboard/components/SaveModal.jsx
index a22f4ac..82b44df 100644
--- a/superset/assets/javascripts/dashboard/components/SaveModal.jsx
+++ b/superset/assets/javascripts/dashboard/components/SaveModal.jsx
@@ -80,6 +80,7 @@ class SaveModal extends React.PureComponent {
       css: this.state.css,
       expanded_slices: expandedSlices,
       dashboard_title: dashboard.dashboard_title,
+      default_filters: dashboard.readFilters(),
     };
     let url = null;
     if (saveType === 'overwrite') {
diff --git a/superset/assets/visualizations/filter_box.jsx 
b/superset/assets/visualizations/filter_box.jsx
index a97ec3f..7e02dd5 100644
--- a/superset/assets/visualizations/filter_box.jsx
+++ b/superset/assets/visualizations/filter_box.jsx
@@ -74,6 +74,24 @@ class FilterBox extends React.Component {
         );
       });
     }
+    // Add created options to filtersChoices, even though it doesn't exist,
+    // or these options will exist in query sql but invisible to end user.
+    if (this.state.selectedValues.hasOwnProperty()) {
+      for (const filterKey of this.state.selectedValues) {
+        const existValues = this.props.filtersChoices[filterKey].map(f => 
f.id);
+        for (const v of this.state.selectedValues[filterKey]) {
+          if (existValues.indexOf(v) === -1) {
+            const addChoice = {
+              filter: filterKey,
+              id: v,
+              text: v,
+              metric: 0,
+            };
+            this.props.filtersChoices[filterKey].push(addChoice);
+          }
+        }
+      }
+    }
     const filters = Object.keys(this.props.filtersChoices).map((filter) => {
       const data = this.props.filtersChoices[filter];
       const maxes = {};
diff --git a/superset/models/core.py b/superset/models/core.py
index 43cbeff..4f76c79 100644
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -322,6 +322,14 @@ class Dashboard(Model, AuditMixinNullable, ImportMixin):
 
     @property
     def url(self):
+        if self.json_metadata:
+            # add default_filters to the preselect_filters of dashboard
+            json_metadata = json.loads(self.json_metadata)
+            default_filters = json_metadata.get('default_filters')
+            if default_filters:
+                filters = parse.quote(default_filters.encode('utf8'))
+                return "/superset/dashboard/{}/?preselect_filters={}".format(
+                    self.slug or self.id, filters)
         return "/superset/dashboard/{}/".format(self.slug or self.id)
 
     @property
diff --git a/superset/views/core.py b/superset/views/core.py
index 4b20e3c..b2a3be4 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -1352,6 +1352,7 @@ class Superset(BaseSupersetView):
         if 'filter_immune_slice_fields' not in md:
             md['filter_immune_slice_fields'] = {}
         md['expanded_slices'] = data['expanded_slices']
+        md['default_filters'] = data.get('default_filters', '')
         dashboard.json_metadata = json.dumps(md, indent=4)
 
     @api
diff --git a/tests/core_tests.py b/tests/core_tests.py
index f3e9887..4a7efc4 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -380,6 +380,42 @@ class CoreTests(SupersetTestCase):
         resp = self.get_resp(url, data=dict(data=json.dumps(data)))
         self.assertIn("SUCCESS", resp)
 
+    def test_save_dash_with_filter(self, username='admin'):
+        self.login(username=username)
+        dash = db.session.query(models.Dashboard).filter_by(
+            slug="world_health").first()
+        positions = []
+        for i, slc in enumerate(dash.slices):
+            d = {
+                'col': 0,
+                'row': i * 4,
+                'size_x': 4,
+                'size_y': 4,
+                'slice_id': '{}'.format(slc.id)}
+            positions.append(d)
+
+        filters = {str(dash.slices[0].id): {'region': ['North America']}}
+        default_filters = json.dumps(filters)
+        data = {
+            'css': '',
+            'expanded_slices': {},
+            'positions': positions,
+            'dashboard_title': dash.dashboard_title,
+            'default_filters': default_filters
+        }
+
+        url = '/superset/save_dash/{}/'.format(dash.id)
+        resp = self.get_resp(url, data=dict(data=json.dumps(data)))
+        self.assertIn("SUCCESS", resp)
+
+        updatedDash = db.session.query(models.Dashboard).filter_by(
+            slug="world_health").first()
+        new_url = updatedDash.url
+        self.assertIn("region", new_url)
+
+        resp = self.get_resp(new_url)
+        self.assertIn("North America", resp)
+
     def test_save_dash_with_dashboard_title(self, username='admin'):
         self.login(username=username)
         dash = (

-- 
To stop receiving notification emails like this one, please contact
['"comm...@superset.apache.org" <comm...@superset.apache.org>'].

Reply via email to