Basic filtering

Summary: This filtering scheme is extremely basic, we only filter based on top level fields. Other schemes I considered were somewhat confusing and this works well in most if not all cases

Reviewed By: lblasa

Differential Revision: D50595986

fbshipit-source-id: 90cb82f8fc482fd4c6f996ff9e857f27766df544
This commit is contained in:
Luke De Feo
2023-10-26 05:24:30 -07:00
committed by Facebook GitHub Bot
parent ce693ef33e
commit 457361985c

View File

@@ -8,7 +8,15 @@
*/ */
import {Button, Divider, Input, Modal, Typography} from 'antd'; import {Button, Divider, Input, Modal, Typography} from 'antd';
import {DataInspector, Panel, theme, Layout, styled} from 'flipper-plugin';
import {
DataInspector,
Panel,
theme,
Layout,
styled,
useLocalStorageState,
} from 'flipper-plugin';
import React, {useState} from 'react'; import React, {useState} from 'react';
import { import {
ClientNode, ClientNode,
@@ -24,6 +32,7 @@ import {upperFirst, sortBy} from 'lodash';
import {any} from 'lodash/fp'; import {any} from 'lodash/fp';
import {InspectableColor} from '../../ClientTypes'; import {InspectableColor} from '../../ClientTypes';
import {transformAny} from '../../utils/dataTransform'; import {transformAny} from '../../utils/dataTransform';
import {SearchOutlined} from '@ant-design/icons';
type ModalData = { type ModalData = {
data: unknown; data: unknown;
@@ -39,6 +48,11 @@ export function AttributesInspector({
}) { }) {
const [modalData, setModalData] = useState<ModalData | null>(null); const [modalData, setModalData] = useState<ModalData | null>(null);
const [attributeFilter, setAttributeFilter] = useLocalStorageState(
'attribute-filter',
'',
);
const showComplexTypeModal = (modaldata: ModalData) => { const showComplexTypeModal = (modaldata: ModalData) => {
setModalData(modaldata); setModalData(modaldata);
}; };
@@ -69,13 +83,15 @@ export function AttributesInspector({
sectionMetadata.name, sectionMetadata.name,
sectionAttributes, sectionAttributes,
showComplexTypeModal, showComplexTypeModal,
attributeFilter,
); );
}) })
.filter((section) => section != null); .filter((section) => section != null);
if (sections.length === 0) { if (sections.length === 0 && !attributeFilter) {
return <NoData message="No data available for this element" />; return <NoData message="No data available for this element" />;
} }
return ( return (
<> <>
{modalData != null && ( {modalData != null && (
@@ -88,7 +104,20 @@ export function AttributesInspector({
<DataInspector data={modalData.data} /> <DataInspector data={modalData.data} />
</Modal> </Modal>
)} )}
{sections} <Layout.Container gap="small" padv="medium">
<Input
value={attributeFilter}
onChange={(e) => setAttributeFilter(e.target.value)}
placeholder="Filter attributes"
prefix={<SearchOutlined />}
/>
{sections.length === 0 ? (
<NoData message="No attributes match filter " />
) : (
sections
)}
</Layout.Container>
</> </>
); );
} }
@@ -98,9 +127,10 @@ function AttributeSection(
name: string, name: string,
inspectable: InspectableObject, inspectable: InspectableObject,
onDisplayModal: (modaldata: ModalData) => void, onDisplayModal: (modaldata: ModalData) => void,
attributeFilter: string,
) { ) {
const attributesOrSubSubsections = Object.entries(inspectable.fields).map( const attributesOrSubSubsections = Object.entries(inspectable.fields)
([fieldKey, attributeValue]) => { .map(([fieldKey, attributeValue]) => {
const metadataId: number = Number(fieldKey); const metadataId: number = Number(fieldKey);
const attributeMetadata = metadataMap.get(metadataId); const attributeMetadata = metadataMap.get(metadataId);
const attributeName = const attributeName =
@@ -120,7 +150,11 @@ function AttributeSection(
attributeValue, attributeValue,
metadataId, metadataId,
}; };
}, })
.filter(
({attributeName}) =>
!attributeFilter ||
attributeName.toLowerCase().includes(attributeFilter),
); );
//push sub sections to the end //push sub sections to the end