From 670949b016eba13dfb34ef58b6596a03fa3fb267 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Mon, 3 Feb 2020 10:06:07 -0800 Subject: [PATCH] Refactor the default plugins and validation logic into Group object Summary: This diff refactors the scattered logic of required plugins and default selection of the plugins into Group class. Also the same class handles the deeplink logic. Reviewed By: mweststrate Differential Revision: D19666745 fbshipit-source-id: c9427f0ddba643f0b32aac7b6f2496e2e3248b12 --- src/dispatcher/application.tsx | 97 +++------------- src/fb-stubs/constants.tsx | 5 + src/fb-stubs/utils/supportForm.tsx | 21 ---- src/reducers/supportForm.tsx | 171 ++++++++++++++++++++++++++++- 4 files changed, 185 insertions(+), 109 deletions(-) delete mode 100644 src/fb-stubs/utils/supportForm.tsx diff --git a/src/dispatcher/application.tsx b/src/dispatcher/application.tsx index cc9911795..9afe85091 100644 --- a/src/dispatcher/application.tsx +++ b/src/dispatcher/application.tsx @@ -9,26 +9,23 @@ import {remote, ipcRenderer, IpcRendererEvent} from 'electron'; import {toggleAction} from '../reducers/application'; -import {setStaticView} from '../reducers/connections'; -import {selectedPlugins as setSelectedPlugins} from '../reducers/plugins'; -import {starPlugin as setStarPlugin} from '../reducers/connections'; -import {setSupportFormV2State, Groups} from '../reducers/supportForm'; -import {addStatusMessage, removeStatusMessage} from '../reducers/application'; +import { + Group, + GRAPHQL_ANDROID_GROUP, + GRAPHQL_IOS_GROUP, + LITHO_GROUP, +} from '../reducers/supportForm'; import {Store} from '../reducers/index.js'; import {Logger} from '../fb-interfaces/Logger'; import {parseFlipperPorts} from '../utils/environmentVariables'; -import SupportRequestFormV2 from '../fb-stubs/SupportRequestFormV2'; import { importDataToStore, importFileToStore, IMPORT_FLIPPER_TRACE_EVENT, } from '../utils/exportData'; import {tryCatchReportPlatformFailures} from '../utils/metrics'; -import {deconstructClientId} from '../utils/clientUtils'; -import {defaultSelectedPluginsForGroup} from '../fb-stubs/utils/supportForm'; import {selectPlugin} from '../reducers/connections'; import qs from 'query-string'; -import {showStatusUpdatesForDuration} from '../utils/promiseTimeout'; export const uriComponents = (url: string): Array => { if (!url) { @@ -97,9 +94,9 @@ export default (store: Store, logger: Logger) => { uri.pathname.includes('support-form') ) { const formParam = uri.searchParams.get('form'); - const grps = deeplinkFormParamToGroups(formParam); - if (grps) { - handleSupportFormDeeplinks(grps); + const grp = deeplinkFormParamToGroups(formParam); + if (grp) { + grp.handleSupportFormDeeplinks(store); } return; } @@ -117,88 +114,20 @@ export default (store: Store, logger: Logger) => { }, ); - function deeplinkFormParamToGroups(formParam: string | null): Groups | null { + function deeplinkFormParamToGroups(formParam: string | null): Group | null { if (!formParam) { return null; } if (formParam.toLowerCase() === 'litho') { - return 'Litho Support'; + return LITHO_GROUP; } else if (formParam.toLowerCase() === 'graphql_android') { - return 'GraphQL Android Support'; + return GRAPHQL_ANDROID_GROUP; } else if (formParam.toLowerCase() === 'graphql_ios') { - return 'GraphQL iOS Support'; + return GRAPHQL_IOS_GROUP; } return null; } - function handleSupportFormDeeplinks(grp: Groups) { - logger.track('usage', 'support-form-source', {source: 'deeplink'}); - // TODO: Incorporate grp info in analytics. - store.dispatch(setStaticView(SupportRequestFormV2)); - const selectedApp = store.getState().connections.selectedApp; - if ( - (grp === 'GraphQL Android Support' || grp === 'GraphQL iOS Support') && - selectedApp - ) { - // Enable GraphQL plugin if grp to be posted is the GraphQL one. - // TODO: Handle the case where GraphQL plugin is not supported by Client - const {app} = deconstructClientId(selectedApp); - const selectedClient = store - .getState() - .connections.clients.find(client => client.id === selectedApp); - const enabledPlugins: Array | null = store.getState().connections - .userStarredPlugins[app]; - const graphQLEnabled = - enabledPlugins != null && enabledPlugins.includes('GraphQL'); - if ( - selectedClient && - selectedClient.plugins.includes('GraphQL') && - !graphQLEnabled - ) { - store.dispatch( - setStarPlugin({ - selectedApp: app, - selectedPlugin: 'GraphQL', - }), - ); - } else if ( - !selectedClient || - !selectedClient.plugins.includes('GraphQL') - ) { - showStatusUpdatesForDuration( - 'The current client does not support GraphQL plugin. Please change the app from the dropdown in the support form', - 'Deeplink', - 10000, - payload => { - store.dispatch(addStatusMessage(payload)); - }, - payload => { - store.dispatch(removeStatusMessage(payload)); - }, - ); - } - } - store.dispatch( - setSupportFormV2State({ - ...store.getState().supportForm.supportFormV2, - selectedGroup: grp, - }), - ); - const selectedClient = store.getState().connections.clients.find(o => { - return o.id === store.getState().connections.selectedApp; - }); - store.dispatch( - setSelectedPlugins( - defaultSelectedPluginsForGroup( - grp, - store.getState().plugins, - selectedClient, - store.getState().connections.userStarredPlugins, - ), - ), - ); - } - ipcRenderer.on( 'open-flipper-file', (_event: IpcRendererEvent, url: string) => { diff --git a/src/fb-stubs/constants.tsx b/src/fb-stubs/constants.tsx index 0ec4c4a29..8ec130e58 100644 --- a/src/fb-stubs/constants.tsx +++ b/src/fb-stubs/constants.tsx @@ -27,4 +27,9 @@ export default Object.freeze({ IS_PUBLIC_BUILD: true, FEEDBACK_GROUP_LINK: 'https://github.com/facebook/flipper/issues', + + // Workplace Group ID's + LITHO_SUPPORT_GROUP_ID: 0, + GRAPHQL_ANDROID_SUPPORT_GROUP_ID: 0, + GRAPHQL_IOS_SUPPORT_GROUP_ID: 0, }); diff --git a/src/fb-stubs/utils/supportForm.tsx b/src/fb-stubs/utils/supportForm.tsx deleted file mode 100644 index d22968992..000000000 --- a/src/fb-stubs/utils/supportForm.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 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 {Groups} from '../../reducers/supportForm'; -import {State as PluginState} from '../../reducers/plugins'; -import Client from '../../Client'; - -export function defaultSelectedPluginsForGroup( - _grp: Groups, - _plugins: PluginState, - _selectedClient: Client | undefined, - _userStarredPlugins: {[client: string]: Array}, -): Array { - return []; -} diff --git a/src/reducers/supportForm.tsx b/src/reducers/supportForm.tsx index d1786c02a..3fe9a8d80 100644 --- a/src/reducers/supportForm.tsx +++ b/src/reducers/supportForm.tsx @@ -7,7 +7,21 @@ * @format */ -import {Actions} from './'; +import {Actions, Store} from './'; +import {setStaticView} from './connections'; +import SupportRequestFormV2 from '../fb-stubs/SupportRequestFormV2'; +import {deconstructClientId} from '../utils/clientUtils'; +import {starPlugin as setStarPlugin} from './connections'; +import {showStatusUpdatesForDuration} from '../utils/promiseTimeout'; +import {selectedPlugins as setSelectedPlugins} from './plugins'; +import {getEnabledOrExportPersistedStatePlugins} from '../utils/pluginUtils'; +import {addStatusMessage, removeStatusMessage} from './application'; +import constants from '../fb-stubs/constants'; +const { + GRAPHQL_IOS_SUPPORT_GROUP_ID, + GRAPHQL_ANDROID_SUPPORT_GROUP_ID, + LITHO_SUPPORT_GROUP_ID, +} = constants; type SubmediaType = | {uploadID: string; status: 'Uploaded'} | {status: 'NotUploaded' | 'Uploading'}; @@ -16,11 +30,160 @@ type MediaObject = SubmediaType & { path: string; }; -export type Groups = +export class Group { + constructor( + name: GroupNames, + workplaceGroupID: number, + requiredPlugins: Array, + defaultPlugins: Array, + ) { + this.name = name; + this.requiredPlugins = requiredPlugins; + this.defaultPlugins = defaultPlugins; + this.workplaceGroupID = workplaceGroupID; + } + readonly name: GroupNames; + requiredPlugins: Array; + defaultPlugins: Array; + workplaceGroupID: number; + + getValidationMessage(selectedPlugins: Array): string | null { + const nonSelectedPlugin: Array = []; + for (const plugin of this.requiredPlugins) { + if (!selectedPlugins.includes(plugin)) { + nonSelectedPlugin.push(plugin); + } + } + if (nonSelectedPlugin.length <= 0) { + return null; + } + let str = 'should be exported if you want to submit to this group.'; + if (nonSelectedPlugin.length == 1) { + str = `the ${nonSelectedPlugin.pop()} plugin ${str}`; + } else { + const lastPlugin = nonSelectedPlugin.pop(); + str = `the ${nonSelectedPlugin.join(',')} and ${lastPlugin} ${str}`; + } + return str; + } + + handleSupportFormDeeplinks(store: Store) { + // TODO: Incorporate grp info in analytics. + store.dispatch(setStaticView(SupportRequestFormV2)); + const selectedApp = store.getState().connections.selectedApp; + const selectedClient = store.getState().connections.clients.find(o => { + return o.id === store.getState().connections.selectedApp; + }); + if (selectedApp) { + const {app} = deconstructClientId(selectedApp); + const enabledPlugins: Array | null = store.getState().connections + .userStarredPlugins[app]; + const unsupportedPlugins = []; + for (const requiredPlugin of this.requiredPlugins) { + const requiredPluginEnabled = + enabledPlugins != null && enabledPlugins.includes(requiredPlugin); + if ( + selectedClient && + selectedClient.plugins.includes(requiredPlugin) && + !requiredPluginEnabled + ) { + store.dispatch( + setStarPlugin({ + selectedApp: app, + selectedPlugin: requiredPlugin, + }), + ); + } else if ( + !selectedClient || + !selectedClient.plugins.includes(requiredPlugin) + ) { + unsupportedPlugins.push(requiredPlugin); + } + } + if (unsupportedPlugins.length > 0) { + showStatusUpdatesForDuration( + `The current client does not support ${unsupportedPlugins.join( + ', ', + )}. Please change the app from the dropdown in the support form.`, + 'Deeplink', + 10000, + payload => { + store.dispatch(addStatusMessage(payload)); + }, + payload => { + store.dispatch(removeStatusMessage(payload)); + }, + ); + } + } else { + showStatusUpdatesForDuration( + 'Please select an app and the device from the dropdown.', + 'Deeplink', + 10000, + payload => { + store.dispatch(addStatusMessage(payload)); + }, + payload => { + store.dispatch(removeStatusMessage(payload)); + }, + ); + } + store.dispatch( + setSupportFormV2State({ + ...store.getState().supportForm.supportFormV2, + selectedGroup: this, + }), + ); + const pluginsList = selectedClient + ? getEnabledOrExportPersistedStatePlugins( + store.getState().connections.userStarredPlugins, + selectedClient, + store.getState().plugins, + ) + : []; + + store.dispatch( + setSelectedPlugins( + this.defaultPlugins.filter(s => { + return pluginsList.map(s => s.id).includes(s); + }), + ), + ); + } +} + +export type GroupNames = | 'Litho Support' | 'GraphQL Android Support' | 'GraphQL iOS Support'; +export const LITHO_GROUP = new Group( + 'Litho Support', + LITHO_SUPPORT_GROUP_ID, + ['Inspector'], + ['Inspector', 'Sections', 'DeviceLogs'], +); + +export const GRAPHQL_ANDROID_GROUP = new Group( + 'GraphQL Android Support', + GRAPHQL_ANDROID_SUPPORT_GROUP_ID, + ['GraphQL'], + ['GraphQL', 'DeviceLogs'], +); + +export const GRAPHQL_IOS_GROUP = new Group( + 'GraphQL iOS Support', + GRAPHQL_IOS_SUPPORT_GROUP_ID, + ['GraphQL'], + ['GraphQL', 'DeviceLogs'], +); + +export const SUPPORTED_GROUPS: Array = [ + LITHO_GROUP, + GRAPHQL_ANDROID_GROUP, + GRAPHQL_IOS_GROUP, +]; + export type MediaType = Array; export type SupportFormV2State = { title: string; @@ -28,7 +191,7 @@ export type SupportFormV2State = { commitHash: string; screenshots?: MediaType; videos?: MediaType; - selectedGroup: Groups; + selectedGroup: Group; }; export type SupportFormRequestDetailsState = SupportFormV2State & { @@ -71,7 +234,7 @@ export const initialState: () => State = () => ({ ].join('\n'), commitHash: '', appName: '', - selectedGroup: 'Litho Support', + selectedGroup: LITHO_GROUP, }, }); export default function reducer(