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

msyavuz pushed a commit to branch msyavuz/feat/matrixify-tag-for-charts
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 57c35daf87f06a95b99ebfef7f86eaa344d90887
Author: Mehmet Salih Yavuz <[email protected]>
AuthorDate: Mon Jan 19 14:33:57 2026 +0300

    feat(Matrixify): add matrixify tag to list view and explore
---
 .../ExploreChartHeader/ExploreChartHeader.test.tsx | 29 ++++++++++++++++++++++
 .../components/ExploreChartHeader/index.jsx        |  6 ++++-
 .../src/pages/ChartList/ChartList.test.tsx         | 29 +++++++++++++++++++++-
 .../src/pages/ChartList/ChartList.testHelpers.tsx  | 13 ++++++++++
 superset-frontend/src/pages/ChartList/index.tsx    | 17 +++++++++++--
 5 files changed, 90 insertions(+), 4 deletions(-)

diff --git 
a/superset-frontend/src/explore/components/ExploreChartHeader/ExploreChartHeader.test.tsx
 
b/superset-frontend/src/explore/components/ExploreChartHeader/ExploreChartHeader.test.tsx
index a8010f1c6a..1f3183845f 100644
--- 
a/superset-frontend/src/explore/components/ExploreChartHeader/ExploreChartHeader.test.tsx
+++ 
b/superset-frontend/src/explore/components/ExploreChartHeader/ExploreChartHeader.test.tsx
@@ -383,6 +383,35 @@ describe('ExploreChartHeader', () => {
 
     expect(setShowModal).toHaveBeenCalledWith(false);
   });
+
+  test('renders Matrixify tag when matrixify is enabled', async () => {
+    const props = createProps({
+      formData: {
+        ...createProps().chart.latestQueryFormData,
+        matrixify_enable_vertical_layout: true,
+        matrixify_mode_rows: 'metrics',
+        matrixify_rows: [{ label: 'COUNT(*)', expressionType: 'SIMPLE' }],
+      },
+    });
+    render(<ExploreHeader {...props} />, { useRedux: true });
+    
+    const matrixifyTag = await screen.findByText('Matrixify');
+    expect(matrixifyTag).toBeInTheDocument();
+    expect(matrixifyTag.closest('[color="purple"]')).toBeInTheDocument();
+  });
+
+  test('does not render Matrixify tag when matrixify is disabled', async () => 
{
+    const props = createProps({
+      formData: {
+        ...createProps().chart.latestQueryFormData,
+      },
+    });
+    render(<ExploreHeader {...props} />, { useRedux: true });
+    
+    await waitFor(() => {
+      expect(screen.queryByText('Matrixify')).not.toBeInTheDocument();
+    });
+  });
 });
 
 // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from 
describe blocks
diff --git 
a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx 
b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
index 8be2bea51b..857e5032f2 100644
--- a/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartHeader/index.jsx
@@ -27,7 +27,7 @@ import {
   UnsavedChangesModal,
 } from '@superset-ui/core/components';
 import { AlteredSliceTag } from 'src/components';
-import { SupersetClient } from '@superset-ui/core';
+import { SupersetClient, isMatrixifyEnabled } from '@superset-ui/core';
 import { logging } from '@apache-superset/core';
 import { css, t } from '@apache-superset/core/ui';
 import { chartPropShape } from 'src/dashboard/util/propShapes';
@@ -42,6 +42,7 @@ import { deleteActiveReport } from 
'src/features/reports/ReportModal/actions';
 import { useUnsavedChangesPrompt } from 'src/hooks/useUnsavedChangesPrompt';
 import { getChartFormDiffs } from 'src/utils/getChartFormDiffs';
 import { StreamingExportModal } from 'src/components/StreamingExportModal';
+import { Tag } from 'src/components/Tag';
 import { useExploreAdditionalActionsMenu } from 
'../useExploreAdditionalActionsMenu';
 import { useExploreMetadataBar } from './useExploreMetadataBar';
 
@@ -272,6 +273,9 @@ export const ExploreChartHeader = ({
                 currentFormData={currentFormData}
               />
             ) : null}
+            {formData && isMatrixifyEnabled(formData) && (
+              <Tag name="Matrixify" color="purple" />
+            )}
             {metadataBar}
           </div>
         }
diff --git a/superset-frontend/src/pages/ChartList/ChartList.test.tsx 
b/superset-frontend/src/pages/ChartList/ChartList.test.tsx
index 214f887c7a..180a023763 100644
--- a/superset-frontend/src/pages/ChartList/ChartList.test.tsx
+++ b/superset-frontend/src/pages/ChartList/ChartList.test.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 import fetchMock from 'fetch-mock';
-import { screen, waitFor, fireEvent } from 'spec/helpers/testing-library';
+import { screen, waitFor, fireEvent, within } from 
'spec/helpers/testing-library';
 import { isFeatureEnabled } from '@superset-ui/core';
 import {
   API_ENDPOINTS,
@@ -245,6 +245,33 @@ describe('ChartList', () => {
     );
   });
 
