mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
4387f3ced7
- Use transient `$rtl` prop on Meta styled component so it isn't forwarded to the DOM - Wrap ActionButton in observer so action visibility checks read MobX computed values inside a reactive context Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
111 lines
3.6 KiB
TypeScript
111 lines
3.6 KiB
TypeScript
import { observer } from "mobx-react";
|
|
import * as React from "react";
|
|
import { colorPalette } from "@shared/utils/collections";
|
|
import type Document from "~/models/Document";
|
|
import type Revision from "~/models/Revision";
|
|
import type { Props as EditorProps } from "~/components/Editor";
|
|
import Flex from "~/components/Flex";
|
|
import { documentPath } from "~/utils/routeHelpers";
|
|
import { Meta as DocumentMeta } from "./DocumentMeta";
|
|
import DocumentTitle from "./DocumentTitle";
|
|
import Editor from "~/components/Editor";
|
|
import { richExtensions, withComments } from "@shared/editor/nodes";
|
|
import Diff from "@shared/editor/extensions/Diff";
|
|
import { RevisionHelper } from "@shared/utils/RevisionHelper";
|
|
import useQuery from "~/hooks/useQuery";
|
|
import useStores from "~/hooks/useStores";
|
|
import { type Editor as TEditor } from "~/editor";
|
|
import { ChangesetHelper } from "@shared/editor/lib/ChangesetHelper";
|
|
|
|
type Props = Omit<EditorProps, "extensions"> & {
|
|
/** The ID of the revision */
|
|
id: string;
|
|
/** The current document */
|
|
document: Document;
|
|
/** The revision to display */
|
|
revision: Revision;
|
|
/** Whether to show changes from the previous revision */
|
|
showChanges?: boolean;
|
|
children?: React.ReactNode;
|
|
};
|
|
|
|
/**
|
|
* Displays a revision with diff highlighting showing changes from the previous revision.
|
|
*
|
|
* This component shows the content of a specific revision with visual diff indicators
|
|
* that highlight what changed compared to the revision that came before it. Insertions
|
|
* are shown with a highlight background, and deletions are shown with strikethrough.
|
|
*
|
|
* @param props - Component props including the revision to display and current document
|
|
*/
|
|
function RevisionViewer(props: Props, ref: React.Ref<TEditor>) {
|
|
const { document, children, revision } = props;
|
|
const { revisions } = useStores();
|
|
const query = useQuery();
|
|
const showChanges = props.showChanges ?? query.has("changes");
|
|
const compareToParam = query.get("compareTo");
|
|
|
|
const compareToRevisionId = React.useMemo(() => {
|
|
if (!compareToParam) {
|
|
return undefined;
|
|
}
|
|
return compareToParam === "latest"
|
|
? RevisionHelper.latestId(revision.documentId)
|
|
: compareToParam;
|
|
}, [compareToParam, revision.documentId]);
|
|
|
|
const compareToRevision = compareToRevisionId
|
|
? revisions.get(compareToRevisionId)
|
|
: undefined;
|
|
|
|
const comparisonData = compareToRevisionId
|
|
? compareToRevision?.data
|
|
: revision.before?.data;
|
|
|
|
/**
|
|
* Create editor extensions with the Diff extension configured to render
|
|
* the calculated changes as decorations in the editor.
|
|
*/
|
|
const extensions = React.useMemo(() => {
|
|
const changeset = ChangesetHelper.getChangeset(
|
|
revision.data,
|
|
comparisonData
|
|
);
|
|
return [
|
|
...withComments(richExtensions),
|
|
...(showChanges && changeset?.changes
|
|
? [new Diff({ changes: changeset?.changes })]
|
|
: []),
|
|
];
|
|
}, [revision.data, comparisonData, showChanges]);
|
|
|
|
return (
|
|
<Flex auto column>
|
|
<DocumentTitle
|
|
documentId={revision.documentId}
|
|
title={revision.title}
|
|
icon={revision.icon}
|
|
color={revision.color ?? colorPalette[0]}
|
|
readOnly
|
|
/>
|
|
<DocumentMeta
|
|
document={document}
|
|
revision={revision}
|
|
to={documentPath(document)}
|
|
$rtl={revision.rtl}
|
|
/>
|
|
<Editor
|
|
key={compareToRevisionId}
|
|
ref={ref}
|
|
defaultValue={revision.data}
|
|
extensions={extensions}
|
|
dir={revision.dir}
|
|
readOnly
|
|
/>
|
|
{children}
|
|
</Flex>
|
|
);
|
|
}
|
|
|
|
export default observer(React.forwardRef(RevisionViewer));
|