Add UI to select plugins

Summary: Adds UI to the select the plugin to export. It lists the plugins which has currently some data in the redux store and it also lists those plugins which has implemented `exportPersistedState` function, as it might happen that the redux store may not have the data for a plugin but it will still export the data by calling `exportPersistedState`, which will ping the mobile client to get the data at point while we export the flipper trace.

Reviewed By: jknoxville

Differential Revision: D16468408

fbshipit-source-id: 452a7caf7199dd2b8df330bbb10d0a90008e92ec
This commit is contained in:
Pritesh Nandgaonkar
2019-07-26 10:46:23 -07:00
committed by Facebook Github Bot
parent aa470a9aef
commit e7198040ea
11 changed files with 513 additions and 33 deletions

View File

@@ -0,0 +1,101 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import {Component, connect} from 'flipper';
import type {ShareType} from '../reducers/application.js';
import type {State as PluginState} from '../reducers/plugins.js';
import type {State as PluginStatesState} from '../reducers/pluginStates.js';
import type {ActiveSheet} from '../reducers/application.js';
import {selectedPlugins as actionForSelectedPlugins} from '../reducers/plugins.js';
import {getActivePersistentPlugins} from '../utils/pluginUtils';
import {
ACTIVE_SHEET_SHARE_DATA,
setActiveSheet as getActiveSheetAction,
setExportDataToFileActiveSheet as getExportDataToFileActiveSheetAction,
} from '../reducers/application.js';
import SelectPluginSheet from './SelectPluginSheet';
type OwnProps = {|
onHide: () => mixed,
|};
type Props = {|
...OwnProps,
share: ShareType,
plugins: PluginState,
pluginStates: PluginStatesState,
selectedPlugins: (payload: Array<string>) => void,
setActiveSheet: (payload: ActiveSheet) => void,
setExportDataToFileActiveSheet: (payload: string) => void,
|};
class ExportDataPluginSheet extends Component<Props, *> {
render() {
const {plugins, pluginStates, onHide} = this.props;
return (
<SelectPluginSheet
onSelect={selectedArray => {
this.props.selectedPlugins(selectedArray);
const {share} = this.props;
if (!share) {
console.error(
'applications.share is undefined, whereas it was expected to be defined',
);
} else {
switch (share.type) {
case 'link':
this.props.setActiveSheet(ACTIVE_SHEET_SHARE_DATA);
break;
case 'file': {
const file = share.file;
if (file) {
this.props.setExportDataToFileActiveSheet(file);
} else {
console.error('share.file is undefined');
}
}
}
}
}}
plugins={getActivePersistentPlugins(pluginStates, plugins).reduce(
(acc, plugin) => {
acc.set(
plugin,
plugins.selectedPlugins.length <= 0
? true
: plugins.selectedPlugins.includes(plugin),
);
return acc;
},
new Map(),
)}
onHide={onHide}
/>
);
}
}
export default connect<Props, OwnProps, _, _, _, _>(
({application: {share}, plugins, pluginStates}) => ({
share: share,
plugins,
pluginStates,
}),
dispatch => {
return {
selectedPlugins: (plugins: Array<string>) => {
dispatch(actionForSelectedPlugins(plugins));
},
setActiveSheet: (payload: ActiveSheet) => {
dispatch(getActiveSheetAction(payload));
},
setExportDataToFileActiveSheet: (payload: string) => {
dispatch(getExportDataToFileActiveSheetAction(payload));
},
};
},
)(ExportDataPluginSheet);

View File

@@ -0,0 +1,167 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import {
Component,
Text,
FlexColumn,
styled,
FlexRow,
Button,
Spacer,
Checkbox,
colors,
View,
} from 'flipper';
export type PluginSelection = Map<string, boolean>;
type Props = {|
onSelect: (plugins: Array<string>) => void,
onHide: () => mixed,
plugins: PluginSelection,
|};
const Title = styled(Text)({
margin: 6,
});
type State = {
plugins: PluginSelection,
};
const Container = styled(FlexColumn)({
padding: 8,
width: 700,
maxHeight: 700,
});
const Line = styled(View)({
backgroundColor: colors.greyTint2,
height: 1,
width: 'auto',
flexShrink: 0,
});
const PluginRowComponentContainer = styled(FlexColumn)({
overflow: 'scroll',
height: 'auto',
backgroundColor: colors.white,
maxHeight: 500,
});
const Padder = styled('div')(
({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({
paddingLeft: paddingLeft || 0,
paddingRight: paddingRight || 0,
paddingBottom: paddingBottom || 0,
paddingTop: paddingTop || 0,
}),
);
type PluginRowComponentProps = {
name: string,
selected: boolean,
onChange: (name: string, selected: boolean) => void,
};
class PluginRowComponent extends Component<PluginRowComponentProps> {
render() {
const {name, selected, onChange} = this.props;
return (
<FlexColumn>
<Padder
paddingRight={8}
paddingTop={8}
paddingBottom={8}
paddingLeft={8}>
<FlexRow>
<Text> {name} </Text>
<Spacer />
<Checkbox
checked={selected}
onChange={selected => {
onChange(name, selected);
}}
/>
</FlexRow>
</Padder>
<Line />
</FlexColumn>
);
}
}
export default class SelectPluginSheet extends Component<Props, State> {
state = {plugins: new Map()};
static getDerivedStateFromProps(props: Props, state: State) {
if (state.plugins.size > 0) {
return null;
}
return {plugins: props.plugins};
}
onSubmit(plugins: PluginSelection) {
const selectedArray = Array.from(plugins.entries()).reduce(
(acc, [plugin, selected]) => {
if (selected) {
acc.push(plugin);
}
return acc;
},
[],
);
this.props.onSelect(selectedArray);
}
render() {
const {onHide} = this.props;
const {plugins} = this.state;
return (
<Container>
<FlexColumn>
<Title>
Select the plugins for which you want to export the data
</Title>
<PluginRowComponentContainer>
{Array.from(plugins.entries()).map(
([pluginID: string, selected: boolean]) => {
return (
<PluginRowComponent
name={pluginID}
selected={selected}
onChange={(id: string, selected: boolean) => {
plugins.set(id, selected);
this.setState({plugins});
}}
/>
);
},
)}
</PluginRowComponentContainer>
</FlexColumn>
<Padder paddingTop={8} paddingBottom={2}>
<FlexRow>
<Spacer />
<Button
compact
padded
type={'success'}
onClick={() => {
this.onSubmit(this.state.plugins);
}}>
Submit
</Button>
<Button compact padded onClick={onHide}>
Close
</Button>
</FlexRow>
</Padder>
</Container>
);
}
}