(Server) Add ManageMockResponsePanel
Summary: - Add ManageMockResponsePanel to add, modify and remove mocked route Note: - This is a part of this PR: https://github.com/facebook/flipper/pull/488 Reviewed By: mweststrate Differential Revision: D20440147 fbshipit-source-id: 3af127c4b091f288c13b41b74d78c07b4eb0e52f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
95376a17b9
commit
adb1d6e976
200
desktop/plugins/network/ManageMockResponsePanel.tsx
Normal file
200
desktop/plugins/network/ManageMockResponsePanel.tsx
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
ManagedTable,
|
||||||
|
Text,
|
||||||
|
FlexBox,
|
||||||
|
FlexRow,
|
||||||
|
FlexColumn,
|
||||||
|
Glyph,
|
||||||
|
styled,
|
||||||
|
colors,
|
||||||
|
Panel,
|
||||||
|
} from 'flipper';
|
||||||
|
import React, {useContext, useState, useMemo, useEffect} from 'react';
|
||||||
|
|
||||||
|
import {Route} from './types';
|
||||||
|
|
||||||
|
import {MockResponseDetails} from './MockResponseDetails';
|
||||||
|
import {NetworkRouteContext} from './index';
|
||||||
|
import {RequestId} from './types';
|
||||||
|
|
||||||
|
type Props = {routes: {[id: string]: Route}};
|
||||||
|
|
||||||
|
const ColumnSizes = {route: 'flex'};
|
||||||
|
|
||||||
|
const Columns = {route: {value: 'Route', resizable: false}};
|
||||||
|
|
||||||
|
const AddRouteButton = styled(FlexBox)({
|
||||||
|
color: colors.blackAlpha50,
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: 10,
|
||||||
|
flexShrink: 0,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
});
|
||||||
|
|
||||||
|
const Container = styled(FlexRow)({
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
alignItems: 'stretch',
|
||||||
|
});
|
||||||
|
|
||||||
|
const LeftPanel = styled(FlexColumn)({
|
||||||
|
flex: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const RightPanel = styled(FlexColumn)({
|
||||||
|
flex: 3,
|
||||||
|
height: '100%',
|
||||||
|
});
|
||||||
|
|
||||||
|
const TextEllipsis = styled(Text)({
|
||||||
|
overflowX: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
maxWidth: '100%',
|
||||||
|
lineHeight: '18px',
|
||||||
|
paddingTop: 4,
|
||||||
|
display: 'block',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
});
|
||||||
|
|
||||||
|
const Icon = styled(Glyph)({
|
||||||
|
marginTop: 5,
|
||||||
|
marginRight: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
// return ids that have the same pair of requestUrl and method; this will return only the duplicate
|
||||||
|
function _duplicateIds(routes: {[id: string]: Route}): Array<RequestId> {
|
||||||
|
const idSet: {[id: string]: {[method: string]: boolean}} = {};
|
||||||
|
return Object.entries(routes).reduce((acc: Array<RequestId>, [id, route]) => {
|
||||||
|
if (idSet.hasOwnProperty(route.requestUrl)) {
|
||||||
|
if (idSet[route.requestUrl].hasOwnProperty(route.requestMethod)) {
|
||||||
|
return acc.concat(id);
|
||||||
|
}
|
||||||
|
idSet[route.requestUrl] = {
|
||||||
|
...idSet[route.requestUrl],
|
||||||
|
[route.requestMethod]: true,
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
} else {
|
||||||
|
idSet[route.requestUrl] = {[route.requestMethod]: true};
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _buildRows(
|
||||||
|
routes: {[id: string]: Route},
|
||||||
|
duplicatedIds: Array<string>,
|
||||||
|
) {
|
||||||
|
return Object.entries(routes).map(([id, route]) => ({
|
||||||
|
columns: {
|
||||||
|
route: {
|
||||||
|
value: duplicatedIds.includes(id) ? (
|
||||||
|
<FlexRow>
|
||||||
|
<Icon name="caution-triangle" color={colors.yellow} />
|
||||||
|
<TextEllipsis>{route.requestUrl}</TextEllipsis>
|
||||||
|
</FlexRow>
|
||||||
|
) : (
|
||||||
|
<TextEllipsis>{route.requestUrl}</TextEllipsis>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
key: id,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function ManagedMockResponseRightPanel(props: {
|
||||||
|
id: string;
|
||||||
|
route: Route;
|
||||||
|
isDuplicated: boolean;
|
||||||
|
}) {
|
||||||
|
const {id, route, isDuplicated} = props;
|
||||||
|
return (
|
||||||
|
<Panel
|
||||||
|
grow={true}
|
||||||
|
collapsable={false}
|
||||||
|
floating={false}
|
||||||
|
heading={'Route Info'}>
|
||||||
|
<MockResponseDetails
|
||||||
|
key={id}
|
||||||
|
id={id}
|
||||||
|
route={route}
|
||||||
|
isDuplicated={isDuplicated}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ManageMockResponsePanel(props: Props) {
|
||||||
|
const networkRouteManager = useContext(NetworkRouteContext);
|
||||||
|
const [selectedId, setSelectedId] = useState<RequestId | null>(null);
|
||||||
|
const [currentRouteSize, setCurrentRouteSize] = useState(0);
|
||||||
|
|
||||||
|
const {routes} = props;
|
||||||
|
useEffect(() => {
|
||||||
|
const keys = Object.keys(routes);
|
||||||
|
const routeSize = keys.length;
|
||||||
|
if (currentRouteSize === routeSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (routeSize > 0 && routeSize > currentRouteSize) {
|
||||||
|
setSelectedId(keys[routeSize - 1]);
|
||||||
|
}
|
||||||
|
setCurrentRouteSize(routeSize);
|
||||||
|
}, [routes]);
|
||||||
|
const duplicatedIds = useMemo(() => _duplicateIds(routes), [routes]);
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<LeftPanel>
|
||||||
|
<AddRouteButton
|
||||||
|
onClick={() => {
|
||||||
|
networkRouteManager.addRoute();
|
||||||
|
}}>
|
||||||
|
<Glyph
|
||||||
|
name="plus-circle"
|
||||||
|
size={16}
|
||||||
|
variant="outline"
|
||||||
|
color={colors.blackAlpha30}
|
||||||
|
/>
|
||||||
|
Add Route
|
||||||
|
</AddRouteButton>
|
||||||
|
<ManagedTable
|
||||||
|
hideHeader={true}
|
||||||
|
multiline={true}
|
||||||
|
columnSizes={ColumnSizes}
|
||||||
|
columns={Columns}
|
||||||
|
rows={_buildRows(routes, duplicatedIds)}
|
||||||
|
stickyBottom={true}
|
||||||
|
autoHeight={false}
|
||||||
|
floating={false}
|
||||||
|
zebra={false}
|
||||||
|
onRowHighlighted={selectedIds => {
|
||||||
|
const newSelectedId =
|
||||||
|
selectedIds.length === 1 ? selectedIds[0] : null;
|
||||||
|
setSelectedId(newSelectedId);
|
||||||
|
}}
|
||||||
|
highlightedRows={new Set(selectedId)}
|
||||||
|
/>
|
||||||
|
</LeftPanel>
|
||||||
|
<RightPanel>
|
||||||
|
{selectedId && routes.hasOwnProperty(selectedId) && (
|
||||||
|
<ManagedMockResponseRightPanel
|
||||||
|
id={selectedId}
|
||||||
|
route={routes[selectedId]}
|
||||||
|
isDuplicated={duplicatedIds.includes(selectedId)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</RightPanel>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user