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
*/