You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2023/04/06 19:00:57 UTC
[superset] branch master updated: fix: Disables email reports for unsaved charts (#23588)
This is an automated email from the ASF dual-hosted git repository.
michaelsmolina 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 290920c4fb fix: Disables email reports for unsaved charts (#23588)
290920c4fb is described below
commit 290920c4fb1fec85bf6f95e23f3c91b2681cfcbe
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Thu Apr 6 16:00:47 2023 -0300
fix: Disables email reports for unsaved charts (#23588)
---
.../ReportModal/HeaderReportDropdown/index.tsx | 67 +++++++++++++---------
.../src/components/ReportModal/index.tsx | 8 ++-
superset-frontend/src/reports/actions/reports.js | 4 +-
superset-frontend/src/reports/reducers/reports.js | 19 +++++-
superset-frontend/src/views/CRUD/hooks.ts | 2 +-
5 files changed, 69 insertions(+), 31 deletions(-)
diff --git a/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx b/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
index 6d141f941c..b2e47cc53c 100644
--- a/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
+++ b/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
@@ -18,6 +18,7 @@
*/
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
+import { isEmpty } from 'lodash';
import {
t,
SupersetTheme,
@@ -103,6 +104,9 @@ export interface HeaderReportProps {
showReportSubMenu?: boolean;
}
+// Same instance to be used in useEffects
+const EMPTY_OBJECT = {};
+
export default function HeaderReportDropDown({
dashboardId,
chart,
@@ -116,7 +120,10 @@ export default function HeaderReportDropDown({
const resourceType = dashboardId
? CreationMethod.DASHBOARDS
: CreationMethod.CHARTS;
- return reportSelector(state, resourceType, dashboardId || chart?.id);
+ return (
+ reportSelector(state, resourceType, dashboardId || chart?.id) ||
+ EMPTY_OBJECT
+ );
});
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.
return false;
}
+
+ // Cannot add reports if the resource is not saved
+ if (!(dashboardId || chart?.id)) {
+ return false;
+ }
+
const roles = Object.keys(user.roles || []);
const permissions = roles.map(key =>
user.roles[key].filter(
@@ -200,7 +213,21 @@ export default function HeaderReportDropDown({
};
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 && (
<Menu selectable={false} css={{ border: 'none' }}>
<Menu.Item
@@ -220,20 +247,6 @@ export default function HeaderReportDropDown({
</Menu.Item>
</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 = () => (
<Menu selectable={false} css={{ width: '200px' }}>
@@ -260,7 +273,17 @@ export default function HeaderReportDropDown({
);
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
overlay={menu()}
@@ -278,16 +301,6 @@ export default function HeaderReportDropDown({
</span>
</NoAnimationDropdown>
</>
- ) : (
- <span
- role="button"
- title={t('Schedule email report')}
- tabIndex={0}
- className="action-button action-schedule-report"
- onClick={() => setShowModal(true)}
- >
- <Icons.Calendar />
- </span>
);
return (
diff --git a/superset-frontend/src/components/ReportModal/index.tsx b/superset-frontend/src/components/ReportModal/index.tsx
index 9f9596e2ff..345d8b8224 100644
--- a/superset-frontend/src/components/ReportModal/index.tsx
+++ b/superset-frontend/src/components/ReportModal/index.tsx
@@ -93,6 +93,9 @@ type ReportObjectState = Partial<ReportObject> & {
isSubmitting?: boolean;
};
+// Same instance to be used in useEffects
+const EMPTY_OBJECT = {};
+
function ReportModal({
onHide,
show = false,
@@ -147,7 +150,10 @@ function ReportModal({
const resourceType = dashboardId
? CreationMethod.DASHBOARDS
: 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;
diff --git a/superset-frontend/src/reports/actions/reports.js b/superset-frontend/src/reports/actions/reports.js
index 96a435ec5d..45edc90129 100644
--- a/superset-frontend/src/reports/actions/reports.js
+++ b/superset-frontend/src/reports/actions/reports.js
@@ -143,6 +143,8 @@ export function toggleActive(report, isActive) {
};
}
+export const DELETE_REPORT = 'DELETE_REPORT';
+
export function deleteActiveReport(report) {
return function deleteActiveReportThunk(dispatch) {
return SupersetClient.delete({
@@ -152,7 +154,7 @@ export function deleteActiveReport(report) {
dispatch(addDangerToast(t('Your report could not be deleted')));
})
.finally(() => {
- dispatch(structureFetchAction);
+ dispatch({ type: DELETE_REPORT, report });
dispatch(addSuccessToast(t('Deleted: %s', report.name)));
});
};
diff --git a/superset-frontend/src/reports/reducers/reports.js b/superset-frontend/src/reports/reducers/reports.js
index 1896250f5c..823660b645 100644
--- a/superset-frontend/src/reports/reducers/reports.js
+++ b/superset-frontend/src/reports/reducers/reports.js
@@ -18,7 +18,13 @@
*/
/* eslint-disable camelcase */
// 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) {
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) {
diff --git a/superset-frontend/src/views/CRUD/hooks.ts b/superset-frontend/src/views/CRUD/hooks.ts
index dfcf23e190..91af5817b4 100644
--- a/superset-frontend/src/views/CRUD/hooks.ts
+++ b/superset-frontend/src/views/CRUD/hooks.ts
@@ -867,5 +867,5 @@ export const reportSelector = (
if (resourceId) {
return state.reports[resourceType]?.[resourceId];
}
- return {};
+ return null;
};