From d2b421213f40df91ae214bdb5c38bcc8529e9477 Mon Sep 17 00:00:00 2001 From: Johnny Date: Sat, 3 Jan 2026 14:27:12 +0800 Subject: [PATCH] chore: optimize RelationList and unify RelationCard usage --- .../MemoEditor/components/RelationList.tsx | 100 +++++++----------- .../components/metadata/SectionHeader.tsx | 4 +- .../StatisticsView/StatisticsView.tsx | 2 +- 3 files changed, 40 insertions(+), 66 deletions(-) diff --git a/web/src/components/MemoEditor/components/RelationList.tsx b/web/src/components/MemoEditor/components/RelationList.tsx index 0d33bc8ff..c7f4ef920 100644 --- a/web/src/components/MemoEditor/components/RelationList.tsx +++ b/web/src/components/MemoEditor/components/RelationList.tsx @@ -2,12 +2,10 @@ import { create } from "@bufbuild/protobuf"; import { LinkIcon, XIcon } from "lucide-react"; import type { FC } from "react"; import { useEffect, useState } from "react"; -import { Link } from "react-router-dom"; +import RelationCard from "@/components/MemoView/components/metadata/RelationCard"; import { memoServiceClient } from "@/connect"; -import { extractMemoIdFromName } from "@/helpers/resource-names"; -import { cn } from "@/lib/utils"; -import type { Memo, MemoRelation } from "@/types/proto/api/v1/memo_service_pb"; -import { MemoRelation_MemoSchema } 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"; interface RelationListProps { relations: MemoRelation[]; @@ -20,65 +18,44 @@ const RelationItemCard: FC<{ onRemove?: () => void; parentPage?: string; }> = ({ memo, onRemove, parentPage }) => { - const memoId = extractMemoIdFromName(memo!.name); - - if (onRemove) { - return ( -
- - - {memo!.snippet} - - -
- -
-
- ); - } - return ( - + + + {onRemove && ( + )} - to={`/${memo!.name}`} - viewTransition - state={{ from: parentPage }} - > - {memoId.slice(0, 6)} - - {memo!.snippet} - - + ); }; const RelationList: FC = ({ relations, onRelationsChange, parentPage }) => { - const [referencingMemos, setReferencingMemos] = useState([]); + const [fetchedMemos, setFetchedMemos] = useState>({}); useEffect(() => { (async () => { - if (relations.length > 0) { - const requests = relations.map(async (relation) => { - return await memoServiceClient.getMemo({ name: relation.relatedMemo!.name }); + const missingSnippetRelations = relations.filter((relation) => !relation.relatedMemo?.snippet && relation.relatedMemo?.name); + if (missingSnippetRelations.length > 0) { + const requests = missingSnippetRelations.map(async (relation) => { + const memo = await memoServiceClient.getMemo({ name: relation.relatedMemo!.name }); + return create(MemoRelation_MemoSchema, { name: memo.name, snippet: memo.snippet }); }); const list = await Promise.all(requests); - setReferencingMemos(list); - } else { - setReferencingMemos([]); + setFetchedMemos((prev) => { + const next = { ...prev }; + for (const memo of list) { + next[memo.name] = memo; + } + return next; + }); } })(); }, [relations]); @@ -89,7 +66,7 @@ const RelationList: FC = ({ relations, onRelationsChange, par } }; - if (referencingMemos.length === 0) { + if (relations.length === 0) { return null; } @@ -97,18 +74,15 @@ const RelationList: FC = ({ relations, onRelationsChange, par
- Relations ({referencingMemos.length}) + Relations ({relations.length})
- {referencingMemos.map((memo) => ( - handleDeleteRelation(memo.name)} - parentPage={parentPage} - /> - ))} + {relations.map((relation) => { + const relatedMemo = relation.relatedMemo!; + const memo = relatedMemo.snippet ? relatedMemo : fetchedMemos[relatedMemo.name] || relatedMemo; + return handleDeleteRelation(memo.name)} parentPage={parentPage} />; + })}
); diff --git a/web/src/components/MemoView/components/metadata/SectionHeader.tsx b/web/src/components/MemoView/components/metadata/SectionHeader.tsx index 11e153232..3c479494e 100644 --- a/web/src/components/MemoView/components/metadata/SectionHeader.tsx +++ b/web/src/components/MemoView/components/metadata/SectionHeader.tsx @@ -30,9 +30,9 @@ const SectionHeader = ({ icon: Icon, title, count, tabs }: SectionHeaderProps) = tab.active ? "text-foreground" : "text-muted-foreground hover:text-foreground", )} > - {tab.label}({tab.count}) + {tab.label} ({tab.count}) - {idx < tabs.length - 1 && /} + {idx < tabs.length - 1 && /} ))} diff --git a/web/src/components/StatisticsView/StatisticsView.tsx b/web/src/components/StatisticsView/StatisticsView.tsx index 91db83014..62e135186 100644 --- a/web/src/components/StatisticsView/StatisticsView.tsx +++ b/web/src/components/StatisticsView/StatisticsView.tsx @@ -21,7 +21,7 @@ const StatisticsView = (props: Props) => { }, [activityStats]); return ( -
+