11<script lang="ts">
22import {
3- defineComponent , onMounted , ref , watch ,
3+ defineComponent , onMounted , onUnmounted , ref , watch ,
44} from ' vue' ;
55import * as d3 from ' d3' ;
66import UVdatApi from ' ../../api/UVDATApi' ;
77import MapStore from ' ../../MapStore' ;
88import { AbstractMapLayer } from ' ../../types' ;
9- import { toggleLayerSelection } from ' ../../map/mapLayers' ;
9+ import { getStringBBox , internalMap , toggleLayerSelection } from ' ../../map/mapLayers' ;
1010
1111export default defineComponent ({
1212 name: ' MetadataLayerFilter' ,
@@ -17,6 +17,7 @@ export default defineComponent({
1717 const colorScale = d3 .scaleOrdinal (d3 .schemeCategory10 );
1818 const search = ref (' ' );
1919 const showFilters = ref (false ); // Toggle filter visibility
20+ const filterBBox = ref (false );
2021
2122 onMounted (async () => {
2223 metadataFilters .value = await UVdatApi .getMetadataFilters ();
@@ -25,11 +26,48 @@ export default defineComponent({
2526 });
2627 });
2728
29+ const updateFilter = async () => {
30+ let bbox: string | undefined ;
31+ if (filterBBox .value ) {
32+ bbox = getStringBBox ();
33+ }
34+ const result = await UVdatApi .filterOnMetadata (selectedFilters .value , search .value , bbox );
35+ filteredLayers .value = result ;
36+ };
37+
38+ let movementTimeout: NodeJS .Timeout | null = null ;
39+ const onMapMoveEnd = () => {
40+ if (movementTimeout ) clearTimeout (movementTimeout );
41+ movementTimeout = setTimeout (updateFilter , 500 );
42+ };
43+
44+ const onMapMove = () => {
45+ if (movementTimeout ) {
46+ clearTimeout (movementTimeout );
47+ }
48+ };
49+
50+ watch (filterBBox , () => {
51+ if (filterBBox .value && internalMap .value ) {
52+ internalMap .value .on (' moveend' , onMapMoveEnd );
53+ internalMap .value .on (' move' , onMapMove );
54+ } else if (internalMap .value ) {
55+ internalMap .value .off (' moveend' , onMapMoveEnd );
56+ internalMap .value .off (' move' , onMapMove );
57+ }
58+ updateFilter ();
59+ });
60+
61+ onUnmounted (() => {
62+ if (internalMap .value ) {
63+ internalMap .value .off (' moveend' , onMapMoveEnd );
64+ internalMap .value .off (' move' , onMapMove );
65+ }
66+ });
2867 watch (
2968 [selectedFilters , search ],
3069 async () => {
31- const result = await UVdatApi .filterOnMetadata (selectedFilters .value , search .value );
32- filteredLayers .value = result ;
70+ updateFilter ();
3371 },
3472 { deep: true },
3573 );
@@ -71,6 +109,7 @@ export default defineComponent({
71109 toggleFilterLayerSelection ,
72110 search ,
73111 showFilters ,
112+ filterBBox ,
74113 };
75114 },
76115});
@@ -88,9 +127,20 @@ export default defineComponent({
88127 clearable
89128 prepend-inner-icon =" mdi-magnify"
90129 />
91- <v-icon icon :color =" showFilters ? 'primary' : ''" @click =" showFilters = !showFilters" >
92- {{ showFilters ? 'mdi-filter' : 'mdi-filter' }}
93- </v-icon >
130+ <v-tooltip text =" Filter by current Map View" >
131+ <template #activator =" { props } " >
132+ <v-icon :color =" filterBBox ? 'primary' : ''" v-bind =" props" @click =" filterBBox = !filterBBox" >
133+ mdi-vector-square
134+ </v-icon >
135+ </template >
136+ </v-tooltip >
137+ <v-tooltip text =" View metadata filters" >
138+ <template #activator =" { props } " >
139+ <v-icon :color =" showFilters ? 'primary' : ''" v-bind =" props" @click =" showFilters = !showFilters" >
140+ mdi-filter
141+ </v-icon >
142+ </template >
143+ </v-tooltip >
94144 </v-row >
95145
96146 <!-- Selected Filters as Chips (Shown when filters are hidden) -->
0 commit comments