feat: implement editor panel functionality and integrate with existing components

- Added editor panel state management using Jotai atoms.
- Integrated editor panel into the right panel and documents sidebar.
- Updated DocumentsTableShell to open the editor panel on edit action.
- Enhanced NewChatPage to close the editor panel when navigating away.
- Improved context menu actions for document editing and deletion.
This commit is contained in:
Anish Sarkar 2026-03-17 16:55:31 +05:30
parent 0d56cfb663
commit f617ae8742
7 changed files with 414 additions and 38 deletions

View file

@ -5,7 +5,9 @@ import { PanelRight, PanelRightClose } from "lucide-react";
import { startTransition, useEffect } from "react";
import { closeReportPanelAtom, reportPanelAtom } from "@/atoms/chat/report-panel.atom";
import { documentsSidebarOpenAtom } from "@/atoms/documents/ui.atoms";
import { closeEditorPanelAtom, editorPanelAtom } from "@/atoms/editor/editor-panel.atom";
import { rightPanelCollapsedAtom, rightPanelTabAtom } from "@/atoms/layout/right-panel.atom";
import { EditorPanelContent } from "@/components/editor-panel/editor-panel";
import { ReportPanelContent } from "@/components/report-panel/report-panel";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
@ -41,8 +43,10 @@ export function RightPanelExpandButton() {
const [collapsed, setCollapsed] = useAtom(rightPanelCollapsedAtom);
const documentsOpen = useAtomValue(documentsSidebarOpenAtom);
const reportState = useAtomValue(reportPanelAtom);
const editorState = useAtomValue(editorPanelAtom);
const reportOpen = reportState.isOpen && !!reportState.reportId;
const hasContent = documentsOpen || reportOpen;
const editorOpen = editorState.isOpen && !!editorState.documentId;
const hasContent = documentsOpen || reportOpen || editorOpen;
if (!collapsed || !hasContent) return null;
@ -66,34 +70,42 @@ export function RightPanelExpandButton() {
);
}
const PANEL_WIDTHS = { sources: 420, report: 640 } as const;
const PANEL_WIDTHS = { sources: 420, report: 640, editor: 640 } as const;
export function RightPanel({ documentsPanel }: RightPanelProps) {
const [activeTab] = useAtom(rightPanelTabAtom);
const reportState = useAtomValue(reportPanelAtom);
const closeReport = useSetAtom(closeReportPanelAtom);
const editorState = useAtomValue(editorPanelAtom);
const closeEditor = useSetAtom(closeEditorPanelAtom);
const [collapsed, setCollapsed] = useAtom(rightPanelCollapsedAtom);
const documentsOpen = documentsPanel?.open ?? false;
const reportOpen = reportState.isOpen && !!reportState.reportId;
const editorOpen = editorState.isOpen && !!editorState.documentId;
useEffect(() => {
if (!reportOpen) return;
if (!reportOpen && !editorOpen) return;
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") closeReport();
if (e.key === "Escape") {
if (editorOpen) closeEditor();
else if (reportOpen) closeReport();
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [reportOpen, closeReport]);
}, [reportOpen, editorOpen, closeReport, closeEditor]);
const isVisible = (documentsOpen || reportOpen) && !collapsed;
const isVisible = (documentsOpen || reportOpen || editorOpen) && !collapsed;
const effectiveTab =
activeTab === "report" && !reportOpen
? "sources"
: activeTab === "sources" && !documentsOpen
? "report"
: activeTab;
let effectiveTab = activeTab;
if (effectiveTab === "editor" && !editorOpen) {
effectiveTab = reportOpen ? "report" : "sources";
} else if (effectiveTab === "report" && !reportOpen) {
effectiveTab = editorOpen ? "editor" : "sources";
} else if (effectiveTab === "sources" && !documentsOpen) {
effectiveTab = editorOpen ? "editor" : reportOpen ? "report" : "sources";
}
const targetWidth = PANEL_WIDTHS[effectiveTab];
const collapseButton = <CollapseButton onClick={() => setCollapsed(true)} />;
@ -126,6 +138,16 @@ export function RightPanel({ documentsPanel }: RightPanelProps) {
/>
</div>
)}
{effectiveTab === "editor" && editorOpen && (
<div className="h-full flex flex-col">
<EditorPanelContent
documentId={editorState.documentId as number}
searchSpaceId={editorState.searchSpaceId as number}
title={editorState.title}
onClose={closeEditor}
/>
</div>
)}
</div>
</aside>
);