feat: Displaying details to Dataset/Database deletion modals (#30016)
This commit is contained in:
parent
5a0e88771b
commit
7bb6a14944
|
|
@ -53,6 +53,7 @@ repos:
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
exclude: ^.*\.(snap)
|
||||||
args: ["--markdown-linebreak-ext=md"]
|
args: ["--markdown-linebreak-ext=md"]
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
rev: v3.1.0 # Use the sha or tag you want to point at
|
rev: v3.1.0 # Use the sha or tag you want to point at
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,9 @@ tsconfig.tsbuildinfo
|
||||||
generator-superset/*
|
generator-superset/*
|
||||||
temporary_superset_ui/*
|
temporary_superset_ui/*
|
||||||
|
|
||||||
|
# skip license checks for auto-generated test snapshots
|
||||||
|
.*snap
|
||||||
|
|
||||||
# docs overrides for third party logos we don't have the rights to
|
# docs overrides for third party logos we don't have the rights to
|
||||||
google-big-query.svg
|
google-big-query.svg
|
||||||
google-sheets.svg
|
google-sheets.svg
|
||||||
|
|
|
||||||
|
|
@ -25,5 +25,6 @@ CHANGELOG/
|
||||||
*.geojson
|
*.geojson
|
||||||
*-topo.json
|
*-topo.json
|
||||||
storybook-static/
|
storybook-static/
|
||||||
|
*.snap
|
||||||
|
|
||||||
/.nx/workspace-data
|
/.nx/workspace-data
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ export default function DeleteModal({
|
||||||
primaryButtonType="danger"
|
primaryButtonType="danger"
|
||||||
show={open}
|
show={open}
|
||||||
title={title}
|
title={title}
|
||||||
|
centered
|
||||||
>
|
>
|
||||||
<DescriptionContainer>{description}</DescriptionContainer>
|
<DescriptionContainer>{description}</DescriptionContainer>
|
||||||
<StyledDiv>
|
<StyledDiv>
|
||||||
|
|
|
||||||
|
|
@ -164,14 +164,7 @@ describe('Admin DatabaseList', () => {
|
||||||
});
|
});
|
||||||
await waitForComponentToPaint(wrapper);
|
await waitForComponentToPaint(wrapper);
|
||||||
|
|
||||||
expect(wrapper.find(DeleteModal).props().description)
|
expect(wrapper.find(DeleteModal).props().description).toMatchSnapshot();
|
||||||
.toMatchInlineSnapshot(`
|
|
||||||
<React.Fragment>
|
|
||||||
<p>
|
|
||||||
The database db 0 is linked to 0 charts that appear on 0 dashboards and users have 0 SQL Lab tabs using this database open. Are you sure you want to continue? Deleting the database will break those objects.
|
|
||||||
</p>
|
|
||||||
</React.Fragment>
|
|
||||||
`);
|
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
wrapper
|
wrapper
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Admin DatabaseList deletes 1`] = `
|
||||||
|
<React.Fragment>
|
||||||
|
<p>
|
||||||
|
The database
|
||||||
|
|
||||||
|
<b>
|
||||||
|
db 0
|
||||||
|
</b>
|
||||||
|
|
||||||
|
is linked to 0 charts that appear on 0 dashboards and users have 0 SQL Lab tabs using this database open. Are you sure you want to continue? Deleting the database will break those objects.
|
||||||
|
</p>
|
||||||
|
</React.Fragment>
|
||||||
|
`;
|
||||||
|
|
@ -27,7 +27,6 @@ import rison from 'rison';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useQueryParams, BooleanParam } from 'use-query-params';
|
import { useQueryParams, BooleanParam } from 'use-query-params';
|
||||||
import { LocalStorageKeys, setItem } from 'src/utils/localStorageHelpers';
|
import { LocalStorageKeys, setItem } from 'src/utils/localStorageHelpers';
|
||||||
|
|
||||||
import Loading from 'src/components/Loading';
|
import Loading from 'src/components/Loading';
|
||||||
import { useListViewResource } from 'src/views/CRUD/hooks';
|
import { useListViewResource } from 'src/views/CRUD/hooks';
|
||||||
import {
|
import {
|
||||||
|
|
@ -65,8 +64,8 @@ const dbConfigExtraExtension = extensionsRegistry.get(
|
||||||
const PAGE_SIZE = 25;
|
const PAGE_SIZE = 25;
|
||||||
|
|
||||||
interface DatabaseDeleteObject extends DatabaseObject {
|
interface DatabaseDeleteObject extends DatabaseObject {
|
||||||
chart_count: number;
|
charts: any;
|
||||||
dashboard_count: number;
|
dashboards: any;
|
||||||
sqllab_tab_count: number;
|
sqllab_tab_count: number;
|
||||||
}
|
}
|
||||||
interface DatabaseListProps {
|
interface DatabaseListProps {
|
||||||
|
|
@ -170,8 +169,8 @@ function DatabaseList({
|
||||||
.then(({ json = {} }) => {
|
.then(({ json = {} }) => {
|
||||||
setDatabaseCurrentlyDeleting({
|
setDatabaseCurrentlyDeleting({
|
||||||
...database,
|
...database,
|
||||||
chart_count: json.charts.count,
|
charts: json.charts,
|
||||||
dashboard_count: json.dashboards.count,
|
dashboards: json.dashboards,
|
||||||
sqllab_tab_count: json.sqllab_tab_states.count,
|
sqllab_tab_count: json.sqllab_tab_states.count,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -609,14 +608,82 @@ function DatabaseList({
|
||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
|
{t('The database')}{' '}
|
||||||
|
<b>{databaseCurrentlyDeleting.database_name}</b>{' '}
|
||||||
{t(
|
{t(
|
||||||
'The database %s is linked to %s charts that appear on %s dashboards and users have %s SQL Lab tabs using this database open. Are you sure you want to continue? Deleting the database will break those objects.',
|
'is linked to %s charts that appear on %s dashboards and users have %s SQL Lab tabs using this database open. Are you sure you want to continue? Deleting the database will break those objects.',
|
||||||
databaseCurrentlyDeleting.database_name,
|
databaseCurrentlyDeleting.charts.count,
|
||||||
databaseCurrentlyDeleting.chart_count,
|
databaseCurrentlyDeleting.dashboards.count,
|
||||||
databaseCurrentlyDeleting.dashboard_count,
|
|
||||||
databaseCurrentlyDeleting.sqllab_tab_count,
|
databaseCurrentlyDeleting.sqllab_tab_count,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
{databaseCurrentlyDeleting.dashboards.count >= 1 && (
|
||||||
|
<>
|
||||||
|
<h4>{t('Affected Dashboards')}</h4>
|
||||||
|
<ul>
|
||||||
|
{databaseCurrentlyDeleting.dashboards.result
|
||||||
|
.slice(0, 10)
|
||||||
|
.map(
|
||||||
|
(
|
||||||
|
result: { id: number; title: string },
|
||||||
|
index: number,
|
||||||
|
) => (
|
||||||
|
<li key={result.id}>
|
||||||
|
<a
|
||||||
|
href={`/superset/dashboard/${result.id}`}
|
||||||
|
target="_atRiskItem"
|
||||||
|
>
|
||||||
|
{result.title}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{databaseCurrentlyDeleting.dashboards.result.length >
|
||||||
|
10 && (
|
||||||
|
<li>
|
||||||
|
{t(
|
||||||
|
'... and %s others',
|
||||||
|
databaseCurrentlyDeleting.dashboards.result.length -
|
||||||
|
10,
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{databaseCurrentlyDeleting.charts.count >= 1 && (
|
||||||
|
<>
|
||||||
|
<h4>{t('Affected Charts')}</h4>
|
||||||
|
<ul>
|
||||||
|
{databaseCurrentlyDeleting.charts.result.slice(0, 10).map(
|
||||||
|
(
|
||||||
|
result: {
|
||||||
|
id: number;
|
||||||
|
slice_name: string;
|
||||||
|
},
|
||||||
|
index: number,
|
||||||
|
) => (
|
||||||
|
<li key={result.id}>
|
||||||
|
<a
|
||||||
|
href={`/explore/?slice_id=${result.id}`}
|
||||||
|
target="_atRiskItem"
|
||||||
|
>
|
||||||
|
{result.slice_name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{databaseCurrentlyDeleting.charts.result.length > 10 && (
|
||||||
|
<li>
|
||||||
|
{t(
|
||||||
|
'... and %s others',
|
||||||
|
databaseCurrentlyDeleting.charts.result.length - 10,
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{DatabaseDeleteRelatedExtension && (
|
{DatabaseDeleteRelatedExtension && (
|
||||||
<DatabaseDeleteRelatedExtension
|
<DatabaseDeleteRelatedExtension
|
||||||
database={databaseCurrentlyDeleting}
|
database={databaseCurrentlyDeleting}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import {
|
||||||
SupersetClient,
|
SupersetClient,
|
||||||
t,
|
t,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { FunctionComponent, useState, useMemo, useCallback } from 'react';
|
import { FunctionComponent, useState, useMemo, useCallback, Key } from 'react';
|
||||||
import { Link, useHistory } from 'react-router-dom';
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
import rison from 'rison';
|
import rison from 'rison';
|
||||||
import {
|
import {
|
||||||
|
|
@ -154,7 +154,11 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||||
} = useListViewResource<Dataset>('dataset', t('dataset'), addDangerToast);
|
} = useListViewResource<Dataset>('dataset', t('dataset'), addDangerToast);
|
||||||
|
|
||||||
const [datasetCurrentlyDeleting, setDatasetCurrentlyDeleting] = useState<
|
const [datasetCurrentlyDeleting, setDatasetCurrentlyDeleting] = useState<
|
||||||
(Dataset & { chart_count: number; dashboard_count: number }) | null
|
| (Dataset & {
|
||||||
|
charts: any;
|
||||||
|
dashboards: any;
|
||||||
|
})
|
||||||
|
| null
|
||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
const [datasetCurrentlyEditing, setDatasetCurrentlyEditing] =
|
const [datasetCurrentlyEditing, setDatasetCurrentlyEditing] =
|
||||||
|
|
@ -243,8 +247,8 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||||
.then(({ json = {} }) => {
|
.then(({ json = {} }) => {
|
||||||
setDatasetCurrentlyDeleting({
|
setDatasetCurrentlyDeleting({
|
||||||
...dataset,
|
...dataset,
|
||||||
chart_count: json.charts.count,
|
charts: json.charts,
|
||||||
dashboard_count: json.dashboards.count,
|
dashboards: json.dashboards,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(
|
.catch(
|
||||||
|
|
@ -742,13 +746,80 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
|
{t('The dataset')}
|
||||||
|
<b> {datasetCurrentlyDeleting.table_name} </b>
|
||||||
{t(
|
{t(
|
||||||
'The dataset %s is linked to %s charts that appear on %s dashboards. Are you sure you want to continue? Deleting the dataset will break those objects.',
|
'is linked to %s charts that appear on %s dashboards. Are you sure you want to continue? Deleting the dataset will break those objects.',
|
||||||
datasetCurrentlyDeleting.table_name,
|
datasetCurrentlyDeleting.charts.count,
|
||||||
datasetCurrentlyDeleting.chart_count,
|
datasetCurrentlyDeleting.dashboards.count,
|
||||||
datasetCurrentlyDeleting.dashboard_count,
|
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
{datasetCurrentlyDeleting.dashboards.count >= 1 && (
|
||||||
|
<>
|
||||||
|
<h4>{t('Affected Dashboards')}</h4>
|
||||||
|
<ul>
|
||||||
|
{datasetCurrentlyDeleting.dashboards.result
|
||||||
|
.slice(0, 10)
|
||||||
|
.map(
|
||||||
|
(
|
||||||
|
result: { id: Key | null | undefined; title: string },
|
||||||
|
index: number,
|
||||||
|
) => (
|
||||||
|
<li key={result.id}>
|
||||||
|
<a
|
||||||
|
href={`/superset/dashboard/${result.id}`}
|
||||||
|
target="_atRiskItem"
|
||||||
|
>
|
||||||
|
{result.title}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{datasetCurrentlyDeleting.dashboards.result.length > 10 && (
|
||||||
|
<li>
|
||||||
|
{t(
|
||||||
|
'... and %s others',
|
||||||
|
datasetCurrentlyDeleting.dashboards.result.length -
|
||||||
|
10,
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{datasetCurrentlyDeleting.charts.count >= 1 && (
|
||||||
|
<>
|
||||||
|
<h4>{t('Affected Charts')}</h4>
|
||||||
|
<ul>
|
||||||
|
{datasetCurrentlyDeleting.charts.result.slice(0, 10).map(
|
||||||
|
(
|
||||||
|
result: {
|
||||||
|
id: Key | null | undefined;
|
||||||
|
slice_name: string;
|
||||||
|
},
|
||||||
|
index: number,
|
||||||
|
) => (
|
||||||
|
<li key={result.id}>
|
||||||
|
<a
|
||||||
|
href={`/explore/?slice_id=${result.id}`}
|
||||||
|
target="_atRiskItem"
|
||||||
|
>
|
||||||
|
{result.slice_name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{datasetCurrentlyDeleting.charts.result.length > 10 && (
|
||||||
|
<li>
|
||||||
|
{t(
|
||||||
|
'... and %s others',
|
||||||
|
datasetCurrentlyDeleting.charts.result.length - 10,
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{DatasetDeleteRelatedExtension && (
|
{DatasetDeleteRelatedExtension && (
|
||||||
<DatasetDeleteRelatedExtension
|
<DatasetDeleteRelatedExtension
|
||||||
dataset={datasetCurrentlyDeleting}
|
dataset={datasetCurrentlyDeleting}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue