doxfood/src/components/RestaurantsTable.vue

107 lines
2.3 KiB
Vue

<script setup lang="ts">
import "../assets/datatable.css";
import DataTable from "datatables.net-vue3";
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<Restaurant[]> },
});
const columns = [
{ data: "name", title: "Name" },
{
data: "tags",
title: "Tags",
render: {
_: "[, ]",
},
},
{ data: "average_rating", title: "" },
];
const table = ref<typeof DataTable>();
function onRowSelected(e, dt, type, indexes) {
if (indexes.length != 0 && props.data !== undefined) {
emit("restaurantSelected", props.data[indexes[0]]);
}
}
function deselectAll() {
table.value?.dt.rows({ selected: true }).deselect();
}
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;
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);
}
hovered.value = null;
}
}
function onMouseLeave() {
emit("restaurantHovered", null);
hovered.value = null;
}
defineExpose({ deselectAll });
</script>
<template>
<DataTable
class="table"
ref="table"
@mouseover="onMouseOver"
@mouseleave="onMouseLeave"
:columns="columns"
:data="props.data"
:options="{
layout: {
top: ['pageLength', null, 'search'],
topStart: null,
topEnd: null,
bottom: 'paging',
bottomStart: null,
bottomEnd: null,
},
select: {
style: 'single',
},
}"
@select="onRowSelected"
>
<template #column-2="props">
<RatingField
v-if="props.cellData !== null"
:disabled="true"
:id="props.rowIndex"
v-model="props.cellData"
:size="'sm'"
/>
<p class="text-gray-500" v-else>No rating yet...</p>
</template>
</DataTable>
</template>