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:
parent
9646591d24
commit
3e3fbccdcb
|
|
@ -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}`;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ export const URL_PARAMS = {
|
|||
name: 'dataset_id',
|
||||
type: 'string',
|
||||
},
|
||||
dashboardId: {
|
||||
name: 'dashboard_id',
|
||||
type: 'string',
|
||||
},
|
||||
force: {
|
||||
name: 'force',
|
||||
type: 'boolean',
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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 />
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ function mapStateToProps({ dashboardState, dashboardInfo }) {
|
|||
return {
|
||||
editMode: dashboardState.editMode,
|
||||
canEdit: dashboardInfo.dash_edit_perm,
|
||||
dashboardId: dashboardInfo.id,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
/* header has mysterious extra margin */
|
||||
header.top {
|
||||
margin-bottom: 2px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -256,8 +256,7 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
|
|||
checked={this.state.action === 'saveas'}
|
||||
onChange={() => this.changeAction('saveas')}
|
||||
>
|
||||
{' '}
|
||||
{t('Save as ...')}
|
||||
{t('Save as...')}
|
||||
</Radio>
|
||||
</FormItem>
|
||||
<hr />
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Reference in New Issue