You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by aa...@apache.org on 2022/02/09 23:03:09 UTC

[superset] 01/18: pexdax refactor (#16333)

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

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

commit 615dffd2bb92a297bc4421c2f839226c61d5d8e8
Author: AAfghahi <48...@users.noreply.github.com>
AuthorDate: Wed Aug 18 15:58:10 2021 -0400

    pexdax refactor (#16333)
---
 .../HeaderReportActionsDropdown/index.tsx          | 106 ++++++++++++++-------
 .../src/dashboard/components/Header/index.jsx      |  57 ++++-------
 .../components/ExploreChartHeader/index.jsx        |  34 ++-----
 3 files changed, 96 insertions(+), 101 deletions(-)

diff --git a/superset-frontend/src/components/ReportModal/HeaderReportActionsDropdown/index.tsx b/superset-frontend/src/components/ReportModal/HeaderReportActionsDropdown/index.tsx
index 6fc3928..4d9ceb8 100644
--- a/superset-frontend/src/components/ReportModal/HeaderReportActionsDropdown/index.tsx
+++ b/superset-frontend/src/components/ReportModal/HeaderReportActionsDropdown/index.tsx
@@ -26,6 +26,7 @@ import { Menu, NoAnimationDropdown } from 'src/common/components';
 import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
 
 import DeleteModal from 'src/components/DeleteModal';
+import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
 
 const deleteColor = (theme: SupersetTheme) => css`
   color: ${theme.colors.error.base};
@@ -40,11 +41,19 @@ export default function HeaderReportActionsDropDown({
   toggleActive: (data: AlertObject, checked: boolean) => void;
   deleteActiveReport: (data: AlertObject) => void;
 }) {
-  const reports = useSelector<any, AlertObject>(state => state.reports);
+  const reports: Record<number, AlertObject> = useSelector<any, AlertObject>(
+    state => state.reports,
+  );
+  const user: UserWithPermissionsAndRoles = useSelector<
+    any,
+    UserWithPermissionsAndRoles
+  >(state => state.user || state.explore?.user);
   const reportsIds = Object.keys(reports);
-  const report = reports[reportsIds[0]];
-  const [currentReportDeleting, setCurrentReportDeleting] =
-    useState<AlertObject | null>(null);
+  const report: AlertObject = reports[reportsIds[0]];
+  const [
+    currentReportDeleting,
+    setCurrentReportDeleting,
+  ] = useState<AlertObject | null>(null);
   const theme = useTheme();
 
   const toggleActiveKey = async (data: AlertObject, checked: boolean) => {
@@ -58,6 +67,23 @@ export default function HeaderReportActionsDropDown({
     setCurrentReportDeleting(null);
   };
 
+  const canAddReports = () => {
+    if (!isFeatureEnabled(FeatureFlag.ALERT_REPORTS)) {
+      return false;
+    }
+    if (!user) {
+      // this is in the case that there is an anonymous user.
+      return false;
+    }
+    const roles = Object.keys(user.roles || []);
+    const permissions = roles.map(key =>
+      user.roles[key].filter(
+        perms => perms[0] === 'menu_access' && perms[1] === 'Manage',
+      ),
+    );
+    return permissions[0].length > 0;
+  };
+
   const menu = () => (
     <Menu selectable={false} css={{ width: '200px' }}>
       <Menu.Item>
@@ -80,36 +106,48 @@ export default function HeaderReportActionsDropDown({
     </Menu>
   );
 
-  return isFeatureEnabled(FeatureFlag.ALERT_REPORTS) ? (
-    <>
-      <NoAnimationDropdown
-        // ref={ref}
-        overlay={menu()}
-        trigger={['click']}
-        getPopupContainer={(triggerNode: any) =>
-          triggerNode.closest('.action-button')
-        }
+  return canAddReports() ? (
+    report ? (
+      <>
+        <NoAnimationDropdown
+          // ref={ref}
+          overlay={menu()}
+          trigger={['click']}
+          getPopupContainer={(triggerNode: any) =>
+            triggerNode.closest('.action-button')
+          }
+        >
+          <span role="button" className="action-button" tabIndex={0}>
+            <Icons.Calendar />
+          </span>
+        </NoAnimationDropdown>
+        {currentReportDeleting && (
+          <DeleteModal
+            description={t(
+              'This action will permanently delete %s.',
+              currentReportDeleting.name,
+            )}
+            onConfirm={() => {
+              if (currentReportDeleting) {
+                handleReportDelete(currentReportDeleting);
+              }
+            }}
+            onHide={() => setCurrentReportDeleting(null)}
+            open
+            title={t('Delete Report?')}
+          />
+        )}
+      </>
+    ) : (
+      <span
+        role="button"
+        title={t('Schedule email report')}
+        tabIndex={0}
+        className="action-button"
+        onClick={showReportModal}
       >
-        <span role="button" className="action-button" tabIndex={0}>
-          <Icons.Calendar />
-        </span>
-      </NoAnimationDropdown>
-      {currentReportDeleting && (
-        <DeleteModal
-          description={t(
-            'This action will permanently delete %s.',
-            currentReportDeleting.name,
-          )}
-          onConfirm={() => {
-            if (currentReportDeleting) {
-              handleReportDelete(currentReportDeleting);
-            }
-          }}
-          onHide={() => setCurrentReportDeleting(null)}
-          open
-          title={t('Delete Report?')}
-        />
-      )}
-    </>
+        <Icons.Calendar />
+      </span>
+    )
   ) : null;
 }
diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx
index a670618..516359a 100644
--- a/superset-frontend/src/dashboard/components/Header/index.jsx
+++ b/superset-frontend/src/dashboard/components/Header/index.jsx
@@ -165,7 +165,6 @@ class Header extends React.PureComponent {
     this.hidePropertiesModal = this.hidePropertiesModal.bind(this);
     this.showReportModal = this.showReportModal.bind(this);
     this.hideReportModal = this.hideReportModal.bind(this);
-    this.renderReportModal = this.renderReportModal.bind(this);
   }
 
   componentDidMount() {
@@ -411,29 +410,6 @@ class Header extends React.PureComponent {
     this.setState({ showingReportModal: false });
   }
 
-  renderReportModal() {
-    const attachedReportExists = !!Object.keys(this.props.reports).length;
-    return attachedReportExists ? (
-      <HeaderReportActionsDropdown
-        showReportModal={this.showReportModal}
-        toggleActive={this.props.toggleActive}
-        deleteActiveReport={this.props.deleteActiveReport}
-      />
-    ) : (
-      <>
-        <span
-          role="button"
-          title={t('Schedule email report')}
-          tabIndex={0}
-          className="action-button"
-          onClick={this.showReportModal}
-        >
-          <Icons.Calendar />
-        </span>
-      </>
-    );
-  }
-
   canAddReports() {
     if (!isFeatureEnabled(FeatureFlag.ALERT_REPORTS)) {
       return false;
@@ -488,7 +464,6 @@ class Header extends React.PureComponent {
     const userCanSaveAs =
       dashboardInfo.dash_save_perm &&
       filterboxMigrationState !== FILTER_BOX_MIGRATION_STATES.REVIEWING;
-    const shouldShowReport = !editMode && this.canAddReports();
     const refreshLimit =
       dashboardInfo.common?.conf?.SUPERSET_DASHBOARD_PERIODICAL_REFRESH_LIMIT;
     const refreshWarning =
@@ -602,27 +577,31 @@ class Header extends React.PureComponent {
               )}
             </div>
           )}
-          {editMode && (
+          {editMode ? (
             <UndoRedoKeyListeners
               onUndo={this.handleCtrlZ}
               onRedo={this.handleCtrlY}
             />
-          )}
-
-          {!editMode && userCanEdit && (
+          ) : (
             <>
-              <span
-                role="button"
-                title={t('Edit dashboard')}
-                tabIndex={0}
-                className="action-button"
-                onClick={this.toggleEditMode}
-              >
-                <Icons.EditAlt />
-              </span>
+              {userCanEdit && (
+                <span
+                  role="button"
+                  title={t('Edit dashboard')}
+                  tabIndex={0}
+                  className="action-button"
+                  onClick={this.toggleEditMode}
+                >
+                  <Icons.EditAlt />
+                </span>
+              )}
+              <HeaderReportActionsDropdown
+                showReportModal={this.showReportModal}
+                toggleActive={this.props.toggleActive}
+                deleteActiveReport={this.props.deleteActiveReport}
+              />
             </>
           )}
-          {shouldShowReport && this.renderReportModal()}
 
           <PropertiesModal
             dashboardId={dashboardInfo.id}
diff --git a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
index bb1fde9..c1bb3c0 100644
--- a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
@@ -119,7 +119,6 @@ export class ExploreChartHeader extends React.PureComponent {
     this.closePropertiesModal = this.closePropertiesModal.bind(this);
     this.showReportModal = this.showReportModal.bind(this);
     this.hideReportModal = this.hideReportModal.bind(this);
-    this.renderReportModal = this.renderReportModal.bind(this);
     this.fetchChartDashboardData = this.fetchChartDashboardData.bind(this);
   }
 
@@ -158,8 +157,7 @@ export class ExploreChartHeader extends React.PureComponent {
             // setting the chart to use the dashboard custom label colors if any
             const labelColors =
               JSON.parse(dashboard.json_metadata).label_colors || {};
-            const categoricalNamespace =
-              CategoricalColorNamespace.getNamespace();
+            const categoricalNamespace = CategoricalColorNamespace.getNamespace();
 
             Object.keys(labelColors).forEach(label => {
               categoricalNamespace.setColor(label, labelColors[label]);
@@ -207,30 +205,6 @@ export class ExploreChartHeader extends React.PureComponent {
     this.setState({ showingReportModal: false });
   }
 
-  renderReportModal() {
-    const attachedReportExists = !!Object.keys(this.props.reports).length;
-    return attachedReportExists ? (
-      <HeaderReportActionsDropdown
-        showReportModal={this.showReportModal}
-        hideReportModal={this.hideReportModal}
-        toggleActive={this.props.toggleActive}
-        deleteActiveReport={this.props.deleteActiveReport}
-      />
-    ) : (
-      <>
-        <span
-          role="button"
-          title={t('Schedule email report')}
-          tabIndex={0}
-          className="action-button"
-          onClick={this.showReportModal}
-        >
-          <Icons.Calendar />
-        </span>
-      </>
-    );
-  }
-
   canAddReports() {
     if (!isFeatureEnabled(FeatureFlag.ALERT_REPORTS)) {
       return false;
@@ -348,7 +322,11 @@ export class ExploreChartHeader extends React.PureComponent {
             isRunning={chartStatus === 'loading'}
             status={CHART_STATUS_MAP[chartStatus]}
           />
-          {this.canAddReports() && this.renderReportModal()}
+          <HeaderReportActionsDropdown
+            showReportModal={this.showReportModal}
+            toggleActive={this.props.toggleActive}
+            deleteActiveReport={this.props.deleteActiveReport}
+          />
           <ReportModal
             show={this.state.showingReportModal}
             onHide={this.hideReportModal}