diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/index.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/index.tsx index 382fcb5bb3316..713fbf1c2dd27 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/index.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/index.tsx @@ -91,6 +91,11 @@ export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 }; const ROW_LIMIT_OPTIONS = [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000]; const SERIES_LIMITS = [5, 10, 25, 50, 100, 500]; +const appContainer = document.getElementById('app'); +const { user } = JSON.parse( + appContainer?.getAttribute('data-bootstrap') || '{}', +); + type Control = { savedMetrics?: Metric[] | null; default?: unknown; @@ -167,6 +172,7 @@ const datasourceControl: SharedControlConfig<'DatasourceControl'> = { mapStateToProps: ({ datasource, form_data }) => ({ datasource, form_data, + user, }), }; diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx index 0f11f48dd840c..99c596b80ed9c 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx @@ -47,7 +47,22 @@ const datasource = { main_dttm_col: 'None', datasource_name: 'table1', description: 'desc', + owners: [{ username: 'admin', userId: 1 }], }; + +const mockUser = { + createdOn: '2021-04-27T18:12:38.952304', + email: 'admin', + firstName: 'admin', + isActive: true, + lastName: 'admin', + permissions: {}, + roles: { Admin: Array(173) }, + userId: 1, + username: 'admin', + isAnonymous: false, +}; + const props: DatasourcePanelProps = { datasource, controls: { @@ -57,6 +72,7 @@ const props: DatasourcePanelProps = { type: DatasourceControl, label: 'hello', datasource, + user: mockUser, }, }, actions: { @@ -154,6 +170,7 @@ test('should render a warning', async () => { datasource: { ...props.controls.datasource, datasource: deprecatedDatasource, + user: mockUser, }, }, }), diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx index c38c1b59ae4fc..8bd39aa52f02c 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx @@ -31,12 +31,14 @@ import { FAST_DEBOUNCE } from 'src/constants'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; import { ExploreActions } from 'src/explore/actions/exploreActions'; import Control from 'src/explore/components/Control'; +import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes'; import DatasourcePanelDragOption from './DatasourcePanelDragOption'; import { DndItemType } from '../DndItemType'; import { StyledColumnOption, StyledMetricOption } from '../optionRenderers'; interface DatasourceControl extends ControlConfig { datasource?: DatasourceMeta; + user: UserWithPermissionsAndRoles; } export interface Props { diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx index 73c2777663a19..41a40c0bc4422 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx +++ b/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.jsx @@ -41,6 +41,7 @@ const defaultProps = { id: 1, columns: [], metrics: [], + owners: [{ username: 'admin', userId: 1 }], database: { backend: 'mysql', name: 'main', @@ -51,6 +52,17 @@ const defaultProps = { setDatasource: sinon.spy(), }, onChange: sinon.spy(), + 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', + }, }; describe('DatasourceControl', () => { @@ -107,6 +119,7 @@ describe('DatasourceControl', () => { id: 1, columns: [], metrics: [], + owners: [{ username: 'admin', userId: 1 }], database: { backend: 'druid', name: 'main', diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.tsx b/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.tsx index f4f66ef43ead8..4811743489ff2 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/DatasourceControl/DatasourceControl.test.tsx @@ -48,6 +48,17 @@ const createProps = () => ({ name: 'datasource', actions: {}, isEditable: true, + 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', + }, onChange: jest.fn(), onDatasourceSave: jest.fn(), }); diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx index b011901eb0306..73aa5e4d913d5 100644 --- a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx +++ b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx @@ -35,6 +35,7 @@ import Button from 'src/components/Button'; import ErrorAlert from 'src/components/ErrorMessage/ErrorAlert'; import WarningIconWithTooltip from 'src/components/WarningIconWithTooltip'; import { URL_PARAMS } from 'src/constants'; +import { isUserAdmin } from 'src/dashboard/util/findPermission'; const propTypes = { actions: PropTypes.object.isRequired, @@ -196,12 +197,32 @@ class DatasourceControl extends React.PureComponent { } const isSqlSupported = datasource.type === 'table'; + const { user } = this.props; + const allowEdit = + datasource.owners.map(o => o.id).includes(user.userId) || + isUserAdmin(user); + + const editText = t('Edit dataset'); const datasourceMenu = (