+  test('displays Matrixify tag for charts with matrixify enabled', async () => 
{
+    renderChartList(mockUser);
+    
+    // Wait for the chart list to load
+    await waitFor(() => {
+      expect(screen.getByText('Test Chart 0')).toBeInTheDocument();
+    });
+    
+    // Find the row containing Test Chart 0 (which has matrixify enabled)
+    const chart0Row = screen.getByText('Test Chart 0').closest('tr');
+    expect(chart0Row).toBeInTheDocument();
+    
+    // Check that the Matrixify tag is present in this row
+    const matrixifyTag = within(chart0Row as 
HTMLElement).getByText('Matrixify');
+    expect(matrixifyTag).toBeInTheDocument();
+    
+    // Verify it's styled as purple (check for the color attribute or class)
+    expect(matrixifyTag.closest('[color="purple"]')).toBeInTheDocument();
+    
+    // Find the row containing Test Chart 1 (which doesn't have matrixify)
+    const chart1Row = screen.getByText('Test Chart 1').closest('tr');
+    expect(chart1Row).toBeInTheDocument();
+    
+    // Check that the Matrixify tag is NOT present in this row
+    expect(within(chart1Row as 
HTMLElement).queryByText('Matrixify')).not.toBeInTheDocument();
+  });
+
   test('handles API errors gracefully', async () => {
     // Mock API failure
     fetchMock.get(
diff --git a/superset-frontend/src/pages/ChartList/ChartList.testHelpers.tsx 
b/superset-frontend/src/pages/ChartList/ChartList.testHelpers.tsx
index 1e600cf41b..b22462ce95 100644
--- a/superset-frontend/src/pages/ChartList/ChartList.testHelpers.tsx
+++ b/superset-frontend/src/pages/ChartList/ChartList.testHelpers.tsx
@@ -60,6 +60,14 @@ export const mockCharts = [
     thumbnail_url: '/api/v1/chart/0/thumbnail/',
     certified_by: null,
     certification_details: null,
+    
+    // Add form_data with matrixify enabled
+    form_data: {
+      viz_type: 'table',
+      matrixify_enable_vertical_layout: true,
+      matrixify_mode_rows: 'metrics',
+      matrixify_rows: [{ label: 'COUNT(*)', expressionType: 'SIMPLE' }],
+    },
   },
   {
     id: 1,
@@ -102,6 +110,11 @@ export const mockCharts = [
     thumbnail_url: '/api/v1/chart/1/thumbnail/',
     certified_by: 'Data Team',
     certification_details: 'Approved for production use',
+    
+    // Add form_data without matrixify
+    form_data: {
+      viz_type: 'bar',
+    },
   },
   {
     id: 2,
diff --git a/superset-frontend/src/pages/ChartList/index.tsx 
b/superset-frontend/src/pages/ChartList/index.tsx
index b0abfe0c8e..0b51c2452b 100644
--- a/superset-frontend/src/pages/ChartList/index.tsx
+++ b/superset-frontend/src/pages/ChartList/index.tsx
@@ -23,6 +23,7 @@ import {
   getChartMetadataRegistry,
   JsonResponse,
   SupersetClient,
+  isMatrixifyEnabled,
 } from '@superset-ui/core';
 import { styled } from '@apache-superset/core/ui';
 import { useState, useMemo, useCallback } from 'react';
@@ -78,6 +79,7 @@ import { UserWithPermissionsAndRoles } from 
'src/types/bootstrapTypes';
 import { findPermission } from 'src/utils/findPermission';
 import { QueryObjectColumns } from 'src/views/CRUD/types';
 import { WIDER_DROPDOWN_WIDTH } from 'src/components/ListView/utils';
+import { Tag } from 'src/components/Tag';
 
 const FlexRowContainer = styled.div`
   align-items: center;
@@ -375,9 +377,20 @@ function ChartList(props: ChartListProps) {
       {
         Cell: ({
           row: {
-            original: { viz_type: vizType },
+            original: { viz_type: vizType, form_data: formData },
           },
-        }: any) => registry.get(vizType)?.name || vizType,
+        }: any) => (
+          <>
+            {registry.get(vizType)?.name || vizType}
+            {formData && isMatrixifyEnabled(formData) && (
+              <Tag
+                name="Matrixify"
+                color="purple"
+                style={{ marginLeft: 8 }}
+              />
+            )}
+          </>
+        ),
         Header: t('Type'),
         accessor: 'viz_type',
         id: 'viz_type',

Reply via email to