feat: add project-aware agent workspace
This commit is contained in:
@@ -9,7 +9,7 @@ import type {
|
||||
StyleSpecification
|
||||
} from "maplibre-gl";
|
||||
import { useCallback, useEffect, useRef, useState, type RefObject } from "react";
|
||||
import type { AccessTokenProvider } from "@/shared/auth/keycloak-auth";
|
||||
import type { WorkbenchAccess } from "../api/request-context";
|
||||
import { env } from "@/shared/config/env";
|
||||
import { fetchScadaSnapshot, type ScadaDevice } from "../api/scada-client";
|
||||
import type { DetailFeature } from "../types";
|
||||
@@ -62,6 +62,7 @@ declare global {
|
||||
}
|
||||
|
||||
type UseWorkbenchMapOptions = {
|
||||
featureInteractionsEnabled?: boolean;
|
||||
containerRef: RefObject<HTMLDivElement | null>;
|
||||
impactVisible: boolean;
|
||||
layerVisibility: Record<string, boolean>;
|
||||
@@ -71,7 +72,8 @@ type UseWorkbenchMapOptions = {
|
||||
simulationOverlay: FeatureCollection<Geometry> | null;
|
||||
allowDemoSimulation: boolean;
|
||||
networkView?: NetworkViewParams | null;
|
||||
getAccessToken?: AccessTokenProvider;
|
||||
getAccessToken?: WorkbenchAccess;
|
||||
geoserverWorkspace?: string;
|
||||
};
|
||||
|
||||
type UseWorkbenchMapResult = {
|
||||
@@ -132,6 +134,7 @@ const EMPTY_SIMULATION_COLLECTION: FeatureCollection = {
|
||||
};
|
||||
|
||||
export function useWorkbenchMap({
|
||||
featureInteractionsEnabled = true,
|
||||
containerRef,
|
||||
impactVisible,
|
||||
layerVisibility,
|
||||
@@ -141,6 +144,7 @@ export function useWorkbenchMap({
|
||||
simulationOverlay,
|
||||
allowDemoSimulation,
|
||||
networkView,
|
||||
geoserverWorkspace,
|
||||
getAccessToken
|
||||
}: UseWorkbenchMapOptions): UseWorkbenchMapResult {
|
||||
const mapRef = useRef<MapLibreMap | null>(null);
|
||||
@@ -199,7 +203,7 @@ export function useWorkbenchMap({
|
||||
);
|
||||
geoServerLayerProbeInFlightRef.current = true;
|
||||
|
||||
void resolveGeoServerLayerAvailability(requestAbortController.signal)
|
||||
void resolveGeoServerLayerAvailability(requestAbortController.signal, geoserverWorkspace)
|
||||
.then((availability) => {
|
||||
if (lifecycleAbortController.signal.aborted) return;
|
||||
setAvailableGeoServerSourceIds((current) =>
|
||||
@@ -237,7 +241,7 @@ export function useWorkbenchMap({
|
||||
geoServerLayerProbeInFlightRef.current = false;
|
||||
window.clearTimeout(probeTimeout);
|
||||
};
|
||||
}, [geoServerLayerRefreshRevision]);
|
||||
}, [geoServerLayerRefreshRevision, geoserverWorkspace]);
|
||||
|
||||
useEffect(() => {
|
||||
impactVisibleRef.current = impactVisible;
|
||||
@@ -306,7 +310,7 @@ export function useWorkbenchMap({
|
||||
(map.getSource(SCADA_SOURCE_ID) as GeoJSONSource | undefined)?.setData(
|
||||
scadaCollectionRef.current
|
||||
);
|
||||
const sources = createWaterNetworkSources(REQUIRED_GEOSERVER_SOURCE_IDS);
|
||||
const sources = createWaterNetworkSources(REQUIRED_GEOSERVER_SOURCE_IDS, geoserverWorkspace);
|
||||
REQUIRED_GEOSERVER_SOURCE_IDS.forEach((sourceId) => {
|
||||
const source = sources[sourceId];
|
||||
if (source) map.addSource(sourceId, source);
|
||||
@@ -315,8 +319,10 @@ export function useWorkbenchMap({
|
||||
map.addSource(SIMULATION_SOURCE_IDS.annotations, simulationSources.annotations);
|
||||
map.addSource(SIMULATION_SOURCE_IDS.backendAnalysis, simulationSources.backendAnalysis);
|
||||
syncSimulationSourceData(map, simulationOverlayRef.current, allowDemoSimulationRef.current);
|
||||
await registerSupplyAssetImages(map);
|
||||
const scadaRegistration = await registerScadaImages(map);
|
||||
await registerSupplyAssetImages(map, scadaAbortController.signal);
|
||||
if (scadaAbortController.signal.aborted) return;
|
||||
const scadaRegistration = await registerScadaImages(map, scadaAbortController.signal);
|
||||
if (scadaAbortController.signal.aborted) return;
|
||||
const activeScadaBusinessLayers =
|
||||
scadaRegistration.status === "unavailable"
|
||||
? scadaFallbackBusinessLayers
|
||||
@@ -444,13 +450,13 @@ export function useWorkbenchMap({
|
||||
mapRef.current = null;
|
||||
delete window.__waterNetworkMap;
|
||||
};
|
||||
}, [containerRef, getAccessToken]);
|
||||
}, [containerRef, getAccessToken, geoserverWorkspace]);
|
||||
|
||||
useEffect(() => {
|
||||
const map = mapRef.current;
|
||||
if (!mapReady || !map) return;
|
||||
syncDataDependentGeoServerLayers(map, availableGeoServerSourceIds, layerVisibility);
|
||||
}, [availableGeoServerSourceIds, layerVisibility, mapReady]);
|
||||
syncDataDependentGeoServerLayers(map, availableGeoServerSourceIds, layerVisibility, geoserverWorkspace);
|
||||
}, [availableGeoServerSourceIds, layerVisibility, mapReady, geoserverWorkspace]);
|
||||
|
||||
useEffect(() => {
|
||||
const map = mapRef.current;
|
||||
@@ -462,6 +468,7 @@ export function useWorkbenchMap({
|
||||
}, [mapReady, networkView]);
|
||||
|
||||
useMapInteractions({
|
||||
enabled: featureInteractionsEnabled,
|
||||
availableSourceIds: availableGeoServerSourceIds,
|
||||
mapRef,
|
||||
mapReady,
|
||||
@@ -557,7 +564,8 @@ function syncSimulationSourceData(
|
||||
function syncDataDependentGeoServerLayers(
|
||||
map: MapLibreMap,
|
||||
availableSourceIds: readonly GeoServerWaterNetworkSourceId[],
|
||||
layerVisibility: Record<string, boolean>
|
||||
layerVisibility: Record<string, boolean>,
|
||||
workspace?: string
|
||||
) {
|
||||
const availableSourceIdSet = new Set<GeoServerWaterNetworkSourceId>(availableSourceIds);
|
||||
|
||||
@@ -574,7 +582,7 @@ function syncDataDependentGeoServerLayers(
|
||||
const requestedOptionalSourceIds = DATA_DEPENDENT_GEOSERVER_SOURCE_IDS.filter((sourceId) =>
|
||||
availableSourceIdSet.has(sourceId)
|
||||
);
|
||||
const sources = createWaterNetworkSources(requestedOptionalSourceIds);
|
||||
const sources = createWaterNetworkSources(requestedOptionalSourceIds, workspace);
|
||||
requestedOptionalSourceIds.forEach((sourceId) => {
|
||||
if (!map.getSource(sourceId) && sources[sourceId]) {
|
||||
map.addSource(sourceId, sources[sourceId]);
|
||||
@@ -620,7 +628,8 @@ function addMissingDataDependentLayers(
|
||||
layers: StyleSpecification["layers"],
|
||||
beforeLayerCandidates: readonly string[],
|
||||
availableSourceIdSet: ReadonlySet<GeoServerWaterNetworkSourceId>,
|
||||
layerVisibility: Record<string, boolean>
|
||||
layerVisibility: Record<string, boolean>,
|
||||
workspace?: string
|
||||
) {
|
||||
const beforeLayerId = beforeLayerCandidates.find((layerId) => map.getLayer(layerId));
|
||||
layers.forEach((layer) => {
|
||||
|
||||
Reference in New Issue
Block a user