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

feat(resizable-side-panels): Make the left and right side panels (optionally) resizable. #4672

Merged
merged 11 commits into from
Jan 21, 2025
Merged
Binary file modified bun.lockb
Binary file not shown.
50 changes: 32 additions & 18 deletions extensions/default/src/Components/SidePanelWithServices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,58 @@ export type SidePanelWithServicesProps = {
side: 'left' | 'right';
className?: string;
activeTabIndex: number;
tabs: any;
tabs?: any;
expandedWidth?: number;
onClose: () => void;
onOpen: () => void;
isExpanded: boolean;
collapsedWidth?: number;
expandedInsideBorderSize?: number;
collapsedInsideBorderSize?: number;
collapsedOutsideBorderSize?: number;
};

const SidePanelWithServices = ({
servicesManager,
side,
activeTabIndex: activeTabIndexProp,
isExpanded,
tabs: tabsProp,
expandedWidth,
onOpen,
onClose,
...props
}: SidePanelWithServicesProps) => {
const panelService = servicesManager?.services?.panelService;

// Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM.
// Thus going to the Study List page and back to the viewer resets this flag for a SidePanel.
const [sidePanelOpen, setSidePanelOpen] = useState(activeTabIndexProp !== null);
const [activeTabIndex, setActiveTabIndex] = useState(activeTabIndexProp);
const [sidePanelExpanded, setSidePanelExpanded] = useState(isExpanded);
const [activeTabIndex, setActiveTabIndex] = useState(activeTabIndexProp ?? 0);
const [closedManually, setClosedManually] = useState(false);
const [tabs, setTabs] = useState(tabsProp ?? panelService.getPanels(side));

const handleActiveTabIndexChange = useCallback(({ activeTabIndex }) => {
setActiveTabIndex(activeTabIndex);
setSidePanelOpen(activeTabIndex !== null);
}, []);

const handleOpen = useCallback(() => {
setSidePanelOpen(true);
// If panel is being opened but no tab is active, set first tab as active
if (activeTabIndex === null && tabs.length > 0) {
setActiveTabIndex(0);
}
}, [activeTabIndex, tabs]);
setSidePanelExpanded(true);
onOpen?.();
}, [onOpen]);

const handleClose = useCallback(() => {
setSidePanelOpen(false);
setActiveTabIndex(null);
}, []);
setSidePanelExpanded(false);
setClosedManually(true);
onClose?.();
}, [onClose]);

useEffect(() => {
setSidePanelExpanded(isExpanded);
}, [isExpanded]);

/** update the active tab index from outside */
useEffect(() => {
setActiveTabIndex(activeTabIndexProp);
setActiveTabIndex(activeTabIndexProp ?? 0);
}, [activeTabIndexProp]);

useEffect(() => {
Expand All @@ -71,9 +82,12 @@ const SidePanelWithServices = ({
const activatePanelSubscription = panelService.subscribe(
panelService.EVENTS.ACTIVATE_PANEL,
(activatePanelEvent: Types.ActivatePanelEvent) => {
if (sidePanelOpen || activatePanelEvent.forceActive) {
if (sidePanelExpanded || activatePanelEvent.forceActive) {
const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
if (tabIndex !== -1) {
if (!closedManually) {
setSidePanelExpanded(true);
}
setActiveTabIndex(tabIndex);
}
}
Expand All @@ -83,18 +97,18 @@ const SidePanelWithServices = ({
return () => {
activatePanelSubscription.unsubscribe();
};
}, [tabs, sidePanelOpen, panelService]);
}, [tabs, sidePanelExpanded, panelService, closedManually]);

return (
<SidePanel
{...props}
side={side}
tabs={tabs}
activeTabIndex={activeTabIndex}
isExpanded={sidePanelExpanded}
onOpen={handleOpen}
onClose={handleClose}
onActiveTabIndexChange={handleActiveTabIndexChange}
expandedWidth={expandedWidth}
/>
);
};
Expand Down
Loading
Loading