diff --git a/backend/danswer/configs/app_configs.py b/backend/danswer/configs/app_configs.py index 0d8b7da70..2497730bf 100644 --- a/backend/danswer/configs/app_configs.py +++ b/backend/danswer/configs/app_configs.py @@ -134,7 +134,7 @@ POSTGRES_PASSWORD = urllib.parse.quote_plus( os.environ.get("POSTGRES_PASSWORD") or "password" ) POSTGRES_HOST = os.environ.get("POSTGRES_HOST") or "localhost" -POSTGRES_PORT = os.environ.get("POSTGRES_PORT") or "5432" +POSTGRES_PORT = os.environ.get("POSTGRES_PORT") or "5433" POSTGRES_DB = os.environ.get("POSTGRES_DB") or "postgres" POSTGRES_API_SERVER_POOL_SIZE = int( diff --git a/deployment/docker_compose/docker-compose.dev.yml b/deployment/docker_compose/docker-compose.dev.yml index 6f4619f83..910e2934c 100644 --- a/deployment/docker_compose/docker-compose.dev.yml +++ b/deployment/docker_compose/docker-compose.dev.yml @@ -312,7 +312,7 @@ services: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} ports: - - "5432:5432" + - "5433:5432" volumes: - db_volume:/var/lib/postgresql/data diff --git a/deployment/docker_compose/docker-compose.gpu-dev.yml b/deployment/docker_compose/docker-compose.gpu-dev.yml index 6397f657c..03e436a2e 100644 --- a/deployment/docker_compose/docker-compose.gpu-dev.yml +++ b/deployment/docker_compose/docker-compose.gpu-dev.yml @@ -312,7 +312,7 @@ services: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} ports: - - "5432:5432" + - "5433:5432" volumes: - db_volume:/var/lib/postgresql/data diff --git a/deployment/docker_compose/docker-compose.search-testing.yml b/deployment/docker_compose/docker-compose.search-testing.yml index fab950c06..2afd54e02 100644 --- a/deployment/docker_compose/docker-compose.search-testing.yml +++ b/deployment/docker_compose/docker-compose.search-testing.yml @@ -157,7 +157,7 @@ services: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} ports: - - "5432" + - "5433" volumes: - db_volume:/var/lib/postgresql/data diff --git a/web/src/components/UserDropdown.tsx b/web/src/components/UserDropdown.tsx index 2642c27c6..f1cfed9f6 100644 --- a/web/src/components/UserDropdown.tsx +++ b/web/src/components/UserDropdown.tsx @@ -9,14 +9,24 @@ import { checkUserIsNoAuthUser, logout } from "@/lib/user"; import { Popover } from "./popover/Popover"; import { LOGOUT_DISABLED } from "@/lib/constants"; import { SettingsContext } from "./settings/SettingsProvider"; -import { LightSettingsIcon } from "./icons/icons"; +import { + AssistantsIconSkeleton, + LightSettingsIcon, + UsersIcon, +} from "./icons/icons"; import { pageType } from "@/app/chat/sessionSidebar/types"; -import { NavigationItem } from "@/app/admin/settings/interfaces"; +import { NavigationItem, Notification } from "@/app/admin/settings/interfaces"; import DynamicFaIcon, { preloadIcons } from "./icons/DynamicFaIcon"; +import { useUser } from "./user/UserProvider"; +import { usePaidEnterpriseFeaturesEnabled } from "./settings/usePaidEnterpriseFeaturesEnabled"; +import { Notifications } from "./chat_search/Notifications"; +import useSWR from "swr"; +import { errorHandlingFetcher } from "@/lib/fetcher"; +import { Bell } from "@phosphor-icons/react"; interface DropdownOptionProps { href?: string; - onClick?: () => void; + onClick?: (e: React.MouseEvent) => void; icon: React.ReactNode; label: string; openInNewTab?: boolean; @@ -51,24 +61,26 @@ const DropdownOption: React.FC = ({ } }; -export function UserDropdown({ - user, - page, -}: { - user: User | null; - page?: pageType; -}) { +export function UserDropdown({ page }: { page?: pageType }) { + const { user } = useUser(); const [userInfoVisible, setUserInfoVisible] = useState(false); const userInfoRef = useRef(null); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); + const isPaidEnterpriseFeaturesEnabled = usePaidEnterpriseFeaturesEnabled(); + const [showNotifications, setShowNotifications] = useState(false); const combinedSettings = useContext(SettingsContext); const customNavItems: NavigationItem[] = useMemo( () => combinedSettings?.enterpriseSettings?.custom_nav_items || [], [combinedSettings] ); + const { + data: notifications, + error, + mutate: refreshNotifications, + } = useSWR("/api/notifications", errorHandlingFetcher); useEffect(() => { const iconNames = customNavItems @@ -137,8 +149,15 @@ export function UserDropdown({ } popover={ -
+ {showNotifications ? ( + + ) : ( +
- {customNavItems.map((item, i) => ( - - -
- ) : ( - + +
+ ) : ( + + ) + } + label={item.title} + openInNewTab + /> + ))} + + {showAdminPanel ? ( + + } + label="Admin Panel" + /> + ) : ( + showCuratorPanel && ( + + } + label="Curator Panel" /> ) - } - label={item.title} - openInNewTab - /> - ))} + )} - {showAdminPanel ? ( - } - label="Admin Panel" - /> - ) : ( - showCuratorPanel && ( - } - label="Curator Panel" - /> - ) + {isPaidEnterpriseFeaturesEnabled && ( + { + console.log("CLICKKK"); + e.stopPropagation(); + setUserInfoVisible(true); + setShowNotifications(true); + }} + icon={} + label={`Notifications ${notifications && notifications.length > 0 ? `(${notifications.length})` : ""}`} + /> + )} + + {showLogout && + (showCuratorPanel || + showAdminPanel || + customNavItems.length > 0) && ( +
+ )} + + {showLogout && ( + } + label="Log out" + /> + )} +
)} - - {showLogout && - (showCuratorPanel || - showAdminPanel || - customNavItems.length > 0) && ( -
- )} - - {showLogout && ( - } - label="Log out" - /> - )} -
+ } side="bottom" align="end" diff --git a/web/src/components/admin/ClientLayout.tsx b/web/src/components/admin/ClientLayout.tsx index 68154c903..16500b5e0 100644 --- a/web/src/components/admin/ClientLayout.tsx +++ b/web/src/components/admin/ClientLayout.tsx @@ -418,7 +418,7 @@ export function ClientLayout({
- +
{children} diff --git a/web/src/components/chat_search/Header.tsx b/web/src/components/chat_search/Header.tsx index 760384b36..3a53e4799 100644 --- a/web/src/components/chat_search/Header.tsx +++ b/web/src/components/chat_search/Header.tsx @@ -2,7 +2,7 @@ import { User } from "@/lib/types"; import { UserDropdown } from "../UserDropdown"; import { FiShare2 } from "react-icons/fi"; -import { SetStateAction, useEffect } from "react"; +import { SetStateAction, useContext, useEffect } from "react"; import { NewChatIcon } from "../icons/icons"; import { NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA } from "@/lib/constants"; import { ChatSession } from "@/app/chat/interfaces"; @@ -11,10 +11,9 @@ import { pageType } from "@/app/chat/sessionSidebar/types"; import { useRouter } from "next/navigation"; import { ChatBanner } from "@/app/chat/ChatBanner"; import LogoType from "../header/LogoType"; -import { Notifications } from "./Notifications"; -import { useUser } from "../user/UserProvider"; export default function FunctionalHeader({ + user, page, currentChatSession, setSharingModalVisible, @@ -24,12 +23,12 @@ export default function FunctionalHeader({ }: { reset?: () => void; page: pageType; + user: User | null; sidebarToggled?: boolean; currentChatSession?: ChatSession | null | undefined; setSharingModalVisible?: (value: SetStateAction) => void; toggleSidebar?: () => void; }) { - const { user } = useUser(); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.metaKey || event.ctrlKey) { @@ -64,7 +63,6 @@ export default function FunctionalHeader({ : ""); router.push(newChatUrl); }; - return (
@@ -110,9 +108,8 @@ export default function FunctionalHeader({
)} -
- +
{ +export const Notifications = ({ + notifications, + refreshNotifications, +}: { + notifications: Notification[]; + refreshNotifications: () => void; +}) => { const [showDropdown, setShowDropdown] = useState(false); - const { - data: notifications, - error, - mutate: refreshNotifications, - } = useSWR("/api/notifications", errorHandlingFetcher); + const { refreshAssistants } = useAssistants(); const { refreshUser } = useUser(); @@ -120,80 +121,69 @@ export const Notifications = () => { return (
-
setShowDropdown(!showDropdown)} - className="cursor-pointer relative notification-dropdown" - > - - {sortedNotifications.length > 0 && ( - - )} -
- {showDropdown && ( -
- {sortedNotifications.length > 0 ? ( - sortedNotifications - .filter( - (notification) => - notification.notif_type === NotificationType.PERSONA_SHARED - ) - .map((notification) => { - const persona = notification.additional_data?.persona_id - ? personas[notification.additional_data.persona_id] - : null; +
+ {sortedNotifications.length > 0 ? ( + sortedNotifications + .filter( + (notification) => + notification.notif_type === NotificationType.PERSONA_SHARED + ) + .map((notification) => { + const persona = notification.additional_data?.persona_id + ? personas[notification.additional_data.persona_id] + : null; - return ( -
-
- {persona && ( -
- -
- )} -
-

- New Assistant Shared With You -

- -

- Do you want to accept this assistant? -

- {persona && ( -

- Assistant: {persona.name} -

- )} + return ( +
+
+ {persona && ( +
+
-
-
- - + )} +
+

+ New Assistant Shared With You +

+ +

+ Do you want to accept this assistant? +

+ {persona && ( +

+ Assistant: {persona.name} +

+ )}
- ); - }) - ) : ( -
- No new notifications -
- )} -
- )} +
+ + +
+
+ ); + }) + ) : ( +
+ No new notifications +
+ )} +
); };