You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2026/04/23 17:37:36 UTC

(superset) 13/33: chore: rename database/database when using semantic layers

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

betodealmeida pushed a commit to branch backup/semantic-layer-dynamic-columns-before-rebase-20260423-133321
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 3e4d465f54adcceb69ebc8941ea00760aa190ffc
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Thu Mar 12 10:12:32 2026 -0400

    chore: rename database/database when using semantic layers
---
 superset-frontend/src/features/home/RightMenu.tsx  | 14 ++--
 superset-frontend/src/pages/DatabaseList/index.tsx | 28 +++++---
 superset-frontend/src/pages/DatasetList/index.tsx  | 78 ++++++++++++++++------
 superset-frontend/src/utils/semanticLayerLabels.ts | 63 +++++++++++++++++
 4 files changed, 146 insertions(+), 37 deletions(-)

diff --git a/superset-frontend/src/features/home/RightMenu.tsx b/superset-frontend/src/features/home/RightMenu.tsx
index 28c25498642..ea35f46db16 100644
--- a/superset-frontend/src/features/home/RightMenu.tsx
+++ b/superset-frontend/src/features/home/RightMenu.tsx
@@ -66,6 +66,10 @@ import {
   RightMenuProps,
 } from './types';
 import { NAVBAR_MENU_POPUP_OFFSET } from './commonMenuData';
+import {
+  datasetLabelLower,
+  databaseLabelLower,
+} from 'src/utils/semanticLayerLabels';
 
 const extensionsRegistry = getExtensionsRegistry();
 
