Yarn workspaces

Summary:
1) moved "sonar/desktop/src" to "sonar/desktop/app/src", so "app" is now a separate package containing the core Flipper app code
2) Configured yarn workspaces with the root in "sonar/desktop": app, static, pkg, doctor, headless-tests. Plugins are not included for now, I plan to do this later.

Reviewed By: jknoxville

Differential Revision: D20535782

fbshipit-source-id: 600b2301960f37c7d72166e0d04eba462bec9fc1
This commit is contained in:
Anton Nikolaev
2020-03-20 13:31:37 -07:00
committed by Facebook GitHub Bot
parent 676d7bbd24
commit 863f89351e
340 changed files with 1635 additions and 294 deletions

View File

@@ -0,0 +1,230 @@
/**
* Copyright (c) Facebook, Inc. and its 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 {FlexColumn, Button, styled, Text, FlexRow, Spacer} from 'flipper';
import React, {Component} from 'react';
import {setExportStatusComponent, unsetShare} from '../reducers/application';
import {reportPlatformFailures} from '../utils/metrics';
import CancellableExportStatus from './CancellableExportStatus';
import {performance} from 'perf_hooks';
import {Logger} from '../fb-interfaces/Logger';
import {Idler} from '../utils/Idler';
import {
exportStoreToFile,
EXPORT_FLIPPER_TRACE_EVENT,
} from '../utils/exportData';
import ShareSheetErrorList from './ShareSheetErrorList';
import ShareSheetPendingDialog from './ShareSheetPendingDialog';
import {ReactReduxContext} from 'react-redux';
import {MiddlewareAPI} from '../reducers/index';
const Container = styled(FlexColumn)({
padding: 20,
width: 500,
});
const ErrorMessage = styled(Text)({
display: 'block',
marginTop: 6,
wordBreak: 'break-all',
whiteSpace: 'pre-line',
lineHeight: 1.35,
});
const Title = styled(Text)({
marginBottom: 6,
});
const InfoText = styled(Text)({
lineHeight: 1.35,
marginBottom: 15,
});
type Props = {
onHide: () => void;
file: string;
logger: Logger;
};
type State = {
errorArray: Array<Error>;
result:
| {
kind: 'success';
}
| {
kind: 'error';
error: Error;
}
| {
kind: 'pending';
};
statusUpdate: string | null;
runInBackground: boolean;
};
export default class ShareSheetExportFile extends Component<Props, State> {
static contextType = ReactReduxContext;
get store(): MiddlewareAPI {
return this.context.store;
}
state: State = {
errorArray: [],
result: {kind: 'pending'},
statusUpdate: null,
runInBackground: false,
};
idler = new Idler();
dispatchAndUpdateToolBarStatus(msg: string) {
this.store.dispatch(
setExportStatusComponent(
<CancellableExportStatus
msg={msg}
onCancel={() => {
this.idler.cancel();
this.store.dispatch(unsetShare());
}}
/>,
),
);
}
async componentDidMount() {
const mark = 'shareSheetExportFile';
performance.mark(mark);
try {
if (!this.props.file) {
return;
}
const {errorArray} = await reportPlatformFailures(
exportStoreToFile(
this.props.file,
this.store,
false,
this.idler,
(msg: string) => {
if (this.state.runInBackground) {
this.dispatchAndUpdateToolBarStatus(msg);
} else {
this.setState({statusUpdate: msg});
}
},
),
`${EXPORT_FLIPPER_TRACE_EVENT}:UI_FILE`,
);
this.store.dispatch(unsetShare());
if (this.state.runInBackground) {
new Notification('Sharable Flipper trace created', {
body: `Flipper trace exported to the ${this.props.file}`,
requireInteraction: true,
});
return;
}
this.setState({errorArray, result: {kind: 'success'}});
this.props.logger.trackTimeSince(mark, 'export:file-success');
} catch (err) {
if (!this.state.runInBackground) {
this.setState({errorArray: [], result: {kind: 'error', error: err}});
}
this.props.logger.trackTimeSince(mark, 'export:file-error');
throw err;
}
}
renderSuccess() {
return (
<ReactReduxContext.Consumer>
{({store}) => (
<Container>
<FlexColumn>
<Title bold>Data Exported Successfully</Title>
<InfoText>
When sharing your Flipper data, consider that the captured data
might contain sensitive information like access tokens used in
network requests.
</InfoText>
<ShareSheetErrorList errors={this.state.errorArray} />
</FlexColumn>
<FlexRow>
<Spacer />
<Button compact padded onClick={() => this.cancelAndHide(store)}>
Close
</Button>
</FlexRow>
</Container>
)}
</ReactReduxContext.Consumer>
);
}
renderError(result: {kind: 'error'; error: Error}) {
return (
<ReactReduxContext.Consumer>
{({store}) => (
<Container>
<Title bold>Error</Title>
<ErrorMessage code>
{result.error.message || 'File could not be saved.'}
</ErrorMessage>
<FlexRow>
<Spacer />
<Button compact padded onClick={() => this.cancelAndHide(store)}>
Close
</Button>
</FlexRow>
</Container>
)}
</ReactReduxContext.Consumer>
);
}
renderPending(statusUpdate: string | null) {
return (
<ReactReduxContext.Consumer>
{({store}) => (
<ShareSheetPendingDialog
width={500}
statusUpdate={statusUpdate}
statusMessage="Exporting Flipper trace..."
onCancel={() => this.cancelAndHide(store)}
onRunInBackground={() => {
this.setState({runInBackground: true});
if (statusUpdate) {
this.dispatchAndUpdateToolBarStatus(statusUpdate);
}
this.props.onHide();
}}
/>
)}
</ReactReduxContext.Consumer>
);
}
cancelAndHide(store: MiddlewareAPI) {
store.dispatch(unsetShare());
this.props.onHide();
this.idler.cancel();
}
render() {
const {result, statusUpdate} = this.state;
switch (result.kind) {
case 'success':
return this.renderSuccess();
case 'error':
return this.renderError(result);
case 'pending':
return this.renderPending(statusUpdate);
}
}
}