Make sure plugin name selections are displayed consistently with sidebar, [Flipper] Make sure plugins have the same name everywhere
Summary: Not all plugin names are created equal in flipper. For example, plugins would bear different names in the sidebar and in the plugin selection when making a support request / flipper trace. Fixed this and also introduced a `getPluginTitle` utility that produces this name consistently. Plugin listview now also sort their items consitently with the sidebar. Probably also fixed an error in the flipper export screen, where a correct TS error was supressed. Reviewed By: jknoxville Differential Revision: D19499404 fbshipit-source-id: c5b23a170d41d96799eb7899e249f70778717d45
This commit is contained in:
committed by
Facebook Github Bot
parent
edd0e01a08
commit
82e65c68dc
@@ -34,6 +34,7 @@ import {selectPlugin} from './reducers/connections';
|
|||||||
import {State as StoreState} from './reducers/index';
|
import {State as StoreState} from './reducers/index';
|
||||||
import textContent from './utils/textContent';
|
import textContent from './utils/textContent';
|
||||||
import createPaste from './fb-stubs/createPaste';
|
import createPaste from './fb-stubs/createPaste';
|
||||||
|
import {getPluginTitle} from './utils/pluginUtils';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
onClear: () => void;
|
onClear: () => void;
|
||||||
@@ -429,7 +430,7 @@ class NotificationItem extends Component<
|
|||||||
const items = [];
|
const items = [];
|
||||||
if (props.onHidePlugin && props.plugin) {
|
if (props.onHidePlugin && props.plugin) {
|
||||||
items.push({
|
items.push({
|
||||||
label: `Hide ${props.plugin.title || props.plugin.id} plugin`,
|
label: `Hide ${getPluginTitle(props.plugin)} plugin`,
|
||||||
click: this.props.onHidePlugin,
|
click: this.props.onHidePlugin,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -534,7 +535,7 @@ class NotificationItem extends Component<
|
|||||||
<FlexRow>
|
<FlexRow>
|
||||||
{action && (
|
{action && (
|
||||||
<Button onClick={this.openDeeplink}>
|
<Button onClick={this.openDeeplink}>
|
||||||
Open in {plugin.title}
|
Open in {getPluginTitle(plugin)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
@@ -543,7 +544,7 @@ class NotificationItem extends Component<
|
|||||||
)}
|
)}
|
||||||
{onHidePlugin && (
|
{onHidePlugin && (
|
||||||
<Button onClick={onHidePlugin}>
|
<Button onClick={onHidePlugin}>
|
||||||
Hide {plugin.title}
|
Hide {getPluginTitle(plugin)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ const Container = styled(FlexColumn)({
|
|||||||
});
|
});
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
availablePluginsToExport: Array<string>;
|
availablePluginsToExport: Array<{id: string; label: string}>;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExportDataPluginSheet extends Component<Props, State> {
|
class ExportDataPluginSheet extends Component<Props, State> {
|
||||||
state: State = {availablePluginsToExport: []};
|
state: State = {availablePluginsToExport: []};
|
||||||
static getDerivedStateFromProps(props: Props, _state: State) {
|
static getDerivedStateFromProps(props: Props, _state: State): State {
|
||||||
const {plugins, pluginStates, pluginMessageQueue, selectedClient} = props;
|
const {plugins, pluginStates, pluginMessageQueue, selectedClient} = props;
|
||||||
const availablePluginsToExport = getActivePersistentPlugins(
|
const availablePluginsToExport = getActivePersistentPlugins(
|
||||||
pluginStates,
|
pluginStates,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type Props = {
|
|||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
onChange: (elements: Array<string>) => void;
|
onChange: (elements: Array<string>) => void;
|
||||||
onHide: () => any;
|
onHide: () => any;
|
||||||
elements: Array<string>;
|
elements: Array<{label: string; id: string}>;
|
||||||
title?: string;
|
title?: string;
|
||||||
} & SubType;
|
} & SubType;
|
||||||
|
|
||||||
@@ -80,14 +80,15 @@ const Padder = styled.div<{
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
type RowComponentProps = {
|
type RowComponentProps = {
|
||||||
name: string;
|
id: string;
|
||||||
|
label: string;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
onChange: (name: string, selected: boolean) => void;
|
onChange: (name: string, selected: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RowComponent extends Component<RowComponentProps> {
|
class RowComponent extends Component<RowComponentProps> {
|
||||||
render() {
|
render() {
|
||||||
const {name, selected, onChange} = this.props;
|
const {id, label, selected, onChange} = this.props;
|
||||||
return (
|
return (
|
||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
<Padder
|
<Padder
|
||||||
@@ -96,12 +97,12 @@ class RowComponent extends Component<RowComponentProps> {
|
|||||||
paddingBottom={8}
|
paddingBottom={8}
|
||||||
paddingLeft={8}>
|
paddingLeft={8}>
|
||||||
<FlexRow>
|
<FlexRow>
|
||||||
<Text> {name} </Text>
|
<Text> {label} </Text>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={selected}
|
checked={selected}
|
||||||
onChange={selected => {
|
onChange={selected => {
|
||||||
onChange(name, selected);
|
onChange(id, selected);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
@@ -151,10 +152,11 @@ export default class ListView extends Component<Props, State> {
|
|||||||
<FlexColumn>
|
<FlexColumn>
|
||||||
{this.props.title && <Title>{this.props.title}</Title>}
|
{this.props.title && <Title>{this.props.title}</Title>}
|
||||||
<RowComponentContainer>
|
<RowComponentContainer>
|
||||||
{this.props.elements.map(id => {
|
{this.props.elements.map(({id, label}) => {
|
||||||
return (
|
return (
|
||||||
<RowComponent
|
<RowComponent
|
||||||
name={id}
|
id={id}
|
||||||
|
label={label}
|
||||||
key={id}
|
key={id}
|
||||||
selected={this.state.selectedElements.has(id)}
|
selected={this.state.selectedElements.has(id)}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import BaseDevice from '../../devices/BaseDevice';
|
import BaseDevice from '../../devices/BaseDevice';
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
import {UninitializedClient} from '../../UninitializedClient';
|
import {UninitializedClient} from '../../UninitializedClient';
|
||||||
import {sortPluginsByName} from '../../plugin';
|
import {sortPluginsByName} from '../../utils/pluginUtils';
|
||||||
import {PluginNotification} from '../../reducers/notifications';
|
import {PluginNotification} from '../../reducers/notifications';
|
||||||
import {ActiveSheet} from '../../reducers/application';
|
import {ActiveSheet} from '../../reducers/application';
|
||||||
import {State as Store} from '../../reducers';
|
import {State as Store} from '../../reducers';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import BaseDevice from '../../devices/BaseDevice';
|
import BaseDevice from '../../devices/BaseDevice';
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
import {UninitializedClient} from '../../UninitializedClient';
|
import {UninitializedClient} from '../../UninitializedClient';
|
||||||
import {sortPluginsByName} from '../../plugin';
|
import {sortPluginsByName} from '../../utils/pluginUtils';
|
||||||
import {PluginNotification} from '../../reducers/notifications';
|
import {PluginNotification} from '../../reducers/notifications';
|
||||||
import {ActiveSheet} from '../../reducers/application';
|
import {ActiveSheet} from '../../reducers/application';
|
||||||
import {State as Store} from '../../reducers';
|
import {State as Store} from '../../reducers';
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import {StaticView} from '../../reducers/connections';
|
import {StaticView} from '../../reducers/connections';
|
||||||
import {BackgroundColorProperty} from 'csstype';
|
import {BackgroundColorProperty} from 'csstype';
|
||||||
|
import {getPluginTitle} from '../../utils/pluginUtils';
|
||||||
|
|
||||||
export type FlipperPlugins = typeof FlipperPlugin[];
|
export type FlipperPlugins = typeof FlipperPlugin[];
|
||||||
export type PluginsByCategory = [string, FlipperPlugins][];
|
export type PluginsByCategory = [string, FlipperPlugins][];
|
||||||
@@ -167,7 +168,7 @@ export const PluginSidebarListItem: React.FC<{
|
|||||||
backgroundColor={starred === false ? colors.light20 : iconColor}
|
backgroundColor={starred === false ? colors.light20 : iconColor}
|
||||||
color={colors.white}
|
color={colors.white}
|
||||||
/>
|
/>
|
||||||
<PluginName>{plugin.title || plugin.id}</PluginName>
|
<PluginName>{getPluginTitle(plugin)}</PluginName>
|
||||||
{starred !== undefined && (!starred || isActive) && (
|
{starred !== undefined && (!starred || isActive) && (
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
onClick={onFavorite}
|
onClick={onFavorite}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import stream from 'stream';
|
import stream from 'stream';
|
||||||
import {FlipperDevicePlugin} from 'flipper';
|
import {FlipperDevicePlugin} from 'flipper';
|
||||||
import {sortPluginsByName} from '../plugin';
|
import {sortPluginsByName} from '../utils/pluginUtils';
|
||||||
|
|
||||||
export type LogLevel =
|
export type LogLevel =
|
||||||
| 'unknown'
|
| 'unknown'
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {textContent} from '../utils/index';
|
|||||||
import GK from '../fb-stubs/GK';
|
import GK from '../fb-stubs/GK';
|
||||||
import {deconstructPluginKey} from '../utils/clientUtils';
|
import {deconstructPluginKey} from '../utils/clientUtils';
|
||||||
import NotificationScreen from '../chrome/NotificationScreen';
|
import NotificationScreen from '../chrome/NotificationScreen';
|
||||||
|
import {getPluginTitle} from '../utils/pluginUtils';
|
||||||
|
|
||||||
type NotificationEvents = 'show' | 'click' | 'close' | 'reply' | 'action';
|
type NotificationEvents = 'show' | 'click' | 'close' | 'reply' | 'action';
|
||||||
const NOTIFICATION_THROTTLE = 5 * 1000; // in milliseconds
|
const NOTIFICATION_THROTTLE = 5 * 1000; // in milliseconds
|
||||||
@@ -173,7 +174,9 @@ export default (store: Store, logger: Logger) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
text: `Hide all ${plugin != null ? plugin.title : ''}`,
|
text: `Hide all ${
|
||||||
|
plugin != null ? getPluginTitle(plugin) : ''
|
||||||
|
}`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
closeButtonText: 'Hide',
|
closeButtonText: 'Hide',
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import {serialize, deserialize} from './utils/serialization';
|
|||||||
import {Idler} from './utils/Idler';
|
import {Idler} from './utils/Idler';
|
||||||
import {StaticView} from './reducers/connections';
|
import {StaticView} from './reducers/connections';
|
||||||
import {State as ReduxState} from './reducers';
|
import {State as ReduxState} from './reducers';
|
||||||
import {PersistedState} from './plugins/layout';
|
|
||||||
import {DEFAULT_MAX_QUEUE_SIZE} from './reducers/pluginMessageQueue';
|
import {DEFAULT_MAX_QUEUE_SIZE} from './reducers/pluginMessageQueue';
|
||||||
type Parameters = any;
|
type Parameters = any;
|
||||||
|
|
||||||
@@ -275,10 +274,3 @@ export class FlipperPlugin<
|
|||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sortPluginsByName(
|
|
||||||
a: typeof FlipperBasePlugin,
|
|
||||||
b: typeof FlipperBasePlugin,
|
|
||||||
): number {
|
|
||||||
return (a.title || a.id) > (b.title || b.id) ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -18,33 +18,45 @@ import type {State as PluginMessageQueueState} from '../../reducers/pluginStates
|
|||||||
import {FlipperBasePlugin} from 'flipper';
|
import {FlipperBasePlugin} from 'flipper';
|
||||||
import type {ReduxState} from '../../reducers/index.tsx';
|
import type {ReduxState} from '../../reducers/index.tsx';
|
||||||
|
|
||||||
class MockFlipperPluginWithDefaultPersistedState extends FlipperBasePlugin<
|
function createMockFlipperPluginWithDefaultPersistedState(id: string) {
|
||||||
|
return class MockFlipperPluginWithDefaultPersistedState extends FlipperBasePlugin<
|
||||||
*,
|
*,
|
||||||
*,
|
*,
|
||||||
{msg: string},
|
{msg: string},
|
||||||
> {
|
> {
|
||||||
|
static id = id;
|
||||||
static defaultPersistedState = {msg: 'MockFlipperPluginWithPersistedState'};
|
static defaultPersistedState = {msg: 'MockFlipperPluginWithPersistedState'};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockFlipperPluginWithExportPersistedState extends FlipperBasePlugin<
|
function createMockFlipperPluginWithExportPersistedState(id: string) {
|
||||||
|
return class MockFlipperPluginWithExportPersistedState extends FlipperBasePlugin<
|
||||||
*,
|
*,
|
||||||
*,
|
*,
|
||||||
{msg: string},
|
{msg: string},
|
||||||
> {
|
> {
|
||||||
|
static id = id;
|
||||||
static exportPersistedState = (
|
static exportPersistedState = (
|
||||||
callClient: (string, ?Object) => Promise<Object>,
|
callClient: (string, ?Object) => Promise<Object>,
|
||||||
persistedState: ?{msg: string},
|
persistedState: ?{msg: string},
|
||||||
store: ?ReduxState,
|
store: ?ReduxState,
|
||||||
): Promise<?{msg: string}> => {
|
): Promise<?{msg: string}> => {
|
||||||
return Promise.resolve({msg: 'MockFlipperPluginWithExportPersistedState'});
|
return Promise.resolve({
|
||||||
|
msg: 'MockFlipperPluginWithExportPersistedState',
|
||||||
|
});
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockFlipperPluginWithNoPersistedState extends FlipperBasePlugin<
|
function createMockFlipperPluginWithNoPersistedState(id: string) {
|
||||||
|
return class MockFlipperPluginWithNoPersistedState extends FlipperBasePlugin<
|
||||||
*,
|
*,
|
||||||
*,
|
*,
|
||||||
*,
|
*,
|
||||||
> {}
|
> {
|
||||||
|
static id = id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function mockPluginState(
|
function mockPluginState(
|
||||||
gatekeepedPlugins: Array<PluginDefinition>,
|
gatekeepedPlugins: Array<PluginDefinition>,
|
||||||
@@ -53,12 +65,24 @@ function mockPluginState(
|
|||||||
): PluginsState {
|
): PluginsState {
|
||||||
return {
|
return {
|
||||||
devicePlugins: new Map([
|
devicePlugins: new Map([
|
||||||
['DevicePlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'DevicePlugin1',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'DevicePlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
clientPlugins: new Map([
|
clientPlugins: new Map([
|
||||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['ClientPlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'ClientPlugin1',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
gatekeepedPlugins,
|
gatekeepedPlugins,
|
||||||
disabledPlugins,
|
disabledPlugins,
|
||||||
@@ -98,12 +122,24 @@ test('getPersistentPlugins with no plugins getting excluded', () => {
|
|||||||
test('getPersistentPlugins, where the plugins with exportPersistedState not getting excluded', () => {
|
test('getPersistentPlugins, where the plugins with exportPersistedState not getting excluded', () => {
|
||||||
const state: PluginsState = {
|
const state: PluginsState = {
|
||||||
devicePlugins: new Map([
|
devicePlugins: new Map([
|
||||||
['DevicePlugin1', MockFlipperPluginWithExportPersistedState],
|
[
|
||||||
['DevicePlugin2', MockFlipperPluginWithExportPersistedState],
|
'DevicePlugin1',
|
||||||
|
createMockFlipperPluginWithExportPersistedState('DevicePlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'DevicePlugin2',
|
||||||
|
createMockFlipperPluginWithExportPersistedState('DevicePlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
clientPlugins: new Map([
|
clientPlugins: new Map([
|
||||||
['ClientPlugin1', MockFlipperPluginWithExportPersistedState],
|
[
|
||||||
['ClientPlugin2', MockFlipperPluginWithExportPersistedState],
|
'ClientPlugin1',
|
||||||
|
createMockFlipperPluginWithExportPersistedState('ClientPlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin2',
|
||||||
|
createMockFlipperPluginWithExportPersistedState('ClientPlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -122,12 +158,24 @@ test('getPersistentPlugins, where the plugins with exportPersistedState not gett
|
|||||||
test('getPersistentPlugins, where the non persistent plugins getting excluded', () => {
|
test('getPersistentPlugins, where the non persistent plugins getting excluded', () => {
|
||||||
const state: PluginsState = {
|
const state: PluginsState = {
|
||||||
devicePlugins: new Map([
|
devicePlugins: new Map([
|
||||||
['DevicePlugin1', MockFlipperPluginWithNoPersistedState],
|
[
|
||||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'DevicePlugin1',
|
||||||
|
createMockFlipperPluginWithNoPersistedState('DevicePlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'DevicePlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
clientPlugins: new Map([
|
clientPlugins: new Map([
|
||||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['ClientPlugin2', MockFlipperPluginWithNoPersistedState],
|
'ClientPlugin1',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin2',
|
||||||
|
createMockFlipperPluginWithNoPersistedState('ClientPlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -141,12 +189,24 @@ test('getPersistentPlugins, where the non persistent plugins getting excluded',
|
|||||||
test('getActivePersistentPlugins, where the non persistent plugins getting excluded', () => {
|
test('getActivePersistentPlugins, where the non persistent plugins getting excluded', () => {
|
||||||
const state: PluginsState = {
|
const state: PluginsState = {
|
||||||
devicePlugins: new Map([
|
devicePlugins: new Map([
|
||||||
['DevicePlugin1', MockFlipperPluginWithNoPersistedState],
|
[
|
||||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'DevicePlugin1',
|
||||||
|
createMockFlipperPluginWithNoPersistedState('DevicePlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'DevicePlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
clientPlugins: new Map([
|
clientPlugins: new Map([
|
||||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['ClientPlugin2', MockFlipperPluginWithNoPersistedState],
|
'ClientPlugin1',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin2',
|
||||||
|
createMockFlipperPluginWithNoPersistedState('ClientPlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -161,19 +221,43 @@ test('getActivePersistentPlugins, where the non persistent plugins getting exclu
|
|||||||
};
|
};
|
||||||
const queues: PluginMessageQueueState = {};
|
const queues: PluginMessageQueueState = {};
|
||||||
const list = getActivePersistentPlugins(plugins, queues, state);
|
const list = getActivePersistentPlugins(plugins, queues, state);
|
||||||
expect(list).toEqual(['ClientPlugin1', 'DevicePlugin2']);
|
expect(list).toEqual([
|
||||||
|
{
|
||||||
|
id: 'ClientPlugin1',
|
||||||
|
label: 'ClientPlugin1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'DevicePlugin2',
|
||||||
|
label: 'DevicePlugin2',
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getActivePersistentPlugins, where the plugins not in pluginState or queue gets excluded', () => {
|
test('getActivePersistentPlugins, where the plugins not in pluginState or queue gets excluded', () => {
|
||||||
const state: PluginsState = {
|
const state: PluginsState = {
|
||||||
devicePlugins: new Map([
|
devicePlugins: new Map([
|
||||||
['DevicePlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['DevicePlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'DevicePlugin1',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'DevicePlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('DevicePlugin2'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
clientPlugins: new Map([
|
clientPlugins: new Map([
|
||||||
['ClientPlugin1', MockFlipperPluginWithDefaultPersistedState],
|
[
|
||||||
['ClientPlugin2', MockFlipperPluginWithDefaultPersistedState],
|
'ClientPlugin1',
|
||||||
['ClientPlugin3', MockFlipperPluginWithDefaultPersistedState],
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin1'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin2',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin2'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClientPlugin3',
|
||||||
|
createMockFlipperPluginWithDefaultPersistedState('ClientPlugin3'),
|
||||||
|
],
|
||||||
]),
|
]),
|
||||||
gatekeepedPlugins: [],
|
gatekeepedPlugins: [],
|
||||||
disabledPlugins: [],
|
disabledPlugins: [],
|
||||||
@@ -190,5 +274,18 @@ test('getActivePersistentPlugins, where the plugins not in pluginState or queue
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
const list = getActivePersistentPlugins(plugins, queues, state);
|
const list = getActivePersistentPlugins(plugins, queues, state);
|
||||||
expect(list).toEqual(['ClientPlugin2', 'ClientPlugin3', 'DevicePlugin1']);
|
expect(list).toEqual([
|
||||||
|
{
|
||||||
|
id: 'ClientPlugin2',
|
||||||
|
label: 'ClientPlugin2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ClientPlugin3',
|
||||||
|
label: 'ClientPlugin3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'DevicePlugin1',
|
||||||
|
label: 'DevicePlugin1',
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import {setSelectPluginsToExportActiveSheet} from '../reducers/application';
|
|||||||
import {deconstructClientId, deconstructPluginKey} from '../utils/clientUtils';
|
import {deconstructClientId, deconstructPluginKey} from '../utils/clientUtils';
|
||||||
import {performance} from 'perf_hooks';
|
import {performance} from 'perf_hooks';
|
||||||
import {processMessageQueue} from './messageQueue';
|
import {processMessageQueue} from './messageQueue';
|
||||||
|
import {getPluginTitle} from './pluginUtils';
|
||||||
|
|
||||||
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
|
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
|
||||||
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
|
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
|
||||||
@@ -85,7 +86,8 @@ type SerializePluginStatesOptions = {
|
|||||||
|
|
||||||
type PluginsToProcess = {
|
type PluginsToProcess = {
|
||||||
pluginKey: string;
|
pluginKey: string;
|
||||||
plugin: string;
|
pluginId: string;
|
||||||
|
pluginName: string;
|
||||||
pluginClass: typeof FlipperPlugin | typeof FlipperDevicePlugin;
|
pluginClass: typeof FlipperPlugin | typeof FlipperDevicePlugin;
|
||||||
client: Client;
|
client: Client;
|
||||||
}[];
|
}[];
|
||||||
@@ -398,33 +400,39 @@ export async function fetchMetadata(
|
|||||||
const newPluginState = {...pluginStates};
|
const newPluginState = {...pluginStates};
|
||||||
const errorArray: Array<Error> = [];
|
const errorArray: Array<Error> = [];
|
||||||
|
|
||||||
for (const {plugin, pluginClass, client, pluginKey} of pluginsToProcess) {
|
for (const {
|
||||||
|
pluginName,
|
||||||
|
pluginId,
|
||||||
|
pluginClass,
|
||||||
|
client,
|
||||||
|
pluginKey,
|
||||||
|
} of pluginsToProcess) {
|
||||||
const exportState = pluginClass ? pluginClass.exportPersistedState : null;
|
const exportState = pluginClass ? pluginClass.exportPersistedState : null;
|
||||||
if (exportState) {
|
if (exportState) {
|
||||||
const fetchMetaDataMarker = `${EXPORT_FLIPPER_TRACE_EVENT}:fetch-meta-data-per-plugin`;
|
const fetchMetaDataMarker = `${EXPORT_FLIPPER_TRACE_EVENT}:fetch-meta-data-per-plugin`;
|
||||||
performance.mark(fetchMetaDataMarker);
|
performance.mark(fetchMetaDataMarker);
|
||||||
try {
|
try {
|
||||||
statusUpdate &&
|
statusUpdate &&
|
||||||
statusUpdate(`Fetching metadata for plugin ${plugin}...`);
|
statusUpdate(`Fetching metadata for plugin ${pluginName}...`);
|
||||||
const data = await promiseTimeout(
|
const data = await promiseTimeout(
|
||||||
240000, // Fetching MobileConfig data takes ~ 3 mins, thus keeping timeout at 4 mins.
|
240000, // Fetching MobileConfig data takes ~ 3 mins, thus keeping timeout at 4 mins.
|
||||||
exportState(
|
exportState(
|
||||||
callClient(client, plugin),
|
callClient(client, pluginId),
|
||||||
newPluginState[pluginKey],
|
newPluginState[pluginKey],
|
||||||
state,
|
state,
|
||||||
idler,
|
idler,
|
||||||
statusUpdate,
|
statusUpdate,
|
||||||
),
|
),
|
||||||
`Timed out while collecting data for ${plugin}`,
|
`Timed out while collecting data for ${pluginName}`,
|
||||||
);
|
);
|
||||||
getLogger().trackTimeSince(fetchMetaDataMarker, fetchMetaDataMarker, {
|
getLogger().trackTimeSince(fetchMetaDataMarker, fetchMetaDataMarker, {
|
||||||
plugin,
|
pluginId,
|
||||||
});
|
});
|
||||||
newPluginState[pluginKey] = data;
|
newPluginState[pluginKey] = data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorArray.push(e);
|
errorArray.push(e);
|
||||||
getLogger().trackTimeSince(fetchMetaDataMarker, fetchMetaDataMarker, {
|
getLogger().trackTimeSince(fetchMetaDataMarker, fetchMetaDataMarker, {
|
||||||
plugin,
|
pluginId,
|
||||||
error: e,
|
error: e,
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
@@ -441,7 +449,12 @@ async function processQueues(
|
|||||||
statusUpdate?: (msg: string) => void,
|
statusUpdate?: (msg: string) => void,
|
||||||
idler?: Idler,
|
idler?: Idler,
|
||||||
) {
|
) {
|
||||||
for (const {plugin, pluginKey, pluginClass} of pluginsToProcess) {
|
for (const {
|
||||||
|
pluginName,
|
||||||
|
pluginId,
|
||||||
|
pluginKey,
|
||||||
|
pluginClass,
|
||||||
|
} of pluginsToProcess) {
|
||||||
if (pluginClass.persistedStateReducer) {
|
if (pluginClass.persistedStateReducer) {
|
||||||
const processQueueMarker = `${EXPORT_FLIPPER_TRACE_EVENT}:process-queue-per-plugin`;
|
const processQueueMarker = `${EXPORT_FLIPPER_TRACE_EVENT}:process-queue-per-plugin`;
|
||||||
performance.mark(processQueueMarker);
|
performance.mark(processQueueMarker);
|
||||||
@@ -454,14 +467,14 @@ async function processQueues(
|
|||||||
statusUpdate?.(
|
statusUpdate?.(
|
||||||
`Processing event ${current} / ${total} (${Math.round(
|
`Processing event ${current} / ${total} (${Math.round(
|
||||||
(current / total) * 100,
|
(current / total) * 100,
|
||||||
)}%) for plugin ${plugin}`,
|
)}%) for plugin ${pluginName}`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
idler,
|
idler,
|
||||||
);
|
);
|
||||||
|
|
||||||
getLogger().trackTimeSince(processQueueMarker, processQueueMarker, {
|
getLogger().trackTimeSince(processQueueMarker, processQueueMarker, {
|
||||||
plugin,
|
pluginId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,7 +519,8 @@ export function determinePluginsToProcess(
|
|||||||
pluginsToProcess.push({
|
pluginsToProcess.push({
|
||||||
pluginKey: key,
|
pluginKey: key,
|
||||||
client,
|
client,
|
||||||
plugin,
|
pluginId: plugin,
|
||||||
|
pluginName: getPluginTitle(pluginClass),
|
||||||
pluginClass,
|
pluginClass,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,13 +77,15 @@ export function getActivePersistentPlugins(
|
|||||||
pluginsMessageQueue: PluginMessageQueueState,
|
pluginsMessageQueue: PluginMessageQueueState,
|
||||||
plugins: PluginsState,
|
plugins: PluginsState,
|
||||||
selectedClient?: Client,
|
selectedClient?: Client,
|
||||||
): Array<string> {
|
): {id: string; label: string}[] {
|
||||||
const pluginsMap: Map<
|
const pluginsMap: Map<
|
||||||
string,
|
string,
|
||||||
typeof FlipperDevicePlugin | typeof FlipperPlugin
|
typeof FlipperDevicePlugin | typeof FlipperPlugin
|
||||||
> = pluginsClassMap(plugins);
|
> = pluginsClassMap(plugins);
|
||||||
return getPersistentPlugins(plugins).filter(plugin => {
|
return getPersistentPlugins(plugins)
|
||||||
const pluginClass = pluginsMap.get(plugin);
|
.map(pluginName => pluginsMap.get(pluginName)!)
|
||||||
|
.sort(sortPluginsByName)
|
||||||
|
.map(plugin => {
|
||||||
const keys = [
|
const keys = [
|
||||||
...new Set([
|
...new Set([
|
||||||
...Object.keys(pluginsState),
|
...Object.keys(pluginsState),
|
||||||
@@ -92,23 +94,29 @@ export function getActivePersistentPlugins(
|
|||||||
]
|
]
|
||||||
.filter(k => !selectedClient || k.includes(selectedClient.id))
|
.filter(k => !selectedClient || k.includes(selectedClient.id))
|
||||||
.map(key => deconstructPluginKey(key).pluginName);
|
.map(key => deconstructPluginKey(key).pluginName);
|
||||||
let result = plugin == 'DeviceLogs';
|
let result = plugin.id == 'DeviceLogs';
|
||||||
const pluginsWithExportPersistedState =
|
const pluginsWithExportPersistedState =
|
||||||
pluginClass && pluginClass.exportPersistedState != undefined;
|
plugin && plugin.exportPersistedState != undefined;
|
||||||
const pluginsWithReduxData = keys.includes(plugin);
|
const pluginsWithReduxData = keys.includes(plugin.id);
|
||||||
if (!result && selectedClient) {
|
if (!result && selectedClient) {
|
||||||
// If there is a selected client, active persistent plugin is the plugin which is active for selectedClient and also persistent.
|
// If there is a selected client, active persistent plugin is the plugin which is active for selectedClient and also persistent.
|
||||||
result =
|
result =
|
||||||
selectedClient.plugins.includes(plugin) &&
|
selectedClient.plugins.includes(plugin.id) &&
|
||||||
(pluginsWithExportPersistedState || pluginsWithReduxData);
|
(pluginsWithExportPersistedState || pluginsWithReduxData);
|
||||||
} else if (!result && !selectedClient) {
|
} else if (!result && !selectedClient) {
|
||||||
// If there is no selected client, active persistent plugin is the plugin which is just persistent.
|
// If there is no selected client, active persistent plugin is the plugin which is just persistent.
|
||||||
result =
|
result =
|
||||||
(pluginClass && pluginClass.exportPersistedState != undefined) ||
|
(plugin && plugin.exportPersistedState != undefined) ||
|
||||||
keys.includes(plugin);
|
keys.includes(plugin.id);
|
||||||
}
|
}
|
||||||
return result;
|
return (result
|
||||||
});
|
? {
|
||||||
|
id: plugin.id,
|
||||||
|
label: getPluginTitle(plugin),
|
||||||
|
}
|
||||||
|
: undefined)!;
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPersistentPlugins(plugins: PluginsState): Array<string> {
|
export function getPersistentPlugins(plugins: PluginsState): Array<string> {
|
||||||
@@ -144,3 +152,27 @@ export function getPersistentPlugins(plugins: PluginsState): Array<string> {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getPluginTitle(pluginClass: typeof FlipperBasePlugin) {
|
||||||
|
return pluginClass.title || pluginClass.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sortPluginsByName(
|
||||||
|
a: typeof FlipperBasePlugin,
|
||||||
|
b: typeof FlipperBasePlugin,
|
||||||
|
): number {
|
||||||
|
// make sure Device plugins are sorted before normal plugins
|
||||||
|
if (
|
||||||
|
a.prototype instanceof FlipperDevicePlugin &&
|
||||||
|
!(b.prototype instanceof FlipperDevicePlugin)
|
||||||
|
) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
b.prototype instanceof FlipperDevicePlugin &&
|
||||||
|
!(a.prototype instanceof FlipperDevicePlugin)
|
||||||
|
) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return getPluginTitle(a) > getPluginTitle(b) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user