Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add reload_on_navigation for modal panels #4846

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/packages/operators/src/Panel/register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
});
Expand Down
6 changes: 6 additions & 0 deletions app/packages/plugins/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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> = T & {
Expand Down
17 changes: 13 additions & 4 deletions app/packages/spaces/src/components/Panel.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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 (
<StyledPanel data-cy={panelContentTestId} $isModalPanel={isModalPanel}>
<StyledPanel data-cy={panelContentTestId}>
<CenteredStack>
{pending ? (
<PanelSkeleton />
Expand All @@ -39,7 +42,9 @@ function Panel(props: PanelProps) {
);
}

const { component: Component } = panel;
const { component: Component, panelOptions } = panel;

const shouldKeyComponent = isModalPanel && panelOptions?.reloadOnNavigation;

return (
<StyledPanel
Expand All @@ -50,7 +55,11 @@ function Panel(props: PanelProps) {
ref={dimensions.ref}
>
<PanelContext.Provider value={{ node, scope }}>
<Component panelNode={node} dimensions={dimensions} />
<Component
key={shouldKeyComponent ? thisModalUniqueId : panelName}
panelNode={node}
dimensions={dimensions}
/>
</PanelContext.Provider>
</StyledPanel>
);
Expand Down
2 changes: 1 addition & 1 deletion app/packages/state/src/recoil/groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ export const groupField = selector<string>({

export const groupId = selector<string>({
key: "groupId",
get: ({ get }) => get(modalSelector).groupId || null,
get: ({ get }) => get(modalSelector)?.groupId || null,
});

export const refreshGroupQuery = atom<number>({
Expand Down
5 changes: 5 additions & 0 deletions fiftyone/operators/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions fiftyone/operators/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__(
Expand All @@ -40,6 +46,7 @@ def __init__(
dark_icon=None,
allow_multiple=False,
surfaces: PANEL_SURFACE = "grid",
reload_on_navigation=False,
**kwargs
):
super().__init__(name)
Expand All @@ -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

Expand All @@ -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,
}

Expand Down Expand Up @@ -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 = [
Expand Down
Loading