78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import type { FeatureCollection, Point } from "geojson";
|
|
import type { Map as MapLibreMap } from "maplibre-gl";
|
|
import type { ScadaDevice } from "../api/scada-client";
|
|
import { useEffect, useRef, useSyncExternalStore, type RefObject } from "react";
|
|
import { getResponsiveWorkbenchPadding } from "../map/camera";
|
|
import type { WaterNetworkSourceId } from "../map/sources";
|
|
import { WorkbenchMapController } from "../map/workbench-map-controller";
|
|
|
|
export function useWorkbenchMapController({
|
|
mapRef,
|
|
geoserverWorkspace,
|
|
mapReady,
|
|
leftPanelOpen,
|
|
rightPanelOpen,
|
|
conditionPanelExpanded = false,
|
|
agentPanelWidth,
|
|
getScadaFeatures,
|
|
availableSourceIds
|
|
}: {
|
|
geoserverWorkspace?: string;
|
|
mapRef: RefObject<MapLibreMap | null>;
|
|
mapReady: boolean;
|
|
leftPanelOpen: boolean;
|
|
rightPanelOpen: boolean;
|
|
conditionPanelExpanded?: boolean;
|
|
agentPanelWidth?: number;
|
|
getScadaFeatures?: (deviceIds?: string[], signal?: AbortSignal) => Promise<FeatureCollection<Point, ScadaDevice>>;
|
|
availableSourceIds?: readonly WaterNetworkSourceId[];
|
|
}) {
|
|
const valuesRef = useRef({
|
|
mapReady,
|
|
leftPanelOpen,
|
|
rightPanelOpen,
|
|
conditionPanelExpanded,
|
|
agentPanelWidth
|
|
});
|
|
valuesRef.current = {
|
|
mapReady,
|
|
leftPanelOpen,
|
|
rightPanelOpen,
|
|
conditionPanelExpanded,
|
|
agentPanelWidth
|
|
};
|
|
const controllerRef = useRef<WorkbenchMapController | null>(null);
|
|
if (!controllerRef.current) {
|
|
controllerRef.current = new WorkbenchMapController({
|
|
geoserverWorkspace,
|
|
getMap: () => mapRef.current,
|
|
isReady: () => valuesRef.current.mapReady,
|
|
getPadding: () => {
|
|
const map = mapRef.current;
|
|
return map
|
|
? getResponsiveWorkbenchPadding(
|
|
map,
|
|
valuesRef.current.leftPanelOpen,
|
|
valuesRef.current.rightPanelOpen,
|
|
valuesRef.current.conditionPanelExpanded,
|
|
valuesRef.current.agentPanelWidth
|
|
)
|
|
: { top: 48, right: 48, bottom: 48, left: 48 };
|
|
},
|
|
getScadaFeatures
|
|
});
|
|
}
|
|
|
|
const controller = controllerRef.current;
|
|
const state = useSyncExternalStore(
|
|
controller.subscribe,
|
|
controller.getSnapshot,
|
|
controller.getSnapshot
|
|
);
|
|
useEffect(() => {
|
|
if (availableSourceIds) controller.syncAvailableSources(availableSourceIds);
|
|
}, [availableSourceIds, controller]);
|
|
useEffect(() => () => controller.destroy(), [controller]);
|
|
return { controller, state };
|
|
}
|