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:
committed by
Facebook Github Bot
parent
aa470a9aef
commit
e7198040ea
@@ -21,7 +21,7 @@ import {listDevices} from '../src/utils/listDevices';
|
||||
// $FlowFixMe this file exist, trust me, flow!
|
||||
import setup from '../static/setup.js';
|
||||
import type {Store} from '../src/reducers';
|
||||
import {getActivePluginNames} from '../src/utils/pluginUtils.js';
|
||||
import {getPersistentPlugins} from '../src/utils/pluginUtils.js';
|
||||
import {serialize} from '../src/utils/serialization';
|
||||
import type BaseDevice from '../src/devices/BaseDevice';
|
||||
|
||||
@@ -360,7 +360,7 @@ async function startFlipper(userArguments: UserArguments) {
|
||||
return Promise.resolve({
|
||||
exit: true,
|
||||
result: await serialize(
|
||||
getActivePluginNames(store.getState().plugins),
|
||||
getPersistentPlugins(store.getState().plugins),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
22
src/App.js
22
src/App.js
@@ -16,6 +16,7 @@ import BugReporterDialog from './chrome/BugReporterDialog.js';
|
||||
import ErrorBar from './chrome/ErrorBar.js';
|
||||
import ShareSheet from './chrome/ShareSheet.js';
|
||||
import SignInSheet from './chrome/SignInSheet.js';
|
||||
import ExportDataPluginSheet from './chrome/ExportDataPluginSheet.js';
|
||||
import ShareSheetExportFile from './chrome/ShareSheetExportFile.js';
|
||||
import PluginContainer from './PluginContainer.js';
|
||||
import Sheet from './chrome/Sheet.js';
|
||||
@@ -27,14 +28,14 @@ import {
|
||||
ACTIVE_SHEET_SHARE_DATA,
|
||||
ACTIVE_SHEET_SIGN_IN,
|
||||
ACTIVE_SHEET_SHARE_DATA_IN_FILE,
|
||||
ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT,
|
||||
ACTIVE_SHEET_PLUGIN_SHEET,
|
||||
} from './reducers/application.js';
|
||||
|
||||
import type {ShareType} from './reducers/application.js';
|
||||
import type {Logger} from './fb-interfaces/Logger.js';
|
||||
import type BugReporter from './fb-stubs/BugReporter.js';
|
||||
import type BaseDevice from './devices/BaseDevice.js';
|
||||
import type {ActiveSheet} from './reducers/application.js';
|
||||
|
||||
const version = remote.app.getVersion();
|
||||
|
||||
type OwnProps = {|
|
||||
@@ -48,7 +49,7 @@ type Props = {|
|
||||
selectedDevice: ?BaseDevice,
|
||||
error: ?string,
|
||||
activeSheet: ActiveSheet,
|
||||
exportFile: ?string,
|
||||
share: ?ShareType,
|
||||
|};
|
||||
|
||||
export class App extends React.Component<Props> {
|
||||
@@ -68,7 +69,8 @@ export class App extends React.Component<Props> {
|
||||
}
|
||||
|
||||
getSheet = (onHide: () => mixed) => {
|
||||
switch (this.props.activeSheet) {
|
||||
const {activeSheet} = this.props;
|
||||
switch (activeSheet) {
|
||||
case ACTIVE_SHEET_BUG_REPORTER:
|
||||
return (
|
||||
<BugReporterDialog
|
||||
@@ -82,11 +84,17 @@ export class App extends React.Component<Props> {
|
||||
return <ShareSheet onHide={onHide} logger={this.props.logger} />;
|
||||
case ACTIVE_SHEET_SIGN_IN:
|
||||
return <SignInSheet onHide={onHide} />;
|
||||
case ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT:
|
||||
return <ExportDataPluginSheet onHide={onHide} />;
|
||||
case ACTIVE_SHEET_SHARE_DATA_IN_FILE:
|
||||
return (
|
||||
<ShareSheetExportFile
|
||||
onHide={onHide}
|
||||
file={this.props.exportFile}
|
||||
file={
|
||||
this.props.share && this.props.share.type === 'file'
|
||||
? this.props.share.file
|
||||
: undefined
|
||||
}
|
||||
logger={this.props.logger}
|
||||
/>
|
||||
);
|
||||
@@ -119,13 +127,13 @@ export class App extends React.Component<Props> {
|
||||
|
||||
export default connect<Props, OwnProps, _, _, _, _>(
|
||||
({
|
||||
application: {leftSidebarVisible, activeSheet, exportFile},
|
||||
application: {leftSidebarVisible, activeSheet, share},
|
||||
connections: {selectedDevice, error},
|
||||
}) => ({
|
||||
leftSidebarVisible,
|
||||
selectedDevice,
|
||||
activeSheet,
|
||||
exportFile,
|
||||
share: share,
|
||||
error,
|
||||
}),
|
||||
)(App);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {showOpenDialog} from './utils/exportData.js';
|
||||
import {
|
||||
setExportDataToFileActiveSheet,
|
||||
setActiveSheet,
|
||||
setSelectPluginsToExportActiveSheet,
|
||||
ACTIVE_SHEET_SHARE_DATA,
|
||||
} from './reducers/application';
|
||||
import type {Store} from './reducers/';
|
||||
@@ -201,7 +202,9 @@ function getTemplate(
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
store.dispatch(setExportDataToFileActiveSheet(file));
|
||||
store.dispatch(
|
||||
setSelectPluginsToExportActiveSheet({type: 'file', file: file}),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -212,7 +215,7 @@ function getTemplate(
|
||||
label: 'Sharable Link',
|
||||
accelerator: 'CommandOrControl+Shift+E',
|
||||
click: async function(item: Object, focusedWindow: Object) {
|
||||
store.dispatch(setActiveSheet(ACTIVE_SHEET_SHARE_DATA));
|
||||
store.dispatch(setSelectPluginsToExportActiveSheet({type: 'link'}));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ test('Empty app state matches snapshot', () => {
|
||||
selectedDevice={null}
|
||||
error={null}
|
||||
activeSheet={null}
|
||||
exportFile={null}
|
||||
share={null}
|
||||
/>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
101
src/chrome/ExportDataPluginSheet.js
Normal file
101
src/chrome/ExportDataPluginSheet.js
Normal 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);
|
||||
167
src/chrome/SelectPluginSheet.js
Normal file
167
src/chrome/SelectPluginSheet.js
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ export const ACTIVE_SHEET_PLUGIN_SHEET: 'PLUGIN_SHEET' = 'PLUGIN_SHEET';
|
||||
export const ACTIVE_SHEET_BUG_REPORTER: 'BUG_REPORTER' = 'BUG_REPORTER';
|
||||
export const ACTIVE_SHEET_PLUGIN_DEBUGGER: 'PLUGIN_DEBUGGER' =
|
||||
'PLUGIN_DEBUGGER';
|
||||
export const ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT: 'SELECT_PLUGINS_TO_EXPORT' =
|
||||
'SELECT_PLUGINS_TO_EXPORT';
|
||||
export const ACTIVE_SHEET_SHARE_DATA: 'SHARE_DATA' = 'SHARE_DATA';
|
||||
export const ACTIVE_SHEET_SIGN_IN: 'SIGN_IN' = 'SIGN_IN';
|
||||
export const ACTIVE_SHEET_SHARE_DATA_IN_FILE: 'SHARE_DATA_IN_FILE' =
|
||||
@@ -24,6 +26,7 @@ export type ActiveSheet =
|
||||
| typeof ACTIVE_SHEET_SHARE_DATA
|
||||
| typeof ACTIVE_SHEET_SIGN_IN
|
||||
| typeof ACTIVE_SHEET_SHARE_DATA_IN_FILE
|
||||
| typeof ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT
|
||||
| null;
|
||||
|
||||
export type LauncherMsg = {
|
||||
@@ -35,13 +38,20 @@ export type ServerPorts = {
|
||||
secure: number,
|
||||
};
|
||||
|
||||
export type ShareType =
|
||||
| {
|
||||
type: 'file',
|
||||
file: string,
|
||||
}
|
||||
| {type: 'link'};
|
||||
|
||||
export type State = {
|
||||
leftSidebarVisible: boolean,
|
||||
rightSidebarVisible: boolean,
|
||||
rightSidebarAvailable: boolean,
|
||||
windowIsFocused: boolean,
|
||||
activeSheet: ActiveSheet,
|
||||
exportFile: ?string,
|
||||
share: ?ShareType,
|
||||
sessionId: ?string,
|
||||
serverPorts: ServerPorts,
|
||||
downloadingImportData: boolean,
|
||||
@@ -69,6 +79,10 @@ export type Action =
|
||||
type: typeof ACTIVE_SHEET_SHARE_DATA_IN_FILE,
|
||||
payload: {file: string},
|
||||
}
|
||||
| {
|
||||
type: typeof ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT,
|
||||
payload: ShareType,
|
||||
}
|
||||
| {
|
||||
type: 'SET_SERVER_PORTS',
|
||||
payload: {
|
||||
@@ -96,7 +110,7 @@ const initialState: () => State = () => ({
|
||||
rightSidebarAvailable: false,
|
||||
windowIsFocused: remote.getCurrentWindow().isFocused(),
|
||||
activeSheet: null,
|
||||
exportFile: null,
|
||||
share: null,
|
||||
sessionId: uuidv1(),
|
||||
serverPorts: {
|
||||
insecure: 8089,
|
||||
@@ -142,7 +156,13 @@ export default function reducer(state: State, action: Action): State {
|
||||
return {
|
||||
...state,
|
||||
activeSheet: ACTIVE_SHEET_SHARE_DATA_IN_FILE,
|
||||
exportFile: action.payload.file,
|
||||
share: {type: 'file', file: action.payload.file},
|
||||
};
|
||||
} else if (action.type === ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT) {
|
||||
return {
|
||||
...state,
|
||||
activeSheet: ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT,
|
||||
share: action.payload,
|
||||
};
|
||||
} else if (action.type === 'SET_SERVER_PORTS') {
|
||||
return {
|
||||
@@ -172,6 +192,13 @@ export const toggleAction = (
|
||||
payload,
|
||||
});
|
||||
|
||||
export const setSelectPluginsToExportActiveSheet = (
|
||||
payload: ShareType,
|
||||
): Action => ({
|
||||
type: ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT,
|
||||
payload,
|
||||
});
|
||||
|
||||
export const setExportDataToFileActiveSheet = (file: string): Action => ({
|
||||
type: ACTIVE_SHEET_SHARE_DATA_IN_FILE,
|
||||
payload: {file},
|
||||
|
||||
@@ -94,16 +94,20 @@ export default function reducer(
|
||||
failedPlugins: state.failedPlugins.concat(action.payload),
|
||||
};
|
||||
} else if (action.type === 'SELECTED_PLUGINS') {
|
||||
const {selectedPlugins} = state;
|
||||
return {
|
||||
...state,
|
||||
selectedPlugins: selectedPlugins.concat(action.payload),
|
||||
selectedPlugins: action.payload,
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export const selectedPlugins = (payload: Array<string>): Action => ({
|
||||
type: 'SELECTED_PLUGINS',
|
||||
payload,
|
||||
});
|
||||
|
||||
export const registerPlugins = (payload: Array<P>): Action => ({
|
||||
type: 'REGISTER_PLUGINS',
|
||||
payload,
|
||||
|
||||
@@ -5,9 +5,39 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {getActivePluginNames} from '../pluginUtils';
|
||||
import {getPersistentPlugins, getActivePersistentPlugins} from '../pluginUtils';
|
||||
import type {State as PluginsState} from '../../reducers/plugins.js';
|
||||
import type {State as PluginStatesState} from '../../reducers/pluginStates.js';
|
||||
import type {PluginDefinition} from '../../dispatcher/plugins';
|
||||
import {FlipperBasePlugin} from '../../..';
|
||||
import type {MiddlewareAPI} from '../../reducers/index.js';
|
||||
class MockFlipperPluginWithDefaultPersistedState extends FlipperBasePlugin<
|
||||
*,
|
||||
*,
|
||||
{msg: string},
|
||||
> {
|
||||
static defaultPersistedState = {msg: 'MockFlipperPluginWithPersistedState'};
|
||||
}
|
||||
|
||||
class MockFlipperPluginWithExportPersistedState extends FlipperBasePlugin<
|
||||
*,
|
||||
*,
|
||||
{msg: string},
|
||||
> {
|
||||
static exportPersistedState = (
|
||||
callClient: (string, ?Object) => Promise<Object>,
|
||||
persistedState: ?{msg: string},
|
||||
store: ?MiddlewareAPI,
|
||||
): Promise<?{msg: string}> => {
|
||||
return Promise.resolve({msg: 'MockFlipperPluginWithExportPersistedState'});
|
||||
};
|
||||
}
|
||||
|
||||
class MockFlipperPluginWithNoPersistedState extends FlipperBasePlugin<
|
||||
*,
|
||||
*,
|
||||
*,
|
||||
> {}
|
||||
|
||||
function mockPluginState(
|
||||
gatekeepedPlugins: Array<PluginDefinition>,
|
||||
@@ -16,16 +46,16 @@ function mockPluginState(
|
||||
): PluginsState {
|
||||
return {
|
||||
devicePlugins: new Map([
|
||||
//$FlowFixMe: Class instance won't be used in the test
|
||||
['DevicePlugin1', undefined],
|
||||
//$FlowFixMe: Class instance won't be used in the test
|
||||
['DevicePlugin2', undefined],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
clientPlugins: new Map([
|
||||
//$FlowFixMe: Class instance won't be used in the test
|
||||
['ClientPlugin1', undefined],
|
||||
//$FlowFixMe: Class instance won't be used in the test
|
||||
['ClientPlugin2', undefined],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
gatekeepedPlugins,
|
||||
disabledPlugins,
|
||||
@@ -41,19 +71,19 @@ function mockPluginDefinition(name: string): PluginDefinition {
|
||||
};
|
||||
}
|
||||
|
||||
test('getActivePluginNames with the plugins getting excluded', () => {
|
||||
test('getPersistentPlugins with the plugins getting excluded', () => {
|
||||
const state = mockPluginState(
|
||||
[mockPluginDefinition('DevicePlugin1')],
|
||||
[mockPluginDefinition('ClientPlugin1')],
|
||||
[[mockPluginDefinition('DevicePlugin2'), 'DevicePlugin2']],
|
||||
);
|
||||
const list = getActivePluginNames(state);
|
||||
const list = getPersistentPlugins(state);
|
||||
expect(list).toEqual(['ClientPlugin2']);
|
||||
});
|
||||
|
||||
test('getActivePluginNames with the no plugins getting excluded', () => {
|
||||
test('getPersistentPlugins with no plugins getting excluded', () => {
|
||||
const state = mockPluginState([], [], []);
|
||||
const list = getActivePluginNames(state);
|
||||
const list = getPersistentPlugins(state);
|
||||
expect(list).toEqual([
|
||||
'ClientPlugin1',
|
||||
'ClientPlugin2',
|
||||
@@ -61,3 +91,110 @@ test('getActivePluginNames with the no plugins getting excluded', () => {
|
||||
'DevicePlugin2',
|
||||
]);
|
||||
});
|
||||
|
||||
test('getPersistentPlugins, where the plugins with exportPersistedState not getting excluded', () => {
|
||||
const state: PluginsState = {
|
||||
devicePlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin1', MockFlipperPluginWithExportPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin2', MockFlipperPluginWithExportPersistedState],
|
||||
]),
|
||||
clientPlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin1', MockFlipperPluginWithExportPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin2', MockFlipperPluginWithExportPersistedState],
|
||||
]),
|
||||
gatekeepedPlugins: [],
|
||||
disabledPlugins: [],
|
||||
failedPlugins: [],
|
||||
selectedPlugins: [],
|
||||
};
|
||||
const list = getPersistentPlugins(state);
|
||||
expect(list).toEqual([
|
||||
'ClientPlugin1',
|
||||
'ClientPlugin2',
|
||||
'DevicePlugin1',
|
||||
'DevicePlugin2',
|
||||
]);
|
||||
});
|
||||
|
||||
test('getPersistentPlugins, where the non persistent plugins getting excluded', () => {
|
||||
const state: PluginsState = {
|
||||
devicePlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin1', MockFlipperPluginWithNoPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
clientPlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin2', MockFlipperPluginWithNoPersistedState],
|
||||
]),
|
||||
gatekeepedPlugins: [],
|
||||
disabledPlugins: [],
|
||||
failedPlugins: [],
|
||||
selectedPlugins: [],
|
||||
};
|
||||
const list = getPersistentPlugins(state);
|
||||
expect(list).toEqual(['ClientPlugin1', 'DevicePlugin2']);
|
||||
});
|
||||
|
||||
test('getActivePersistentPlugins, where the non persistent plugins getting excluded', () => {
|
||||
const state: PluginsState = {
|
||||
devicePlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin1', MockFlipperPluginWithNoPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
clientPlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin2', MockFlipperPluginWithNoPersistedState],
|
||||
]),
|
||||
gatekeepedPlugins: [],
|
||||
disabledPlugins: [],
|
||||
failedPlugins: [],
|
||||
selectedPlugins: [],
|
||||
};
|
||||
const plugins: PluginStatesState = {
|
||||
'serial#app#DevicePlugin1': {msg: 'DevicePlugin1'},
|
||||
'serial#app#DevicePlugin2': {msg: 'DevicePlugin2'},
|
||||
'serial#app#ClientPlugin1': {msg: 'ClientPlugin1'},
|
||||
'serial#app#ClientPlugin2': {msg: 'ClientPlugin2'},
|
||||
};
|
||||
const list = getActivePersistentPlugins(plugins, state);
|
||||
expect(list).toEqual(['ClientPlugin1', 'DevicePlugin2']);
|
||||
});
|
||||
|
||||
test('getActivePersistentPlugins, where the plugins not in pluginState gets excluded', () => {
|
||||
const state: PluginsState = {
|
||||
devicePlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
clientPlugins: new Map([
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
||||
//$FlowFixMe: Just for testing
|
||||
['ClientPlugin2', MockFlipperPluginWithDefaultPersistedState],
|
||||
]),
|
||||
gatekeepedPlugins: [],
|
||||
disabledPlugins: [],
|
||||
failedPlugins: [],
|
||||
selectedPlugins: [],
|
||||
};
|
||||
const plugins: PluginStatesState = {
|
||||
'serial#app#DevicePlugin1': {msg: 'DevicePlugin1'},
|
||||
'serial#app#ClientPlugin2': {msg: 'ClientPlugin2'},
|
||||
};
|
||||
const list = getActivePersistentPlugins(plugins, state);
|
||||
expect(list).toEqual(['ClientPlugin2', 'DevicePlugin1']);
|
||||
});
|
||||
|
||||
@@ -62,6 +62,7 @@ type AddSaltToDeviceSerialOptions = {
|
||||
clients: Array<ClientExport>,
|
||||
pluginStates: PluginStatesState,
|
||||
pluginNotification: Array<PluginNotification>,
|
||||
selectedPlugins: Array<string>,
|
||||
statusUpdate?: (msg: string) => void,
|
||||
};
|
||||
|
||||
@@ -164,6 +165,7 @@ const addSaltToDeviceSerial = async (
|
||||
pluginStates,
|
||||
pluginNotification,
|
||||
statusUpdate,
|
||||
selectedPlugins,
|
||||
} = options;
|
||||
const {serial} = device;
|
||||
const newSerial = salt + '-' + serial;
|
||||
@@ -172,7 +174,7 @@ const addSaltToDeviceSerial = async (
|
||||
device.deviceType,
|
||||
device.title,
|
||||
device.os,
|
||||
device.getLogs(),
|
||||
selectedPlugins.includes('DeviceLogs') ? device.getLogs() : [],
|
||||
);
|
||||
statusUpdate &&
|
||||
statusUpdate('Adding salt to the selected device id in the client data...');
|
||||
@@ -278,6 +280,7 @@ export const processStore = async (
|
||||
pluginStates: processedPluginStates,
|
||||
pluginNotification: processedActiveNotifications,
|
||||
statusUpdate,
|
||||
selectedPlugins,
|
||||
});
|
||||
return exportFlipperData;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,26 @@ export function getPersistedState<PersistedState>(
|
||||
return persistedState;
|
||||
}
|
||||
|
||||
export function getActivePluginNames(plugins: PluginsState): Array<string> {
|
||||
export function getActivePersistentPlugins(
|
||||
pluginsState: PluginStatesState,
|
||||
plugins: PluginsState,
|
||||
): Array<string> {
|
||||
const pluginsMap: Map<
|
||||
string,
|
||||
Class<FlipperDevicePlugin<> | FlipperPlugin<>>,
|
||||
> = pluginsClassMap(plugins);
|
||||
return getPersistentPlugins(plugins).filter(plugin => {
|
||||
const pluginClass = pluginsMap.get(plugin);
|
||||
const keys = Object.keys(pluginsState).map(key => key.split('#').pop());
|
||||
return (
|
||||
(pluginClass && pluginClass.exportPersistedState != undefined) ||
|
||||
plugin == 'DeviceLogs' ||
|
||||
keys.includes(plugin)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function getPersistentPlugins(plugins: PluginsState): Array<string> {
|
||||
const pluginsMap: Map<
|
||||
string,
|
||||
Class<FlipperDevicePlugin<> | FlipperPlugin<>>,
|
||||
@@ -65,5 +84,16 @@ export function getActivePluginNames(plugins: PluginsState): Array<string> {
|
||||
pluginsMap.delete(plugin[0].name);
|
||||
}
|
||||
});
|
||||
return [...pluginsMap.keys()];
|
||||
|
||||
const activePlugins = [...pluginsMap.keys()];
|
||||
|
||||
return activePlugins.filter(plugin => {
|
||||
const pluginClass = pluginsMap.get(plugin);
|
||||
return (
|
||||
plugin == 'DeviceLogs' ||
|
||||
(pluginClass &&
|
||||
(pluginClass.defaultPersistedState != undefined ||
|
||||
pluginClass.exportPersistedState != undefined))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user