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

hugh pushed a commit to branch hugh/rbac-2
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 70c3033393db7edf64331362de5a17876b3a308d
Author: hughhhh <[email protected]>
AuthorDate: Tue Aug 31 11:04:34 2021 -0700

    user into dumb components
---
 superset-frontend/src/components/Menu/Menu.tsx     |   5 +-
 .../src/components/Menu/MenuRight.tsx              | 255 +++++++++++----------
 superset-frontend/src/views/App.tsx                |   2 +-
 3 files changed, 142 insertions(+), 120 deletions(-)

diff --git a/superset-frontend/src/components/Menu/Menu.tsx 
b/superset-frontend/src/components/Menu/Menu.tsx
index 098aa3a..10baa91 100644
--- a/superset-frontend/src/components/Menu/Menu.tsx
+++ b/superset-frontend/src/components/Menu/Menu.tsx
@@ -61,6 +61,7 @@ export interface MenuProps {
     brand: BrandProps;
     navbar_right: NavBarProps;
     settings: MenuObjectProps[];
+    user: object;
   };
   isFrontendRoute?: (path?: string) => boolean;
 }
@@ -171,7 +172,7 @@ const { SubMenu } = DropdownMenu;
 const { useBreakpoint } = Grid;
 
 export function Menu({
-  data: { menu, brand, navbar_right: navbarRight, settings },
+  data: { menu, brand, navbar_right: navbarRight, settings, user },
   isFrontendRoute = () => false,
 }: MenuProps) {
   const [showMenu, setMenu] = useState<MenuMode>('horizontal');
@@ -283,7 +284,6 @@ export function Menu({
                   if (typeof c === 'string') {
                     return c;
                   }
-
                   return {
                     ...c,
                     isFrontendRoute: isFrontendRoute(c.url),
@@ -301,6 +301,7 @@ export function Menu({
             settings={settings}
             navbarRight={navbarRight}
             isFrontendRoute={isFrontendRoute}
+            user={user}
           />
         </Col>
       </Row>
diff --git a/superset-frontend/src/components/Menu/MenuRight.tsx 
b/superset-frontend/src/components/Menu/MenuRight.tsx
index 35d2cb0..a9f1456 100644
--- a/superset-frontend/src/components/Menu/MenuRight.tsx
+++ b/superset-frontend/src/components/Menu/MenuRight.tsx
@@ -21,6 +21,7 @@ import { MainNav as Menu } from 'src/common/components';
 import { t, styled, css, SupersetTheme } from '@superset-ui/core';
 import { Link } from 'react-router-dom';
 import Icons from 'src/components/Icons';
+import findPermission from 'src/dashboard/util/findPermission';
 import LanguagePicker from './LanguagePicker';
 import { NavBarProps, MenuObjectProps } from './Menu';
 
@@ -29,16 +30,22 @@ export const dropdownItems = [
     label: t('SQL query'),
     url: '/superset/sqllab?new=true',
     icon: 'fa-fw fa-search',
+    perm: 'can_sqllab',
+    view: 'Superset',
   },
   {
     label: t('Chart'),
     url: '/chart/add',
     icon: 'fa-fw fa-bar-chart',
+    perm: 'can_write',
+    view: 'Dashboard',
   },
   {
     label: t('Dashboard'),
     url: '/dashboard/new',
     icon: 'fa-fw fa-dashboard',
+    perm: 'can_write',
+    view: 'Chart',
   },
 ];
 
@@ -76,6 +83,7 @@ interface RightMenuProps {
   settings: MenuObjectProps[];
   navbarRight: NavBarProps;
   isFrontendRoute: (path?: string) => boolean;
+  user: any;
 }
 
 const RightMenu = ({
@@ -83,127 +91,140 @@ const RightMenu = ({
   settings,
   navbarRight,
   isFrontendRoute,
-}: RightMenuProps) => (
-  <StyledDiv align={align}>
-    <Menu mode="horizontal">
-      {!navbarRight.user_is_anonymous && (
-        <SubMenu
-          data-test="new-dropdown"
-          title={
-            <StyledI data-test="new-dropdown-icon" className="fa fa-plus" />
-          }
-          icon={<Icons.TriangleDown />}
-        >
-          {dropdownItems.map(menu => (
-            <Menu.Item key={menu.label}>
-              <a href={menu.url}>
-                <i
-                  data-test={`menu-item-${menu.label}`}
-                  className={`fa ${menu.icon}`}
-                />{' '}
-                {menu.label}
-              </a>
-            </Menu.Item>
-          ))}
-        </SubMenu>
-      )}
-      <SubMenu title="Settings" icon={<Icons.TriangleDown iconSize="xl" />}>
-        {settings.map((section, index) => [
-          <Menu.ItemGroup key={`${section.label}`} title={section.label}>
-            {section.childs?.map(child => {
-              if (typeof child !== 'string') {
-                return (
-                  <Menu.Item key={`${child.label}`}>
-                    {isFrontendRoute(child.url) ? (
-                      <Link to={child.url || ''}>{child.label}</Link>
-                    ) : (
-                      <a href={child.url}>{child.label}</a>
-                    )}
-                  </Menu.Item>
-                );
-              }
-              return null;
-            })}
-          </Menu.ItemGroup>,
-          index < settings.length - 1 && <Menu.Divider />,
-        ])}
+  user,
+}: RightMenuProps) => {
+  const { roles } = user;
 
-        {!navbarRight.user_is_anonymous && [
-          <Menu.Divider key="user-divider" />,
-          <Menu.ItemGroup key="user-section" title={t('User')}>
-            {navbarRight.user_profile_url && (
-              <Menu.Item key="profile">
-                <a href={navbarRight.user_profile_url}>{t('Profile')}</a>
-              </Menu.Item>
-            )}
-            {navbarRight.user_info_url && (
-              <Menu.Item key="info">
-                <a href={navbarRight.user_info_url}>{t('Info')}</a>
-              </Menu.Item>
+  // if user has any of these roles the dropdown will appear
+  const canSql = findPermission('can_sqllab', 'Superset', roles);
+  const canDashboard = findPermission('can_write', 'Dashboard', roles);
+  const canChart = findPermission('can_write', 'Chart', roles);
+  const showActionDropdown = canSql || canChart || canDashboard;
+  return (
+    <StyledDiv align={align}>
+      <Menu mode="horizontal">
+        {!navbarRight.user_is_anonymous && showActionDropdown && (
+          <SubMenu
+            data-test="new-dropdown"
+            title={
+              <StyledI data-test="new-dropdown-icon" className="fa fa-plus" />
+            }
+            icon={<Icons.TriangleDown />}
+          >
+            {dropdownItems.map(
+              menu =>
+                findPermission(menu.perm, menu.view, roles) && (
+                  <Menu.Item key={menu.label}>
+                    <a href={menu.url}>
+                      <i
+                        data-test={`menu-item-${menu.label}`}
+                        className={`fa ${menu.icon}`}
+                      />{' '}
+                      {menu.label}
+                    </a>
+                  </Menu.Item>
+                ),
             )}
-            <Menu.Item key="logout">
-              <a href={navbarRight.user_logout_url}>{t('Logout')}</a>
-            </Menu.Item>
-          </Menu.ItemGroup>,
-        ]}
-        {(navbarRight.version_string || navbarRight.version_sha) && [
-          <Menu.Divider key="version-info-divider" />,
-          <Menu.ItemGroup key="about-section" title={t('About')}>
-            <div className="about-section">
-              {navbarRight.show_watermark && (
-                <div css={versionInfoStyles}>
-                  {t('Powered by Apache Superset')}
-                </div>
-              )}
-              {navbarRight.version_string && (
-                <div css={versionInfoStyles}>
-                  Version: {navbarRight.version_string}
-                </div>
+          </SubMenu>
+        )}
+        <SubMenu title="Settings" icon={<Icons.TriangleDown iconSize="xl" />}>
+          {settings.map((section, index) => [
+            <Menu.ItemGroup key={`${section.label}`} title={section.label}>
+              {section.childs?.map(child => {
+                if (typeof child !== 'string') {
+                  return (
+                    <Menu.Item key={`${child.label}`}>
+                      {isFrontendRoute(child.url) ? (
+                        <Link to={child.url || ''}>{child.label}</Link>
+                      ) : (
+                        <a href={child.url}>{child.label}</a>
+                      )}
+                    </Menu.Item>
+                  );
+                }
+                return null;
+              })}
+            </Menu.ItemGroup>,
+            index < settings.length - 1 && <Menu.Divider />,
+          ])}
+
+          {!navbarRight.user_is_anonymous && [
+            <Menu.Divider key="user-divider" />,
+            <Menu.ItemGroup key="user-section" title={t('User')}>
+              {navbarRight.user_profile_url && (
+                <Menu.Item key="profile">
+                  <a href={navbarRight.user_profile_url}>{t('Profile')}</a>
+                </Menu.Item>
               )}
-              {navbarRight.version_sha && (
-                <div css={versionInfoStyles}>
-                  SHA: {navbarRight.version_sha}
-                </div>
+              {navbarRight.user_info_url && (
+                <Menu.Item key="info">
+                  <a href={navbarRight.user_info_url}>{t('Info')}</a>
+                </Menu.Item>
               )}
-            </div>
-          </Menu.ItemGroup>,
-        ]}
-      </SubMenu>
-      {navbarRight.show_language_picker && (
-        <LanguagePicker
-          locale={navbarRight.locale}
-          languages={navbarRight.languages}
-        />
+              <Menu.Item key="logout">
+                <a href={navbarRight.user_logout_url}>{t('Logout')}</a>
+              </Menu.Item>
+            </Menu.ItemGroup>,
+          ]}
+          {(navbarRight.version_string || navbarRight.version_sha) && [
+            <Menu.Divider key="version-info-divider" />,
+            <Menu.ItemGroup key="about-section" title={t('About')}>
+              <div className="about-section">
+                {navbarRight.show_watermark && (
+                  <div css={versionInfoStyles}>
+                    {t('Powered by Apache Superset')}
+                  </div>
+                )}
+                {navbarRight.version_string && (
+                  <div css={versionInfoStyles}>
+                    Version: {navbarRight.version_string}
+                  </div>
+                )}
+                {navbarRight.version_sha && (
+                  <div css={versionInfoStyles}>
+                    SHA: {navbarRight.version_sha}
+                  </div>
+                )}
+              </div>
+            </Menu.ItemGroup>,
+          ]}
+        </SubMenu>
+        {navbarRight.show_language_picker && (
+          <LanguagePicker
+            locale={navbarRight.locale}
+            languages={navbarRight.languages}
+          />
+        )}
+      </Menu>
+      {navbarRight.documentation_url && (
+        <StyledAnchor
+          href={navbarRight.documentation_url}
+          target="_blank"
+          rel="noreferrer"
+          title={t('Documentation')}
+        >
+          <i className="fa fa-question" />
+          &nbsp;
+        </StyledAnchor>
+      )}
+      {navbarRight.bug_report_url && (
+        <StyledAnchor
+          href={navbarRight.bug_report_url}
+          target="_blank"
+          rel="noreferrer"
+          title={t('Report a bug')}
+        >
+          <i className="fa fa-bug" />
+        </StyledAnchor>
+      )}
+      {navbarRight.user_is_anonymous && (
+        <StyledAnchor href={navbarRight.user_login_url}>
+          <i className="fa fa-fw fa-sign-in" />
+          {t('Login')}
+        </StyledAnchor>
       )}
-    </Menu>
-    {navbarRight.documentation_url && (
-      <StyledAnchor
-        href={navbarRight.documentation_url}
-        target="_blank"
-        rel="noreferrer"
-        title={t('Documentation')}
-      >
-        <i className="fa fa-question" />
-        &nbsp;
-      </StyledAnchor>
-    )}
-    {navbarRight.bug_report_url && (
-      <StyledAnchor
-        href={navbarRight.bug_report_url}
-        target="_blank"
-        rel="noreferrer"
-        title={t('Report a bug')}
-      >
-        <i className="fa fa-bug" />
-      </StyledAnchor>
-    )}
-    {navbarRight.user_is_anonymous && (
-      <StyledAnchor href={navbarRight.user_login_url}>
-        <i className="fa fa-fw fa-sign-in" />
-        {t('Login')}
-      </StyledAnchor>
-    )}
-  </StyledDiv>
-);
+    </StyledDiv>
+  );
+};
 
 export default RightMenu;
diff --git a/superset-frontend/src/views/App.tsx 
b/superset-frontend/src/views/App.tsx
index 445a875..b4a2d19 100644
--- a/superset-frontend/src/views/App.tsx
+++ b/superset-frontend/src/views/App.tsx
@@ -41,7 +41,7 @@ setupApp();
 const container = document.getElementById('app');
 const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? 
'{}');
 const user = { ...bootstrap.user };
-const menu = { ...bootstrap.common.menu_data };
+const menu = { ...bootstrap.common.menu_data, user };
 const common = { ...bootstrap.common };
 initFeatureFlags(bootstrap.common.feature_flags);
 

Reply via email to