@@ -176,12 +180,12 @@ const RightMenu = ({
       icon: <Icons.DatabaseOutlined data-test={`menu-item-${t('Data')}`} />,
       childs: [
         {
-          label: t('Connect database'),
+          label: t('Connect %s', databaseLabelLower()),
           name: GlobalMenuDataOptions.DbConnection,
           perm: canDatabase && !nonExamplesDBConnected,
         },
         {
-          label: t('Create dataset'),
+          label: t('Create %s', datasetLabelLower()),
           name: GlobalMenuDataOptions.DatasetCreation,
           url: '/dataset/add/',
           perm: canDataset && nonExamplesDBConnected,
@@ -192,19 +196,19 @@ const RightMenu = ({
           perm: canDatabase && HAS_GSHEETS_INSTALLED,
         },
         {
-          label: t('Upload CSV to database'),
+          label: t('Upload CSV to %s', databaseLabelLower()),
           name: GlobalMenuDataOptions.CSVUpload,
           perm: canUploadCSV && showUploads,
           disable: isAdmin && !allowUploads,
         },
         {
-          label: t('Upload Excel to database'),
+          label: t('Upload Excel to %s', databaseLabelLower()),
           name: GlobalMenuDataOptions.ExcelUpload,
           perm: canUploadExcel && showUploads,
           disable: isAdmin && !allowUploads,
         },
         {
-          label: t('Upload Columnar file to database'),
+          label: t('Upload Columnar file to %s', databaseLabelLower()),
           name: GlobalMenuDataOptions.ColumnarUpload,
           perm: canUploadColumnar && showUploads,
           disable: isAdmin && !allowUploads,
diff --git a/superset-frontend/src/pages/DatabaseList/index.tsx b/superset-frontend/src/pages/DatabaseList/index.tsx
index a263fe2d2b4..c428d84b229 100644
--- a/superset-frontend/src/pages/DatabaseList/index.tsx
+++ b/superset-frontend/src/pages/DatabaseList/index.tsx
@@ -68,6 +68,11 @@ import { DatabaseObject } from 'src/features/databases/types';
 import { QueryObjectColumns } from 'src/views/CRUD/types';
 import { WIDER_DROPDOWN_WIDTH } from 'src/components/ListView/utils';
 import { ModalTitleWithIcon } from 'src/components/ModalTitleWithIcon';
+import {
+  databaseLabel,
+  databaseLabelLower,
+  databasesLabel,
+} from 'src/utils/semanticLayerLabels';
 
 const extensionsRegistry = getExtensionsRegistry();
 const DatabaseDeleteRelatedExtension = extensionsRegistry.get(
@@ -137,7 +142,7 @@ function DatabaseList({
     refreshData: dbRefreshData,
   } = useListViewResource<DatabaseObject>(
     'database',
-    t('database'),
+    databaseLabelLower(),
     addDangerToast,
   );
 
@@ -423,7 +428,7 @@ function DatabaseList({
   const menuData: SubMenuProps = {
     activeChild: 'Databases',
     dropDownLinks: filteredDropDown,
-    name: t('Databases'),
+    name: databasesLabel(),
   };
 
   if (canCreate) {
@@ -441,7 +446,7 @@ function DatabaseList({
                 items: [
                   {
                     key: 'database',
-                    label: t('Database'),
+                    label: databaseLabel(),
                     onClick: openDatabaseModal,
                   },
                   {
@@ -478,7 +483,7 @@ function DatabaseList({
         {
           'data-test': 'btn-create-database',
           icon: <Icons.PlusOutlined iconSize="m" />,
-          name: t('Database'),
+          name: databaseLabel(),
           buttonStyle: 'primary',
           onClick: openDatabaseModal,
         },
@@ -499,7 +504,9 @@ function DatabaseList({
         });
       } catch (error) {
         setPreparingExport(false);
-        addDangerToast(t('There was an issue exporting the database'));
+        addDangerToast(
+          t('There was an issue exporting the %s', databaseLabelLower()),
+        );
       }
     },
     [addDangerToast, setPreparingExport],
@@ -777,7 +784,7 @@ function DatabaseList({
                 >
                   <Tooltip
                     id="delete-action-tooltip"
-                    title={t('Delete database')}
+                    title={t('Delete %s', databaseLabelLower())}
                     placement="bottom"
                   >
                     <Icons.DeleteOutlined iconSize="l" />
@@ -835,7 +842,7 @@ function DatabaseList({
         operator: FilterOperator.Equals,
         unfilteredLabel: t('All'),
         selects: [
-          { label: t('Database'), value: 'database' },
+          { label: databaseLabel(), value: 'database' },
           { label: t('Semantic Layer'), value: 'semantic_layer' },
         ],
       });
@@ -887,7 +894,8 @@ function DatabaseList({
             'changed_by',
             createErrorHandler(errMsg =>
               t(
-                'An error occurred while fetching dataset datasource values: %s',
+                'An error occurred while fetching %s values: %s',
+                databaseLabelLower(),
                 errMsg,
               ),
             ),
@@ -990,7 +998,7 @@ function DatabaseList({
           description={
             <>
               <p>
-                {t('The database')}{' '}
+                {t('The %s', databaseLabelLower())}{' '}
                 <b>{databaseCurrentlyDeleting.database_name}</b>{' '}
                 {t(
                   '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.',
@@ -1098,7 +1106,7 @@ function DatabaseList({
           title={
             <ModalTitleWithIcon
               icon={<Icons.DeleteOutlined />}
-              title={t('Delete Database?')}
+              title={t('Delete %s?', databaseLabel())}
             />
           }
         />
diff --git a/superset-frontend/src/pages/DatasetList/index.tsx b/superset-frontend/src/pages/DatasetList/index.tsx
index dcb9f4d11cd..3d22d5b4a9b 100644
--- a/superset-frontend/src/pages/DatasetList/index.tsx
+++ b/superset-frontend/src/pages/DatasetList/index.tsx
@@ -80,6 +80,13 @@ import DuplicateDatasetModal from 'src/features/datasets/DuplicateDatasetModal';
 import type DatasetType from 'src/types/Dataset';
 import SemanticViewEditModal from 'src/features/semanticViews/SemanticViewEditModal';
 import AddSemanticViewModal from 'src/features/semanticViews/AddSemanticViewModal';
+import {
+  datasetLabel,
+  datasetLabelLower,
+  datasetsLabel,
+  datasetsLabelLower,
+  databaseLabel,
+} from 'src/utils/semanticLayerLabels';
 import { useSelector } from 'react-redux';
 import { QueryObjectColumns } from 'src/views/CRUD/types';
 import { WIDER_DROPDOWN_WIDTH } from 'src/components/ListView/utils';
@@ -175,7 +182,11 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
     state: { bulkSelectEnabled },
     hasPerm,
     toggleBulkSelect,
-  } = useListViewResource<Dataset>('dataset', t('dataset'), addDangerToast);
+  } = useListViewResource<Dataset>(
+    'dataset',
+    datasetLabelLower(),
+    addDangerToast,
+  );
 
   // Combined endpoint state
   const [datasets, setDatasets] = useState<Dataset[]>([]);
@@ -236,7 +247,9 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           setDatasetCount(json.count);
         })
         .catch(() => {
-          addDangerToast(t('An error occurred while fetching datasets'));
+          addDangerToast(
+            t('An error occurred while fetching %s', datasetsLabelLower()),
+          );
         })
         .finally(() => {
           setLoading(false);
@@ -322,7 +335,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
   const handleDatasetImport = () => {
     showImportModal(false);
     refreshData();
-    addSuccessToast(t('Dataset imported'));
+    addSuccessToast(t('%s imported', datasetLabel()));
   };
 
   const canEdit = hasPerm('can_write');
@@ -360,7 +373,10 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
         })
         .catch(() => {
           addDangerToast(
-            t('An error occurred while fetching dataset related data'),
+            t(
+              'An error occurred while fetching %s related data',
+              datasetLabelLower(),
+            ),
           );
         });
     },
@@ -404,7 +420,12 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
         });
       } catch {
         setPreparingExport(false);
-        addDangerToast(t('There was an issue exporting the selected datasets'));
+        addDangerToast(
+          t(
+            'There was an issue exporting the selected %s',
+            datasetsLabelLower(),
+          ),
+        );
       }
     },
     [addDangerToast, setPreparingExport],
@@ -517,7 +538,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
             original: { database },
           },
         }: CellProps<Dataset>) => database?.database_name || '-',
-        Header: t('Database'),
+        Header: databaseLabel(),
         accessor: 'database.database_name',
         size: 'xl',
         id: 'database.database_name',
@@ -752,7 +773,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
               operator: FilterOperator.Equals,
               unfilteredLabel: t('All'),
               selects: [
-                { label: t('Database'), value: 'database' },
+                { label: databaseLabel(), value: 'database' },
                 { label: t('Semantic Layer'), value: 'semantic_layer' },
               ],
             },
@@ -802,7 +823,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
             },
           ]),
       {
-        Header: t('Database'),
+        Header: databaseLabel(),
         key: 'database',
         id: 'database',
         input: 'select',
@@ -812,7 +833,11 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           'dataset',
           'database',
           createErrorHandler(errMsg =>
-            t('An error occurred while fetching datasets: %s', errMsg),
+            t(
+              'An error occurred while fetching %s: %s',
+              datasetsLabelLower(),
+              errMsg,
+            ),
           ),
         ),
         paginate: true,
@@ -846,7 +871,8 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           'dataset',
           createErrorHandler(errMsg =>
             t(
-              'An error occurred while fetching dataset owner values: %s',
+              'An error occurred while fetching %s owner values: %s',
+              datasetLabelLower(),
               errMsg,
             ),
           ),
@@ -881,7 +907,8 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           'changed_by',
           createErrorHandler(errMsg =>
             t(
-              'An error occurred while fetching dataset datasource values: %s',
+              'An error occurred while fetching %s values: %s',
+              datasetLabelLower(),
               errMsg,
             ),
           ),
@@ -896,7 +923,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
 
   const menuData: SubMenuProps = {
     activeChild: 'Datasets',
-    name: t('Datasets'),
+    name: datasetsLabel(),
   };
 
   const buttonArr: Array<ButtonProps> = [];
@@ -906,7 +933,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
       name: (
         <Tooltip
           id="import-tooltip"
-          title={t('Import datasets')}
+          title={t('Import %s', datasetsLabelLower())}
           placement="bottomRight"
         >
           <Icons.DownloadOutlined
@@ -943,7 +970,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
               items: [
                 {
                   key: 'dataset',
-                  label: t('Dataset'),
+                  label: datasetLabel(),
                   onClick: () => history.push('/dataset/add/'),
                 },
                 {
@@ -975,7 +1002,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
     } else {
       buttonArr.push({
         icon: <Icons.PlusOutlined iconSize="m" />,
-        name: t('Dataset'),
+        name: datasetLabel(),
         onClick: () => {
           history.push('/dataset/add/');
         },
@@ -1053,7 +1080,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
         addSuccessToast(t('Deleted %s item(s)', datasetsToDelete.length));
       } else {
         addDangerToast(
-          t('There was an issue deleting the selected items'),
+          t('There was an issue deleting the selected %s', datasetsLabelLower()),
         );
       }
     });
@@ -1061,7 +1088,9 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
 
   const handleDatasetDuplicate = (newDatasetName: string) => {
     if (datasetCurrentlyDuplicating === null) {
-      addDangerToast(t('There was an issue duplicating the dataset.'));
+      addDangerToast(
+        t('There was an issue duplicating the %s.', datasetLabelLower()),
+      );
     }
 
     SupersetClient.post({
@@ -1077,7 +1106,11 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
       },
       createErrorHandler(errMsg =>
         addDangerToast(
-          t('There was an issue duplicating the selected datasets: %s', errMsg),
+          t(
+            'There was an issue duplicating the selected %s: %s',
+            datasetsLabelLower(),
+            errMsg,
+          ),
         ),
       ),
     );
@@ -1091,7 +1124,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           description={
             <>
               <p>
-                {t('The dataset')}
+                {t('The %s', datasetLabelLower())}
                 <b> {datasetCurrentlyDeleting.table_name} </b>
                 {t(
                   'is linked to %s charts that appear on %s dashboards. Are you sure you want to continue? Deleting the dataset will break those objects.',
@@ -1197,7 +1230,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
           }}
           onHide={closeDatasetDeleteModal}
           open
-          title={t('Delete Dataset?')}
+          title={t('Delete %s?', datasetLabel())}
         />
       )}
       {svCurrentlyDeleting && (
@@ -1243,7 +1276,8 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
       <ConfirmStatusChange
         title={t('Please confirm')}
         description={t(
-          'Are you sure you want to delete the selected datasets?',
+          'Are you sure you want to delete the selected %s?',
+          datasetsLabelLower(),
         )}
         onConfirm={handleBulkDatasetDelete}
       >
@@ -1326,7 +1360,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
 
       <ImportModelsModal
         resourceName="dataset"
-        resourceLabel={t('dataset')}
+        resourceLabel={datasetLabelLower()}
         passwordsNeededMessage={PASSWORDS_NEEDED_MESSAGE}
         confirmOverwriteMessage={CONFIRM_OVERWRITE_MESSAGE}
         addDangerToast={addDangerToast}
diff --git a/superset-frontend/src/utils/semanticLayerLabels.ts b/superset-frontend/src/utils/semanticLayerLabels.ts
new file mode 100644
index 00000000000..e5ad52b3006
--- /dev/null
+++ b/superset-frontend/src/utils/semanticLayerLabels.ts
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   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
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { isFeatureEnabled, FeatureFlag } from '@superset-ui/core';
+import { t } from '@apache-superset/core/translation';
+
+/**
+ * When the SEMANTIC_LAYERS feature flag is enabled the UI broadens
+ * "dataset" → "datasource" and "database" → "data connection" so
+ * that semantic views and semantic layers feel like first-class
+ * citizens alongside traditional datasets and database connections.
+ */
+function sl<T>(legacy: T, semantic: T): T {
+  return isFeatureEnabled(FeatureFlag.SemanticLayers) ? semantic : legacy;
+}
+
+// ---------------------------------------------------------------------------
+// "dataset" family
+// ---------------------------------------------------------------------------
+
+/** Capitalized singular: "Dataset" / "Datasource" */
+export const datasetLabel = () => sl(t('Dataset'), t('Datasource'));
+
+/** Lower-case singular: "dataset" / "datasource" */
+export const datasetLabelLower = () => sl(t('dataset'), t('datasource'));
+
+/** Capitalized plural: "Datasets" / "Datasources" */
+export const datasetsLabel = () => sl(t('Datasets'), t('Datasources'));
+
+/** Lower-case plural: "datasets" / "datasources" */
+export const datasetsLabelLower = () => sl(t('datasets'), t('datasources'));
+
+// ---------------------------------------------------------------------------
+// "database" family
+// ---------------------------------------------------------------------------
+
+/** Capitalized singular: "Database" / "Data connection" */
+export const databaseLabel = () => sl(t('Database'), t('Data connection'));
+
+/** Lower-case singular: "database" / "data connection" */
+export const databaseLabelLower = () => sl(t('database'), t('data connection'));
+
+/** Capitalized plural: "Databases" / "Data connections" */
+export const databasesLabel = () => sl(t('Databases'), t('Data connections'));
+
+/** Lower-case plural: "databases" / "data connections" */
+export const databasesLabelLower = () =>
+  sl(t('databases'), t('data connections'));