mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-10 22:32:16 +02:00
refactor: enhance UI component styles and functionality in Documents filters, table shell, and editor for improved user experience and consistency
This commit is contained in:
parent
0f7878a3a0
commit
5ce3790847
12 changed files with 38 additions and 34 deletions
|
|
@ -79,7 +79,7 @@ export function DocumentsFilters({
|
|||
<PopoverContent className="w-64 !p-0 overflow-hidden" align="end">
|
||||
<div>
|
||||
{/* Search input */}
|
||||
<div className="p-2 border-b border-neutral-700">
|
||||
<div className="p-2 border-b border-border dark:border-neutral-700">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-0.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
|
|
@ -108,7 +108,7 @@ export function DocumentsFilters({
|
|||
<button
|
||||
type="button"
|
||||
key={value}
|
||||
className="flex w-full items-center gap-2.5 py-2 px-3 rounded-md hover:bg-muted/50 transition-colors cursor-pointer text-left"
|
||||
className="flex w-full items-center gap-2.5 py-2 px-3 rounded-md hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-colors cursor-pointer text-left"
|
||||
onClick={() => onToggleType(value, !activeTypes.includes(value))}
|
||||
>
|
||||
{/* Icon */}
|
||||
|
|
@ -137,11 +137,11 @@ export function DocumentsFilters({
|
|||
)}
|
||||
</div>
|
||||
{activeTypes.length > 0 && (
|
||||
<div className="px-3 pt-1.5 pb-1.5 border-t border-neutral-700">
|
||||
<div className="px-3 pt-1.5 pb-1.5 border-t border-border dark:border-neutral-700">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full h-7 text-[11px] text-muted-foreground hover:text-foreground hover:bg-neutral-700"
|
||||
className="w-full h-7 text-[11px] text-muted-foreground hover:text-foreground hover:bg-neutral-200 dark:hover:bg-neutral-700"
|
||||
onClick={() => {
|
||||
activeTypes.forEach((t) => {
|
||||
onToggleType(t, false);
|
||||
|
|
|
|||
|
|
@ -222,12 +222,14 @@ function RowContextMenu({
|
|||
onPreview,
|
||||
onDelete,
|
||||
searchSpaceId,
|
||||
onEditNavigate,
|
||||
}: {
|
||||
doc: Document;
|
||||
children: React.ReactNode;
|
||||
onPreview: (doc: Document) => void;
|
||||
onDelete: (doc: Document) => void;
|
||||
searchSpaceId: string;
|
||||
onEditNavigate?: () => void;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
|
|
@ -252,9 +254,12 @@ function RowContextMenu({
|
|||
</ContextMenuItem>
|
||||
{isEditable && (
|
||||
<ContextMenuItem
|
||||
onClick={() =>
|
||||
!isEditDisabled && router.push(`/dashboard/${searchSpaceId}/editor/${doc.id}`)
|
||||
}
|
||||
onClick={() => {
|
||||
if (!isEditDisabled) {
|
||||
onEditNavigate?.();
|
||||
router.push(`/dashboard/${searchSpaceId}/editor/${doc.id}`);
|
||||
}
|
||||
}}
|
||||
disabled={isEditDisabled}
|
||||
>
|
||||
<PenLine className="h-4 w-4" />
|
||||
|
|
@ -318,9 +323,9 @@ export function DocumentsTableShell({
|
|||
hasMore = false,
|
||||
loadingMore = false,
|
||||
onLoadMore,
|
||||
isSearchMode = false,
|
||||
mentionedDocIds,
|
||||
onToggleChatMention,
|
||||
onEditNavigate,
|
||||
}: {
|
||||
documents: Document[];
|
||||
loading: boolean;
|
||||
|
|
@ -333,11 +338,12 @@ export function DocumentsTableShell({
|
|||
hasMore?: boolean;
|
||||
loadingMore?: boolean;
|
||||
onLoadMore?: () => void;
|
||||
isSearchMode?: boolean;
|
||||
/** IDs of documents currently mentioned as chips in the chat composer */
|
||||
mentionedDocIds?: Set<number>;
|
||||
/** Toggle a document's mention in the chat (add if not mentioned, remove if mentioned) */
|
||||
onToggleChatMention?: (doc: Document, mentioned: boolean) => void;
|
||||
/** Called when user navigates to the editor via Edit — use to close containing sidebar/panel */
|
||||
onEditNavigate?: () => void;
|
||||
}) {
|
||||
const t = useTranslations("documents");
|
||||
const { openDialog } = useDocumentUploadDialog();
|
||||
|
|
@ -579,6 +585,7 @@ export function DocumentsTableShell({
|
|||
onPreview={handleViewDocument}
|
||||
onDelete={setDeleteDoc}
|
||||
searchSpaceId={searchSpaceId}
|
||||
onEditNavigate={onEditNavigate}
|
||||
>
|
||||
<tr
|
||||
className={`border-b border-border/50 transition-colors ${
|
||||
|
|
@ -839,6 +846,7 @@ export function DocumentsTableShell({
|
|||
}
|
||||
onClick={() => {
|
||||
if (mobileActionDoc) {
|
||||
onEditNavigate?.();
|
||||
router.push(`/dashboard/${searchSpaceId}/editor/${mobileActionDoc.id}`);
|
||||
setMobileActionDoc(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {
|
|||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Button, buttonVariants } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { notesApiService } from "@/lib/apis/notes-api.service";
|
||||
|
|
@ -83,6 +83,7 @@ export default function EditorPage() {
|
|||
const [error, setError] = useState<string | null>(null);
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
||||
const [showUnsavedDialog, setShowUnsavedDialog] = useState(false);
|
||||
const [editorTitle, setEditorTitle] = useState<string>("Untitled");
|
||||
|
||||
// Store the latest markdown from the editor
|
||||
const markdownRef = useRef<string>("");
|
||||
|
|
@ -117,20 +118,18 @@ export default function EditorPage() {
|
|||
}
|
||||
}, [pendingNavigation, hasUnsavedChanges, router, setPendingNavigation]);
|
||||
|
||||
// Reset state when documentId changes
|
||||
// Reset state and fetch document content when documentId changes
|
||||
useEffect(() => {
|
||||
setDocument(null);
|
||||
setError(null);
|
||||
setHasUnsavedChanges(false);
|
||||
setLoading(true);
|
||||
initialLoadDone.current = false;
|
||||
}, [documentId]);
|
||||
|
||||
// Fetch document content
|
||||
useEffect(() => {
|
||||
async function fetchDocument() {
|
||||
if (isNewNote) {
|
||||
markdownRef.current = "";
|
||||
setEditorTitle("Untitled");
|
||||
setDocument({
|
||||
document_id: 0,
|
||||
title: "Untitled",
|
||||
|
|
@ -173,6 +172,7 @@ export default function EditorPage() {
|
|||
}
|
||||
|
||||
markdownRef.current = data.source_markdown;
|
||||
setEditorTitle(extractTitleFromMarkdown(data.source_markdown));
|
||||
setDocument(data);
|
||||
setError(null);
|
||||
initialLoadDone.current = true;
|
||||
|
|
@ -193,20 +193,17 @@ export default function EditorPage() {
|
|||
|
||||
const isNote = isNewNote || document?.document_type === "NOTE";
|
||||
|
||||
// Extract title dynamically from current markdown for notes
|
||||
const displayTitle = useMemo(() => {
|
||||
if (isNote) {
|
||||
return extractTitleFromMarkdown(markdownRef.current || document?.source_markdown);
|
||||
}
|
||||
if (isNote) return editorTitle;
|
||||
return document?.title || "Untitled";
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isNote, document?.title, document?.source_markdown, hasUnsavedChanges]);
|
||||
}, [isNote, document?.title, editorTitle]);
|
||||
|
||||
// Handle markdown changes from the Plate editor
|
||||
const handleMarkdownChange = useCallback((md: string) => {
|
||||
markdownRef.current = md;
|
||||
if (initialLoadDone.current) {
|
||||
setHasUnsavedChanges(true);
|
||||
setEditorTitle(extractTitleFromMarkdown(md));
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
|
@ -493,13 +490,13 @@ export default function EditorPage() {
|
|||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onClick={handleCancelLeave}>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleSaveAndLeave}>Save</AlertDialogAction>
|
||||
<AlertDialogAction
|
||||
onClick={handleConfirmLeave}
|
||||
className="border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground"
|
||||
className={buttonVariants({ variant: "secondary" })}
|
||||
>
|
||||
Leave without saving
|
||||
</AlertDialogAction>
|
||||
<AlertDialogAction onClick={handleSaveAndLeave}>Save</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue