You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2023/04/18 20:42:16 UTC

[superset] branch master updated: feat: Drill by error management (#23724)

This is an automated email from the ASF dual-hosted git repository.

kgabryje pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 818a1d482b feat: Drill by error management (#23724)
818a1d482b is described below

commit 818a1d482bb22f2a243b874ed909a1be55e76282
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Tue Apr 18 22:42:00 2023 +0200

    feat: Drill by error management (#23724)
---
 .../components/Chart/DrillBy/DrillByMenuItems.tsx  |  5 ++-
 .../components/Chart/DrillBy/DrillByModal.test.tsx | 20 +++++++--
 .../src/components/Chart/DrillBy/DrillByModal.tsx  | 48 ++++++++++++++++++----
 3 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx
index e5b919ff6d..b503b1eed5 100644
--- a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx
+++ b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx
@@ -39,6 +39,7 @@ import {
 } from '@superset-ui/core';
 import Icons from 'src/components/Icons';
 import { Input } from 'src/components/Input';
+import { useToasts } from 'src/components/MessageToasts/withToasts';
 import {
   cachedSupersetGet,
   supersetGetCache,
@@ -80,12 +81,12 @@ export const DrillByMenuItems = ({
   ...rest
 }: DrillByMenuItemsProps) => {
   const theme = useTheme();
+  const { addDangerToast } = useToasts();
   const [searchInput, setSearchInput] = useState('');
   const [dataset, setDataset] = useState<Dataset>();
   const [columns, setColumns] = useState<Column[]>([]);
   const [showModal, setShowModal] = useState(false);
   const [currentColumn, setCurrentColumn] = useState();
-
   const handleSelection = useCallback(
     (event, column) => {
       onClick(event);
@@ -143,9 +144,11 @@ export const DrillByMenuItems = ({
         })
         .catch(() => {
           supersetGetCache.delete(`/api/v1/dataset/${datasetId}`);
+          addDangerToast(t('Failed to load dimensions for drill by'));
         });
     }
   }, [
+    addDangerToast,
     excludedColumns,
     formData,
     groupbyFieldName,
diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.test.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.test.tsx
index f0768253e0..66fd6a42ba 100644
--- a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.test.tsx
+++ b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.test.tsx
@@ -104,7 +104,7 @@ beforeEach(() => {
     .post(CHART_DATA_ENDPOINT, { body: {} }, {})
     .post(FORM_DATA_KEY_ENDPOINT, { key: '123' });
 });
-afterEach(fetchMock.restore);
+afterEach(() => fetchMock.restore());
 
 test('should render the title', async () => {
   await renderModal();
@@ -127,10 +127,22 @@ test('should close the modal', async () => {
 });
 
 test('should render loading indicator', async () => {
-  await renderModal();
-  await waitFor(() =>
-    expect(screen.getByLabelText('Loading')).toBeInTheDocument(),
+  fetchMock.post(
+    CHART_DATA_ENDPOINT,
+    { body: {} },
+    // delay is missing in fetch-mock types
+    // @ts-ignore
+    { overwriteRoutes: true, delay: 1000 },
   );
+  await renderModal();
+  expect(screen.getByLabelText('Loading')).toBeInTheDocument();
+});
+
+test('should render alert banner when results fail to load', async () => {
+  await renderModal();
+  expect(
+    await screen.findByText('There was an error loading the chart data'),
+  ).toBeInTheDocument();
 });
 
 test('should generate Explore url', async () => {
diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx
index 7f65576854..0a05635645 100644
--- a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx
+++ b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx
@@ -47,6 +47,8 @@ import { noOp } from 'src/utils/common';
 import { simpleFilterToAdhoc } from 'src/utils/simpleFilterToAdhoc';
 import { useDatasetMetadataBar } from 'src/features/datasets/metadataBar/useDatasetMetadataBar';
 import { SingleQueryResultPane } from 'src/explore/components/DataTablesPane/components/SingleQueryResultPane';
+import { useToasts } from 'src/components/MessageToasts/withToasts';
+import Alert from 'src/components/Alert';
 import { Dataset, DrillByType } from '../types';
 import DrillByChart from './DrillByChart';
 import { ContextMenuItem } from '../ChartContextMenu/ChartContextMenu';
@@ -65,6 +67,7 @@ interface ModalFooterProps {
 }
 
 const ModalFooter = ({ formData, closeModal }: ModalFooterProps) => {
+  const { addDangerToast } = useToasts();
   const [url, setUrl] = useState('');
   const dashboardPageId = useContext(DashboardPageIdContext);
   const [datasource_id, datasource_type] = formData.datasource.split('__');
@@ -75,13 +78,24 @@ const ModalFooter = ({ formData, closeModal }: ModalFooterProps) => {
           `/explore/?form_data_key=${key}&dashboard_page_id=${dashboardPageId}`,
         );
       })
-      .catch(e => {
-        console.log(e);
+      .catch(() => {
+        addDangerToast(t('Failed to generate chart edit URL'));
       });
-  }, [dashboardPageId, datasource_id, datasource_type, formData]);
+  }, [
+    addDangerToast,
+    dashboardPageId,
+    datasource_id,
+    datasource_type,
+    formData,
+  ]);
   return (
     <>
-      <Button buttonStyle="secondary" buttonSize="small" onClick={noOp}>
+      <Button
+        buttonStyle="secondary"
+        buttonSize="small"
+        onClick={noOp}
+        disabled={!url}
+      >
         <Link
           css={css`
             &:hover {
@@ -126,6 +140,8 @@ export default function DrillByModal({
   onHideModal,
 }: DrillByModalProps) {
   const theme = useTheme();
+  const { addDangerToast } = useToasts();
+  const [isChartDataLoading, setIsChartDataLoading] = useState(true);
 
   const initialGroupbyColumns = useMemo(
     () =>
@@ -278,14 +294,22 @@ export default function DrillByModal({
 
   useEffect(() => {
     if (drilledFormData) {
+      setIsChartDataLoading(true);
       setChartDataResult(undefined);
       getChartDataRequest({
         formData: drilledFormData,
-      }).then(({ json }) => {
-        setChartDataResult(json.result);
-      });
+      })
+        .then(({ json }) => {
+          setChartDataResult(json.result);
+        })
+        .catch(() => {
+          addDangerToast(t('Failed to load chart data.'));
+        })
+        .finally(() => {
+          setIsChartDataLoading(false);
+        });
     }
-  }, [drilledFormData]);
+  }, [addDangerToast, drilledFormData]);
   const { metadataBar } = useDatasetMetadataBar({ dataset });
 
   return (
@@ -323,7 +347,13 @@ export default function DrillByModal({
         {metadataBar}
         {breadcrumbs}
         {displayModeToggle}
-        {!chartDataResult && <Loading />}
+        {isChartDataLoading && <Loading />}
+        {!isChartDataLoading && !chartDataResult && (
+          <Alert
+            type="error"
+            message={t('There was an error loading the chart data')}
+          />
+        )}
         {drillByDisplayMode === DrillByType.Chart && chartDataResult && (
           <DrillByChart
             formData={drilledFormData}