220 lines
8.2 KiB
Vue
220 lines
8.2 KiB
Vue
<script setup>
|
|
import { ref } from 'vue';
|
|
import { Head } from '@inertiajs/vue3';
|
|
import AppLayout from '@/Layouts/AppLayout.vue';
|
|
import DataTableNew2 from '@/Components/DataTable/DataTableNew2.vue';
|
|
import { Badge } from '@/Components/ui/badge';
|
|
import { Button } from '@/Components/ui/button';
|
|
|
|
// Simple columns example
|
|
const simpleColumns = [
|
|
{ key: 'id', label: 'ID', sortable: true, class: 'w-20' },
|
|
{ key: 'name', label: 'Name', sortable: true },
|
|
{ key: 'email', label: 'Email', sortable: true },
|
|
{ key: 'status', label: 'Status', sortable: false },
|
|
{ key: 'amount', label: 'Amount', sortable: true, align: 'right', class: 'text-right' },
|
|
];
|
|
|
|
// Sample data
|
|
const data = ref([
|
|
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com', status: 'active', amount: 1250.50 },
|
|
{ id: 2, name: 'Bob Smith', email: 'bob@example.com', status: 'inactive', amount: 890.25 },
|
|
{ id: 3, name: 'Carol Williams', email: 'carol@example.com', status: 'active', amount: 2100.00 },
|
|
{ id: 4, name: 'David Brown', email: 'david@example.com', status: 'pending', amount: 450.75 },
|
|
{ id: 5, name: 'Eve Davis', email: 'eve@example.com', status: 'active', amount: 1875.30 },
|
|
{ id: 6, name: 'Frank Miller', email: 'frank@example.com', status: 'inactive', amount: 670.00 },
|
|
{ id: 7, name: 'Grace Wilson', email: 'grace@example.com', status: 'active', amount: 3200.50 },
|
|
{ id: 8, name: 'Henry Moore', email: 'henry@example.com', status: 'pending', amount: 520.25 },
|
|
{ id: 9, name: 'Ivy Taylor', email: 'ivy@example.com', status: 'active', amount: 1950.00 },
|
|
{ id: 10, name: 'Jack Anderson', email: 'jack@example.com', status: 'inactive', amount: 780.40 },
|
|
{ id: 11, name: 'Kate Thomas', email: 'kate@example.com', status: 'active', amount: 2450.75 },
|
|
{ id: 12, name: 'Leo Jackson', email: 'leo@example.com', status: 'pending', amount: 930.60 },
|
|
]);
|
|
|
|
const selectedRows = ref([]);
|
|
|
|
function handleRowClick(row) {
|
|
console.log('Row clicked:', row);
|
|
}
|
|
|
|
function handleSelectionChange(keys) {
|
|
selectedRows.value = keys;
|
|
console.log('Selection changed:', keys);
|
|
}
|
|
|
|
function getStatusVariant(status) {
|
|
const variants = {
|
|
active: 'default',
|
|
inactive: 'secondary',
|
|
pending: 'outline',
|
|
};
|
|
return variants[status] || 'outline';
|
|
}
|
|
|
|
function formatCurrency(value) {
|
|
return new Intl.NumberFormat('sl-SI', {
|
|
style: 'currency',
|
|
currency: 'EUR',
|
|
}).format(value);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<AppLayout title="DataTable Example">
|
|
<Head title="DataTable Example" />
|
|
|
|
<div class="py-12">
|
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
|
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg p-6">
|
|
<div class="mb-6">
|
|
<h2 class="text-2xl font-bold text-gray-900">
|
|
DataTable Component Example
|
|
</h2>
|
|
<p class="mt-1 text-sm text-gray-600">
|
|
This is a working example of the new shadcn-vue style DataTable component
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Example 1: Basic Table -->
|
|
<div class="mb-12">
|
|
<h3 class="text-lg font-semibold mb-4">Basic Table with Simple Columns</h3>
|
|
<DataTableNew2
|
|
:columns="simpleColumns"
|
|
:data="data"
|
|
filter-column="email"
|
|
filter-placeholder="Search by email..."
|
|
@row:click="handleRowClick"
|
|
>
|
|
<!-- Custom cell for status using slot -->
|
|
<template #cell-status="{ value }">
|
|
<Badge :variant="getStatusVariant(value)">
|
|
{{ value }}
|
|
</Badge>
|
|
</template>
|
|
|
|
<!-- Custom cell for amount using slot -->
|
|
<template #cell-amount="{ value }">
|
|
<span class="font-medium">{{ formatCurrency(value) }}</span>
|
|
</template>
|
|
</DataTableNew2>
|
|
</div>
|
|
|
|
<!-- Example 2: Table with Row Selection -->
|
|
<div class="mb-12">
|
|
<h3 class="text-lg font-semibold mb-4">Table with Row Selection</h3>
|
|
<div v-if="selectedRows.length" class="mb-4 p-4 bg-blue-50 rounded-lg">
|
|
<p class="text-sm font-medium text-blue-900">
|
|
Selected {{ selectedRows.length }} row(s)
|
|
</p>
|
|
</div>
|
|
<DataTableNew2
|
|
:columns="simpleColumns"
|
|
:data="data"
|
|
enable-row-selection
|
|
filter-column="name"
|
|
filter-placeholder="Search by name..."
|
|
@selection:change="handleSelectionChange"
|
|
>
|
|
<template #cell-status="{ value }">
|
|
<Badge :variant="getStatusVariant(value)">
|
|
{{ value }}
|
|
</Badge>
|
|
</template>
|
|
<template #cell-amount="{ value }">
|
|
<span class="font-medium">{{ formatCurrency(value) }}</span>
|
|
</template>
|
|
</DataTableNew2>
|
|
</div>
|
|
|
|
<!-- Example 3: Striped & Hoverable -->
|
|
<div class="mb-12">
|
|
<h3 class="text-lg font-semibold mb-4">Striped Table with Hover</h3>
|
|
<DataTableNew2
|
|
:columns="simpleColumns"
|
|
:data="data.slice(0, 5)"
|
|
:page-size="5"
|
|
striped
|
|
hoverable
|
|
>
|
|
<template #cell-status="{ value }">
|
|
<Badge :variant="getStatusVariant(value)">
|
|
{{ value }}
|
|
</Badge>
|
|
</template>
|
|
<template #cell-amount="{ value }">
|
|
<span class="font-medium">{{ formatCurrency(value) }}</span>
|
|
</template>
|
|
</DataTableNew2>
|
|
</div>
|
|
|
|
<!-- Example 4: Custom Toolbar -->
|
|
<div>
|
|
<h3 class="text-lg font-semibold mb-4">Table with Custom Toolbar Actions</h3>
|
|
<DataTableNew2
|
|
:columns="simpleColumns"
|
|
:data="data"
|
|
filter-column="email"
|
|
filter-placeholder="Search emails..."
|
|
>
|
|
<!-- Add custom buttons to toolbar -->
|
|
<template #toolbar-actions="{ table }">
|
|
<Button variant="outline" size="sm" @click="() => console.log('Export clicked')">
|
|
Export
|
|
</Button>
|
|
<Button variant="default" size="sm" @click="() => console.log('Add clicked')">
|
|
Add New
|
|
</Button>
|
|
</template>
|
|
|
|
<template #cell-status="{ value }">
|
|
<Badge :variant="getStatusVariant(value)">
|
|
{{ value }}
|
|
</Badge>
|
|
</template>
|
|
<template #cell-amount="{ value }">
|
|
<span class="font-medium">{{ formatCurrency(value) }}</span>
|
|
</template>
|
|
</DataTableNew2>
|
|
</div>
|
|
|
|
<!-- Example 5: Full Custom Toolbar -->
|
|
<div class="mt-12">
|
|
<h3 class="text-lg font-semibold mb-4">Table with Custom Filters in Toolbar</h3>
|
|
<DataTableNew2
|
|
:columns="simpleColumns"
|
|
:data="data"
|
|
filter-column="name"
|
|
filter-placeholder="Search names..."
|
|
>
|
|
<!-- Add custom filter controls -->
|
|
<template #toolbar-filters="{ table }">
|
|
<select
|
|
class="h-8 rounded-md border border-input bg-background px-3 py-1 text-sm"
|
|
@change="(e) => {
|
|
const column = table.getColumn('status');
|
|
column?.setFilterValue(e.target.value || undefined);
|
|
}"
|
|
>
|
|
<option value="">All Status</option>
|
|
<option value="active">Active</option>
|
|
<option value="inactive">Inactive</option>
|
|
<option value="pending">Pending</option>
|
|
</select>
|
|
</template>
|
|
|
|
<template #cell-status="{ value }">
|
|
<Badge :variant="getStatusVariant(value)">
|
|
{{ value }}
|
|
</Badge>
|
|
</template>
|
|
<template #cell-amount="{ value }">
|
|
<span class="font-medium">{{ formatCurrency(value) }}</span>
|
|
</template>
|
|
</DataTableNew2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AppLayout>
|
|
</template>
|