mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-30 21:59:46 +02:00
organize seach space apis
This commit is contained in:
parent
43362a383e
commit
78ab020d80
15 changed files with 154 additions and 42 deletions
|
|
@ -55,8 +55,8 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import { activeSearchSpaceChatsAtom } from "@/atoms/chats/queries/active-search-space-chats.query.atom";
|
import { activeSearchSpaceChatsAtom } from "@/atoms/chats/chat-queries.atom";
|
||||||
import { deleteChatMutationAtom } from "@/atoms/chats/mutations/delete-chat.mutation.atom";
|
import { deleteChatMutationAtom } from "@/atoms/chats/chat-mutations.atom";
|
||||||
|
|
||||||
export interface Chat {
|
export interface Chat {
|
||||||
created_at: string;
|
created_at: string;
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ import {
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
import { useLLMPreferences } from "@/hooks/use-llm-configs";
|
import { useLLMPreferences } from "@/hooks/use-llm-configs";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { activeChatIdAtom } from "@/atoms/chats/queries/active-chat.query.atom";
|
import { activeChatIdAtom } from "@/atoms/chats/chat-queries.atom";
|
||||||
import { chatUIAtom } from "@/atoms/chats/active-chat.atom";
|
import { chatUIAtom } from "@/atoms/chats/chat-uis.atom";
|
||||||
import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/active-seach-space.atom";
|
import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/seach-space-queries.atom";
|
||||||
|
|
||||||
export function DashboardClientLayout({
|
export function DashboardClientLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ const DashboardPage = () => {
|
||||||
{searchSpaces &&
|
{searchSpaces &&
|
||||||
searchSpaces.length > 0 &&
|
searchSpaces.length > 0 &&
|
||||||
searchSpaces.map((space) => (
|
searchSpaces.map((space) => (
|
||||||
<motion.div key={space.id} variants={itemVariants} className="aspect-[4/3]">
|
<motion.div key={space.id} variants={itemVariants} className="aspect-4/3">
|
||||||
<Tilt
|
<Tilt
|
||||||
rotationFactor={6}
|
rotationFactor={6}
|
||||||
isRevese
|
isRevese
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { atomWithMutation } from "jotai-tanstack-query";
|
import { atomWithMutation } from "jotai-tanstack-query";
|
||||||
import { deleteChat } from "@/lib/apis/chat-apis";
|
import { deleteChat } from "@/lib/apis/chats.api";
|
||||||
import { activeSearchSpaceIdAtom } from "../../seach-spaces/active-seach-space.atom";
|
import { activeSearchSpaceIdAtom } from "../seach-spaces/seach-space-queries.atom";
|
||||||
import { queryClient } from "@/lib/query-client/client";
|
import { queryClient } from "@/lib/query-client/client";
|
||||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
@ -2,9 +2,13 @@ import { atom } from "jotai";
|
||||||
import { atomWithQuery } from "jotai-tanstack-query";
|
import { atomWithQuery } from "jotai-tanstack-query";
|
||||||
import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-client";
|
import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-client";
|
||||||
import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/podcasts-client";
|
import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/podcasts-client";
|
||||||
import { fetchChatDetails } from "@/lib/apis/chat-apis";
|
import {
|
||||||
import { getPodcastByChatId } from "@/lib/apis/podcast-apis";
|
fetchChatDetails,
|
||||||
|
fetchChatsBySearchSpace,
|
||||||
|
} from "@/lib/apis/chats.api";
|
||||||
|
import { getPodcastByChatId } from "@/lib/apis/podcasts.api";
|
||||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||||
|
import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/seach-space-queries.atom";
|
||||||
|
|
||||||
type ActiveChatState = {
|
type ActiveChatState = {
|
||||||
chatId: string | null;
|
chatId: string | null;
|
||||||
|
|
@ -38,3 +42,23 @@ export const activeChatAtom = atomWithQuery<ActiveChatState>((get) => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const activeSearchSpaceChatsAtom = atomWithQuery((get) => {
|
||||||
|
const searchSpaceId = get(activeSearchSpaceIdAtom);
|
||||||
|
const authToken = localStorage.getItem("surfsense_bearer_token");
|
||||||
|
|
||||||
|
return {
|
||||||
|
queryKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""),
|
||||||
|
enabled: !!searchSpaceId && !!authToken,
|
||||||
|
queryFn: async () => {
|
||||||
|
if (!authToken) {
|
||||||
|
throw new Error("No authentication token found");
|
||||||
|
}
|
||||||
|
if (!searchSpaceId) {
|
||||||
|
throw new Error("No search space id found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetchChatsBySearchSpace(searchSpaceId, authToken);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import { atomWithQuery } from "jotai-tanstack-query";
|
|
||||||
import { fetchChatsBySearchSpace } from "@/lib/apis/chat-apis";
|
|
||||||
import { activeSearchSpaceIdAtom } from "../../seach-spaces/active-seach-space.atom";
|
|
||||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
|
||||||
|
|
||||||
export const activeSearchSpaceChatsAtom = atomWithQuery((get) => {
|
|
||||||
const searchSpaceId = get(activeSearchSpaceIdAtom);
|
|
||||||
const authToken = localStorage.getItem("surfsense_bearer_token");
|
|
||||||
|
|
||||||
return {
|
|
||||||
queryKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""),
|
|
||||||
enabled: !!searchSpaceId && !!authToken,
|
|
||||||
queryFn: async () => {
|
|
||||||
if (!authToken) {
|
|
||||||
throw new Error("No authentication token found");
|
|
||||||
}
|
|
||||||
if (!searchSpaceId) {
|
|
||||||
throw new Error("No search space id found");
|
|
||||||
}
|
|
||||||
|
|
||||||
return fetchChatsBySearchSpace(searchSpaceId, authToken);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
|
|
||||||
export const activeSearchSpaceIdAtom = atom<string | null>(null);
|
export const activeSearchSpaceIdAtom = atom<string | null>(null);
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import { LoaderIcon, PanelRight, TriangleAlert } from "lucide-react";
|
import { LoaderIcon, PanelRight, TriangleAlert } from "lucide-react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { generatePodcast } from "@/lib/apis/podcast-apis";
|
import { generatePodcast } from "@/lib/apis/podcasts.api";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { activeChatAtom, activeChatIdAtom } from "@/atoms/chats/queries/active-chat.query.atom";
|
import { activeChatAtom, activeChatIdAtom } from "@/atoms/chats/chat-queries.atom";
|
||||||
import { chatUIAtom } from "@/atoms/chats/active-chat.atom";
|
import { chatUIAtom } from "@/atoms/chats/chat-uis.atom";
|
||||||
import { ChatPanelView } from "./ChatPanelView";
|
import { ChatPanelView } from "./ChatPanelView";
|
||||||
|
|
||||||
export interface GeneratePodcastRequest {
|
export interface GeneratePodcastRequest {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import { AlertCircle, Play, RefreshCw, Sparkles } from "lucide-react";
|
||||||
import { motion } from "motion/react";
|
import { motion } from "motion/react";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { activeChatAtom } from "@/atoms/chats/queries/active-chat.query.atom";
|
import { activeChatAtom } from "@/atoms/chats/chat-queries.atom";
|
||||||
import { chatUIAtom } from "@/atoms/chats/active-chat.atom";
|
import { chatUIAtom } from "@/atoms/chats/chat-uis.atom";
|
||||||
import { getPodcastStalenessMessage, isPodcastStale } from "../PodcastUtils";
|
import { getPodcastStalenessMessage, isPodcastStale } from "../PodcastUtils";
|
||||||
import type { GeneratePodcastRequest } from "./ChatPanelContainer";
|
import type { GeneratePodcastRequest } from "./ChatPanelContainer";
|
||||||
import { ConfigModal } from "./ConfigModal";
|
import { ConfigModal } from "./ConfigModal";
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { useAtomValue } from "jotai";
|
||||||
import { Pencil } from "lucide-react";
|
import { Pencil } from "lucide-react";
|
||||||
import { useCallback, useContext, useState } from "react";
|
import { useCallback, useContext, useState } from "react";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
import { activeChatAtom } from "@/atoms/chats/queries/active-chat.query.atom";
|
import { activeChatAtom } from "@/atoms/chats/chat-queries.atom";
|
||||||
import type { GeneratePodcastRequest } from "./ChatPanelContainer";
|
import type { GeneratePodcastRequest } from "./ChatPanelContainer";
|
||||||
|
|
||||||
interface ConfigModalProps {
|
interface ConfigModalProps {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from "@/components/ui/breadcrumb";
|
} from "@/components/ui/breadcrumb";
|
||||||
import { useSearchSpace } from "@/hooks/use-search-space";
|
import { useSearchSpace } from "@/hooks/use-search-space";
|
||||||
import { fetchChatDetails } from "@/lib/apis/chat-apis";
|
import { fetchChatDetails } from "@/lib/apis/chats.api";
|
||||||
|
|
||||||
interface BreadcrumbItemInterface {
|
interface BreadcrumbItemInterface {
|
||||||
label: string;
|
label: string;
|
||||||
|
|
|
||||||
112
surfsense_web/lib/apis/search-spaces.api.ts
Normal file
112
surfsense_web/lib/apis/search-spaces.api.ts
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
export const fetchSearchSpaces = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem(
|
||||||
|
"surfsense_bearer_token"
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
method: "GET",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Not authenticated");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error("Error fetching search spaces:", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const handleDeleteSearchSpace = async (id: number) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${id}`,
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem(
|
||||||
|
"surfsense_bearer_token"
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to delete search space");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting search space:", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const handleCreateSearchSpace = async (data: {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${localStorage.getItem(
|
||||||
|
"surfsense_bearer_token"
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to create search space");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating search space:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchSearchSpace = async (searchSpaceId: string) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem(
|
||||||
|
"surfsense_bearer_token"
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
method: "GET",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.status === 401) {
|
||||||
|
// Clear token and redirect to home
|
||||||
|
localStorage.removeItem("surfsense_bearer_token");
|
||||||
|
window.location.href = "/";
|
||||||
|
throw new Error("Unauthorized: Redirecting to login page");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to fetch search space: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error("Error fetching search space:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue