mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-10 22:32:16 +02:00
feat(workspace): remove AI file sorting feature and related components
This commit is contained in:
parent
72c2dd0e1b
commit
cda232101f
18 changed files with 40 additions and 1005 deletions
|
|
@ -1,6 +1,5 @@
|
|||
"use client";
|
||||
|
||||
import { IconBinaryTree, IconBinaryTreeFilled } from "@tabler/icons-react";
|
||||
import { FolderPlus, ListFilter, Search, Upload, X } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import React, { useCallback, useMemo, useRef, useState } from "react";
|
||||
|
|
@ -9,12 +8,10 @@ import { Button } from "@/components/ui/button";
|
|||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import type { DocumentTypeEnum } from "@/contracts/types/document.types";
|
||||
import { getDocumentTypeLabel } from "@/lib/documents/document-type-labels";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getDocumentTypeIcon } from "./DocumentTypeIcon";
|
||||
|
||||
export function DocumentsFilters({
|
||||
|
|
@ -24,9 +21,6 @@ export function DocumentsFilters({
|
|||
onToggleType,
|
||||
activeTypes,
|
||||
onCreateFolder,
|
||||
aiSortEnabled = false,
|
||||
aiSortBusy = false,
|
||||
onToggleAiSort,
|
||||
onUploadClick,
|
||||
}: {
|
||||
typeCounts: Partial<Record<DocumentTypeEnum, number>>;
|
||||
|
|
@ -35,9 +29,6 @@ export function DocumentsFilters({
|
|||
onToggleType: (type: DocumentTypeEnum, checked: boolean) => void;
|
||||
activeTypes: DocumentTypeEnum[];
|
||||
onCreateFolder?: () => void;
|
||||
aiSortEnabled?: boolean;
|
||||
aiSortBusy?: boolean;
|
||||
onToggleAiSort?: () => void;
|
||||
onUploadClick?: () => void;
|
||||
}) {
|
||||
const t = useTranslations("documents");
|
||||
|
|
@ -77,7 +68,7 @@ export function DocumentsFilters({
|
|||
return (
|
||||
<div className="flex select-none">
|
||||
<div className="flex items-center gap-2 w-full">
|
||||
{/* New Folder + AI Sort + Filter Toggle Group */}
|
||||
{/* New Folder + Filter Toggle Group */}
|
||||
<ToggleGroup type="multiple" value={[]} className="overflow-visible">
|
||||
{onCreateFolder && (
|
||||
<Tooltip>
|
||||
|
|
@ -97,46 +88,6 @@ export function DocumentsFilters({
|
|||
</Tooltip>
|
||||
)}
|
||||
|
||||
{onToggleAiSort && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<ToggleGroupItem
|
||||
value="ai-sort"
|
||||
disabled={aiSortBusy}
|
||||
className={cn(
|
||||
"h-8 w-8 shrink-0 border-0 bg-muted transition-colors",
|
||||
"relative before:absolute before:left-0 before:top-1/2 before:h-4 before:w-px before:-translate-y-1/2 before:bg-border/60 before:content-[''] dark:before:bg-white/10",
|
||||
"disabled:pointer-events-none disabled:opacity-50",
|
||||
aiSortEnabled
|
||||
? "bg-accent text-accent-foreground hover:bg-accent"
|
||||
: "text-muted-foreground hover:bg-accent hover:text-accent-foreground"
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onToggleAiSort();
|
||||
}}
|
||||
aria-label={aiSortEnabled ? "Disable AI sort" : "Enable AI sort"}
|
||||
aria-pressed={aiSortEnabled}
|
||||
>
|
||||
{aiSortBusy ? (
|
||||
<Spinner size="xs" />
|
||||
) : aiSortEnabled ? (
|
||||
<IconBinaryTreeFilled size={14} />
|
||||
) : (
|
||||
<IconBinaryTree size={14} />
|
||||
)}
|
||||
</ToggleGroupItem>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{aiSortBusy
|
||||
? "AI sort in progress..."
|
||||
: aiSortEnabled
|
||||
? "AI sort active — click to disable"
|
||||
: "Enable AI sort"}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Popover>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
|
|
|||
|
|
@ -93,8 +93,6 @@ export function FolderTreeView({
|
|||
|
||||
const [openContextMenuId, setOpenContextMenuId] = useState<string | null>(null);
|
||||
|
||||
const [manuallyCollapsedAiIds, setManuallyCollapsedAiIds] = useState<Set<number>>(new Set());
|
||||
|
||||
// Single subscription for rename state — derived boolean passed to each FolderNode
|
||||
const [renamingFolderId, setRenamingFolderId] = useAtom(renamingFolderIdAtom);
|
||||
const handleStartRename = useCallback(
|
||||
|
|
@ -103,38 +101,6 @@ export function FolderTreeView({
|
|||
);
|
||||
const handleCancelRename = useCallback(() => setRenamingFolderId(null), [setRenamingFolderId]);
|
||||
|
||||
const aiSortFolderLevels = useMemo(() => {
|
||||
const map = new Map<number, number>();
|
||||
for (const f of folders) {
|
||||
if (f.metadata?.ai_sort === true && typeof f.metadata?.ai_sort_level === "number") {
|
||||
map.set(f.id, f.metadata.ai_sort_level as number);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}, [folders]);
|
||||
|
||||
const handleToggleExpand = useCallback(
|
||||
(folderId: number) => {
|
||||
const aiLevel = aiSortFolderLevels.get(folderId);
|
||||
if (aiLevel !== undefined && aiLevel < 4) {
|
||||
// AI-auto-expanded folder: only toggle the manual-collapse set.
|
||||
// Calling onToggleExpand would add it to expandedIds and fight auto-expand.
|
||||
setManuallyCollapsedAiIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(folderId)) {
|
||||
next.delete(folderId);
|
||||
} else {
|
||||
next.add(folderId);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
return;
|
||||
}
|
||||
onToggleExpand(folderId);
|
||||
},
|
||||
[onToggleExpand, aiSortFolderLevels]
|
||||
);
|
||||
|
||||
const effectiveActiveTypes = useMemo(() => {
|
||||
if (
|
||||
activeTypes.includes("FILE" as DocumentTypeEnum) &&
|
||||
|
|
@ -280,14 +246,9 @@ export function FolderTreeView({
|
|||
|
||||
function renderLevel(parentId: number | null, depth: number): React.ReactNode[] {
|
||||
const key = parentId ?? "root";
|
||||
const childFolders = (foldersByParent[key] ?? []).slice().sort((a, b) => {
|
||||
const aIsDate = a.metadata?.ai_sort === true && a.metadata?.ai_sort_level === 2;
|
||||
const bIsDate = b.metadata?.ai_sort === true && b.metadata?.ai_sort_level === 2;
|
||||
if (aIsDate && bIsDate) {
|
||||
return b.name.localeCompare(a.name);
|
||||
}
|
||||
return a.position.localeCompare(b.position);
|
||||
});
|
||||
const childFolders = (foldersByParent[key] ?? [])
|
||||
.slice()
|
||||
.sort((a, b) => a.position.localeCompare(b.position));
|
||||
const visibleFolders = hasDescendantMatch
|
||||
? childFolders.filter((f) => hasDescendantMatch[f.id])
|
||||
: childFolders;
|
||||
|
|
@ -317,14 +278,7 @@ export function FolderTreeView({
|
|||
};
|
||||
|
||||
const isSearchAutoExpanded = !!searchQuery && !!hasDescendantMatch?.[f.id];
|
||||
const isAiAutoExpandCandidate =
|
||||
f.metadata?.ai_sort === true &&
|
||||
typeof f.metadata?.ai_sort_level === "number" &&
|
||||
(f.metadata.ai_sort_level as number) < 4;
|
||||
const isManuallyCollapsed = manuallyCollapsedAiIds.has(f.id);
|
||||
const isExpanded = isManuallyCollapsed
|
||||
? isSearchAutoExpanded
|
||||
: expandedIds.has(f.id) || isSearchAutoExpanded || isAiAutoExpandCandidate;
|
||||
const isExpanded = expandedIds.has(f.id) || isSearchAutoExpanded;
|
||||
|
||||
nodes.push(
|
||||
<FolderNode
|
||||
|
|
@ -336,7 +290,7 @@ export function FolderTreeView({
|
|||
selectionState={folderSelectionStates[f.id] ?? "none"}
|
||||
processingState={folderProcessingStates[f.id] ?? "idle"}
|
||||
onToggleSelect={onToggleFolderSelect}
|
||||
onToggleExpand={handleToggleExpand}
|
||||
onToggleExpand={onToggleExpand}
|
||||
onRename={onRenameFolder}
|
||||
onStartRename={handleStartRename}
|
||||
onCancelRename={handleCancelRename}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue