Make it possible to export support form V2 with meta data
Summary: This diff enables a full roundtrip of exporting a bug report to file / link, and importing it again. Styling is not part of this story. Reviewed By: jknoxville Differential Revision: D18636418 fbshipit-source-id: ef9a8e3622bdac9361f612d51415a593f4268b80
This commit is contained in:
committed by
Facebook Github Bot
parent
f33666a4b9
commit
dd65ec6ed0
@@ -8,9 +8,12 @@
|
||||
*/
|
||||
|
||||
import {FlipperPlugin, FlipperDevicePlugin} from './plugin';
|
||||
import {showOpenDialog} from './utils/exportData';
|
||||
import {
|
||||
setSelectPluginsToExportActiveSheet,
|
||||
showOpenDialog,
|
||||
startFileExport,
|
||||
startLinkExport,
|
||||
} from './utils/exportData';
|
||||
import {
|
||||
setActiveSheet,
|
||||
ACTIVE_SHEET_PLUGINS,
|
||||
ACTIVE_SHEET_SETTINGS,
|
||||
@@ -21,8 +24,6 @@ import {Store} from './reducers/';
|
||||
import electron, {MenuItemConstructorOptions} from 'electron';
|
||||
import {notNull} from './utils/typeUtils';
|
||||
import constants from './fb-stubs/constants';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import GK from './fb-stubs/GK';
|
||||
|
||||
export type DefaultKeyboardAction = 'clear' | 'goToBottom' | 'createPaste';
|
||||
@@ -186,44 +187,14 @@ function getTemplate(
|
||||
{
|
||||
label: 'File...',
|
||||
accelerator: 'CommandOrControl+E',
|
||||
click: function() {
|
||||
electron.remote.dialog
|
||||
.showSaveDialog(
|
||||
// @ts-ignore This appears to work but isn't allowed by the types
|
||||
null,
|
||||
{
|
||||
title: 'FlipperExport',
|
||||
defaultPath: path.join(os.homedir(), 'FlipperExport.flipper'),
|
||||
},
|
||||
)
|
||||
.then(async (result: electron.SaveDialogReturnValue) => {
|
||||
const file = result.filePath;
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
store.dispatch(
|
||||
setSelectPluginsToExportActiveSheet({
|
||||
type: 'file',
|
||||
file: file,
|
||||
closeOnFinish: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
},
|
||||
click: () => startFileExport(store.dispatch),
|
||||
},
|
||||
];
|
||||
if (constants.ENABLE_SHAREABLE_LINK) {
|
||||
exportSubmenu.push({
|
||||
label: 'Shareable Link',
|
||||
accelerator: 'CommandOrControl+Shift+E',
|
||||
click: function() {
|
||||
store.dispatch(
|
||||
setSelectPluginsToExportActiveSheet({
|
||||
type: 'link',
|
||||
closeOnFinish: false,
|
||||
}),
|
||||
);
|
||||
},
|
||||
click: () => startLinkExport(store.dispatch),
|
||||
});
|
||||
}
|
||||
const fileSubmenu: MenuItemConstructorOptions[] = [
|
||||
|
||||
@@ -29,12 +29,6 @@ const Container = styled(FlexColumn)({
|
||||
width: 500,
|
||||
});
|
||||
|
||||
const Center = styled(FlexColumn)({
|
||||
alignItems: 'center',
|
||||
paddingTop: 50,
|
||||
paddingBottom: 50,
|
||||
});
|
||||
|
||||
const ErrorMessage = styled(Text)({
|
||||
display: 'block',
|
||||
marginTop: 6,
|
||||
|
||||
@@ -39,6 +39,7 @@ import CancellableExportStatus from './CancellableExportStatus';
|
||||
import {performance} from 'perf_hooks';
|
||||
import ShareSheetPendingDialog from './ShareSheetPendingDialog';
|
||||
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
||||
import {resetSupportFormV2State} from '../reducers/supportForm';
|
||||
export const SHARE_FLIPPER_TRACE_EVENT = 'share-flipper-link';
|
||||
|
||||
const Container = styled(FlexColumn)({
|
||||
@@ -142,6 +143,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
requireInteraction: true,
|
||||
});
|
||||
}
|
||||
store.dispatch(resetSupportFormV2State());
|
||||
this.props.logger.trackTimeSince(mark, 'export:url-success');
|
||||
} catch (e) {
|
||||
if (!this.state.runInBackground) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import BaseDevice from './BaseDevice';
|
||||
import {DeviceType, OS, DeviceShell, DeviceLogEntry} from './BaseDevice';
|
||||
import {SupportRequestDetailsMetaData} from '../utils/exportData';
|
||||
import {SupportFormV2State} from '../reducers/supportForm';
|
||||
|
||||
function normalizeArchivedDeviceType(deviceType: DeviceType): DeviceType {
|
||||
let archivedDeviceType = deviceType;
|
||||
@@ -29,7 +29,7 @@ export default class ArchivedDevice extends BaseDevice {
|
||||
os: OS,
|
||||
logEntries: Array<DeviceLogEntry>,
|
||||
source: string = '',
|
||||
supportRequestDetails?: SupportRequestDetailsMetaData,
|
||||
supportRequestDetails?: SupportFormV2State,
|
||||
) {
|
||||
super(serial, normalizeArchivedDeviceType(deviceType), title, os);
|
||||
this.logs = logEntries;
|
||||
@@ -41,7 +41,7 @@ export default class ArchivedDevice extends BaseDevice {
|
||||
|
||||
isArchived = true;
|
||||
|
||||
supportRequestDetails?: SupportRequestDetailsMetaData;
|
||||
supportRequestDetails?: SupportFormV2State;
|
||||
|
||||
getLogs() {
|
||||
return this.logs;
|
||||
|
||||
@@ -169,6 +169,14 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
||||
selectedPlugin: payload != null ? null : selectedPlugin,
|
||||
};
|
||||
}
|
||||
|
||||
case 'RESET_SUPPORT_FORM_V2_STATE': {
|
||||
return updateSelection({
|
||||
...state,
|
||||
staticView: null,
|
||||
});
|
||||
}
|
||||
|
||||
case 'SELECT_DEVICE': {
|
||||
const {payload} = action;
|
||||
return updateSelection({
|
||||
|
||||
@@ -13,6 +13,8 @@ export type SupportFormV2State = {
|
||||
description: string;
|
||||
commitHash: string;
|
||||
appName: string;
|
||||
screenshots?: {image: string; description: string}[];
|
||||
videos?: {url: string; description: string}[];
|
||||
};
|
||||
|
||||
export type State = {
|
||||
@@ -27,6 +29,9 @@ export type Action =
|
||||
| {
|
||||
type: 'SET_SUPPORT_FORM_V2_STATE';
|
||||
payload: SupportFormV2State;
|
||||
}
|
||||
| {
|
||||
type: 'RESET_SUPPORT_FORM_V2_STATE';
|
||||
};
|
||||
|
||||
export type NTUsersFormData = {
|
||||
@@ -66,6 +71,8 @@ export default function reducer(
|
||||
...state,
|
||||
supportFormV2: action.payload,
|
||||
};
|
||||
} else if (action.type === 'RESET_SUPPORT_FORM_V2_STATE') {
|
||||
return initialState();
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
@@ -82,3 +89,7 @@ export const setSupportFormV2State = (payload: SupportFormV2State): Action => ({
|
||||
type: 'SET_SUPPORT_FORM_V2_STATE',
|
||||
payload,
|
||||
});
|
||||
|
||||
export const resetSupportFormV2State = (): Action => ({
|
||||
type: 'RESET_SUPPORT_FORM_V2_STATE',
|
||||
});
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import electron from 'electron';
|
||||
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
||||
import {Store, MiddlewareAPI} from '../reducers';
|
||||
import {DeviceExport} from '../devices/BaseDevice';
|
||||
@@ -33,6 +36,12 @@ import {promisify} from 'util';
|
||||
import promiseTimeout from './promiseTimeout';
|
||||
import {Idler} from './Idler';
|
||||
import {setStaticView} from '../reducers/connections';
|
||||
import {
|
||||
SupportFormV2State,
|
||||
resetSupportFormV2State,
|
||||
} from '../reducers/supportForm';
|
||||
import {setSelectPluginsToExportActiveSheet} from '../reducers/application';
|
||||
|
||||
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
|
||||
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
|
||||
export const EXPORT_FLIPPER_TRACE_TIME_SERIALIZATION_EVENT = `${EXPORT_FLIPPER_TRACE_EVENT}:serialization`;
|
||||
@@ -49,7 +58,7 @@ export type ExportType = {
|
||||
pluginStates: PluginStatesExportState;
|
||||
activeNotifications: Array<PluginNotification>;
|
||||
};
|
||||
supportRequestDetails?: SupportRequestDetailsMetaData;
|
||||
supportRequestDetails?: SupportFormV2State;
|
||||
};
|
||||
|
||||
type ProcessPluginStatesOptions = {
|
||||
@@ -83,15 +92,6 @@ type AddSaltToDeviceSerialOptions = {
|
||||
statusUpdate?: (msg: string) => void;
|
||||
};
|
||||
|
||||
export type SupportRequestDetailsMetaData = {
|
||||
title: string;
|
||||
app: string;
|
||||
description: string;
|
||||
commitHash: string;
|
||||
screenshots: {image: string; description: string}[];
|
||||
videos: {url: string; description: string}[];
|
||||
};
|
||||
|
||||
export function processClients(
|
||||
clients: Array<ClientExport>,
|
||||
serial: string,
|
||||
@@ -545,6 +545,7 @@ export function exportStore(
|
||||
idler,
|
||||
);
|
||||
if (exportData != null) {
|
||||
exportData.supportRequestDetails = store.getState().supportForm?.supportFormV2;
|
||||
statusUpdate && statusUpdate('Serializing Flipper data...');
|
||||
const serializedString = JSON.stringify(exportData);
|
||||
if (serializedString.length <= 0) {
|
||||
@@ -578,6 +579,7 @@ export const exportStoreToFile = (
|
||||
({serializedString, errorArray}) => {
|
||||
return promisify(fs.writeFile)(exportFilePath, serializedString).then(
|
||||
() => {
|
||||
store.dispatch(resetSupportFormV2State());
|
||||
return {errorArray};
|
||||
},
|
||||
);
|
||||
@@ -697,3 +699,37 @@ export function showOpenDialog(store: Store) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function startFileExport(dispatch: Store['dispatch']) {
|
||||
electron.remote.dialog
|
||||
.showSaveDialog(
|
||||
// @ts-ignore This appears to work but isn't allowed by the types
|
||||
null,
|
||||
{
|
||||
title: 'FlipperExport',
|
||||
defaultPath: path.join(os.homedir(), 'FlipperExport.flipper'),
|
||||
},
|
||||
)
|
||||
.then(async (result: electron.SaveDialogReturnValue) => {
|
||||
const file = result.filePath;
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
dispatch(
|
||||
setSelectPluginsToExportActiveSheet({
|
||||
type: 'file',
|
||||
file: file,
|
||||
closeOnFinish: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function startLinkExport(dispatch: Store['dispatch']) {
|
||||
dispatch(
|
||||
setSelectPluginsToExportActiveSheet({
|
||||
type: 'link',
|
||||
closeOnFinish: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user