mirror of
https://github.com/MODSetter/SurfSense.git
synced 2025-09-02 02:29:08 +00:00
Biome: fixes for app/dashboard/search_pace_id pages
This commit is contained in:
parent
07063a1a18
commit
ecc4c11100
22 changed files with 472 additions and 480 deletions
|
@ -1,25 +1,23 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { format } from "date-fns";
|
||||
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
||||
import {
|
||||
MessageCircleMore,
|
||||
Search,
|
||||
Calendar,
|
||||
Tag,
|
||||
Trash2,
|
||||
ExternalLink,
|
||||
MoreHorizontal,
|
||||
Radio,
|
||||
CheckCircle,
|
||||
Circle,
|
||||
ExternalLink,
|
||||
MessageCircleMore,
|
||||
MoreHorizontal,
|
||||
Podcast,
|
||||
Search,
|
||||
Tag,
|
||||
Trash2,
|
||||
} from "lucide-react";
|
||||
import { format } from "date-fns";
|
||||
|
||||
// UI Components
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
|
@ -29,22 +27,6 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuSeparator,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
Pagination,
|
||||
PaginationContent,
|
||||
PaginationItem,
|
||||
PaginationLink,
|
||||
PaginationNext,
|
||||
PaginationPrevious,
|
||||
} from "@/components/ui/pagination";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
|
@ -53,6 +35,24 @@ import {
|
|||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
// UI Components
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Pagination,
|
||||
PaginationContent,
|
||||
PaginationItem,
|
||||
PaginationLink,
|
||||
PaginationNext,
|
||||
PaginationPrevious,
|
||||
} from "@/components/ui/pagination";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
@ -61,9 +61,6 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface Chat {
|
||||
created_at: string;
|
||||
|
@ -86,13 +83,13 @@ interface ChatsPageClientProps {
|
|||
searchSpaceId: string;
|
||||
}
|
||||
|
||||
const pageVariants = {
|
||||
const pageVariants: Variants = {
|
||||
initial: { opacity: 0 },
|
||||
enter: { opacity: 1, transition: { duration: 0.3, ease: "easeInOut" } },
|
||||
exit: { opacity: 0, transition: { duration: 0.3, ease: "easeInOut" } },
|
||||
};
|
||||
|
||||
const chatCardVariants = {
|
||||
const chatCardVariants: Variants = {
|
||||
initial: { y: 20, opacity: 0 },
|
||||
animate: { y: 0, opacity: 1 },
|
||||
exit: { y: -20, opacity: 0 },
|
||||
|
@ -101,6 +98,7 @@ const chatCardVariants = {
|
|||
const MotionCard = motion(Card);
|
||||
|
||||
export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps) {
|
||||
const router = useRouter();
|
||||
const [chats, setChats] = useState<Chat[]>([]);
|
||||
const [filteredChats, setFilteredChats] = useState<Chat[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
@ -134,7 +132,7 @@ export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps)
|
|||
const pageParam = searchParams.get("page");
|
||||
if (pageParam) {
|
||||
const pageNumber = parseInt(pageParam, 10);
|
||||
if (!isNaN(pageNumber) && pageNumber > 0) {
|
||||
if (!Number.isNaN(pageNumber) && pageNumber > 0) {
|
||||
setCurrentPage(pageNumber);
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +316,7 @@ export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps)
|
|||
throw new Error(errorData.detail || "Failed to generate podcast");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const _data = await response.json();
|
||||
toast.success(`Podcast "${currentTitle}" generation started!`);
|
||||
|
||||
// Move to the next chat or finish
|
||||
|
@ -636,7 +634,9 @@ export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps)
|
|||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
(window.location.href = `/dashboard/${chat.search_space_id}/researcher/${chat.id}`)
|
||||
router.push(
|
||||
`/dashboard/${chat.search_space_id}/researcher/${chat.id}`
|
||||
)
|
||||
}
|
||||
>
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
|
@ -841,10 +841,7 @@ export default function ChatsPageClient({ searchSpaceId }: ChatsPageClientProps)
|
|||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Create a podcast from this chat. The podcast will be available in the podcasts
|
||||
section once generated.
|
||||
</>
|
||||
"Create a podcast from this chat. The podcast will be available in the podcasts section once generated."
|
||||
)}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
"use client";
|
||||
|
||||
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
|
||||
import { ThemeTogglerComponent } from "@/components/theme/theme-toggle";
|
||||
import type React from "react";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { AppSidebarProvider } from "@/components/sidebar/AppSidebarProvider";
|
||||
import { ThemeTogglerComponent } from "@/components/theme/theme-toggle";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
|
||||
|
||||
export function DashboardClientLayout({
|
||||
children,
|
||||
|
|
|
@ -1,22 +1,12 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { format } from "date-fns";
|
||||
import { motion } from "framer-motion";
|
||||
import { Calendar as CalendarIcon, Edit, Plus, RefreshCw, Trash2 } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Edit, Plus, Trash2, RefreshCw, Calendar as CalendarIcon } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { getConnectorIcon } from "@/components/chat";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
|
@ -28,7 +18,9 @@ import {
|
|||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
|
@ -36,14 +28,20 @@ import {
|
|||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Calendar } from "@/components/ui/calendar";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { getConnectorIcon } from "@/components/chat";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { format } from "date-fns";
|
||||
|
||||
// Helper function to format date with time
|
||||
const formatDateTime = (dateString: string | null): string => {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
"use client";
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Loader2 } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { ArrowLeft, Check, Loader2, Github } from "lucide-react";
|
||||
|
||||
import { Form } from "@/components/ui/form";
|
||||
import { getConnectorIcon } from "@/components/chat";
|
||||
import { EditConnectorLoadingSkeleton } from "@/components/editConnector/EditConnectorLoadingSkeleton";
|
||||
import { EditConnectorNameForm } from "@/components/editConnector/EditConnectorNameForm";
|
||||
import { EditGitHubConnectorConfig } from "@/components/editConnector/EditGitHubConnectorConfig";
|
||||
import { EditSimpleTokenForm } from "@/components/editConnector/EditSimpleTokenForm";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
|
@ -16,15 +19,10 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
|
||||
import { Form } from "@/components/ui/form";
|
||||
import { useConnectorEditPage } from "@/hooks/useConnectorEditPage";
|
||||
// Import Utils, Types, Hook, and Components
|
||||
import { getConnectorTypeDisplay } from "@/lib/connectors/utils";
|
||||
import { useConnectorEditPage } from "@/hooks/useConnectorEditPage";
|
||||
import { EditConnectorLoadingSkeleton } from "@/components/editConnector/EditConnectorLoadingSkeleton";
|
||||
import { EditConnectorNameForm } from "@/components/editConnector/EditConnectorNameForm";
|
||||
import { EditGitHubConnectorConfig } from "@/components/editConnector/EditGitHubConnectorConfig";
|
||||
import { EditSimpleTokenForm } from "@/components/editConnector/EditSimpleTokenForm";
|
||||
import { getConnectorIcon } from "@/components/chat";
|
||||
|
||||
export default function EditConnectorPage() {
|
||||
const router = useRouter();
|
||||
|
@ -58,7 +56,7 @@ export default function EditConnectorPage() {
|
|||
|
||||
// Redirect if connectorId is not a valid number after parsing
|
||||
useEffect(() => {
|
||||
if (isNaN(connectorId)) {
|
||||
if (Number.isNaN(connectorId)) {
|
||||
toast.error("Invalid Connector ID.");
|
||||
router.push(`/dashboard/${searchSpaceId}/connectors`);
|
||||
}
|
||||
|
@ -67,7 +65,7 @@ export default function EditConnectorPage() {
|
|||
// Loading State
|
||||
if (connectorsLoading || !connector) {
|
||||
// Handle NaN case before showing skeleton
|
||||
if (isNaN(connectorId)) return null;
|
||||
if (Number.isNaN(connectorId)) return null;
|
||||
return <EditConnectorLoadingSkeleton />;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import {
|
||||
useSearchSourceConnectors,
|
||||
type SearchSourceConnector,
|
||||
} from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -23,9 +21,10 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
type SearchSourceConnector,
|
||||
useSearchSourceConnectors,
|
||||
} from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const apiConnectorFormSchema = z.object({
|
||||
|
@ -57,6 +56,20 @@ const getConnectorTypeDisplay = (type: string): string => {
|
|||
// Define the type for the form values
|
||||
type ApiConnectorFormValues = z.infer<typeof apiConnectorFormSchema>;
|
||||
|
||||
// Get API key field name based on connector type
|
||||
const getApiKeyFieldName = (connectorType: string): string => {
|
||||
const fieldMap: Record<string, string> = {
|
||||
SERPER_API: "SERPER_API_KEY",
|
||||
TAVILY_API: "TAVILY_API_KEY",
|
||||
SLACK_CONNECTOR: "SLACK_BOT_TOKEN",
|
||||
NOTION_CONNECTOR: "NOTION_INTEGRATION_TOKEN",
|
||||
GITHUB_CONNECTOR: "GITHUB_PAT",
|
||||
DISCORD_CONNECTOR: "DISCORD_BOT_TOKEN",
|
||||
LINKUP_API: "LINKUP_API_KEY",
|
||||
};
|
||||
return fieldMap[connectorType] || "";
|
||||
};
|
||||
|
||||
export default function EditConnectorPage() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
|
@ -77,20 +90,6 @@ export default function EditConnectorPage() {
|
|||
},
|
||||
});
|
||||
|
||||
// Get API key field name based on connector type
|
||||
const getApiKeyFieldName = (connectorType: string): string => {
|
||||
const fieldMap: Record<string, string> = {
|
||||
SERPER_API: "SERPER_API_KEY",
|
||||
TAVILY_API: "TAVILY_API_KEY",
|
||||
SLACK_CONNECTOR: "SLACK_BOT_TOKEN",
|
||||
NOTION_CONNECTOR: "NOTION_INTEGRATION_TOKEN",
|
||||
GITHUB_CONNECTOR: "GITHUB_PAT",
|
||||
DISCORD_CONNECTOR: "DISCORD_BOT_TOKEN",
|
||||
LINKUP_API: "LINKUP_API_KEY",
|
||||
};
|
||||
return fieldMap[connectorType] || "";
|
||||
};
|
||||
|
||||
// Find connector in the list
|
||||
useEffect(() => {
|
||||
const currentConnector = connectors.find((c) => c.id === connectorId);
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,23 +34,8 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const discordConnectorFormSchema = z.object({
|
||||
|
|
|
@ -1,16 +1,30 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, CircleAlert, Github, Info, ListChecks, Loader2 } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { ArrowLeft, Check, Info, Loader2, Github, CircleAlert, ListChecks } from "lucide-react";
|
||||
|
||||
// Assuming useSearchSourceConnectors hook exists and works similarly
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -21,24 +35,9 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
// Assuming useSearchSourceConnectors hook exists and works similarly
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod for GitHub PAT entry step
|
||||
const githubPatFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,23 +34,8 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const jiraConnectorFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,23 +34,8 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const linearConnectorFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,16 +28,7 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const linkupApiFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,23 +34,8 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const notionConnectorFormSchema = z.object({
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
"use client";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||
import {
|
||||
IconBrandDiscord,
|
||||
IconBrandGithub,
|
||||
|
@ -12,16 +8,20 @@ import {
|
|||
IconBrandZoom,
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconMail,
|
||||
IconWorldWww,
|
||||
IconTicket,
|
||||
IconLayoutKanban,
|
||||
IconLinkPlus,
|
||||
IconMail,
|
||||
IconTicket,
|
||||
IconWorldWww,
|
||||
} from "@tabler/icons-react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||
|
||||
// Define the Connector type
|
||||
interface Connector {
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,16 +28,7 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const serperApiFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,23 +34,8 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const slackConnectorFormSchema = z.object({
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion } from "framer-motion";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { toast } from "sonner";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import * as z from "zod";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
|
@ -20,16 +28,7 @@ import {
|
|||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||
|
||||
// Define the form schema with Zod
|
||||
const tavilyApiFormSchema = z.object({
|
||||
|
|
|
@ -1,5 +1,57 @@
|
|||
"use client";
|
||||
|
||||
import {
|
||||
IconBrandDiscord,
|
||||
IconBrandGithub,
|
||||
IconBrandNotion,
|
||||
IconBrandSlack,
|
||||
IconBrandYoutube,
|
||||
IconLayoutKanban,
|
||||
IconTicket,
|
||||
} from "@tabler/icons-react";
|
||||
import {
|
||||
type ColumnDef,
|
||||
type ColumnFiltersState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getFacetedUniqueValues,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
type PaginationState,
|
||||
type Row,
|
||||
type SortingState,
|
||||
useReactTable,
|
||||
type VisibilityState,
|
||||
} from "@tanstack/react-table";
|
||||
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
||||
import {
|
||||
AlertCircle,
|
||||
ChevronDown,
|
||||
ChevronFirst,
|
||||
ChevronLast,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronUp,
|
||||
CircleAlert,
|
||||
CircleX,
|
||||
Columns3,
|
||||
File,
|
||||
FileX,
|
||||
Filter,
|
||||
Globe,
|
||||
ListFilter,
|
||||
MoreHorizontal,
|
||||
Trash,
|
||||
Webhook,
|
||||
} from "lucide-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import React, { useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import rehypeSanitize from "rehype-sanitize";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { toast } from "sonner";
|
||||
import { DocumentViewer } from "@/components/document-viewer";
|
||||
import { JsonMetadataViewer } from "@/components/json-metadata-viewer";
|
||||
import {
|
||||
|
@ -43,64 +95,12 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { useDocuments } from "@/hooks/use-documents";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
IconBrandDiscord,
|
||||
IconBrandGithub,
|
||||
IconBrandNotion,
|
||||
IconBrandSlack,
|
||||
IconBrandYoutube,
|
||||
IconLayoutKanban,
|
||||
IconTicket,
|
||||
} from "@tabler/icons-react";
|
||||
import {
|
||||
type ColumnDef,
|
||||
type ColumnFiltersState,
|
||||
type FilterFn,
|
||||
type PaginationState,
|
||||
type Row,
|
||||
type SortingState,
|
||||
type VisibilityState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getFacetedUniqueValues,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import {
|
||||
AlertCircle,
|
||||
ChevronDown,
|
||||
ChevronFirst,
|
||||
ChevronLast,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronUp,
|
||||
CircleAlert,
|
||||
CircleX,
|
||||
Columns3,
|
||||
File,
|
||||
FileX,
|
||||
Filter,
|
||||
Globe,
|
||||
ListFilter,
|
||||
MoreHorizontal,
|
||||
Trash,
|
||||
Webhook,
|
||||
} from "lucide-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import React, { useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import rehypeSanitize from "rehype-sanitize";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// Define animation variants for reuse
|
||||
const fadeInScale = {
|
||||
const fadeInScale: Variants = {
|
||||
hidden: { opacity: 0, scale: 0.95 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
|
@ -132,19 +132,6 @@ type Document = {
|
|||
search_space_id: number;
|
||||
};
|
||||
|
||||
// Custom filter function for multi-column searching
|
||||
const multiColumnFilterFn: FilterFn<Document> = (row, columnId, filterValue) => {
|
||||
const searchableRowContent = `${row.original.title}`.toLowerCase();
|
||||
const searchTerm = (filterValue ?? "").toLowerCase();
|
||||
return searchableRowContent.includes(searchTerm);
|
||||
};
|
||||
|
||||
const statusFilterFn: FilterFn<Document> = (row, columnId, filterValue: string[]) => {
|
||||
if (!filterValue?.length) return true;
|
||||
const status = row.getValue(columnId) as string;
|
||||
return filterValue.includes(status);
|
||||
};
|
||||
|
||||
// Add document type icons mapping
|
||||
const documentTypeIcons = {
|
||||
EXTENSION: Webhook,
|
||||
|
@ -187,6 +174,8 @@ const columns: ColumnDef<Document>[] = [
|
|||
accessorKey: "title",
|
||||
cell: ({ row }) => {
|
||||
const Icon = documentTypeIcons[row.original.document_type];
|
||||
const title = row.getValue("title") as string;
|
||||
const truncatedTitle = title.length > 30 ? `${title.slice(0, 30)}...` : title;
|
||||
return (
|
||||
<motion.div
|
||||
className="flex items-center gap-2 font-medium"
|
||||
|
@ -194,8 +183,17 @@ const columns: ColumnDef<Document>[] = [
|
|||
transition={{ type: "spring", stiffness: 300 }}
|
||||
style={{ display: "flex" }}
|
||||
>
|
||||
<Icon size={16} className="text-muted-foreground shrink-0" />
|
||||
<span>{row.getValue("title")}</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="flex items-center gap-2">
|
||||
<Icon size={16} className="text-muted-foreground shrink-0" />
|
||||
<span>{truncatedTitle}</span>
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{title}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</motion.div>
|
||||
);
|
||||
},
|
||||
|
@ -231,7 +229,7 @@ const columns: ColumnDef<Document>[] = [
|
|||
const title = row.getValue("title") as string;
|
||||
|
||||
// Create a truncated preview (first 150 characters)
|
||||
const previewContent = content.length > 150 ? content.substring(0, 150) + "..." : content;
|
||||
const previewContent = content.length > 150 ? `${content.substring(0, 150)}...` : content;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
|
@ -336,7 +334,7 @@ export default function DocumentsTable() {
|
|||
|
||||
useEffect(() => {
|
||||
if (documents) {
|
||||
setData(documents);
|
||||
setData(documents as Document[]);
|
||||
}
|
||||
}, [documents]);
|
||||
|
||||
|
@ -408,19 +406,19 @@ export default function DocumentsTable() {
|
|||
const values = Array.from(statusColumn.getFacetedUniqueValues().keys());
|
||||
|
||||
return values.sort();
|
||||
}, [table.getColumn("document_type")?.getFacetedUniqueValues()]);
|
||||
}, [table.getColumn]);
|
||||
|
||||
// Get counts for each status
|
||||
const statusCounts = useMemo(() => {
|
||||
const statusColumn = table.getColumn("document_type");
|
||||
if (!statusColumn) return new Map();
|
||||
return statusColumn.getFacetedUniqueValues();
|
||||
}, [table.getColumn("document_type")?.getFacetedUniqueValues()]);
|
||||
}, [table.getColumn]);
|
||||
|
||||
const selectedStatuses = useMemo(() => {
|
||||
const filterValue = table.getColumn("document_type")?.getFilterValue() as string[];
|
||||
return filterValue ?? [];
|
||||
}, [table.getColumn("document_type")?.getFilterValue()]);
|
||||
}, [table.getColumn]);
|
||||
|
||||
const handleStatusChange = (checked: boolean, value: string) => {
|
||||
const filterValue = table.getColumn("document_type")?.getFilterValue() as string[];
|
||||
|
@ -722,7 +720,8 @@ export default function DocumentsTable() {
|
|||
className="h-12 px-4 py-3"
|
||||
>
|
||||
{header.isPlaceholder ? null : header.column.getCanSort() ? (
|
||||
<div
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
header.column.getCanSort() &&
|
||||
"flex h-full cursor-pointer select-none items-center justify-between gap-2"
|
||||
|
@ -759,7 +758,7 @@ export default function DocumentsTable() {
|
|||
/>
|
||||
),
|
||||
}[header.column.getIsSorted() as string] ?? null}
|
||||
</div>
|
||||
</Button>
|
||||
) : (
|
||||
flexRender(header.column.columnDef.header, header.getContext())
|
||||
)}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"use client";
|
||||
|
||||
import { useState, useCallback, useRef } from "react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { Calendar, CheckCircle2, FileType, Tag, Upload, X } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
import { X, Upload, Tag, CheckCircle2, Calendar, FileType } from "lucide-react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
// Grid pattern component inspired by Aceternity UI
|
||||
function GridPattern() {
|
||||
|
@ -230,7 +230,7 @@ export default function FileUploader() {
|
|||
const k = 1024;
|
||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / k ** i).toFixed(2)) + " " + sizes[i];
|
||||
return `${parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
const handleUpload = async () => {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { type Tag, TagInput } from "emblor";
|
||||
import { Globe, Loader2 } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
|
@ -13,8 +14,7 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { toast } from "sonner";
|
||||
import { Globe, Loader2 } from "lucide-react";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
||||
// URL validation regex
|
||||
const urlRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { IconBrandYoutube } from "@tabler/icons-react";
|
||||
import { type Tag, TagInput } from "emblor";
|
||||
import { motion, type Variants } from "framer-motion";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
|
@ -13,9 +16,7 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { toast } from "sonner";
|
||||
import { Youtube, Loader2 } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
||||
// YouTube video ID validation regex
|
||||
const youtubeRegex =
|
||||
|
@ -135,7 +136,7 @@ export default function YouTubeVideoAdder() {
|
|||
};
|
||||
|
||||
// Animation variants
|
||||
const containerVariants = {
|
||||
const containerVariants: Variants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
|
@ -145,7 +146,7 @@ export default function YouTubeVideoAdder() {
|
|||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
const itemVariants: Variants = {
|
||||
hidden: { y: 20, opacity: 0 },
|
||||
visible: {
|
||||
y: 0,
|
||||
|
@ -165,7 +166,7 @@ export default function YouTubeVideoAdder() {
|
|||
<motion.div variants={itemVariants}>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Youtube className="h-5 w-5" />
|
||||
<IconBrandYoutube className="h-5 w-5" />
|
||||
Add YouTube Videos
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
|
@ -282,7 +283,7 @@ export default function YouTubeVideoAdder() {
|
|||
transition={{ delay: 0.2 }}
|
||||
className="mr-2"
|
||||
>
|
||||
<Youtube className="h-4 w-4" />
|
||||
<IconBrandYoutube className="h-4 w-4" />
|
||||
</motion.span>
|
||||
Submit YouTube Videos
|
||||
</>
|
||||
|
|
|
@ -1,5 +1,51 @@
|
|||
"use client";
|
||||
|
||||
import {
|
||||
type ColumnDef,
|
||||
type ColumnFiltersState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getFacetedUniqueValues,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
type PaginationState,
|
||||
type Row,
|
||||
type SortingState,
|
||||
useReactTable,
|
||||
type VisibilityState,
|
||||
} from "@tanstack/react-table";
|
||||
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
||||
import {
|
||||
Activity,
|
||||
AlertCircle,
|
||||
AlertTriangle,
|
||||
Bug,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
ChevronFirst,
|
||||
ChevronLast,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronUp,
|
||||
CircleAlert,
|
||||
CircleX,
|
||||
Clock,
|
||||
Columns3,
|
||||
Filter,
|
||||
Info,
|
||||
ListFilter,
|
||||
MoreHorizontal,
|
||||
RefreshCw,
|
||||
Terminal,
|
||||
Trash,
|
||||
X,
|
||||
Zap,
|
||||
} from "lucide-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import React, { useContext, useId, useMemo, useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { JsonMetadataViewer } from "@/components/json-metadata-viewer";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
|
@ -12,7 +58,7 @@ import {
|
|||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
@ -42,57 +88,11 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { JsonMetadataViewer } from "@/components/json-metadata-viewer";
|
||||
import { useLogs, useLogsSummary, type Log, type LogLevel, type LogStatus } from "@/hooks/use-logs";
|
||||
import { type Log, type LogLevel, type LogStatus, useLogs, useLogsSummary } from "@/hooks/use-logs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
type ColumnDef,
|
||||
type ColumnFiltersState,
|
||||
type PaginationState,
|
||||
type Row,
|
||||
type SortingState,
|
||||
type VisibilityState,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
getFacetedUniqueValues,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import {
|
||||
Activity,
|
||||
AlertCircle,
|
||||
AlertTriangle,
|
||||
Bug,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
ChevronFirst,
|
||||
ChevronLast,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
ChevronUp,
|
||||
CircleAlert,
|
||||
CircleX,
|
||||
Clock,
|
||||
Columns3,
|
||||
Filter,
|
||||
Info,
|
||||
ListFilter,
|
||||
MoreHorizontal,
|
||||
RefreshCw,
|
||||
Terminal,
|
||||
Trash,
|
||||
X,
|
||||
Zap,
|
||||
} from "lucide-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import React, { useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// Define animation variants for reuse
|
||||
const fadeInScale = {
|
||||
const fadeInScale: Variants = {
|
||||
hidden: { opacity: 0, scale: 0.95 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
|
@ -324,13 +324,13 @@ export default function LogsManagePage() {
|
|||
const levelColumn = table.getColumn("level");
|
||||
if (!levelColumn) return [];
|
||||
return Array.from(levelColumn.getFacetedUniqueValues().keys()).sort();
|
||||
}, [table.getColumn("level")?.getFacetedUniqueValues()]);
|
||||
}, [table.getColumn]);
|
||||
|
||||
const uniqueStatuses = useMemo(() => {
|
||||
const statusColumn = table.getColumn("status");
|
||||
if (!statusColumn) return [];
|
||||
return Array.from(statusColumn.getFacetedUniqueValues().keys()).sort();
|
||||
}, [table.getColumn("status")?.getFacetedUniqueValues()]);
|
||||
}, [table.getColumn]);
|
||||
|
||||
const handleDeleteRows = async () => {
|
||||
const selectedRows = table.getSelectedRowModel().rows;
|
||||
|
@ -631,15 +631,17 @@ function LogsFilters({
|
|||
<ListFilter size={16} strokeWidth={2} />
|
||||
</div>
|
||||
{Boolean(table.getColumn("message")?.getFilterValue()) && (
|
||||
<button
|
||||
<Button
|
||||
className="absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-lg text-muted-foreground/80 hover:text-foreground"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => {
|
||||
table.getColumn("message")?.setFilterValue("");
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
<CircleX size={16} strokeWidth={2} />
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
</motion.div>
|
||||
|
||||
|
@ -705,7 +707,7 @@ function FilterDropdown({
|
|||
const selectedValues = useMemo(() => {
|
||||
const filterValue = column?.getFilterValue() as string[];
|
||||
return filterValue ?? [];
|
||||
}, [column?.getFilterValue()]);
|
||||
}, [column?.getFilterValue]);
|
||||
|
||||
const handleValueChange = (checked: boolean, value: string) => {
|
||||
const filterValue = column?.getFilterValue() as string[];
|
||||
|
@ -848,7 +850,9 @@ function LogsTable({
|
|||
className="h-12 px-4 py-3"
|
||||
>
|
||||
{header.isPlaceholder ? null : header.column.getCanSort() ? (
|
||||
<div
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={cn(
|
||||
"flex h-full cursor-pointer select-none items-center justify-between gap-2"
|
||||
)}
|
||||
|
@ -859,7 +863,7 @@ function LogsTable({
|
|||
asc: <ChevronUp className="shrink-0 opacity-60" size={16} />,
|
||||
desc: <ChevronDown className="shrink-0 opacity-60" size={16} />,
|
||||
}[header.column.getIsSorted() as string] ?? null}
|
||||
</div>
|
||||
</Button>
|
||||
) : (
|
||||
flexRender(header.column.columnDef.header, header.getContext())
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { format } from "date-fns";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
||||
import {
|
||||
Calendar,
|
||||
MoreHorizontal,
|
||||
|
@ -16,8 +16,9 @@ import {
|
|||
VolumeX,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import { toast } from "sonner";
|
||||
// UI Components
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
|
@ -45,7 +46,6 @@ import {
|
|||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Slider } from "@/components/ui/slider";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface PodcastItem {
|
||||
id: number;
|
||||
|
@ -60,7 +60,7 @@ interface PodcastsPageClientProps {
|
|||
searchSpaceId: string;
|
||||
}
|
||||
|
||||
const pageVariants = {
|
||||
const pageVariants: Variants = {
|
||||
initial: { opacity: 0 },
|
||||
enter: {
|
||||
opacity: 1,
|
||||
|
@ -69,7 +69,7 @@ const pageVariants = {
|
|||
exit: { opacity: 0, transition: { duration: 0.3, ease: "easeInOut" } },
|
||||
};
|
||||
|
||||
const podcastCardVariants = {
|
||||
const podcastCardVariants: Variants = {
|
||||
initial: { scale: 0.95, y: 20, opacity: 0 },
|
||||
animate: {
|
||||
scale: 1,
|
||||
|
@ -162,7 +162,7 @@ export default function PodcastsPageClient({ searchSpaceId }: PodcastsPageClient
|
|||
};
|
||||
|
||||
fetchPodcasts();
|
||||
}, [searchSpaceId]);
|
||||
}, []);
|
||||
|
||||
// Filter and sort podcasts based on search query and sort order
|
||||
useEffect(() => {
|
||||
|
@ -540,11 +540,13 @@ export default function PodcastsPageClient({ searchSpaceId }: PodcastsPageClient
|
|||
>
|
||||
<div className="relative w-full aspect-[16/10] mb-4 rounded-lg overflow-hidden">
|
||||
{/* Podcast image with gradient overlay */}
|
||||
<img
|
||||
<Image
|
||||
src={PODCAST_IMAGE_URL}
|
||||
alt="Podcast illustration"
|
||||
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105 brightness-[0.85] contrast-[1.1]"
|
||||
loading="lazy"
|
||||
width={100}
|
||||
height={100}
|
||||
/>
|
||||
|
||||
{/* Better overlay with gradient for improved text legibility */}
|
||||
|
@ -675,7 +677,8 @@ export default function PodcastsPageClient({ searchSpaceId }: PodcastsPageClient
|
|||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
<div
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="h-1.5 bg-muted rounded-full cursor-pointer group relative overflow-hidden"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
@ -702,7 +705,7 @@ export default function PodcastsPageClient({ searchSpaceId }: PodcastsPageClient
|
|||
whileHover={{ scale: 1.5 }}
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</Button>
|
||||
<div className="flex justify-between mt-1.5 text-xs text-muted-foreground">
|
||||
<span>{formatTime(currentTime)}</span>
|
||||
<span>{formatTime(duration)}</span>
|
||||
|
@ -1024,7 +1027,9 @@ export default function PodcastsPageClient({ searchSpaceId }: PodcastsPageClient
|
|||
// Reset playing state on error
|
||||
setIsPlaying(false);
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<track kind="captions" />
|
||||
</audio>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -229,14 +229,14 @@ export function DocumentsDataTable({
|
|||
if (hasChanges && Object.keys(initialRowSelection).length > 0) {
|
||||
setRowSelection(initialRowSelection);
|
||||
}
|
||||
}, [initialRowSelection, rowSelection]);
|
||||
}, [initialRowSelection]);
|
||||
|
||||
// Initialize row selection on mount
|
||||
useEffect(() => {
|
||||
if (Object.keys(rowSelection).length === 0 && Object.keys(initialRowSelection).length > 0) {
|
||||
setRowSelection(initialRowSelection);
|
||||
}
|
||||
}, [initialRowSelection, rowSelection]);
|
||||
}, []);
|
||||
|
||||
const filteredDocuments = useMemo(() => {
|
||||
if (documentTypeFilter === "ALL") return documents;
|
||||
|
@ -263,7 +263,7 @@ export function DocumentsDataTable({
|
|||
const selectedRows = table.getFilteredSelectedRowModel().rows;
|
||||
const selectedDocuments = selectedRows.map((row) => row.original);
|
||||
onSelectionChange(selectedDocuments);
|
||||
}, [onSelectionChange, table]);
|
||||
}, [rowSelection, onSelectionChange, table]);
|
||||
|
||||
const handleClearAll = () => setRowSelection({});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue