Add import/export left rail menu
Summary: See D32311662 for details Reviewed By: mweststrate Differential Revision: D32316987 fbshipit-source-id: c2d173f981cce1b148f463d981977e23258ffc02
This commit is contained in:
committed by
Facebook GitHub Bot
parent
32f722264f
commit
2591d1629e
@@ -376,7 +376,7 @@ function getTemplate(
|
||||
{
|
||||
label: 'Trigger deeplink...',
|
||||
click() {
|
||||
openDeeplinkDialog(store, logger);
|
||||
openDeeplinkDialog(store);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import {Group, SUPPORTED_GROUPS} from './reducers/supportForm';
|
||||
import {Logger} from 'flipper-common';
|
||||
import {getLogger, Logger} from 'flipper-common';
|
||||
import {Store} from './reducers/index';
|
||||
import {importDataToStore} from './utils/exportData';
|
||||
import {selectPlugin, getAllClients} from './reducers/connections';
|
||||
@@ -150,13 +150,13 @@ export const uriComponents = (url: string): Array<string> => {
|
||||
return [];
|
||||
};
|
||||
|
||||
export function openDeeplinkDialog(store: Store, logger: Logger) {
|
||||
export function openDeeplinkDialog(store: Store) {
|
||||
Dialog.prompt({
|
||||
title: 'Open deeplink',
|
||||
message: 'Enter a deeplink:',
|
||||
defaultValue: 'flipper://',
|
||||
onConfirm: async (deeplink) => {
|
||||
await handleDeeplink(store, logger, deeplink);
|
||||
await handleDeeplink(store, getLogger(), deeplink);
|
||||
return deeplink;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import React, {cloneElement, useState, useCallback, useMemo} from 'react';
|
||||
import {Button, Divider, Badge, Tooltip, Avatar, Popover} from 'antd';
|
||||
import {Button, Divider, Badge, Tooltip, Avatar, Popover, Menu} from 'antd';
|
||||
import {
|
||||
MobileFilled,
|
||||
AppstoreOutlined,
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
QuestionCircleOutlined,
|
||||
MedicineBoxOutlined,
|
||||
RocketOutlined,
|
||||
SwapOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {SidebarLeft, SidebarRight} from './SandyIcons';
|
||||
import {useDispatch, useStore} from '../utils/useStore';
|
||||
@@ -27,7 +28,13 @@ import {
|
||||
toggleLeftSidebarVisible,
|
||||
toggleRightSidebarVisible,
|
||||
} from '../reducers/application';
|
||||
import {theme, Layout, withTrackingScope, Dialog} from 'flipper-plugin';
|
||||
import {
|
||||
theme,
|
||||
Layout,
|
||||
withTrackingScope,
|
||||
Dialog,
|
||||
useTrackedCallback,
|
||||
} from 'flipper-plugin';
|
||||
import SetupDoctorScreen, {checkHasNewProblem} from './SetupDoctorScreen';
|
||||
import SettingsSheet from '../chrome/SettingsSheet';
|
||||
import WelcomeScreen from './WelcomeScreen';
|
||||
@@ -50,6 +57,17 @@ import FpsGraph from '../chrome/FpsGraph';
|
||||
import UpdateIndicator from '../chrome/UpdateIndicator';
|
||||
import PluginManager from '../chrome/plugin-manager/PluginManager';
|
||||
import {showLoginDialog} from '../chrome/fb-stubs/SignInSheet';
|
||||
import SubMenu from 'antd/lib/menu/SubMenu';
|
||||
import constants from '../fb-stubs/constants';
|
||||
import {
|
||||
canFileExport,
|
||||
canOpenDialog,
|
||||
showOpenDialog,
|
||||
startFileExport,
|
||||
startLinkExport,
|
||||
} from '../utils/exportData';
|
||||
import {openDeeplinkDialog} from '../deeplink';
|
||||
import {css} from '@emotion/css';
|
||||
|
||||
const LeftRailButtonElem = styled(Button)<{kind?: 'small'}>(({kind}) => ({
|
||||
width: kind === 'small' ? 32 : 36,
|
||||
@@ -76,7 +94,7 @@ export function LeftRailButton({
|
||||
selected?: boolean;
|
||||
disabled?: boolean;
|
||||
count?: number | true;
|
||||
title: string;
|
||||
title?: string;
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
}) {
|
||||
let iconElement =
|
||||
@@ -89,22 +107,31 @@ export function LeftRailButton({
|
||||
<Badge count={count}>{iconElement}</Badge>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip title={title} placement="right">
|
||||
<LeftRailButtonElem
|
||||
title={title}
|
||||
kind={small ? 'small' : undefined}
|
||||
type={selected ? 'primary' : 'ghost'}
|
||||
icon={iconElement}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
style={{
|
||||
color: toggled ? theme.primaryColor : undefined,
|
||||
background: toggled ? theme.backgroundWash : undefined,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
let res = (
|
||||
<LeftRailButtonElem
|
||||
title={title}
|
||||
kind={small ? 'small' : undefined}
|
||||
type={selected ? 'primary' : 'ghost'}
|
||||
icon={iconElement}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
style={{
|
||||
color: toggled ? theme.primaryColor : undefined,
|
||||
background: toggled ? theme.backgroundWash : undefined,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
if (title) {
|
||||
res = (
|
||||
<Tooltip title={title} placement="right">
|
||||
{res}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const LeftRailDivider = styled(Divider)({
|
||||
@@ -163,6 +190,7 @@ export const LeftRail = withTrackingScope(function LeftRail({
|
||||
<SupportFormButton />
|
||||
<RightSidebarToggleButton />
|
||||
<LeftSidebarToggleButton />
|
||||
<ImportExportButton />
|
||||
{config.showLogin && <LoginButton />}
|
||||
</Layout.Container>
|
||||
</Layout.Bottom>
|
||||
@@ -170,6 +198,72 @@ export const LeftRail = withTrackingScope(function LeftRail({
|
||||
);
|
||||
});
|
||||
|
||||
const menu = css`
|
||||
border: none;
|
||||
`;
|
||||
const submenu = css`
|
||||
.ant-menu-submenu-title {
|
||||
width: 32px;
|
||||
height: 32px !important;
|
||||
line-height: 32px !important;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.ant-menu-submenu-arrow {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
function ImportExportButton() {
|
||||
const store = useStore();
|
||||
|
||||
const startFileExportTracked = useTrackedCallback(
|
||||
'File export',
|
||||
() => startFileExport(store.dispatch),
|
||||
[store.dispatch],
|
||||
);
|
||||
const startLinkExportTracked = useTrackedCallback(
|
||||
'Link export',
|
||||
() => startLinkExport(store.dispatch),
|
||||
[store.dispatch],
|
||||
);
|
||||
const startImportTracked = useTrackedCallback(
|
||||
'File import',
|
||||
() => showOpenDialog(store),
|
||||
[store],
|
||||
);
|
||||
|
||||
return (
|
||||
<Menu mode="vertical" className={menu}>
|
||||
<SubMenu
|
||||
popupOffset={[10, 0]}
|
||||
key="importexport"
|
||||
title={<LeftRailButton icon={<SwapOutlined />} small />}
|
||||
className={submenu}>
|
||||
{canFileExport() ? (
|
||||
<Menu.Item key="exportFile" onClick={startFileExportTracked}>
|
||||
Export file
|
||||
</Menu.Item>
|
||||
) : null}
|
||||
{constants.ENABLE_SHAREABLE_LINK ? (
|
||||
<Menu.Item key="exportShareableLink" onClick={startLinkExportTracked}>
|
||||
Export shareable link
|
||||
</Menu.Item>
|
||||
) : null}
|
||||
{canOpenDialog() ? (
|
||||
<Menu.Item key="importFlipperFile" onClick={startImportTracked}>
|
||||
Import Flipper file
|
||||
</Menu.Item>
|
||||
) : null}
|
||||
<Menu.Item
|
||||
key="triggerDeeplink"
|
||||
onClick={() => openDeeplinkDialog(store)}>
|
||||
Trigger deeplink
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
function LeftSidebarToggleButton() {
|
||||
const dispatch = useDispatch();
|
||||
const mainMenuVisible = useStore(
|
||||
|
||||
@@ -599,6 +599,10 @@ export const importFileToStore = (file: string, store: Store) => {
|
||||
});
|
||||
};
|
||||
|
||||
export function canOpenDialog() {
|
||||
return !!getRenderHostInstance().showOpenDialog;
|
||||
}
|
||||
|
||||
export function showOpenDialog(store: Store) {
|
||||
return getRenderHostInstance()
|
||||
.showOpenDialog?.({
|
||||
@@ -613,6 +617,10 @@ export function showOpenDialog(store: Store) {
|
||||
});
|
||||
}
|
||||
|
||||
export function canFileExport() {
|
||||
return !!getRenderHostInstance().showSaveDialog;
|
||||
}
|
||||
|
||||
export async function startFileExport(dispatch: Store['dispatch']) {
|
||||
const file = await getRenderHostInstance().showSaveDialog?.({
|
||||
title: 'FlipperExport',
|
||||
|
||||
Reference in New Issue
Block a user