mirror of
https://github.com/docmost/docmost.git
synced 2026-08-15 08:01:36 +10:00
feat(client): compare two page history versions in history view
This commit is contained in:
@@ -1293,5 +1293,7 @@
|
||||
"Compare": "Compare",
|
||||
"Compare versions": "Compare versions",
|
||||
"Select version from {{date}}": "Select version from {{date}}",
|
||||
"Version actions for {{date}}": "Version actions for {{date}}"
|
||||
"Version actions for {{date}}": "Version actions for {{date}}",
|
||||
"Comparing {{newer}} and {{older}}": "Comparing {{newer}} and {{older}}",
|
||||
"Exit compare": "Exit compare"
|
||||
}
|
||||
|
||||
@@ -99,3 +99,8 @@
|
||||
flex: 1;
|
||||
padding: rem(16px) rem(40px);
|
||||
}
|
||||
|
||||
.compareBanner {
|
||||
border-bottom: rem(1px) solid
|
||||
light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
CloseButton,
|
||||
Group,
|
||||
Paper,
|
||||
ScrollArea,
|
||||
@@ -12,17 +13,20 @@ import { useAtom, useAtomValue } from "jotai";
|
||||
import {
|
||||
activeHistoryIdAtom,
|
||||
activeHistoryPrevIdAtom,
|
||||
comparePairAtom,
|
||||
diffCountsAtom,
|
||||
highlightChangesAtom,
|
||||
} from "@/features/page-history/atoms/history-atoms";
|
||||
import HistoryView from "@/features/page-history/components/history-view";
|
||||
import { useRef } from "react";
|
||||
import { useMemo, useRef } from "react";
|
||||
import { IconChevronUp, IconChevronDown } from "@tabler/icons-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
useDiffNavigation,
|
||||
useHistoryReset,
|
||||
} from "@/features/page-history/hooks";
|
||||
import { usePageHistoryListQuery } from "@/features/page-history/queries/page-history-query";
|
||||
import { formattedDate } from "@/lib/time";
|
||||
|
||||
interface Props {
|
||||
pageId: string;
|
||||
@@ -36,6 +40,28 @@ export default function HistoryModalBody({ pageId }: Props) {
|
||||
const activeHistoryPrevId = useAtomValue(activeHistoryPrevIdAtom);
|
||||
const [highlightChanges, setHighlightChanges] = useAtom(highlightChangesAtom);
|
||||
const diffCounts = useAtomValue(diffCountsAtom);
|
||||
const [comparePair, setComparePair] = useAtom(comparePairAtom);
|
||||
|
||||
const { data: pageHistoryData } = usePageHistoryListQuery(pageId);
|
||||
const historyItems = useMemo(
|
||||
() => pageHistoryData?.pages.flatMap((page) => page.items) ?? [],
|
||||
[pageHistoryData],
|
||||
);
|
||||
|
||||
const compareLabel = useMemo(() => {
|
||||
if (!comparePair) return null;
|
||||
const newerItem = historyItems.find(
|
||||
(item) => item.id === comparePair.newerId,
|
||||
);
|
||||
const olderItem = historyItems.find(
|
||||
(item) => item.id === comparePair.olderId,
|
||||
);
|
||||
if (!newerItem || !olderItem) return null;
|
||||
return t("Comparing {{newer}} and {{older}}", {
|
||||
newer: formattedDate(new Date(newerItem.createdAt)),
|
||||
older: formattedDate(new Date(olderItem.createdAt)),
|
||||
});
|
||||
}, [comparePair, historyItems, t]);
|
||||
|
||||
useHistoryReset(pageId);
|
||||
const { currentChangeIndex, handlePrevChange, handleNextChange } =
|
||||
@@ -50,6 +76,25 @@ export default function HistoryModalBody({ pageId }: Props) {
|
||||
</nav>
|
||||
|
||||
<div style={{ position: "relative", flex: 1 }}>
|
||||
{comparePair && compareLabel && (
|
||||
<Group
|
||||
justify="space-between"
|
||||
wrap="nowrap"
|
||||
px="md"
|
||||
py={4}
|
||||
className={classes.compareBanner}
|
||||
>
|
||||
<Text size="sm" fw={500} lineClamp={1}>
|
||||
{compareLabel}
|
||||
</Text>
|
||||
<CloseButton
|
||||
size="sm"
|
||||
aria-label={t("Exit compare")}
|
||||
onClick={() => setComparePair(null)}
|
||||
/>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
<ScrollArea
|
||||
h={650}
|
||||
w="100%"
|
||||
@@ -57,11 +102,18 @@ export default function HistoryModalBody({ pageId }: Props) {
|
||||
viewportRef={scrollViewportRef}
|
||||
>
|
||||
<div className={classes.sidebarRightSection}>
|
||||
{activeHistoryId && <HistoryView />}
|
||||
{comparePair ? (
|
||||
<HistoryView
|
||||
historyId={comparePair.newerId}
|
||||
prevHistoryId={comparePair.olderId}
|
||||
/>
|
||||
) : (
|
||||
activeHistoryId && <HistoryView />
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
{activeHistoryId && activeHistoryPrevId && (
|
||||
{(comparePair || (activeHistoryId && activeHistoryPrevId)) && (
|
||||
<Paper
|
||||
shadow="md"
|
||||
radius="xl"
|
||||
|
||||
@@ -7,21 +7,29 @@ import {
|
||||
activeHistoryPrevIdAtom,
|
||||
} from "@/features/page-history/atoms/history-atoms";
|
||||
|
||||
function HistoryView() {
|
||||
interface Props {
|
||||
historyId?: string;
|
||||
prevHistoryId?: string;
|
||||
}
|
||||
|
||||
function HistoryView({ historyId, prevHistoryId }: Props) {
|
||||
const { t } = useTranslation();
|
||||
const historyId = useAtomValue(activeHistoryIdAtom);
|
||||
const prevHistoryId = useAtomValue(activeHistoryPrevIdAtom);
|
||||
const activeId = useAtomValue(activeHistoryIdAtom);
|
||||
const activePrevId = useAtomValue(activeHistoryPrevIdAtom);
|
||||
|
||||
const resolvedId = historyId ?? activeId;
|
||||
const resolvedPrevId = prevHistoryId ?? activePrevId;
|
||||
|
||||
const {
|
||||
data,
|
||||
isLoading: isLoadingCurrent,
|
||||
isError: isErrorCurrent,
|
||||
} = usePageHistoryQuery(historyId);
|
||||
} = usePageHistoryQuery(resolvedId);
|
||||
const {
|
||||
data: prevData,
|
||||
isLoading: isLoadingPrev,
|
||||
isError: isErrorPrev,
|
||||
} = usePageHistoryQuery(prevHistoryId);
|
||||
} = usePageHistoryQuery(resolvedPrevId);
|
||||
|
||||
if (isLoadingCurrent || isLoadingPrev) {
|
||||
return <></>;
|
||||
|
||||
Reference in New Issue
Block a user