feat: Add 3 new extension points for inserting custom icons (#22027)

This commit is contained in:
Jack Fragassi 2022-11-04 11:53:57 -07:00 committed by GitHub
parent 9832bbd469
commit c870fbe9e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 5 deletions

View File

@ -35,16 +35,36 @@ type ReturningDisplayable<P = void> = (props: P) => string | React.ReactElement;
* When defining a new option here, take care to keep any parameters to functions (or components) minimal.
* Any removal or alteration to a parameter will be considered a breaking change.
*/
// from src/views/components/Menu, not imported since this is a separate package
interface MenuObjectChildProps {
label: string;
name?: string;
icon?: string;
index?: number;
url?: string;
isFrontendRoute?: boolean;
perm?: string | boolean;
view?: string;
disable?: boolean;
}
type ConfigDetailsProps = {
embeddedId: string;
};
type RightMenuItemIconProps = {
menuChild: MenuObjectChildProps;
};
export type Extensions = Partial<{
'alertsreports.header.icon': React.ComponentType;
'embedded.documentation.configuration_details': React.ComponentType<ConfigDetailsProps>;
'embedded.documentation.description': ReturningDisplayable;
'embedded.documentation.url': string;
'dashboard.nav.right': React.ComponentType;
'navbar.right-menu.item.icon': React.ComponentType<RightMenuItemIconProps>;
'navbar.right': React.ComponentType;
'report-modal.dropdown.item.icon': React.ComponentType;
'welcome.message': React.ComponentType;
'welcome.banner': React.ComponentType;
'welcome.main.replacement': React.ComponentType;

View File

@ -23,9 +23,11 @@ import {
t,
SupersetTheme,
css,
styled,
useTheme,
FeatureFlag,
isFeatureEnabled,
getExtensionsRegistry,
} from '@superset-ui/core';
import Icons from 'src/components/Icons';
import { Switch } from 'src/components/Switch';
@ -46,6 +48,8 @@ import {
import { reportSelector } from 'src/views/CRUD/hooks';
import { MenuItemWithCheckboxContainer } from 'src/explore/components/useExploreAdditionalActionsMenu/index';
const extensionsRegistry = getExtensionsRegistry();
const deleteColor = (theme: SupersetTheme) => css`
color: ${theme.colors.error.base};
`;
@ -70,6 +74,21 @@ const onMenuItemHover = (theme: SupersetTheme) => css`
background-color: ${theme.colors.secondary.light5};
}
`;
const StyledDropdownItemWithIcon = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
> *:first-child {
margin-right: ${({ theme }) => theme.gridUnit}px;
}
`;
const DropdownItemExtension = extensionsRegistry.get(
'report-modal.dropdown.item.icon',
);
export enum CreationMethod {
CHARTS = 'charts',
DASHBOARDS = 'dashboards',
@ -204,7 +223,14 @@ export default function HeaderReportDropDown({
) : (
<Menu selectable={false} css={onMenuHover}>
<Menu.Item onClick={handleShowMenu}>
{t('Set up an email report')}
{DropdownItemExtension ? (
<StyledDropdownItemWithIcon>
<div>{t('Set up an email report')}</div>
<DropdownItemExtension />
</StyledDropdownItemWithIcon>
) : (
t('Set up an email report')
)}
</Menu.Item>
<Menu.Divider />
</Menu>

View File

@ -19,7 +19,13 @@
import React, { useState, useMemo, useEffect, useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { t, SupersetClient, makeApi, styled } from '@superset-ui/core';
import {
t,
SupersetClient,
makeApi,
styled,
getExtensionsRegistry,
} from '@superset-ui/core';
import moment from 'moment';
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
import FacePile from 'src/components/FacePile';
@ -49,6 +55,8 @@ import Owner from 'src/types/Owner';
import AlertReportModal from './AlertReportModal';
import { AlertObject, AlertState } from './types';
const extensionsRegistry = getExtensionsRegistry();
const PAGE_SIZE = 25;
const AlertStateLabel: Record<AlertState, string> = {
@ -82,6 +90,18 @@ const RefreshContainer = styled.div`
background-color: ${({ theme }) => theme.colors.grayscale.light5};
`;
const StyledHeaderWithIcon = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
> *:first-child {
margin-right: ${({ theme }) => theme.gridUnit}px;
}
`;
const HeaderExtension = extensionsRegistry.get('alertsreports.header.icon');
function AlertList({
addDangerToast,
isReportEnabled = false,
@ -495,11 +515,20 @@ function AlertList({
[],
);
const header = HeaderExtension ? (
<StyledHeaderWithIcon>
<div>{t('Alerts & reports')}</div>
<HeaderExtension />
</StyledHeaderWithIcon>
) : (
t('Alerts & reports')
);
return (
<>
<SubMenu
activeChild={pathName}
name={t('Alerts & reports')}
name={header}
tabs={[
{
name: 'Alerts',

View File

@ -84,6 +84,13 @@ const StyledDiv = styled.div<{ align: string }>`
}
`;
const StyledMenuItemWithIcon = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
`;
const StyledAnchor = styled.a`
padding-right: ${({ theme }) => theme.gridUnit}px;
padding-left: ${({ theme }) => theme.gridUnit}px;
@ -330,6 +337,9 @@ const RightMenu = ({
return null;
};
const RightMenuExtension = extensionsRegistry.get('navbar.right');
const RightMenuItemIconExtension = extensionsRegistry.get(
'navbar.right-menu.item.icon',
);
const handleDatabaseAdd = () => setQuery({ databaseAdded: true });
const handleDatasetAdd = () => setQuery({ datasetAdded: true });
@ -447,12 +457,20 @@ const RightMenu = ({
<Menu.ItemGroup key={`${section.label}`} title={section.label}>
{section?.childs?.map?.(child => {
if (typeof child !== 'string') {
const menuItemDisplay = RightMenuItemIconExtension ? (
<StyledMenuItemWithIcon>
{child.label}
<RightMenuItemIconExtension menuChild={child} />
</StyledMenuItemWithIcon>
) : (
child.label
);
return (
<Menu.Item key={`${child.label}`}>
{isFrontendRoute(child.url) ? (
<Link to={child.url || ''}>{child.label}</Link>
<Link to={child.url || ''}>{menuItemDisplay}</Link>
) : (
<a href={child.url}>{child.label}</a>
<a href={child.url}>{menuItemDisplay}</a>
)}
</Menu.Item>
);