fix: read map POIs from authenticated FalkorDB
This commit is contained in:
1 parent
90f75d41ae
commit
712ca1418c
7 files changed
+646
-206
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Card, Statistic, Row, Col, Space, Table, Tag } from "antd";
|
||||
import {
|
||||
ApartmentOutlined, HistoryOutlined, NodeIndexOutlined,
|
||||
@@ -11,12 +11,11 @@ import {
|
||||
graphQuery,
|
||||
listProjects,
|
||||
plazaOverview,
|
||||
superAgentCoverage,
|
||||
type KgProjectContext,
|
||||
type ProjectSummary,
|
||||
type SpatialMapConfig,
|
||||
} from "../../api";
|
||||
import { KnowledgeMap, type CoverageSnapshot } from "./SuperAgentPanel";
|
||||
import { KnowledgeMap } from "./SuperAgentPanel";
|
||||
import {
|
||||
buildGenericGraphCategories,
|
||||
resolveOverviewCategoryView,
|
||||
@@ -132,14 +131,15 @@ export default function PlazaOverview() {
|
||||
const [graphData, setGraphData] = useState<Record<string, unknown>>({});
|
||||
const [graphCategories, setGraphCategories] = useState<EntityCategory[]>([]);
|
||||
const [graphCategoriesLoading, setGraphCategoriesLoading] = useState(true);
|
||||
const [mapCoverage, setMapCoverage] = useState<CoverageSnapshot | null>(null);
|
||||
const [projectContext, setProjectContextState] = useState<KgProjectContext>(getProjectContext());
|
||||
const [projectSummary, setProjectSummary] = useState<ProjectSummary | null>(null);
|
||||
const [spatialMap, setSpatialMap] = useState<SpatialMapConfig>(() => (
|
||||
resolveSpatialMap(null, getProjectContext())
|
||||
));
|
||||
const fetchSequence = useRef(0);
|
||||
|
||||
const fetch = async () => {
|
||||
const sequence = ++fetchSequence.current;
|
||||
setGraphCategoriesLoading(true);
|
||||
const currentContext = getProjectContext();
|
||||
try {
|
||||
@@ -148,6 +148,7 @@ export default function PlazaOverview() {
|
||||
graphOverview(),
|
||||
listProjects(),
|
||||
]);
|
||||
if (sequence !== fetchSequence.current) return;
|
||||
const plazaData = plazaResult.status === "fulfilled"
|
||||
? plazaResult.value.data as Record<string, unknown>
|
||||
: {};
|
||||
@@ -163,9 +164,7 @@ export default function PlazaOverview() {
|
||||
const placeTypeRows = isKnowledgeMapProject && currentGraphData.connected === true
|
||||
? await graphQuery(GRAPH_CATEGORY_CYPHER).then((res) => res.data.rows || []).catch(() => [])
|
||||
: [];
|
||||
const coverage = currentContext.graphName === DEFAULT_PROJECT_CONTEXT.graphName
|
||||
? await superAgentCoverage().then((res) => res.data).catch(() => null)
|
||||
: null;
|
||||
if (sequence !== fetchSequence.current) return;
|
||||
setProjectContextState(currentContext);
|
||||
setProjectSummary(currentProject);
|
||||
setSpatialMap(currentSpatialMap);
|
||||
@@ -176,9 +175,8 @@ export default function PlazaOverview() {
|
||||
? buildGraphCategories(currentGraphData, placeTypeRows)
|
||||
: buildGenericGraphCategories(currentGraphData, LABEL_NAMES),
|
||||
);
|
||||
setMapCoverage(coverage);
|
||||
} finally {
|
||||
setGraphCategoriesLoading(false);
|
||||
if (sequence === fetchSequence.current) setGraphCategoriesLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -186,7 +184,10 @@ export default function PlazaOverview() {
|
||||
fetch();
|
||||
const onChange = () => fetch();
|
||||
window.addEventListener("znkg-project-context", onChange);
|
||||
return () => window.removeEventListener("znkg-project-context", onChange);
|
||||
return () => {
|
||||
++fetchSequence.current;
|
||||
window.removeEventListener("znkg-project-context", onChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const releases = (data.graph_releases as Array<Record<string, unknown>>) || [];
|
||||
@@ -220,7 +221,7 @@ export default function PlazaOverview() {
|
||||
|
||||
{isKnowledgeMapProject && (
|
||||
<KnowledgeMap
|
||||
cov={mapCoverage}
|
||||
key={`${projectContext.projectId}:${projectContext.graphName}:${spatialMap.region_adcode}`}
|
||||
projectId={projectContext.projectId}
|
||||
projectName={projectSummary?.display_name || projectSummary?.name || projectContext.projectId}
|
||||
scope={spatialMap.scope}
|
||||
|
||||
@@ -2002,7 +2002,6 @@ const loadAmapSdk = (jsKey: string, securityJsCode?: string) => {
|
||||
};
|
||||
|
||||
export function KnowledgeMap({
|
||||
cov = null,
|
||||
scope = "guizhou",
|
||||
projectId = "default",
|
||||
projectName = "当前项目",
|
||||
@@ -2010,7 +2009,6 @@ export function KnowledgeMap({
|
||||
regionAdcode = "520000",
|
||||
regionLevel = "province",
|
||||
}: {
|
||||
cov?: CoverageSnapshot | null;
|
||||
scope?: "guizhou" | "libo";
|
||||
projectId?: string;
|
||||
projectName?: string;
|
||||
@@ -2061,7 +2059,7 @@ export function KnowledgeMap({
|
||||
}
|
||||
});
|
||||
const searchBoxRef = useRef<HTMLDivElement | null>(null);
|
||||
const [poiLoading, setPoiLoading] = useState(false);
|
||||
const [poiLoading, setPoiLoading] = useState(true);
|
||||
const [poiError, setPoiError] = useState("");
|
||||
const [selectedPoi, setSelectedPoi] = useState<MapPoi | null>(null);
|
||||
const [poiDetail, setPoiDetail] = useState<MapPoiDetail | null>(null);
|
||||
@@ -2300,6 +2298,8 @@ export function KnowledgeMap({
|
||||
let disposed = false;
|
||||
setPoiLoading(true);
|
||||
setPoiError("");
|
||||
setMapPois([]);
|
||||
setSelectedCategories([]);
|
||||
plazaMapPois()
|
||||
.then(({ data }) => {
|
||||
if (disposed) return;
|
||||
@@ -3544,10 +3544,10 @@ export function KnowledgeMap({
|
||||
}}
|
||||
>
|
||||
<div style={{ color: "#888", fontSize: 12, marginBottom: 4 }}>
|
||||
{isLibo ? `${activeRegionName}馆藏汇总` : "省域馆藏汇总"}
|
||||
{regionLevel === "province" ? "省域馆藏汇总" : `${activeRegionName}馆藏汇总`}
|
||||
</div>
|
||||
<div style={{ fontSize: 28, fontWeight: 700, lineHeight: 1.15 }}>
|
||||
{(isLibo ? regionPois.length : (cov?.total ?? regionPois.length)).toLocaleString()}
|
||||
{poiLoading ? "加载中…" : poiError ? "—" : regionPois.length.toLocaleString()}
|
||||
</div>
|
||||
<div style={{ color: "#888", fontSize: 12, marginTop: 4 }}>
|
||||
{isLibo && selectedTowncode
|
||||
|
||||
@@ -25,14 +25,23 @@ test("every map-enabled project uses the single KnowledgeMap template", () => {
|
||||
assert.doesNotMatch(overviewSource, /<SuperAgentPanel/);
|
||||
});
|
||||
|
||||
test("the shared map preserves the four approved shortcut logos and province summary", () => {
|
||||
test("the shared map preserves approved logos and counts only current-region graph POIs", () => {
|
||||
assert.match(mapSource, /MAP_SHORTCUT_CATEGORIES = \["美食", "酒店", "景点", "交通设施"\]/);
|
||||
assert.match(mapSource, /MAP_SHORTCUT_CATEGORIES\.map/);
|
||||
assert.match(mapSource, /省域馆藏汇总/);
|
||||
assert.match(mapSource, /cov\?\.total \?\? regionPois\.length/);
|
||||
assert.match(mapSource, /regionPois\.length\.toLocaleString\(\)/);
|
||||
assert.doesNotMatch(mapSource, /cov\?\.total/);
|
||||
assert.match(mapSource, /regionLevel === "province"/);
|
||||
assert.match(mapSource, /poiLoading \? "加载中…" : poiError \? "—"/);
|
||||
assert.match(mapSource, /当前已入藏知识 \/ POI 条目/);
|
||||
});
|
||||
|
||||
test("switching a graph version remounts the map and clears stale POIs", () => {
|
||||
assert.match(overviewSource, /key=\{.*projectContext\.projectId.*projectContext\.graphName.*spatialMap\.region_adcode/);
|
||||
assert.match(mapSource, /setPoiError\(""\);\s+setMapPois\(\[\]\);\s+setSelectedCategories\(\[\]\)/);
|
||||
assert.match(overviewSource, /if \(sequence !== fetchSequence\.current\) return/);
|
||||
});
|
||||
|
||||
test("map-enabled project creation requires an explicit administrative region", () => {
|
||||
assert.match(projectLandingSource, /name="map_region_adcode"/);
|
||||
assert.match(projectLandingSource, /请选择地图区域/);
|
||||
|
||||
Reference in new issue
Block a user