From c783ab7942c3d3d446925710f3b9854dfaf98c00 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Fri, 24 Apr 2026 23:06:07 +0000 Subject: [PATCH] Add report rendering table to status page --- ts/map/Layer.vue | 24 +++- ts/map/Map.vue | 23 ++++ ts/rmo/components/TableReport.vue | 197 ++++++++++++++++++++++++++++++ ts/rmo/content/Status.vue | 34 ++++-- 4 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 ts/rmo/components/TableReport.vue diff --git a/ts/map/Layer.vue b/ts/map/Layer.vue index 08b5478d..95e35098 100644 --- a/ts/map/Layer.vue +++ b/ts/map/Layer.vue @@ -6,12 +6,15 @@ import maplibregl from "maplibre-gl"; import { inject, onMounted, onBeforeUnmount, Ref, useAttrs, watch } from "vue"; +export type MapEventType = maplibregl.MapEventType; export type MouseEvent = maplibregl.MapLayerMouseEvent; +export type Feature = maplibregl.MapGeoJSONFeature; type LayerType = maplibregl.LayerSpecification["type"]; interface Emits { (e: "click", evt: MouseEvent): void; (e: "mouseenter"): void; (e: "mouseleave"): void; + (e: "update:modelValue", features: Feature[]): void; } export interface Props { filter?: maplibregl.FilterSpecification; @@ -26,7 +29,7 @@ const attrs = useAttrs(); const emit = defineEmits(); const props = withDefaults(defineProps(), {}); -type OnCallbackFunc = (e?: MouseEvent) => void; +type OnCallbackFunc = (e?: any) => void; type RegisterOnFunc = ( eventname: string, layerid: string, @@ -37,6 +40,7 @@ type UnregisterLayerFunc = (id: string) => void; const map: Ref | undefined = inject("map"); const registerOn: RegisterOnFunc | undefined = inject("registerOn"); +const registerOnce: RegisterOnFunc | undefined = inject("registerOnce"); const registerLayer: RegisterLayerFunc | undefined = inject("registerLayer"); const unregisterLayer: UnregisterLayerFunc | undefined = inject("unregisterLayer"); @@ -54,6 +58,18 @@ const getLayerConfig = (): maplibregl.LayerSpecification => { return result; }; +function updateModel() { + if (!(map && map.value)) return; + const query: maplibregl.QueryRenderedFeaturesOptions = { + layers: [props.id], + }; + const features = map.value.queryRenderedFeatures(query); + const features_from_source = features.filter( + (feature: any) => feature.source == props.source, + ); + emit("update:modelValue", features_from_source); + //emit("mouseleave"); +} onMounted(() => { if (registerLayer) { registerLayer(props.id, getLayerConfig()); @@ -75,6 +91,12 @@ onMounted(() => { emit("mouseleave"); }); } + if (registerOn) { + registerOn("moveend", props.id, updateModel); + } + if (registerOnce) { + registerOnce("idle", props.id, updateModel); + } }); onBeforeUnmount(() => { diff --git a/ts/map/Map.vue b/ts/map/Map.vue index 6d60b5eb..a3a43c0c 100644 --- a/ts/map/Map.vue +++ b/ts/map/Map.vue @@ -47,6 +47,7 @@ provide("map", map); // Registry for tracking child components const ons = new Map(); +const onces = new Map(); const sources = new Map(); const layers = new Map(); @@ -69,6 +70,24 @@ provide( } }, ); +provide( + "registerOnce", + ( + eventname: keyof maplibregl.MapLayerEventType, + layerid: string, + callback: OnCallbackFunc, + ) => { + console.log("register map.once", eventname, layerid); + onces.set(`${eventname}.${layerid}`, { + callback: callback, + eventname: eventname, + layerid: layerid, + }); + if (map.value && map.value.loaded()) { + map.value.once(eventname, layerid, callback); + } + }, +); provide("registerSource", (id: string, config: any) => { console.log("register source", id, config); sources.set(id, config); @@ -143,6 +162,10 @@ function initializeMap() { _map.on(config.eventname, config.layerid, config.callback); }); }); + onces.forEach((config, id) => { + console.log("adding map.on", config.eventname, config.layerid); + _map.once(config.eventname, config.layerid, config.callback); + }); map.value = _map; } onMounted(() => { diff --git a/ts/rmo/components/TableReport.vue b/ts/rmo/components/TableReport.vue new file mode 100644 index 00000000..fefc5005 --- /dev/null +++ b/ts/rmo/components/TableReport.vue @@ -0,0 +1,197 @@ + + + + diff --git a/ts/rmo/content/Status.vue b/ts/rmo/content/Status.vue index 272fd4db..ef459279 100644 --- a/ts/rmo/content/Status.vue +++ b/ts/rmo/content/Status.vue @@ -141,6 +141,7 @@ source="tegola" sourceLayer="nuisance_location" type="circle" + v-model="renderedReportsNuisance" /> @@ -162,9 +163,7 @@
- +