Move sidebar client selection state to redux store

Summary:
This diff moves the selection storage from local state to the Redux store.
This makes the state available to the export data functionality (next diff)

Reviewed By: priteshrnandgaonkar

Differential Revision: D18448193

fbshipit-source-id: b1cce083ac7805c539de22aca0bd05c18e1b66e0
This commit is contained in:
Michel Weststrate
2019-11-12 04:44:27 -08:00
committed by Facebook Github Bot
parent e2c196cc7c
commit d6814a8bf6
3 changed files with 37 additions and 18 deletions

View File

@@ -38,6 +38,7 @@ import {
starPlugin, starPlugin,
StaticView, StaticView,
setStaticView, setStaticView,
selectClient,
} from '../reducers/connections'; } from '../reducers/connections';
import {setActiveSheet} from '../reducers/application'; import {setActiveSheet} from '../reducers/application';
import UserAccount from './UserAccount'; import UserAccount from './UserAccount';
@@ -222,6 +223,7 @@ type StateFromProps = {
selectedApp: string | null | undefined; selectedApp: string | null | undefined;
userStarredPlugins: Store['connections']['userStarredPlugins']; userStarredPlugins: Store['connections']['userStarredPlugins'];
clients: Array<Client>; clients: Array<Client>;
selectedClient: string;
uninitializedClients: Array<{ uninitializedClients: Array<{
client: UninitializedClient; client: UninitializedClient;
deviceId?: string; deviceId?: string;
@@ -237,6 +239,7 @@ type DispatchFromProps = {
selectedApp: string | null; selectedApp: string | null;
deepLinkPayload: string | null; deepLinkPayload: string | null;
}) => void; }) => void;
selectClient: typeof selectClient;
setActiveSheet: (activeSheet: ActiveSheet) => void; setActiveSheet: (activeSheet: ActiveSheet) => void;
setStaticView: (payload: StaticView) => void; setStaticView: (payload: StaticView) => void;
starPlugin: typeof starPlugin; starPlugin: typeof starPlugin;
@@ -245,14 +248,11 @@ type DispatchFromProps = {
type Props = OwnProps & StateFromProps & DispatchFromProps; type Props = OwnProps & StateFromProps & DispatchFromProps;
type State = { type State = {
showSupportForm: boolean; showSupportForm: boolean;
selectedClientIndex: number;
showAllPlugins: boolean; showAllPlugins: boolean;
}; };
class MainSidebar extends PureComponent<Props, State> { class MainSidebar extends PureComponent<Props, State> {
state: State = { state: State = {
showSupportForm: GK.get('flipper_support_requests'), showSupportForm: GK.get('flipper_support_requests'),
// Not to be confused with selectedApp prop, this one only used to remember the client drowdown selector
selectedClientIndex: 0,
showAllPlugins: false, showAllPlugins: false,
}; };
static getDerivedStateFromProps(props: Props, state: State) { static getDerivedStateFromProps(props: Props, state: State) {
@@ -271,6 +271,8 @@ class MainSidebar extends PureComponent<Props, State> {
render() { render() {
const { const {
selectedDevice, selectedDevice,
selectedClient,
selectClient,
selectedPlugin, selectedPlugin,
staticView, staticView,
selectPlugin, selectPlugin,
@@ -290,8 +292,9 @@ class MainSidebar extends PureComponent<Props, State> {
client.query.device_id === 'unknown', client.query.device_id === 'unknown',
) )
.sort((a, b) => (a.query.app || '').localeCompare(b.query.app)); .sort((a, b) => (a.query.app || '').localeCompare(b.query.app));
const client: Client | null = const client: Client | undefined = clients.find(
clients[this.state.selectedClientIndex] || null; client => client.query.app === selectedClient,
);
return ( return (
<Sidebar <Sidebar
@@ -328,16 +331,16 @@ class MainSidebar extends PureComponent<Props, State> {
<SidebarButton <SidebarButton
title="Select an app to see available plugins" title="Select an app to see available plugins"
compact={true} compact={true}
dropdown={clients.map((c, index) => ({ dropdown={clients.map(c => ({
checked: client === c, checked: client === c,
label: c.query.app, label: c.query.app,
type: 'checkbox', type: 'checkbox',
click: () => this.setState({selectedClientIndex: index}), click: () => selectClient(c.query.app),
}))}> }))}>
{clients.length === 0 ? ( {clients.length === 0 ? (
'(Not connected to app)' '(Not connected clients)'
) : this.state.selectedClientIndex >= clients.length ? ( ) : !client ? (
'(Select app)' '(Select client)'
) : ( ) : (
<> <>
{client.query.app} {client.query.app}
@@ -463,7 +466,7 @@ class MainSidebar extends PureComponent<Props, State> {
)); ));
} }
renderClientPlugins(client: Client | null) { renderClientPlugins(client?: Client) {
if (!client) { if (!client) {
return null; return null;
} }
@@ -594,6 +597,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
selectedDevice, selectedDevice,
selectedPlugin, selectedPlugin,
selectedApp, selectedApp,
selectedClient,
userStarredPlugins, userStarredPlugins,
clients, clients,
uninitializedClients, uninitializedClients,
@@ -610,6 +614,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
})(), })(),
windowIsFocused, windowIsFocused,
selectedDevice, selectedDevice,
selectedClient,
staticView, staticView,
selectedPlugin, selectedPlugin,
selectedApp, selectedApp,
@@ -621,6 +626,7 @@ export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
}), }),
{ {
selectPlugin, selectPlugin,
selectClient,
setStaticView, setStaticView,
setActiveSheet, setActiveSheet,
starPlugin, starPlugin,

View File

@@ -47,6 +47,9 @@ export type State = {
userStarredPlugins: {[key: string]: Array<string>}; userStarredPlugins: {[key: string]: Array<string>};
errors: FlipperError[]; errors: FlipperError[];
clients: Array<Client>; clients: Array<Client>;
// refers to the client that is selected in the main side bar, not to be confused with
// selectedApp, which represents the app of the currently active plugin!
selectedClient: string;
uninitializedClients: Array<{ uninitializedClients: Array<{
client: UninitializedClient; client: UninitializedClient;
deviceId?: string; deviceId?: string;
@@ -131,6 +134,10 @@ export type Action =
selectedPlugin: string; selectedPlugin: string;
selectedApp: string; selectedApp: string;
}; };
}
| {
type: 'SELECT_CLIENT';
payload: string;
}; };
const DEFAULT_PLUGIN = 'DeviceLogs'; const DEFAULT_PLUGIN = 'DeviceLogs';
@@ -147,6 +154,7 @@ const INITAL_STATE: State = {
userStarredPlugins: {}, userStarredPlugins: {},
errors: [], errors: [],
clients: [], clients: [],
selectedClient: '',
uninitializedClients: [], uninitializedClients: [],
deepLinkPayload: null, deepLinkPayload: null,
staticView: WelcomeScreen, staticView: WelcomeScreen,
@@ -425,6 +433,12 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
errors, errors,
}; };
} }
case 'SELECT_CLIENT': {
return {
...state,
selectedClient: action.payload,
};
}
default: default:
return state; return state;
} }
@@ -514,14 +528,12 @@ export const userPreferredPlugin = (payload: string): Action => ({
payload, payload,
}); });
function extractAppNameFromAppId(appId: string | null): string | null {
const nameRegex = /([^#]+)#/;
const matchedRegex = appId ? appId.match(nameRegex) : null;
// Expect the name of the app to be on the first matching
return matchedRegex && matchedRegex[1];
}
export const dismissError = (index: number): Action => ({ export const dismissError = (index: number): Action => ({
type: 'DISMISS_ERROR', type: 'DISMISS_ERROR',
payload: index, payload: index,
}); });
export const selectClient = (clientId: string): Action => ({
type: 'SELECT_CLIENT',
payload: clientId,
});

View File

@@ -97,6 +97,7 @@ export default combineReducers<State, Actions>({
'userPreferredPlugin', 'userPreferredPlugin',
'userPreferredApp', 'userPreferredApp',
'userStarredPlugins', 'userStarredPlugins',
'selectedClient',
], ],
}, },
connections, connections,