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:
Anish Sarkar 2026-03-08 17:43:19 +05:30
parent 0f7878a3a0
commit 5ce3790847
12 changed files with 38 additions and 34 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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>