1+ <!-- eslint-disable vuejs-accessibility/mouse-events-have-key-events -->
2+ <!-- eslint-disable vuejs-accessibility/mouse-events-have-key-events -->
13<script lang="ts">
24import {
35 Ref ,
4- computed , defineComponent , ref , watch ,
6+ computed , defineComponent , onMounted , onUnmounted , ref , watch ,
57} from ' vue' ;
68import UVdatApi from ' ../../api/UVDATApi' ;
79import MapStore from ' ../../MapStore' ;
@@ -15,6 +17,18 @@ export default defineComponent({
1517 const filterBBox = ref (false );
1618 const showFilters = ref (false );
1719 const selectedLayer = ref <number | null >(null );
20+ const availableProperties = computed (() => {
21+ if (selectedLayer .value !== null ) {
22+ const found = MapStore .selectedVectorMapLayers .value .find ((item ) => item .id === selectedLayer .value );
23+ if (found ) {
24+ if (found .default_style .properties ?.availableProperties ) {
25+ return found .default_style .properties .availableProperties ;
26+ }
27+ }
28+ }
29+ return {};
30+ });
31+
1832 const availableLayers = computed (
1933 () => MapStore .mapLayerVectorSearchable .value .map ((item ) => ({ title: item .name , value: item .id })),
2034 );
@@ -26,6 +40,15 @@ export default defineComponent({
2640 });
2741 const searchResults: Ref <SearchableVectorFeatureResponse []> = ref ([]);
2842
43+ const displayKeys = computed (() => {
44+ if (selectedSearchSettings .value ) {
45+ const subTitleKeys = selectedSearchSettings .value .display .subtitleKeys .filter ((key ) => key .showDisplayName ).map ((key ) => key .key );
46+ const detailKeys = selectedSearchSettings .value .display .detailStrings .filter ((key ) => key .showDisplayName ).map ((key ) => key .key );
47+ return { subTitleKeys , detailKeys };
48+ }
49+ return { subTitleKeys: [], detailKeys: [] };
50+ });
51+
2952 const updateSearch = async () => {
3053 if (selectedSearchSettings .value && selectedLayer .value !== null ) {
3154 const data: SearchableVectorDataRequest = {
@@ -52,6 +75,20 @@ export default defineComponent({
5275 }
5376 };
5477
78+ onMounted (() => {
79+ if (availableLayers .value .length ) {
80+ selectedLayer .value = availableLayers .value [0 ].value ;
81+ }
82+ updateSearch ();
83+ });
84+
85+ onUnmounted (() => {
86+ if (internalMap .value ) {
87+ internalMap .value .off (' moveend' , onMapMoveEnd );
88+ internalMap .value .off (' move' , onMapMove );
89+ }
90+ });
91+
5592 watch (filterBBox , () => {
5693 if (filterBBox .value && internalMap .value ) {
5794 internalMap .value .on (' moveend' , onMapMoveEnd );
@@ -67,6 +104,33 @@ export default defineComponent({
67104 updateSearch ();
68105 });
69106
107+ const getPropertyDisplayName = (key : string ) => {
108+ if (availableProperties .value [key ]) {
109+ return availableProperties .value [key ].displayName ;
110+ }
111+ return key ;
112+ };
113+
114+ const zoomToFeature = (id : number ) => {
115+ const found = searchResults .value .find ((item ) => item .id === id );
116+ if (found && internalMap .value && selectedSearchSettings .value ?.display .zoomBufferOrLevel ) {
117+ internalMap .value .setCenter ([found .center .lon , found .center .lat ]);
118+ internalMap .value .setZoom (selectedSearchSettings .value .display .zoomBufferOrLevel );
119+ }
120+ };
121+
122+ const onCardHover = (vectorFeatureId : number ) => {
123+ if (! MapStore .hoveredFeatures .value .includes (vectorFeatureId )) {
124+ MapStore .hoveredFeatures .value .push (vectorFeatureId );
125+ }
126+ };
127+ const onCardExit = (vectorFeatureId : number ) => {
128+ const foundIndex = MapStore .hoveredFeatures .value .findIndex ((item ) => item === vectorFeatureId );
129+ if (foundIndex !== - 1 ) {
130+ MapStore .hoveredFeatures .value .splice (foundIndex , 1 );
131+ }
132+ };
133+
70134 return {
71135 search ,
72136 filterBBox ,
@@ -75,6 +139,11 @@ export default defineComponent({
75139 availableLayers ,
76140 selectedSearchSettings ,
77141 searchResults ,
142+ getPropertyDisplayName ,
143+ displayKeys ,
144+ zoomToFeature ,
145+ onCardHover ,
146+ onCardExit ,
78147 };
79148 },
80149});
@@ -113,7 +182,8 @@ export default defineComponent({
113182 </v-icon >
114183 </template >
115184 </v-tooltip >
116- <v-tooltip text =" View metadata filters" >
185+ <!-- Eventual Filters added to the system -->
186+ <v-tooltip v-if =" false" text =" View metadata filters" >
117187 <template #activator =" { props } " >
118188 <v-icon :color =" showFilters ? 'primary' : ''" v-bind =" props" @click =" showFilters = !showFilters" >
119189 mdi-filter
@@ -122,8 +192,6 @@ export default defineComponent({
122192 </v-tooltip >
123193 </v-row >
124194
125- <!-- Selected Filters as Chips (Shown when filters are hidden) -->
126-
127195 <!-- Filters (Toggles Visibility) -->
128196 <v-expand-transition class =" pt-2" >
129197 <div v-if =" showFilters && selectedSearchSettings?.configurableFilters.length" >
@@ -135,17 +203,45 @@ export default defineComponent({
135203
136204 <!-- Filtered Layers -->
137205 <div v-if =" searchResults" >
138- <v-card v-for =" result in searchResults" :key =" result.id" >
139- {{ result.title }}
140- <v-list-item-subtitle >
141- <div v-for =" item in result.subtitles" :key =" item" >
142- {{ item }}
206+ <v-card
207+ v-for =" result in searchResults"
208+ :key =" result.id"
209+ class =" my-1 search-card"
210+ @mouseenter =" onCardHover(result.id)"
211+ @focusin =" onCardHover(result.id)"
212+ @focusout =" onCardExit(result.id)"
213+ @mouseleave =" onCardExit(result.id)"
214+ >
215+ <v-container >
216+ <v-row dense >
217+ <h4 >{{ result.title }}</h4 >
218+ <v-spacer />
219+ <v-tooltip v-if =" selectedSearchSettings?.display.zoomButton" text =" Zoom to Feature" >
220+ <template #activator =" { props } " >
221+ <v-icon v-bind =" props" @click =" zoomToFeature(result.id)" >
222+ mdi-magnify
223+ </v-icon >
224+ </template >
225+ </v-tooltip >
226+ </v-row >
227+ <div v-for =" item in result.subtitles" :key =" item.key" >
228+ <b v-if =" displayKeys.subTitleKeys.includes(item.key)" class =" mx-2" >{{ getPropertyDisplayName(item.key) }}:</b >
229+ <span >{{ item.value }}</span >
143230 </div >
144- </v-list-item-subtitle >
231+ <ul v-if =" result.details.length" class =" ml-8" >
232+ <li v-for =" item in result.details" :key =" item.key" >
233+ <b v-if =" displayKeys.detailKeys.includes(item.key)" class =" mx-2" >{{ getPropertyDisplayName(item.key) }}:</b >
234+ <span >{{ item.value }}</span >
235+ </li >
236+ </ul >
237+ </v-container >
145238 </v-card >
146239 </div >
147240 </v-container >
148241</template >
149242
150243<style scoped>
244+ .search-card :hover {
245+ background-color : #adf4ff78 ;
246+ }
151247 </style >
0 commit comments