From a5631c8d9fcab57ddd2101cfdd684180e49f8180 Mon Sep 17 00:00:00 2001 From: Anton Kastritskiy Date: Tue, 18 Jul 2023 03:52:34 -0700 Subject: [PATCH] remove LeftRail Reviewed By: elboman Differential Revision: D47441161 fbshipit-source-id: f0c792beb64fc2474bf6e72b4e4a69d40b699c1e --- .../src/chrome/RatingButton.tsx | 359 ------------------ .../src/sandy-chrome/LeftRail.tsx | 238 ------------ .../src/sandy-chrome/Navbar.tsx | 149 +++++++- .../src/sandy-chrome/SandyApp.tsx | 8 +- 4 files changed, 149 insertions(+), 605 deletions(-) delete mode 100644 desktop/flipper-ui-core/src/chrome/RatingButton.tsx delete mode 100644 desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx diff --git a/desktop/flipper-ui-core/src/chrome/RatingButton.tsx b/desktop/flipper-ui-core/src/chrome/RatingButton.tsx deleted file mode 100644 index a36d20ff6..000000000 --- a/desktop/flipper-ui-core/src/chrome/RatingButton.tsx +++ /dev/null @@ -1,359 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -import React, { - Component, - ReactElement, - useCallback, - useEffect, - useState, -} from 'react'; -import { - FlexColumn, - FlexRow, - Button, - Checkbox, - styled, - Input, - Link, -} from '../ui'; -import {LeftRailButton} from '../sandy-chrome/LeftRail'; -import * as UserFeedback from '../fb-stubs/UserFeedback'; -import {FeedbackPrompt} from '../fb-stubs/UserFeedback'; -import {StarOutlined} from '@ant-design/icons'; -import {Popover, Rate} from 'antd'; -import {useStore} from '../utils/useStore'; -import {currentUser} from '../fb-stubs/user'; -import {theme, useValue} from 'flipper-plugin'; -import {reportPlatformFailures} from 'flipper-common'; -import {getRenderHostInstance} from 'flipper-frontend-core'; - -type NextAction = 'select-rating' | 'leave-comment' | 'finished'; - -class PredefinedComment extends Component<{ - comment: string; - selected: boolean; - onClick: (_: unknown) => unknown; -}> { - static Container = styled.div<{selected: boolean}>((props) => { - return { - border: '1px solid #f2f3f5', - cursor: 'pointer', - borderRadius: 24, - backgroundColor: props.selected ? '#ecf3ff' : '#f2f3f5', - marginBottom: 4, - marginRight: 4, - padding: '4px 8px', - color: props.selected ? 'rgb(56, 88, 152)' : undefined, - borderColor: props.selected ? '#3578e5' : undefined, - ':hover': { - borderColor: '#3578e5', - }, - }; - }); - render() { - return ( - - {this.props.comment} - - ); - } -} - -const Row = styled(FlexRow)({ - marginTop: 5, - marginBottom: 5, - justifyContent: 'center', - textAlign: 'center', - color: '#9a9a9a', - flexWrap: 'wrap', -}); - -const DismissRow = styled(Row)({ - marginBottom: 0, - marginTop: 10, -}); - -const DismissButton = styled.span({ - '&:hover': { - textDecoration: 'underline', - cursor: 'pointer', - }, -}); - -const Spacer = styled(FlexColumn)({ - flexGrow: 1, -}); - -function dismissRow(dismiss: () => void) { - return ( - - - Dismiss - - - ); -} - -type FeedbackComponentState = { - rating: number | null; - hoveredRating: number; - allowUserInfoSharing: boolean; - nextAction: NextAction; - predefinedComments: {[key: string]: boolean}; - comment: string; -}; - -class FeedbackComponent extends Component< - { - submitRating: (rating: number) => void; - submitComment: ( - rating: number, - comment: string, - selectedPredefinedComments: Array, - allowUserInfoSharing: boolean, - ) => void; - close: () => void; - dismiss: () => void; - promptData: FeedbackPrompt; - }, - FeedbackComponentState -> { - state: FeedbackComponentState = { - rating: null, - hoveredRating: 0, - allowUserInfoSharing: true, - nextAction: 'select-rating' as NextAction, - predefinedComments: this.props.promptData.predefinedComments.reduce( - (acc, cv) => ({...acc, [cv]: false}), - {}, - ), - comment: '', - }; - onSubmitRating(newRating: number) { - const nextAction = newRating <= 2 ? 'leave-comment' : 'finished'; - this.setState({rating: newRating, nextAction: nextAction}); - this.props.submitRating(newRating); - if (nextAction === 'finished') { - setTimeout(this.props.close, 5000); - } - } - onCommentSubmitted(comment: string) { - this.setState({nextAction: 'finished'}); - const selectedPredefinedComments: Array = Object.entries( - this.state.predefinedComments, - ) - .map((x) => ({comment: x[0], enabled: x[1]})) - .filter((x) => x.enabled) - .map((x) => x.comment); - const currentRating = this.state.rating; - if (currentRating) { - this.props.submitComment( - currentRating, - comment, - selectedPredefinedComments, - this.state.allowUserInfoSharing, - ); - } else { - console.error('Illegal state: Submitting comment with no rating set.'); - } - setTimeout(this.props.close, 1000); - } - onAllowUserSharingChanged(allowed: boolean) { - this.setState({allowUserInfoSharing: allowed}); - } - render() { - let body: Array; - switch (this.state.nextAction) { - case 'select-rating': - body = [ - {this.props.promptData.bodyText}, - - this.onSubmitRating(newRating)} /> - , - dismissRow(this.props.dismiss), - ]; - break; - case 'leave-comment': - const predefinedComments = Object.entries( - this.state.predefinedComments, - ).map((c: [string, unknown], idx: number) => ( - - this.setState({ - predefinedComments: { - ...this.state.predefinedComments, - [c[0]]: !c[1], - }, - }) - } - /> - )); - body = [ - {predefinedComments}, - - this.setState({comment: e.target.value})} - onKeyDown={(e) => - e.key == 'Enter' && this.onCommentSubmitted(this.state.comment) - } - autoFocus - /> - , - - - {'Tool owner can contact me '} - , - - - , - dismissRow(this.props.dismiss), - ]; - break; - case 'finished': - body = [ - - Thanks for the feedback! You can now help - - prioritize bugs and features for Flipper in Papercuts - - , - dismissRow(this.props.dismiss), - ]; - break; - default: { - console.error('Illegal state: nextAction: ' + this.state.nextAction); - return null; - } - } - return ( - - - {this.state.nextAction === 'finished' - ? this.props.promptData.postSubmitHeading - : this.props.promptData.preSubmitHeading} - - {body} - - ); - } -} - -export function SandyRatingButton() { - const [promptData, setPromptData] = - useState(null); - const [isShown, setIsShown] = useState(false); - const [hasTriggered, setHasTriggered] = useState(false); - const sessionId = useStore((store) => store.application.sessionId); - const loggedIn = useValue(currentUser()); - - const triggerPopover = useCallback(() => { - if (!hasTriggered) { - setIsShown(true); - setHasTriggered(true); - } - }, [hasTriggered]); - - useEffect(() => { - if ( - getRenderHostInstance().GK('flipper_enable_star_ratiings') && - !hasTriggered && - loggedIn - ) { - reportPlatformFailures( - UserFeedback.getPrompt().then((prompt) => { - setPromptData(prompt); - setTimeout(triggerPopover, 30000); - }), - 'RatingButton:getPrompt', - ).catch((e) => { - console.warn('Failed to load ratings prompt:', e); - }); - } - }, [triggerPopover, hasTriggered, loggedIn]); - - const onClick = () => { - const willBeShown = !isShown; - setIsShown(willBeShown); - setHasTriggered(true); - if (!willBeShown) { - UserFeedback.dismiss(sessionId); - } - }; - - const submitRating = (rating: number) => { - UserFeedback.submitRating(rating, sessionId); - }; - - const submitComment = ( - rating: number, - comment: string, - selectedPredefinedComments: Array, - allowUserInfoSharing: boolean, - ) => { - UserFeedback.submitComment( - rating, - comment, - selectedPredefinedComments, - allowUserInfoSharing, - sessionId, - ); - }; - - if (!promptData) { - return null; - } - if (!promptData.shouldPopup || (hasTriggered && !isShown)) { - return null; - } - return ( - { - setIsShown(false); - }} - dismiss={onClick} - promptData={promptData} - /> - } - placement="right" - trigger="click"> - } - title="Rate Flipper" - onClick={onClick} - small - /> - - ); -} diff --git a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx b/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx deleted file mode 100644 index 91faf40c7..000000000 --- a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx +++ /dev/null @@ -1,238 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -import React, {cloneElement, useState, useCallback} from 'react'; -import {Button, Divider, Badge, Tooltip, Menu} from 'antd'; -import {SettingOutlined} from '@ant-design/icons'; -import {useStore} from '../utils/useStore'; -import { - theme, - withTrackingScope, - useTrackedCallback, - NUX, -} from 'flipper-plugin'; -import SettingsSheet from '../chrome/SettingsSheet'; -import WelcomeScreen from './WelcomeScreen'; -import styled from '@emotion/styled'; -import {setStaticView} from '../reducers/connections'; -import constants from '../fb-stubs/constants'; -import { - canFileExport, - canOpenDialog, - showOpenDialog, - startFileExport, - startLinkExport, -} from '../utils/exportData'; -import {openDeeplinkDialog} from '../deeplink'; -import {css} from '@emotion/css'; -import {getRenderHostInstance} from 'flipper-frontend-core'; -import {StyleGuide} from './StyleGuide'; - -const LeftRailButtonElem = styled(Button)<{kind?: 'small'}>(({kind}) => ({ - width: kind === 'small' ? 32 : 36, - height: kind === 'small' ? 32 : 36, - padding: '5px 0', - border: 'none', - boxShadow: 'none', -})); -LeftRailButtonElem.displayName = 'LeftRailButtonElem'; - -export function LeftRailButton({ - icon, - small, - selected, - toggled, - count, - title, - onClick, - disabled, -}: { - icon?: React.ReactElement; - small?: boolean; - toggled?: boolean; - selected?: boolean; - disabled?: boolean; - count?: number | true; - title?: string; - onClick?: React.MouseEventHandler; -}) { - const iconElement = - icon && cloneElement(icon, {style: {fontSize: small ? 16 : 24}}); - - let res = ( - - ); - - if (count !== undefined) { - res = - count === true ? ( - - {res} - - ) : ( - - {res} - - ); - } - - if (title) { - res = ( - - {res} - - ); - } - - return res; -} - -const LeftRailDivider = styled(Divider)({ - margin: `10px 0`, - width: 32, - minWidth: 32, -}); -LeftRailDivider.displayName = 'LeftRailDividier'; - -export const LeftRail = withTrackingScope(function LeftRail() { - return ; -}); - -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 ExtrasMenu() { - 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], - ); - - const [showSettings, setShowSettings] = useState(false); - const onSettingsClose = useCallback(() => setShowSettings(false), []); - - const settings = useStore((state) => state.settingsState); - const {showWelcomeAtStartup} = settings; - const [welcomeVisible, setWelcomeVisible] = useState(showWelcomeAtStartup); - - return ( - <> - - - } small />} - className={submenu}> - {canOpenDialog() ? ( - - Import Flipper file - - ) : null} - {canFileExport() ? ( - - Export Flipper file - - ) : null} - {constants.ENABLE_SHAREABLE_LINK ? ( - - Export shareable link - - ) : null} - - - { - store.dispatch(setStaticView(StyleGuide)); - }}> - Flipper Style Guide - - openDeeplinkDialog(store)}> - Trigger deeplink - - - - setShowSettings(true)}> - Settings - - setWelcomeVisible(true)}> - Help - - - - - {showSettings && ( - - )} - setWelcomeVisible(false)} - showAtStartup={showWelcomeAtStartup} - onCheck={(value) => - store.dispatch({ - type: 'UPDATE_SETTINGS', - payload: {...settings, showWelcomeAtStartup: value}, - }) - } - /> - - ); -} diff --git a/desktop/flipper-ui-core/src/sandy-chrome/Navbar.tsx b/desktop/flipper-ui-core/src/sandy-chrome/Navbar.tsx index af23b3adb..0192c2063 100644 --- a/desktop/flipper-ui-core/src/sandy-chrome/Navbar.tsx +++ b/desktop/flipper-ui-core/src/sandy-chrome/Navbar.tsx @@ -30,21 +30,20 @@ import {useDispatch, useStore} from '../utils/useStore'; import config from '../fb-stubs/config'; import {isConnected, currentUser, logoutUser} from '../fb-stubs/user'; import {showLoginDialog} from '../chrome/fb-stubs/SignInSheet'; -import {Avatar, Badge, Button, Modal, Popover, Tooltip} from 'antd'; +import {Avatar, Badge, Button, Menu, Modal, Popover, Tooltip} from 'antd'; import { ApiOutlined, AppstoreAddOutlined, BellOutlined, BugOutlined, CameraOutlined, - EllipsisOutlined, FileExclamationOutlined, LayoutOutlined, LoginOutlined, MedicineBoxOutlined, MobileOutlined, - QuestionCircleOutlined, RocketOutlined, + SettingOutlined, VideoCameraOutlined, WarningOutlined, } from '@ant-design/icons'; @@ -62,10 +61,22 @@ import NetworkGraph from '../chrome/NetworkGraph'; import {errorCounterAtom} from '../chrome/ConsoleLogs'; import {filterNotifications} from './notification/notificationUtils'; import { + canFileExport, + canOpenDialog, exportEverythingEverywhereAllAtOnce, ExportEverythingEverywhereAllAtOnceStatus, + showOpenDialog, + startFileExport, + startLinkExport, } from '../utils/exportData'; +import UpdateIndicator from '../chrome/UpdateIndicator'; import {css} from '@emotion/css'; +import constants from '../fb-stubs/constants'; +import {setStaticView} from '../reducers/connections'; +import {StyleGuide} from './StyleGuide'; +import {openDeeplinkDialog} from '../deeplink'; +import SettingsSheet from '../chrome/SettingsSheet'; +import WelcomeScreen from './WelcomeScreen'; export const Navbar = withTrackingScope(function Navbar({ toplevelSelection, @@ -126,12 +137,12 @@ export const Navbar = withTrackingScope(function Navbar({ toplevelSelection={toplevelSelection} setToplevelSelection={setToplevelSelection} /> + - - {config.showLogin && } + ); @@ -607,3 +618,131 @@ export function LeftRailButton({ return res; } + +const menu = css` + border: none; + height: 56px; + + .ant-menu-submenu-title { + hieght: 56px; + } +`; +const submenu = css` + height: 56px; + + .ant-menu-submenu-title { + width: 61px !important; + height: 56px !important; + padding: 0; + margin: 0; + } + .ant-menu-submenu-arrow { + display: none; + } +`; + +function ExtrasMenu() { + 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], + ); + + const [showSettings, setShowSettings] = useState(false); + const onSettingsClose = useCallback(() => setShowSettings(false), []); + + const settings = useStore((state) => state.settingsState); + const {showWelcomeAtStartup} = settings; + const [welcomeVisible, setWelcomeVisible] = useState(showWelcomeAtStartup); + + return ( + <> + + + } + className={submenu}> + {canOpenDialog() ? ( + + Import Flipper file + + ) : null} + {canFileExport() ? ( + + Export Flipper file + + ) : null} + {constants.ENABLE_SHAREABLE_LINK ? ( + + Export shareable link + + ) : null} + + + { + store.dispatch(setStaticView(StyleGuide)); + }}> + Flipper Style Guide + + openDeeplinkDialog(store)}> + Trigger deeplink + + + + setShowSettings(true)}> + Settings + + setWelcomeVisible(true)}> + Help + + + + + {showSettings && ( + + )} + setWelcomeVisible(false)} + showAtStartup={showWelcomeAtStartup} + onCheck={(value) => + store.dispatch({ + type: 'UPDATE_SETTINGS', + payload: {...settings, showWelcomeAtStartup: value}, + }) + } + /> + + ); +} diff --git a/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx b/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx index f370a2e97..1d8a11589 100644 --- a/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx +++ b/desktop/flipper-ui-core/src/sandy-chrome/SandyApp.tsx @@ -21,7 +21,6 @@ import {theme} from 'flipper-plugin'; import {Logger} from 'flipper-common'; import {Navbar} from './Navbar'; -import {LeftRail} from './LeftRail'; import {useStore, useDispatch} from '../utils/useStore'; import {FlipperDevTools} from '../chrome/FlipperDevTools'; import {setStaticView} from '../reducers/connections'; @@ -173,9 +172,12 @@ export function SandyApp() { toplevelSelection={toplevelSelection} setToplevelSelection={setToplevelSelection} /> - + - <_Sidebar width={250} minWidth={220} maxWidth={800} gutter> {leftMenuContent && (