Skip to content

Commit

Permalink
Move user fetching to SS + parallelize some server-side calls (#2932)
Browse files Browse the repository at this point in the history
* Move user fetching to SS

* Cleanup

* Add more logging

* Small cleanup
  • Loading branch information
Weves authored Oct 27, 2024
1 parent 1261d85 commit 0c2cc74
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 33 deletions.
49 changes: 37 additions & 12 deletions web/src/app/admin/connectors/[connector]/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,47 @@ import { credentialTemplates } from "@/lib/connectors/credentials";
import Link from "next/link";
import { useUser } from "@/components/user/UserProvider";
import { useContext } from "react";
import { User } from "@/lib/types";

function BackButton({
isAdmin,
isCurator,
user,
}: {
isAdmin: boolean;
isCurator: boolean;
user: User | null;
}) {
const buttonText = isAdmin ? "Admin Page" : "Curator Page";

if (!isAdmin && !isCurator) {
console.error(
`User is neither admin nor curator, defaulting to curator view. Found user:\n ${JSON.stringify(
user,
null,
2
)}`
);
}

return (
<div className="mx-3 mt-6 flex-col flex items-center">
<Link
href={"/admin/add-connector"}
className="w-full p-2 bg-white border-border border rounded items-center hover:bg-background-200 cursor-pointer transition-all duration-150 flex gap-x-2"
>
<SettingsIcon className="flex-none " />
<p className="my-auto flex items-center text-sm">{buttonText}</p>
</Link>
</div>
);
}

export default function Sidebar() {
const { formStep, setFormStep, connector, allowAdvanced, allowCreate } =
useFormContext();
const combinedSettings = useContext(SettingsContext);
const { isLoadingUser, isAdmin } = useUser();
const { isCurator, isAdmin, user } = useUser();
if (!combinedSettings) {
return null;
}
Expand Down Expand Up @@ -55,17 +90,7 @@ export default function Sidebar() {
</div>
</div>

<div className="mx-3 mt-6 gap-y-1 flex-col flex gap-x-1.5 items-center items-center">
<Link
href={"/admin/add-connector"}
className="w-full p-2 bg-white border-border border rounded items-center hover:bg-background-200 cursor-pointer transition-all duration-150 flex gap-x-2"
>
<SettingsIcon className="flex-none " />
<p className="my-auto flex items-center text-sm">
{isAdmin ? "Admin Page" : "Curator Page"}
</p>
</Link>
</div>
<BackButton isAdmin={isAdmin} isCurator={isCurator} user={user} />

<div className="h-full flex">
<div className="mx-auto w-full max-w-2xl px-4 py-8">
Expand Down
1 change: 0 additions & 1 deletion web/src/app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { WelcomeModal } from "@/components/initialSetup/welcome/WelcomeModalWrap
import { ChatProvider } from "@/components/context/ChatContext";
import { fetchChatData } from "@/lib/chat/fetchChatData";
import WrappedChat from "./WrappedChat";
import { AssistantsProvider } from "@/components/context/AssistantsContext";

export default async function Page({
searchParams,
Expand Down
12 changes: 9 additions & 3 deletions web/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { fetchAssistantData } from "@/lib/chat/fetchAssistantdata";
import { AppProvider } from "@/components/context/AppProvider";
import { PHProvider } from "./providers";
import { default as dynamicImport } from "next/dynamic";
import { getCurrentUserSS } from "@/lib/userSS";

const PostHogPageView = dynamicImport(() => import("./PostHogPageView"), {
ssr: false,
Expand Down Expand Up @@ -57,7 +58,11 @@ export default async function RootLayout({
}: {
children: React.ReactNode;
}) {
const combinedSettings = await fetchSettingsSS();
const [combinedSettings, assistantsData, user] = await Promise.all([
fetchSettingsSS(),
fetchAssistantData(),
getCurrentUserSS(),
]);

const productGating =
combinedSettings?.settings.product_gating ?? GatingType.NONE;
Expand Down Expand Up @@ -165,11 +170,12 @@ export default async function RootLayout({
);
}

const data = await fetchAssistantData();
const { assistants, hasAnyConnectors, hasImageCompatibleModel } = data;
const { assistants, hasAnyConnectors, hasImageCompatibleModel } =
assistantsData;

return getPageContent(
<AppProvider
user={user}
settings={combinedSettings}
assistants={assistants}
hasAnyConnectors={hasAnyConnectors}
Expand Down
5 changes: 4 additions & 1 deletion web/src/components/context/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { ProviderContextProvider } from "../chat_search/ProviderContext";
import { SettingsProvider } from "../settings/SettingsProvider";
import { AssistantsProvider } from "./AssistantsContext";
import { Persona } from "@/app/admin/assistants/interfaces";
import { User } from "@/lib/types";

interface AppProviderProps {
children: React.ReactNode;
user: User | null;
settings: CombinedSettings;
assistants: Persona[];
hasAnyConnectors: boolean;
Expand All @@ -16,13 +18,14 @@ interface AppProviderProps {

export const AppProvider = ({
children,
user,
settings,
assistants,
hasAnyConnectors,
hasImageCompatibleModel,
}: AppProviderProps) => {
return (
<UserProvider>
<UserProvider user={user}>
<ProviderContextProvider>
<SettingsProvider settings={settings}>
<AssistantsProvider
Expand Down
35 changes: 19 additions & 16 deletions web/src/components/user/UserProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,41 @@ interface UserContextType {

const UserContext = createContext<UserContextType | undefined>(undefined);

export function UserProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [isLoadingUser, setIsLoadingUser] = useState(true);
const [isAdmin, setIsAdmin] = useState(false);
const [isCurator, setIsCurator] = useState(false);
export function UserProvider({
children,
user,
}: {
children: React.ReactNode;
user: User | null;
}) {
const [upToDateUser, setUpToDateUser] = useState<User | null>(user);
const [isLoadingUser, setIsLoadingUser] = useState(false);

const fetchUser = async () => {
try {
const user = await getCurrentUser();
setUser(user);
setIsAdmin(user?.role === UserRole.ADMIN);
setIsCurator(
user?.role === UserRole.CURATOR || user?.role == UserRole.GLOBAL_CURATOR
);
setIsLoadingUser(true);
const currentUser = await getCurrentUser();
setUpToDateUser(currentUser);
} catch (error) {
console.error("Error fetching current user:", error);
} finally {
setIsLoadingUser(false);
}
};

useEffect(() => {
fetchUser();
}, []);

const refreshUser = async () => {
await fetchUser();
};

return (
<UserContext.Provider
value={{ user, isLoadingUser, isAdmin, refreshUser, isCurator }}
value={{
user: upToDateUser,
isLoadingUser,
refreshUser,
isAdmin: upToDateUser?.role === UserRole.ADMIN,
isCurator: upToDateUser?.role === UserRole.CURATOR,
}}
>
{children}
</UserContext.Provider>
Expand Down

0 comments on commit 0c2cc74

Please sign in to comment.