diff --git a/superset-frontend/spec/javascripts/dashboard/util/getFilterScopeFromNodesTree_spec.js b/superset-frontend/spec/javascripts/dashboard/util/getFilterScopeFromNodesTree_spec.js index 6399ac4fd..b0f85550d 100644 --- a/superset-frontend/spec/javascripts/dashboard/util/getFilterScopeFromNodesTree_spec.js +++ b/superset-frontend/spec/javascripts/dashboard/util/getFilterScopeFromNodesTree_spec.js @@ -71,6 +71,19 @@ describe('getFilterScopeFromNodesTree', () => { }); describe('should return scope for tabbed dashboard', () => { + // this is a commonly used layout for dashboard: + // - Tab 1 + // - filter_107 + // - chart_106 + // - Tab 2 + // - filter_108 + // - chart_104 + // - Row Tab + // - chart_105 + // - chart_103 + // - New Tab + // - chart_101 + // - chart_102 const nodes = [ { label: 'All dashboard', @@ -157,6 +170,120 @@ describe('getFilterScopeFromNodesTree', () => { }, ]; + // this is another commonly used layout for dashboard: + // - filter_109 + // - Tab 1 + // - Row Tab 1 + // - filter_107 + // - chart_106 + // - Tab 2 + // - filter_108 + // - chart_104 + // - Row Tab + // - chart_105 + // - chart_103 + // - New Tab + // - chart_101 + // - chart_102 + const nodes2 = [ + { + label: 'All dashboard', + type: 'ROOT', + value: 'ROOT_ID', + children: [ + { + label: 'Time Filter', + showCheckbox: true, + type: 'CHART', + value: 109, + }, + { + label: 'Tab 1', + type: 'TAB', + value: 'TAB-Rb5aaqKWgG', + children: [ + { + label: 'Row Tab 1', + type: 'TAB', + value: 'TAB-row-tab1', + children: [ + { + label: 'Geo Filters', + showCheckbox: false, + type: 'CHART', + value: 107, + }, + { + label: "World's Pop Growth", + showCheckbox: true, + type: 'CHART', + value: 106, + }, + ], + }, + ], + }, + { + label: 'Tab 2', + type: 'TAB', + value: 'TAB-w5Fp904Rs', + children: [ + { + label: 'Time Filter', + showCheckbox: true, + type: 'CHART', + value: 108, + }, + { + label: 'Life Expectancy VS Rural %', + showCheckbox: true, + type: 'CHART', + value: 104, + }, + { + label: 'Row Tab 1', + type: 'TAB', + value: 'TAB-E4mJaZ-uQM', + children: [ + { + value: 105, + label: 'Rural Breakdown', + type: 'CHART', + showCheckbox: true, + }, + { + value: 103, + label: '% Rural', + type: 'CHART', + showCheckbox: true, + }, + ], + }, + { + value: 'TAB-rLYu-Cryu', + label: 'New Tab', + type: 'TAB', + children: [ + { + value: 102, + label: 'Most Populated Countries', + type: 'CHART', + showCheckbox: true, + }, + { + value: 101, + label: "World's Population", + type: 'CHART', + showCheckbox: true, + }, + ], + }, + ], + }, + ], + }, + ]; + it('root level tab scope', () => { const checkedChartIds = [106]; expect( @@ -226,5 +353,33 @@ describe('getFilterScopeFromNodesTree', () => { immune: [101], }); }); + + it('exclude sub-tab', () => { + const checkedChartIds = [103, 104, 105]; + expect( + getFilterScopeFromNodesTree({ + filterKey: '108___time_range', + nodes, + checkedChartIds, + }), + ).toEqual({ + scope: ['TAB-w5Fp904Rs'], + immune: [102, 101], + }); + }); + + it('exclude top-tab', () => { + const checkedChartIds = [106, 109]; + expect( + getFilterScopeFromNodesTree({ + filterKey: '107_region', + nodes: nodes2, + checkedChartIds, + }), + ).toEqual({ + scope: ['ROOT_ID'], + immune: [105, 103, 102, 101, 108, 104], + }); + }); }); }); diff --git a/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js b/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js index 8a14fbaee..25779d403 100644 --- a/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js +++ b/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.js @@ -26,13 +26,14 @@ function getTabChildrenScope({ tabScopes, parentNodeValue, forceAggregate = false, - hasChartSibilings = false, + hasChartSiblings = false, + immuneChartSiblings = [], }) { // if all sub-tabs are in scope, or forceAggregate = true // aggregate scope to parentNodeValue if ( forceAggregate || - (!hasChartSibilings && + (!hasChartSiblings && Object.entries(tabScopes).every( ([key, { scope }]) => scope && scope.length && key === scope[0], )) @@ -48,7 +49,11 @@ function getTabChildrenScope({ ); return { scope: flatMap(componentsInScope, ({ scope }) => scope), - immune: flatMap(componentsInScope, ({ immune }) => immune), + immune: componentsInScope.length + ? flatMap(componentsInScope, ({ immune }) => immune) + : flatMap(Object.values(tabScopes), ({ immune }) => immune).concat( + immuneChartSiblings, + ), }; } @@ -103,7 +108,8 @@ function traverse({ currentNode = {}, filterId, checkedChartIds = [] }) { return getTabChildrenScope({ tabScopes, parentNodeValue: currentValue, - hasChartSibilings: !isEmpty(chartChildren), + hasChartSiblings: !isEmpty(chartChildren), + immuneChartSiblings: chartsImmune, }); }