Network Plugin - Disable routes (#1969)
Summary: Mock routes may contain quite a bit of data for header values and response bodies. Currently, to turn off a mock a user must delete the mock and then go through the process of creating it when needed again. This change will allow a user to temporarily disable a mock without deleting it. A checkbox on the Routes list is used to enable/disable mocks. As shown in this screenshot:  ## Changelog Network Plugin - disable/enable mock routes Pull Request resolved: https://github.com/facebook/flipper/pull/1969 Test Plan: Create mocks using sample app Verify that mocks are working as expected Disable the mocks Verify that the client has been updated with mocks (minus the disabled ones) user Flipper Messages plugin Use the sample app to send the disabled requests again and verify that they are not mocked Reviewed By: mweststrate Differential Revision: D26888815 Pulled By: passy fbshipit-source-id: cb8a05a27dd69ba4d2b60085a077efe795a99a7c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c82313b161
commit
d07b74eed0
@@ -17,14 +17,11 @@ import {
|
||||
Panel,
|
||||
} from 'flipper';
|
||||
import React, {useContext, useState, useMemo, useEffect} from 'react';
|
||||
|
||||
import {Route, Request, Response} from './types';
|
||||
|
||||
import {MockResponseDetails} from './MockResponseDetails';
|
||||
import {NetworkRouteContext} from './index';
|
||||
import {RequestId} from './types';
|
||||
|
||||
import {message, Modal} from 'antd';
|
||||
import {message, Checkbox, Modal, Tooltip} from 'antd';
|
||||
import {NUX, Layout} from 'flipper-plugin';
|
||||
|
||||
type Props = {
|
||||
@@ -77,6 +74,7 @@ function _buildRows(
|
||||
routes: {[id: string]: Route},
|
||||
duplicatedIds: Array<string>,
|
||||
handleRemoveId: (id: string) => void,
|
||||
handleEnableId: (id: string) => void,
|
||||
) {
|
||||
return Object.entries(routes).map(([id, route]) => ({
|
||||
columns: {
|
||||
@@ -87,6 +85,8 @@ function _buildRows(
|
||||
text={route.requestUrl}
|
||||
showWarning={duplicatedIds.includes(id)}
|
||||
handleRemoveId={() => handleRemoveId(id)}
|
||||
handleEnableId={() => handleEnableId(id)}
|
||||
enabled={route.enabled}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -99,27 +99,35 @@ function RouteRow(props: {
|
||||
text: string;
|
||||
showWarning: boolean;
|
||||
handleRemoveId: () => void;
|
||||
handleEnableId: () => void;
|
||||
enabled: boolean;
|
||||
}) {
|
||||
const tip = props.enabled
|
||||
? 'Un-check to disable mock route'
|
||||
: 'Check to enable mock route';
|
||||
return (
|
||||
<Layout.Container>
|
||||
<Layout.Horizontal style={{paddingBottom: 20}}>
|
||||
<Layout.Horizontal gap>
|
||||
<Tooltip title={tip} mouseEnterDelay={1.1}>
|
||||
<Checkbox
|
||||
onClick={props.handleEnableId}
|
||||
checked={props.enabled}></Checkbox>
|
||||
</Tooltip>
|
||||
<Tooltip title="Click to delete mock route" mouseEnterDelay={1.1}>
|
||||
<Layout.Horizontal onClick={props.handleRemoveId}>
|
||||
<Icon name="cross-circle" color={colors.red} />
|
||||
</Layout.Horizontal>
|
||||
<Layout.Horizontal>
|
||||
{props.showWarning && (
|
||||
<Icon name="caution-triangle" color={colors.yellow} />
|
||||
)}
|
||||
{props.text.length === 0 ? (
|
||||
<TextEllipsis style={{color: colors.blackAlpha50}}>
|
||||
untitled
|
||||
</TextEllipsis>
|
||||
) : (
|
||||
<TextEllipsis>{props.text}</TextEllipsis>
|
||||
)}
|
||||
</Layout.Horizontal>
|
||||
</Layout.Horizontal>
|
||||
</Layout.Container>
|
||||
</Tooltip>
|
||||
{props.showWarning && (
|
||||
<Icon name="caution-triangle" color={colors.yellow} />
|
||||
)}
|
||||
{props.text.length === 0 ? (
|
||||
<TextEllipsis style={{color: colors.blackAlpha50}}>
|
||||
untitled
|
||||
</TextEllipsis>
|
||||
) : (
|
||||
<TextEllipsis>{props.text}</TextEllipsis>
|
||||
)}
|
||||
</Layout.Horizontal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -248,19 +256,25 @@ export function ManageMockResponsePanel(props: Props) {
|
||||
multiline={false}
|
||||
columnSizes={ColumnSizes}
|
||||
columns={Columns}
|
||||
rowLineHeight={26}
|
||||
rows={_buildRows(props.routes, duplicatedIds, (id) => {
|
||||
Modal.confirm({
|
||||
title: 'Are you sure you want to delete this item?',
|
||||
icon: '',
|
||||
onOk() {
|
||||
const nextId = getNextId(id);
|
||||
networkRouteManager.removeRoute(id);
|
||||
setSelectedId(nextId);
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
})}
|
||||
rows={_buildRows(
|
||||
props.routes,
|
||||
duplicatedIds,
|
||||
(id) => {
|
||||
Modal.confirm({
|
||||
title: 'Are you sure you want to delete this item?',
|
||||
icon: '',
|
||||
onOk() {
|
||||
const nextId = getNextId(id);
|
||||
networkRouteManager.removeRoute(id);
|
||||
setSelectedId(nextId);
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
},
|
||||
(id) => {
|
||||
networkRouteManager.enableRoute(id);
|
||||
},
|
||||
)}
|
||||
stickyBottom={true}
|
||||
autoHeight={false}
|
||||
floating={false}
|
||||
|
||||
@@ -127,6 +127,7 @@ export interface NetworkRouteManager {
|
||||
addRoute(): string | null;
|
||||
modifyRoute(id: string, routeChange: Partial<Route>): void;
|
||||
removeRoute(id: string): void;
|
||||
enableRoute(id: string): void;
|
||||
copyHighlightedCalls(
|
||||
highlightedRows: Set<string>,
|
||||
requests: {[id: string]: Request},
|
||||
@@ -142,6 +143,7 @@ const nullNetworkRouteManager: NetworkRouteManager = {
|
||||
},
|
||||
modifyRoute(_id: string, _routeChange: Partial<Route>) {},
|
||||
removeRoute(_id: string) {},
|
||||
enableRoute(_id: string) {},
|
||||
copyHighlightedCalls(
|
||||
_highlightedRows: Set<string>,
|
||||
_requests: {[id: string]: Request},
|
||||
@@ -348,6 +350,7 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
responseData: '',
|
||||
responseHeaders: {},
|
||||
responseStatus: '200',
|
||||
enabled: true,
|
||||
};
|
||||
});
|
||||
nextRouteId.set(newNextRouteId + 1);
|
||||
@@ -370,6 +373,14 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
}
|
||||
informClientMockChange(routes.get());
|
||||
},
|
||||
enableRoute(id: string) {
|
||||
if (routes.get().hasOwnProperty(id)) {
|
||||
routes.update((draft) => {
|
||||
draft[id].enabled = !draft[id].enabled;
|
||||
});
|
||||
}
|
||||
informClientMockChange(routes.get());
|
||||
},
|
||||
copyHighlightedCalls(
|
||||
highlightedRows: Set<string> | null | undefined,
|
||||
requests: {[id: string]: Request},
|
||||
@@ -396,6 +407,7 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
responseData: responseData as string,
|
||||
responseHeaders: headers,
|
||||
responseStatus: responses[row].status.toString(),
|
||||
enabled: true,
|
||||
};
|
||||
});
|
||||
nextRouteId.set(newNextRouteId + 1);
|
||||
@@ -427,6 +439,7 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
responseData: importedRoute.responseData as string,
|
||||
responseHeaders: importedRoute.responseHeaders,
|
||||
responseStatus: importedRoute.responseStatus,
|
||||
enabled: true,
|
||||
};
|
||||
});
|
||||
nextRouteId.set(newNextRouteId + 1);
|
||||
@@ -541,13 +554,16 @@ export function plugin(client: PluginClient<Events, Methods>) {
|
||||
|
||||
try {
|
||||
await client.send('mockResponses', {
|
||||
routes: routesValuesArray.map((route: Route) => ({
|
||||
requestUrl: route.requestUrl,
|
||||
method: route.requestMethod,
|
||||
data: route.responseData,
|
||||
headers: [...Object.values(route.responseHeaders)],
|
||||
status: route.responseStatus,
|
||||
})),
|
||||
routes: routesValuesArray
|
||||
.filter((e) => e.enabled)
|
||||
.map((route: Route) => ({
|
||||
requestUrl: route.requestUrl,
|
||||
method: route.requestMethod,
|
||||
data: route.responseData,
|
||||
headers: [...Object.values(route.responseHeaders)],
|
||||
status: route.responseStatus,
|
||||
enabled: route.enabled,
|
||||
})),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed to mock responses.', e);
|
||||
|
||||
@@ -70,6 +70,7 @@ export type Route = {
|
||||
responseData: string;
|
||||
responseHeaders: {[id: string]: Header};
|
||||
responseStatus: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export type MockRoute = {
|
||||
@@ -78,6 +79,7 @@ export type MockRoute = {
|
||||
data: string;
|
||||
headers: Header[];
|
||||
status: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export type PersistedState = {
|
||||
|
||||
Reference in New Issue
Block a user