You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2025/08/18 20:22:40 UTC

(superset) branch move-controls updated: feat: Restructure Pie control panel with tabs for Data and Customize

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

rusackas pushed a commit to branch move-controls
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/move-controls by this push:
     new 51c40dc971 feat: Restructure Pie control panel with tabs for Data and Customize
51c40dc971 is described below

commit 51c40dc97197b58467cc8ad91b82a17d5bebda48
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Mon Aug 18 13:22:20 2025 -0700

    feat: Restructure Pie control panel with tabs for Data and Customize
    
    - Added Ant Design Tabs to split controls into Data and Customize tabs
    - Data tab contains: Group by, Metric, Filters, Row limit, Sort by metric
    - Customize tab contains: Chart Options, Labels, and Pie shape sections
    - Added chart/viz type picker above the tabs showing 'Pie Chart' title and description
    - Maintains all existing controls and their conditional rendering logic
    - Uses useState hook to manage active tab state
---
 .../src/Pie/PieControlPanelSimple.tsx              | 245 ++++++++++++---------
 1 file changed, 143 insertions(+), 102 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
index 21e5f1fe2a..8e6a1f02cf 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/PieControlPanelSimple.tsx
@@ -16,8 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { FC } from 'react';
+import { FC, useState } from 'react';
 import { t } from '@superset-ui/core';
