Commit 9a3451b9 authored by Johnny's avatar Johnny

fix(editor): filter RelationList to only show referencing memos

- Filter out COMMENT type relations, only show REFERENCE type
- When editing a memo, only show relations where current memo is the source
- Pass memoName through EditorMetadata to RelationList for filtering
parent 7053edae
...@@ -5,7 +5,7 @@ import AttachmentList from "./AttachmentList"; ...@@ -5,7 +5,7 @@ import AttachmentList from "./AttachmentList";
import LocationDisplay from "./LocationDisplay"; import LocationDisplay from "./LocationDisplay";
import RelationList from "./RelationList"; import RelationList from "./RelationList";
export const EditorMetadata: FC<EditorMetadataProps> = () => { export const EditorMetadata: FC<EditorMetadataProps> = ({ memoName }) => {
const { state, actions, dispatch } = useEditorContext(); const { state, actions, dispatch } = useEditorContext();
return ( return (
...@@ -17,7 +17,11 @@ export const EditorMetadata: FC<EditorMetadataProps> = () => { ...@@ -17,7 +17,11 @@ export const EditorMetadata: FC<EditorMetadataProps> = () => {
onRemoveLocalFile={(previewUrl) => dispatch(actions.removeLocalFile(previewUrl))} onRemoveLocalFile={(previewUrl) => dispatch(actions.removeLocalFile(previewUrl))}
/> />
<RelationList relations={state.metadata.relations} onRelationsChange={(relations) => dispatch(actions.setMetadata({ relations }))} /> <RelationList
relations={state.metadata.relations}
onRelationsChange={(relations) => dispatch(actions.setMetadata({ relations }))}
memoName={memoName}
/>
{state.metadata.location && ( {state.metadata.location && (
<LocationDisplay location={state.metadata.location} onRemove={() => dispatch(actions.setMetadata({ location: undefined }))} /> <LocationDisplay location={state.metadata.location} onRemove={() => dispatch(actions.setMetadata({ location: undefined }))} />
......
...@@ -5,12 +5,13 @@ import { useEffect, useState } from "react"; ...@@ -5,12 +5,13 @@ import { useEffect, useState } from "react";
import RelationCard from "@/components/MemoView/components/metadata/RelationCard"; import RelationCard from "@/components/MemoView/components/metadata/RelationCard";
import { memoServiceClient } from "@/connect"; import { memoServiceClient } from "@/connect";
import type { MemoRelation } from "@/types/proto/api/v1/memo_service_pb"; import type { MemoRelation } from "@/types/proto/api/v1/memo_service_pb";
import { MemoRelation_Memo, MemoRelation_MemoSchema } from "@/types/proto/api/v1/memo_service_pb"; import { MemoRelation_Memo, MemoRelation_MemoSchema, MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
interface RelationListProps { interface RelationListProps {
relations: MemoRelation[]; relations: MemoRelation[];
onRelationsChange?: (relations: MemoRelation[]) => void; onRelationsChange?: (relations: MemoRelation[]) => void;
parentPage?: string; parentPage?: string;
memoName?: string;
} }
const RelationItemCard: FC<{ const RelationItemCard: FC<{
...@@ -37,12 +38,13 @@ const RelationItemCard: FC<{ ...@@ -37,12 +38,13 @@ const RelationItemCard: FC<{
); );
}; };
const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, parentPage }) => { const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, parentPage, memoName }) => {
const referenceRelations = relations.filter((r) => r.type === MemoRelation_Type.REFERENCE && (!memoName || r.memo?.name === memoName));
const [fetchedMemos, setFetchedMemos] = useState<Record<string, MemoRelation_Memo>>({}); const [fetchedMemos, setFetchedMemos] = useState<Record<string, MemoRelation_Memo>>({});
useEffect(() => { useEffect(() => {
(async () => { (async () => {
const missingSnippetRelations = relations.filter((relation) => !relation.relatedMemo?.snippet && relation.relatedMemo?.name); const missingSnippetRelations = referenceRelations.filter((relation) => !relation.relatedMemo?.snippet && relation.relatedMemo?.name);
if (missingSnippetRelations.length > 0) { if (missingSnippetRelations.length > 0) {
const requests = missingSnippetRelations.map(async (relation) => { const requests = missingSnippetRelations.map(async (relation) => {
const memo = await memoServiceClient.getMemo({ name: relation.relatedMemo!.name }); const memo = await memoServiceClient.getMemo({ name: relation.relatedMemo!.name });
...@@ -58,7 +60,7 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par ...@@ -58,7 +60,7 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par
}); });
} }
})(); })();
}, [relations]); }, [referenceRelations]);
const handleDeleteRelation = (memoName: string) => { const handleDeleteRelation = (memoName: string) => {
if (onRelationsChange) { if (onRelationsChange) {
...@@ -66,7 +68,7 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par ...@@ -66,7 +68,7 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par
} }
}; };
if (relations.length === 0) { if (referenceRelations.length === 0) {
return null; return null;
} }
...@@ -74,11 +76,11 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par ...@@ -74,11 +76,11 @@ const RelationList: FC<RelationListProps> = ({ relations, onRelationsChange, par
<div className="w-full rounded-lg border border-border bg-muted/20 overflow-hidden"> <div className="w-full rounded-lg border border-border bg-muted/20 overflow-hidden">
<div className="flex items-center gap-1.5 px-2 py-1.5 border-b border-border bg-muted/30"> <div className="flex items-center gap-1.5 px-2 py-1.5 border-b border-border bg-muted/30">
<LinkIcon className="w-3.5 h-3.5 text-muted-foreground" /> <LinkIcon className="w-3.5 h-3.5 text-muted-foreground" />
<span className="text-xs font-medium text-muted-foreground">Relations ({relations.length})</span> <span className="text-xs font-medium text-muted-foreground">Relations ({referenceRelations.length})</span>
</div> </div>
<div className="p-1 sm:p-1.5 flex flex-col gap-0.5"> <div className="p-1 sm:p-1.5 flex flex-col gap-0.5">
{relations.map((relation) => { {referenceRelations.map((relation) => {
const relatedMemo = relation.relatedMemo!; const relatedMemo = relation.relatedMemo!;
const memo = relatedMemo.snippet ? relatedMemo : fetchedMemos[relatedMemo.name] || relatedMemo; const memo = relatedMemo.snippet ? relatedMemo : fetchedMemos[relatedMemo.name] || relatedMemo;
return <RelationItemCard key={memo.name} memo={memo} onRemove={() => handleDeleteRelation(memo.name)} parentPage={parentPage} />; return <RelationItemCard key={memo.name} memo={memo} onRemove={() => handleDeleteRelation(memo.name)} parentPage={parentPage} />;
......
...@@ -146,7 +146,7 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({ ...@@ -146,7 +146,7 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({
{/* Metadata and toolbar grouped together at bottom */} {/* Metadata and toolbar grouped together at bottom */}
<div className="w-full flex flex-col gap-2"> <div className="w-full flex flex-col gap-2">
<EditorMetadata /> <EditorMetadata memoName={memoName} />
<EditorToolbar onSave={handleSave} onCancel={onCancel} memoName={memoName} /> <EditorToolbar onSave={handleSave} onCancel={onCancel} memoName={memoName} />
</div> </div>
</div> </div>
......
...@@ -26,7 +26,9 @@ export interface EditorToolbarProps { ...@@ -26,7 +26,9 @@ export interface EditorToolbarProps {
memoName?: string; memoName?: string;
} }
export interface EditorMetadataProps {} export interface EditorMetadataProps {
memoName?: string;
}
export interface FocusModeOverlayProps { export interface FocusModeOverlayProps {
isActive: boolean; isActive: boolean;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment