From ff1e70e7fe1e4a3568643368684929df235141ff Mon Sep 17 00:00:00 2001 From: Camron Staley <55006027+CamronStaley@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:40:21 -0600 Subject: [PATCH] Fix query performance bugs (#5094) * make lightning icon change color based on if expanded tooltip is dismissed * add lightning bolt for indexed sub fields in a group * fix qp toast not dismissing when clicked outside --- .../components/src/components/Toast/Toast.tsx | 12 ++++++++---- .../NumericFieldFilter/NumericFieldFilter.tsx | 12 ++++++++++-- .../components/Filters/StringFilter/StringFilter.tsx | 12 ++++++++++++ .../core/src/components/QueryPerformanceToast.tsx | 5 +++++ .../Sidebar/Entries/QueryPerformanceIcon.tsx | 5 ++++- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/app/packages/components/src/components/Toast/Toast.tsx b/app/packages/components/src/components/Toast/Toast.tsx index d2ace439ab..3a10f35c7a 100644 --- a/app/packages/components/src/components/Toast/Toast.tsx +++ b/app/packages/components/src/components/Toast/Toast.tsx @@ -18,6 +18,7 @@ interface ToastProps { fontSize?: string; textAlign?: string; }; + onHandleClose?: (event, reason) => void; } const toastStateAtom = atom({ @@ -31,6 +32,12 @@ const Toast: React.FC = ({ secondary, duration = 5000, layout = {}, + onHandleClose = (event, reason) => { + if (reason === "clickaway") { + return; + } + setOpen(false); + }, }) => { const snackbarStyle = { height: layout?.height || 5, @@ -57,10 +64,7 @@ const Toast: React.FC = ({ const [open, setOpen] = useRecoilState(toastStateAtom); // State management for toast visibility const handleClose = (event, reason) => { - if (reason === "clickaway") { - return; - } - setOpen(false); + onHandleClose(event, reason); }; const action = ( diff --git a/app/packages/core/src/components/Filters/NumericFieldFilter/NumericFieldFilter.tsx b/app/packages/core/src/components/Filters/NumericFieldFilter/NumericFieldFilter.tsx index 75342a925a..b5a0115420 100644 --- a/app/packages/core/src/components/Filters/NumericFieldFilter/NumericFieldFilter.tsx +++ b/app/packages/core/src/components/Filters/NumericFieldFilter/NumericFieldFilter.tsx @@ -1,4 +1,4 @@ -import { LoadingDots } from "@fiftyone/components"; +import { LoadingDots, useTheme } from "@fiftyone/components"; import * as fos from "@fiftyone/state"; import * as schemaAtoms from "@fiftyone/state/src/recoil/schema"; import React, { Suspense } from "react"; @@ -8,6 +8,7 @@ import FieldLabelAndInfo from "../../FieldLabelAndInfo"; import { Button } from "../../utils"; import RangeSlider from "./RangeSlider"; import * as state from "./state"; +import Bolt from "@mui/icons-material/Bolt"; const Container = styled.div` margin: 3px; @@ -17,6 +18,7 @@ const Container = styled.div` const Header = styled.div` display: flex; justify-content: space-between; + align-items: center; `; const Box = styled.div` @@ -44,9 +46,11 @@ const NumericFieldFilter = ({ color, modal, named = true, path }: Props) => { const [showRange, setShowRange] = React.useState(!isGroup); const field = fos.useAssertedRecoilValue(fos.field(path)); const queryPerformance = useRecoilValue(fos.queryPerformance); + const indexed = useRecoilValue(fos.pathHasIndexes(path)); const hasBounds = useRecoilValue( state.hasBounds({ path, modal, shouldCalculate: !queryPerformance }) ); + const theme = useTheme(); if (!queryPerformance && named && !hasBounds) { return null; @@ -57,7 +61,8 @@ const NumericFieldFilter = ({ color, modal, named = true, path }: Props) => { }; const showButton = isGroup && queryPerformance && !showRange && !modal; - + const showQueryPerformanceIcon = + isGroup && queryPerformance && indexed && !modal; return ( e.stopPropagation()}> {named && name && ( @@ -68,6 +73,9 @@ const NumericFieldFilter = ({ color, modal, named = true, path }: Props) => { template={({ label, hoverTarget }) => (
{label} + {showQueryPerformanceIcon && ( + + )}
)} /> diff --git a/app/packages/core/src/components/Filters/StringFilter/StringFilter.tsx b/app/packages/core/src/components/Filters/StringFilter/StringFilter.tsx index b727631b3a..adcb3fefc0 100644 --- a/app/packages/core/src/components/Filters/StringFilter/StringFilter.tsx +++ b/app/packages/core/src/components/Filters/StringFilter/StringFilter.tsx @@ -11,6 +11,8 @@ import ResultComponent from "./Result"; import useOnSelect from "./useOnSelect"; import type { ResultsAtom } from "./useSelected"; import useSelected from "./useSelected"; +import * as schemaAtoms from "@fiftyone/state/src/recoil/schema"; +import Bolt from "@mui/icons-material/Bolt"; const StringFilterContainer = styled.div` background: ${({ theme }) => theme.background.level2}; @@ -31,6 +33,7 @@ const NamedStringFilterHeader = styled.div` display: flex; justify-content: space-between; text-overflow: ellipsis; + align-items: center; `; interface Props { @@ -73,15 +76,21 @@ const StringFilter = ({ path, resultsAtom ); + const fieldType = useRecoilValue(schemaAtoms.filterFields(path)); + const isGroup = fieldType.length > 1; const onSelect = useOnSelect(modal, path, selectedAtom); const skeleton = useRecoilValue(isInKeypointsField(path)) && name === "keypoints"; + const indexed = useRecoilValue(fos.pathHasIndexes(path)); const theme = useTheme(); const queryPerformance = useRecoilValue(fos.queryPerformance); if (named && !queryPerformance && !results?.count) { return null; } + const showQueryPerformanceIcon = + isGroup && queryPerformance && indexed && !modal; + return ( ( {label} + {showQueryPerformanceIcon && ( + + )} )} /> diff --git a/app/packages/core/src/components/QueryPerformanceToast.tsx b/app/packages/core/src/components/QueryPerformanceToast.tsx index 508306fafd..f48c67d3ea 100644 --- a/app/packages/core/src/components/QueryPerformanceToast.tsx +++ b/app/packages/core/src/components/QueryPerformanceToast.tsx @@ -54,6 +54,10 @@ const QueryPerformanceToast = ({ return () => window.removeEventListener("queryperformance", listen); }, []); + const onHandleClose = (event, reason) => { + setShown(false); + }; + if (!element) { throw new Error("no query performance element"); } @@ -69,6 +73,7 @@ const QueryPerformanceToast = ({ return createPortal( { const theme = useTheme(); const [showExpanded, setShowExpanded] = useRecoilState(showExpandedTooltip); + const lightningBoltColor = showExpanded + ? theme.custom.lightning + : theme.text.secondary; return ( { }, }} > - + ); };