feat: add extension point to the right side of the menu bar (#20514)

* add setupExtensions

* add 'navbar.right' extension to registry

* add test for navbar.right extension point

* rename MenuRight -> RightMenu

* lint
This commit is contained in:
Sam Faber-Manning 2022-06-30 10:43:20 -07:00 committed by GitHub
parent edb1383bf8
commit f2af81b1c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 1 deletions

View File

@ -34,6 +34,7 @@ type UiGeneratorText<P = void> = (props: P) => string | React.ReactElement;
export type UiOverrides = Partial<{ export type UiOverrides = Partial<{
'embedded.documentation.description': UiGeneratorText; 'embedded.documentation.description': UiGeneratorText;
'embedded.documentation.url': string; 'embedded.documentation.url': string;
'navbar.right': React.ComponentType;
}>; }>;
/** /**

View File

@ -24,6 +24,7 @@ import { configure, makeApi, supersetTheme } from '@superset-ui/core';
import { merge } from 'lodash'; import { merge } from 'lodash';
import setupClient from './setup/setupClient'; import setupClient from './setup/setupClient';
import setupColors from './setup/setupColors'; import setupColors from './setup/setupColors';
import setupExtensions from './setup/setupExtensions';
import setupFormatters from './setup/setupFormatters'; import setupFormatters from './setup/setupFormatters';
import setupDashboardComponents from './setup/setupDasboardComponents'; import setupDashboardComponents from './setup/setupDasboardComponents';
import { BootstrapUser, User } from './types/bootstrapTypes'; import { BootstrapUser, User } from './types/bootstrapTypes';
@ -32,6 +33,8 @@ if (process.env.WEBPACK_MODE === 'development') {
setHotLoaderConfig({ logLevel: 'debug', trackTailUpdates: false }); setHotLoaderConfig({ logLevel: 'debug', trackTailUpdates: false });
} }
setupExtensions();
// eslint-disable-next-line import/no-mutable-exports // eslint-disable-next-line import/no-mutable-exports
export let bootstrapData: { export let bootstrapData: {
user?: BootstrapUser; user?: BootstrapUser;

View File

@ -0,0 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// For individual deployments to add custom overrides
export default function setupExtensions() {}

View File

@ -20,7 +20,9 @@ import React from 'react';
import * as reactRedux from 'react-redux'; import * as reactRedux from 'react-redux';
import fetchMock from 'fetch-mock'; import fetchMock from 'fetch-mock';
import { render, screen } from 'spec/helpers/testing-library'; import { render, screen } from 'spec/helpers/testing-library';
import setupExtensions from 'src/setup/setupExtensions';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import { getUiOverrideRegistry } from '@superset-ui/core';
import { Menu } from './Menu'; import { Menu } from './Menu';
const dropdownItems = [ const dropdownItems = [
@ -482,3 +484,19 @@ test('should render without QueryParamProvider', () => {
render(<Menu {...mockedProps} />, { useRedux: true }); render(<Menu {...mockedProps} />, { useRedux: true });
expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument(); expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument();
}); });
test('should render an extension component if one is supplied', () => {
const uiOverrideRegistry = getUiOverrideRegistry();
uiOverrideRegistry.set('navbar.right', () => (
<>navbar.right extension component</>
));
setupExtensions();
render(<Menu {...mockedProps} />);
expect(
screen.getByText('navbar.right extension component'),
).toBeInTheDocument();
});

View File

@ -28,7 +28,7 @@ import { Link } from 'react-router-dom';
import Icons from 'src/components/Icons'; import Icons from 'src/components/Icons';
import { useUiConfig } from 'src/components/UiConfigContext'; import { useUiConfig } from 'src/components/UiConfigContext';
import { URL_PARAMS } from 'src/constants'; import { URL_PARAMS } from 'src/constants';
import RightMenu from './MenuRight'; import RightMenu from './RightMenu';
import { Languages } from './LanguagePicker'; import { Languages } from './LanguagePicker';
interface BrandProps { interface BrandProps {

View File

@ -28,6 +28,7 @@ import {
css, css,
SupersetTheme, SupersetTheme,
SupersetClient, SupersetClient,
getUiOverrideRegistry,
} from '@superset-ui/core'; } from '@superset-ui/core';
import { MainNav as Menu } from 'src/components/Menu'; import { MainNav as Menu } from 'src/components/Menu';
import { Tooltip } from 'src/components/Tooltip'; import { Tooltip } from 'src/components/Tooltip';
@ -46,6 +47,8 @@ import {
} from './types'; } from './types';
import { MenuObjectProps } from './Menu'; import { MenuObjectProps } from './Menu';
const uiOverrideRegistry = getUiOverrideRegistry();
const versionInfoStyles = (theme: SupersetTheme) => css` const versionInfoStyles = (theme: SupersetTheme) => css`
padding: ${theme.gridUnit * 1.5}px ${theme.gridUnit * 4}px padding: ${theme.gridUnit * 1.5}px ${theme.gridUnit * 4}px
${theme.gridUnit * 4}px ${theme.gridUnit * 7}px; ${theme.gridUnit * 4}px ${theme.gridUnit * 7}px;
@ -255,6 +258,7 @@ const RightMenu = ({
} }
return null; return null;
}; };
const RightMenuExtension = uiOverrideRegistry.get('navbar.right');
const handleDatabaseAdd = () => setQuery({ databaseAdded: true }); const handleDatabaseAdd = () => setQuery({ databaseAdded: true });
@ -274,6 +278,7 @@ const RightMenu = ({
onClick={handleMenuSelection} onClick={handleMenuSelection}
onOpenChange={onMenuOpen} onOpenChange={onMenuOpen}
> >
{RightMenuExtension && <RightMenuExtension />}
{!navbarRight.user_is_anonymous && showActionDropdown && ( {!navbarRight.user_is_anonymous && showActionDropdown && (
<SubMenu <SubMenu
data-test="new-dropdown" data-test="new-dropdown"