Wire up tracking to Sandy Chrome

Summary: Wired up tracking to all chrome sections and some import UI elements

Reviewed By: jknoxville

Differential Revision: D25219089

fbshipit-source-id: c75bed91894609dafc5fcc6423a5228211fb92d8
This commit is contained in:
Michel Weststrate
2020-12-03 04:13:07 -08:00
committed by Facebook GitHub Bot
parent dd6f39c2b3
commit 84c6e05b8a
18 changed files with 539 additions and 447 deletions

View File

@@ -26,7 +26,11 @@ import electron, {MenuItemConstructorOptions} from 'electron';
import {notNull} from './utils/typeUtils';
import constants from './fb-stubs/constants';
import {Logger} from './fb-interfaces/Logger';
import {NormalizedMenuEntry, _buildInMenuEntries} from 'flipper-plugin';
import {
NormalizedMenuEntry,
_buildInMenuEntries,
_wrapInteractionHandler,
} from 'flipper-plugin';
import {StyleGuide} from './sandy-chrome/StyleGuide';
import {showEmulatorLauncher} from './sandy-chrome/appinspect/LaunchEmulator';
@@ -191,7 +195,13 @@ export function addSandyPluginEntries(entries: NormalizedMenuEntry[]) {
if (parent) {
const item = new electron.remote.MenuItem({
enabled: true,
click: () => pluginActionHandler?.(entry.action!),
click: _wrapInteractionHandler(
() => pluginActionHandler?.(entry.action!),
'MenuItem',
'onClick',
'flipper:menu:' + entry.topLevelMenu,
entry.label,
),
label: entry.label,
accelerator: entry.accelerator,
});
@@ -206,6 +216,20 @@ export function addSandyPluginEntries(entries: NormalizedMenuEntry[]) {
}
}
function trackMenuItems(menu: string, items: MenuItemConstructorOptions[]) {
items.forEach((item) => {
if (item.label && item.click) {
item.click = _wrapInteractionHandler(
item.click,
'MenuItem',
'onClick',
'flipper:menu:' + menu,
item.label,
);
}
});
}
function getTemplate(
app: electron.App,
shell: electron.Shell,
@@ -226,6 +250,8 @@ function getTemplate(
click: () => startLinkExport(store.dispatch),
});
}
trackMenuItems('export', exportSubmenu);
const fileSubmenu: MenuItemConstructorOptions[] = [
{
label: 'Launch Emulator...',
@@ -250,6 +276,8 @@ function getTemplate(
submenu: exportSubmenu,
},
];
trackMenuItems('file', fileSubmenu);
const supportRequestSubmenu = [
{
label: 'Create...',
@@ -259,11 +287,101 @@ function getTemplate(
},
},
];
trackMenuItems('support', supportRequestSubmenu);
fileSubmenu.push({
label: 'Support Requests',
submenu: supportRequestSubmenu,
});
const viewMenu: MenuItemConstructorOptions[] = [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click: function (_, focusedWindow: electron.BrowserWindow | undefined) {
if (focusedWindow) {
logger.track('usage', 'reload');
focusedWindow.reload();
}
},
},
{
label: 'Toggle Full Screen',
accelerator: (function () {
if (process.platform === 'darwin') {
return 'Ctrl+Command+F';
} else {
return 'F11';
}
})(),
click: function (_, focusedWindow: electron.BrowserWindow | undefined) {
if (focusedWindow) {
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
},
{
label: 'Manage Plugins...',
click: function () {
store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS));
},
},
{
label: 'Flipper style guide',
click() {
store.dispatch(setStaticView(StyleGuide));
},
},
{
label: 'Toggle Developer Tools',
accelerator: (function () {
if (process.platform === 'darwin') {
return 'Alt+Command+I';
} else {
return 'Ctrl+Shift+I';
}
})(),
click: function (_, focusedWindow: electron.BrowserWindow | undefined) {
if (focusedWindow) {
// @ts-ignore: https://github.com/electron/electron/issues/7832
focusedWindow.toggleDevTools();
}
},
},
{
type: 'separator',
},
];
trackMenuItems('view', viewMenu);
const helpMenu: MenuItemConstructorOptions[] = [
{
label: 'Getting started',
click: function () {
shell.openExternal('https://fbflipper.com/docs/getting-started/index');
},
},
{
label: 'Create plugins',
click: function () {
shell.openExternal('https://fbflipper.com/docs/tutorial/intro');
},
},
{
label: 'Report problems',
click: function () {
shell.openExternal(constants.FEEDBACK_GROUP_LINK);
},
},
{
label: 'Changelog',
click() {
store.dispatch(setActiveSheet(ACTIVE_SHEET_CHANGELOG));
},
},
];
trackMenuItems('help', helpMenu);
const template: MenuItemConstructorOptions[] = [
{
label: 'File',
@@ -309,73 +427,7 @@ function getTemplate(
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click: function (
_,
focusedWindow: electron.BrowserWindow | undefined,
) {
if (focusedWindow) {
logger.track('usage', 'reload');
focusedWindow.reload();
}
},
},
{
label: 'Toggle Full Screen',
accelerator: (function () {
if (process.platform === 'darwin') {
return 'Ctrl+Command+F';
} else {
return 'F11';
}
})(),
click: function (
_,
focusedWindow: electron.BrowserWindow | undefined,
) {
if (focusedWindow) {
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
},
{
label: 'Manage Plugins...',
click: function () {
store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS));
},
},
{
label: 'Flipper style guide',
click() {
store.dispatch(setStaticView(StyleGuide));
},
},
{
label: 'Toggle Developer Tools',
accelerator: (function () {
if (process.platform === 'darwin') {
return 'Alt+Command+I';
} else {
return 'Ctrl+Shift+I';
}
})(),
click: function (
_,
focusedWindow: electron.BrowserWindow | undefined,
) {
if (focusedWindow) {
// @ts-ignore: https://github.com/electron/electron/issues/7832
focusedWindow.toggleDevTools();
}
},
},
{
type: 'separator',
},
],
submenu: viewMenu,
},
{
label: 'Window',
@@ -396,36 +448,10 @@ function getTemplate(
{
label: 'Help',
role: 'help',
submenu: [
{
label: 'Getting started',
click: function () {
shell.openExternal(
'https://fbflipper.com/docs/getting-started/index',
);
},
},
{
label: 'Create plugins',
click: function () {
shell.openExternal('https://fbflipper.com/docs/tutorial/intro');
},
},
{
label: 'Report problems',
click: function () {
shell.openExternal(constants.FEEDBACK_GROUP_LINK);
},
},
{
label: 'Changelog',
click() {
store.dispatch(setActiveSheet(ACTIVE_SHEET_CHANGELOG));
},
},
],
submenu: helpMenu,
},
];
trackMenuItems('support', supportRequestSubmenu);
if (process.platform === 'darwin') {
const name = app.name;

View File

@@ -48,15 +48,15 @@ export default function ScreenCaptureButtons({useSandy}: {useSandy?: boolean}) {
const handleScreenshot = useCallback(() => {
setIsTakingScreenshot(true);
capture(selectedDevice!)
.then(openFile)
.catch((e) => {
const p = capture(selectedDevice!).then(openFile);
p.catch((e) => {
console.error('Taking screenshot failed:', e);
message.error('Taking screenshot failed:' + e);
})
.finally(() => {
}).finally(() => {
setIsTakingScreenshot(false);
});
return p;
}, [selectedDevice]);
const handleRecording = useCallback(() => {
if (!selectedDevice) {
@@ -65,13 +65,13 @@ export default function ScreenCaptureButtons({useSandy}: {useSandy?: boolean}) {
if (!isRecording) {
setIsRecording(true);
const videoPath = path.join(CAPTURE_LOCATION, getFileName('mp4'));
selectedDevice.startScreenCapture(videoPath).catch((e) => {
return selectedDevice.startScreenCapture(videoPath).catch((e) => {
console.error('Failed to start recording', e);
message.error('Failed to start recording' + e);
setIsRecording(false);
});
} else {
selectedDevice
return selectedDevice
.stopScreenCapture()
.then(openFile)
.catch((e) => {

View File

@@ -28,7 +28,7 @@ import LauncherSettingsPanel from '../fb-stubs/LauncherSettingsPanel';
import SandySettingsPanel from '../fb-stubs/SandySettingsPanel';
import {reportUsage} from '../utils/metrics';
import {Modal} from 'antd';
import {Layout, _NuxManagerContext} from 'flipper-plugin';
import {Layout, withTrackingScope, _NuxManagerContext} from 'flipper-plugin';
const Container = styled(FlexColumn)({
padding: 20,
@@ -356,7 +356,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
isXcodeDetected: application.xcodeCommandLineToolsDetected,
}),
{updateSettings, updateLauncherSettings},
)(SettingsSheet);
)(withTrackingScope(SettingsSheet));
function ResetTooltips() {
const nuxManager = useContext(_NuxManagerContext);

View File

@@ -27,6 +27,7 @@ import ContextMenu from '../ui/components/ContextMenu';
import {clipboard} from 'electron';
import {reportPlatformFailures} from '../utils/metrics';
import {Modal} from 'antd';
import {TrackingScope} from 'flipper-plugin';
const Container = styled(FlexColumn)({
padding: 20,
@@ -135,6 +136,7 @@ class SignInSheet extends Component<Props, State> {
footer: React.ReactElement,
) {
return (
<TrackingScope scope="logindialog">
<Modal
visible
centered
@@ -144,6 +146,7 @@ class SignInSheet extends Component<Props, State> {
footer={footer}>
<FlexColumn>{contents}</FlexColumn>
</Modal>
</TrackingScope>
);
}

View File

@@ -21,6 +21,7 @@ const {shell, remote} = !isHeadless()
: {shell: undefined, remote: undefined};
import {PureComponent} from 'react';
import React from 'react';
import {Tracked, TrackingScope} from 'flipper-plugin';
const Container = styled(FlexColumn)({
height: '100%',
@@ -127,6 +128,7 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
render() {
return (
<Container>
<TrackingScope scope="welcomescreen">
<Welcome isMounted={this.state.isMounted}>
<Logo src="./icon.png" />
<Title>Welcome to Flipper</Title>
@@ -135,11 +137,14 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
? `Version ${remote.app.getVersion()}`
: 'Development Mode'}
</Version>
<Tracked>
<Item
onClick={() =>
onClick={() => {
shell &&
shell.openExternal('https://fbflipper.com/docs/features/index')
}>
shell.openExternal(
'https://fbflipper.com/docs/features/index',
);
}}>
<Icon size={20} name="rocket" color={brandColors.Flipper} />
<FlexColumn>
<ItemTitle>Using Flipper</ItemTitle>
@@ -151,7 +156,9 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
<Item
onClick={() =>
shell &&
shell.openExternal('https://fbflipper.com/docs/tutorial/intro')
shell.openExternal(
'https://fbflipper.com/docs/tutorial/intro',
)
}>
<Icon size={20} name="magic-wand" color={brandColors.Flipper} />
<FlexColumn>
@@ -184,7 +191,9 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
</ItemSubTitle>
</FlexColumn>
</Item>
</Tracked>
</Welcome>
</TrackingScope>
</Container>
);
}

View File

@@ -343,7 +343,7 @@ const demos: PreviewProps[] = [
],
demos: {
'Basic example': (
<TrackingScope scope="Tracking scope demo">
<TrackingScope scope="tracking scope demo">
<Tracked>
<Button onClick={() => {}}>Test</Button>
</Tracked>
@@ -356,6 +356,7 @@ const demos: PreviewProps[] = [
function ComponentPreview({title, demos, description, props}: PreviewProps) {
return (
<Card title={title} size="small" type="inner">
<TrackingScope scope={title}>
<Layout.Container gap="small">
<Text type="secondary">{description}</Text>
<Collapse ghost>
@@ -415,6 +416,7 @@ function ComponentPreview({title, demos, description, props}: PreviewProps) {
</Collapse.Panel>
</Collapse>
</Layout.Container>
</TrackingScope>
</Card>
);
}

View File

@@ -35,7 +35,7 @@ import {
toggleLeftSidebarVisible,
toggleRightSidebarVisible,
} from '../reducers/application';
import {theme, Layout} from 'flipper-plugin';
import {theme, Layout, withTrackingScope} from 'flipper-plugin';
import SetupDoctorScreen, {checkHasNewProblem} from './SetupDoctorScreen';
import SettingsSheet from '../chrome/SettingsSheet';
import WelcomeScreen from './WelcomeScreen';
@@ -98,6 +98,7 @@ export function LeftRailButton({
return (
<Tooltip title={title} placement="right">
<LeftRailButtonElem
title={title}
kind={small ? 'small' : undefined}
type={selected ? 'primary' : 'ghost'}
icon={iconElement}
@@ -119,7 +120,7 @@ const LeftRailDivider = styled(Divider)({
});
LeftRailDivider.displayName = 'LeftRailDividier';
export function LeftRail({
export const LeftRail = withTrackingScope(function LeftRail({
toplevelSelection,
setToplevelSelection,
}: ToplevelProps) {
@@ -167,7 +168,7 @@ export function LeftRail({
</Layout.Bottom>
</Layout.Container>
);
}
});
function LeftSidebarToggleButton() {
const dispatch = useDispatch();

View File

@@ -127,9 +127,9 @@ export function SandyApp({logger}: {logger: Logger}) {
{staticView ? (
<TrackingScope
scope={
staticView.constructor?.name ??
staticView.displayName ??
staticView.name ??
staticView.constructor?.name ??
'unknown static view'
}>
<ContentContainer>

View File

@@ -16,7 +16,7 @@ import {
CodeOutlined,
BugOutlined,
} from '@ant-design/icons';
import {theme} from 'flipper-plugin';
import {theme, Tracked, TrackingScope} from 'flipper-plugin';
const {Text, Title} = Typography;
@@ -45,6 +45,7 @@ function Row(props: {
onClick?: () => void;
}) {
return (
<Tracked action={props.title}>
<RowContainer onClick={props.onClick}>
<Space size="middle">
{cloneElement(props.icon, {
@@ -58,6 +59,7 @@ function Row(props: {
</FlexColumn>
</Space>
</RowContainer>
</Tracked>
);
}
@@ -114,6 +116,7 @@ export default function WelcomeScreen({
/>
}
onCancel={onClose}>
<TrackingScope scope="welcomescreen">
<Space
direction="vertical"
size="middle"
@@ -154,6 +157,7 @@ export default function WelcomeScreen({
onClick={openExternal(constants.FEEDBACK_GROUP_LINK)}
/>
</Space>
</TrackingScope>
</Modal>
);
}

View File

@@ -16,9 +16,9 @@ import {
CaretDownOutlined,
} from '@ant-design/icons';
import {Glyph, Layout, styled} from '../../ui';
import {theme} from 'flipper-plugin';
import {theme, useTrackedCallback} from 'flipper-plugin';
import {batch} from 'react-redux';
import {Dispatch, useDispatch, useStore} from '../../utils/useStore';
import {useDispatch, useStore} from '../../utils/useStore';
import {
canBeDefaultDevice,
getAvailableClients,
@@ -55,11 +55,34 @@ export function AppSelector() {
uninitializedClients,
selectedApp,
} = useStore((state) => state.connections);
const onSelectDevice = useTrackedCallback(
'select-device',
(device: BaseDevice) => {
batch(() => {
dispatch(selectDevice(device));
dispatch(selectClient(null));
});
},
[],
);
const onSelectApp = useTrackedCallback(
'select-app',
(device: BaseDevice, client: Client) => {
batch(() => {
dispatch(selectDevice(device));
dispatch(selectClient(client.id));
});
},
[],
);
const entries = computeEntries(
devices,
dispatch,
clients,
uninitializedClients,
onSelectDevice,
onSelectApp,
);
const client = clients.find((client) => client.id === selectedApp);
@@ -144,9 +167,10 @@ const AppIconContainer = styled.div({
function computeEntries(
devices: BaseDevice[],
dispatch: Dispatch,
clients: Client[],
uninitializedClients: State['connections']['uninitializedClients'],
onSelectDevice: (device: BaseDevice) => void,
onSelectApp: (device: BaseDevice, client: Client) => void,
) {
const entries = devices.filter(canBeDefaultDevice).map((device) => {
const deviceEntry = (
@@ -155,10 +179,7 @@ function computeEntries(
key={device.serial}
style={{fontWeight: 'bold'}}
onClick={() => {
batch(() => {
dispatch(selectDevice(device));
dispatch(selectClient(null));
});
onSelectDevice(device);
}}>
{device.displayTitle()}
</Menu.Item>
@@ -167,10 +188,7 @@ function computeEntries(
<Menu.Item
key={client.id}
onClick={() => {
batch(() => {
dispatch(selectDevice(device));
dispatch(selectClient(client.id));
});
onSelectApp(device, client);
}}>
<Radio value={client.id}>{client.query.app}</Radio>
</Menu.Item>

View File

@@ -7,11 +7,17 @@
* @format
*/
import React, {useCallback, useMemo} from 'react';
import React, {useMemo} from 'react';
import {AutoComplete, Input, Typography} from 'antd';
import {StarFilled, StarOutlined} from '@ant-design/icons';
import {useStore} from '../../utils/useStore';
import {Layout, NUX, useValue} from 'flipper-plugin';
import {
Layout,
NUX,
TrackingScope,
useTrackedCallback,
useValue,
} from 'flipper-plugin';
import {navPluginStateSelector} from '../../chrome/LocationsButton';
// eslint-disable-next-line flipper/no-relative-imports-across-packages
@@ -25,11 +31,13 @@ export function BookmarkSection() {
const navPlugin = useStore(navPluginStateSelector);
return navPlugin ? (
<TrackingScope scope="bookmarks">
<NUX
title="Use bookmarks to directly navigate to a location in the app."
placement="right">
<BookmarkSectionInput navPlugin={navPlugin} />
</NUX>
</TrackingScope>
) : null;
}
@@ -48,7 +56,9 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) {
[currentURI, bookmarks, patterns, 20],
);
const handleBookmarkClick = useCallback(() => {
const handleBookmarkClick = useTrackedCallback(
'bookmark',
() => {
if (isBookmarked) {
navPlugin.removeBookmark(currentURI);
} else if (currentURI) {
@@ -57,7 +67,11 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) {
commonName: null,
});
}
}, [navPlugin, currentURI, isBookmarked]);
},
[navPlugin, currentURI, isBookmarked],
);
const navigate = useTrackedCallback('navigate', navPlugin.navigateTo, []);
const bookmarkButton = isBookmarked ? (
<StarFilled onClick={handleBookmarkClick} />
@@ -69,7 +83,7 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) {
<StyledAutoComplete
dropdownMatchSelectWidth={500}
value={currentURI}
onSelect={navPlugin.navigateTo}
onSelect={navigate}
style={{flex: 1}}
options={[
{
@@ -99,7 +113,7 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) {
navPlugin.currentURI.set(e.target.value);
}}
onPressEnter={() => {
navPlugin.navigateTo(currentURI);
navigate(currentURI);
}}
/>
</StyledAutoComplete>

View File

@@ -13,7 +13,7 @@ import {AndroidOutlined, AppleOutlined} from '@ant-design/icons';
import {Store} from '../../reducers';
import {useStore} from '../../utils/useStore';
import {launchEmulator} from '../../devices/AndroidDevice';
import {Layout, renderReactRoot} from 'flipper-plugin';
import {Layout, renderReactRoot, withTrackingScope} from 'flipper-plugin';
import {Provider} from 'react-redux';
import {
launchSimulator,
@@ -31,16 +31,19 @@ export function showEmulatorLauncher(store: Store) {
type GetSimulators = typeof getSimulators;
export function LaunchEmulatorDialog({
export const LaunchEmulatorDialog = withTrackingScope(
function LaunchEmulatorDialog({
onClose,
getSimulators,
}: {
}: {
onClose: () => void;
getSimulators: GetSimulators;
}) {
}) {
const iosEnabled = useStore((state) => state.settingsState.enableIOS);
const androidEmulators = useStore((state) =>
state.settingsState.enableAndroid ? state.connections.androidEmulators : [],
state.settingsState.enableAndroid
? state.connections.androidEmulators
: [],
);
const [iosEmulators, setIosEmulators] = useState<IOSDeviceParams[]>([]);
@@ -64,14 +67,14 @@ export function LaunchEmulatorDialog({
<Button
key={name}
icon={<AndroidOutlined />}
onClick={() => {
onClick={() =>
launchEmulator(name)
.catch((e) => {
console.error(e);
message.error('Failed to start emulator: ' + e);
})
.finally(onClose);
}}>
.then(onClose)
}>
{name}
</Button>
)),
@@ -79,14 +82,14 @@ export function LaunchEmulatorDialog({
<Button
key={device.udid}
icon={<AppleOutlined />}
onClick={() => {
onClick={() =>
launchSimulator(device.udid)
.catch((e) => {
console.error(e);
message.error('Failed to start simulator: ' + e);
})
.finally(onClose);
}}>
.then(onClose)
}>
{device.name}
</Button>
)),
@@ -104,4 +107,5 @@ export function LaunchEmulatorDialog({
</Layout.Container>
</Modal>
);
}
},
);

View File

@@ -12,7 +12,7 @@ import {Badge, Button, Menu, Tooltip, Typography} from 'antd';
import {InfoIcon, SidebarTitle} from '../LeftSidebar';
import {PlusOutlined, MinusOutlined} from '@ant-design/icons';
import {Glyph, Layout, styled} from '../../ui';
import {theme, NUX} from 'flipper-plugin';
import {theme, NUX, Tracked} from 'flipper-plugin';
import {useDispatch, useStore} from '../../utils/useStore';
import {getPluginTitle, sortPluginsByName} from '../../utils/pluginUtils';
import {ClientPluginDefinition, DevicePluginDefinition} from '../../plugin';
@@ -225,8 +225,9 @@ function ActionButton({
icon={icon}
title={title}
style={{border: 'none', color: theme.textColorPrimary}}
onClick={() => {
onClick={(e) => {
onClick(id);
e.stopPropagation();
}}
/>
);
@@ -273,6 +274,7 @@ const PluginEntry = memo(function PluginEntry({
}, [active]);
return (
<Tracked action={`open:${plugin.id}`}>
<Menu.Item
key={plugin.id}
active={active}
@@ -293,6 +295,7 @@ const PluginEntry = memo(function PluginEntry({
{hovering && actions}
</Layout.Horizontal>
</Menu.Item>
</Tracked>
);
});

View File

@@ -21,7 +21,7 @@ import {useStore} from '../../utils/useStore';
import {useIsSandy} from '../../sandy-chrome/SandyContext';
import type {ButtonProps} from 'antd/lib/button';
import {DownOutlined, CheckOutlined} from '@ant-design/icons';
import {theme} from 'flipper-plugin';
import {theme, Tracked} from 'flipper-plugin';
type ButtonType = 'primary' | 'success' | 'warning' | 'danger';
@@ -366,6 +366,7 @@ function ClassicButton(props: Props) {
}
return (
<Tracked>
<StyledButton
{...restProps}
ref={_ref as any}
@@ -377,6 +378,7 @@ function ClassicButton(props: Props) {
{iconComponent}
{children}
</StyledButton>
</Tracked>
);
}

View File

@@ -12,6 +12,7 @@ import Tooltip from './Tooltip';
import {colors} from './colors';
import styled from '@emotion/styled';
import React from 'react';
import {Tracked} from 'flipper-plugin';
type Props = React.ComponentProps<typeof ToolbarIconContainer> & {
active?: boolean;
@@ -30,6 +31,7 @@ const ToolbarIconContainer = styled.div({
export default function ToolbarIcon({active, icon, title, ...props}: Props) {
return (
<Tooltip title={title}>
<Tracked action={title}>
<ToolbarIconContainer {...props}>
<Glyph
name={icon}
@@ -41,6 +43,7 @@ export default function ToolbarIcon({active, icon, title, ...props}: Props) {
}
/>
</ToolbarIconContainer>
</Tracked>
</Tooltip>
);
}

View File

@@ -58,6 +58,7 @@ export {
setGlobalInteractionReporter as _setGlobalInteractionReporter,
withTrackingScope,
useTrackedCallback,
wrapInteractionHandler as _wrapInteractionHandler,
} from './ui/Tracked';
export {sleep} from './utils/sleep';

View File

@@ -21,6 +21,7 @@ import {createHash} from 'crypto';
import type {TooltipPlacement} from 'antd/lib/tooltip';
import {SandyPluginInstance} from '../plugin/Plugin';
import {theme} from './theme';
import {Tracked} from './Tracked';
const {Text} = Typography;
@@ -121,9 +122,11 @@ export function NUX({
style={{color: theme.textColorPrimary}}>
<BulbTwoTone style={{fontSize: 24}} />
<Text>{title}</Text>
<Tracked action={'nux:dismiss:' + title.substr(0, 50)}>
<Button size="small" type="default" onClick={dismiss}>
Dismiss
</Button>
</Tracked>
</Layout.Container>
}>
<Pulse />

View File

@@ -109,7 +109,6 @@ export function useTrackedCallback<T extends Function>(
}, deps) as any;
}
// Exported for test
export function wrapInteractionHandler<T extends Function>(
fn: T,
element: React.ReactElement | null | string,