From 554b73cab5a4abb5ffcb378fc31dfe8de00a14f5 Mon Sep 17 00:00:00 2001 From: Sashank Aryal Date: Wed, 25 Sep 2024 16:45:46 -0500 Subject: [PATCH 1/2] add reload_on_navigation --- app/packages/operators/src/Panel/register.tsx | 1 + app/packages/plugins/src/index.ts | 6 ++++++ app/packages/spaces/src/components/Panel.tsx | 17 +++++++++++++---- fiftyone/operators/operations.py | 5 +++++ fiftyone/operators/panel.py | 10 ++++++++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/packages/operators/src/Panel/register.tsx b/app/packages/operators/src/Panel/register.tsx index 24a8fa973d3..01e4522690e 100644 --- a/app/packages/operators/src/Panel/register.tsx +++ b/app/packages/operators/src/Panel/register.tsx @@ -23,6 +23,7 @@ export default function registerPanel(ctx: ExecutionContext) { panelOptions: { allowDuplicates: ctx.params.allow_duplicates, helpMarkdown: ctx.params.help_markdown, + reloadOnNavigation: ctx.params.reload_on_navigation, surfaces: ctx.params.surfaces, }, }); diff --git a/app/packages/plugins/src/index.ts b/app/packages/plugins/src/index.ts index cd527a74c8d..a14e1423e4f 100644 --- a/app/packages/plugins/src/index.ts +++ b/app/packages/plugins/src/index.ts @@ -325,6 +325,12 @@ type PanelOptions = { * Content displayed on the right side of the label in the panel title bar. */ TabIndicator?: React.ComponentType; + + /** + * If true, the plugin will be remounted when the user navigates to a different sample or group. + * This is only applicable to plugins that are in a modal. + */ + reloadOnNavigation?: boolean; }; type PluginComponentProps = T & { diff --git a/app/packages/spaces/src/components/Panel.tsx b/app/packages/spaces/src/components/Panel.tsx index 6a2fc56d1e0..3b8c9859ee8 100644 --- a/app/packages/spaces/src/components/Panel.tsx +++ b/app/packages/spaces/src/components/Panel.tsx @@ -1,7 +1,7 @@ import { CenteredStack, scrollable } from "@fiftyone/components"; import * as fos from "@fiftyone/state"; import React, { useEffect } from "react"; -import { useSetRecoilState } from "recoil"; +import { useRecoilValue, useSetRecoilState } from "recoil"; import { PANEL_LOADING_TIMEOUT } from "../constants"; import { PanelContext } from "../contexts"; import { useReactivePanel } from "../hooks"; @@ -20,14 +20,17 @@ function Panel(props: PanelProps) { const setPanelIdToScope = useSetRecoilState(panelIdToScopeAtom); const scope = isModalPanel ? "modal" : "grid"; + const thisModalUniqueId = useRecoilValue(fos.currentModalUniqueId); + useEffect(() => { setPanelIdToScope((ids) => ({ ...ids, [node.id]: scope })); }, [scope, setPanelIdToScope, node.id]); const panelContentTestId = `panel-content-${panelName}`; + if (!panel) { return ( - + {pending ? ( @@ -39,7 +42,9 @@ function Panel(props: PanelProps) { ); } - const { component: Component } = panel; + const { component: Component, panelOptions } = panel; + + const shouldKeyComponent = isModalPanel && panelOptions?.reloadOnNavigation; return ( - + ); diff --git a/fiftyone/operators/operations.py b/fiftyone/operators/operations.py index 1f1a8673a79..2cd150e19d9 100644 --- a/fiftyone/operators/operations.py +++ b/fiftyone/operators/operations.py @@ -305,6 +305,7 @@ def register_panel( light_icon=None, dark_icon=None, surfaces="grid", + reload_on_navigation=False, on_load=None, on_unload=None, on_change=None, @@ -331,6 +332,9 @@ def register_panel( is in dark mode surfaces ('grid'): surfaces in which to show the panel. Must be one of 'grid', 'modal', or 'grid modal' + reload_on_navigation (False): whether to reload the panel when the + user navigates to a new page. This is only applicable to panels + that are not shown in a modal on_load (None): an operator to invoke when the panel is loaded on_unload (None): an operator to invoke when the panel is unloaded on_change (None): an operator to invoke when the panel state @@ -360,6 +364,7 @@ def register_panel( "light_icon": light_icon, "dark_icon": dark_icon, "surfaces": surfaces, + "reload_on_navigation": reload_on_navigation, "on_load": on_load, "on_unload": on_unload, "on_change": on_change, diff --git a/fiftyone/operators/panel.py b/fiftyone/operators/panel.py index 8f645d9b9dd..c2a032ec510 100644 --- a/fiftyone/operators/panel.py +++ b/fiftyone/operators/panel.py @@ -28,6 +28,12 @@ class PanelConfig(OperatorConfig): in dark mode allow_multiple (False): whether to allow multiple instances of the panel to be opened + reload_on_navigation (False): whether to reload the panel when the + user navigates to a new page. This is only applicable to panels + that are not shown in a modal + surfaces ("grid"): the surfaces on which the panel can be displayed + help_markdown (None): a markdown string to display in the panel's help + tooltip """ def __init__( @@ -40,6 +46,7 @@ def __init__( dark_icon=None, allow_multiple=False, surfaces: PANEL_SURFACE = "grid", + reload_on_navigation=False, **kwargs ): super().__init__(name) @@ -52,6 +59,7 @@ def __init__( self.allow_multiple = allow_multiple self.unlisted = True self.on_startup = True + self.reload_on_navigation = reload_on_navigation self.surfaces = surfaces self.kwargs = kwargs # unused, placeholder for future extensibility @@ -66,6 +74,7 @@ def to_json(self): "allow_multiple": self.allow_multiple, "on_startup": self.on_startup, "unlisted": self.unlisted, + "reload_on_navigation": self.reload_on_navigation, "surfaces": self.surfaces, } @@ -105,6 +114,7 @@ def on_startup(self, ctx): "dark_icon": self.config.dark_icon, "light_icon": self.config.light_icon, "surfaces": self.config.surfaces, + "reload_on_navigation": self.config.reload_on_navigation, } methods = ["on_load", "on_unload", "on_change"] ctx_change_events = [ From 02ba861fb42e84d9a1851a12c275b167fa506bc8 Mon Sep 17 00:00:00 2001 From: Sashank Aryal Date: Wed, 25 Sep 2024 16:48:48 -0500 Subject: [PATCH 2/2] optional chaining for group id --- app/packages/state/src/recoil/groups.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/packages/state/src/recoil/groups.ts b/app/packages/state/src/recoil/groups.ts index 080ccc9a52f..3f426f9cc0b 100644 --- a/app/packages/state/src/recoil/groups.ts +++ b/app/packages/state/src/recoil/groups.ts @@ -389,7 +389,7 @@ export const groupField = selector({ export const groupId = selector({ key: "groupId", - get: ({ get }) => get(modalSelector).groupId || null, + get: ({ get }) => get(modalSelector)?.groupId || null, }); export const refreshGroupQuery = atom({