This is an automated email from the ASF dual-hosted git repository.
elizabeth pushed a commit to branch selfSubscribeReports
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/selfSubscribeReports by this
push:
new 03f8ddd feat: toggle the ReportModal Icon based on user permissions
(#15780)
03f8ddd is described below
commit 03f8dddfb9563f5314ae493157568a560959aa9f
Author: AAfghahi <[email protected]>
AuthorDate: Tue Jul 20 19:32:53 2021 -0400
feat: toggle the ReportModal Icon based on user permissions (#15780)
* style: Rough draft of email report modal (#15666)
* clears errors when closing out of modal (#15623)
* fix: avoid fetching favorite status for anonymous user (#15590)
* avoid fetching favorite status for anonymous user
* add test + fix types
* fix lint errors
* Building ReportModal component
* Continued ReportModal creation
* Visual details updated
* CronError style
* Very basic testing added
Co-authored-by: AAfghahi <[email protected]>
Co-authored-by: aspedrosa <[email protected]>
* first draft
* added testing props
* cleaned up rebase
* changed name and type
Co-authored-by: Lyndsi Kay Williams
<[email protected]>
Co-authored-by: aspedrosa <[email protected]>
---
superset-frontend/spec/fixtures/mockState.js | 2 ++
.../dashboard/components/Header/Header.test.tsx | 14 +++++++--
.../src/dashboard/components/Header/index.jsx | 34 +++++++++++++++-------
.../src/dashboard/components/Header/types.ts | 2 +-
.../src/dashboard/containers/DashboardHeader.jsx | 3 +-
5 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/superset-frontend/spec/fixtures/mockState.js
b/superset-frontend/spec/fixtures/mockState.js
index dfa77fd..3687004 100644
--- a/superset-frontend/spec/fixtures/mockState.js
+++ b/superset-frontend/spec/fixtures/mockState.js
@@ -28,6 +28,7 @@ import dashboardInfo from './mockDashboardInfo';
import { emptyFilters } from './mockDashboardFilters';
import dashboardState from './mockDashboardState';
import { sliceEntitiesForChart } from './mockSliceEntities';
+import { user } from '../javascripts/sqllab/fixtures';
export default {
datasources,
@@ -40,5 +41,6 @@ export default {
dashboardState,
dashboardLayout,
messageToasts,
+ user,
impressionId: 'mock_impression_id',
};
diff --git a/superset-frontend/src/dashboard/components/Header/Header.test.tsx
b/superset-frontend/src/dashboard/components/Header/Header.test.tsx
index 88d22b8..47006ab 100644
--- a/superset-frontend/src/dashboard/components/Header/Header.test.tsx
+++ b/superset-frontend/src/dashboard/components/Header/Header.test.tsx
@@ -38,7 +38,17 @@ const createProps = () => ({
conf: {},
},
},
- userId: 1,
+ user: {
+ createdOn: '2021-04-27T18:12:38.952304',
+ email: 'admin',
+ firstName: 'admin',
+ isActive: true,
+ lastName: 'admin',
+ permissions: {},
+ roles: { Admin: Array(173) },
+ userId: 1,
+ username: 'admin',
+ },
dashboardTitle: 'Dashboard Title',
charts: {},
layout: {},
@@ -253,7 +263,7 @@ test('should NOT render the fave icon on anonymous user',
() => {
const mockedProps = createProps();
const anonymousUserProps = {
...mockedProps,
- userId: undefined,
+ user: undefined,
};
render(setup(anonymousUserProps));
expect(mockedProps.fetchFaveStar).not.toHaveBeenCalled();
diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx
b/superset-frontend/src/dashboard/components/Header/index.jsx
index 9acff98..e86e36f 100644
--- a/superset-frontend/src/dashboard/components/Header/index.jsx
+++ b/superset-frontend/src/dashboard/components/Header/index.jsx
@@ -40,6 +40,7 @@ import UndoRedoKeyListeners from
'src/dashboard/components/UndoRedoKeyListeners'
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
import ReportModal from 'src/components/ReportModal';
import { chartPropShape } from 'src/dashboard/util/propShapes';
+import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
import {
UNDO_LIMIT,
SAVE_TYPE_OVERWRITE,
@@ -52,8 +53,7 @@ const propTypes = {
addSuccessToast: PropTypes.func.isRequired,
addDangerToast: PropTypes.func.isRequired,
addWarningToast: PropTypes.func.isRequired,
- userId: PropTypes.number,
- userEmail: PropTypes.string,
+ user: UserWithPermissionsAndRoles,
dashboardInfo: PropTypes.object.isRequired,
dashboardTitle: PropTypes.string.isRequired,
dataMask: PropTypes.object.isRequired,
@@ -365,6 +365,20 @@ class Header extends React.PureComponent {
this.setState({ showingReportModal: false });
}
+ canAddReportsModal() {
+ if (!this.props.user) {
+ // this is in the case that there is an anonymous user.
+ return false;
+ }
+ const roles = Object.keys(this.props.user?.roles);
+ const permissions = roles.map(key =>
+ this.props.user.roles[key].filter(
+ perms => perms[0] === 'can_add' && perms[1] === 'AlertModelView',
+ ),
+ );
+ return permissions[0].length > 0;
+ }
+
render() {
const {
dashboardTitle,
@@ -384,8 +398,7 @@ class Header extends React.PureComponent {
updateCss,
editMode,
isPublished,
- userId,
- userEmail,
+ user,
dashboardInfo,
hasUnsavedChanges,
isLoading,
@@ -394,10 +407,10 @@ class Header extends React.PureComponent {
setRefreshFrequency,
lastModifiedTime,
} = this.props;
-
const userCanEdit = dashboardInfo.dash_edit_perm;
const userCanShare = dashboardInfo.dash_share_perm;
const userCanSaveAs = dashboardInfo.dash_save_perm;
+ const shouldShowReportsModal = !editMode && this.canAddReportsModal();
const refreshLimit =
dashboardInfo.common.conf.SUPERSET_DASHBOARD_PERIODICAL_REFRESH_LIMIT;
const refreshWarning =
@@ -424,7 +437,7 @@ class Header extends React.PureComponent {
canEdit={userCanEdit}
canSave={userCanSaveAs}
/>
- {userId && (
+ {user?.userId && (
<FaveStar
itemId={dashboardInfo.id}
fetchFaveStar={this.props.fetchFaveStar}
@@ -513,8 +526,7 @@ class Header extends React.PureComponent {
</span>
</>
)}
-
- {!editMode && (
+ {shouldShowReportsModal && (
<>
<span
role="button"
@@ -523,7 +535,7 @@ class Header extends React.PureComponent {
className="action-button"
onClick={this.showReportModal}
>
- <Icon name="calendar" />
+ <Icons.Calendar />
</span>
</>
)}
@@ -561,8 +573,8 @@ class Header extends React.PureComponent {
show={this.state.showingReportModal}
onHide={this.hideReportModal}
props={{
- userId,
- userEmail,
+ userId: user.userId,
+ userEmail: user.email,
dashboardId: dashboardInfo.id,
}}
/>
diff --git a/superset-frontend/src/dashboard/components/Header/types.ts
b/superset-frontend/src/dashboard/components/Header/types.ts
index 3c8e8cf..8ddf9bf 100644
--- a/superset-frontend/src/dashboard/components/Header/types.ts
+++ b/superset-frontend/src/dashboard/components/Header/types.ts
@@ -65,7 +65,7 @@ export interface HeaderProps {
charts: ChartState | {};
colorScheme?: string;
customCss: string;
- userId: number | undefined;
+ user: Object | undefined;
dashboardInfo: DashboardInfo;
dashboardTitle: string;
setColorSchemeAndUnsavedChanges: () => void;
diff --git a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx
b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx
index b099494..c0e8e8c 100644
--- a/superset-frontend/src/dashboard/containers/DashboardHeader.jsx
+++ b/superset-frontend/src/dashboard/containers/DashboardHeader.jsx
@@ -81,8 +81,7 @@ function mapStateToProps({
colorScheme: dashboardState.colorScheme,
charts,
dataMask,
- userId: user.userId,
- userEmail: user.email,
+ user,
isStarred: !!dashboardState.isStarred,
isPublished: !!dashboardState.isPublished,
isLoading: isDashboardLoading(charts),