chore: linting

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-01-12 14:17:15 -08:00
parent 11915df97b
commit 73a57589ac
25 changed files with 184 additions and 181 deletions

View file

@ -7,7 +7,6 @@ Revises: 59
from collections.abc import Sequence from collections.abc import Sequence
from alembic import op from alembic import op
from app.config import config from app.config import config
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
@ -162,4 +161,3 @@ def downgrade() -> None:
# Drop tables (chunks first due to FK) # Drop tables (chunks first due to FK)
op.execute("DROP TABLE IF EXISTS surfsense_docs_chunks") op.execute("DROP TABLE IF EXISTS surfsense_docs_chunks")
op.execute("DROP TABLE IF EXISTS surfsense_docs_documents") op.execute("DROP TABLE IF EXISTS surfsense_docs_documents")

View file

@ -48,10 +48,12 @@ def format_surfsense_docs_results(results: list[tuple]) -> str:
"metadata": {"source": doc.source}, "metadata": {"source": doc.source},
"chunks": [], "chunks": [],
} }
grouped[doc.id]["chunks"].append({ grouped[doc.id]["chunks"].append(
{
"chunk_id": f"doc-{chunk.id}", "chunk_id": f"doc-{chunk.id}",
"content": chunk.content, "content": chunk.content,
}) }
)
# Render XML matching format_documents_for_context structure # Render XML matching format_documents_for_context structure
parts: list[str] = [] parts: list[str] = []
@ -70,7 +72,9 @@ def format_surfsense_docs_results(results: list[tuple]) -> str:
parts.append("<document_content>") parts.append("<document_content>")
for ch in g["chunks"]: for ch in g["chunks"]:
parts.append(f" <chunk id='{ch['chunk_id']}'><![CDATA[{ch['content']}]]></chunk>") parts.append(
f" <chunk id='{ch['chunk_id']}'><![CDATA[{ch['content']}]]></chunk>"
)
parts.append("</document_content>") parts.append("</document_content>")
parts.append("</document>") parts.append("</document>")
@ -157,4 +161,3 @@ def create_search_surfsense_docs_tool(db_session: AsyncSession):
) )
return search_surfsense_docs return search_surfsense_docs

View file

@ -436,7 +436,9 @@ class SurfsenseDocsDocument(BaseModel, TimestampMixin):
__tablename__ = "surfsense_docs_documents" __tablename__ = "surfsense_docs_documents"
source = Column(String, nullable=False, unique=True, index=True) # File path: "connectors/slack.mdx" source = Column(
String, nullable=False, unique=True, index=True
) # File path: "connectors/slack.mdx"
title = Column(String, nullable=False) title = Column(String, nullable=False)
content = Column(Text, nullable=False) content = Column(Text, nullable=False)
content_hash = Column(String, nullable=False, index=True) # For detecting changes content_hash = Column(String, nullable=False, index=True) # For detecting changes

View file

@ -623,10 +623,7 @@ async def index_connector_content(
SearchSourceConnectorType.LUMA_CONNECTOR, SearchSourceConnectorType.LUMA_CONNECTOR,
]: ]:
# Default to today if no end_date provided (users can manually select future dates) # Default to today if no end_date provided (users can manually select future dates)
if end_date is None: indexing_to = today_str if end_date is None else end_date
indexing_to = today_str
else:
indexing_to = end_date
else: else:
# For non-calendar connectors, cap at today # For non-calendar connectors, cap at today
indexing_to = end_date if end_date else today_str indexing_to = end_date if end_date else today_str

View file

@ -24,4 +24,3 @@ class SurfsenseDocsDocumentWithChunksRead(BaseModel):
chunks: list[SurfsenseDocsChunkRead] chunks: list[SurfsenseDocsChunkRead]
model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)

View file