+import { Tabs } from 'antd';
 import {
   ColorSchemeControl,
   D3_FORMAT_OPTIONS,
@@ -87,118 +88,122 @@ export const PieControlPanel: FC<PieControlPanelProps> = ({
   // Get form values
   const formValues = form_data || value || {};
 
-  return (
-    <div style={{ padding: '16px' }}>
-      {/* Query Section */}
-      <div style={{ marginBottom: 24 }}>
-        <h4>{t('Query')}</h4>
+  // State for active tab
+  const [activeTab, setActiveTab] = useState('data');
+
+  // Data tab content
+  const dataTabContent = (
+    <div>
+      {/* Group by */}
+      <div style={{ marginBottom: 16 }}>
+        <ControlHeader
+          label={t('Group by')}
+          description={t('Columns to group by')}
+          hovered
+        />
+        {safeColumns.length > 0 ? (
+          <DndColumnSelect
+            value={formValues.groupby || []}
+            onChange={handleChange('groupby')}
+            options={safeColumns}
+            name="groupby"
+            label=""
+            multi
+            canDelete
+            ghostButtonText={t('Add dimension')}
+            type="DndColumnSelect"
+            actions={actions}
+          />
+        ) : (
+          <div style={{ padding: '10px' }}>
+            {t('No columns available. Please select a dataset first.')}
+          </div>
+        )}
+      </div>
 
-        {/* Group by */}
-        <div style={{ marginBottom: 16 }}>
-          <ControlHeader
-            label={t('Group by')}
-            description={t('Columns to group by')}
-            hovered
+      {/* Metric */}
+      <div style={{ marginBottom: 16 }}>
+        <ControlHeader
+          label={t('Metric')}
+          description={t('Metric to display')}
+          hovered
+        />
+        {safeDataSource && safeDataSource.columns ? (
+          <DndMetricSelect
+            value={formValues.metric}
+            onChange={handleChange('metric')}
+            datasource={safeDataSource}
+            name="metric"
+            label=""
+            multi={false}
+            savedMetrics={safeMetrics}
           />
-          {safeColumns.length > 0 ? (
-            <DndColumnSelect
-              value={formValues.groupby || []}
-              onChange={handleChange('groupby')}
-              options={safeColumns}
-              name="groupby"
-              label=""
-              multi
-              canDelete
-              ghostButtonText={t('Add dimension')}
-              type="DndColumnSelect"
-              actions={actions}
-            />
-          ) : (
-            <div style={{ padding: '10px' }}>
-              {t('No columns available. Please select a dataset first.')}
-            </div>
-          )}
-        </div>
+        ) : (
+          <div style={{ padding: '10px' }}>{t('No metrics available.')}</div>
+        )}
+      </div>
 
-        {/* Metric */}
-        <div style={{ marginBottom: 16 }}>
-          <ControlHeader
-            label={t('Metric')}
-            description={t('Metric to display')}
-            hovered
+      {/* Filters */}
+      <div style={{ marginBottom: 16 }}>
+        <ControlHeader
+          label={t('Filters')}
+          description={t('Filters to apply to the data')}
+          hovered
+        />
+        {safeDataSource && safeColumns.length > 0 ? (
+          <DndFilterSelect
+            value={formValues.adhoc_filters || []}
+            onChange={handleChange('adhoc_filters')}
+            datasource={safeDataSource}
+            columns={safeColumns}
+            formData={formValues}
+            name="adhoc_filters"
+            savedMetrics={safeMetrics}
+            selectedMetrics={formValues.metric ? [formValues.metric] : []}
+            type="DndFilterSelect"
+            actions={actions}
           />
-          {safeDataSource && safeDataSource.columns ? (
-            <DndMetricSelect
-              value={formValues.metric}
-              onChange={handleChange('metric')}
-              datasource={safeDataSource}
-              name="metric"
-              label=""
-              multi={false}
-              savedMetrics={safeMetrics}
-            />
-          ) : (
-            <div style={{ padding: '10px' }}>{t('No metrics available.')}</div>
-          )}
-        </div>
+        ) : (
+          <div style={{ padding: '10px' }}>
+            {t('No columns available for filtering.')}
+          </div>
+        )}
+      </div>
 
-        {/* Filters */}
-        <div style={{ marginBottom: 16 }}>
+      {/* Row limit and Sort by metric */}
+      <div style={{ display: 'flex', gap: 16 }}>
+        <div style={{ flex: 1 }}>
           <ControlHeader
-            label={t('Filters')}
-            description={t('Filters to apply to the data')}
+            label={t('Row limit')}
+            description={t('Limit the number of rows that are returned')}
             hovered
           />
-          {safeDataSource && safeColumns.length > 0 ? (
-            <DndFilterSelect
-              value={formValues.adhoc_filters || []}
-              onChange={handleChange('adhoc_filters')}
-              datasource={safeDataSource}
-              columns={safeColumns}
-              formData={formValues}
-              name="adhoc_filters"
-              savedMetrics={safeMetrics}
-              selectedMetrics={formValues.metric ? [formValues.metric] : []}
-              type="DndFilterSelect"
-              actions={actions}
-            />
-          ) : (
-            <div style={{ padding: '10px' }}>
-              {t('No columns available for filtering.')}
-            </div>
-          )}
+          <TextControl
+            value={formValues.row_limit}
+            onChange={handleChange('row_limit')}
+            isInt
+            placeholder="100"
+            controlId="row_limit"
+          />
         </div>
-
-        {/* Row limit and Sort by metric */}
-        <div style={{ display: 'flex', gap: 16 }}>
-          <div style={{ flex: 1 }}>
-            <ControlHeader
-              label={t('Row limit')}
-              description={t('Limit the number of rows that are returned')}
-              hovered
-            />
-            <TextControl
-              value={formValues.row_limit}
-              onChange={handleChange('row_limit')}
-              isInt
-              placeholder="100"
-              controlId="row_limit"
-            />
-          </div>
-          <div style={{ flex: 1 }}>
-            <CheckboxControl
-              label={t('Sort by metric')}
-              description={t(
-                'Whether to sort results by the selected metric in descending order',
-              )}
-              value={formValues.sort_by_metric ?? true}
-              onChange={handleChange('sort_by_metric')}
-              hovered
-            />
-          </div>
+        <div style={{ flex: 1 }}>
+          <CheckboxControl
+            label={t('Sort by metric')}
+            description={t(
+              'Whether to sort results by the selected metric in descending order',
+            )}
+            value={formValues.sort_by_metric ?? true}
+            onChange={handleChange('sort_by_metric')}
+            hovered
+          />
         </div>
       </div>
+    </div>
+  );
 
+  // Customize tab content
+  const customizeTabContent = (
+    <div>
       {/* Chart Options Section */}
       <div style={{ marginBottom: 24 }}>
         <h4>{t('Chart Options')}</h4>
@@ -482,6 +487,42 @@ export const PieControlPanel: FC<PieControlPanelProps> = ({
       </div>
     </div>
   );
+
+  // Tab items
+  const tabItems = [
+    {
+      key: 'data',
+      label: t('Data'),
+      children: dataTabContent,
+    },
+    {
+      key: 'customize',
+      label: t('Customize'),
+      children: customizeTabContent,
+    },
+  ];
+
+  return (
+    <div style={{ padding: '16px' }}>
+      {/* Chart/Viz Type Picker */}
+      <div style={{ marginBottom: 16, padding: '12px', borderRadius: '4px' }}>
+        <div style={{ fontSize: '16px', fontWeight: 500, marginBottom: '8px' }}>
+          {t('Pie Chart')}
+        </div>
+        <div style={{ fontSize: '12px', color: '#666' }}>
+          {t('Visualize data as a pie or donut chart')}
+        </div>
+      </div>
+
+      {/* Tabs for Data and Customize */}
+      <Tabs
+        activeKey={activeTab}
+        onChange={setActiveTab}
+        items={tabItems}
+        size="large"
+      />
+    </div>
+  );
 };
 
 // Mark this component as a modern panel
@@ -606,4 +647,4 @@ const config = {
   },
 };
 
-export default config;
+export default config;
\ No newline at end of file