fix(core): remove openInfoModalAtom to avoid multiple modal opened in split-view (#8329)
close AF-1403
This commit is contained in:
@@ -4,9 +4,15 @@ import {
|
|||||||
Modal,
|
Modal,
|
||||||
Scrollable,
|
Scrollable,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { LiveData, useLiveData, useServices } from '@toeverything/infra';
|
import {
|
||||||
|
LiveData,
|
||||||
|
useLiveData,
|
||||||
|
useService,
|
||||||
|
useServices,
|
||||||
|
} from '@toeverything/infra';
|
||||||
import { Suspense, useCallback, useContext, useMemo, useRef } from 'react';
|
import { Suspense, useCallback, useContext, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import { BlocksuiteHeaderTitle } from '../../../blocksuite/block-suite-header/title';
|
import { BlocksuiteHeaderTitle } from '../../../blocksuite/block-suite-header/title';
|
||||||
@@ -22,20 +28,23 @@ import { LinksRow } from './links-row';
|
|||||||
import { TagsRow } from './tags-row';
|
import { TagsRow } from './tags-row';
|
||||||
import { TimeRow } from './time-row';
|
import { TimeRow } from './time-row';
|
||||||
|
|
||||||
export const InfoModal = ({
|
export const InfoModal = () => {
|
||||||
open,
|
const modal = useService(DocInfoService).modal;
|
||||||
onOpenChange,
|
const docId = useLiveData(modal.docId$);
|
||||||
docId,
|
|
||||||
}: {
|
if (!docId) return null;
|
||||||
open: boolean;
|
|
||||||
onOpenChange: (open: boolean) => void;
|
return <InfoModalOpened docId={docId} />;
|
||||||
docId: string;
|
};
|
||||||
}) => {
|
|
||||||
|
const InfoModalOpened = ({ docId }: { docId: string }) => {
|
||||||
|
const modal = useService(DocInfoService).modal;
|
||||||
|
|
||||||
const titleInputHandleRef = useRef<InlineEditHandle>(null);
|
const titleInputHandleRef = useRef<InlineEditHandle>(null);
|
||||||
const manager = usePagePropertiesManager(docId);
|
const manager = usePagePropertiesManager(docId ?? '');
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
onOpenChange(false);
|
modal.close();
|
||||||
}, [onOpenChange]);
|
}, [modal]);
|
||||||
|
|
||||||
if (!manager.page || manager.readonly) {
|
if (!manager.page || manager.readonly) {
|
||||||
return null;
|
return null;
|
||||||
@@ -46,8 +55,8 @@ export const InfoModal = ({
|
|||||||
contentOptions={{
|
contentOptions={{
|
||||||
className: styles.container,
|
className: styles.container,
|
||||||
}}
|
}}
|
||||||
open={open}
|
open
|
||||||
onOpenChange={onOpenChange}
|
onOpenChange={v => modal.onOpenChange(v)}
|
||||||
withoutCloseButton
|
withoutCloseButton
|
||||||
>
|
>
|
||||||
<Scrollable.Root>
|
<Scrollable.Root>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ export const openQuotaModalAtom = atom(false);
|
|||||||
export const openStarAFFiNEModalAtom = atom(false);
|
export const openStarAFFiNEModalAtom = atom(false);
|
||||||
export const openIssueFeedbackModalAtom = atom(false);
|
export const openIssueFeedbackModalAtom = atom(false);
|
||||||
export const openHistoryTipsModalAtom = atom(false);
|
export const openHistoryTipsModalAtom = atom(false);
|
||||||
export const openInfoModalAtom = atom(false);
|
|
||||||
|
|
||||||
export const rightSidebarWidthAtom = atom(320);
|
export const rightSidebarWidthAtom = atom(320);
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { IconButton } from '@affine/component';
|
import { IconButton } from '@affine/component';
|
||||||
import { openInfoModalAtom } from '@affine/core/components/atoms';
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { track } from '@affine/track';
|
import { track } from '@affine/track';
|
||||||
import { InformationIcon } from '@blocksuite/icons/rc';
|
import { InformationIcon } from '@blocksuite/icons/rc';
|
||||||
import { useSetAtom } from 'jotai';
|
import { useService } from '@toeverything/infra';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export const InfoButton = () => {
|
export const InfoButton = ({ docId }: { docId: string }) => {
|
||||||
const setOpenInfoModal = useSetAtom(openInfoModalAtom);
|
const modal = useService(DocInfoService).modal;
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const onOpenInfoModal = useCallback(() => {
|
const onOpenInfoModal = useCallback(() => {
|
||||||
track.$.header.actions.openDocInfo();
|
track.$.header.actions.openDocInfo();
|
||||||
setOpenInfoModal(true);
|
modal.open(docId);
|
||||||
}, [setOpenInfoModal]);
|
}, [docId, modal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import {
|
|||||||
} from '@affine/component/ui/menu';
|
} from '@affine/component/ui/menu';
|
||||||
import { PageHistoryModal } from '@affine/core/components/affine/page-history-modal';
|
import { PageHistoryModal } from '@affine/core/components/affine/page-history-modal';
|
||||||
import { ShareMenuContent } from '@affine/core/components/affine/share-page-modal/share-menu';
|
import { ShareMenuContent } from '@affine/core/components/affine/share-page-modal/share-menu';
|
||||||
import {
|
import { openHistoryTipsModalAtom } from '@affine/core/components/atoms';
|
||||||
openHistoryTipsModalAtom,
|
|
||||||
openInfoModalAtom,
|
|
||||||
} from '@affine/core/components/atoms';
|
|
||||||
import { useBlockSuiteMetaHelper } from '@affine/core/components/hooks/affine/use-block-suite-meta-helper';
|
import { useBlockSuiteMetaHelper } from '@affine/core/components/hooks/affine/use-block-suite-meta-helper';
|
||||||
import { useEnableCloud } from '@affine/core/components/hooks/affine/use-enable-cloud';
|
import { useEnableCloud } from '@affine/core/components/hooks/affine/use-enable-cloud';
|
||||||
import { useExportPage } from '@affine/core/components/hooks/affine/use-export-page';
|
import { useExportPage } from '@affine/core/components/hooks/affine/use-export-page';
|
||||||
@@ -20,6 +17,7 @@ import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-
|
|||||||
import { Export, MoveToTrash } from '@affine/core/components/page-list';
|
import { Export, MoveToTrash } from '@affine/core/components/page-list';
|
||||||
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
|
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
|
||||||
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
|
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
|
||||||
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
||||||
@@ -117,11 +115,11 @@ export const PageHeaderMenuButton = ({
|
|||||||
return setOpenHistoryTipsModal(true);
|
return setOpenHistoryTipsModal(true);
|
||||||
}, [setOpenHistoryTipsModal, workspace.flavour]);
|
}, [setOpenHistoryTipsModal, workspace.flavour]);
|
||||||
|
|
||||||
const setOpenInfoModal = useSetAtom(openInfoModalAtom);
|
const docInfoModal = useService(DocInfoService).modal;
|
||||||
const openInfoModal = useCallback(() => {
|
const openInfoModal = useCallback(() => {
|
||||||
track.$.header.pageInfo.open();
|
track.$.header.pageInfo.open();
|
||||||
setOpenInfoModal(true);
|
docInfoModal.open(pageId);
|
||||||
}, [setOpenInfoModal]);
|
}, [docInfoModal, pageId]);
|
||||||
|
|
||||||
const handleOpenInNewTab = useCallback(() => {
|
const handleOpenInNewTab = useCallback(() => {
|
||||||
workbench.openDoc(pageId, {
|
workbench.openDoc(pageId, {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
PreconditionStrategy,
|
PreconditionStrategy,
|
||||||
registerAffineCommand,
|
registerAffineCommand,
|
||||||
} from '@affine/core/commands';
|
} from '@affine/core/commands';
|
||||||
import { openInfoModalAtom } from '@affine/core/components/atoms';
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import type { Editor } from '@affine/core/modules/editor';
|
import type { Editor } from '@affine/core/modules/editor';
|
||||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||||
@@ -36,7 +36,7 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
|
|||||||
const trash = useLiveData(doc.trash$);
|
const trash = useLiveData(doc.trash$);
|
||||||
|
|
||||||
const setPageHistoryModalState = useSetAtom(pageHistoryModalAtom);
|
const setPageHistoryModalState = useSetAtom(pageHistoryModalAtom);
|
||||||
const setInfoModalState = useSetAtom(openInfoModalAtom);
|
const docInfoModal = useService(DocInfoService).modal;
|
||||||
|
|
||||||
const openHistoryModal = useCallback(() => {
|
const openHistoryModal = useCallback(() => {
|
||||||
setPageHistoryModalState(() => ({
|
setPageHistoryModalState(() => ({
|
||||||
@@ -46,8 +46,8 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
|
|||||||
}, [docId, setPageHistoryModalState]);
|
}, [docId, setPageHistoryModalState]);
|
||||||
|
|
||||||
const openInfoModal = useCallback(() => {
|
const openInfoModal = useCallback(() => {
|
||||||
setInfoModalState(true);
|
docInfoModal.open(docId);
|
||||||
}, [setInfoModalState]);
|
}, [docId, docInfoModal]);
|
||||||
|
|
||||||
const { duplicate } = useBlockSuiteMetaHelper();
|
const { duplicate } = useBlockSuiteMetaHelper();
|
||||||
const exportHandler = useExportPage();
|
const exportHandler = useExportPage();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
import { useBlockSuiteMetaHelper } from '@affine/core/components/hooks/affine/use-block-suite-meta-helper';
|
import { useBlockSuiteMetaHelper } from '@affine/core/components/hooks/affine/use-block-suite-meta-helper';
|
||||||
import { useTrashModalHelper } from '@affine/core/components/hooks/affine/use-trash-modal-helper';
|
import { useTrashModalHelper } from '@affine/core/components/hooks/affine/use-trash-modal-helper';
|
||||||
import { useCatchEventCallback } from '@affine/core/components/hooks/use-catch-event-hook';
|
import { useCatchEventCallback } from '@affine/core/components/hooks/use-catch-event-hook';
|
||||||
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import { FavoriteService } from '@affine/core/modules/favorite';
|
import { FavoriteService } from '@affine/core/modules/favorite';
|
||||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
@@ -32,6 +33,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
FeatureFlagService,
|
FeatureFlagService,
|
||||||
useLiveData,
|
useLiveData,
|
||||||
|
useService,
|
||||||
useServices,
|
useServices,
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
@@ -39,7 +41,6 @@ import type { MouseEvent } from 'react';
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
import type { CollectionService } from '../../modules/collection';
|
import type { CollectionService } from '../../modules/collection';
|
||||||
import { InfoModal } from '../affine/page-properties';
|
|
||||||
import { usePageHelper } from '../blocksuite/block-suite-page-list/utils';
|
import { usePageHelper } from '../blocksuite/block-suite-page-list/utils';
|
||||||
import { IsFavoriteIcon } from '../pure/icons';
|
import { IsFavoriteIcon } from '../pure/icons';
|
||||||
import { FavoriteTag } from './components/favorite-tag';
|
import { FavoriteTag } from './components/favorite-tag';
|
||||||
@@ -86,11 +87,11 @@ export const PageOperationCell = ({
|
|||||||
const { duplicate } = useBlockSuiteMetaHelper();
|
const { duplicate } = useBlockSuiteMetaHelper();
|
||||||
const blocksuiteDoc = currentWorkspace.docCollection.getDoc(page.id);
|
const blocksuiteDoc = currentWorkspace.docCollection.getDoc(page.id);
|
||||||
|
|
||||||
const [openInfoModal, setOpenInfoModal] = useState(false);
|
const docInfoModal = useService(DocInfoService).modal;
|
||||||
const onOpenInfoModal = useCallback(() => {
|
const onOpenInfoModal = useCallback(() => {
|
||||||
track.$.docInfoPanel.$.open();
|
track.$.docInfoPanel.$.open();
|
||||||
setOpenInfoModal(true);
|
docInfoModal.open(blocksuiteDoc?.id);
|
||||||
}, []);
|
}, [blocksuiteDoc?.id, docInfoModal]);
|
||||||
|
|
||||||
const onDisablePublicSharing = useCallback(() => {
|
const onDisablePublicSharing = useCallback(() => {
|
||||||
// TODO(@EYHN): implement disable public sharing
|
// TODO(@EYHN): implement disable public sharing
|
||||||
@@ -214,13 +215,6 @@ export const PageOperationCell = ({
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Menu>
|
</Menu>
|
||||||
</ColWrapper>
|
</ColWrapper>
|
||||||
{blocksuiteDoc ? (
|
|
||||||
<InfoModal
|
|
||||||
open={openInfoModal}
|
|
||||||
onOpenChange={setOpenInfoModal}
|
|
||||||
docId={blocksuiteDoc.id}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { AuthModal } from '../affine/auth';
|
|||||||
import { AiLoginRequiredModal } from '../affine/auth/ai-login-required';
|
import { AiLoginRequiredModal } from '../affine/auth/ai-login-required';
|
||||||
import { HistoryTipsModal } from '../affine/history-tips-modal';
|
import { HistoryTipsModal } from '../affine/history-tips-modal';
|
||||||
import { IssueFeedbackModal } from '../affine/issue-feedback-modal';
|
import { IssueFeedbackModal } from '../affine/issue-feedback-modal';
|
||||||
|
import { InfoModal } from '../affine/page-properties/info-modal/info-modal';
|
||||||
import {
|
import {
|
||||||
CloudQuotaModal,
|
CloudQuotaModal,
|
||||||
LocalQuotaModal,
|
LocalQuotaModal,
|
||||||
@@ -126,6 +127,7 @@ export function CurrentWorkspaceModals() {
|
|||||||
onOpenChange={onTrashConfirmOpenChange}
|
onOpenChange={onTrashConfirmOpenChange}
|
||||||
titles={deletePageTitles}
|
titles={deletePageTitles}
|
||||||
/>
|
/>
|
||||||
|
<InfoModal />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import {
|
|||||||
type InlineEditHandle,
|
type InlineEditHandle,
|
||||||
observeResize,
|
observeResize,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { InfoModal } from '@affine/core/components/affine/page-properties';
|
|
||||||
import { openInfoModalAtom } from '@affine/core/components/atoms';
|
|
||||||
import { FavoriteButton } from '@affine/core/components/blocksuite/block-suite-header/favorite';
|
import { FavoriteButton } from '@affine/core/components/blocksuite/block-suite-header/favorite';
|
||||||
import { InfoButton } from '@affine/core/components/blocksuite/block-suite-header/info';
|
import { InfoButton } from '@affine/core/components/blocksuite/block-suite-header/info';
|
||||||
import { JournalWeekDatePicker } from '@affine/core/components/blocksuite/block-suite-header/journal/date-picker';
|
import { JournalWeekDatePicker } from '@affine/core/components/blocksuite/block-suite-header/journal/date-picker';
|
||||||
@@ -19,7 +17,7 @@ import { EditorService } from '@affine/core/modules/editor';
|
|||||||
import { ViewIcon, ViewTitle } from '@affine/core/modules/workbench';
|
import { ViewIcon, ViewTitle } from '@affine/core/modules/workbench';
|
||||||
import type { Doc } from '@blocksuite/affine/store';
|
import type { Doc } from '@blocksuite/affine/store';
|
||||||
import { useLiveData, useService, type Workspace } from '@toeverything/infra';
|
import { useLiveData, useService, type Workspace } from '@toeverything/infra';
|
||||||
import { useAtom, useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { SharePageButton } from '../../../../components/affine/share-page-modal';
|
import { SharePageButton } from '../../../../components/affine/share-page-modal';
|
||||||
@@ -139,7 +137,7 @@ export function NormalPageHeader({ page, workspace }: PageHeaderProps) {
|
|||||||
{hideCollect ? null : (
|
{hideCollect ? null : (
|
||||||
<>
|
<>
|
||||||
<FavoriteButton pageId={page?.id} />
|
<FavoriteButton pageId={page?.id} />
|
||||||
<InfoButton />
|
<InfoButton docId={page.id} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<PageHeaderMenuButton
|
<PageHeaderMenuButton
|
||||||
@@ -168,25 +166,15 @@ export function DetailPageHeader(props: PageHeaderProps) {
|
|||||||
const { page, workspace } = props;
|
const { page, workspace } = props;
|
||||||
const { isJournal } = useJournalInfoHelper(page.id);
|
const { isJournal } = useJournalInfoHelper(page.id);
|
||||||
const isInTrash = page.meta?.trash;
|
const isInTrash = page.meta?.trash;
|
||||||
const [openInfoModal, setOpenInfoModal] = useAtom(openInfoModalAtom);
|
|
||||||
|
|
||||||
useRegisterCopyLinkCommands({
|
useRegisterCopyLinkCommands({
|
||||||
workspaceMeta: workspace.meta,
|
workspaceMeta: workspace.meta,
|
||||||
docId: page.id,
|
docId: page.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return isJournal && !isInTrash ? (
|
||||||
<>
|
<JournalPageHeader {...props} />
|
||||||
{isJournal && !isInTrash ? (
|
) : (
|
||||||
<JournalPageHeader {...props} />
|
<NormalPageHeader {...props} />
|
||||||
) : (
|
|
||||||
<NormalPageHeader {...props} />
|
|
||||||
)}
|
|
||||||
<InfoModal
|
|
||||||
open={openInfoModal}
|
|
||||||
onOpenChange={setOpenInfoModal}
|
|
||||||
docId={page.id}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { NotificationCenter } from '@affine/component';
|
|||||||
import { AiLoginRequiredModal } from '@affine/core/components/affine/auth/ai-login-required';
|
import { AiLoginRequiredModal } from '@affine/core/components/affine/auth/ai-login-required';
|
||||||
import { HistoryTipsModal } from '@affine/core/components/affine/history-tips-modal';
|
import { HistoryTipsModal } from '@affine/core/components/affine/history-tips-modal';
|
||||||
import { IssueFeedbackModal } from '@affine/core/components/affine/issue-feedback-modal';
|
import { IssueFeedbackModal } from '@affine/core/components/affine/issue-feedback-modal';
|
||||||
|
import { InfoModal } from '@affine/core/components/affine/page-properties/info-modal/info-modal';
|
||||||
import {
|
import {
|
||||||
CloudQuotaModal,
|
CloudQuotaModal,
|
||||||
LocalQuotaModal,
|
LocalQuotaModal,
|
||||||
@@ -57,6 +58,7 @@ export function MobileCurrentWorkspaceModals() {
|
|||||||
onOpenChange={onTrashConfirmOpenChange}
|
onOpenChange={onTrashConfirmOpenChange}
|
||||||
titles={deletePageTitles}
|
titles={deletePageTitles}
|
||||||
/>
|
/>
|
||||||
|
<InfoModal />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Entity, LiveData } from '@toeverything/infra';
|
||||||
|
|
||||||
|
export class DocInfoModal extends Entity {
|
||||||
|
public readonly docId$ = new LiveData<string | null>(null);
|
||||||
|
public readonly open$ = LiveData.computed(get => !!get(this.docId$));
|
||||||
|
|
||||||
|
public open(docId?: string) {
|
||||||
|
if (docId) {
|
||||||
|
this.docId$.next(docId);
|
||||||
|
} else {
|
||||||
|
this.docId$.next(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public close() {
|
||||||
|
this.docId$.next(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onOpenChange(open: boolean) {
|
||||||
|
if (!open) this.docId$.next(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
packages/frontend/core/src/modules/doc-info/index.ts
Normal file
10
packages/frontend/core/src/modules/doc-info/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { type Framework, WorkspaceScope } from '@toeverything/infra';
|
||||||
|
|
||||||
|
import { DocInfoModal } from './entities/modal';
|
||||||
|
import { DocInfoService } from './services/doc-info';
|
||||||
|
|
||||||
|
export { DocInfoService };
|
||||||
|
|
||||||
|
export function configureDocInfoModule(framework: Framework) {
|
||||||
|
framework.scope(WorkspaceScope).service(DocInfoService).entity(DocInfoModal);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { Service } from '@toeverything/infra';
|
||||||
|
|
||||||
|
import { DocInfoModal } from '../entities/modal';
|
||||||
|
|
||||||
|
export class DocInfoService extends Service {
|
||||||
|
public readonly modal = this.framework.createEntity(DocInfoModal);
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ import {
|
|||||||
toast,
|
toast,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { InfoModal } from '@affine/core/components/affine/page-properties';
|
|
||||||
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
|
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
|
||||||
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
||||||
|
import { DocInfoService } from '@affine/core/modules/doc-info';
|
||||||
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
||||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
GlobalContextService,
|
GlobalContextService,
|
||||||
LiveData,
|
LiveData,
|
||||||
useLiveData,
|
useLiveData,
|
||||||
|
useService,
|
||||||
useServices,
|
useServices,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
@@ -175,15 +176,15 @@ export const ExplorerDocNode = ({
|
|||||||
[canDrop]
|
[canDrop]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [enableInfoModal, setEnableInfoModal] = useState(false);
|
const docInfoModal = useService(DocInfoService).modal;
|
||||||
const operations = useExplorerDocNodeOperations(
|
const operations = useExplorerDocNodeOperations(
|
||||||
docId,
|
docId,
|
||||||
useMemo(
|
useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
openInfoModal: () => setEnableInfoModal(true),
|
openInfoModal: () => docInfoModal.open(docId),
|
||||||
openNodeCollapsed: () => setCollapsed(false),
|
openNodeCollapsed: () => setCollapsed(false),
|
||||||
}),
|
}),
|
||||||
[]
|
[docId, docInfoModal]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -199,57 +200,48 @@ export const ExplorerDocNode = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<ExplorerTreeNode
|
||||||
<ExplorerTreeNode
|
icon={Icon}
|
||||||
icon={Icon}
|
name={typeof docTitle === 'string' ? docTitle : t[docTitle.key]()}
|
||||||
name={typeof docTitle === 'string' ? docTitle : t[docTitle.key]()}
|
dndData={dndData}
|
||||||
dndData={dndData}
|
onDrop={handleDropOnDoc}
|
||||||
onDrop={handleDropOnDoc}
|
renameable
|
||||||
renameable
|
collapsed={collapsed}
|
||||||
collapsed={collapsed}
|
setCollapsed={setCollapsed}
|
||||||
setCollapsed={setCollapsed}
|
canDrop={handleCanDrop}
|
||||||
canDrop={handleCanDrop}
|
to={`/${docId}`}
|
||||||
to={`/${docId}`}
|
active={active}
|
||||||
active={active}
|
postfix={
|
||||||
postfix={
|
referencesLoading &&
|
||||||
referencesLoading &&
|
!collapsed && (
|
||||||
!collapsed && (
|
<Tooltip
|
||||||
<Tooltip
|
content={t['com.affine.rootAppSidebar.docs.references-loading']()}
|
||||||
content={t['com.affine.rootAppSidebar.docs.references-loading']()}
|
>
|
||||||
>
|
<div className={styles.loadingIcon}>
|
||||||
<div className={styles.loadingIcon}>
|
<Loading />
|
||||||
<Loading />
|
</div>
|
||||||
</div>
|
</Tooltip>
|
||||||
</Tooltip>
|
)
|
||||||
)
|
}
|
||||||
}
|
reorderable={reorderable}
|
||||||
reorderable={reorderable}
|
onRename={handleRename}
|
||||||
onRename={handleRename}
|
childrenPlaceholder={<Empty onDrop={handleDropOnPlaceholder} />}
|
||||||
childrenPlaceholder={<Empty onDrop={handleDropOnPlaceholder} />}
|
operations={finalOperations}
|
||||||
operations={finalOperations}
|
dropEffect={handleDropEffectOnDoc}
|
||||||
dropEffect={handleDropEffectOnDoc}
|
data-testid={`explorer-doc-${docId}`}
|
||||||
data-testid={`explorer-doc-${docId}`}
|
>
|
||||||
>
|
{children?.map(child => (
|
||||||
{children?.map(child => (
|
<ExplorerDocNode
|
||||||
<ExplorerDocNode
|
key={child.docId}
|
||||||
key={child.docId}
|
docId={child.docId}
|
||||||
docId={child.docId}
|
reorderable={false}
|
||||||
reorderable={false}
|
location={{
|
||||||
location={{
|
at: 'explorer:doc:linked-docs',
|
||||||
at: 'explorer:doc:linked-docs',
|
docId,
|
||||||
docId,
|
}}
|
||||||
}}
|
isLinked
|
||||||
isLinked
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</ExplorerTreeNode>
|
|
||||||
{enableInfoModal && (
|
|
||||||
<InfoModal
|
|
||||||
open={enableInfoModal}
|
|
||||||
onOpenChange={setEnableInfoModal}
|
|
||||||
docId={docId}
|
|
||||||
/>
|
/>
|
||||||
)}
|
))}
|
||||||
</>
|
</ExplorerTreeNode>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { configureCloudModule } from './cloud';
|
|||||||
import { configureCollectionModule } from './collection';
|
import { configureCollectionModule } from './collection';
|
||||||
import { configureCreateWorkspaceModule } from './create-workspace';
|
import { configureCreateWorkspaceModule } from './create-workspace';
|
||||||
import { configureDocDisplayMetaModule } from './doc-display-meta';
|
import { configureDocDisplayMetaModule } from './doc-display-meta';
|
||||||
|
import { configureDocInfoModule } from './doc-info';
|
||||||
import { configureDocLinksModule } from './doc-link';
|
import { configureDocLinksModule } from './doc-link';
|
||||||
import { configureDocsSearchModule } from './docs-search';
|
import { configureDocsSearchModule } from './docs-search';
|
||||||
import { configureEditorModule } from './editor';
|
import { configureEditorModule } from './editor';
|
||||||
@@ -55,4 +56,5 @@ export function configureCommonModules(framework: Framework) {
|
|||||||
configureImportTemplateModule(framework);
|
configureImportTemplateModule(framework);
|
||||||
configureCreateWorkspaceModule(framework);
|
configureCreateWorkspaceModule(framework);
|
||||||
configureUserspaceModule(framework);
|
configureUserspaceModule(framework);
|
||||||
|
configureDocInfoModule(framework);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user