feat(explore): Fill dashboard name when adding new chart from dashboard view (#20129)

* feat(explore): Fill dashboard name when adding new chart from dashboard view

* Update import paths

* Update test

* Fix test
This commit is contained in:
Kamil Gabryjelski 2022-05-31 18:11:02 +02:00 committed by GitHub
parent 9646591d24
commit 3e3fbccdcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 50 additions and 12 deletions

View File

@ -19,6 +19,9 @@
import React, { ReactNode } from 'react';
import rison from 'rison';
import { styled, t, SupersetClient, JsonResponse } from '@superset-ui/core';
import { getUrlParam } from 'src/utils/urlUtils';
import { URL_PARAMS } from 'src/constants';
import { isNullish } from 'src/utils/common';
import Button from 'src/components/Button';
import { Select, Steps } from 'src/components';
import { FormLabel } from 'src/components/Form';
@ -195,10 +198,12 @@ export default class AddSliceContainer extends React.PureComponent<
}
exploreUrl() {
const dashboardId = getUrlParam(URL_PARAMS.dashboardId);
const formData = encodeURIComponent(
JSON.stringify({
viz_type: this.state.visType,
datasource: this.state.datasource?.value,
...(!isNullish(dashboardId) && { dashboardId }),
}),
);
return `/superset/explore/?form_data=${formData}`;

View File

@ -71,6 +71,10 @@ export const URL_PARAMS = {
name: 'dataset_id',
type: 'string',
},
dashboardId: {
name: 'dashboard_id',
type: 'string',
},
force: {
name: 'force',
type: 'boolean',

View File

@ -35,6 +35,7 @@ const propTypes = {
resizeComponent: PropTypes.func.isRequired,
setDirectPathToChild: PropTypes.func.isRequired,
width: PropTypes.number.isRequired,
dashboardId: PropTypes.number,
};
const defaultProps = {};
@ -143,6 +144,7 @@ class DashboardGrid extends React.PureComponent {
editMode,
canEdit,
setEditMode,
dashboardId,
} = this.props;
const columnPlusGutterWidth =
(width + GRID_GUTTER_SIZE) / GRID_COLUMN_COUNT;
@ -167,7 +169,11 @@ class DashboardGrid extends React.PureComponent {
</>
}
buttonAction={() => {
window.open('/chart/add', '_blank', 'noopener noreferrer');
window.open(
`/chart/add?dashboard_id=${dashboardId}`,
'_blank',
'noopener noreferrer',
);
}}
image="chart.svg"
/>
@ -186,7 +192,11 @@ class DashboardGrid extends React.PureComponent {
</>
}
buttonAction={() => {
window.open('/chart/add', '_blank', 'noopener noreferrer');
window.open(
`/chart/add?dashboard_id=${dashboardId}`,
'_blank',
'noopener noreferrer',
);
}}
image="chart.svg"
/>

View File

@ -58,6 +58,7 @@ const propTypes = {
editMode: PropTypes.bool,
height: PropTypes.number,
filterboxMigrationState: FILTER_BOX_MIGRATION_STATES,
dashboardId: PropTypes.number,
};
const defaultProps = {
@ -276,7 +277,11 @@ class SliceAdder extends React.Component {
buttonStyle="link"
buttonSize="xsmall"
onClick={() =>
window.open('/chart/add', '_blank', 'noopener noreferrer')
window.open(
`/chart/add?dashboard_id=${this.props.dashboardId}`,
'_blank',
'noopener noreferrer',
)
}
>
<Icons.PlusSmall />

View File

@ -150,6 +150,7 @@ class Tab extends React.PureComponent {
isComponentVisible,
canEdit,
setEditMode,
dashboardId,
} = this.props;
const shouldDisplayEmptyState = tabComponent.children.length === 0;
@ -183,7 +184,7 @@ class Tab extends React.PureComponent {
<span>
{t('You can')}{' '}
<a
href="/chart/add"
href={`/chart/add?dashboard_id=${dashboardId}`}
rel="noopener noreferrer"
target="_blank"
>

View File

@ -294,5 +294,5 @@ test('Render tab content with no children, editMode: true, canEdit: true', () =>
).toBeVisible();
expect(
screen.getByRole('link', { name: 'create a new chart' }),
).toHaveAttribute('href', '/chart/add');
).toHaveAttribute('href', '/chart/add?dashboard_id=23');
});

View File

@ -30,6 +30,7 @@ function mapStateToProps({ dashboardState, dashboardInfo }) {
return {
editMode: dashboardState.editMode,
canEdit: dashboardInfo.dash_edit_perm,
dashboardId: dashboardInfo.id,
};
}

View File

@ -29,6 +29,7 @@ function mapStateToProps(
return {
height: ownProps.height,
userId: dashboardInfo.userId,
dashboardId: dashboardInfo.id,
selectedSliceIds: dashboardState.sliceIds,
slices: sliceEntities.slices,
isLoading: sliceEntities.isLoading,

View File

@ -19,6 +19,7 @@
/* header has mysterious extra margin */
header.top {
margin-bottom: 2px;
z-index: 10;
}
body {

View File

@ -678,12 +678,17 @@ function mapStateToProps(state) {
const chartKey = Object.keys(charts)[0];
const chart = charts[chartKey];
let dashboardId = Number(explore.form_data?.dashboardId);
if (Number.isNaN(dashboardId)) {
dashboardId = undefined;
}
return {
isDatasourceMetaLoading: explore.isDatasourceMetaLoading,
datasource: explore.datasource,
datasource_type: explore.datasource.type,
datasourceId: explore.datasource_id,
dashboardId: explore.form_data ? explore.form_data.dashboardId : undefined,
dashboardId,
controls: explore.controls,
can_overwrite: !!explore.can_overwrite,
can_add: !!explore.can_add,

View File

@ -256,8 +256,7 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
checked={this.state.action === 'saveas'}
onChange={() => this.changeAction('saveas')}
>
{' '}
{t('Save as ...')} &nbsp;
{t('Save as...')}
</Radio>
</FormItem>
<hr />

View File

@ -18,7 +18,8 @@
*/
import React, { Fragment, useState, useEffect } from 'react';
import rison from 'rison';
import { MainNav as Menu } from 'src/components/Menu';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import {
t,
styled,
@ -26,12 +27,12 @@ import {
SupersetTheme,
SupersetClient,
} from '@superset-ui/core';
import { MainNav as Menu } from 'src/components/Menu';
import { Tooltip } from 'src/components/Tooltip';
import { Link } from 'react-router-dom';
import Icons from 'src/components/Icons';
import findPermission, { isUserAdmin } from 'src/dashboard/util/findPermission';
import { useSelector } from 'react-redux';
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
import { RootState } from 'src/dashboard/types';
import LanguagePicker from './LanguagePicker';
import DatabaseModal from '../CRUD/data/database/DatabaseModal';
import { uploadUserPerms } from '../CRUD/utils';
@ -89,6 +90,9 @@ const RightMenu = ({
const user = useSelector<any, UserWithPermissionsAndRoles>(
state => state.user,
);
const dashboardId = useSelector<RootState, number | undefined>(
state => state.dashboardInfo?.id,
);
const { roles } = user;
const {
@ -162,7 +166,9 @@ const RightMenu = ({
},
{
label: t('Chart'),
url: '/chart/add',
url: Number.isInteger(dashboardId)
? `/chart/add?dashboard_id=${dashboardId}`
: '/chart/add',
icon: 'fa-fw fa-bar-chart',
perm: 'can_write',
view: 'Chart',