diff --git a/superset-frontend/spec/javascripts/dashboard/components/HeaderActionsDropdown_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/HeaderActionsDropdown_spec.jsx index 495e629092524..d1e19623fa56d 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/HeaderActionsDropdown_spec.jsx +++ b/superset-frontend/spec/javascripts/dashboard/components/HeaderActionsDropdown_spec.jsx @@ -66,9 +66,9 @@ describe('HeaderActionsDropdown', () => { expect(wrapper.find(SaveModal)).not.toExist(); }); - it('should render two MenuItems', () => { + it('should render four MenuItems', () => { const wrapper = setup(overrideProps); - expect(wrapper.find(MenuItem)).toHaveLength(3); + expect(wrapper.find(MenuItem)).toHaveLength(4); }); it('should render the RefreshIntervalModal', () => { @@ -100,9 +100,9 @@ describe('HeaderActionsDropdown', () => { expect(wrapper.find(SaveModal)).toExist(); }); - it('should render three MenuItems', () => { + it('should render four MenuItems', () => { const wrapper = setup(overrideProps); - expect(wrapper.find(MenuItem)).toHaveLength(3); + expect(wrapper.find(MenuItem)).toHaveLength(4); }); it('should render the RefreshIntervalModal', () => { diff --git a/superset-frontend/spec/javascripts/dashboard/util/getDashboardUrl_spec.js b/superset-frontend/spec/javascripts/dashboard/util/getDashboardUrl_spec.js index 43a33adb9041b..bb2ae43ed6740 100644 --- a/superset-frontend/spec/javascripts/dashboard/util/getDashboardUrl_spec.js +++ b/superset-frontend/spec/javascripts/dashboard/util/getDashboardUrl_spec.js @@ -31,5 +31,15 @@ describe('getChartIdsFromLayout', () => { expect(url).toBe( 'path?preselect_filters=%7B%2235%22%3A%7B%22key%22%3A%5B%22value%22%5D%7D%7D', ); + + const urlWithHash = getDashboardUrl('path', filters, 'iamhashtag'); + expect(urlWithHash).toBe( + 'path?preselect_filters=%7B%2235%22%3A%7B%22key%22%3A%5B%22value%22%5D%7D%7D#iamhashtag', + ); + + const urlWithStandalone = getDashboardUrl('path', filters, '', true); + expect(urlWithStandalone).toBe( + 'path?preselect_filters=%7B%2235%22%3A%7B%22key%22%3A%5B%22value%22%5D%7D%7D&standalone=true', + ); }); }); diff --git a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx index 00ba41fdcbe24..c99e164bc3848 100644 --- a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx +++ b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx @@ -226,6 +226,25 @@ class HeaderActionsDropdown extends React.PureComponent { {t('Download as image')} )} + + {!editMode && ( + { + const hasStandalone = window.location.search.includes( + 'standalone=true', + ); + const url = getDashboardUrl( + window.location.pathname, + getActiveFilters(), + window.location.hash, + !hasStandalone, + ); + window.location.replace(url); + }} + > + {t('Toggle FullScreen')} + + )} ); } diff --git a/superset-frontend/src/dashboard/util/getDashboardUrl.js b/superset-frontend/src/dashboard/util/getDashboardUrl.js index bf2040c315f0e..f921c09a21b27 100644 --- a/superset-frontend/src/dashboard/util/getDashboardUrl.js +++ b/superset-frontend/src/dashboard/util/getDashboardUrl.js @@ -18,11 +18,17 @@ */ import serializeActiveFilterValues from './serializeActiveFilterValues'; -export default function getDashboardUrl(pathname, filters = {}, hash = '') { +export default function getDashboardUrl( + pathname, + filters = {}, + hash = '', + standalone = false, +) { // convert flattened { [id_column]: values } object // to nested filter object const obj = serializeActiveFilterValues(filters); const preselectFilters = encodeURIComponent(JSON.stringify(obj)); const hashSection = hash ? `#${hash}` : ''; - return `${pathname}?preselect_filters=${preselectFilters}${hashSection}`; + const standaloneParam = standalone ? '&standalone=true' : ''; + return `${pathname}?preselect_filters=${preselectFilters}${standaloneParam}${hashSection}`; }