diff --git a/docker/.env.example b/docker/.env.example index 2f9e232886..a6cabe6558 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -279,4 +279,12 @@ GID='1000' # AGENT_SERPLY_API_KEY= #------ SearXNG ----------- https://github.com/searxng/searxng -# AGENT_SEARXNG_API_URL= \ No newline at end of file +# AGENT_SEARXNG_API_URL= + +########################################### +######## Other Configurations ############ +########################################### + +# Disable viewing chat history from the UI and frontend APIs. +# See https://docs.anythingllm.com/configuration#disable-view-chat-history for more information. +# DISABLE_VIEW_CHAT_HISTORY=1 \ No newline at end of file diff --git a/frontend/src/components/CanViewChatHistory/index.jsx b/frontend/src/components/CanViewChatHistory/index.jsx new file mode 100644 index 0000000000..44e7535314 --- /dev/null +++ b/frontend/src/components/CanViewChatHistory/index.jsx @@ -0,0 +1,50 @@ +import { useEffect, useState } from "react"; +import { FullScreenLoader } from "@/components/Preloader"; +import System from "@/models/system"; +import paths from "@/utils/paths"; + +/** + * Protects the view from system set ups who cannot view chat history. + * If the user cannot view chat history, they are redirected to the home page. + * @param {React.ReactNode} children + */ +export function CanViewChatHistory({ children }) { + const { loading, viewable } = useCanViewChatHistory(); + if (loading) return ; + if (!viewable) { + window.location.href = paths.home(); + return ; + } + + return <>{children}; +} + +/** + * Provides the `viewable` state to the children. + * @returns {React.ReactNode} + */ +export function CanViewChatHistoryProvider({ children }) { + const { loading, viewable } = useCanViewChatHistory(); + if (loading) return null; + return <>{children({ viewable })}; +} + +/** + * Hook that fetches the can view chat history state from local storage or the system settings. + * @returns {Promise<{viewable: boolean, error: string | null}>} + */ +export function useCanViewChatHistory() { + const [loading, setLoading] = useState(true); + const [viewable, setViewable] = useState(false); + + useEffect(() => { + async function fetchViewable() { + const { viewable } = await System.fetchCanViewChatHistory(); + setViewable(viewable); + setLoading(false); + } + fetchViewable(); + }, []); + + return { loading, viewable }; +} diff --git a/frontend/src/components/SettingsSidebar/MenuOption/index.jsx b/frontend/src/components/SettingsSidebar/MenuOption/index.jsx index 38be4883b9..3834549ea9 100644 --- a/frontend/src/components/SettingsSidebar/MenuOption/index.jsx +++ b/frontend/src/components/SettingsSidebar/MenuOption/index.jsx @@ -149,17 +149,32 @@ function useIsExpanded({ return { isExpanded, setIsExpanded }; } +/** + * Checks if the child options are visible to the user. + * This hides the top level options if the child options are not visible + * for either the users permissions or the child options hidden prop is set to true by other means. + * If all child options return false for `isVisible` then the parent option will not be visible as well. + * @param {object} user - The user object. + * @param {array} childOptions - The child options. + * @returns {boolean} - True if the child options are visible, false otherwise. + */ function hasVisibleOptions(user = null, childOptions = []) { if (!Array.isArray(childOptions) || childOptions?.length === 0) return false; - function isVisible({ roles = [], user = null, flex = false }) { + function isVisible({ + roles = [], + user = null, + flex = false, + hidden = false, + }) { + if (hidden) return false; if (!flex && !roles.includes(user?.role)) return false; if (flex && !!user && !roles.includes(user?.role)) return false; return true; } return childOptions.some((opt) => - isVisible({ roles: opt.roles, user, flex: opt.flex }) + isVisible({ roles: opt.roles, user, flex: opt.flex, hidden: opt.hidden }) ); } diff --git a/frontend/src/components/SettingsSidebar/index.jsx b/frontend/src/components/SettingsSidebar/index.jsx index 367b21ab65..46eba5db9c 100644 --- a/frontend/src/components/SettingsSidebar/index.jsx +++ b/frontend/src/components/SettingsSidebar/index.jsx @@ -21,6 +21,7 @@ import { useTranslation } from "react-i18next"; import showToast from "@/utils/toast"; import System from "@/models/system"; import Option from "./MenuOption"; +import { CanViewChatHistoryProvider } from "../CanViewChatHistory"; export default function SettingsSidebar() { const { t } = useTranslation(); @@ -208,151 +209,157 @@ function SupportEmail() { } const SidebarOptions = ({ user = null, t }) => ( - <> -