chore: ran linting

This commit is contained in:
Anish Sarkar 2026-03-10 16:17:12 +05:30
parent ad7bbcbc8f
commit 6a88f9e0eb
18 changed files with 478 additions and 472 deletions

View file

@ -9,7 +9,14 @@ import { useEffect } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -108,37 +115,26 @@ export default function MorePagesPage() {
<div <div
className={cn( className={cn(
"flex h-9 w-9 shrink-0 items-center justify-center rounded-full", "flex h-9 w-9 shrink-0 items-center justify-center rounded-full",
task.completed task.completed ? "bg-primary text-primary-foreground" : "bg-muted"
? "bg-primary text-primary-foreground"
: "bg-muted"
)} )}
> >
{task.completed ? ( {task.completed ? <Check className="h-4 w-4" /> : <Star className="h-4 w-4" />}
<Check className="h-4 w-4" />
) : (
<Star className="h-4 w-4" />
)}
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<p <p
className={cn( className={cn(
"text-sm font-medium", "text-sm font-medium",
task.completed && task.completed && "text-muted-foreground line-through"
"text-muted-foreground line-through"
)} )}
> >
{task.title} {task.title}
</p> </p>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">+{task.pages_reward} pages</p>
+{task.pages_reward} pages
</p>
</div> </div>
<Button <Button
variant={task.completed ? "ghost" : "outline"} variant={task.completed ? "ghost" : "outline"}
size="sm" size="sm"
disabled={ disabled={task.completed || completeMutation.isPending}
task.completed || completeMutation.isPending
}
onClick={() => handleTaskClick(task)} onClick={() => handleTaskClick(task)}
asChild={!task.completed} asChild={!task.completed}
> >
@ -181,8 +177,9 @@ export default function MorePagesPage() {
</Badge> </Badge>
</div> </div>
<CardDescription> <CardDescription>
For a limited time, get <span className="font-semibold text-foreground">6,000 additional pages</span> at For a limited time, get{" "}
no cost. Contact us and we&apos;ll upgrade your account instantly. <span className="font-semibold text-foreground">6,000 additional pages</span> at no
cost. Contact us and we&apos;ll upgrade your account instantly.
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardFooter className="pt-2"> <CardFooter className="pt-2">
@ -196,9 +193,7 @@ export default function MorePagesPage() {
<DialogContent className="select-none sm:max-w-sm"> <DialogContent className="select-none sm:max-w-sm">
<DialogHeader> <DialogHeader>
<DialogTitle>Get in Touch</DialogTitle> <DialogTitle>Get in Touch</DialogTitle>
<DialogDescription> <DialogDescription>Pick the option that works best for you.</DialogDescription>
Pick the option that works best for you.
</DialogDescription>
</DialogHeader> </DialogHeader>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Button asChild> <Button asChild>

View file

@ -1,16 +1,10 @@
import Image from "next/image";
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
import Image from "next/image";
export const baseOptions: BaseLayoutProps = { export const baseOptions: BaseLayoutProps = {
nav: { nav: {
title: ( title: (
<> <>
<Image <Image src="/icon-128.svg" alt="SurfSense" width={24} height={24} className="dark:invert" />
src="/icon-128.svg"
alt="SurfSense"
width={24}
height={24}
className="dark:invert"
/>
SurfSense Docs SurfSense Docs
</> </>
), ),

View file

@ -10,10 +10,7 @@ import { useAtomValue } from "jotai";
import { CheckIcon, CopyIcon, DownloadIcon, MessageSquare, RefreshCwIcon } from "lucide-react"; import { CheckIcon, CopyIcon, DownloadIcon, MessageSquare, RefreshCwIcon } from "lucide-react";
import type { FC } from "react"; import type { FC } from "react";
import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { useContext, useEffect, useMemo, useRef, useState } from "react";
import { import { commentsEnabledAtom, targetCommentIdAtom } from "@/atoms/chat/current-thread.atom";
commentsEnabledAtom,
targetCommentIdAtom,
} from "@/atoms/chat/current-thread.atom";
import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms";
import { MarkdownText } from "@/components/assistant-ui/markdown-text"; import { MarkdownText } from "@/components/assistant-ui/markdown-text";
import { import {
@ -139,7 +136,8 @@ export const AssistantMessage: FC = () => {
commentPanelRef.current?.contains(target) || commentPanelRef.current?.contains(target) ||
commentTriggerRef.current?.contains(target) || commentTriggerRef.current?.contains(target) ||
target.closest?.("[data-radix-popper-content-wrapper]") target.closest?.("[data-radix-popper-content-wrapper]")
) return; )
return;
setIsInlineOpen(false); setIsInlineOpen(false);
}; };
document.addEventListener("mousedown", handleClickOutside); document.addEventListener("mousedown", handleClickOutside);
@ -178,7 +176,9 @@ export const AssistantMessage: FC = () => {
<button <button
ref={isDesktop ? commentTriggerRef : undefined} ref={isDesktop ? commentTriggerRef : undefined}
type="button" type="button"
onClick={isDesktop ? () => setIsInlineOpen((prev) => !prev) : () => setIsSheetOpen(true)} onClick={
isDesktop ? () => setIsInlineOpen((prev) => !prev) : () => setIsSheetOpen(true)
}
className={cn( className={cn(
"flex items-center gap-1.5 rounded-full px-3 py-1 text-sm transition-colors", "flex items-center gap-1.5 rounded-full px-3 py-1 text-sm transition-colors",
isDesktop && isInlineOpen isDesktop && isInlineOpen
@ -206,11 +206,7 @@ export const AssistantMessage: FC = () => {
ref={commentPanelRef} ref={commentPanelRef}
className="absolute right-0 top-10 z-30 w-full max-w-md animate-in fade-in slide-in-from-top-2 duration-200" className="absolute right-0 top-10 z-30 w-full max-w-md animate-in fade-in slide-in-from-top-2 duration-200"
> >
<CommentPanelContainer <CommentPanelContainer messageId={dbMessageId} isOpen={true} variant="inline" />
messageId={dbMessageId}
isOpen={true}
variant="inline"
/>
</div> </div>
)} )}

View file

@ -6,6 +6,7 @@ import Link from "next/link";
import { useSearchParams } from "next/navigation"; import { useSearchParams } from "next/navigation";
import { type FC, forwardRef, useImperativeHandle, useMemo } from "react"; import { type FC, forwardRef, useImperativeHandle, useMemo } from "react";
import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms"; import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms";
import { statusInboxItemsAtom } from "@/atoms/inbox/status-inbox.atom";
import { import {
globalNewLLMConfigsAtom, globalNewLLMConfigsAtom,
llmPreferencesAtom, llmPreferencesAtom,
@ -19,7 +20,6 @@ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import { Tabs, TabsContent } from "@/components/ui/tabs"; import { Tabs, TabsContent } from "@/components/ui/tabs";
import type { SearchSourceConnector } from "@/contracts/types/connector.types"; import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import { statusInboxItemsAtom } from "@/atoms/inbox/status-inbox.atom";
import { useConnectorsElectric } from "@/hooks/use-connectors-electric"; import { useConnectorsElectric } from "@/hooks/use-connectors-electric";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { ConnectorDialogHeader } from "./connector-popup/components/connector-dialog-header"; import { ConnectorDialogHeader } from "./connector-popup/components/connector-dialog-header";
@ -206,7 +206,9 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
{showTrigger && ( {showTrigger && (
<TooltipIconButton <TooltipIconButton
data-joyride="connector-icon" data-joyride="connector-icon"
tooltip={hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"} tooltip={
hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"
}
side="bottom" side="bottom"
className={cn( className={cn(
"size-[34px] rounded-full p-1 flex items-center justify-center transition-colors relative", "size-[34px] rounded-full p-1 flex items-center justify-center transition-colors relative",
@ -215,7 +217,9 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
"border-0 ring-0 focus:ring-0 shadow-none focus:shadow-none" "border-0 ring-0 focus:ring-0 shadow-none focus:shadow-none"
)} )}
aria-label={ aria-label={
hasConnectors ? `View ${activeConnectorsCount} connectors` : "Add your first connector" hasConnectors
? `View ${activeConnectorsCount} connectors`
: "Add your first connector"
} }
onClick={() => handleOpenChange(true)} onClick={() => handleOpenChange(true)}
> >
@ -411,7 +415,9 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
indexingConnectorIds={indexingConnectorIds} indexingConnectorIds={indexingConnectorIds}
onConnectOAuth={hasDocumentSummaryLLM ? handleConnectOAuth : () => {}} onConnectOAuth={hasDocumentSummaryLLM ? handleConnectOAuth : () => {}}
onConnectNonOAuth={hasDocumentSummaryLLM ? handleConnectNonOAuth : () => {}} onConnectNonOAuth={hasDocumentSummaryLLM ? handleConnectNonOAuth : () => {}}
onCreateWebcrawler={hasDocumentSummaryLLM ? handleCreateWebcrawler : () => {}} onCreateWebcrawler={
hasDocumentSummaryLLM ? handleCreateWebcrawler : () => {}
}
onCreateYouTubeCrawler={ onCreateYouTubeCrawler={
hasDocumentSummaryLLM ? handleCreateYouTubeCrawler : () => {} hasDocumentSummaryLLM ? handleCreateYouTubeCrawler : () => {}
} }
@ -441,6 +447,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );
}); }
);
ConnectorIndicator.displayName = "ConnectorIndicator"; ConnectorIndicator.displayName = "ConnectorIndicator";

View file

@ -63,7 +63,8 @@ export const WebcrawlerConfig: FC<ConnectorConfigProps> = ({ connector, onConfig
<div className="flex items-start gap-3 rounded-lg border border-blue-200/50 bg-blue-50/50 dark:border-blue-500/20 dark:bg-blue-950/20 p-3 text-xs sm:text-sm"> <div className="flex items-start gap-3 rounded-lg border border-blue-200/50 bg-blue-50/50 dark:border-blue-500/20 dark:bg-blue-950/20 p-3 text-xs sm:text-sm">
<Info className="size-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400" /> <Info className="size-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400" />
<p className="text-muted-foreground"> <p className="text-muted-foreground">
Want a quick answer from a webpage without indexing it? Just paste the URL directly into the chat instead. Want a quick answer from a webpage without indexing it? Just paste the URL directly into
the chat instead.
</p> </p>
</div> </div>

View file

@ -280,9 +280,7 @@ export const YouTubeCrawlerView: FC<YouTubeCrawlerViewProps> = ({ searchSpaceId,
<div className="flex items-start gap-3 rounded-lg border border-blue-200/50 bg-blue-50/50 dark:border-blue-500/20 dark:bg-blue-950/20 p-4 text-sm"> <div className="flex items-start gap-3 rounded-lg border border-blue-200/50 bg-blue-50/50 dark:border-blue-500/20 dark:bg-blue-950/20 p-4 text-sm">
<Info className="size-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400" /> <Info className="size-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400" />
<p className="text-muted-foreground"> <p className="text-muted-foreground">{t("chat_tip")}</p>
{t("chat_tip")}
</p>
</div> </div>
<div className="bg-muted/50 rounded-lg p-4 text-sm"> <div className="bg-muted/50 rounded-lg p-4 text-sm">

View file

@ -14,7 +14,6 @@ import {
AlertCircle, AlertCircle,
ArrowDownIcon, ArrowDownIcon,
ArrowUpIcon, ArrowUpIcon,
Unplug,
CheckIcon, CheckIcon,
ChevronLeftIcon, ChevronLeftIcon,
ChevronRightIcon, ChevronRightIcon,
@ -24,6 +23,7 @@ import {
RefreshCwIcon, RefreshCwIcon,
SquareIcon, SquareIcon,
SquareLibrary, SquareLibrary,
Unplug,
Upload, Upload,
X, X,
} from "lucide-react"; } from "lucide-react";
@ -47,12 +47,12 @@ import {
} from "@/atoms/new-llm-config/new-llm-config-query.atoms"; } from "@/atoms/new-llm-config/new-llm-config-query.atoms";
import { currentUserAtom } from "@/atoms/user/user-query.atoms"; import { currentUserAtom } from "@/atoms/user/user-query.atoms";
import { AssistantMessage } from "@/components/assistant-ui/assistant-message"; import { AssistantMessage } from "@/components/assistant-ui/assistant-message";
import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup";
import { ChatSessionStatus } from "@/components/assistant-ui/chat-session-status"; import { ChatSessionStatus } from "@/components/assistant-ui/chat-session-status";
import { import {
ConnectorIndicator, ConnectorIndicator,
type ConnectorIndicatorHandle, type ConnectorIndicatorHandle,
} from "@/components/assistant-ui/connector-popup"; } from "@/components/assistant-ui/connector-popup";
import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup";
import { import {
InlineMentionEditor, InlineMentionEditor,
type InlineMentionEditorRef, type InlineMentionEditorRef,
@ -65,6 +65,7 @@ import {
import { ToolFallback } from "@/components/assistant-ui/tool-fallback"; import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button"; import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
import { UserMessage } from "@/components/assistant-ui/user-message"; import { UserMessage } from "@/components/assistant-ui/user-message";
import { SLIDEOUT_PANEL_OPENED_EVENT } from "@/components/layout/ui/sidebar/SidebarSlideOutPanel";
import { import {
DocumentMentionPicker, DocumentMentionPicker,
type DocumentMentionPickerRef, type DocumentMentionPickerRef,
@ -83,7 +84,6 @@ import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import type { Document } from "@/contracts/types/document.types"; import type { Document } from "@/contracts/types/document.types";
import { useBatchCommentsPreload } from "@/hooks/use-comments"; import { useBatchCommentsPreload } from "@/hooks/use-comments";
import { useCommentsElectric } from "@/hooks/use-comments-electric"; import { useCommentsElectric } from "@/hooks/use-comments-electric";
import { SLIDEOUT_PANEL_OPENED_EVENT } from "@/components/layout/ui/sidebar/SidebarSlideOutPanel";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
/** Placeholder texts that cycle in new chats when input is empty */ /** Placeholder texts that cycle in new chats when input is empty */
@ -273,16 +273,10 @@ const ConnectToolsBanner: FC = () => {
onClick={() => setConnectorDialogOpen(true)} onClick={() => setConnectorDialogOpen(true)}
> >
<Unplug className="size-4 text-muted-foreground/70 shrink-0" /> <Unplug className="size-4 text-muted-foreground/70 shrink-0" />
<span className="text-[13px] text-muted-foreground/80 flex-1"> <span className="text-[13px] text-muted-foreground/80 flex-1">Connect your tools</span>
Connect your tools
</span>
<AvatarGroup className="shrink-0"> <AvatarGroup className="shrink-0">
{BANNER_CONNECTORS.map(({ type, label }, i) => ( {BANNER_CONNECTORS.map(({ type, label }, i) => (
<Avatar <Avatar key={type} className="size-6" style={{ zIndex: BANNER_CONNECTORS.length - i }}>
key={type}
className="size-6"
style={{ zIndex: BANNER_CONNECTORS.length - i }}
>
<AvatarFallback className="bg-muted text-[10px]"> <AvatarFallback className="bg-muted text-[10px]">
{getConnectorIcon(type, "size-3.5")} {getConnectorIcon(type, "size-3.5")}
</AvatarFallback> </AvatarFallback>
@ -658,9 +652,7 @@ const ComposerAction: FC<ComposerActionProps> = ({ isBlockedByOtherUser = false
<Unplug className="size-4 shrink-0" /> <Unplug className="size-4 shrink-0" />
{connectorCount > 0 ? "Manage connectors" : "Connect your tools"} {connectorCount > 0 ? "Manage connectors" : "Connect your tools"}
{connectorCount > 0 && ( {connectorCount > 0 && (
<span className="ml-auto text-xs text-muted-foreground"> <span className="ml-auto text-xs text-muted-foreground">{connectorCount}</span>
{connectorCount}
</span>
)} )}
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
@ -685,7 +677,6 @@ const ComposerAction: FC<ComposerActionProps> = ({ isBlockedByOtherUser = false
)} )}
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<AssistantIf condition={({ thread }) => !thread.isRunning}> <AssistantIf condition={({ thread }) => !thread.isRunning}>
<ComposerPrimitive.Send asChild disabled={isSendDisabled}> <ComposerPrimitive.Send asChild disabled={isSendDisabled}>
<TooltipIconButton <TooltipIconButton

View file

@ -73,7 +73,9 @@ export function CommentPanel({
isInline && "w-full rounded-xl border bg-card shadow-lg max-h-80", isInline && "w-full rounded-xl border bg-card shadow-lg max-h-80",
!isMobile && !isInline && "w-85 rounded-lg border bg-card" !isMobile && !isInline && "w-85 rounded-lg border bg-card"
)} )}
style={!isMobile && !isInline && effectiveMaxHeight ? { maxHeight: effectiveMaxHeight } : undefined} style={
!isMobile && !isInline && effectiveMaxHeight ? { maxHeight: effectiveMaxHeight } : undefined
}
> >
{hasThreads && ( {hasThreads && (
<div className={cn("min-h-0 flex-1 overflow-y-auto scrollbar-thin", isMobile && "pb-24")}> <div className={cn("min-h-0 flex-1 overflow-y-auto scrollbar-thin", isMobile && "pb-24")}>

View file

@ -176,7 +176,6 @@ function GetStartedButton() {
); );
} }
const BackgroundGrids = () => { const BackgroundGrids = () => {
return ( return (
<div className="pointer-events-none absolute inset-0 z-0 grid h-screen w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4"> <div className="pointer-events-none absolute inset-0 z-0 grid h-screen w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4">

View file

@ -1,12 +1,6 @@
"use client"; "use client";
import { import { ArchiveIcon, MoreHorizontal, PenLine, RotateCcwIcon, Trash2 } from "lucide-react";
ArchiveIcon,
MoreHorizontal,
PenLine,
RotateCcwIcon,
Trash2,
} from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";

View file

@ -14,8 +14,8 @@ import {
import { sidebarSelectedDocumentsAtom } from "@/atoms/chat/mentioned-documents.atom"; import { sidebarSelectedDocumentsAtom } from "@/atoms/chat/mentioned-documents.atom";
import { connectorDialogOpenAtom } from "@/atoms/connector-dialog/connector-dialog.atoms"; import { connectorDialogOpenAtom } from "@/atoms/connector-dialog/connector-dialog.atoms";
import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarFallback, AvatarGroup } from "@/components/ui/avatar"; import { Avatar, AvatarFallback, AvatarGroup } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import type { DocumentTypeEnum } from "@/contracts/types/document.types"; import type { DocumentTypeEnum } from "@/contracts/types/document.types";
@ -40,7 +40,12 @@ interface DocumentsSidebarProps {
onDockedChange?: (docked: boolean) => void; onDockedChange?: (docked: boolean) => void;
} }
export function DocumentsSidebar({ open, onOpenChange, isDocked = false, onDockedChange }: DocumentsSidebarProps) { export function DocumentsSidebar({
open,
onOpenChange,
isDocked = false,
onDockedChange,
}: DocumentsSidebarProps) {
const t = useTranslations("documents"); const t = useTranslations("documents");
const tSidebar = useTranslations("sidebar"); const tSidebar = useTranslations("sidebar");
const params = useParams(); const params = useParams();
@ -221,17 +226,12 @@ export function DocumentsSidebar({ open, onOpenChange, isDocked = false, onDocke
className="flex items-center gap-2 min-w-0 flex-1 text-left" className="flex items-center gap-2 min-w-0 flex-1 text-left"
> >
<Unplug className="size-4 shrink-0 text-muted-foreground" /> <Unplug className="size-4 shrink-0 text-muted-foreground" />
<span className="truncate text-xs text-muted-foreground"> <span className="truncate text-xs text-muted-foreground">Connect your tools</span>
Connect your tools
</span>
<AvatarGroup className="ml-auto shrink-0"> <AvatarGroup className="ml-auto shrink-0">
{SHOWCASE_CONNECTORS.map(({ type, label }, i) => ( {SHOWCASE_CONNECTORS.map(({ type, label }, i) => (
<Tooltip key={type}> <Tooltip key={type}>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<Avatar <Avatar className="size-6" style={{ zIndex: SHOWCASE_CONNECTORS.length - i }}>
className="size-6"
style={{ zIndex: SHOWCASE_CONNECTORS.length - i }}
>
<AvatarFallback className="bg-muted text-[10px]"> <AvatarFallback className="bg-muted text-[10px]">
{getConnectorIcon(type, "size-3.5")} {getConnectorIcon(type, "size-3.5")}
</AvatarFallback> </AvatarFallback>

View file

@ -352,27 +352,51 @@ function ReportPanelContent({
> >
{!shareToken && ( {!shareToken && (
<> <>
<DropdownMenuLabel className="text-xs text-muted-foreground">Documents</DropdownMenuLabel> <DropdownMenuLabel className="text-xs text-muted-foreground">
<DropdownMenuItem onClick={() => handleExport("pdf")} disabled={exporting !== null}> Documents
</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => handleExport("pdf")}
disabled={exporting !== null}
>
PDF (.pdf) PDF (.pdf)
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport("docx")} disabled={exporting !== null}> <DropdownMenuItem
onClick={() => handleExport("docx")}
disabled={exporting !== null}
>
Word (.docx) Word (.docx)
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport("odt")} disabled={exporting !== null}> <DropdownMenuItem
onClick={() => handleExport("odt")}
disabled={exporting !== null}
>
OpenDocument (.odt) OpenDocument (.odt)
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuLabel className="text-xs text-muted-foreground">Web &amp; E-Book</DropdownMenuLabel> <DropdownMenuLabel className="text-xs text-muted-foreground">
<DropdownMenuItem onClick={() => handleExport("html")} disabled={exporting !== null}> Web &amp; E-Book
</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => handleExport("html")}
disabled={exporting !== null}
>
HTML (.html) HTML (.html)
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport("epub")} disabled={exporting !== null}> <DropdownMenuItem
onClick={() => handleExport("epub")}
disabled={exporting !== null}
>
EPUB (.epub) EPUB (.epub)
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuLabel className="text-xs text-muted-foreground">Source &amp; Plain</DropdownMenuLabel> <DropdownMenuLabel className="text-xs text-muted-foreground">
<DropdownMenuItem onClick={() => handleExport("latex")} disabled={exporting !== null}> Source &amp; Plain
</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => handleExport("latex")}
disabled={exporting !== null}
>
LaTeX (.tex) LaTeX (.tex)
</DropdownMenuItem> </DropdownMenuItem>
</> </>
@ -381,7 +405,10 @@ function ReportPanelContent({
Markdown (.md) Markdown (.md)
</DropdownMenuItem> </DropdownMenuItem>
{!shareToken && ( {!shareToken && (
<DropdownMenuItem onClick={() => handleExport("plain")} disabled={exporting !== null}> <DropdownMenuItem
onClick={() => handleExport("plain")}
disabled={exporting !== null}
>
Plain Text (.txt) Plain Text (.txt)
</DropdownMenuItem> </DropdownMenuItem>
)} )}

View file

@ -700,7 +700,12 @@ function PermissionsEditor({
tabIndex={0} tabIndex={0}
className="w-full flex items-center justify-between px-3 py-2.5 cursor-pointer hover:bg-muted/40 transition-colors" className="w-full flex items-center justify-between px-3 py-2.5 cursor-pointer hover:bg-muted/40 transition-colors"
onClick={() => toggleCategoryExpanded(category)} onClick={() => toggleCategoryExpanded(category)}
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggleCategoryExpanded(category); } }} onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
toggleCategoryExpanded(category);
}
}}
> >
<div className="flex items-center gap-2.5"> <div className="flex items-center gap-2.5">
<IconComponent className="h-4 w-4 text-muted-foreground shrink-0" /> <IconComponent className="h-4 w-4 text-muted-foreground shrink-0" />
@ -763,7 +768,12 @@ function PermissionsEditor({
isSelected ? "bg-muted/60 hover:bg-muted/80" : "hover:bg-muted/40" isSelected ? "bg-muted/60 hover:bg-muted/80" : "hover:bg-muted/40"
)} )}
onClick={() => onTogglePermission(perm.value)} onClick={() => onTogglePermission(perm.value)}
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onTogglePermission(perm.value); } }} onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
onTogglePermission(perm.value);
}
}}
> >
<div className="flex-1 min-w-0 text-left"> <div className="flex-1 min-w-0 text-left">
<span className="text-sm font-medium">{actionLabel}</span> <span className="text-sm font-medium">{actionLabel}</span>

View file

@ -39,13 +39,7 @@ function AvatarFallback({
} }
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) { function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
return ( return <div data-slot="avatar-group" className={cn("flex -space-x-2", className)} {...props} />;
<div
data-slot="avatar-group"
className={cn("flex -space-x-2", className)}
{...props}
/>
);
} }
function AvatarGroupCount({ className, ...props }: React.ComponentProps<"span">) { function AvatarGroupCount({ className, ...props }: React.ComponentProps<"span">) {

View file

@ -1,7 +1,7 @@
"use client"; "use client";
import { AnimatePresence, motion } from "motion/react";
import { ChevronLeft, ChevronRight } from "lucide-react"; import { ChevronLeft, ChevronRight } from "lucide-react";
import { AnimatePresence, motion } from "motion/react";
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { ExpandedGifOverlay, useExpandedGif } from "@/components/ui/expanded-gif-overlay"; import { ExpandedGifOverlay, useExpandedGif } from "@/components/ui/expanded-gif-overlay";

View file

@ -59,7 +59,7 @@ export function useInbox(
searchSpaceId: number | null, searchSpaceId: number | null,
category: NotificationCategory, category: NotificationCategory,
prefetchedUnread?: { total_unread: number; recent_unread: number } | null, prefetchedUnread?: { total_unread: number; recent_unread: number } | null,
prefetchedUnreadReady = true, prefetchedUnreadReady = true
) { ) {
const electricClient = useElectricClient(); const electricClient = useElectricClient();

View file

@ -156,9 +156,7 @@ class NotificationsApiService {
* Get unread counts for all categories in a single request. * Get unread counts for all categories in a single request.
* Replaces 2 separate getUnreadCount calls (comments + status). * Replaces 2 separate getUnreadCount calls (comments + status).
*/ */
getBatchUnreadCounts = async ( getBatchUnreadCounts = async (searchSpaceId?: number): Promise<GetBatchUnreadCountResponse> => {
searchSpaceId?: number
): Promise<GetBatchUnreadCountResponse> => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (searchSpaceId !== undefined) { if (searchSpaceId !== undefined) {
params.append("search_space_id", String(searchSpaceId)); params.append("search_space_id", String(searchSpaceId));