Summary: Bumps [prettier](https://github.com/prettier/prettier) from 2.2.1 to 2.3.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/releases">prettier's releases</a>.</em></p> <blockquote> <h2>2.3.0</h2> <p><a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">diff</a></p> <p>{emoji:1f517} <a href="https://prettier.io/blog/2021/05/09/2.3.0.html">Release Notes</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's changelog</a>.</em></p> <blockquote> <h1>2.3.0</h1> <p><a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">diff</a></p> <p>{emoji:1f517} <a href="https://prettier.io/blog/2021/05/09/2.3.0.html">Release Notes</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="2afc3b9ae6"><code>2afc3b9</code></a> Release 2.3.0</li> <li><a href="7cfa9aa89b"><code>7cfa9aa</code></a> Fix pre-commit hook setup command (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10710">#10710</a>)</li> <li><a href="c8c02b4753"><code>c8c02b4</code></a> Build(deps-dev): Bump concurrently from 6.0.2 to 6.1.0 in /website (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10834">#10834</a>)</li> <li><a href="6506e0f50e"><code>6506e0f</code></a> Build(deps-dev): Bump webpack-cli from 4.6.0 to 4.7.0 in /website (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10836">#10836</a>)</li> <li><a href="69fae9c291"><code>69fae9c</code></a> Build(deps): Bump flow-parser from 0.150.0 to 0.150.1 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10839">#10839</a>)</li> <li><a href="164a6e2351"><code>164a6e2</code></a> Switch CLI to async (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10804">#10804</a>)</li> <li><a href="d3e7e2f634"><code>d3e7e2f</code></a> Build(deps): Bump codecov/codecov-action from v1.4.1 to v1.5.0 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10833">#10833</a>)</li> <li><a href="9e09845da0"><code>9e09845</code></a> Build(deps): Bump <code>@angular/compiler</code> from 11.2.12 to 11.2.13 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10838">#10838</a>)</li> <li><a href="1bfab3d045"><code>1bfab3d</code></a> Build(deps-dev): Bump eslint from 7.25.0 to 7.26.0 (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10840">#10840</a>)</li> <li><a href="387fce4ed8"><code>387fce4</code></a> Minor formatting tweaks (<a href="https://github-redirect.dependabot.com/prettier/prettier/issues/10807">#10807</a>)</li> <li>Additional commits viewable in <a href="https://github.com/prettier/prettier/compare/2.2.1...2.3.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `dependabot rebase` will rebase this PR - `dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `dependabot merge` will merge this PR after your CI passes on it - `dependabot squash and merge` will squash and merge this PR after your CI passes on it - `dependabot cancel merge` will cancel a previously requested merge and block automerging - `dependabot reopen` will reopen this PR if it is closed - `dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Pull Request resolved: https://github.com/facebook/flipper/pull/2300 Reviewed By: passy Differential Revision: D28323849 Pulled By: cekkaewnumchai fbshipit-source-id: 1842877ccc9a9587af7f0d9ff9432c2075c8ee22
375 lines
10 KiB
TypeScript
375 lines
10 KiB
TypeScript
/**
|
|
* 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 {Actions, Store} from './';
|
|
import {setStaticView} from './connections';
|
|
import {deconstructClientId} from '../utils/clientUtils';
|
|
import {switchPlugin} from './pluginManager';
|
|
import {showStatusUpdatesForDuration} from '../utils/promiseTimeout';
|
|
import {selectedPlugins as setSelectedPlugins} from './plugins';
|
|
import {addStatusMessage, removeStatusMessage} from './application';
|
|
import constants from '../fb-stubs/constants';
|
|
import {getInstance} from '../fb-stubs/Logger';
|
|
import {logPlatformSuccessRate} from '../utils/metrics';
|
|
import {getExportablePlugins} from '../utils/pluginUtils';
|
|
export const SUPPORT_FORM_PREFIX = 'support-form-v2';
|
|
import Client from '../Client';
|
|
import BaseDevice, {OS} from '../devices/BaseDevice';
|
|
|
|
const {DEFAULT_SUPPORT_GROUP} = constants;
|
|
|
|
type SubmediaType =
|
|
| {uploadID: string; status: 'Uploaded'}
|
|
| {status: 'NotUploaded' | 'Uploading'};
|
|
type MediaObject = SubmediaType & {
|
|
description: string;
|
|
path: string;
|
|
};
|
|
|
|
export type GroupValidationErrors = {
|
|
plugins: string | null;
|
|
os: string | null;
|
|
};
|
|
|
|
export class Group {
|
|
constructor(
|
|
name: string,
|
|
workplaceGroupID: number,
|
|
requiredPlugins: Array<string>,
|
|
defaultPlugins: Array<string>,
|
|
supportedOS: Array<OS>,
|
|
deeplinkSuffix: string,
|
|
papercuts?: string,
|
|
) {
|
|
this.name = name;
|
|
this.requiredPlugins = requiredPlugins;
|
|
this.defaultPlugins = defaultPlugins;
|
|
this.workplaceGroupID = workplaceGroupID;
|
|
this.supportedOS = supportedOS;
|
|
this.deeplinkSuffix = deeplinkSuffix;
|
|
this.papercuts = papercuts;
|
|
}
|
|
readonly name: string;
|
|
requiredPlugins: Array<string>;
|
|
defaultPlugins: Array<string>;
|
|
workplaceGroupID: number;
|
|
supportedOS: Array<OS>;
|
|
deeplinkSuffix: string;
|
|
papercuts?: string;
|
|
|
|
getPluginsToSelect(): Array<string> {
|
|
return Array.from(
|
|
new Set([...this.defaultPlugins, ...this.requiredPlugins]),
|
|
);
|
|
}
|
|
|
|
getValidationMessage(
|
|
selectedPlugins: Array<string>,
|
|
selectedOS: OS | null,
|
|
): GroupValidationErrors {
|
|
const nonSelectedPlugin: Array<string> = [];
|
|
for (const plugin of this.requiredPlugins) {
|
|
if (!selectedPlugins.includes(plugin)) {
|
|
nonSelectedPlugin.push(plugin);
|
|
}
|
|
}
|
|
|
|
// Plugin validation
|
|
let str: string | null =
|
|
'should be exported if you want to submit to this group. Make sure, if your selected app supports those plugins, if so then enable it and select it from the plugin selection.';
|
|
if (nonSelectedPlugin.length == 1) {
|
|
str = `the ${nonSelectedPlugin.pop()} plugin ${str}`;
|
|
} else if (nonSelectedPlugin.length > 1) {
|
|
const lastPlugin = nonSelectedPlugin.pop();
|
|
str = `the ${nonSelectedPlugin.join(',')} and ${lastPlugin} ${str}`;
|
|
} else {
|
|
// nonSelectedPlugin is empty
|
|
str = null;
|
|
}
|
|
|
|
// OS validation
|
|
let osError: string | null = null;
|
|
if (this.name !== 'Flipper') {
|
|
if (!selectedOS) {
|
|
osError = 'Please select an app from the drop down.';
|
|
} else if (!this.supportedOS.includes(selectedOS)) {
|
|
osError = `The group ${
|
|
this.name
|
|
} supports exports from ${this.supportedOS.join(
|
|
', ',
|
|
)}. But your selected device's OS is ${selectedOS}, which is unsupported.`;
|
|
}
|
|
}
|
|
return {plugins: str, os: osError};
|
|
}
|
|
|
|
handleSupportFormDeeplinks(store: Store) {
|
|
getInstance().track('usage', 'support-form-source', {
|
|
source: 'deeplink',
|
|
group: this.name,
|
|
});
|
|
store.dispatch(
|
|
setStaticView(require('../fb-stubs/SupportRequestFormV2').default),
|
|
);
|
|
const selectedApp = store.getState().connections.selectedApp;
|
|
const selectedClient = store.getState().connections.clients.find((o) => {
|
|
return o.id === store.getState().connections.selectedApp;
|
|
});
|
|
let errorMessage: string | undefined = undefined;
|
|
if (selectedApp) {
|
|
const {app} = deconstructClientId(selectedApp);
|
|
const enabledPlugins: Array<string> | null =
|
|
store.getState().connections.enabledPlugins[app];
|
|
const unsupportedPlugins = [];
|
|
for (const requiredPlugin of this.requiredPlugins) {
|
|
const requiredPluginEnabled =
|
|
enabledPlugins != null && enabledPlugins.includes(requiredPlugin);
|
|
if (
|
|
selectedClient &&
|
|
selectedClient.plugins.includes(requiredPlugin) &&
|
|
!requiredPluginEnabled
|
|
) {
|
|
const plugin =
|
|
store.getState().plugins.clientPlugins.get(requiredPlugin) ||
|
|
store.getState().plugins.devicePlugins.get(requiredPlugin)!;
|
|
store.dispatch(
|
|
switchPlugin({
|
|
selectedApp: app,
|
|
plugin,
|
|
}),
|
|
);
|
|
} else if (
|
|
!selectedClient ||
|
|
!selectedClient.plugins.includes(requiredPlugin)
|
|
) {
|
|
unsupportedPlugins.push(requiredPlugin);
|
|
}
|
|
}
|
|
if (unsupportedPlugins.length > 0) {
|
|
errorMessage = `The current client does not support ${unsupportedPlugins.join(
|
|
', ',
|
|
)}. Please change the app from the dropdown in the support form.`;
|
|
logPlatformSuccessRate(`${SUPPORT_FORM_PREFIX}-deeplink`, {
|
|
kind: 'failure',
|
|
supportedOperation: true,
|
|
error: errorMessage,
|
|
});
|
|
showStatusUpdatesForDuration(
|
|
errorMessage,
|
|
'Deeplink',
|
|
10000,
|
|
(payload) => {
|
|
store.dispatch(addStatusMessage(payload));
|
|
},
|
|
(payload) => {
|
|
store.dispatch(removeStatusMessage(payload));
|
|
},
|
|
);
|
|
}
|
|
} else {
|
|
errorMessage =
|
|
'Selected app is null, thus the deeplink failed to enable required plugin.';
|
|
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 = getExportablePlugins(
|
|
store.getState(),
|
|
store.getState().connections.selectedDevice ?? undefined,
|
|
selectedClient,
|
|
);
|
|
|
|
store.dispatch(
|
|
setSelectedPlugins(
|
|
this.getPluginsToSelect().filter((s) => {
|
|
return pluginsList.map((s) => s.id).includes(s);
|
|
}),
|
|
),
|
|
);
|
|
logPlatformSuccessRate(
|
|
`${SUPPORT_FORM_PREFIX}-deeplink`,
|
|
errorMessage
|
|
? {
|
|
kind: 'failure',
|
|
supportedOperation: true,
|
|
error: errorMessage,
|
|
}
|
|
: {kind: 'success'},
|
|
);
|
|
}
|
|
|
|
getWarningMessage(
|
|
state: Parameters<typeof getExportablePlugins>[0],
|
|
device: BaseDevice | undefined,
|
|
client: Client,
|
|
): string | null {
|
|
const activePersistentPlugins = getExportablePlugins(state, device, client);
|
|
const emptyPlugins: Array<string> = [];
|
|
for (const plugin of this.requiredPlugins) {
|
|
if (
|
|
!activePersistentPlugins.find((o) => {
|
|
return o.id === plugin;
|
|
})
|
|
) {
|
|
emptyPlugins.push(plugin);
|
|
}
|
|
}
|
|
const commonStr = 'Are you sure you want to submit?';
|
|
if (emptyPlugins.length == 1) {
|
|
return `There is no data in ${emptyPlugins.pop()} plugin. ${commonStr}`;
|
|
} else if (emptyPlugins.length > 1) {
|
|
return `The following plugins have no data: ${emptyPlugins.join(
|
|
',',
|
|
)}. ${commonStr}`;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const DEFAULT_GROUP = new Group(
|
|
DEFAULT_SUPPORT_GROUP.name,
|
|
DEFAULT_SUPPORT_GROUP.workplaceGroupID,
|
|
DEFAULT_SUPPORT_GROUP.requiredPlugins,
|
|
DEFAULT_SUPPORT_GROUP.defaultPlugins,
|
|
DEFAULT_SUPPORT_GROUP.supportedOS,
|
|
DEFAULT_SUPPORT_GROUP.deeplinkSuffix,
|
|
DEFAULT_SUPPORT_GROUP.papercuts,
|
|
);
|
|
|
|
export const SUPPORTED_GROUPS: Array<Group> = [
|
|
DEFAULT_GROUP,
|
|
...constants.SUPPORT_GROUPS.map(
|
|
({
|
|
name,
|
|
workplaceGroupID,
|
|
requiredPlugins,
|
|
defaultPlugins,
|
|
supportedOS,
|
|
deeplinkSuffix,
|
|
papercuts,
|
|
}) => {
|
|
return new Group(
|
|
name,
|
|
workplaceGroupID,
|
|
requiredPlugins,
|
|
defaultPlugins,
|
|
supportedOS,
|
|
deeplinkSuffix,
|
|
papercuts,
|
|
);
|
|
},
|
|
),
|
|
];
|
|
|
|
export type MediaType = Array<MediaObject>;
|
|
export type SupportFormV2State = {
|
|
title: string;
|
|
description: string;
|
|
commitHash: string;
|
|
screenshots?: MediaType;
|
|
videos?: MediaType;
|
|
selectedGroup: Group;
|
|
};
|
|
|
|
export type SupportFormRequestDetailsState = SupportFormV2State & {
|
|
appName: string;
|
|
};
|
|
export type State = {
|
|
webState: NTUsersFormData | null;
|
|
supportFormV2: SupportFormV2State;
|
|
};
|
|
export type Action =
|
|
| {
|
|
type: 'SET_SUPPORT_FORM_STATE';
|
|
payload: NTUsersFormData | null;
|
|
}
|
|
| {
|
|
type: 'SET_SUPPORT_FORM_V2_STATE';
|
|
payload: SupportFormV2State;
|
|
}
|
|
| {
|
|
type: 'RESET_SUPPORT_FORM_V2_STATE';
|
|
};
|
|
|
|
export type NTUsersFormData = {
|
|
flipper_trace: string | null;
|
|
};
|
|
|
|
export const initialState: () => State = () => ({
|
|
webState: null,
|
|
supportFormV2: {
|
|
title: '',
|
|
description: [
|
|
'## Context',
|
|
'What are you trying to accomplish at a high level? Feel free to include mocks and tasks.',
|
|
'',
|
|
'## Problem',
|
|
"What's blocking you?",
|
|
'',
|
|
"## Workarounds I've Tried",
|
|
'',
|
|
].join('\n'),
|
|
commitHash: '',
|
|
appName: '',
|
|
selectedGroup: DEFAULT_GROUP,
|
|
},
|
|
});
|
|
export default function reducer(
|
|
state: State | undefined,
|
|
action: Actions,
|
|
): State {
|
|
state = state || initialState();
|
|
if (action.type === 'SET_SUPPORT_FORM_STATE') {
|
|
return {
|
|
...state,
|
|
webState: action.payload,
|
|
};
|
|
} else if (action.type === 'SET_SUPPORT_FORM_V2_STATE') {
|
|
return {
|
|
...state,
|
|
supportFormV2: action.payload,
|
|
};
|
|
} else if (action.type === 'RESET_SUPPORT_FORM_V2_STATE') {
|
|
return initialState();
|
|
} else {
|
|
return state;
|
|
}
|
|
}
|
|
|
|
export const setSupportFormState = (
|
|
payload: NTUsersFormData | null,
|
|
): Action => ({
|
|
type: 'SET_SUPPORT_FORM_STATE',
|
|
payload,
|
|
});
|
|
|
|
export const setSupportFormV2State = (payload: SupportFormV2State): Action => ({
|
|
type: 'SET_SUPPORT_FORM_V2_STATE',
|
|
payload,
|
|
});
|
|
|
|
export const resetSupportFormV2State = (): Action => ({
|
|
type: 'RESET_SUPPORT_FORM_V2_STATE',
|
|
});
|