diff --git a/superset-frontend/packages/superset-ui-core/src/ui-overrides/ExtensionsRegistry.ts b/superset-frontend/packages/superset-ui-core/src/ui-overrides/ExtensionsRegistry.ts
index 82e68efcf0e96..2da3231ee57bb 100644
--- a/superset-frontend/packages/superset-ui-core/src/ui-overrides/ExtensionsRegistry.ts
+++ b/superset-frontend/packages/superset-ui-core/src/ui-overrides/ExtensionsRegistry.ts
@@ -35,16 +35,36 @@ type ReturningDisplayable
= (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;
'embedded.documentation.description': ReturningDisplayable;
'embedded.documentation.url': string;
'dashboard.nav.right': React.ComponentType;
+ 'navbar.right-menu.item.icon': React.ComponentType;
'navbar.right': React.ComponentType;
+ 'report-modal.dropdown.item.icon': React.ComponentType;
'welcome.message': React.ComponentType;
'welcome.banner': React.ComponentType;
'welcome.main.replacement': React.ComponentType;
diff --git a/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx b/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
index 92388f9f8a0a7..f7bb9ba55cf2f 100644
--- a/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
+++ b/superset-frontend/src/components/ReportModal/HeaderReportDropdown/index.tsx
@@ -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({
) : (
diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
index c907d63f05d18..e861f9e4ef713 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
@@ -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 = {
@@ -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,
@@ -491,11 +511,20 @@ function AlertList({
[],
);
+ const header = HeaderExtension ? (
+
+ {t('Alerts & reports')}
+
+
+ ) : (
+ t('Alerts & reports')
+ );
+
return (
<>
`
}
`;
+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 = ({
{section?.childs?.map?.(child => {
if (typeof child !== 'string') {
+ const menuItemDisplay = RightMenuItemIconExtension ? (
+
+ {child.label}
+
+
+ ) : (
+ child.label
+ );
return (
{isFrontendRoute(child.url) ? (
- {child.label}
+ {menuItemDisplay}
) : (
- {child.label}
+ {menuItemDisplay}
)}
);