diff --git a/desktop/plugins/public/ui-debugger/components/sidebarV2/AttributesInspector.tsx b/desktop/plugins/public/ui-debugger/components/sidebarV2/AttributesInspector.tsx index cbde1cfa3..b1e843f46 100644 --- a/desktop/plugins/public/ui-debugger/components/sidebarV2/AttributesInspector.tsx +++ b/desktop/plugins/public/ui-debugger/components/sidebarV2/AttributesInspector.tsx @@ -7,7 +7,7 @@ * @format */ -import {Input, Typography} from 'antd'; +import {Divider, Input, Typography} from 'antd'; import {Panel, theme, Layout} from 'flipper-plugin'; import React from 'react'; import { @@ -19,7 +19,8 @@ import { import {MetadataMap} from '../../DesktopTypes'; import {NoData} from '../sidebar/inspector/NoData'; import {css, cx} from '@emotion/css'; -import {upperFirst} from 'lodash'; +import {upperFirst, sortBy} from 'lodash'; +import {any} from 'lodash/fp'; export function AttributesInspector({ node, @@ -64,40 +65,63 @@ function AttributeSection( name: string, inspectable: InspectableObject, ) { - const children = Object.keys(inspectable.fields) - .map((key) => { - const metadataId: number = Number(key); + const attributesOrSubSubsections = Object.entries(inspectable.fields).map( + ([fieldKey, attributeValue]) => { + const metadataId: number = Number(fieldKey); const attributeMetadata = metadataMap.get(metadataId); + const attributeName = + upperFirst(attributeMetadata?.name) ?? String(metadataId); + //subsections are complex types that are only 1 level deep + const isSubSection = + attributeValue.type === 'object' && + !any( + (inspectable) => + inspectable.type === 'array' || inspectable.type === 'object', + Object.values(attributeValue.fields), + ); + return { + attributeName, + attributeMetadata, + isSubSection, + attributeValue, + metadataId, + }; + }, + ); + //push sub sections to the end + const sortedAttributesOrSubsections = sortBy( + attributesOrSubSubsections, + [(item) => item.isSubSection], + (item) => item.attributeName, + ); + + const children = sortedAttributesOrSubsections + .map(({isSubSection, attributeValue, attributeMetadata, attributeName}) => { if (attributeMetadata == null) { return null; } - const attributeValue = inspectable.fields[metadataId]; - const attributeName = - upperFirst(attributeMetadata?.name) ?? String(metadataId); - return ( - - - {attributeName} - - - - - - + ); + } + } + + return ( + ); }) .filter((attr) => attr != null); @@ -115,6 +139,81 @@ function AttributeSection( } } +function SubSection({ + attributeName, + inspectableObject, + metadataMap, +}: { + attributeName: string; + inspectableObject: InspectableObject; + metadataMap: MetadataMap; +}) { + return ( + + + {attributeName} + {Object.entries(inspectableObject.fields).map(([key, value]) => { + const metadataId: number = Number(key); + const attributeMetadata = metadataMap.get(metadataId); + if (attributeMetadata == null) { + return null; + } + const attributeName = + upperFirst(attributeMetadata?.name) ?? String(metadataId); + + return ( + + ); + })} + + ); +} + +function NamedAttribute({ + key, + name, + value, + metadataMap, + attributeMetadata, +}: { + name: string; + value: Inspectable; + attributeMetadata: Metadata; + metadataMap: MetadataMap; + key: string; +}) { + return ( + + + {name} + + + + + + + ); +} + /** * disables hover and focsued states */