feat: Add 3 new extension points for inserting custom icons (#22027)
This commit is contained in:
parent
9832bbd469
commit
c870fbe9e2
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue