sourcebot/packages/web/src/app/[domain]/browse/browseStateProvider.tsx
Michael Sukkarieh 60a3528394
V4 (#311)
Sourcebot V4 introduces authentication, performance improvements and code navigation. Checkout the [migration guide](https://docs.sourcebot.dev/self-hosting/upgrade/v3-to-v4-guide) for information on upgrading your instance to v4.

### Changed
- [**Breaking Change**] Authentication is now required by default. Notes:
  - When setting up your instance, email / password login will be the default authentication provider.
  - The first user that logs into the instance is given the `owner` role. ([docs](https://docs.sourcebot.dev/docs/more/roles-and-permissions)).
  - Subsequent users can request to join the instance. The `owner` can approve / deny requests to join the instance via `Settings` > `Members` > `Pending Requests`.
  - If a user is approved to join the instance, they are given the `member` role.
  - Additional login providers, including email links and SSO, can be configured with additional environment variables. ([docs](https://docs.sourcebot.dev/self-hosting/configuration/authentication)).
- Clicking on a search result now takes you to the `/browse` view. Files can still be previewed by clicking the "Preview" button or holding `Cmd` / `Ctrl` when clicking on a search result. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315)

### Added
- [Sourcebot EE] Added search-based code navigation, allowing you to jump between symbol definition and references when viewing source files. [Read the documentation](https://docs.sourcebot.dev/docs/search/code-navigation). [#315](https://github.com/sourcebot-dev/sourcebot/pull/315)
- Added collapsible filter panel. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315)

### Fixed
- Improved scroll performance for large numbers of search results. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315)
2025-05-28 16:08:42 -07:00

73 lines
No EOL
2.2 KiB
TypeScript

'use client';
import { useNonEmptyQueryParam } from "@/hooks/useNonEmptyQueryParam";
import { createContext, useCallback, useEffect, useState } from "react";
import { BOTTOM_PANEL_MIN_SIZE } from "./components/bottomPanel";
export interface BrowseState {
selectedSymbolInfo?: {
symbolName: string;
repoName: string;
revisionName: string;
language: string;
}
isBottomPanelCollapsed: boolean;
activeExploreMenuTab: "references" | "definitions";
bottomPanelSize: number;
}
const defaultState: BrowseState = {
selectedSymbolInfo: undefined,
isBottomPanelCollapsed: true,
activeExploreMenuTab: "references",
bottomPanelSize: BOTTOM_PANEL_MIN_SIZE,
};
export const SET_BROWSE_STATE_QUERY_PARAM = "setBrowseState";
export const BrowseStateContext = createContext<{
state: BrowseState;
updateBrowseState: (state: Partial<BrowseState>) => void;
}>({
state: defaultState,
updateBrowseState: () => {},
});
export const BrowseStateProvider = ({ children }: { children: React.ReactNode }) => {
const [state, setState] = useState<BrowseState>(defaultState);
const hydratedBrowseState = useNonEmptyQueryParam(SET_BROWSE_STATE_QUERY_PARAM);
const onUpdateState = useCallback((state: Partial<BrowseState>) => {
setState((prevState) => ({
...prevState,
...state,
}));
}, []);
useEffect(() => {
if (hydratedBrowseState) {
try {
const parsedState = JSON.parse(hydratedBrowseState) as Partial<BrowseState>;
onUpdateState(parsedState);
} catch (error) {
console.error("Error parsing hydratedBrowseState", error);
}
// Remove the query param
const url = new URL(window.location.href);
url.searchParams.delete(SET_BROWSE_STATE_QUERY_PARAM);
window.history.replaceState({}, '', url.toString());
}
}, [hydratedBrowseState, onUpdateState]);
return (
<BrowseStateContext.Provider
value={{
state,
updateBrowseState: onUpdateState,
}}
>
{children}
</BrowseStateContext.Provider>
);
};