You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2026/04/10 00:06:30 UTC

(superset) 02/02: fix(dataset-modal): fix Source tab spacing per sc-101861

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

maximebeauchemin pushed a commit to branch dataset-modal-alignment
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 63901941ff016686ca28d7a9426e57e8d3064514
Author: Maxime Beauchemin <ma...@gmail.com>
AuthorDate: Thu Apr 9 19:23:31 2026 +0000

    fix(dataset-modal): fix Source tab spacing per sc-101861
    
    - Add bottom margin to radio buttons section so lock icon/text has
      more separation from the divider line (issue 1)
    - Remove last FormItem bottom margin in both virtual and physical
      datasource views to reduce excess whitespace below the SQL text box
      and table selector (issue 2)
    - Move search inputs into CollectionTable toolbar via new toolbarExtra
      prop so search and "Add item" button sit on the same row
    - Update CrudButtonWrapper to use flex layout with space-between for
      proper toolbar alignment
    
    Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
 .../components/CollectionTable/index.tsx           | 43 +++++++------
 .../DatasourceEditor/DatasourceEditor.tsx          | 74 ++++++++++++++--------
 .../src/components/Datasource/types.ts             |  1 +
 3 files changed, 73 insertions(+), 45 deletions(-)

diff --git a/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx b/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx
index 0004ade750a..2f1db070a3b 100644
--- a/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx
+++ b/superset-frontend/src/components/Datasource/components/CollectionTable/index.tsx
@@ -38,7 +38,9 @@ import {
 } from '../../types';
 
 const CrudButtonWrapper = styled.div`
-  text-align: right;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
   ${({ theme }) => `margin-bottom: ${theme.sizeUnit * 2}px`}
 `;
 
