feat: dashboard page xlsx export (#24005)
Co-authored-by: Vitali Logvin <vitali.logvin@noogadev.com>
This commit is contained in:
parent
d583ca9ef5
commit
d0687d04eb
|
|
@ -135,6 +135,7 @@ const SliceHeader: FC<SliceHeaderProps> = ({
|
|||
logExploreChart = () => ({}),
|
||||
logEvent,
|
||||
exportCSV = () => ({}),
|
||||
exportXLSX = () => ({}),
|
||||
editMode = false,
|
||||
annotationQuery = {},
|
||||
annotationError = {},
|
||||
|
|
@ -264,6 +265,7 @@ const SliceHeader: FC<SliceHeaderProps> = ({
|
|||
logEvent={logEvent}
|
||||
exportCSV={exportCSV}
|
||||
exportFullCSV={exportFullCSV}
|
||||
exportXLSX={exportXLSX}
|
||||
supersetCanExplore={supersetCanExplore}
|
||||
supersetCanShare={supersetCanShare}
|
||||
supersetCanCSV={supersetCanCSV}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ const createProps = (viz_type = 'sunburst') =>
|
|||
exploreChart: jest.fn(),
|
||||
exportCSV: jest.fn(),
|
||||
exportFullCSV: jest.fn(),
|
||||
exportXLSX: jest.fn(),
|
||||
forceRefresh: jest.fn(),
|
||||
handleToggleFullSize: jest.fn(),
|
||||
toggleExpandSlice: jest.fn(),
|
||||
|
|
@ -126,6 +127,8 @@ test('Should render default props', () => {
|
|||
// @ts-ignore
|
||||
delete props.exportCSV;
|
||||
// @ts-ignore
|
||||
delete props.exportXLSX;
|
||||
// @ts-ignore
|
||||
delete props.cachedDttm;
|
||||
// @ts-ignore
|
||||
delete props.updatedDttm;
|
||||
|
|
@ -170,6 +173,16 @@ test('Should "export to CSV"', async () => {
|
|||
expect(props.exportCSV).toBeCalledWith(371);
|
||||
});
|
||||
|
||||
test('Should "export to Excel"', async () => {
|
||||
const props = createProps();
|
||||
renderWrapper(props);
|
||||
expect(props.exportXLSX).toBeCalledTimes(0);
|
||||
userEvent.hover(screen.getByText('Download'));
|
||||
userEvent.click(await screen.findByText('Export to Excel'));
|
||||
expect(props.exportXLSX).toBeCalledTimes(1);
|
||||
expect(props.exportXLSX).toBeCalledWith(371);
|
||||
});
|
||||
|
||||
test('Should not show "Download" if slice is filter box', () => {
|
||||
const props = createProps('filter_box');
|
||||
renderWrapper(props);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ const MENU_KEYS = {
|
|||
EXPLORE_CHART: 'explore_chart',
|
||||
EXPORT_CSV: 'export_csv',
|
||||
EXPORT_FULL_CSV: 'export_full_csv',
|
||||
EXPORT_XLSX: 'export_xlsx',
|
||||
FORCE_REFRESH: 'force_refresh',
|
||||
FULLSCREEN: 'fullscreen',
|
||||
TOGGLE_CHART_DESCRIPTION: 'toggle_chart_description',
|
||||
|
|
@ -144,6 +145,7 @@ export interface SliceHeaderControlsProps {
|
|||
toggleExpandSlice?: (sliceId: number) => void;
|
||||
exportCSV?: (sliceId: number) => void;
|
||||
exportFullCSV?: (sliceId: number) => void;
|
||||
exportXLSX?: (sliceId: number) => void;
|
||||
handleToggleFullSize: () => void;
|
||||
|
||||
addDangerToast: (message: string) => void;
|
||||
|
|
@ -294,6 +296,10 @@ const SliceHeaderControls = (props: SliceHeaderControlsPropsWithRouter) => {
|
|||
// eslint-disable-next-line no-unused-expressions
|
||||
props.exportFullCSV?.(props.slice.slice_id);
|
||||
break;
|
||||
case MENU_KEYS.EXPORT_XLSX:
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
props.exportXLSX?.(props.slice.slice_id);
|
||||
break;
|
||||
case MENU_KEYS.DOWNLOAD_AS_IMAGE: {
|
||||
// menu closes with a delay, we need to hide it manually,
|
||||
// so that we don't capture it on the screenshot
|
||||
|
|
@ -493,6 +499,12 @@ const SliceHeaderControls = (props: SliceHeaderControlsPropsWithRouter) => {
|
|||
</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} />}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import {
|
|||
LOG_ACTIONS_CHANGE_DASHBOARD_FILTER,
|
||||
LOG_ACTIONS_EXPLORE_DASHBOARD_CHART,
|
||||
LOG_ACTIONS_EXPORT_CSV_DASHBOARD_CHART,
|
||||
LOG_ACTIONS_EXPORT_XLSX_DASHBOARD_CHART,
|
||||
LOG_ACTIONS_FORCE_REFRESH_CHART,
|
||||
} from 'src/logger/LogUtils';
|
||||
import { areObjectsEqual } from 'src/reduxUtils';
|
||||
|
|
@ -139,6 +140,7 @@ class Chart extends React.Component {
|
|||
this.handleFilterMenuClose = this.handleFilterMenuClose.bind(this);
|
||||
this.exportCSV = this.exportCSV.bind(this);
|
||||
this.exportFullCSV = this.exportFullCSV.bind(this);
|
||||
this.exportXLSX = this.exportXLSX.bind(this);
|
||||
this.forceRefresh = this.forceRefresh.bind(this);
|
||||
this.resize = this.resize.bind(this);
|
||||
this.setDescriptionRef = this.setDescriptionRef.bind(this);
|
||||
|
|
@ -324,8 +326,24 @@ class Chart extends React.Component {
|
|||
}
|
||||
};
|
||||
|
||||
exportFullCSV() {
|
||||
this.exportCSV(true);
|
||||
}
|
||||
|
||||
exportCSV(isFullCSV = false) {
|
||||
this.props.logEvent(LOG_ACTIONS_EXPORT_CSV_DASHBOARD_CHART, {
|
||||
this.exportTable('csv', isFullCSV);
|
||||
}
|
||||
|
||||
exportXLSX() {
|
||||
this.exportTable('xlsx', false);
|
||||
}
|
||||
|
||||
exportTable(format, isFullCSV) {
|
||||
const logAction =
|
||||
format === 'csv'
|
||||
? LOG_ACTIONS_EXPORT_CSV_DASHBOARD_CHART
|
||||
: LOG_ACTIONS_EXPORT_XLSX_DASHBOARD_CHART;
|
||||
this.props.logEvent(logAction, {
|
||||
slice_id: this.props.slice.slice_id,
|
||||
is_cached: this.props.isCached,
|
||||
});
|
||||
|
|
@ -334,16 +352,12 @@ class Chart extends React.Component {
|
|||
? { ...this.props.formData, row_limit: this.props.maxRows }
|
||||
: this.props.formData,
|
||||
resultType: 'full',
|
||||
resultFormat: 'csv',
|
||||
resultFormat: format,
|
||||
force: true,
|
||||
ownState: this.props.ownState,
|
||||
});
|
||||
}
|
||||
|
||||
exportFullCSV() {
|
||||
this.exportCSV(true);
|
||||
}
|
||||
|
||||
forceRefresh() {
|
||||
this.props.logEvent(LOG_ACTIONS_FORCE_REFRESH_CHART, {
|
||||
slice_id: this.props.slice.slice_id,
|
||||
|
|
@ -437,6 +451,7 @@ class Chart extends React.Component {
|
|||
logEvent={logEvent}
|
||||
onExploreChart={this.onExploreChart}
|
||||
exportCSV={this.exportCSV}
|
||||
exportXLSX={this.exportXLSX}
|
||||
exportFullCSV={this.exportFullCSV}
|
||||
updateSliceName={updateSliceName}
|
||||
sliceName={sliceName}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ describe('Chart', () => {
|
|||
addDangerToast() {},
|
||||
exportCSV() {},
|
||||
exportFullCSV() {},
|
||||
exportXLSX() {},
|
||||
componentId: 'test',
|
||||
dashboardId: 111,
|
||||
editMode: false,
|
||||
|
|
@ -145,4 +146,20 @@ describe('Chart', () => {
|
|||
expect(stubbedExportCSV.lastCall.args[0].formData.row_limit).toEqual(666);
|
||||
exploreUtils.exportChart.restore();
|
||||
});
|
||||
it('should call exportChart when exportXLSX is clicked', () => {
|
||||
const stubbedExportXLSX = sinon
|
||||
.stub(exploreUtils, 'exportChart')
|
||||
.returns(() => {});
|
||||
const wrapper = setup();
|
||||
wrapper.instance().exportXLSX(props.slice.sliceId);
|
||||
expect(stubbedExportXLSX.calledOnce).toBe(true);
|
||||
expect(stubbedExportXLSX.lastCall.args[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
formData: expect.anything(),
|
||||
resultType: 'full',
|
||||
resultFormat: 'xlsx',
|
||||
}),
|
||||
);
|
||||
exploreUtils.exportChart.restore();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ export const LOG_ACTIONS_PERIODIC_RENDER_DASHBOARD =
|
|||
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 const LOG_ACTIONS_CHANGE_DASHBOARD_FILTER = 'change_dashboard_filter';
|
||||
export const LOG_ACTIONS_DATASET_CREATION_EMPTY_CANCELLATION =
|
||||
'dataset_creation_empty_cancellation';
|
||||
|
|
|
|||
Loading…
Reference in New Issue