fix: Disables email reports for unsaved charts (#23588)

This commit is contained in:
Michael S. Molina 2023-04-06 16:00:47 -03:00 committed by GitHub
parent 83df609782
commit 290920c4fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 31 deletions

View File

@ -18,6 +18,7 @@
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { isEmpty } from 'lodash';
import { import {
t, t,
SupersetTheme, SupersetTheme,
@ -103,6 +104,9 @@ export interface HeaderReportProps {
showReportSubMenu?: boolean; showReportSubMenu?: boolean;
} }
// Same instance to be used in useEffects
const EMPTY_OBJECT = {};
export default function HeaderReportDropDown({ export default function HeaderReportDropDown({
dashboardId, dashboardId,
chart, chart,
@ -116,7 +120,10 @@ export default function HeaderReportDropDown({
const resourceType = dashboardId const resourceType = dashboardId
? CreationMethod.DASHBOARDS ? CreationMethod.DASHBOARDS
: CreationMethod.CHARTS; : CreationMethod.CHARTS;
return reportSelector(state, resourceType, dashboardId || chart?.id); return (
reportSelector(state, resourceType, dashboardId || chart?.id) ||
EMPTY_OBJECT
);
}); });
const isReportActive: boolean = report?.active || false; const isReportActive: boolean = report?.active || false;
@ -133,6 +140,12 @@ export default function HeaderReportDropDown({
// this is in the case that there is an anonymous user. // this is in the case that there is an anonymous user.
return false; return false;
} }
// Cannot add reports if the resource is not saved
if (!(dashboardId || chart?.id)) {
return false;
}
const roles = Object.keys(user.roles || []); const roles = Object.keys(user.roles || []);
const permissions = roles.map(key => const permissions = roles.map(key =>
user.roles[key].filter( user.roles[key].filter(
@ -200,7 +213,21 @@ export default function HeaderReportDropDown({
}; };
const textMenu = () => const textMenu = () =>
report ? ( isEmpty(report) ? (
<Menu selectable={false} css={onMenuHover}>
<Menu.Item onClick={handleShowMenu}>
{DropdownItemExtension ? (
<StyledDropdownItemWithIcon>
<div>{t('Set up an email report')}</div>
<DropdownItemExtension />
</StyledDropdownItemWithIcon>
) : (
t('Set up an email report')
)}
</Menu.Item>
<Menu.Divider />
</Menu>
) : (
isDropdownVisible && ( isDropdownVisible && (
<Menu selectable={false} css={{ border: 'none' }}> <Menu selectable={false} css={{ border: 'none' }}>
<Menu.Item <Menu.Item
@ -220,20 +247,6 @@ export default function HeaderReportDropDown({
</Menu.Item> </Menu.Item>
</Menu> </Menu>
) )
) : (
<Menu selectable={false} css={onMenuHover}>
<Menu.Item onClick={handleShowMenu}>
{DropdownItemExtension ? (
<StyledDropdownItemWithIcon>
<div>{t('Set up an email report')}</div>
<DropdownItemExtension />
</StyledDropdownItemWithIcon>
) : (
t('Set up an email report')
)}
</Menu.Item>
<Menu.Divider />
</Menu>
); );
const menu = () => ( const menu = () => (
<Menu selectable={false} css={{ width: '200px' }}> <Menu selectable={false} css={{ width: '200px' }}>
@ -260,7 +273,17 @@ export default function HeaderReportDropDown({
); );
const iconMenu = () => const iconMenu = () =>
report ? ( isEmpty(report) ? (
<span
role="button"
title={t('Schedule email report')}
tabIndex={0}
className="action-button action-schedule-report"
onClick={() => setShowModal(true)}
>
<Icons.Calendar />
</span>
) : (
<> <>
<NoAnimationDropdown <NoAnimationDropdown
overlay={menu()} overlay={menu()}
@ -278,16 +301,6 @@ export default function HeaderReportDropDown({
</span> </span>
</NoAnimationDropdown> </NoAnimationDropdown>
</> </>
) : (
<span
role="button"
title={t('Schedule email report')}
tabIndex={0}
className="action-button action-schedule-report"
onClick={() => setShowModal(true)}
>
<Icons.Calendar />
</span>
); );
return ( return (

View File

@ -93,6 +93,9 @@ type ReportObjectState = Partial<ReportObject> & {
isSubmitting?: boolean; isSubmitting?: boolean;
}; };
// Same instance to be used in useEffects
const EMPTY_OBJECT = {};
function ReportModal({ function ReportModal({
onHide, onHide,
show = false, show = false,
@ -147,7 +150,10 @@ function ReportModal({
const resourceType = dashboardId const resourceType = dashboardId
? CreationMethod.DASHBOARDS ? CreationMethod.DASHBOARDS
: CreationMethod.CHARTS; : CreationMethod.CHARTS;
return reportSelector(state, resourceType, dashboardId || chart?.id); return (
reportSelector(state, resourceType, dashboardId || chart?.id) ||
EMPTY_OBJECT
);
}); });
const isEditMode = report && Object.keys(report).length; const isEditMode = report && Object.keys(report).length;

View File

@ -143,6 +143,8 @@ export function toggleActive(report, isActive) {
}; };
} }
export const DELETE_REPORT = 'DELETE_REPORT';
export function deleteActiveReport(report) { export function deleteActiveReport(report) {
return function deleteActiveReportThunk(dispatch) { return function deleteActiveReportThunk(dispatch) {
return SupersetClient.delete({ return SupersetClient.delete({
@ -152,7 +154,7 @@ export function deleteActiveReport(report) {
dispatch(addDangerToast(t('Your report could not be deleted'))); dispatch(addDangerToast(t('Your report could not be deleted')));
}) })
.finally(() => { .finally(() => {
dispatch(structureFetchAction); dispatch({ type: DELETE_REPORT, report });
dispatch(addSuccessToast(t('Deleted: %s', report.name))); dispatch(addSuccessToast(t('Deleted: %s', report.name)));
}); });
}; };

View File

@ -18,7 +18,13 @@
*/ */
/* eslint-disable camelcase */ /* eslint-disable camelcase */
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import { SET_REPORT, ADD_REPORT, EDIT_REPORT } from '../actions/reports'; import { omit } from 'lodash';
import {
SET_REPORT,
ADD_REPORT,
EDIT_REPORT,
DELETE_REPORT,
} from '../actions/reports';
export default function reportsReducer(state = {}, action) { export default function reportsReducer(state = {}, action) {
const actionHandlers = { const actionHandlers = {
@ -78,6 +84,17 @@ export default function reportsReducer(state = {}, action) {
}, },
}; };
}, },
[DELETE_REPORT]() {
const { report } = action;
const reportTypeId = report.dashboard || report.chart;
return {
...state,
[report.creation_method]: {
...omit(state[report.creation_method], reportTypeId),
},
};
},
}; };
if (action.type in actionHandlers) { if (action.type in actionHandlers) {

View File

@ -867,5 +867,5 @@ export const reportSelector = (
if (resourceId) { if (resourceId) {
return state.reports[resourceType]?.[resourceId]; return state.reports[resourceType]?.[resourceId];
} }
return {}; return null;
}; };