@@ -466,24 +468,27 @@ export default class CRUDCollection extends PureComponent<
 
     return (
       <>
-        <CrudButtonWrapper>
-          {this.props.allowAddItem && (
-            <StyledButtonWrapper>
-              <Button
-                buttonSize="small"
-                buttonStyle="secondary"
-                onClick={this.onAddItem}
-                data-test="add-item-button"
-              >
-                <Icons.PlusOutlined
-                  iconSize="m"
-                  data-test="crud-add-table-item"
-                />
-                {t('Add item')}
-              </Button>
-            </StyledButtonWrapper>
-          )}
-        </CrudButtonWrapper>
+        {(this.props.toolbarExtra || this.props.allowAddItem) && (
+          <CrudButtonWrapper>
+            {this.props.toolbarExtra}
+            {this.props.allowAddItem && (
+              <StyledButtonWrapper>
+                <Button
+                  buttonSize="small"
+                  buttonStyle="secondary"
+                  onClick={this.onAddItem}
+                  data-test="add-item-button"
+                >
+                  <Icons.PlusOutlined
+                    iconSize="m"
+                    data-test="crud-add-table-item"
+                  />
+                  {t('Add item')}
+                </Button>
+              </StyledButtonWrapper>
+            )}
+          </CrudButtonWrapper>
+        )}
         <Table<CollectionItem>
           data-test="crud-table"
           columns={tableColumns}
diff --git a/superset-frontend/src/components/Datasource/components/DatasourceEditor/DatasourceEditor.tsx b/superset-frontend/src/components/Datasource/components/DatasourceEditor/DatasourceEditor.tsx
index 5c0e483310d..122ca89b918 100644
--- a/superset-frontend/src/components/Datasource/components/DatasourceEditor/DatasourceEditor.tsx
+++ b/superset-frontend/src/components/Datasource/components/DatasourceEditor/DatasourceEditor.tsx
@@ -311,6 +311,7 @@ interface ColumnCollectionTableProps {
   columnLabelTooltips?: Record<string, string>;
   filterTerm?: string;
   filterFields?: string[];
+  toolbarExtra?: ReactNode;
 }
 
 interface StackedFieldProps {
@@ -517,6 +518,7 @@ function ColumnCollectionTable({
   columnLabelTooltips,
   filterTerm,
   filterFields,
+  toolbarExtra,
 }: ColumnCollectionTableProps): JSX.Element {
   return (
     <CollectionTable
@@ -551,6 +553,7 @@ function ColumnCollectionTable({
       columnLabelTooltips={columnLabelTooltips}
       filterTerm={filterTerm}
       filterFields={filterFields}
+      toolbarExtra={toolbarExtra}
       stickyHeader
       expandFieldset={
         <FormContainer>
@@ -1820,6 +1823,7 @@ class DatasourceEditor extends PureComponent<
         <div
           css={theme => css`
             margin-top: ${theme.sizeUnit * 3}px;
+            margin-bottom: ${theme.sizeUnit * 2}px;
             display: flex;
             gap: ${theme.sizeUnit * 4}px;
           `}
@@ -1839,7 +1843,13 @@ class DatasourceEditor extends PureComponent<
         <Divider />
         <Fieldset item={datasource} onChange={this.onDatasourceChange} compact>
           {this.state.datasourceType === DATASOURCE_TYPES.virtual.key && (
-            <div>
+            <div
+              css={css`
+                .ant-form-item:last-child {
+                  margin-bottom: 0;
+                }
+              `}
+            >
               {this.state.isSqla && (
                 <>
                   <Col xs={24} md={12}>
@@ -2036,7 +2046,15 @@ class DatasourceEditor extends PureComponent<
             </div>
           )}
           {this.state.datasourceType === DATASOURCE_TYPES.physical.key && (
-            <Col xs={24} md={12}>
+            <Col
+              xs={24}
+              md={12}
+              css={css`
+                .ant-form-item:last-child {
+                  margin-bottom: 0;
+                }
+              `}
+            >
               {this.state.isSqla && (
                 <Field
                   fieldKey="tableSelector"
@@ -2131,21 +2149,24 @@ class DatasourceEditor extends PureComponent<
     const sortedMetrics = metrics?.length ? this.sortMetrics(metrics) : [];
     return (
       <div>
-        <Input.Search
-          placeholder={t('Search metrics by key or label')}
-          value={metricSearchTerm}
-          onChange={e => this.setState({ metricSearchTerm: e.target.value })}
-          css={theme => ({
-            marginBottom: theme.sizeUnit * 4,
-            width: theme.sizeUnit * 75,
-          })}
-          allowClear
-        />
         <CollectionTable
           tableColumns={['metric_name', 'verbose_name', 'expression']}
           sortColumns={['metric_name', 'verbose_name', 'expression']}
           filterTerm={metricSearchTerm}
           filterFields={['metric_name', 'verbose_name']}
+          toolbarExtra={
+            <Input.Search
+              placeholder={t('Search metrics by key or label')}
+              value={metricSearchTerm}
+              onChange={e =>
+                this.setState({ metricSearchTerm: e.target.value })
+              }
+              css={theme => ({
+                width: theme.sizeUnit * 75,
+              })}
+              allowClear
+            />
+          }
           columnLabels={{
             metric_name: t('Metric Key'),
             verbose_name: t('Label'),
@@ -2420,24 +2441,25 @@ class DatasourceEditor extends PureComponent<
               children: (
                 <StyledTableTabWrapper>
                   {this.renderDefaultColumnSettings()}
-                  <Input.Search
-                    placeholder={t('Search calculated columns by name')}
-                    value={this.state.calculatedColumnSearchTerm}
-                    onChange={e =>
-                      this.setState({
-                        calculatedColumnSearchTerm: e.target.value,
-                      })
-                    }
-                    css={theme => ({
-                      marginBottom: theme.sizeUnit * 4,
-                      width: theme.sizeUnit * 75,
-                    })}
-                    allowClear
-                  />
                   <ColumnCollectionTable
                     columns={this.state.calculatedColumns}
                     filterTerm={this.state.calculatedColumnSearchTerm}
                     filterFields={['column_name']}
+                    toolbarExtra={
+                      <Input.Search
+                        placeholder={t('Search calculated columns by name')}
+                        value={this.state.calculatedColumnSearchTerm}
+                        onChange={e =>
+                          this.setState({
+                            calculatedColumnSearchTerm: e.target.value,
+                          })
+                        }
+                        css={theme => ({
+                          width: theme.sizeUnit * 75,
+                        })}
+                        allowClear
+                      />
+                    }
                     onColumnsChange={calculatedColumns =>
                       this.setColumns({ calculatedColumns })
                     }
diff --git a/superset-frontend/src/components/Datasource/types.ts b/superset-frontend/src/components/Datasource/types.ts
index 3d5dea5c659..c790e33542c 100644
--- a/superset-frontend/src/components/Datasource/types.ts
+++ b/superset-frontend/src/components/Datasource/types.ts
@@ -53,6 +53,7 @@ export interface CRUDCollectionProps {
   emptyMessage?: ReactNode;
   expandFieldset?: ReactNode;
   extraButtons?: ReactNode;
+  toolbarExtra?: ReactNode;
   itemGenerator?: () => any;
   itemCellProps?: Record<
     string,