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

maximebeauchemin 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 fcd166149c chore: Empty state refactor (#31860)
fcd166149c is described below

commit fcd166149cfb896a2a389a5c9075b24eb2cf1ade
Author: Maxime Beauchemin <[email protected]>
AuthorDate: Wed Jan 22 13:20:38 2025 -0800

    chore: Empty state refactor (#31860)
---
 superset-frontend/package-lock.json                | 118 ++--------
 .../src/SqlLab/components/QueryHistory/index.tsx   |   5 +-
 .../src/SqlLab/components/SouthPane/Results.tsx    |   4 +-
 .../src/SqlLab/components/SqlEditor/index.tsx      |   5 +-
 .../SqlLab/components/SqlEditorLeftBar/index.tsx   |   6 +-
 .../SqlLab/components/TabbedSqlEditors/index.tsx   |   5 +-
 superset-frontend/src/assets/images/chart.svg      | Bin 3130 -> 3223 bytes
 superset-frontend/src/assets/images/document.svg   | Bin 1038 -> 1072 bytes
 .../src/assets/images/empty-charts.svg             | Bin 3823 -> 1461 bytes
 .../src/assets/images/empty-dashboard.svg          | Bin 1583 -> 1631 bytes
 .../src/assets/images/empty-dataset.svg            | Bin 4219 -> 4303 bytes
 .../src/assets/images/empty-queries.svg            | Bin 5778 -> 5832 bytes
 .../src/assets/images/empty-query.svg              | Bin 1702 -> 1702 bytes
 .../src/assets/images/empty-table.svg              | Bin 2554 -> 2541 bytes
 superset-frontend/src/assets/images/empty.svg      | Bin 1915 -> 1944 bytes
 .../src/assets/images/empty_sql_chart.svg          | Bin 5972 -> 5957 bytes
 .../src/assets/images/filter-results.svg           | Bin 1904 -> 1902 bytes
 superset-frontend/src/assets/images/filter.svg     | Bin 1728 -> 1606 bytes
 .../src/assets/images/star-circle.svg              | Bin 2023 -> 2051 bytes
 superset-frontend/src/assets/images/union.svg      | Bin 1871 -> 1899 bytes
 superset-frontend/src/assets/images/vector.svg     | Bin 2665 -> 2669 bytes
 superset-frontend/src/components/Chart/Chart.tsx   |   8 +-
 .../src/components/Chart/ChartRenderer.jsx         |   7 +-
 .../Chart/DrillDetail/DrillDetailPane.tsx          |   4 +-
 .../DatabaseSelector/DatabaseSelector.test.tsx     |   4 +-
 .../components/EmptyState/EmptyState.stories.tsx   |  99 ++++----
 .../src/components/EmptyState/index.tsx            | 251 ++++++++-------------
 .../src/components/ListView/ListView.tsx           |   8 +-
 superset-frontend/src/components/Table/index.tsx   |  59 ++---
 .../DashboardBuilder/DashboardBuilder.tsx          |   5 +-
 .../src/dashboard/components/DashboardGrid.jsx     |  11 +-
 .../components/gridComponents/ChartHolder.test.tsx |   2 +-
 .../dashboard/components/gridComponents/Tab.jsx    |   4 +-
 .../components/gridComponents/Tab.test.tsx         |   4 +-
 .../nativeFilters/FilterBar/Vertical.tsx           |   5 +-
 .../DataTablesPane/components/SamplesPane.tsx      |   4 +-
 .../DataTablesPane/components/useResultsPane.tsx   |   6 +-
 .../AnnotationLayerControl/AnnotationLayer.jsx     |   5 +-
 .../DndColumnSelectControl/ColumnSelectPopover.tsx |  11 +-
 .../MetricControl/AdhocMetricEditPopover/index.jsx |   8 +-
 .../src/features/allEntities/AllEntitiesTable.tsx  |   5 +-
 .../AddDataset/DatasetPanel/MessageContent.tsx     |   7 +-
 .../AddDataset/EditDataset/UsageTab/index.tsx      |   7 +-
 .../datasets/AddDataset/LeftPanel/index.tsx        |  21 +-
 .../src/features/home/ActivityTable.test.tsx       |   6 +-
 .../src/features/home/ChartTable.test.tsx          |   4 +-
 .../src/features/home/EmptyState.test.tsx          |  14 +-
 superset-frontend/src/features/home/EmptyState.tsx | 206 ++++++-----------
 48 files changed, 363 insertions(+), 555 deletions(-)

diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index a7ac01fa41..1b06e003e4 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -1714,15 +1714,18 @@
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.24.8",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz";,
-      "integrity": 
"sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+      "version": "7.25.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
+      "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+      "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.24.7",
+      "version": "7.25.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
+      "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -3496,13 +3499,13 @@
       "license": "MIT"
     },
     "node_modules/@babel/types": {
-      "version": "7.25.2",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz";,
-      "integrity": 
"sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
+      "version": "7.26.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz";,
+      "integrity": 
"sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==",
+      "license": "MIT",
       "dependencies": {
-        "@babel/helper-string-parser": "^7.24.8",
-        "@babel/helper-validator-identifier": "^7.24.7",
-        "to-fast-properties": "^2.0.0"
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -50919,13 +50922,6 @@
       "dev": true,
       "license": "BSD-3-Clause"
     },
-    "node_modules/to-fast-properties": {
-      "version": "2.0.0",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/to-object-path": {
       "version": "0.3.0",
       "dev": true,
@@ -56297,26 +56293,6 @@
         "node": ">=6.9.0"
       }
     },
-    "packages/superset-ui-demo/node_modules/@babel/helper-string-parser": {
-      "version": "7.25.9",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
-      "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    
"packages/superset-ui-demo/node_modules/@babel/helper-validator-identifier": {
-      "version": "7.25.9",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
-      "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
     "packages/superset-ui-demo/node_modules/@babel/helper-validator-option": {
       "version": "7.25.9",
       "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz";,
@@ -58309,26 +58285,6 @@
         "react-dom": "^16.13.1"
       }
     },
-    
"plugins/plugin-chart-pivot-table/node_modules/@babel/helper-string-parser": {
-      "version": "7.25.9",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
-      "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    
"plugins/plugin-chart-pivot-table/node_modules/@babel/helper-validator-identifier":
 {
-      "version": "7.25.9",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
-      "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
     "plugins/plugin-chart-pivot-table/node_modules/@babel/types": {
       "version": "7.26.3",
       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz";,
@@ -59449,12 +59405,14 @@
       }
     },
     "@babel/helper-string-parser": {
-      "version": "7.24.8",
-      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz";,
-      "integrity": 
"sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ=="
+      "version": "7.25.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
+      "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.24.7"
+      "version": "7.25.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
+      "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
     },
     "@babel/helper-validator-option": {
       "version": "7.24.7",
@@ -60507,13 +60465,12 @@
       }
     },
     "@babel/types": {
-      "version": "7.25.2",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz";,
-      "integrity": 
"sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
+      "version": "7.26.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz";,
+      "integrity": 
"sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==",
       "requires": {
-        "@babel/helper-string-parser": "^7.24.8",
-        "@babel/helper-validator-identifier": "^7.24.7",
-        "to-fast-properties": "^2.0.0"
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
       }
     },
     "@base2/pretty-print-object": {
@@ -66764,18 +66721,6 @@
           "integrity": 
"sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
           "dev": true
         },
-        "@babel/helper-string-parser": {
-          "version": "7.25.9",
-          "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
-          "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
-          "dev": true
-        },
-        "@babel/helper-validator-identifier": {
-          "version": "7.25.9",
-          "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
-          "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
-          "dev": true
-        },
         "@babel/helper-validator-option": {
           "version": "7.25.9",
           "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz";,
@@ -68904,18 +68849,6 @@
         "jest": "^29.7.0"
       },
       "dependencies": {
-        "@babel/helper-string-parser": {
-          "version": "7.25.9",
-          "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz";,
-          "integrity": 
"sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
-          "dev": true
-        },
-        "@babel/helper-validator-identifier": {
-          "version": "7.25.9",
-          "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz";,
-          "integrity": 
"sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
-          "dev": true
-        },
         "@babel/types": {
           "version": "7.26.3",
           "resolved": 
"https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz";,
@@ -93957,9 +93890,6 @@
       "version": "1.0.5",
       "dev": true
     },
-    "to-fast-properties": {
-      "version": "2.0.0"
-    },
     "to-object-path": {
       "version": "0.3.0",
       "dev": true,
diff --git a/superset-frontend/src/SqlLab/components/QueryHistory/index.tsx 
b/superset-frontend/src/SqlLab/components/QueryHistory/index.tsx
index 30103dafa5..6916e1e19b 100644
--- a/superset-frontend/src/SqlLab/components/QueryHistory/index.tsx
+++ b/superset-frontend/src/SqlLab/components/QueryHistory/index.tsx
@@ -20,7 +20,7 @@ import { useEffect, useMemo, useState } from 'react';
 import { shallowEqual, useSelector } from 'react-redux';
 import { useInView } from 'react-intersection-observer';
 import { omit } from 'lodash';
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import {
   t,
   styled,
@@ -143,8 +143,9 @@ const QueryHistory = ({
     </>
   ) : (
     <StyledEmptyStateWrapper>
-      <EmptyStateMedium
+      <EmptyState
         title={t('Run a query to display query history')}
+        size="medium"
         image="document.svg"
       />
     </StyledEmptyStateWrapper>
diff --git a/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx 
b/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
index 3dfec40bdc..6a2a60831b 100644
--- a/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
+++ b/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
@@ -19,7 +19,7 @@
 import { FC } from 'react';
 import { shallowEqual, useSelector } from 'react-redux';
 import Alert from 'src/components/Alert';
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { FeatureFlag, styled, t, isFeatureEnabled } from '@superset-ui/core';
 
 import { SqlLabRootState } from 'src/SqlLab/types';
@@ -67,7 +67,7 @@ const Results: FC<Props> = ({
   ) {
     return (
       <StyledEmptyStateWrapper>
-        <EmptyStateMedium
+        <EmptyState
           title={t('Run a query to display results')}
           image="document.svg"
         />
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx 
b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
index 4d1aded5be..09a2fa94e4 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
@@ -100,7 +100,7 @@ import {
   LocalStorageKeys,
   setItem,
 } from 'src/utils/localStorageHelpers';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import Alert from 'src/components/Alert';
 import getBootstrapData from 'src/utils/getBootstrapData';
 import useLogAction from 'src/logger/useLogAction';
@@ -968,8 +968,9 @@ const SqlEditor: FC<Props> = ({
           <Skeleton active />
         </div>
       ) : showEmptyState && !hasSqlStatement ? (
-        <EmptyStateBig
+        <EmptyState
           image="vector.svg"
+          size="large"
           title={t('Select a database to write a query')}
           description={t(
             'Choose one of the available databases from the panel on the 
left.',
diff --git a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx 
b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
index c91036a725..1e0012aed2 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
@@ -41,7 +41,7 @@ import { TableSelectorMultiple } from 
'src/components/TableSelector';
 import { IconTooltip } from 'src/components/IconTooltip';
 import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
 import type { DatabaseObject } from 'src/components/DatabaseSelector';
-import { emptyStateComponent } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import {
   getItem,
   LocalStorageKeys,
@@ -113,7 +113,7 @@ const SqlEditorLeftBar = ({
     'schema',
   ]);
 
-  const [emptyResultsWithSearch, setEmptyResultsWithSearch] = useState(false);
+  const [_emptyResultsWithSearch, setEmptyResultsWithSearch] = useState(false);
   const [userSelectedDb, setUserSelected] = useState<DatabaseObject | null>(
     null,
   );
@@ -249,7 +249,7 @@ const SqlEditorLeftBar = ({
     <LeftBarStyles data-test="sql-editor-left-bar">
       <TableSelectorMultiple
         onEmptyResults={onEmptyResults}
-        emptyState={emptyStateComponent(emptyResultsWithSearch)}
+        emptyState={<EmptyState />}
         database={userSelectedDb}
         getDbList={handleDbList}
         handleError={handleError}
diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx 
b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
index 3105aa94bd..a9360ad655 100644
--- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
+++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
@@ -27,7 +27,7 @@ import { Logger } from 'src/logger/LogUtils';
 import { Tooltip } from 'src/components/Tooltip';
 import { detectOS } from 'src/utils/common';
 import * as Actions from 'src/SqlLab/actions/sqlLab';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import getBootstrapData from 'src/utils/getBootstrapData';
 import { locationContext } from 'src/pages/SqlLab/LocationContext';
 import SqlEditor from '../SqlEditor';
@@ -259,8 +259,9 @@ class TabbedSqlEditors extends 
PureComponent<TabbedSqlEditorsProps> {
         tab={emptyTab}
         closable={false}
       >
-        <EmptyStateBig
+        <EmptyState
           image="empty_sql_chart.svg"
+          size="large"
           description={t('Add a new tab to create SQL Query')}
         />
       </EditableTabs.TabPane>
diff --git a/superset-frontend/src/assets/images/chart.svg 
b/superset-frontend/src/assets/images/chart.svg
index 2267342bcc..34e45631e0 100644
Binary files a/superset-frontend/src/assets/images/chart.svg and 
b/superset-frontend/src/assets/images/chart.svg differ
diff --git a/superset-frontend/src/assets/images/document.svg 
b/superset-frontend/src/assets/images/document.svg
index e3d1bfe1be..552fc8d220 100644
Binary files a/superset-frontend/src/assets/images/document.svg and 
b/superset-frontend/src/assets/images/document.svg differ
diff --git a/superset-frontend/src/assets/images/empty-charts.svg 
b/superset-frontend/src/assets/images/empty-charts.svg
index b4cdd99086..8c7b205d2a 100644
Binary files a/superset-frontend/src/assets/images/empty-charts.svg and 
b/superset-frontend/src/assets/images/empty-charts.svg differ
diff --git a/superset-frontend/src/assets/images/empty-dashboard.svg 
b/superset-frontend/src/assets/images/empty-dashboard.svg
index c76eca0c30..2acf05c801 100644
Binary files a/superset-frontend/src/assets/images/empty-dashboard.svg and 
b/superset-frontend/src/assets/images/empty-dashboard.svg differ
diff --git a/superset-frontend/src/assets/images/empty-dataset.svg 
b/superset-frontend/src/assets/images/empty-dataset.svg
index 5ce1752545..9a0299d3b4 100644
Binary files a/superset-frontend/src/assets/images/empty-dataset.svg and 
b/superset-frontend/src/assets/images/empty-dataset.svg differ
diff --git a/superset-frontend/src/assets/images/empty-queries.svg 
b/superset-frontend/src/assets/images/empty-queries.svg
index 2239c0ae8e..1d2d8b00f2 100644
Binary files a/superset-frontend/src/assets/images/empty-queries.svg and 
b/superset-frontend/src/assets/images/empty-queries.svg differ
diff --git a/superset-frontend/src/assets/images/empty-query.svg 
b/superset-frontend/src/assets/images/empty-query.svg
index be72857d8e..a19fc73eeb 100644
Binary files a/superset-frontend/src/assets/images/empty-query.svg and 
b/superset-frontend/src/assets/images/empty-query.svg differ
diff --git a/superset-frontend/src/assets/images/empty-table.svg 
b/superset-frontend/src/assets/images/empty-table.svg
index c1062502f3..9079b07114 100644
Binary files a/superset-frontend/src/assets/images/empty-table.svg and 
b/superset-frontend/src/assets/images/empty-table.svg differ
diff --git a/superset-frontend/src/assets/images/empty.svg 
b/superset-frontend/src/assets/images/empty.svg
index e2c78339ce..b503324f67 100644
Binary files a/superset-frontend/src/assets/images/empty.svg and 
b/superset-frontend/src/assets/images/empty.svg differ
diff --git a/superset-frontend/src/assets/images/empty_sql_chart.svg 
b/superset-frontend/src/assets/images/empty_sql_chart.svg
index 6ab969575c..b729b471a6 100644
Binary files a/superset-frontend/src/assets/images/empty_sql_chart.svg and 
b/superset-frontend/src/assets/images/empty_sql_chart.svg differ
diff --git a/superset-frontend/src/assets/images/filter-results.svg 
b/superset-frontend/src/assets/images/filter-results.svg
index 770a54b34f..7244f5538b 100644
Binary files a/superset-frontend/src/assets/images/filter-results.svg and 
b/superset-frontend/src/assets/images/filter-results.svg differ
diff --git a/superset-frontend/src/assets/images/filter.svg 
b/superset-frontend/src/assets/images/filter.svg
index 0e1f6b41ef..2e8c5e0f09 100644
Binary files a/superset-frontend/src/assets/images/filter.svg and 
b/superset-frontend/src/assets/images/filter.svg differ
diff --git a/superset-frontend/src/assets/images/star-circle.svg 
b/superset-frontend/src/assets/images/star-circle.svg
index a46a1dd0fb..d9e6c77e2c 100644
Binary files a/superset-frontend/src/assets/images/star-circle.svg and 
b/superset-frontend/src/assets/images/star-circle.svg differ
diff --git a/superset-frontend/src/assets/images/union.svg 
b/superset-frontend/src/assets/images/union.svg
index 6ac0e0f016..9ccf437b22 100644
Binary files a/superset-frontend/src/assets/images/union.svg and 
b/superset-frontend/src/assets/images/union.svg differ
diff --git a/superset-frontend/src/assets/images/vector.svg 
b/superset-frontend/src/assets/images/vector.svg
index 0bf9c39c6c..d2f946e810 100644
Binary files a/superset-frontend/src/assets/images/vector.svg and 
b/superset-frontend/src/assets/images/vector.svg differ
diff --git a/superset-frontend/src/components/Chart/Chart.tsx 
b/superset-frontend/src/components/Chart/Chart.tsx
index 3526a26b3f..fd7b5fcaab 100644
--- a/superset-frontend/src/components/Chart/Chart.tsx
+++ b/superset-frontend/src/components/Chart/Chart.tsx
@@ -31,7 +31,7 @@ import {
 } from '@superset-ui/core';
 import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants';
 import Loading from 'src/components/Loading';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import ErrorBoundary from 'src/components/ErrorBoundary';
 import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
 import { URL_PARAMS } from 'src/constants';
@@ -337,7 +337,8 @@ class Chart extends PureComponent<ChartProps, {}> {
 
     if (errorMessage && ensureIsArray(queriesResponse).length === 0) {
       return (
-        <EmptyStateBig
+        <EmptyState
+          size="large"
           title={t('Add required control values to preview chart')}
           description={getChartRequiredFieldsMissingMessage(true)}
           image="chart.svg"
@@ -352,7 +353,8 @@ class Chart extends PureComponent<ChartProps, {}> {
       ensureIsArray(queriesResponse).length === 0
     ) {
       return (
-        <EmptyStateBig
+        <EmptyState
+          size="large"
           title={t('Your chart is ready to go!')}
           description={
             <span>
diff --git a/superset-frontend/src/components/Chart/ChartRenderer.jsx 
b/superset-frontend/src/components/Chart/ChartRenderer.jsx
index d93e30a107..dd456b0db4 100644
--- a/superset-frontend/src/components/Chart/ChartRenderer.jsx
+++ b/superset-frontend/src/components/Chart/ChartRenderer.jsx
@@ -30,7 +30,7 @@ import {
   VizType,
 } from '@superset-ui/core';
 import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
-import { EmptyStateBig, EmptyStateSmall } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { ChartSource } from 'src/types/ChartSource';
 import ChartContextMenu from './ChartContextMenu/ChartContextMenu';
 
@@ -308,7 +308,8 @@ class ChartRenderer extends Component {
     const noResultImage = 'chart.svg';
     if (width > BIG_NO_RESULT_MIN_WIDTH && height > BIG_NO_RESULT_MIN_HEIGHT) {
       noResultsComponent = (
-        <EmptyStateBig
+        <EmptyState
+          size="large"
           title={noResultTitle}
           description={noResultDescription}
           image={noResultImage}
@@ -316,7 +317,7 @@ class ChartRenderer extends Component {
       );
     } else {
       noResultsComponent = (
-        <EmptyStateSmall title={noResultTitle} image={noResultImage} />
+        <EmptyState size="small" title={noResultTitle} image={noResultImage} />
       );
     }
 
diff --git 
a/superset-frontend/src/components/Chart/DrillDetail/DrillDetailPane.tsx 
b/superset-frontend/src/components/Chart/DrillDetail/DrillDetailPane.tsx
index 9cf0102b5e..bcab733f48 100644
--- a/superset-frontend/src/components/Chart/DrillDetail/DrillDetailPane.tsx
+++ b/superset-frontend/src/components/Chart/DrillDetail/DrillDetailPane.tsx
@@ -41,7 +41,7 @@ import Loading from 'src/components/Loading';
 import BooleanCell from 'src/components/Table/cell-renderers/BooleanCell';
 import NullCell from 'src/components/Table/cell-renderers/NullCell';
 import TimeCell from 'src/components/Table/cell-renderers/TimeCell';
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { getDatasourceSamples } from 'src/components/Chart/chartAction';
 import Table, { ColumnsType, TableSize } from 'src/components/Table';
 import HeaderWithRadioGroup from 
'src/components/Table/header-renderers/HeaderWithRadioGroup';
@@ -285,7 +285,7 @@ export default function DrillDetailPane({
   } else if (resultsPage?.total === 0) {
     // Render empty state if no results are returned for page
     const title = t('No rows were returned for this dataset');
-    tableContent = <EmptyStateMedium image="document.svg" title={title} />;
+    tableContent = <EmptyState image="document.svg" title={title} />;
   } else {
     // Render table if at least one page has successfully loaded
     tableContent = (
diff --git 
a/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx 
b/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
index 44d0bff0e0..ee17f2d801 100644
--- 
a/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
+++ 
b/superset-frontend/src/components/DatabaseSelector/DatabaseSelector.test.tsx
@@ -28,7 +28,7 @@ import {
 import userEvent from '@testing-library/user-event';
 import { api } from 'src/hooks/apiResources/queryApi';
 import DatabaseSelector, { DatabaseSelectorProps } from '.';
-import { EmptyStateSmall } from '../EmptyState';
+import { EmptyState } from '../EmptyState';
 
 const createProps = (): DatabaseSelectorProps => ({
   db: {
@@ -307,7 +307,7 @@ test('should show empty state if there are no options', 
async () => {
     <DatabaseSelector
       {...props}
       db={undefined}
-      emptyState={<EmptyStateSmall title="empty" image="" />}
+      emptyState={<EmptyState size="small" title="empty" />}
     />,
     { useRedux: true, store },
   );
diff --git a/superset-frontend/src/components/EmptyState/EmptyState.stories.tsx 
b/superset-frontend/src/components/EmptyState/EmptyState.stories.tsx
index 9d6f56c52d..dbc3a0af9c 100644
--- a/superset-frontend/src/components/EmptyState/EmptyState.stories.tsx
+++ b/superset-frontend/src/components/EmptyState/EmptyState.stories.tsx
@@ -9,64 +9,59 @@
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
+import { Meta, StoryFn } from '@storybook/react';
+import { Row, Col } from 'antd';
+import { EmptyState, imageMap } from '.';
 
-import EmptyImage from 'src/assets/images/empty.svg';
-import ChartImage from 'src/assets/images/chart.svg';
-import FilterImage from 'src/assets/images/filter.svg';
-import { EmptyStateBig, EmptyStateMedium, EmptyStateSmall } from '.';
+const emptyStates = [
+  { title: null, description: null, image: undefined },
+  ...Object.keys(imageMap).map(key => ({
+    image: key,
+    title: `Empty State with image ${key}`,
+    description: 'This is the default empty state.',
+  })),
+];
 
 export default {
-  title: 'Empty state',
-  component: EmptyStateMedium,
-};
-
-export const SmallEmptyState = () => (
-  <EmptyStateSmall
-    image={<FilterImage />}
-    title="Small empty state"
-    description="This is an example of a small empty state"
-  />
-);
-
-export const MediumEmptyState = () => (
-  <EmptyStateMedium
-    image={<ChartImage />}
-    title="Medium empty state"
-    description="This is an example of a medium empty state"
-  />
-);
+  title: 'Empty State Gallery',
+  component: EmptyState,
+  argTypes: {
+    size: {
+      control: { type: 'select' },
+      options: ['small', 'medium', 'large'],
+      defaultValue: 'medium',
+      description: 'Size of the Empty State components',
+    },
+  },
+} as Meta;
 
-export const MediumEmptyStateWithButton = () => (
-  <EmptyStateMedium
-    image={<EmptyImage />}
-    title="Medium empty state"
-    description="This is an example of a medium empty state with a button"
-    buttonAction={() => {}}
-    buttonText="Click!"
-  />
+export const Gallery: StoryFn<{ size: 'small' | 'medium' | 'large' }> = ({
+  size,
+}) => (
+  <Row gutter={[16, 16]}>
+    {emptyStates.map((state, index) => (
+      <Col key={index} xs={24} sm={12} md={8} lg={6}>
+        <EmptyState
+          size={size}
+          title={state.title}
+          description={state.description}
+          image={state.image}
+        >
+          Childrens render here.
+        </EmptyState>
+      </Col>
+    ))}
+  </Row>
 );
 
-export const BigEmptyState = () => (
-  <EmptyStateBig
-    image={<EmptyImage />}
-    title="Big empty state"
-    description="This is an example of a big empty state"
-  />
-);
-
-export const BigEmptyStateWithButton = () => (
-  <EmptyStateBig
-    image={<ChartImage />}
-    title="Big empty state"
-    description="This is an example of a big empty state with a button"
-    buttonText="Click!"
-    buttonAction={() => {}}
-  />
-);
+Gallery.args = {
+  size: 'medium',
+};
diff --git a/superset-frontend/src/components/EmptyState/index.tsx 
b/superset-frontend/src/components/EmptyState/index.tsx
index edc13e622f..a083b6cdcf 100644
--- a/superset-frontend/src/components/EmptyState/index.tsx
+++ b/superset-frontend/src/components/EmptyState/index.tsx
@@ -16,38 +16,57 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-import {
-  ReactNode,
-  SyntheticEvent,
-  MouseEventHandler as ReactMouseEventHandler,
-} from 'react';
+import { ReactNode, SyntheticEvent } from 'react';
 import { styled, css, SupersetTheme, t } from '@superset-ui/core';
 import Button from 'src/components/Button';
+
+// Importing svg images
+import FilterResultsImage from 'src/assets/images/filter-results.svg';
+import ChartImage from 'src/assets/images/chart.svg';
+import FilterImage from 'src/assets/images/filter.svg';
+import EmptyChartsImage from 'src/assets/images/empty-charts.svg';
+import EmptyDashboardImage from 'src/assets/images/empty-dashboard.svg';
+import UnionImage from 'src/assets/images/union.svg';
+import EmptyQueriesImage from 'src/assets/images/empty-queries.svg';
+import StarCircleImage from 'src/assets/images/star-circle.svg';
+import VectorImage from 'src/assets/images/vector.svg';
+import DocumentImage from 'src/assets/images/document.svg';
+import DatasetImage from 'src/assets/images/empty-dataset.svg';
+import EmptySqlChartImage from 'src/assets/images/empty_sql_chart.svg';
+import EmptyQueryImage from 'src/assets/images/empty-query.svg';
+import EmptyTableImage from 'src/assets/images/empty-table.svg';
+import EmptyImage from 'src/assets/images/empty.svg';
 import { Empty } from './Empty';
 
-export enum EmptyStateSize {
-  Small,
-  Medium,
-  Big,
-}
+export const imageMap = {
+  'chart.svg': <ChartImage />,
+  'document.svg': <DocumentImage />,
+  'empty-charts.svg': <EmptyChartsImage />,
+  'empty-dashboard.svg': <EmptyDashboardImage />,
+  'empty-dataset.svg': <DatasetImage />,
+  'empty-queries.svg': <EmptyQueriesImage />,
+  'empty-query.svg': <EmptyQueryImage />,
+  'empty-table.svg': <EmptyTableImage />,
+  'empty.svg': <EmptyImage />,
+  'empty_sql_chart.svg': <EmptySqlChartImage />,
+  'filter-results.svg': <FilterResultsImage />,
+  'filter.svg': <FilterImage />,
+  'star-circle.svg': <StarCircleImage />,
+  'union.svg': <UnionImage />,
+  'vector.svg': <VectorImage />,
+};
 
-export interface EmptyStateSmallProps {
+type EmptyStateSize = 'small' | 'medium' | 'large';
+
+export type EmptyStateProps = {
   title?: ReactNode;
   description?: ReactNode;
-  image?: ReactNode;
-}
-
-export interface EmptyStateProps extends EmptyStateSmallProps {
+  image?: ReactNode | string;
   buttonText?: ReactNode;
-  buttonAction?: ReactMouseEventHandler<HTMLElement>;
-  className?: string;
-}
-
-export interface ImageContainerProps {
-  image: ReactNode;
-  size: EmptyStateSize;
-}
+  buttonAction?: (event: SyntheticEvent) => void;
+  size?: EmptyStateSize;
+  children?: ReactNode;
+};
 
 const EmptyStateContainer = styled.div`
   ${({ theme }) => css`
@@ -55,6 +74,7 @@ const EmptyStateContainer = styled.div`
     flex-direction: column;
     width: 100%;
     height: 100%;
+    color: ${theme.colors.grayscale.light2};
     align-items: center;
     justify-content: center;
     padding: ${theme.gridUnit * 4}px;
@@ -75,43 +95,24 @@ const EmptyStateContainer = styled.div`
   `}
 `;
 
-const TextContainer = styled.div``;
-
-const Title = styled.p`
-  ${({ theme }) => css`
-    font-size: ${theme.typography.sizes.m}px;
+const Title = styled.p<{ size: EmptyStateSize }>`
+  ${({ theme, size }) => css`
+    font-size: ${size === 'large'
+      ? theme.typography.sizes.l
+      : theme.typography.sizes.m}px;
     color: ${theme.colors.grayscale.light1};
-    margin: ${theme.gridUnit * 2}px 0 0 0;
+    margin-top: ${size === 'large' ? theme.gridUnit * 4 : theme.gridUnit * 
2}px;
     font-weight: ${theme.typography.weights.bold};
   `}
 `;
 
-const BigTitle = styled(Title)`
-  ${({ theme }) => css`
-    font-size: ${theme.typography.sizes.l}px;
-    color: ${theme.colors.grayscale.light1};
-    margin-top: ${theme.gridUnit * 4}px;
-  `}
-`;
-
-const Description = styled.p`
-  ${({ theme }) => css`
-    font-size: ${theme.typography.sizes.s}px;
+const Description = styled.p<{ size: EmptyStateSize }>`
+  ${({ theme, size }) => css`
+    font-size: ${size === 'large'
+      ? theme.typography.sizes.m
+      : theme.typography.sizes.s}px;
     color: ${theme.colors.grayscale.light1};
-    margin: ${theme.gridUnit * 2}px 0 0 0;
-  `}
-`;
-
-const BigDescription = styled(Description)`
-  ${({ theme }) => css`
-    font-size: ${theme.typography.sizes.m}px;
-  `}
-`;
-
-const SmallDescription = styled(Description)`
-  ${({ theme }) => css`
-    margin-top: ${theme.gridUnit}px;
-    line-height: 1.2;
+    margin-top: ${theme.gridUnit * 2}px;
   `}
 `;
 
@@ -122,81 +123,68 @@ const ActionButton = styled(Button)`
   `}
 `;
 
-const getImage = (image: string | ReactNode) =>
-  typeof image === 'string' ? `/static/assets/images/${image}` : image;
-
 const getImageHeight = (size: EmptyStateSize) => {
   switch (size) {
-    case EmptyStateSize.Small:
+    case 'small':
       return { height: '50px' };
-    case EmptyStateSize.Medium:
+    case 'medium':
       return { height: '80px' };
-    case EmptyStateSize.Big:
+    case 'large':
       return { height: '150px' };
     default:
-      return { height: '50px' };
+      return { height: '80px' };
   }
 };
 
-const ImageContainer = ({ image, size }: ImageContainerProps) => (
-  <Empty
-    description={false}
-    image={getImage(image)}
-    imageStyle={getImageHeight(size)}
-  />
-);
+const ImageContainer = ({
+  image,
+  size,
+}: {
+  image?: ReactNode | string;
+  size: EmptyStateSize;
+}) => {
+  if (!image) return null;
+  const mappedImage = typeof image === 'string' ? imageMap[image] : image;
+  return (
+    <div role="img" aria-label="empty">
+      <Empty
+        description={false}
+        image={mappedImage}
+        imageStyle={getImageHeight(size)}
+      />
+    </div>
+  );
+};
 
 const handleMouseDown = (e: SyntheticEvent) => {
   e.preventDefault();
   e.stopPropagation();
 };
 
-export const EmptyStateBig = ({
-  title,
-  image,
-  description,
-  buttonAction,
+export const EmptyState: React.FC<EmptyStateProps> = ({
+  title = t('No results'),
+  description = t('There is currently no information to display.'),
+  image = 'empty.svg',
   buttonText,
-  className,
-}: EmptyStateProps) => (
-  <EmptyStateContainer className={className}>
-    {image && <ImageContainer image={image} size={EmptyStateSize.Big} />}
-    <TextContainer
-      css={(theme: SupersetTheme) => css`
-        max-width: ${theme.gridUnit * 150}px;
-      `}
-    >
-      <BigTitle>{title}</BigTitle>
-      {description && <BigDescription>{description}</BigDescription>}
-      {buttonAction && buttonText && (
-        <ActionButton
-          buttonStyle="primary"
-          onClick={buttonAction}
-          onMouseDown={handleMouseDown}
-        >
-          {buttonText}
-        </ActionButton>
-      )}
-    </TextContainer>
-  </EmptyStateContainer>
-);
-
-export const EmptyStateMedium = ({
-  title,
-  image,
-  description,
   buttonAction,
-  buttonText,
-}: EmptyStateProps) => (
+  size = 'medium',
+  children,
+}) => (
   <EmptyStateContainer>
-    {image && <ImageContainer image={image} size={EmptyStateSize.Medium} />}
-    <TextContainer
+    {image && <ImageContainer image={image} size={size} />}
+    <div
       css={(theme: SupersetTheme) => css`
-        max-width: ${theme.gridUnit * 100}px;
+        max-width: ${size === 'large'
+          ? theme.gridUnit * 150
+          : theme.gridUnit * 100}px;
       `}
     >
-      <Title>{title}</Title>
-      {description && <Description>{description}</Description>}
+      {title && <Title size={size}>{title}</Title>}
+      {description && (
+        <Description size={size} className="ant-empty-description">
+          {description}
+        </Description>
+      )}
       {buttonText && buttonAction && (
         <ActionButton
           buttonStyle="primary"
@@ -206,48 +194,7 @@ export const EmptyStateMedium = ({
           {buttonText}
         </ActionButton>
       )}
-    </TextContainer>
-  </EmptyStateContainer>
-);
-
-export const EmptyStateSmall = ({
-  title,
-  image,
-  description,
-}: EmptyStateSmallProps) => (
-  <EmptyStateContainer>
-    {image && <ImageContainer image={image} size={EmptyStateSize.Small} />}
-    <TextContainer
-      css={(theme: SupersetTheme) => css`
-        max-width: ${theme.gridUnit * 75}px;
-      `}
-    >
-      <Title>{title}</Title>
-      {description && <SmallDescription>{description}</SmallDescription>}
-    </TextContainer>
+      {children}
+    </div>
   </EmptyStateContainer>
 );
-
-const TRANSLATIONS = {
-  NO_DATABASES_MATCH_TITLE: t('No databases match your search'),
-  NO_DATABASES_AVAILABLE_TITLE: t('There are no databases available'),
-  MANAGE_YOUR_DATABASES_TEXT: t('Manage your databases'),
-  HERE_TEXT: t('here'),
-};
-
-export const emptyStateComponent = (emptyResultsWithSearch: boolean) => (
-  <EmptyStateSmall
-    image="empty.svg"
-    title={
-      emptyResultsWithSearch
-        ? TRANSLATIONS.NO_DATABASES_MATCH_TITLE
-        : TRANSLATIONS.NO_DATABASES_AVAILABLE_TITLE
-    }
-    description={
-      <p>
-        {TRANSLATIONS.MANAGE_YOUR_DATABASES_TEXT}{' '}
-        <a href="/databaseview/list">{TRANSLATIONS.HERE_TEXT}</a>
-      </p>
-    }
-  />
-);
diff --git a/superset-frontend/src/components/ListView/ListView.tsx 
b/superset-frontend/src/components/ListView/ListView.tsx
index 30bcb99aa3..cfa060f11d 100644
--- a/superset-frontend/src/components/ListView/ListView.tsx
+++ b/superset-frontend/src/components/ListView/ListView.tsx
@@ -37,7 +37,7 @@ import {
   ViewModeType,
 } from './types';
 import { ListViewError, useListViewState } from './utils';
-import { EmptyStateBig, EmptyStateProps } from '../EmptyState';
+import { EmptyState, EmptyStateProps } from '../EmptyState';
 
 const ListViewStyles = styled.div`
   text-align: center;
@@ -447,17 +447,19 @@ function ListView<T extends object = any>({
           {!loading && rows.length === 0 && (
             <EmptyWrapper className={viewMode}>
               {query.filters ? (
-                <EmptyStateBig
+                <EmptyState
                   title={t('No results match your filter criteria')}
                   description={t('Try different criteria to display results.')}
+                  size="large"
                   image="filter-results.svg"
                   buttonAction={() => handleClearFilterControls()}
                   buttonText={t('clear all filters')}
                 />
               ) : (
-                <EmptyStateBig
+                <EmptyState
                   {...emptyState}
                   title={emptyState?.title || t('No Data')}
+                  size="large"
                   image={emptyState?.image || 'filter-results.svg'}
                 />
               )}
diff --git a/superset-frontend/src/components/Table/index.tsx 
b/superset-frontend/src/components/Table/index.tsx
index 1495befa5a..11a803893b 100644
--- a/superset-frontend/src/components/Table/index.tsx
+++ b/superset-frontend/src/components/Table/index.tsx
@@ -16,13 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { useState, useEffect, useRef, ReactElement, Key } from 'react';
+import { useState, useEffect, useRef, Key } from 'react';
 
 import AntTable, {
   ColumnsType,
   TableProps as AntTableProps,
 } from 'antd/lib/table';
-import ConfigProvider from 'antd/lib/config-provider';
 import { PaginationProps } from 'antd/lib/pagination';
 import { t, useTheme, logging, styled } from '@superset-ui/core';
 import Loading from 'src/components/Loading';
@@ -116,10 +115,6 @@ export interface TableProps<RecordType> {
    * Set table to display no data even if data has been provided
    */
   hideData?: boolean;
-  /**
-   * emptyComponent
-   */
-  emptyComponent?: ReactElement;
   /**
    * Enables setting the text displayed in various components and tooltips 
within the Table UI.
    */
@@ -256,7 +251,6 @@ export function Table<RecordType extends object>(
     defaultPageSize = 15,
     pageSizeOptions = ['5', '15', '25', '50', '100'],
     hideData = false,
-    emptyComponent,
     locale,
     height,
     virtualize = false,
@@ -288,9 +282,6 @@ export function Table<RecordType extends object>(
     onChange: onSelectChange,
   };
 
-  const renderEmpty = () =>
-    emptyComponent ?? <div>{mergedLocale.emptyText}</div>;
-
   // Log use of experimental features
   useEffect(() => {
     if (reorderable === true) {
@@ -403,31 +394,29 @@ export function Table<RecordType extends object>(
   };
 
   return (
-    <ConfigProvider renderEmpty={renderEmpty}>
-      <div ref={wrapperRef}>
-        {!virtualize && (
-          <StyledTable
-            {...sharedProps}
-            rowSelection={selectionTypeValue ? rowSelection : undefined}
-            sticky={sticky}
-          />
-        )}
-        {virtualize && (
-          <StyledVirtualTable
-            {...sharedProps}
-            scroll={{
-              y: 300,
-              x: '100vw',
-              // To avoid jest failure by scrollTo
-              ...(process.env.WEBPACK_MODE === 'test' && {
-                scrollToFirstRowOnChange: false,
-              }),
-            }}
-            allowHTML={allowHTML}
-          />
-        )}
-      </div>
-    </ConfigProvider>
+    <div ref={wrapperRef}>
+      {!virtualize && (
+        <StyledTable
+          {...sharedProps}
+          rowSelection={selectionTypeValue ? rowSelection : undefined}
+          sticky={sticky}
+        />
+      )}
+      {virtualize && (
+        <StyledVirtualTable
+          {...sharedProps}
+          scroll={{
+            y: 300,
+            x: '100vw',
+            // To avoid jest failure by scrollTo
+            ...(process.env.WEBPACK_MODE === 'test' && {
+              scrollToFirstRowOnChange: false,
+            }),
+          }}
+          allowHTML={allowHTML}
+        />
+      )}
+    </div>
   );
 }
 
diff --git 
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
 
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
index 29dc12a7c8..cdd59b459a 100644
--- 
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
+++ 
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
@@ -65,7 +65,7 @@ import {
 } from 'src/dashboard/util/constants';
 import FilterBar from 'src/dashboard/components/nativeFilters/FilterBar';
 import Loading from 'src/components/Loading';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { useUiConfig } from 'src/components/UiConfigContext';
 import ResizableSidebar from 'src/components/ResizableSidebar';
 import {
@@ -667,8 +667,9 @@ const DashboardBuilder = () => {
         {!editMode &&
           !topLevelTabs &&
           dashboardLayout[DASHBOARD_GRID_ID]?.children?.length === 0 && (
-            <EmptyStateBig
+            <EmptyState
               title={t('There are no charts added to this dashboard')}
+              size="large"
               description={
                 canEdit &&
                 t(
diff --git a/superset-frontend/src/dashboard/components/DashboardGrid.jsx 
b/superset-frontend/src/dashboard/components/DashboardGrid.jsx
index 6c6d5f853a..a5f0e52408 100644
--- a/superset-frontend/src/dashboard/components/DashboardGrid.jsx
+++ b/superset-frontend/src/dashboard/components/DashboardGrid.jsx
@@ -20,7 +20,7 @@ import { PureComponent, Fragment } from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
 import { addAlpha, css, styled, t } from '@superset-ui/core';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { componentShape } from '../util/propShapes';
 import DashboardComponent from '../containers/DashboardComponent';
 import { Droppable } from './dnd/DragDroppable';
@@ -205,11 +205,12 @@ class DashboardGrid extends PureComponent {
       shouldDisplayEmptyState && gridComponent.type === TAB_TYPE;
 
     const dashboardEmptyState = editMode && (
-      <EmptyStateBig
+      <EmptyState
         title={t('Drag and drop components and charts to the dashboard')}
         description={t(
           'You can create a new chart or use existing ones from the panel on 
the right',
         )}
+        size="large"
         buttonText={
           <>
             <i className="fa fa-plus" />
@@ -228,8 +229,9 @@ class DashboardGrid extends PureComponent {
     );
 
     const topLevelTabEmptyState = editMode ? (
-      <EmptyStateBig
+      <EmptyState
         title={t('Drag and drop components to this tab')}
+        size="large"
         description={t(
           `You can create a new chart or use existing ones from the panel on 
the right`,
         )}
@@ -249,8 +251,9 @@ class DashboardGrid extends PureComponent {
         image="chart.svg"
       />
     ) : (
-      <EmptyStateBig
+      <EmptyState
         title={t('There are no components added to this tab')}
+        size="large"
         description={
           canEdit && t('You can add the components in the edit mode.')
         }
diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
 
b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
index 990647b2c3..2a3d0ada5d 100644
--- 
a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
+++ 
b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.test.tsx
@@ -117,7 +117,7 @@ describe('ChartHolder', () => {
         'Make sure that the controls are configured properly and the 
datasource contains data for the selected time range',
       ),
     ).not.toBeInTheDocument(); // description should display only in Explore 
view
-    expect(screen.getByAltText('empty')).toBeVisible();
+    expect(screen.getByRole('img', { name: 'empty' })).toBeVisible();
   });
 
   it('should render anchor link when not editing', async () => {
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx 
b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
index 2c4695f8c7..36a7731641 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
@@ -22,7 +22,7 @@ import classNames from 'classnames';
 import { useDispatch, useSelector } from 'react-redux';
 import { styled, t } from '@superset-ui/core';
 
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import EditableTitle from 'src/components/EditableTitle';
 import { setEditMode } from 'src/dashboard/actions/dashboardState';
 import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
@@ -197,7 +197,7 @@ const Tab = props => {
           </Droppable>
         )}
         {shouldDisplayEmptyState && (
-          <EmptyStateMedium
+          <EmptyState
             title={
               editMode
                 ? t('Drag and drop components to this tab')
diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/Tab.test.tsx 
b/superset-frontend/src/dashboard/components/gridComponents/Tab.test.tsx
index 39adea09f9..c007b535d4 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tab.test.tsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.test.tsx
@@ -288,7 +288,7 @@ test('Render tab content with no children', () => {
   expect(
     screen.getByText('There are no components added to this tab'),
   ).toBeVisible();
-  expect(screen.getByAltText('empty')).toBeVisible();
+  expect(screen.getByRole('img', { name: 'empty' })).toBeVisible();
   expect(screen.queryByText('edit mode')).not.toBeInTheDocument();
 });
 
@@ -397,7 +397,7 @@ test('Render tab content with no children, editMode: true, 
canEdit: true', () =>
   expect(
     screen.getByText('Drag and drop components to this tab'),
   ).toBeVisible();
-  expect(screen.getByAltText('empty')).toBeVisible();
+  expect(screen.getByRole('img', { name: 'empty' })).toBeVisible();
   expect(
     screen.getByRole('link', { name: 'create a new chart' }),
   ).toBeVisible();
diff --git 
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
 
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
index b76b65c133..d6960ad370 100644
--- 
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
+++ 
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
@@ -33,7 +33,7 @@ import cx from 'classnames';
 import { FeatureFlag, isFeatureEnabled, styled, t } from '@superset-ui/core';
 import Icons from 'src/components/Icons';
 import Loading from 'src/components/Loading';
-import { EmptyStateSmall } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { getFilterBarTestId } from './utils';
 import { VerticalBarProps } from './types';
 import Header from './Header';
@@ -168,7 +168,8 @@ const VerticalFilterBar: FC<VerticalBarProps> = ({
     () =>
       filterValues.length === 0 ? (
         <FilterBarEmptyStateContainer>
-          <EmptyStateSmall
+          <EmptyState
+            size="small"
             title={t('No global filters are currently added')}
             image="filter.svg"
             description={
diff --git 
a/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx
 
b/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx
index ca0a1d6af4..4e83fa63a5 100644
--- 
a/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx
+++ 
b/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx
@@ -19,7 +19,7 @@
 import { useState, useEffect, useMemo } from 'react';
 import { ensureIsArray, GenericDataType, styled, t } from '@superset-ui/core';
 import Loading from 'src/components/Loading';
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import TableView, { EmptyWrapperType } from 'src/components/TableView';
 import {
   useFilteredTableData,
@@ -124,7 +124,7 @@ export const SamplesPane = ({
 
   if (data.length === 0) {
     const title = t('No samples were returned for this dataset');
-    return <EmptyStateMedium image="document.svg" title={title} />;
+    return <EmptyState image="document.svg" title={title} />;
   }
 
   return (
diff --git 
a/superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx
 
b/superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx
index fe262fe720..e96963d108 100644
--- 
a/superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx
+++ 
b/superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx
@@ -26,7 +26,7 @@ import {
   getClientErrorObject,
 } from '@superset-ui/core';
 import Loading from 'src/components/Loading';
-import { EmptyStateMedium } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { getChartDataRequest } from 'src/components/Chart/chartAction';
 import { ResultsPaneProps, QueryResultInterface } from '../types';
 import { SingleQueryResultPane } from './SingleQueryResultPane';
@@ -110,7 +110,7 @@ export const useResultsPane = ({
   if (errorMessage) {
     const title = t('Run a query to display results');
     return Array(queryCount).fill(
-      <EmptyStateMedium image="document.svg" title={title} />,
+      <EmptyState image="document.svg" title={title} />,
     );
   }
 
@@ -136,7 +136,7 @@ export const useResultsPane = ({
   if (resultResp.length === 0) {
     const title = t('No results were returned for this query');
     return Array(queryCount).fill(
-      <EmptyStateMedium image="document.svg" title={title} />,
+      <EmptyState image="document.svg" title={title} />,
     );
   }
   return resultResp
diff --git 
a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx
 
b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx
index 304ec3409d..905fd04f9c 100644
--- 
a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx
+++ 
b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.jsx
@@ -38,7 +38,7 @@ import TextControl from 
'src/explore/components/controls/TextControl';
 import CheckboxControl from 'src/explore/components/controls/CheckboxControl';
 import PopoverSection from 'src/components/PopoverSection';
 import ControlHeader from 'src/explore/components/ControlHeader';
-import { EmptyStateSmall } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import {
   ANNOTATION_SOURCE_TYPES,
   ANNOTATION_TYPES,
@@ -111,8 +111,9 @@ const NotFoundContentWrapper = styled.div`
 
 const NotFoundContent = () => (
   <NotFoundContentWrapper>
-    <EmptyStateSmall
+    <EmptyState
       title={t('No annotation layers')}
+      size="small"
       description={
         <span>
           {t('Add an annotation layer')}{' '}
diff --git 
a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx
 
b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx
index 711cad392d..6e0a256965 100644
--- 
a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx
+++ 
b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx
@@ -43,7 +43,7 @@ import { Select } from 'src/components';
 import { Form, FormItem } from 'src/components/Form';
 import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
-import { EmptyStateSmall } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { getColumnKeywords } from 'src/explore/controlUtils/getColumnKeywords';
 import { StyledColumnOption } from 'src/explore/components/optionRenderers';
 import {
@@ -334,8 +334,9 @@ const ColumnSelectPopover = ({
               />
             </FormItem>
           ) : datasourceType === DatasourceType.Table ? (
-            <EmptyStateSmall
+            <EmptyState
               image="empty.svg"
+              size="small"
               title={
                 isTemporal
                   ? t('No temporal columns found')
@@ -352,8 +353,9 @@ const ColumnSelectPopover = ({
               }
             />
           ) : (
-            <EmptyStateSmall
+            <EmptyState
               image="empty.svg"
+              size="small"
               title={
                 isTemporal
                   ? t('No temporal columns found')
@@ -393,8 +395,9 @@ const ColumnSelectPopover = ({
           disabled={disabledTabs.has('simple')}
         >
           {isTemporal && simpleColumns.length === 0 ? (
-            <EmptyStateSmall
+            <EmptyState
               image="empty.svg"
+              size="small"
               title={t('No temporal columns found')}
               description={
                 datasourceType === DatasourceType.Table ? (
diff --git 
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
 
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
index c527aa5825..188487b338 100644
--- 
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
+++ 
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
@@ -30,7 +30,7 @@ import Tabs from 'src/components/Tabs';
 import Button from 'src/components/Button';
 import { Select } from 'src/components';
 import { Tooltip } from 'src/components/Tooltip';
-import { EmptyStateSmall } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { Form, FormItem } from 'src/components/Form';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
 import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
@@ -389,16 +389,18 @@ export default class AdhocMetricEditPopover extends 
PureComponent {
                 />
               </FormItem>
             ) : datasource.type === DatasourceType.Table ? (
-              <EmptyStateSmall
+              <EmptyState
                 image="empty.svg"
+                size="small"
                 title={t('No saved metrics found')}
                 description={t(
                   'Add metrics to dataset in "Edit datasource" modal',
                 )}
               />
             ) : (
-              <EmptyStateSmall
+              <EmptyState
                 image="empty.svg"
+                size="small"
                 title={t('No saved metrics found')}
                 description={
                   <>
diff --git a/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx 
b/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
index 8ecbf33872..ae51762d78 100644
--- a/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
+++ b/superset-frontend/src/features/allEntities/AllEntitiesTable.tsx
@@ -23,7 +23,7 @@ import { TagsList } from 'src/components/Tags';
 import FacePile from 'src/components/FacePile';
 import Tag from 'src/types/TagType';
 import Owner from 'src/types/Owner';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { NumberParam, useQueryParam } from 'use-query-params';
 
 const MAX_TAGS_TO_SHOW = 3;
@@ -160,8 +160,9 @@ export default function AllEntitiesTable({
           {renderTable('query')}
         </>
       ) : (
-        <EmptyStateBig
+        <EmptyState
           image="dashboard.svg"
+          size="large"
           title={t('No entities have this tag currently assigned')}
           buttonAction={() => setShowTagModal(true)}
           buttonText={t('Add tag to entities')}
diff --git 
a/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/MessageContent.tsx
 
b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/MessageContent.tsx
index 9f57935947..5aab720272 100644
--- 
a/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/MessageContent.tsx
+++ 
b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/MessageContent.tsx
@@ -18,7 +18,7 @@
  */
 
 import { t, styled } from '@superset-ui/core';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { Link } from 'react-router-dom';
 
 const StyledContainer = styled.div`
@@ -31,7 +31,7 @@ const StyledContainer = styled.div`
   height: 100%;
 `;
 
-const StyledEmptyStateBig = styled(EmptyStateBig)`
+const StyledEmptyState = styled(EmptyState)`
   max-width: 50%;
 
   p {
@@ -91,8 +91,9 @@ export const MessageContent = (props: MessageContentProps) => 
{
   }
   return (
     <StyledContainer>
-      <StyledEmptyStateBig
+      <StyledEmptyState
         image={currentImage}
+        size="large"
         title={currentTitle}
         description={currentDescription}
       />
diff --git 
a/superset-frontend/src/features/datasets/AddDataset/EditDataset/UsageTab/index.tsx
 
b/superset-frontend/src/features/datasets/AddDataset/EditDataset/UsageTab/index.tsx
index 0e41182096..289a67f5aa 100644
--- 
a/superset-frontend/src/features/datasets/AddDataset/EditDataset/UsageTab/index.tsx
+++ 
b/superset-frontend/src/features/datasets/AddDataset/EditDataset/UsageTab/index.tsx
@@ -32,7 +32,7 @@ import Table, {
   TableSize,
   OnChangeFunction,
 } from 'src/components/Table';
-import { EmptyStateBig } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import ChartImage from 'src/assets/images/chart.svg';
 import Icons from 'src/components/Icons';
 import { useToasts } from 'src/components/MessageToasts/withToasts';
@@ -147,7 +147,7 @@ const emptyStateButtonText = (
   </>
 );
 
-const StyledEmptyStateBig = styled(EmptyStateBig)`
+const StyledEmptyState = styled(EmptyState)`
   margin: ${({ theme }) => 13 * theme.gridUnit}px 0;
 `;
 
@@ -250,8 +250,9 @@ const DatasetUsage = ({ datasetId }: DatasetUsageProps) => {
         onChange={onChange}
       />
       {!data.length && !loading ? (
-        <StyledEmptyStateBig
+        <StyledEmptyState
           image={<ChartImage />}
+          size="large"
           title={t('No charts')}
           description={t('This dataset is not used to power any charts.')}
           buttonText={emptyStateButtonText}
diff --git 
a/superset-frontend/src/features/datasets/AddDataset/LeftPanel/index.tsx 
b/superset-frontend/src/features/datasets/AddDataset/LeftPanel/index.tsx
index c14109aede..adb5223422 100644
--- a/superset-frontend/src/features/datasets/AddDataset/LeftPanel/index.tsx
+++ b/superset-frontend/src/features/datasets/AddDataset/LeftPanel/index.tsx
@@ -20,7 +20,7 @@ import { useEffect, SetStateAction, Dispatch, useCallback } 
from 'react';
 import { styled, t } from '@superset-ui/core';
 import TableSelector, { TableOption } from 'src/components/TableSelector';
 import { DatabaseObject } from 'src/components/DatabaseSelector';
-import { emptyStateComponent } from 'src/components/EmptyState';
+import { EmptyState } from 'src/components/EmptyState';
 import { useToasts } from 'src/components/MessageToasts/withToasts';
 import { LocalStorageKeys, getItem } from 'src/utils/localStorageHelpers';
 import {
@@ -178,13 +178,30 @@ export default function LeftPanel({
     ),
     [datasetNames],
   );
+  const getDatabaseEmptyState = (emptyResultsWithSearch: boolean) => (
+    <EmptyState
+      image="empty.svg"
+      title={
+        emptyResultsWithSearch
+          ? t('No databases match your search')
+          : t('No databases available')
+      }
+      description={
+        <span>
+          {t('Manage your databases')}{' '}
+          <a href="/databaseview/list">{t('here')}</a>
+        </span>
+      }
+      size="small"
+    />
+  );
 
   return (
     <LeftPanelStyle>
       <TableSelector
         database={dataset?.db}
         handleError={addDangerToast}
-        emptyState={emptyStateComponent(false)}
+        emptyState={getDatabaseEmptyState(false)}
         onDbChange={setDatabase}
         onCatalogChange={setCatalog}
         onSchemaChange={setSchema}
diff --git a/superset-frontend/src/features/home/ActivityTable.test.tsx 
b/superset-frontend/src/features/home/ActivityTable.test.tsx
index 54fe3c7542..9b5ee127b7 100644
--- a/superset-frontend/src/features/home/ActivityTable.test.tsx
+++ b/superset-frontend/src/features/home/ActivityTable.test.tsx
@@ -137,9 +137,5 @@ test('calls the getEdited batch call when edited tab is 
clicked', async () => {
 });
 test('show empty state if there is no data', () => {
   renderActivityTable(emptyActivityProps);
-  expect(
-    screen.getByText(
-      /recently created charts, dashboards, and saved queries will appear 
here/i,
-    ),
-  ).toBeInTheDocument();
+  expect(screen.getByText(/nothing here yet/i)).toBeInTheDocument();
 });
diff --git a/superset-frontend/src/features/home/ChartTable.test.tsx 
b/superset-frontend/src/features/home/ChartTable.test.tsx
index f03a705245..0e19f8c059 100644
--- a/superset-frontend/src/features/home/ChartTable.test.tsx
+++ b/superset-frontend/src/features/home/ChartTable.test.tsx
@@ -87,9 +87,7 @@ const renderChartTable = (props: any) =>
 test('renders with EmptyState if no data present', async () => {
   await renderChartTable(mockedProps);
   expect(screen.getAllByRole('tab')).toHaveLength(3);
-  expect(
-    screen.getByText(/other charts will appear here/i),
-  ).toBeInTheDocument();
+  expect(screen.getByText(/nothing here yet/i)).toBeInTheDocument();
 });
 
 test('fetches chart favorites and renders chart cards', async () => {
diff --git a/superset-frontend/src/features/home/EmptyState.test.tsx 
b/superset-frontend/src/features/home/EmptyState.test.tsx
index fe633bc788..0be86559dc 100644
--- a/superset-frontend/src/features/home/EmptyState.test.tsx
+++ b/superset-frontend/src/features/home/EmptyState.test.tsx
@@ -70,15 +70,7 @@ describe('EmptyState', () => {
 
       // Select the first description node
       const textContainer = wrapper.find('.ant-empty-description').at(0);
-      expect(textContainer.text()).toEqual(
-        variant.tab === TableTab.Favorite
-          ? "You don't have any favorites yet!"
-          : `No ${
-              variant.tableName === WelcomeTable.SavedQueries
-                ? 'saved queries'
-                : variant.tableName.toLowerCase()
-            } yet`,
-      );
+      expect(textContainer.text()).toEqual('Nothing here yet');
       expect(wrapper.find('button')).toHaveLength(1);
     });
   });
@@ -95,9 +87,7 @@ describe('EmptyState', () => {
       expect(wrapper.find('.ant-empty-image').children()).toHaveLength(1);
 
       // Check the correct text is displayed
-      expect(textContainer.text()).toContain(
-        `Recently ${recent.tab?.toLowerCase()} charts, dashboards, and saved 
queries will appear here`,
-      );
+      expect(textContainer.text()).toContain(`Nothing here yet`);
     });
   });
 });
diff --git a/superset-frontend/src/features/home/EmptyState.tsx 
b/superset-frontend/src/features/home/EmptyState.tsx
index cbcede55ec..7a2ba4d62b 100644
--- a/superset-frontend/src/features/home/EmptyState.tsx
+++ b/superset-frontend/src/features/home/EmptyState.tsx
@@ -16,172 +16,96 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Link } from 'react-router-dom';
 import Button from 'src/components/Button';
-import { Empty } from 'src/components/EmptyState/Empty';
+import { EmptyState as EmptyStateComponent } from 'src/components/EmptyState';
 import { TableTab } from 'src/views/CRUD/types';
 import { styled, t } from '@superset-ui/core';
 import { WelcomeTable } from './types';
 
-const welcomeTableLabels: Record<WelcomeTable, string> = {
-  [WelcomeTable.Charts]: t('charts'),
-  [WelcomeTable.Dashboards]: t('dashboards'),
-  [WelcomeTable.Recents]: t('recents'),
-  [WelcomeTable.SavedQueries]: t('saved queries'),
-};
-
-const welcomeTableEmpty: Record<WelcomeTable, string> = {
-  [WelcomeTable.Charts]: t('No charts yet'),
-  [WelcomeTable.Dashboards]: t('No dashboards yet'),
-  [WelcomeTable.Recents]: t('No recents yet'),
-  [WelcomeTable.SavedQueries]: t('No saved queries yet'),
-};
-
-const welcomeTableWillAppear: Record<WelcomeTable, (other: string) => string> =
-  {
-    [WelcomeTable.Charts]: (other: string) =>
-      t('%(other)s charts will appear here', { other }),
-    [WelcomeTable.Dashboards]: (other: string) =>
-      t('%(other)s dashboards will appear here', { other }),
-    [WelcomeTable.Recents]: (other: string) =>
-      t('%(other)s recents will appear here', { other }),
-    [WelcomeTable.SavedQueries]: (other: string) =>
-      t('%(other)s saved queries will appear here', { other }),
-  };
-
-export interface EmptyStateProps {
-  tableName: WelcomeTable;
-  tab?: string;
-  otherTabTitle?: string;
-}
 const EmptyContainer = styled.div`
   min-height: 200px;
   display: flex;
+  color: ${({ theme }) => theme.colors.grayscale.light2};
   flex-direction: column;
   justify-content: space-around;
 `;
-const ButtonContainer = styled.div`
-  Button {
-    svg {
-      color: ${({ theme }) => theme.colors.grayscale.light5};
-    }
-  }
-`;
 
-type Redirects = Record<
-  WelcomeTable.Charts | WelcomeTable.Dashboards | WelcomeTable.SavedQueries,
-  string
->;
+const ICONS = {
+  [WelcomeTable.Charts]: 'empty-charts.svg',
+  [WelcomeTable.Dashboards]: 'empty-dashboard.svg',
+  [WelcomeTable.Recents]: 'union.svg',
+  [WelcomeTable.SavedQueries]: 'empty-queries.svg',
+} as const;
 
-export default function EmptyState({
-  tableName,
-  tab,
-  otherTabTitle,
-}: EmptyStateProps) {
-  const mineRedirects: Redirects = {
+const REDIRECTS = {
+  create: {
     [WelcomeTable.Charts]: '/chart/add',
     [WelcomeTable.Dashboards]: '/dashboard/new',
     [WelcomeTable.SavedQueries]: '/sqllab?new=true',
-  };
-  const favRedirects: Redirects = {
+  },
+  viewAll: {
     [WelcomeTable.Charts]: '/chart/list',
     [WelcomeTable.Dashboards]: '/dashboard/list/',
     [WelcomeTable.SavedQueries]: '/savedqueryview/list/',
-  };
-  const tableIcon: Record<WelcomeTable, string> = {
-    [WelcomeTable.Charts]: 'empty-charts.svg',
-    [WelcomeTable.Dashboards]: 'empty-dashboard.svg',
-    [WelcomeTable.Recents]: 'union.svg',
-    [WelcomeTable.SavedQueries]: 'empty-queries.svg',
-  };
-  const mine = <span>{welcomeTableEmpty[tableName]}</span>;
-  const recent = (
-    <span className="no-recents">
-      {(() => {
-        if (tab === TableTab.Viewed) {
-          return t(
-            `Recently viewed charts, dashboards, and saved queries will appear 
here`,
-          );
-        }
-        if (tab === TableTab.Created) {
-          return t(
-            'Recently created charts, dashboards, and saved queries will 
appear here',
-          );
-        }
-        if (tab === TableTab.Other) {
-          const other = otherTabTitle || t('Other');
-          return welcomeTableWillAppear[tableName](other);
-        }
-        if (tab === TableTab.Edited) {
-          return t(
-            `Recently edited charts, dashboards, and saved queries will appear 
here`,
-          );
-        }
-        return null;
-      })()}
-    </span>
-  );
+  },
+} as const;
+
+export interface EmptyStateProps {
+  tableName: WelcomeTable;
+  tab?: string;
+  otherTabTitle?: string;
+}
+
+export default function EmptyState({
+  tableName,
+  tab,
+  otherTabTitle,
+}: EmptyStateProps) {
+  const getActionButton = () => {
+    if (tableName === WelcomeTable.Recents) {
+      return null;
+    }
+
+    const isFavorite = tab === TableTab.Favorite;
+    const buttonText =
+      tableName === WelcomeTable.SavedQueries
+        ? isFavorite
+          ? t('SQL Lab queries')
+          : t('SQL query')
+        : isFavorite
+          ? t(tableName.toLowerCase())
+          : tableName.slice(0, -1);
+
+    const url = isFavorite
+      ? REDIRECTS.viewAll[tableName]
+      : REDIRECTS.create[tableName];
 
-  // Mine and Recent Activity(all tabs) tab empty state
-  if (
-    tab === TableTab.Mine ||
-    tableName === WelcomeTable.Recents ||
-    tab === TableTab.Other
-  ) {
     return (
-      <EmptyContainer>
-        <Empty
-          image={`/static/assets/images/${tableIcon[tableName]}`}
-          description={
-            tableName === WelcomeTable.Recents || tab === TableTab.Other
-              ? recent
-              : mine
-          }
-        >
-          {tableName !== WelcomeTable.Recents && (
-            <ButtonContainer>
-              <Link to={mineRedirects[tableName]}>
-                <Button buttonStyle="primary">
-                  <i className="fa fa-plus" />
-                  {tableName === WelcomeTable.SavedQueries
-                    ? t('SQL query')
-                    : tableName
-                        .split('')
-                        .slice(0, tableName.length - 1)
-                        .join('')}
-                </Button>
-              </Link>
-            </ButtonContainer>
-          )}
-        </Empty>
-      </EmptyContainer>
+      <Button
+        buttonStyle="default"
+        onClick={() => {
+          window.location.href = url;
+        }}
+      >
+        {isFavorite
+          ? t('See all %(tableName)s', { tableName: buttonText })
+          : buttonText}
+      </Button>
     );
-  }
-  // Favorite tab empty state
+  };
+
+  const image =
+    tab === TableTab.Favorite ? 'star-circle.svg' : ICONS[tableName];
+
   return (
     <EmptyContainer>
-      <Empty
-        image="/static/assets/images/star-circle.svg"
-        description={
-          <span className="no-favorites">
-            {t("You don't have any favorites yet!")}
-          </span>
-        }
+      <EmptyStateComponent
+        image={image}
+        size="large"
+        description={t('Nothing here yet')}
       >
-        <Button
-          buttonStyle="primary"
-          onClick={() => {
-            window.location.href = favRedirects[tableName];
-          }}
-        >
-          {t('See all %(tableName)s', {
-            tableName:
-              tableName === WelcomeTable.SavedQueries
-                ? t('SQL Lab queries')
-                : welcomeTableLabels[tableName],
-          })}
-        </Button>
-      </Empty>
+        {getActionButton()}
+      </EmptyStateComponent>
     </EmptyContainer>
   );
 }

Reply via email to