feat(core): add outgoing links to doc info (#7955)

close AF-1270

![CleanShot 2024-08-23 at 13 22 38@2x](https://github.com/user-attachments/assets/7eb21db5-ab33-41ad-a51a-fd2cf46a0e30)
This commit is contained in:
JimmFly 2024-08-29 06:41:41 +00:00
parent 3ce92f2abc
commit 5e8683c9be
No known key found for this signature in database
GPG Key ID: 126E0320FEB0D05C
8 changed files with 52 additions and 31 deletions

View File

@ -5,6 +5,7 @@ import {
Scrollable,
} from '@affine/component';
import { DocsSearchService } from '@affine/core/modules/docs-search';
import { useI18n } from '@affine/i18n';
import { LiveData, useLiveData, useServices } from '@toeverything/infra';
import { Suspense, useCallback, useContext, useMemo, useRef } from 'react';
@ -16,8 +17,8 @@ import {
SortableProperties,
usePagePropertiesManager,
} from '../table';
import { BackLinksRow } from './back-links-row';
import * as styles from './info-modal.css';
import { LinksRow } from './links-row';
import { TagsRow } from './tags-row';
import { TimeRow } from './time-row';
@ -30,22 +31,12 @@ export const InfoModal = ({
onOpenChange: (open: boolean) => void;
docId: string;
}) => {
const { docsSearchService } = useServices({
DocsSearchService,
});
const titleInputHandleRef = useRef<InlineEditHandle>(null);
const manager = usePagePropertiesManager(docId);
const handleClose = useCallback(() => {
onOpenChange(false);
}, [onOpenChange]);
const references = useLiveData(
useMemo(
() => LiveData.from(docsSearchService.watchRefsFrom(docId), null),
[docId, docsSearchService]
)
);
if (!manager.page || manager.readonly) {
return null;
}
@ -76,7 +67,6 @@ export const InfoModal = ({
<InfoTable
docId={docId}
onClose={handleClose}
references={references}
readonly={manager.readonly}
/>
</Suspense>
@ -90,29 +80,52 @@ export const InfoModal = ({
const InfoTable = ({
onClose,
references,
docId,
readonly,
}: {
docId: string;
onClose: () => void;
readonly: boolean;
references:
| {
docId: string;
title: string;
}[]
| null;
}) => {
const t = useI18n();
const manager = useContext(managerContext);
const { docsSearchService } = useServices({
DocsSearchService,
});
const links = useLiveData(
useMemo(
() => LiveData.from(docsSearchService.watchRefsFrom(docId), null),
[docId, docsSearchService]
)
);
const backlinks = useLiveData(
useMemo(
() => LiveData.from(docsSearchService.watchRefsTo(docId), null),
[docId, docsSearchService]
)
);
return (
<div>
<TimeRow docId={docId} />
<Divider size="thinner" />
{references && references.length > 0 ? (
{backlinks && backlinks.length > 0 ? (
<>
<BackLinksRow references={references} onClick={onClose} />
<LinksRow
references={backlinks}
onClick={onClose}
label={t['com.affine.page-properties.backlinks']()}
/>
<Divider size="thinner" />
</>
) : null}
{links && links.length > 0 ? (
<>
<LinksRow
references={links}
onClick={onClose}
label={t['com.affine.page-properties.outgoing-links']()}
/>
<Divider size="thinner" />
</>
) : null}

View File

@ -1,22 +1,24 @@
import { useI18n } from '@affine/i18n';
import type { Backlink, Link } from '@affine/core/modules/doc-link';
import { useContext } from 'react';
import { AffinePageReference } from '../../reference-link';
import { managerContext } from '../common';
import * as styles from './back-links-row.css';
export const BackLinksRow = ({
import * as styles from './links-row.css';
export const LinksRow = ({
references,
label,
onClick,
}: {
references: { docId: string; title: string }[];
references: Backlink[] | Link[];
label: string;
onClick?: () => void;
}) => {
const manager = useContext(managerContext);
const t = useI18n();
return (
<div>
<div className={styles.title}>
{t['com.affine.page-properties.backlinks']()} · {references.length}
{label} · {references.length}
</div>
{references.map(link => (
<AffinePageReference

View File

@ -1,4 +1,5 @@
import { DocLinksService } from '@affine/core/modules/doc-link';
import { useI18n } from '@affine/i18n';
import {
useLiveData,
useServices,
@ -15,6 +16,7 @@ export const BiDirectionalLinkPanel = () => {
DocLinksService,
WorkspaceService,
});
const t = useI18n();
const links = useLiveData(docLinksService.links.links$);
const backlinks = useLiveData(docLinksService.backlinks.backlinks$);
@ -44,7 +46,7 @@ export const BiDirectionalLinkPanel = () => {
</div>
<div className={styles.linksContainer}>
<div className={styles.linksTitles}>
Backlinks · {backlinks.length}
{t['com.affine.page-properties.backlinks']()} · {backlinks.length}
</div>
{backlinks.map(link => (
<div key={link.docId} className={styles.link}>
@ -58,7 +60,8 @@ export const BiDirectionalLinkPanel = () => {
</div>
<div className={styles.linksContainer}>
<div className={styles.linksTitles}>
Outgoing links · {links.length}
{t['com.affine.page-properties.outgoing-links']()} ·{' '}
{links.length}
</div>
{links.map(link => (
<div key={link.docId} className={styles.link}>

View File

@ -3,7 +3,7 @@ import { Entity, LiveData } from '@toeverything/infra';
import type { DocsSearchService } from '../../docs-search';
interface Backlink {
export interface Backlink {
docId: string;
blockId: string;
title: string;

View File

@ -3,7 +3,7 @@ import { Entity, LiveData } from '@toeverything/infra';
import type { DocsSearchService } from '../../docs-search';
interface Link {
export interface Link {
docId: string;
title: string;
}

View File

@ -10,6 +10,8 @@ import { DocBacklinks } from './entities/doc-backlinks';
import { DocLinks } from './entities/doc-links';
import { DocLinksService } from './services/doc-links';
export type { Backlink } from './entities/doc-backlinks';
export type { Link } from './entities/doc-links';
export { DocLinksService } from './services/doc-links';
export function configureDocLinksModule(framework: Framework) {

View File

@ -851,6 +851,7 @@
"com.affine.page-properties.add-property.menu.create": "Create property",
"com.affine.page-properties.add-property.menu.header": "Properties",
"com.affine.page-properties.backlinks": "Backlinks",
"com.affine.page-properties.outgoing-links": "Outgoing links",
"com.affine.page-properties.create-property.menu.header": "Type",
"com.affine.page-properties.icons": "Icons",
"com.affine.page-properties.page-info": "Info",