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

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

commit 43f170aed64e2dbce04e9ff0a74cdd791e2ec2ca
Author: Evan Rusackas <[email protected]>
AuthorDate: Fri Jan 9 11:42:23 2026 -0800

    feat(mobile): improve mobile nav drawer UX
    
    - Hide main nav items on mobile, show hamburger menu in header
    - Simplify drawer: remove header, full-width items, no right border
    - Show only consumption items (Dashboards, Theme, User/Logout, About)
    - Hide create actions and admin settings on mobile
    - Pass menu prop to RightMenu for Dashboards link
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude Opus 4 <[email protected]>
---
 superset-frontend/src/features/home/Menu.tsx      | 28 ++++-----
 superset-frontend/src/features/home/RightMenu.tsx | 71 ++++++++++++++++++++++-
 superset-frontend/src/features/home/types.ts      |  1 +
 3 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/superset-frontend/src/features/home/Menu.tsx 
b/superset-frontend/src/features/home/Menu.tsx
index feaabd3e4f..99fdadd543 100644
--- a/superset-frontend/src/features/home/Menu.tsx
+++ b/superset-frontend/src/features/home/Menu.tsx
@@ -323,7 +323,7 @@ export function Menu({
   return (
     <StyledHeader className="top" id="main-menu" role="navigation">
       <StyledRow>
-        <StyledCol md={16} xs={24}>
+        <StyledCol md={16} xs={screens.md ? 24 : 12}>
           <Tooltip
             id="brand-tooltip"
             placement="bottomLeft"
@@ -337,15 +337,15 @@ export function Menu({
               <span>{brand.text}</span>
             </StyledBrandText>
           )}
-          <StyledMainNav
-            mode="horizontal"
-            data-test="navbar-top"
-            className="main-nav"
-            selectedKeys={activeTabs}
-            disabledOverflow
-            items={menu
-              .filter(item => screens.md || item.label === 'Dashboards')
-              .map(item => {
+          {/* Only show nav items on desktop */}
+          {screens.md && (
+            <StyledMainNav
+              mode="horizontal"
+              data-test="navbar-top"
+              className="main-nav"
+              selectedKeys={activeTabs}
+              disabledOverflow
+              items={menu.map(item => {
                 const props = {
                   ...item,
                   isFrontendRoute: isFrontendRoute(item.url),
@@ -363,15 +363,17 @@ export function Menu({
 
                 return buildMenuItem(props);
               })}
-          />
+            />
+          )}
         </StyledCol>
-        <Col md={8} xs={24}>
+        <Col md={8} xs={screens.md ? 24 : 12}>
           <RightMenu
-            align={screens.md ? 'flex-end' : 'flex-start'}
+            align="flex-end"
             settings={settings}
             navbarRight={navbarRight}
             isFrontendRoute={isFrontendRoute}
             environmentTag={environmentTag}
+            menu={menu}
           />
         </Col>
       </StyledRow>
diff --git a/superset-frontend/src/features/home/RightMenu.tsx 
b/superset-frontend/src/features/home/RightMenu.tsx
index 756267e2de..f772b76e27 100644
--- a/superset-frontend/src/features/home/RightMenu.tsx
+++ b/superset-frontend/src/features/home/RightMenu.tsx
@@ -101,6 +101,7 @@ const RightMenu = ({
   navbarRight,
   isFrontendRoute,
   environmentTag,
+  menu,
   setQuery,
 }: RightMenuProps & {
   setQuery: ({
@@ -609,6 +610,64 @@ const RightMenu = ({
     handleLogout,
   ]);
 
+  // Build mobile menu items - consumption only (no create/admin actions)
+  const mobileMenuItems = useMemo(() => {
+    const items: MenuItem[] = [];
+
+    // Add Dashboards link at top (from main menu)
+    const dashboardsMenu = menu?.find(
+      item => item.label === 'Dashboards' || item.name === 'Dashboards',
+    );
+    if (dashboardsMenu) {
+      const dashboardUrl = dashboardsMenu.url || '/dashboard/list/';
+      items.push({
+        key: 'dashboards',
+        label: isFrontendRoute(dashboardUrl) ? (
+          <Link to={dashboardUrl}>{t('Dashboards')}</Link>
+        ) : (
+          <Typography.Link href={dashboardUrl}>
+            {t('Dashboards')}
+          </Typography.Link>
+        ),
+        icon: <Icons.DashboardOutlined />,
+      });
+    }
+
+    // Add theme menu (flatten children directly)
+    menuItems.forEach(item => {
+      if (!item || !('key' in item)) return;
+
+      // Only include theme-sub-menu and language picker
+      if (item.key === 'theme-sub-menu' || item.key === 'language-picker') {
+        items.push({ type: 'divider', key: `divider-before-${item.key}` });
+
+        if ('children' in item && item.children) {
+          // Theme menu already has a nested group, so just add its children 
directly
+          item.children.forEach(child => {
+            items.push(child);
+          });
+        } else {
+          items.push(item);
+        }
+      }
+
+      // Extract user-related items from settings
+      if (item.key === 'settings' && 'children' in item && item.children) {
+        item.children.forEach(child => {
+          if (!child || !('key' in child)) return;
+
+          // Only include user-section and about-section
+          if (child.key === 'user-section' || child.key === 'about-section') {
+            items.push({ type: 'divider', key: `divider-before-${child.key}` 
});
+            items.push(child);
+          }
+        });
+      }
+    });
+
+    return items;
+  }, [menu, menuItems, isFrontendRoute]);
+
   return (
     <StyledDiv align={align}>
       {canDatabase && (
@@ -680,11 +739,15 @@ const RightMenu = ({
             <Icons.MenuOutlined iconSize="l" />
           </Button>
           <Drawer
-            title={t('Menu')}
+            title={null}
             placement="right"
             onClose={() => setMobileMenuOpen(false)}
             open={mobileMenuOpen}
             width={280}
+            styles={{
+              header: { display: 'none' },
+              body: { padding: 0 },
+            }}
           >
             <Menu
               mode="inline"
@@ -693,8 +756,10 @@ const RightMenu = ({
                 handleMenuSelection(info);
                 setMobileMenuOpen(false);
               }}
-              onOpenChange={onMenuOpen}
-              items={menuItems}
+              items={mobileMenuItems}
+              css={css`
+                border-inline-end: none !important;
+              `}
             />
           </Drawer>
         </>
diff --git a/superset-frontend/src/features/home/types.ts 
b/superset-frontend/src/features/home/types.ts
index a59e9fcd85..92b0da2826 100644
--- a/superset-frontend/src/features/home/types.ts
+++ b/superset-frontend/src/features/home/types.ts
@@ -45,6 +45,7 @@ export interface RightMenuProps {
     text: string;
     color: string;
   };
+  menu?: MenuObjectProps[];
 }
 
 export enum GlobalMenuDataOptions {

Reply via email to