Summary: See title. The issue occurs because this tabs component derives a key by essentially serializing the children. Since its possible for different elements in the UIDebugger to have different number of tabs, due to framework events not always being present this was never anticipated. Solution is to just let the callee supply a storage key which does not depend on the exact number of tabs Reviewed By: lblasa Differential Revision: D47520033 fbshipit-source-id: 67e57db5110fde52451d30496c25a25b0eb4a6f7
136 lines
3.7 KiB
TypeScript
136 lines
3.7 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and 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 React, {ReactNode} from 'react';
|
|
// eslint-disable-next-line rulesdir/no-restricted-imports-clone
|
|
import {Glyph} from 'flipper';
|
|
import {
|
|
DeviceOS,
|
|
Layout,
|
|
Tab,
|
|
Tabs,
|
|
theme,
|
|
usePlugin,
|
|
useValue,
|
|
} from 'flipper-plugin';
|
|
import {Id, Metadata, MetadataId, UINode} from '../../types';
|
|
import {IdentityInspector} from './inspector/IdentityInspector';
|
|
import {AttributesInspector} from './inspector/AttributesInspector';
|
|
import {Tooltip} from 'antd';
|
|
import {NoData} from './inspector/NoData';
|
|
import {plugin} from '../../index';
|
|
import {FrameworkEventsInspector} from './inspector/FrameworkEventsInspector';
|
|
|
|
type Props = {
|
|
os: DeviceOS;
|
|
nodes: Map<Id, UINode>;
|
|
metadata: Map<MetadataId, Metadata>;
|
|
showExtra: (element: ReactNode) => void;
|
|
};
|
|
|
|
export const Inspector: React.FC<Props> = ({
|
|
os,
|
|
nodes,
|
|
metadata,
|
|
showExtra,
|
|
}) => {
|
|
const instance = usePlugin(plugin);
|
|
const selectedNodeId = useValue(instance.uiState.selectedNode)?.id;
|
|
const frameworkEvents = useValue(instance.frameworkEvents);
|
|
|
|
const selectedNode = selectedNodeId ? nodes.get(selectedNodeId) : undefined;
|
|
if (!selectedNode) {
|
|
return <NoData message="Please select a node to view its details" />;
|
|
}
|
|
|
|
const selectedFrameworkEvents = selectedNodeId
|
|
? frameworkEvents?.get(selectedNodeId)
|
|
: undefined;
|
|
|
|
return (
|
|
<Layout.Container gap pad>
|
|
<Tabs
|
|
localStorageKeyOverride="sidebar-tabs"
|
|
grow
|
|
centered
|
|
key={selectedNodeId}>
|
|
<Tab
|
|
key={'identity'}
|
|
tab={
|
|
<Tooltip title="Identity">
|
|
<Layout.Horizontal center>
|
|
<Glyph name="badge" size={16} color={theme.primaryColor} />
|
|
</Layout.Horizontal>
|
|
</Tooltip>
|
|
}>
|
|
<IdentityInspector node={selectedNode} />
|
|
</Tab>
|
|
|
|
<Tab
|
|
key={'attributes'}
|
|
tab={
|
|
<Tooltip title="Attributes">
|
|
<Layout.Horizontal center>
|
|
<Glyph name="data-table" size={16} color={theme.primaryColor} />
|
|
</Layout.Horizontal>
|
|
</Tooltip>
|
|
}>
|
|
<AttributesInspector
|
|
mode="attribute"
|
|
node={selectedNode}
|
|
metadata={metadata}
|
|
/>
|
|
</Tab>
|
|
{os !== 'Android' && (
|
|
<Tab
|
|
key={'layout'}
|
|
tab={
|
|
<Tooltip title="Layout">
|
|
<Layout.Horizontal center>
|
|
<Glyph
|
|
name="square-ruler"
|
|
size={16}
|
|
color={theme.primaryColor}
|
|
/>
|
|
</Layout.Horizontal>
|
|
</Tooltip>
|
|
}>
|
|
<AttributesInspector
|
|
mode="layout"
|
|
node={selectedNode}
|
|
metadata={metadata}
|
|
/>
|
|
</Tab>
|
|
)}
|
|
{selectedFrameworkEvents && (
|
|
<Tab
|
|
key={'events'}
|
|
tab={
|
|
<Tooltip title="Events">
|
|
<Layout.Horizontal center>
|
|
<Glyph
|
|
name="weather-thunder"
|
|
size={16}
|
|
color={theme.primaryColor}
|
|
/>
|
|
</Layout.Horizontal>
|
|
</Tooltip>
|
|
}>
|
|
<FrameworkEventsInspector
|
|
node={selectedNode}
|
|
events={selectedFrameworkEvents}
|
|
showExtra={showExtra}
|
|
/>
|
|
</Tab>
|
|
)}
|
|
</Tabs>
|
|
</Layout.Container>
|
|
);
|
|
};
|