You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2023/06/15 11:43:43 UTC

[superset] branch master updated: feat: add dashboard page full xlsx export (#24287)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new fa82ee1947 feat: add dashboard page full xlsx export (#24287)
fa82ee1947 is described below

commit fa82ee1947987becc91d0286ca78b0f35ab2ea6d
Author: Vitali Logvin <82...@users.noreply.github.com>
AuthorDate: Thu Jun 15 14:43:34 2023 +0300

    feat: add dashboard page full xlsx export (#24287)
    
    Co-authored-by: Vitali Logvin <vi...@noogadev.com>
---
 .../src/dashboard/components/SliceHeader/index.tsx |  2 ++
 .../SliceHeaderControls.test.tsx                   | 38 ++++++++++++++++++++++
 .../components/SliceHeaderControls/index.tsx       | 38 +++++++++++++++-------
 .../dashboard/components/gridComponents/Chart.jsx  |  6 ++++
 .../components/gridComponents/Chart.test.jsx       | 11 +++++++
 superset-frontend/src/logger/LogUtils.ts           |  2 +-
 6 files changed, 84 insertions(+), 13 deletions(-)

diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
index 497832766a..c9cb74a8af 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
@@ -148,6 +148,7 @@ const SliceHeader: FC<SliceHeaderProps> = ({
   supersetCanShare = false,
   supersetCanCSV = false,
   exportFullCSV,
+  exportFullXLSX,
   slice,
   componentId,
   dashboardId,
@@ -265,6 +266,7 @@ const SliceHeader: FC<SliceHeaderProps> = ({
                 exportCSV={exportCSV}
                 exportFullCSV={exportFullCSV}
                 exportXLSX={exportXLSX}
+                exportFullXLSX={exportFullXLSX}
                 supersetCanExplore={supersetCanExplore}
                 supersetCanShare={supersetCanShare}
                 supersetCanCSV={supersetCanCSV}
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx b/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
index d2bc3e4bcc..add9bb9739 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
@@ -45,6 +45,7 @@ const createProps = (viz_type = 'sunburst') =>
     exportCSV: jest.fn(),
     exportFullCSV: jest.fn(),
     exportXLSX: jest.fn(),
+    exportFullXLSX: jest.fn(),
     forceRefresh: jest.fn(),
     handleToggleFullSize: jest.fn(),
     toggleExpandSlice: jest.fn(),
@@ -223,6 +224,43 @@ test('Should not show export full CSV if report is not table', async () => {
   expect(screen.queryByText('Export to full .CSV')).not.toBeInTheDocument();
 });
 
+test('Export full Excel is under featureflag', async () => {
+  // @ts-ignore
+  global.featureFlags = {
+    [FeatureFlag.ALLOW_FULL_CSV_EXPORT]: false,
+  };
+  const props = createProps('table');
+  renderWrapper(props);
+  userEvent.hover(screen.getByText('Download'));
+  expect(await screen.findByText('Export to Excel')).toBeInTheDocument();
+  expect(screen.queryByText('Export to full Excel')).not.toBeInTheDocument();
+});
+
+test('Should "export full Excel"', async () => {
+  // @ts-ignore
+  global.featureFlags = {
+    [FeatureFlag.ALLOW_FULL_CSV_EXPORT]: true,
+  };
+  const props = createProps('table');
+  renderWrapper(props);
+  expect(props.exportFullXLSX).toBeCalledTimes(0);
+  userEvent.hover(screen.getByText('Download'));
+  userEvent.click(await screen.findByText('Export to full Excel'));
+  expect(props.exportFullXLSX).toBeCalledTimes(1);
+  expect(props.exportFullXLSX).toBeCalledWith(371);
+});
+
+test('Should not show export full Excel if report is not table', async () => {
+  // @ts-ignore
+  global.featureFlags = {
+    [FeatureFlag.ALLOW_FULL_CSV_EXPORT]: true,
+  };
+  renderWrapper();
+  userEvent.hover(screen.getByText('Download'));
+  expect(await screen.findByText('Export to Excel')).toBeInTheDocument();
+  expect(screen.queryByText('Export to full Excel')).not.toBeInTheDocument();
+});
+
 test('Should "Show chart description"', () => {
   const props = createProps();
   renderWrapper(props);
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
index 3a0137cbf0..e395875517 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
@@ -65,6 +65,7 @@ const MENU_KEYS = {
   EXPORT_CSV: 'export_csv',
   EXPORT_FULL_CSV: 'export_full_csv',
   EXPORT_XLSX: 'export_xlsx',
+  EXPORT_FULL_XLSX: 'export_full_xlsx',
   FORCE_REFRESH: 'force_refresh',
   FULLSCREEN: 'fullscreen',
   TOGGLE_CHART_DESCRIPTION: 'toggle_chart_description',
@@ -146,6 +147,7 @@ export interface SliceHeaderControlsProps {
   exportCSV?: (sliceId: number) => void;
   exportFullCSV?: (sliceId: number) => void;
   exportXLSX?: (sliceId: number) => void;
+  exportFullXLSX?: (sliceId: number) => void;
   handleToggleFullSize: () => void;
 
   addDangerToast: (message: string) => void;
@@ -295,6 +297,10 @@ const SliceHeaderControls = (props: SliceHeaderControlsPropsWithRouter) => {
         // eslint-disable-next-line no-unused-expressions
         props.exportFullCSV?.(props.slice.slice_id);
         break;
+      case MENU_KEYS.EXPORT_FULL_XLSX:
+        // eslint-disable-next-line no-unused-expressions
+        props.exportFullXLSX?.(props.slice.slice_id);
+        break;
       case MENU_KEYS.EXPORT_XLSX:
         // eslint-disable-next-line no-unused-expressions
         props.exportXLSX?.(props.slice.slice_id);
@@ -485,25 +491,33 @@ const SliceHeaderControls = (props: SliceHeaderControlsPropsWithRouter) => {
           >
             {t('Export to .CSV')}
           </Menu.Item>
+          <Menu.Item
+            key={MENU_KEYS.EXPORT_XLSX}
+            icon={<Icons.FileOutlined css={dropdownIconsStyles} />}
+          >
+            {t('Export to Excel')}
+          </Menu.Item>
 
           {props.slice.viz_type !== 'filter_box' &&
             isFeatureEnabled(FeatureFlag.ALLOW_FULL_CSV_EXPORT) &&
             props.supersetCanCSV &&
             isTable && (
-              <Menu.Item
-                key={MENU_KEYS.EXPORT_FULL_CSV}
-                icon={<Icons.FileOutlined css={dropdownIconsStyles} />}
-              >
-                {t('Export to full .CSV')}
-              </Menu.Item>
+              <>
+                <Menu.Item
+                  key={MENU_KEYS.EXPORT_FULL_CSV}
+                  icon={<Icons.FileOutlined css={dropdownIconsStyles} />}
+                >
+                  {t('Export to full .CSV')}
+                </Menu.Item>
+                <Menu.Item
+                  key={MENU_KEYS.EXPORT_FULL_XLSX}
+                  icon={<Icons.FileOutlined css={dropdownIconsStyles} />}
+                >
+                  {t('Export to full Excel')}
+                </Menu.Item>
+              </>
             )}
 
-          <Menu.Item
-            key={MENU_KEYS.EXPORT_XLSX}
-            icon={<Icons.FileOutlined css={dropdownIconsStyles} />}
-          >
-            {t('Export to Excel')}
-          </Menu.Item>
           <Menu.Item
             key={MENU_KEYS.DOWNLOAD_AS_IMAGE}
             icon={<Icons.FileImageOutlined css={dropdownIconsStyles} />}
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
index 38b6c837e1..1c4d0dd956 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
@@ -140,6 +140,7 @@ class Chart extends React.Component {
     this.exportCSV = this.exportCSV.bind(this);
     this.exportFullCSV = this.exportFullCSV.bind(this);
     this.exportXLSX = this.exportXLSX.bind(this);
+    this.exportFullXLSX = this.exportFullXLSX.bind(this);
     this.forceRefresh = this.forceRefresh.bind(this);
     this.resize = this.resize.bind(this);
     this.setDescriptionRef = this.setDescriptionRef.bind(this);
@@ -337,6 +338,10 @@ class Chart extends React.Component {
     this.exportTable('xlsx', false);
   }
 
+  exportFullXLSX() {
+    this.exportTable('xlsx', true);
+  }
+
   exportTable(format, isFullCSV) {
     const logAction =
       format === 'csv'
@@ -451,6 +456,7 @@ class Chart extends React.Component {
           exportCSV={this.exportCSV}
           exportXLSX={this.exportXLSX}
           exportFullCSV={this.exportFullCSV}
+          exportFullXLSX={this.exportFullXLSX}
           updateSliceName={updateSliceName}
           sliceName={sliceName}
           supersetCanExplore={supersetCanExplore}
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.test.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.test.jsx
index 28a972069b..89bcca7f78 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Chart.test.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.test.jsx
@@ -63,6 +63,7 @@ describe('Chart', () => {
     exportCSV() {},
     exportFullCSV() {},
     exportXLSX() {},
+    exportFullXLSX() {},
     componentId: 'test',
     dashboardId: 111,
     editMode: false,
@@ -161,4 +162,14 @@ describe('Chart', () => {
     );
     exploreUtils.exportChart.restore();
   });
+  it('should call exportChart with row_limit props.maxRows when exportFullXLSX is clicked', () => {
+    const stubbedExportXLSX = sinon
+      .stub(exploreUtils, 'exportChart')
+      .returns(() => {});
+    const wrapper = setup();
+    wrapper.instance().exportFullXLSX(props.slice.sliceId);
+    expect(stubbedExportXLSX.calledOnce).toBe(true);
+    expect(stubbedExportXLSX.lastCall.args[0].formData.row_limit).toEqual(666);
+    exploreUtils.exportChart.restore();
+  });
 });
diff --git a/superset-frontend/src/logger/LogUtils.ts b/superset-frontend/src/logger/LogUtils.ts
index 258b5dbb5e..289846fa1c 100644
--- a/superset-frontend/src/logger/LogUtils.ts
+++ b/superset-frontend/src/logger/LogUtils.ts
@@ -35,7 +35,7 @@ export const LOG_ACTIONS_EXPLORE_DASHBOARD_CHART = 'explore_dashboard_chart';
 export const LOG_ACTIONS_EXPORT_CSV_DASHBOARD_CHART =
   'export_csv_dashboard_chart';
 export const LOG_ACTIONS_EXPORT_XLSX_DASHBOARD_CHART =
-  'export_csv_dashboard_chart';
+  'export_xlsx_dashboard_chart';
 export const LOG_ACTIONS_CHANGE_DASHBOARD_FILTER = 'change_dashboard_filter';
 export const LOG_ACTIONS_DATASET_CREATION_EMPTY_CANCELLATION =
   'dataset_creation_empty_cancellation';