diff --git a/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx
index 4532be429c..fec065fd15 100644
--- a/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx
+++ b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx
@@ -3,17 +3,21 @@ import {
BlockSuiteEditor,
EditorLoading,
} from '@affine/component/block-suite-editor';
-import { Button } from '@affine/component/ui/button';
+import { Button, IconButton } from '@affine/component/ui/button';
import { ConfirmModal, Modal } from '@affine/component/ui/modal';
-import type { PageMode } from '@affine/core/atoms';
+import { openSettingModalAtom, type PageMode } from '@affine/core/atoms';
+import { useIsWorkspaceOwner } from '@affine/core/hooks/affine/use-is-workspace-owner';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
+import { useUserSubscription } from '@affine/core/hooks/use-subscription';
import { waitForCurrentWorkspaceAtom } from '@affine/core/modules/workspace';
+import { SubscriptionPlan } from '@affine/graphql';
+import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
-import { ToggleCollapseIcon } from '@blocksuite/icons';
+import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons';
import type { Page, Workspace } from '@blocksuite/store';
import * as Collapsible from '@radix-ui/react-collapsible';
import type { DialogContentProps } from '@radix-ui/react-dialog';
-import { useAtom, useAtomValue } from 'jotai';
+import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai';
import {
Fragment,
type PropsWithChildren,
@@ -154,6 +158,71 @@ const HistoryEditorPreview = ({
);
};
+const planPromptClosedAtom = atom(false);
+
+const PlanPrompt = () => {
+ const [subscription] = useUserSubscription();
+ const currentWorkspace = useAtomValue(waitForCurrentWorkspaceAtom);
+ const isOwner = useIsWorkspaceOwner(currentWorkspace.meta);
+ const freePlan = subscription?.plan === SubscriptionPlan.Free;
+
+ const setSettingModalAtom = useSetAtom(openSettingModalAtom);
+ const [planPromptClosed, setPlanPromptClosed] = useAtom(planPromptClosedAtom);
+
+ const closeFreePlanPrompt = useCallback(() => {
+ setPlanPromptClosed(true);
+ }, [setPlanPromptClosed]);
+
+ const onClickUpgrade = useCallback(() => {
+ setSettingModalAtom({
+ open: true,
+ activeTab: 'plans',
+ });
+ }, [setSettingModalAtom]);
+
+ const t = useAFFiNEI18N();
+
+ return !planPromptClosed ? (
+
+
+
+ {freePlan
+ ? t[
+ 'com.affine.history.confirm-restore-modal.plan-prompt.limited-title'
+ ]()
+ : t['com.affine.history.confirm-restore-modal.plan-prompt.title']()}
+
+ }
+ onClick={closeFreePlanPrompt}
+ />
+
+ {freePlan ? (
+ <>
+
+ Free users can view up to the last 7 days of page history.
+
+ {isOwner ? (
+
+ {t[
+ 'com.affine.history.confirm-restore-modal.pro-plan-prompt.upgrade'
+ ]()}
+
+ ) : null}
+ >
+ ) : (
+
+ Pro users can view up to the last 30 days of page history.
+
+ )}
+
+
+ ) : null;
+};
const PageHistoryList = ({
pageDocId,
@@ -191,6 +260,7 @@ const PageHistoryList = ({
+
{historyListByDay.map(([day, list], i) => {
const collapsed = collapsedMap[i];
return (
@@ -252,7 +322,7 @@ const PageHistoryList = ({
className={styles.historyItemLoadMore}
onClick={loadMore}
>
- Load More
+ {t['com.affine.history.confirm-restore-modal.load-more']()}
) : null}
diff --git a/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts b/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts
index 5d0aec0419..25e5fa80a9 100644
--- a/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts
+++ b/packages/frontend/core/src/components/affine/page-history-modal/styles.css.ts
@@ -10,7 +10,7 @@ export const root = style({
vars: {
[headerHeight]: '52px',
[footerHeight]: '68px',
- [historyListWidth]: '160px',
+ [historyListWidth]: '240px',
},
});
@@ -273,3 +273,31 @@ export const collapsedIconContainer = style({
},
},
});
+
+export const planPromptWrapper = style({
+ padding: '4px 12px',
+});
+
+export const planPrompt = style({
+ gap: 6,
+ borderRadius: 8,
+ flexDirection: 'column',
+ padding: 10,
+ fontSize: 'var(--affine-font-xs)',
+ backgroundColor: 'var(--affine-background-secondary-color)',
+});
+
+export const planPromptTitle = style({
+ fontWeight: 600,
+ marginBottom: 14,
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ color: 'var(--affine-text-secondary-color)',
+});
+
+export const planPromptUpdateButton = style({
+ textDecoration: 'underline',
+ cursor: 'pointer',
+ marginLeft: 4,
+});
diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json
index ee2b37977c..b4baf26319 100644
--- a/packages/frontend/i18n/src/resources/en.json
+++ b/packages/frontend/i18n/src/resources/en.json
@@ -1011,6 +1011,12 @@
"com.affine.history.empty-prompt.description": "This document is such a spring chicken, it hasn't sprouted a single historical sprig yet!",
"com.affine.history.confirm-restore-modal.restore": "Restore",
"com.affine.history.confirm-restore-modal.hint": "You are about to restore the current version of the page to the latest version available. This action will overwrite any changes made prior to the latest version.",
+ "com.affine.history.confirm-restore-modal.load-more": "Load More",
+ "com.affine.history.confirm-restore-modal.plan-prompt.title": "HELP INFO",
+ "com.affine.history.confirm-restore-modal.plan-prompt.limited-title": "LIMITED PAGE HISTORY",
+ "com.affine.history.confirm-restore-modal.free-plan-prompt.description": "Free users can view up to the <1>last 7 days<1> of page history.",
+ "com.affine.history.confirm-restore-modal.pro-plan-prompt.description": "Pro users can view up to the <1>last 30 days<1> of page history.",
+ "com.affine.history.confirm-restore-modal.pro-plan-prompt.upgrade": "Upgrade",
"com.affine.share-page.header.present": "Present",
"com.affine.page-operation.add-linked-page": "Add linked page",
"com.affine.onboarding.workspace-guide.title": "Start AFFiNE by creating your own Workspace here!",