62 lines
2.6 KiB
Vue
62 lines
2.6 KiB
Vue
<script setup>
|
|
import Modal from '@/Components/Modal.vue'
|
|
const props = defineProps({
|
|
show: Boolean,
|
|
limit: Number,
|
|
rows: Array,
|
|
columns: Array,
|
|
loading: Boolean,
|
|
truncated: Boolean,
|
|
hasHeader: Boolean,
|
|
})
|
|
const emits = defineEmits(['close','change-limit','refresh'])
|
|
function onLimit(e){ emits('change-limit', Number(e.target.value)); emits('refresh') }
|
|
</script>
|
|
<template>
|
|
<Modal :show="show" max-width="wide" @close="$emit('close')">
|
|
<div class="p-4">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h3 class="font-semibold text-lg">CSV Preview ({{ rows.length }} / {{ limit }})</h3>
|
|
<button class="text-sm px-2 py-1 rounded border" @click="$emit('close')">Close</button>
|
|
</div>
|
|
<div class="mb-2 flex items-center gap-3 text-sm">
|
|
<div>
|
|
<label class="mr-1 text-gray-600">Limit:</label>
|
|
<select :value="limit" class="border rounded p-1" @change="onLimit">
|
|
<option :value="50">50</option>
|
|
<option :value="100">100</option>
|
|
<option :value="200">200</option>
|
|
<option :value="300">300</option>
|
|
<option :value="500">500</option>
|
|
</select>
|
|
</div>
|
|
<button @click="$emit('refresh')" class="px-2 py-1 border rounded" :disabled="loading">{{ loading ? 'Loading…' : 'Refresh' }}</button>
|
|
<span v-if="truncated" class="text-xs text-amber-600">Truncated at limit</span>
|
|
</div>
|
|
<div class="overflow-auto max-h-[60vh] border rounded">
|
|
<table class="min-w-full text-xs">
|
|
<thead class="bg-gray-50 sticky top-0">
|
|
<tr>
|
|
<th class="p-2 border bg-white">#</th>
|
|
<th v-for="col in columns" :key="col" class="p-2 border text-left">{{ col }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-if="loading">
|
|
<td :colspan="columns.length + 1" class="p-4 text-center text-gray-500">Loading…</td>
|
|
</tr>
|
|
<tr v-for="(r, idx) in rows" :key="idx" class="border-t hover:bg-gray-50">
|
|
<td class="p-2 border text-gray-500">{{ idx + 1 }}</td>
|
|
<td v-for="col in columns" :key="col" class="p-2 border whitespace-pre-wrap">{{ r[col] }}</td>
|
|
</tr>
|
|
<tr v-if="!loading && !rows.length">
|
|
<td :colspan="columns.length + 1" class="p-4 text-center text-gray-500">No rows</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="mt-2 text-xs text-gray-500">Showing up to {{ limit }} rows from source file. Header detection: {{ hasHeader ? 'header present' : 'no header' }}.</p>
|
|
</div>
|
|
</Modal>
|
|
</template>
|