Dev branch
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
<script setup>
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import SkeletonTable from "@/Components/Skeleton/SkeletonTable.vue";
|
||||
import EmptyState from "@/Components/EmptyState.vue";
|
||||
import {
|
||||
FwbTable,
|
||||
FwbTableHead,
|
||||
FwbTableHeadCell,
|
||||
FwbTableBody,
|
||||
FwbTableRow,
|
||||
FwbTableCell,
|
||||
} from "flowbite-vue";
|
||||
Table,
|
||||
TableHeader,
|
||||
TableHead,
|
||||
TableBody,
|
||||
TableRow,
|
||||
TableCell,
|
||||
} from "@/Components/ui/table";
|
||||
|
||||
const props = defineProps({
|
||||
columns: { type: Array, required: true }, // [{ key, label, sortable?, align?, class? }]
|
||||
@@ -94,7 +96,8 @@ function setPageSize(ps) {
|
||||
function doRequest(overrides = {}) {
|
||||
const q = {
|
||||
...props.query,
|
||||
perPage: overrides.perPage ?? props.meta?.per_page ?? props.pageSize ?? 10,
|
||||
// Laravel expects snake_case per_page
|
||||
per_page: overrides.perPage ?? props.meta?.per_page ?? props.pageSize ?? 10,
|
||||
sort: overrides.sort ?? props.sort?.key ?? null,
|
||||
direction: overrides.direction ?? props.sort?.direction ?? null,
|
||||
search: overrides.search ?? props.search ?? "",
|
||||
@@ -197,42 +200,43 @@ function goToPageInput() {
|
||||
<div
|
||||
class="relative overflow-x-auto rounded-lg border border-gray-200 bg-white shadow-sm"
|
||||
>
|
||||
<FwbTable hoverable striped class="text-sm">
|
||||
<FwbTableHead
|
||||
<Table class="text-sm">
|
||||
<TableHeader
|
||||
class="sticky top-0 z-10 bg-gray-50/90 backdrop-blur border-b border-gray-200 shadow-sm"
|
||||
>
|
||||
<FwbTableHeadCell v-for="col in columns" :key="col.key" :class="col.class">
|
||||
<button
|
||||
v-if="col.sortable"
|
||||
type="button"
|
||||
class="inline-flex items-center gap-1 hover:text-indigo-600"
|
||||
@click="toggleSort(col)"
|
||||
:aria-sort="sort?.key === col.key ? sort.direction || 'none' : 'none'"
|
||||
>
|
||||
<span class="uppercase">{{ col.label }}</span>
|
||||
<span v-if="sort?.key === col.key && sort.direction === 'asc'">▲</span>
|
||||
<span v-else-if="sort?.key === col.key && sort.direction === 'desc'"
|
||||
>▼</span
|
||||
<TableRow class="border-b">
|
||||
<TableHead v-for="col in columns" :key="col.key" :class="col.class">
|
||||
<button
|
||||
v-if="col.sortable"
|
||||
type="button"
|
||||
class="inline-flex items-center gap-1 hover:text-indigo-600"
|
||||
@click="toggleSort(col)"
|
||||
:aria-sort="sort?.key === col.key ? sort.direction || 'none' : 'none'"
|
||||
>
|
||||
</button>
|
||||
<span v-else>{{ col.label }}</span>
|
||||
</FwbTableHeadCell>
|
||||
<FwbTableHeadCell v-if="$slots.actions" class="w-px"> </FwbTableHeadCell>
|
||||
</FwbTableHead>
|
||||
<span class="uppercase">{{ col.label }}</span>
|
||||
<span v-if="sort?.key === col.key && sort.direction === 'asc'">▲</span>
|
||||
<span v-else-if="sort?.key === col.key && sort.direction === 'desc'"
|
||||
>▼</span
|
||||
>
|
||||
</button>
|
||||
<span v-else>{{ col.label }}</span>
|
||||
</TableHead>
|
||||
<TableHead v-if="$slots.actions" class="w-px"> </TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<FwbTableBody>
|
||||
<TableBody>
|
||||
<template v-if="!loading && rows.length">
|
||||
<FwbTableRow
|
||||
<TableRow
|
||||
v-for="(row, idx) in rows"
|
||||
:key="keyOf(row)"
|
||||
@click="$emit('row:click', row)"
|
||||
class="cursor-default"
|
||||
class="cursor-default hover:bg-gray-50/50"
|
||||
>
|
||||
<FwbTableCell
|
||||
<TableCell
|
||||
v-for="col in columns"
|
||||
:key="col.key"
|
||||
:class="col.class"
|
||||
:align="col.align || 'left'"
|
||||
>
|
||||
<template v-if="$slots['cell-' + col.key]">
|
||||
<slot
|
||||
@@ -255,30 +259,30 @@ function goToPageInput() {
|
||||
<template v-else>
|
||||
{{ row?.[col.key] ?? "" }}
|
||||
</template>
|
||||
</FwbTableCell>
|
||||
<FwbTableCell v-if="$slots.actions" class="w-px text-right">
|
||||
</TableCell>
|
||||
<TableCell v-if="$slots.actions" class="w-px text-right">
|
||||
<slot name="actions" :row="row" :index="idx" />
|
||||
</FwbTableCell>
|
||||
</FwbTableRow>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</template>
|
||||
<template v-else-if="loading">
|
||||
<FwbTableRow>
|
||||
<FwbTableCell :colspan="columns.length + ($slots.actions ? 1 : 0)">
|
||||
<div class="p-6 text-center text-gray-500">Nalagam...</div>
|
||||
</FwbTableCell>
|
||||
</FwbTableRow>
|
||||
<TableRow>
|
||||
<TableCell :colspan="columns.length + ($slots.actions ? 1 : 0)">
|
||||
<SkeletonTable :rows="5" :cols="columns.length" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</template>
|
||||
<template v-else>
|
||||
<FwbTableRow>
|
||||
<FwbTableCell :colspan="columns.length + ($slots.actions ? 1 : 0)">
|
||||
<TableRow>
|
||||
<TableCell :colspan="columns.length + ($slots.actions ? 1 : 0)">
|
||||
<slot name="empty">
|
||||
<div class="p-6 text-center text-gray-500">{{ emptyText }}</div>
|
||||
</slot>
|
||||
</FwbTableCell>
|
||||
</FwbTableRow>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</template>
|
||||
</FwbTableBody>
|
||||
</FwbTable>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<nav
|
||||
|
||||
Reference in New Issue
Block a user