mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-02 16:57:07 +03:00
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:
parent
3ce92f2abc
commit
5e8683c9be
@ -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}
|
||||
|
@ -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
|
@ -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}>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user