@ -19,7 +19,12 @@ from app.db import SurfsenseDocsChunk, SurfsenseDocsDocument, async_session_make
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Path to docs relative to project root # Path to docs relative to project root
DOCS_DIR = Path(__file__).resolve().parent.parent.parent.parent / "surfsense_web" / "content" / "docs" DOCS_DIR = (
Path(__file__).resolve().parent.parent.parent.parent
/ "surfsense_web"
/ "content"
/ "docs"
)
def parse_mdx_frontmatter(content: str) -> tuple[str, str]: def parse_mdx_frontmatter(content: str) -> tuple[str, str]:
@ -38,7 +43,7 @@ def parse_mdx_frontmatter(content: str) -> tuple[str, str]:
if match: if match:
frontmatter = match.group(1) frontmatter = match.group(1)
content_without_frontmatter = content[match.end():] content_without_frontmatter = content[match.end() :]
# Extract title from frontmatter # Extract title from frontmatter
title_match = re.search(r"^title:\s*(.+)$", frontmatter, re.MULTILINE) title_match = re.search(r"^title:\s*(.+)$", frontmatter, re.MULTILINE)
@ -107,7 +112,9 @@ async def index_surfsense_docs(session: AsyncSession) -> tuple[int, int, int, in
# Get all existing docs from database # Get all existing docs from database
existing_docs_result = await session.execute( existing_docs_result = await session.execute(
select(SurfsenseDocsDocument).options(selectinload(SurfsenseDocsDocument.chunks)) select(SurfsenseDocsDocument).options(
selectinload(SurfsenseDocsDocument.chunks)
)
) )
existing_docs = {doc.source: doc for doc in existing_docs_result.scalars().all()} existing_docs = {doc.source: doc for doc in existing_docs_result.scalars().all()}

View file

@ -105,9 +105,7 @@ function EmptyState({ onCreateClick }: { onCreateClick: () => void }) {
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<h1 className="text-2xl font-bold">{t("welcome_title")}</h1> <h1 className="text-2xl font-bold">{t("welcome_title")}</h1>
<p className="max-w-md text-muted-foreground"> <p className="max-w-md text-muted-foreground">{t("welcome_description")}</p>
{t("welcome_description")}
</p>
</div> </div>
<Button size="lg" onClick={onCreateClick} className="gap-2"> <Button size="lg" onClick={onCreateClick} className="gap-2">
@ -123,11 +121,7 @@ export default function DashboardPage() {
const router = useRouter(); const router = useRouter();
const [showCreateDialog, setShowCreateDialog] = useState(false); const [showCreateDialog, setShowCreateDialog] = useState(false);
const { const { data: searchSpaces = [], isLoading, error } = useAtomValue(searchSpacesAtom);
data: searchSpaces = [],
isLoading,
error,
} = useAtomValue(searchSpacesAtom);
useEffect(() => { useEffect(() => {
if (isLoading) return; if (isLoading) return;

View file

@ -17,12 +17,7 @@ import { useTranslations } from "next-intl";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { useApiKey } from "@/hooks/use-api-key"; import { useApiKey } from "@/hooks/use-api-key";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@ -249,16 +244,10 @@ function ApiKeyContent({ onMenuClick }: { onMenuClick: () => void }) {
onClick={copyToClipboard} onClick={copyToClipboard}
className="shrink-0" className="shrink-0"
> >
{copied ? ( {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
<Check className="h-4 w-4" />
) : (
<Copy className="h-4 w-4" />
)}
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>{copied ? t("copied") : t("copy")}</TooltipContent>
{copied ? t("copied") : t("copy")}
</TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
</div> </div>

View file

@ -3,8 +3,8 @@
import { AlertTriangle, Ban, Wrench } from "lucide-react"; import { AlertTriangle, Ban, Wrench } from "lucide-react";
import type { FC } from "react"; import type { FC } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import type { ConnectorStatus } from "../config/connector-status-config";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import type { ConnectorStatus } from "../config/connector-status-config";
interface ConnectorStatusBadgeProps { interface ConnectorStatusBadgeProps {
status: ConnectorStatus; status: ConnectorStatus;

View file

@ -8,8 +8,8 @@ import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import type { SearchSourceConnector } from "@/contracts/types/connector.types"; import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types"; import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { getConnectorDisplayName } from "../tabs/all-connectors-tab";
import { useConnectorStatus } from "../hooks/use-connector-status"; import { useConnectorStatus } from "../hooks/use-connector-status";
import { getConnectorDisplayName } from "../tabs/all-connectors-tab";
interface ConnectorAccountsListViewProps { interface ConnectorAccountsListViewProps {
connectorType: string; connectorType: string;

View file

@ -15,7 +15,11 @@ interface InlineCitationProps {
* Renders a clickable numbered badge that opens the SourceDetailPanel with document chunk details. * Renders a clickable numbered badge that opens the SourceDetailPanel with document chunk details.
* Supports both regular knowledge base chunks and Surfsense documentation chunks. * Supports both regular knowledge base chunks and Surfsense documentation chunks.
*/ */
export const InlineCitation: FC<InlineCitationProps> = ({ chunkId, citationNumber, isDocsChunk = false }) => { export const InlineCitation: FC<InlineCitationProps> = ({
chunkId,
citationNumber,
isDocsChunk = false,
}) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
return ( return (

View file

@ -6,9 +6,9 @@ export type {
NavItem, NavItem,
NoteItem, NoteItem,
PageUsage, PageUsage,
SearchSpace,
SidebarSectionProps, SidebarSectionProps,
User, User,
SearchSpace,
} from "./types/layout.types"; } from "./types/layout.types";
export { export {
AllSearchSpacesSheet, AllSearchSpacesSheet,
@ -23,10 +23,10 @@ export {
NavSection, NavSection,
NoteListItem, NoteListItem,
PageUsageDisplay, PageUsageDisplay,
SearchSpaceAvatar,
Sidebar, Sidebar,
SidebarCollapseButton, SidebarCollapseButton,
SidebarHeader, SidebarHeader,
SidebarSection, SidebarSection,
SidebarUserProfile, SidebarUserProfile,
SearchSpaceAvatar,
} from "./ui"; } from "./ui";

View file

@ -28,8 +28,8 @@ import { resetUser, trackLogout } from "@/lib/posthog/events";
import { cacheKeys } from "@/lib/query-client/cache-keys"; import { cacheKeys } from "@/lib/query-client/cache-keys";
import type { ChatItem, NavItem, NoteItem, SearchSpace } from "../types/layout.types"; import type { ChatItem, NavItem, NoteItem, SearchSpace } from "../types/layout.types";
import { CreateSearchSpaceDialog } from "../ui/dialogs"; import { CreateSearchSpaceDialog } from "../ui/dialogs";
import { LayoutShell } from "../ui/shell";
import { AllSearchSpacesSheet } from "../ui/sheets"; import { AllSearchSpacesSheet } from "../ui/sheets";
import { LayoutShell } from "../ui/shell";
import { AllChatsSidebar } from "../ui/sidebar/AllChatsSidebar"; import { AllChatsSidebar } from "../ui/sidebar/AllChatsSidebar";
import { AllNotesSidebar } from "../ui/sidebar/AllNotesSidebar"; import { AllNotesSidebar } from "../ui/sidebar/AllNotesSidebar";

View file

@ -104,11 +104,7 @@ export function CreateSearchSpaceDialog({ open, onOpenChange }: CreateSearchSpac
<FormItem> <FormItem>
<FormLabel>{t("name_label")}</FormLabel> <FormLabel>{t("name_label")}</FormLabel>
<FormControl> <FormControl>
<Input <Input placeholder={t("name_placeholder")} {...field} autoFocus />
placeholder={t("name_placeholder")}
{...field}
autoFocus
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -163,4 +159,3 @@ export function CreateSearchSpaceDialog({ open, onOpenChange }: CreateSearchSpac
</Dialog> </Dialog>
); );
} }

View file

@ -1,2 +1 @@
export { CreateSearchSpaceDialog } from "./CreateSearchSpaceDialog"; export { CreateSearchSpaceDialog } from "./CreateSearchSpaceDialog";

View file

@ -42,7 +42,12 @@ function getInitials(name: string): string {
return name.slice(0, 2).toUpperCase(); return name.slice(0, 2).toUpperCase();
} }
export function SearchSpaceAvatar({ name, isActive, onClick, size = "md" }: SearchSpaceAvatarProps) { export function SearchSpaceAvatar({
name,
isActive,
onClick,
size = "md",
}: SearchSpaceAvatarProps) {
const bgColor = stringToColor(name); const bgColor = stringToColor(name);
const initials = getInitials(name); const initials = getInitials(name);
const sizeClasses = size === "sm" ? "h-8 w-8 text-xs" : "h-10 w-10 text-sm"; const sizeClasses = size === "sm" ? "h-8 w-8 text-xs" : "h-10 w-10 text-sm";

View file

@ -1,8 +1,8 @@
export { CreateSearchSpaceDialog } from "./dialogs"; export { CreateSearchSpaceDialog } from "./dialogs";
export { Header } from "./header"; export { Header } from "./header";
export { IconRail, NavIcon, SearchSpaceAvatar } from "./icon-rail"; export { IconRail, NavIcon, SearchSpaceAvatar } from "./icon-rail";
export { LayoutShell } from "./shell";
export { AllSearchSpacesSheet } from "./sheets"; export { AllSearchSpacesSheet } from "./sheets";
export { LayoutShell } from "./shell";
export { export {
ChatListItem, ChatListItem,
MobileSidebar, MobileSidebar,

View file

@ -1,6 +1,15 @@
"use client"; "use client";
import { Calendar, MoreHorizontal, Search, Settings, Share2, Trash2, UserCheck, Users } from "lucide-react"; import {
Calendar,
MoreHorizontal,
Search,
Settings,
Share2,
Trash2,
UserCheck,
Users,
} from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { useState } from "react"; import { useState } from "react";
import { import {
@ -112,9 +121,7 @@ export function AllSearchSpacesSheet({
</div> </div>
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<p className="font-medium">{t("no_search_spaces")}</p> <p className="font-medium">{t("no_search_spaces")}</p>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">{t("create_first_search_space")}</p>
{t("create_first_search_space")}
</p>
</div> </div>
{onCreateNew && ( {onCreateNew && (
<Button onClick={onCreateNew} className="mt-2"> <Button onClick={onCreateNew} className="mt-2">
@ -132,9 +139,7 @@ export function AllSearchSpacesSheet({
> >
<div className="flex items-start justify-between gap-2"> <div className="flex items-start justify-between gap-2">
<div className="flex flex-1 flex-col gap-1"> <div className="flex flex-1 flex-col gap-1">
<span className="font-medium leading-tight"> <span className="font-medium leading-tight">{space.name}</span>
{space.name}
</span>
{space.description && ( {space.description && (
<span className="text-sm text-muted-foreground line-clamp-2"> <span className="text-sm text-muted-foreground line-clamp-2">
{space.description} {space.description}

View file

@ -1,2 +1 @@
export { AllSearchSpacesSheet } from "./AllSearchSpacesSheet"; export { AllSearchSpacesSheet } from "./AllSearchSpacesSheet";

View file

@ -10,8 +10,8 @@ import type {
NavItem, NavItem,
NoteItem, NoteItem,
PageUsage, PageUsage,
User,
SearchSpace, SearchSpace,
User,
} from "../../types/layout.types"; } from "../../types/layout.types";
import { Header } from "../header"; import { Header } from "../header";
import { IconRail } from "../icon-rail"; import { IconRail } from "../icon-rail";

View file

@ -9,8 +9,8 @@ import type {
NavItem, NavItem,
NoteItem, NoteItem,
PageUsage, PageUsage,
User,
SearchSpace, SearchSpace,
User,
} from "../../types/layout.types"; } from "../../types/layout.types";
import { IconRail } from "../icon-rail"; import { IconRail } from "../icon-rail";
import { Sidebar } from "./Sidebar"; import { Sidebar } from "./Sidebar";

View file

@ -11,8 +11,8 @@ import type {
NavItem, NavItem,
NoteItem, NoteItem,
PageUsage, PageUsage,
User,
SearchSpace, SearchSpace,
User,
} from "../../types/layout.types"; } from "../../types/layout.types";
import { ChatListItem } from "./ChatListItem"; import { ChatListItem } from "./ChatListItem";
import { NavSection } from "./NavSection"; import { NavSection } from "./NavSection";
@ -289,7 +289,12 @@ export function Sidebar({
<PageUsageDisplay pagesUsed={pageUsage.pagesUsed} pagesLimit={pageUsage.pagesLimit} /> <PageUsageDisplay pagesUsed={pageUsage.pagesUsed} pagesLimit={pageUsage.pagesLimit} />
)} )}
<SidebarUserProfile user={user} onUserSettings={onUserSettings} onLogout={onLogout} isCollapsed={isCollapsed} /> <SidebarUserProfile
user={user}
onUserSettings={onUserSettings}
onLogout={onLogout}
isCollapsed={isCollapsed}
/>
</div> </div>
</div> </div>
); );

View file

@ -43,7 +43,9 @@ export function SidebarHeader({
isCollapsed ? "w-10" : "w-50" isCollapsed ? "w-10" : "w-50"
)} )}
> >
<span className="truncate text-base">{searchSpace?.name ?? t("select_search_space")}</span> <span className="truncate text-base">
{searchSpace?.name ?? t("select_search_space")}
</span>
<ChevronsUpDown className="h-4 w-4 shrink-0 text-muted-foreground" /> <ChevronsUpDown className="h-4 w-4 shrink-0 text-muted-foreground" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>