From 33a866b65990cc9d8141b0ca20345dea04c6bc18 Mon Sep 17 00:00:00 2001 From: taDuc Date: Wed, 13 May 2026 02:40:48 +0700 Subject: [PATCH] add new list view for ent - wiki --- src/app/editor/[id]/page.tsx | 44 +----- src/uhm/components/Editor.tsx | 18 --- .../editor/EntityWikiBindingsPanel.tsx | 141 +++++++++++++++++- src/uhm/components/editor/SessionPanel.tsx | 62 -------- 4 files changed, 142 insertions(+), 123 deletions(-) delete mode 100644 src/uhm/components/editor/SessionPanel.tsx diff --git a/src/app/editor/[id]/page.tsx b/src/app/editor/[id]/page.tsx index 21a2f9a..9683aa1 100644 --- a/src/app/editor/[id]/page.tsx +++ b/src/app/editor/[id]/page.tsx @@ -280,8 +280,13 @@ export default function Page() { const ids = new Set(); for (const ref of snapshotEntitiesVisible) ids.add(String(ref.id)); const rows = Array.from(ids).map((id) => { + const ref = snapshotEntitiesVisible.find((entity) => String(entity.id) === id) || null; const found = entities.find((e) => e.id === id) || null; - return { id, name: found?.name || id }; + return { + id, + name: found?.name || id, + isNew: ref?.source === "inline" && ref?.operation === "create", + }; }); rows.sort((a, b) => a.name.localeCompare(b.name)); return rows; @@ -328,41 +333,6 @@ export default function Page() { return normalizeFeatureBindingIds(selectedFeature); }, [selectedFeature]); - const createdEntities = useMemo(() => { - return (snapshotEntities || []) - .filter((e) => e && e.source === "inline" && e.operation === "create") - .map((e) => ({ - id: String(e.id || ""), - name: String(e.name || "").trim() || String(e.id || ""), - })) - .filter((e) => e.id.length > 0 && e.name.length > 0); - }, [snapshotEntities]); - - const createdGeometries = useMemo(() => { - const rows: Array<{ - id: string | number; - geometryType: string; - semanticType?: string | null; - entityNames: string[]; - }> = []; - - for (const change of editor.changes.values()) { - if (change.action !== "create") continue; - const feature = change.feature; - const entityNames = normalizeFeatureEntityIds(feature) - .map((entityId) => entities.find((entity) => entity.id === entityId)?.name || entityId); - - rows.push({ - id: feature.properties.id, - geometryType: feature.geometry.type, - semanticType: feature.properties.type || getDefaultTypeIdForFeature(feature), - entityNames, - }); - } - - return rows; - }, [editor.changes, entities]); - const wikiDirty = useMemo(() => { const prev = normalizeWikisForCompare(baselineSnapshot?.wikis); const next = normalizeWikisForCompare(snapshotWikis); @@ -1274,8 +1244,6 @@ export default function Page() { commits={sectionCommits} changesCount={pendingSaveCount} undoStack={editor.undoStack} - createdEntities={createdEntities} - createdGeometries={createdGeometries} width={leftPanelWidth} /> diff --git a/src/uhm/components/Editor.tsx b/src/uhm/components/Editor.tsx index df67197..c724149 100644 --- a/src/uhm/components/Editor.tsx +++ b/src/uhm/components/Editor.tsx @@ -9,7 +9,6 @@ import { ToolsPanel } from "./editor/ToolsPanel"; import { CommitPanel } from "./editor/CommitPanel"; import { CommitHistoryPanel } from "./editor/CommitHistoryPanel"; import { UndoListPanel } from "./editor/UndoListPanel"; -import { SessionPanel } from "./editor/SessionPanel"; import { SubmitModal } from "./editor/SubmitModal"; type Props = { @@ -38,16 +37,6 @@ type Props = { }>; changesCount: number; undoStack: UndoAction[]; - createdEntities: Array<{ - id: string; - name: string; - }>; - createdGeometries: Array<{ - id: string | number; - geometryType: string; - semanticType?: string | null; - entityNames: string[]; - }>; width?: number; }; @@ -72,8 +61,6 @@ export default function Editor({ commits, changesCount, undoStack, - createdEntities, - createdGeometries, width = 280, }: Props) { const [isSubmitModalOpen, setIsSubmitModalOpen] = useState(false); @@ -159,11 +146,6 @@ export default function Editor({ - - (wikis || []) .filter((w) => w && typeof w.id === "string" && w.id.trim().length > 0) - .map((w) => ({ id: w.id, title: wikiTitle(w) })), + .map((w) => ({ + id: w.id, + title: wikiTitle(w), + isNew: w.source === "inline" && w.operation === "create", + })), [wikis] ); @@ -48,6 +62,41 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin return set; }, [activeEntityId, links]); + const activeBindingRows = useMemo(() => { + const byKey = new Map(); + for (const link of links || []) { + const entityId = String(link?.entity_id || "").trim(); + const wikiId = String(link?.wiki_id || "").trim(); + if (!entityId || !wikiId) continue; + if (link.operation === "delete") continue; + byKey.set(`${entityId}::${wikiId}`, link); + } + + const rows = Array.from(byKey.values()).map((link) => { + const entityId = String(link.entity_id); + const wikiId = String(link.wiki_id); + const entity = entityChoices.find((item) => item.id === entityId) || null; + const wiki = wikiChoices.find((item) => item.id === wikiId) || null; + return { + entityId, + entityName: entity?.name || entityId, + entityIsNew: Boolean(entity?.isNew), + wikiId, + wikiTitle: wiki?.title || wikiId, + wikiIsNew: Boolean(wiki?.isNew), + linkIsNew: link.operation === "binding", + }; + }); + + rows.sort((a, b) => { + if (a.linkIsNew !== b.linkIsNew) return a.linkIsNew ? -1 : 1; + const entityCompare = a.entityName.localeCompare(b.entityName); + if (entityCompare !== 0) return entityCompare; + return a.wikiTitle.localeCompare(b.wikiTitle); + }); + return rows; + }, [entityChoices, links, wikiChoices]); + const toggle = (wikiId: string) => { if (!activeEntityId) return; const id = String(wikiId || "").trim(); @@ -69,6 +118,7 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin const activeWikiLinked = activeEntityId && activeWikiId ? activeLinks.has(activeWikiId) : false; const activeWikiChoice = activeWikiId ? wikiChoices.find((w) => w.id === activeWikiId) || null : null; + const activeEntityChoice = activeEntityId ? entityChoices.find((e) => e.id === activeEntityId) || null : null; return (
Entity ↔ Wiki
-
{links.length}
+
{activeBindingRows.length}
@@ -173,6 +224,7 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin ) : null} @@ -275,6 +327,82 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin )}
+ +
+
+ All bindings ({activeBindingRows.length}) +
+ {activeBindingRows.length ? ( +
+ {activeBindingRows.map((row) => ( +
+
+ + {row.entityName} + + {row.entityIsNew ? : null} + {row.linkIsNew ? : null} +
+
+ Wiki + + {row.wikiTitle} + + {row.wikiIsNew ? : null} +
+
+ {row.entityId} ↔ {row.wikiId} +
+
+ ))} +
+ ) : ( +
No entity-wiki binding yet.
+ )} +
)} @@ -284,9 +412,11 @@ export default function EntityWikiBindingsPanel({ entities, wikis, links, setLin function ActiveSelectionLabel({ label, id, + isNew, }: { label: string; id: string; + isNew?: boolean; }) { return (
@@ -296,6 +426,7 @@ function ActiveSelectionLabel({ {id} + {isNew ? : null}
); } diff --git a/src/uhm/components/editor/SessionPanel.tsx b/src/uhm/components/editor/SessionPanel.tsx deleted file mode 100644 index 197b298..0000000 --- a/src/uhm/components/editor/SessionPanel.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { Panel } from "./Panel"; - -type SessionPanelProps = { - createdEntities: Array<{ - id: string; - name: string; - }>; - createdGeometries: Array<{ - id: string | number; - geometryType: string; - semanticType?: string | null; - entityNames: string[]; - }>; -}; - -export function SessionPanel({ - createdEntities, - createdGeometries, -}: SessionPanelProps) { - return ( - -
- Entities ({createdEntities.length}) -
- {createdEntities.length === 0 ? ( -
Chưa tạo entity mới
- ) : ( -
    - {createdEntities.map((entity) => ( -
  • - {entity.name} -
  • - ))} -
- )} - -
- Geometries mới chưa commit ({createdGeometries.length}) -
- {createdGeometries.length === 0 ? ( -
Chưa có geometry mới chờ commit
- ) : ( -
    - {createdGeometries.map((geometry) => ( -
  • - #{geometry.id} [{geometry.geometryType}]{" "} - {geometry.semanticType ? `- ${geometry.semanticType}` : ""} - {geometry.entityNames.length ? ` | ${geometry.entityNames.join(", ")}` : ""} -
  • - ))} -
- )} -
- ); -}