mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-18 23:11:12 +02:00
chore: linting
This commit is contained in:
parent
d61e29e74b
commit
d960a065b1
4 changed files with 119 additions and 116 deletions
|
|
@ -540,14 +540,10 @@ export function DocumentsTableShell({
|
||||||
).length;
|
).length;
|
||||||
const failCount = deletableSelectedIds.length - successCount;
|
const failCount = deletableSelectedIds.length - successCount;
|
||||||
if (successCount > 0) {
|
if (successCount > 0) {
|
||||||
toast.success(
|
toast.success(`Deleted ${successCount} document${successCount !== 1 ? "s" : ""}`);
|
||||||
`Deleted ${successCount} document${successCount !== 1 ? "s" : ""}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (failCount > 0) {
|
if (failCount > 0) {
|
||||||
toast.error(
|
toast.error(`Failed to delete ${failCount} document${failCount !== 1 ? "s" : ""}`);
|
||||||
`Failed to delete ${failCount} document${failCount !== 1 ? "s" : ""}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -561,58 +557,56 @@ export function DocumentsTableShell({
|
||||||
<div className="bg-sidebar overflow-hidden select-none border-t border-border/50 flex-1 flex flex-col min-h-0">
|
<div className="bg-sidebar overflow-hidden select-none border-t border-border/50 flex-1 flex flex-col min-h-0">
|
||||||
{/* Desktop Table View */}
|
{/* Desktop Table View */}
|
||||||
<div className="hidden md:flex md:flex-col flex-1 min-h-0">
|
<div className="hidden md:flex md:flex-col flex-1 min-h-0">
|
||||||
<Table className="table-fixed w-full">
|
<Table className="table-fixed w-full">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow className="hover:bg-transparent border-b border-border/50">
|
<TableRow className="hover:bg-transparent border-b border-border/50">
|
||||||
<TableHead className="w-10 pl-3 pr-0 text-center h-8">
|
<TableHead className="w-10 pl-3 pr-0 text-center h-8">
|
||||||
<div className="flex items-center justify-center h-full">
|
<div className="flex items-center justify-center h-full">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={allMentionedOnPage || (someMentionedOnPage && "indeterminate")}
|
checked={allMentionedOnPage || (someMentionedOnPage && "indeterminate")}
|
||||||
onCheckedChange={(v) => toggleAll(!!v)}
|
onCheckedChange={(v) => toggleAll(!!v)}
|
||||||
aria-label={hasChatMode ? "Toggle all for chat" : "Select all"}
|
aria-label={hasChatMode ? "Toggle all for chat" : "Select all"}
|
||||||
className="border-foreground data-[state=checked]:bg-primary data-[state=checked]:border-primary"
|
className="border-foreground data-[state=checked]:bg-primary data-[state=checked]:border-primary"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableHead className="h-8 px-2">
|
<TableHead className="h-8 px-2">
|
||||||
<SortableHeader
|
<SortableHeader
|
||||||
sortKey="title"
|
sortKey="title"
|
||||||
currentSortKey={sortKey}
|
currentSortKey={sortKey}
|
||||||
sortDesc={sortDesc}
|
sortDesc={sortDesc}
|
||||||
onSort={onSortHeader}
|
onSort={onSortHeader}
|
||||||
icon={<FileText size={14} className="text-muted-foreground" />}
|
icon={<FileText size={14} className="text-muted-foreground" />}
|
||||||
>
|
>
|
||||||
Document
|
Document
|
||||||
</SortableHeader>
|
</SortableHeader>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableHead className="w-10 text-center h-8 px-0">
|
<TableHead className="w-10 text-center h-8 px-0">
|
||||||
<span className="flex items-center justify-center">
|
<span className="flex items-center justify-center">
|
||||||
<Network size={14} className="text-muted-foreground" />
|
<Network size={14} className="text-muted-foreground" />
|
||||||
</span>
|
</span>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableHead className="w-12 text-center h-8 pl-0 pr-3">
|
<TableHead className="w-12 text-center h-8 pl-0 pr-3">
|
||||||
{hasDeletableSelection ? (
|
{hasDeletableSelection ? (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setBulkDeleteConfirmOpen(true)}
|
onClick={() => setBulkDeleteConfirmOpen(true)}
|
||||||
className="inline-flex items-center justify-center h-6 w-6 rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
|
className="inline-flex items-center justify-center h-6 w-6 rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
|
||||||
>
|
>
|
||||||
<Trash2 size={14} />
|
<Trash2 size={14} />
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>Delete {deletableSelectedIds.length} selected</TooltipContent>
|
||||||
Delete {deletableSelectedIds.length} selected
|
</Tooltip>
|
||||||
</TooltipContent>
|
) : (
|
||||||
</Tooltip>
|
<span className="text-xs font-medium text-muted-foreground">Status</span>
|
||||||
) : (
|
)}
|
||||||
<span className="text-xs font-medium text-muted-foreground">Status</span>
|
</TableHead>
|
||||||
)}
|
</TableRow>
|
||||||
</TableHead>
|
</TableHeader>
|
||||||
</TableRow>
|
</Table>
|
||||||
</TableHeader>
|
|
||||||
</Table>
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="flex-1 overflow-auto">
|
<div className="flex-1 overflow-auto">
|
||||||
<Table className="table-fixed w-full">
|
<Table className="table-fixed w-full">
|
||||||
|
|
@ -683,50 +677,50 @@ export function DocumentsTableShell({
|
||||||
<div ref={desktopScrollRef} className="flex-1 overflow-auto">
|
<div ref={desktopScrollRef} className="flex-1 overflow-auto">
|
||||||
<Table className="table-fixed w-full">
|
<Table className="table-fixed w-full">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{sorted.map((doc) => {
|
{sorted.map((doc) => {
|
||||||
const isMentioned = mentionedDocIds?.has(doc.id) ?? false;
|
const isMentioned = mentionedDocIds?.has(doc.id) ?? false;
|
||||||
const canInteract = isSelectable(doc);
|
const canInteract = isSelectable(doc);
|
||||||
const handleRowToggle = () => {
|
const handleRowToggle = () => {
|
||||||
if (canInteract && onToggleChatMention) {
|
if (canInteract && onToggleChatMention) {
|
||||||
onToggleChatMention(doc, isMentioned);
|
onToggleChatMention(doc, isMentioned);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleRowClick = (e: React.MouseEvent) => {
|
const handleRowClick = (e: React.MouseEvent) => {
|
||||||
if (e.ctrlKey || e.metaKey) {
|
if (e.ctrlKey || e.metaKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleViewMetadata(doc);
|
handleViewMetadata(doc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleRowToggle();
|
handleRowToggle();
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<RowContextMenu
|
<RowContextMenu
|
||||||
key={doc.id}
|
key={doc.id}
|
||||||
doc={doc}
|
doc={doc}
|
||||||
onPreview={handleViewDocument}
|
onPreview={handleViewDocument}
|
||||||
onDelete={setDeleteDoc}
|
onDelete={setDeleteDoc}
|
||||||
searchSpaceId={searchSpaceId}
|
searchSpaceId={searchSpaceId}
|
||||||
onEditNavigate={onEditNavigate}
|
onEditNavigate={onEditNavigate}
|
||||||
>
|
|
||||||
<tr
|
|
||||||
className={`border-b border-border/50 transition-colors ${
|
|
||||||
isMentioned ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"
|
|
||||||
} ${canInteract && hasChatMode ? "cursor-pointer" : ""}`}
|
|
||||||
onClick={handleRowClick}
|
|
||||||
>
|
>
|
||||||
|
<tr
|
||||||
|
className={`border-b border-border/50 transition-colors ${
|
||||||
|
isMentioned ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"
|
||||||
|
} ${canInteract && hasChatMode ? "cursor-pointer" : ""}`}
|
||||||
|
onClick={handleRowClick}
|
||||||
|
>
|
||||||
<TableCell
|
<TableCell
|
||||||
className="w-10 pl-3 pr-0 py-1.5 text-center"
|
className="w-10 pl-3 pr-0 py-1.5 text-center"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-center h-full">
|
<div className="flex items-center justify-center h-full">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={isMentioned}
|
checked={isMentioned}
|
||||||
onCheckedChange={() => handleRowToggle()}
|
onCheckedChange={() => handleRowToggle()}
|
||||||
disabled={!canInteract}
|
disabled={!canInteract}
|
||||||
aria-label={isMentioned ? "Remove from chat" : "Add to chat"}
|
aria-label={isMentioned ? "Remove from chat" : "Add to chat"}
|
||||||
className={`border-foreground data-[state=checked]:bg-primary data-[state=checked]:border-primary ${!canInteract ? "opacity-40 cursor-not-allowed" : ""}`}
|
className={`border-foreground data-[state=checked]:bg-primary data-[state=checked]:border-primary ${!canInteract ? "opacity-40 cursor-not-allowed" : ""}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="px-2 py-1.5 max-w-0">
|
<TableCell className="px-2 py-1.5 max-w-0">
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,11 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
|
|
||||||
// Atoms
|
// Atoms
|
||||||
const { data: user } = useAtomValue(currentUserAtom);
|
const { data: user } = useAtomValue(currentUserAtom);
|
||||||
const { data: searchSpacesData, refetch: refetchSearchSpaces, isSuccess: searchSpacesLoaded } = useAtomValue(searchSpacesAtom);
|
const {
|
||||||
|
data: searchSpacesData,
|
||||||
|
refetch: refetchSearchSpaces,
|
||||||
|
isSuccess: searchSpacesLoaded,
|
||||||
|
} = useAtomValue(searchSpacesAtom);
|
||||||
const { mutateAsync: deleteSearchSpace } = useAtomValue(deleteSearchSpaceMutationAtom);
|
const { mutateAsync: deleteSearchSpace } = useAtomValue(deleteSearchSpaceMutationAtom);
|
||||||
const currentThreadState = useAtomValue(currentThreadAtom);
|
const currentThreadState = useAtomValue(currentThreadAtom);
|
||||||
const resetCurrentThread = useSetAtom(resetCurrentThreadAtom);
|
const resetCurrentThread = useSetAtom(resetCurrentThreadAtom);
|
||||||
|
|
@ -279,13 +283,22 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
// Safety redirect: if the current search space is no longer in the user's list
|
// Safety redirect: if the current search space is no longer in the user's list
|
||||||
// (e.g. deleted by background task, membership revoked), redirect to a valid space.
|
// (e.g. deleted by background task, membership revoked), redirect to a valid space.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!searchSpacesLoaded || !searchSpaceId || isDeletingSearchSpace || isLeavingSearchSpace) return;
|
if (!searchSpacesLoaded || !searchSpaceId || isDeletingSearchSpace || isLeavingSearchSpace)
|
||||||
|
return;
|
||||||
if (searchSpaces.length > 0 && !activeSearchSpace) {
|
if (searchSpaces.length > 0 && !activeSearchSpace) {
|
||||||
router.replace(`/dashboard/${searchSpaces[0].id}/new-chat`);
|
router.replace(`/dashboard/${searchSpaces[0].id}/new-chat`);
|
||||||
} else if (searchSpaces.length === 0 && searchSpacesLoaded) {
|
} else if (searchSpaces.length === 0 && searchSpacesLoaded) {
|
||||||
router.replace("/dashboard");
|
router.replace("/dashboard");
|
||||||
}
|
}
|
||||||
}, [searchSpacesLoaded, searchSpaceId, searchSpaces, activeSearchSpace, isDeletingSearchSpace, isLeavingSearchSpace, router]);
|
}, [
|
||||||
|
searchSpacesLoaded,
|
||||||
|
searchSpaceId,
|
||||||
|
searchSpaces,
|
||||||
|
activeSearchSpace,
|
||||||
|
isDeletingSearchSpace,
|
||||||
|
isLeavingSearchSpace,
|
||||||
|
router,
|
||||||
|
]);
|
||||||
|
|
||||||
// Transform and split chats into private and shared based on visibility
|
// Transform and split chats into private and shared based on visibility
|
||||||
const { myChats, sharedChats } = useMemo(() => {
|
const { myChats, sharedChats } = useMemo(() => {
|
||||||
|
|
@ -400,9 +413,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
|
|
||||||
// Await refetch so we have the freshest list (backend now hides [DELETING] spaces)
|
// Await refetch so we have the freshest list (backend now hides [DELETING] spaces)
|
||||||
const result = await refetchSearchSpaces();
|
const result = await refetchSearchSpaces();
|
||||||
const updatedSpaces = (result.data ?? []).filter(
|
const updatedSpaces = (result.data ?? []).filter((s) => s.id !== searchSpaceToDelete.id);
|
||||||
(s) => s.id !== searchSpaceToDelete.id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isCurrentSpace) {
|
if (isCurrentSpace) {
|
||||||
if (updatedSpaces.length > 0) {
|
if (updatedSpaces.length > 0) {
|
||||||
|
|
@ -421,14 +432,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
setShowDeleteSearchSpaceDialog(false);
|
setShowDeleteSearchSpaceDialog(false);
|
||||||
setSearchSpaceToDelete(null);
|
setSearchSpaceToDelete(null);
|
||||||
}
|
}
|
||||||
}, [
|
}, [searchSpaceToDelete, deleteSearchSpace, refetchSearchSpaces, searchSpaceId, router, t]);
|
||||||
searchSpaceToDelete,
|
|
||||||
deleteSearchSpace,
|
|
||||||
refetchSearchSpaces,
|
|
||||||
searchSpaceId,
|
|
||||||
router,
|
|
||||||
t,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const confirmLeaveSearchSpace = useCallback(async () => {
|
const confirmLeaveSearchSpace = useCallback(async () => {
|
||||||
if (!searchSpaceToLeave) return;
|
if (!searchSpaceToLeave) return;
|
||||||
|
|
@ -439,9 +443,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
const isCurrentSpace = Number(searchSpaceId) === searchSpaceToLeave.id;
|
const isCurrentSpace = Number(searchSpaceId) === searchSpaceToLeave.id;
|
||||||
|
|
||||||
const result = await refetchSearchSpaces();
|
const result = await refetchSearchSpaces();
|
||||||
const updatedSpaces = (result.data ?? []).filter(
|
const updatedSpaces = (result.data ?? []).filter((s) => s.id !== searchSpaceToLeave.id);
|
||||||
(s) => s.id !== searchSpaceToLeave.id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isCurrentSpace) {
|
if (isCurrentSpace) {
|
||||||
if (updatedSpaces.length > 0) {
|
if (updatedSpaces.length > 0) {
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,14 @@ export function DocumentsSidebar({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[deleteDocumentMutation, isSearchMode, t, searchRemoveItems, realtimeRemoveItems, setSidebarDocs]
|
[
|
||||||
|
deleteDocumentMutation,
|
||||||
|
isSearchMode,
|
||||||
|
t,
|
||||||
|
searchRemoveItems,
|
||||||
|
realtimeRemoveItems,
|
||||||
|
setSidebarDocs,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleBulkDeleteDocuments = useCallback(
|
const handleBulkDeleteDocuments = useCallback(
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ function initPostHog() {
|
||||||
defaults: "2025-11-30",
|
defaults: "2025-11-30",
|
||||||
capture_pageview: "history_change",
|
capture_pageview: "history_change",
|
||||||
capture_pageleave: true,
|
capture_pageleave: true,
|
||||||
before_send: (event) => {
|
before_send: (event) => {
|
||||||
if (event?.properties) {
|
if (event?.properties) {
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const ref = params.get("ref");
|
const ref = params.get("ref");
|
||||||
if (ref) {
|
if (ref) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue