mirror of
https://github.com/docmost/docmost.git
synced 2026-08-23 21:02:16 +10:00
fix: comment error boundary
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { ActionIcon, Box, Group, ScrollArea, Title, Tooltip } from "@mantine/core";
|
||||
import { IconX } from "@tabler/icons-react";
|
||||
import CommentListWithTabs from "@/features/comment/components/comment-list-with-tabs.tsx";
|
||||
import { CommentErrorBoundary } from "@/features/comment/components/comment-error-boundary.tsx";
|
||||
import { useAtom } from "jotai";
|
||||
import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts";
|
||||
import React, { ReactNode, useEffect } from "react";
|
||||
@@ -28,7 +29,11 @@ export default function Aside() {
|
||||
|
||||
switch (tab) {
|
||||
case "comments":
|
||||
component = <CommentListWithTabs />;
|
||||
component = (
|
||||
<CommentErrorBoundary>
|
||||
<CommentListWithTabs />
|
||||
</CommentErrorBoundary>
|
||||
);
|
||||
title = "Comments";
|
||||
break;
|
||||
case "toc":
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from "@/features/comment/atoms/comment-atom";
|
||||
import CommentEditor from "@/features/comment/components/comment-editor";
|
||||
import CommentActions from "@/features/comment/components/comment-actions";
|
||||
import { CommentErrorBoundary } from "@/features/comment/components/comment-error-boundary";
|
||||
import { currentUserAtom } from "@/features/user/atoms/current-user-atom";
|
||||
import { useCreateCommentMutation } from "@/features/comment/queries/comment-query";
|
||||
import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom";
|
||||
@@ -170,14 +171,16 @@ function CommentDialog({ editor, pageId, readOnly }: CommentDialogProps) {
|
||||
</div>
|
||||
</Group>
|
||||
|
||||
<CommentEditor
|
||||
onUpdate={handleCommentEditorChange}
|
||||
onSave={handleAddComment}
|
||||
placeholder={t("Write a comment")}
|
||||
editable={true}
|
||||
autofocus={true}
|
||||
/>
|
||||
<CommentActions onSave={handleAddComment} isLoading={isPending} />
|
||||
<CommentErrorBoundary>
|
||||
<CommentEditor
|
||||
onUpdate={handleCommentEditorChange}
|
||||
onSave={handleAddComment}
|
||||
placeholder={t("Write a comment")}
|
||||
editable={true}
|
||||
autofocus={true}
|
||||
/>
|
||||
<CommentActions onSave={handleAddComment} isLoading={isPending} />
|
||||
</CommentErrorBoundary>
|
||||
</Stack>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -6,13 +6,9 @@ import { Color } from "@tiptap/extension-color";
|
||||
import {
|
||||
Mention,
|
||||
LinkExtension,
|
||||
CustomTable,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableHeader,
|
||||
TableView,
|
||||
TiptapImage,
|
||||
SharedStorage,
|
||||
Attachment,
|
||||
} from "@docmost/editor-ext";
|
||||
import ImageView from "@/features/editor/components/image/image-view";
|
||||
import classes from "./comment.module.css";
|
||||
@@ -24,6 +20,8 @@ import EmojiCommand from "@/features/editor/extensions/emoji-command";
|
||||
import mentionRenderItems from "@/features/editor/components/mention/mention-suggestion";
|
||||
import MentionView from "@/features/editor/components/mention/mention-view";
|
||||
import { platformModifierKey } from "@/lib";
|
||||
import { TableKit } from "@tiptap/extension-table";
|
||||
import AttachmentView from "@/features/editor/components/attachment/attachment-view.tsx";
|
||||
|
||||
interface CommentEditorProps {
|
||||
defaultContent?: any;
|
||||
@@ -81,14 +79,11 @@ const CommentEditor = forwardRef(
|
||||
return ReactNodeViewRenderer(MentionView);
|
||||
},
|
||||
}),
|
||||
SharedStorage,
|
||||
CustomTable.configure({
|
||||
resizable: false,
|
||||
View: TableView,
|
||||
TableKit,
|
||||
Attachment.configure({
|
||||
view: AttachmentView,
|
||||
}),
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableHeader,
|
||||
SharedStorage,
|
||||
TiptapImage.configure({
|
||||
view: ImageView,
|
||||
allowBase64: false,
|
||||
@@ -139,7 +134,12 @@ const CommentEditor = forwardRef(
|
||||
// websocket on another browser). Skip for editable editors to avoid
|
||||
// resetting the cursor position on every keystroke.
|
||||
useEffect(() => {
|
||||
if (!editable && commentEditor && !commentEditor.isDestroyed && defaultContent) {
|
||||
if (
|
||||
!editable &&
|
||||
commentEditor &&
|
||||
!commentEditor.isDestroyed &&
|
||||
defaultContent
|
||||
) {
|
||||
commentEditor.commands.setContent(defaultContent);
|
||||
}
|
||||
}, [defaultContent, editable, commentEditor]);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ReactNode } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { Button } from "@mantine/core";
|
||||
import { IconAlertTriangle } from "@tabler/icons-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { EmptyState } from "@/components/ui/empty-state.tsx";
|
||||
|
||||
type CommentErrorBoundaryProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
// Contain comment-editor render throws (e.g. schema errors) so they don't unmount the whole app.
|
||||
export function CommentErrorBoundary({ children }: CommentErrorBoundaryProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<ErrorBoundary
|
||||
fallbackRender={({ resetErrorBoundary }) => (
|
||||
<EmptyState
|
||||
icon={IconAlertTriangle}
|
||||
title={t("Failed to load comments. An error occurred.")}
|
||||
action={
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
mt="xs"
|
||||
onClick={resetErrorBoundary}
|
||||
>
|
||||
{t("Try again")}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user