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 {FlipperPlugin, FlipperDevicePlugin} from './plugin';
|
||||||
import {showOpenDialog} from './utils/exportData';
|
|
||||||
import {
|
import {
|
||||||
setSelectPluginsToExportActiveSheet,
|
showOpenDialog,
|
||||||
|
startFileExport,
|
||||||
|
startLinkExport,
|
||||||
|
} from './utils/exportData';
|
||||||
|
import {
|
||||||
setActiveSheet,
|
setActiveSheet,
|
||||||
ACTIVE_SHEET_PLUGINS,
|
ACTIVE_SHEET_PLUGINS,
|
||||||
ACTIVE_SHEET_SETTINGS,
|
ACTIVE_SHEET_SETTINGS,
|
||||||
@@ -21,8 +24,6 @@ import {Store} from './reducers/';
|
|||||||
import electron, {MenuItemConstructorOptions} from 'electron';
|
import electron, {MenuItemConstructorOptions} from 'electron';
|
||||||
import {notNull} from './utils/typeUtils';
|
import {notNull} from './utils/typeUtils';
|
||||||
import constants from './fb-stubs/constants';
|
import constants from './fb-stubs/constants';
|
||||||
import os from 'os';
|
|
||||||
import path from 'path';
|
|
||||||
import GK from './fb-stubs/GK';
|
import GK from './fb-stubs/GK';
|
||||||
|
|
||||||
export type DefaultKeyboardAction = 'clear' | 'goToBottom' | 'createPaste';
|
export type DefaultKeyboardAction = 'clear' | 'goToBottom' | 'createPaste';
|
||||||
@@ -186,44 +187,14 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'File...',
|
label: 'File...',
|
||||||
accelerator: 'CommandOrControl+E',
|
accelerator: 'CommandOrControl+E',
|
||||||
click: function() {
|
click: () => startFileExport(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;
|
|
||||||
}
|
|
||||||
store.dispatch(
|
|
||||||
setSelectPluginsToExportActiveSheet({
|
|
||||||
type: 'file',
|
|
||||||
file: file,
|
|
||||||
closeOnFinish: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (constants.ENABLE_SHAREABLE_LINK) {
|
if (constants.ENABLE_SHAREABLE_LINK) {
|
||||||
exportSubmenu.push({
|
exportSubmenu.push({
|
||||||
label: 'Shareable Link',
|
label: 'Shareable Link',
|
||||||
accelerator: 'CommandOrControl+Shift+E',
|
accelerator: 'CommandOrControl+Shift+E',
|
||||||
click: function() {
|
click: () => startLinkExport(store.dispatch),
|
||||||
store.dispatch(
|
|
||||||
setSelectPluginsToExportActiveSheet({
|
|
||||||
type: 'link',
|
|
||||||
closeOnFinish: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const fileSubmenu: MenuItemConstructorOptions[] = [
|
const fileSubmenu: MenuItemConstructorOptions[] = [
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ const Container = styled(FlexColumn)({
|
|||||||
width: 500,
|
width: 500,
|
||||||
});
|
});
|
||||||
|
|
||||||
const Center = styled(FlexColumn)({
|
|
||||||
alignItems: 'center',
|
|
||||||
paddingTop: 50,
|
|
||||||
paddingBottom: 50,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ErrorMessage = styled(Text)({
|
const ErrorMessage = styled(Text)({
|
||||||
display: 'block',
|
display: 'block',
|
||||||
marginTop: 6,
|
marginTop: 6,
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import CancellableExportStatus from './CancellableExportStatus';
|
|||||||
import {performance} from 'perf_hooks';
|
import {performance} from 'perf_hooks';
|
||||||
import ShareSheetPendingDialog from './ShareSheetPendingDialog';
|
import ShareSheetPendingDialog from './ShareSheetPendingDialog';
|
||||||
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
||||||
|
import {resetSupportFormV2State} from '../reducers/supportForm';
|
||||||
export const SHARE_FLIPPER_TRACE_EVENT = 'share-flipper-link';
|
export const SHARE_FLIPPER_TRACE_EVENT = 'share-flipper-link';
|
||||||
|
|
||||||
const Container = styled(FlexColumn)({
|
const Container = styled(FlexColumn)({
|
||||||
@@ -142,6 +143,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
|||||||
requireInteraction: true,
|
requireInteraction: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
store.dispatch(resetSupportFormV2State());
|
||||||
this.props.logger.trackTimeSince(mark, 'export:url-success');
|
this.props.logger.trackTimeSince(mark, 'export:url-success');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!this.state.runInBackground) {
|
if (!this.state.runInBackground) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import BaseDevice from './BaseDevice';
|
import BaseDevice from './BaseDevice';
|
||||||
import {DeviceType, OS, DeviceShell, DeviceLogEntry} from './BaseDevice';
|
import {DeviceType, OS, DeviceShell, DeviceLogEntry} from './BaseDevice';
|
||||||
import {SupportRequestDetailsMetaData} from '../utils/exportData';
|
import {SupportFormV2State} from '../reducers/supportForm';
|
||||||
|
|
||||||
function normalizeArchivedDeviceType(deviceType: DeviceType): DeviceType {
|
function normalizeArchivedDeviceType(deviceType: DeviceType): DeviceType {
|
||||||
let archivedDeviceType = deviceType;
|
let archivedDeviceType = deviceType;
|
||||||
@@ -29,7 +29,7 @@ export default class ArchivedDevice extends BaseDevice {
|
|||||||
os: OS,
|
os: OS,
|
||||||
logEntries: Array<DeviceLogEntry>,
|
logEntries: Array<DeviceLogEntry>,
|
||||||
source: string = '',
|
source: string = '',
|
||||||
supportRequestDetails?: SupportRequestDetailsMetaData,
|
supportRequestDetails?: SupportFormV2State,
|
||||||
) {
|
) {
|
||||||
super(serial, normalizeArchivedDeviceType(deviceType), title, os);
|
super(serial, normalizeArchivedDeviceType(deviceType), title, os);
|
||||||
this.logs = logEntries;
|
this.logs = logEntries;
|
||||||
@@ -41,7 +41,7 @@ export default class ArchivedDevice extends BaseDevice {
|
|||||||
|
|
||||||
isArchived = true;
|
isArchived = true;
|
||||||
|
|
||||||
supportRequestDetails?: SupportRequestDetailsMetaData;
|
supportRequestDetails?: SupportFormV2State;
|
||||||
|
|
||||||
getLogs() {
|
getLogs() {
|
||||||
return this.logs;
|
return this.logs;
|
||||||
|
|||||||
@@ -169,6 +169,14 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
|||||||
selectedPlugin: payload != null ? null : selectedPlugin,
|
selectedPlugin: payload != null ? null : selectedPlugin,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'RESET_SUPPORT_FORM_V2_STATE': {
|
||||||
|
return updateSelection({
|
||||||
|
...state,
|
||||||
|
staticView: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
case 'SELECT_DEVICE': {
|
case 'SELECT_DEVICE': {
|
||||||
const {payload} = action;
|
const {payload} = action;
|
||||||
return updateSelection({
|
return updateSelection({
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export type SupportFormV2State = {
|
|||||||
description: string;
|
description: string;
|
||||||
commitHash: string;
|
commitHash: string;
|
||||||
appName: string;
|
appName: string;
|
||||||
|
screenshots?: {image: string; description: string}[];
|
||||||
|
videos?: {url: string; description: string}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
@@ -27,6 +29,9 @@ export type Action =
|
|||||||
| {
|
| {
|
||||||
type: 'SET_SUPPORT_FORM_V2_STATE';
|
type: 'SET_SUPPORT_FORM_V2_STATE';
|
||||||
payload: SupportFormV2State;
|
payload: SupportFormV2State;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'RESET_SUPPORT_FORM_V2_STATE';
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NTUsersFormData = {
|
export type NTUsersFormData = {
|
||||||
@@ -66,6 +71,8 @@ export default function reducer(
|
|||||||
...state,
|
...state,
|
||||||
supportFormV2: action.payload,
|
supportFormV2: action.payload,
|
||||||
};
|
};
|
||||||
|
} else if (action.type === 'RESET_SUPPORT_FORM_V2_STATE') {
|
||||||
|
return initialState();
|
||||||
} else {
|
} else {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -82,3 +89,7 @@ export const setSupportFormV2State = (payload: SupportFormV2State): Action => ({
|
|||||||
type: 'SET_SUPPORT_FORM_V2_STATE',
|
type: 'SET_SUPPORT_FORM_V2_STATE',
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const resetSupportFormV2State = (): Action => ({
|
||||||
|
type: 'RESET_SUPPORT_FORM_V2_STATE',
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
import electron from 'electron';
|
||||||
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
import {getInstance as getLogger} from '../fb-stubs/Logger';
|
||||||
import {Store, MiddlewareAPI} from '../reducers';
|
import {Store, MiddlewareAPI} from '../reducers';
|
||||||
import {DeviceExport} from '../devices/BaseDevice';
|
import {DeviceExport} from '../devices/BaseDevice';
|
||||||
@@ -33,6 +36,12 @@ import {promisify} from 'util';
|
|||||||
import promiseTimeout from './promiseTimeout';
|
import promiseTimeout from './promiseTimeout';
|
||||||
import {Idler} from './Idler';
|
import {Idler} from './Idler';
|
||||||
import {setStaticView} from '../reducers/connections';
|
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 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';
|
||||||
export const EXPORT_FLIPPER_TRACE_TIME_SERIALIZATION_EVENT = `${EXPORT_FLIPPER_TRACE_EVENT}:serialization`;
|
export const EXPORT_FLIPPER_TRACE_TIME_SERIALIZATION_EVENT = `${EXPORT_FLIPPER_TRACE_EVENT}:serialization`;
|
||||||
@@ -49,7 +58,7 @@ export type ExportType = {
|
|||||||
pluginStates: PluginStatesExportState;
|
pluginStates: PluginStatesExportState;
|
||||||
activeNotifications: Array<PluginNotification>;
|
activeNotifications: Array<PluginNotification>;
|
||||||
};
|
};
|
||||||
supportRequestDetails?: SupportRequestDetailsMetaData;
|
supportRequestDetails?: SupportFormV2State;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProcessPluginStatesOptions = {
|
type ProcessPluginStatesOptions = {
|
||||||
@@ -83,15 +92,6 @@ type AddSaltToDeviceSerialOptions = {
|
|||||||
statusUpdate?: (msg: string) => void;
|
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(
|
export function processClients(
|
||||||
clients: Array<ClientExport>,
|
clients: Array<ClientExport>,
|
||||||
serial: string,
|
serial: string,
|
||||||
@@ -545,6 +545,7 @@ export function exportStore(
|
|||||||
idler,
|
idler,
|
||||||
);
|
);
|
||||||
if (exportData != null) {
|
if (exportData != null) {
|
||||||
|
exportData.supportRequestDetails = store.getState().supportForm?.supportFormV2;
|
||||||
statusUpdate && statusUpdate('Serializing Flipper data...');
|
statusUpdate && statusUpdate('Serializing Flipper data...');
|
||||||
const serializedString = JSON.stringify(exportData);
|
const serializedString = JSON.stringify(exportData);
|
||||||
if (serializedString.length <= 0) {
|
if (serializedString.length <= 0) {
|
||||||
@@ -578,6 +579,7 @@ export const exportStoreToFile = (
|
|||||||
({serializedString, errorArray}) => {
|
({serializedString, errorArray}) => {
|
||||||
return promisify(fs.writeFile)(exportFilePath, serializedString).then(
|
return promisify(fs.writeFile)(exportFilePath, serializedString).then(
|
||||||
() => {
|
() => {
|
||||||
|
store.dispatch(resetSupportFormV2State());
|
||||||
return {errorArray};
|
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