Added marker highlighting when hovering table.

main
Eloi Zalczer 2024-06-18 18:04:21 +02:00
parent fa49ed91a8
commit 0dae1684d1
4 changed files with 81 additions and 9 deletions

View File

@ -7,36 +7,66 @@ import LatLng from "../models/map";
import { storeToRefs } from "pinia";
import { useRestaurantsStore } from "../stores/restaurants";
const initialMap = ref<L.Map | null>(null);
const map = ref<L.Map | null>(null);
const { restaurants } = storeToRefs(useRestaurantsStore());
const props = defineProps({
highlighted: { type: String },
});
const emit = defineEmits({
clicked: (latlng: LatLng) => true,
});
const markers = ref<Map<string, L.Marker>>(new Map());
onMounted(() => {
initialMap.value = L.map("map").setView([48.8363012, 2.240709935], 14);
map.value = L.map("map").setView([48.8363012, 2.240709935], 14);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(initialMap.value);
}).addTo(map.value);
initialMap.value!.on("click", function (e) {
map.value!.on("click", function (e) {
emit("clicked", e.latlng);
});
watch(
() => restaurants.value,
async (newval, oldval) => {
markers.value.forEach((marker) => marker.remove());
markers.value.clear();
restaurants.value?.forEach((restaurant) => {
const marker = L.marker({ lat: restaurant.latitude, lng: restaurant.longitude });
marker.bindPopup(`<p>${restaurant.name}</p>`);
marker.addTo(initialMap.value);
marker.addTo(map.value);
markers.value.set(restaurant.id, marker);
});
},
{ immediate: true }
);
watch(
() => props.highlighted,
(newval, oldval) => {
console.log(markers.value);
if (oldval != null) {
var old = markers.value.get(oldval);
console.log("old", old, oldval);
if (old.isPopupOpen()) {
old.closePopup();
}
}
if (newval != null) {
var marker = markers.value.get(newval);
console.log("new", marker, newval);
if (!marker.isPopupOpen()) {
marker.openPopup();
}
}
}
);
});
</script>

View File

@ -6,11 +6,12 @@ import DataTablesCore from "datatables.net";
import "datatables.net-select";
import { PropType, ref } from "vue";
import RatingField from "./RatingField.vue";
import Restaurant from "../models/restaurant";
DataTable.use(DataTablesCore);
const props = defineProps({
data: { type: Array as PropType<Object[]> },
data: { type: Array as PropType<Restaurant[]> },
});
const columns = [
@ -31,7 +32,35 @@ function deselectAll() {
table.value?.dt.rows({ selected: true }).deselect();
}
const emit = defineEmits(["restaurantSelected"]);
const emit = defineEmits({
restaurantSelected: (restaurant: Object) => true,
restaurantHovered: (restaurant: Object | null) => true,
});
const hovered = ref<Restaurant | null>();
function onMouseOver(e) {
const row = e.target?._DT_CellIndex?.row;
console.log("row", row);
if (row !== undefined && props.data !== undefined) {
if (hovered.value != props.data[row]) {
emit("restaurantHovered", props.data[row].id);
}
hovered.value = props.data[row];
} else {
if (hovered.value !== null) {
emit("restaurantHovered", null);
console.log("hovered");
}
hovered.value = null;
}
}
function onMouseLeave() {
emit("restaurantHovered", null);
hovered.value = null;
}
defineExpose({ deselectAll });
</script>
@ -40,6 +69,8 @@ defineExpose({ deselectAll });
<DataTable
class="table"
ref="table"
@mouseover="onMouseOver"
@mouseleave="onMouseLeave"
:columns="columns"
:data="props.data"
:options="{

View File

@ -1,4 +1,5 @@
export default interface Restaurant {
id: string;
name: string;
tags: string[];
price: string;

View File

@ -14,6 +14,7 @@ const drawer = ref<typeof ReviewsDrawer>();
const table = ref<typeof RestaurantsTable>();
const selectedRestaurant = ref<Object>();
const highlightedRestaurant = ref<string>();
const { restaurants } = storeToRefs(useRestaurantsStore());
@ -22,6 +23,10 @@ function onRestaurantSelected(restaurant: Object) {
drawer.value?.open();
}
function onRestaurantHovered(id: string) {
highlightedRestaurant.value = id;
}
function onDrawerClosed() {
console.log("closed");
table.value?.deselectAll();
@ -31,10 +36,15 @@ function onDrawerClosed() {
<template>
<div class="flex flex-col-reverse sm:flex-row">
<div class="w-full flex-1">
<RestaurantsTable ref="table" @restaurant-selected="onRestaurantSelected" :data="restaurants" />
<RestaurantsTable
ref="table"
@restaurant-selected="onRestaurantSelected"
@restaurant-hovered="onRestaurantHovered"
:data="restaurants"
/>
</div>
<div class="flex-1 h-3/6 lg:h-full">
<RestaurantsMap />
<RestaurantsMap :highlighted="highlightedRestaurant" />
</div>
</div>