"Add pagination to OrderBookingsTable.vue with next/previous controls, dynamic page limit, and loading state management; refine empty state handling and table structure for improved user experience"
This commit is contained in:
+139
-84
@@ -8,12 +8,44 @@ import ActionSettingsWheelItemLabel from "@/components/displays/buttons/ActionSe
|
||||
import ActionSettingsWheelItem from "@/components/displays/buttons/ActionSettingsWheelItem.vue";
|
||||
|
||||
const bookings = ref([]);
|
||||
const page = ref(1);
|
||||
const limit = ref(10);
|
||||
const loading = ref(false);
|
||||
const isLastPage = ref(false);
|
||||
|
||||
const fetch = async () => {
|
||||
SessionUser.objects.order_bookings.get.all().then((res) => {
|
||||
bookings.value = res;
|
||||
loading.value = true;
|
||||
return SessionUser.objects.order_bookings.get.all({ page: page.value, limit: limit.value }).then((res) => {
|
||||
bookings.value = res || [];
|
||||
// Infer if this is the last page based on result size
|
||||
isLastPage.value = bookings.value.length < limit.value;
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
bookings.value = [];
|
||||
isLastPage.value = true;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
const nextPage = async () => {
|
||||
if (isLastPage.value || loading.value) return;
|
||||
page.value += 1;
|
||||
await fetch();
|
||||
}
|
||||
|
||||
const prevPage = async () => {
|
||||
if (page.value === 1 || loading.value) return;
|
||||
page.value -= 1;
|
||||
await fetch();
|
||||
}
|
||||
|
||||
const onLimitChange = async () => {
|
||||
// Reset to first page when page size changes
|
||||
page.value = 1;
|
||||
await fetch();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
})
|
||||
@@ -109,95 +141,118 @@ const formatSummaryString = (items) => {
|
||||
<th><!-- Items -->Ydelser</th>
|
||||
<th><!-- Actions --></th>
|
||||
</tr>
|
||||
<template v-if="bookings.length === 0">
|
||||
<template v-if="bookings.length === 0 && !loading">
|
||||
<tr>
|
||||
<td colspan="1">Ingen bookinger fundet</td>
|
||||
<td colspan="8">Ingen bookinger fundet</td>
|
||||
</tr>
|
||||
</template>
|
||||
<tr v-for="booking in bookings" :key="booking.id">
|
||||
<!-- Date -->
|
||||
<EditableTableColumn
|
||||
<template v-else>
|
||||
<tr v-for="booking in bookings" :key="booking.id">
|
||||
<!-- Date -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="datetime"
|
||||
:parse-function="(value) => value ? `${value}` : 'Ingen dato valgt'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Vehicles -->
|
||||
<td>
|
||||
<p>
|
||||
<EditableTableColumn
|
||||
:componentWrapper="'div'"
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reg_1"
|
||||
:parse-function="(value) => value || 'Ingen registreret'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<EditableTableColumn
|
||||
:componentWrapper="'div'"
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reg_2"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
</p>
|
||||
</td>
|
||||
<!-- Department -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="department"
|
||||
:parse-function="(value) => getDepartmentName(parseInt(booking.department))"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- PO -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="po"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Reference -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reference"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Pickup -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="pickup"
|
||||
:permissionCheckFunction="(bookingobj) => true"
|
||||
:parse-function="(value) => value ? 'Ja' : 'Nej'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Items -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="datetime"
|
||||
:parse-function="(value) => value ? `${value}` : 'Ingen dato valgt'"
|
||||
column="items"
|
||||
:permissionCheckFunction = "(bookingobj) => booking.items.length > 0"
|
||||
:parse-function="(bookingobj) => formatSummaryString(booking.items)"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Vehicles -->
|
||||
<td>
|
||||
<p>
|
||||
<EditableTableColumn
|
||||
:componentWrapper="'div'"
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reg_1"
|
||||
:parse-function="(value) => value || 'Ingen registreret'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<EditableTableColumn
|
||||
:componentWrapper="'div'"
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reg_2"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
</p>
|
||||
</td>
|
||||
<!-- Department -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="department"
|
||||
:parse-function="(value) => getDepartmentName(parseInt(booking.department))"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- PO -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="po"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Reference -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="reference"
|
||||
:parse-function="(value) => value || '-'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Pickup -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="pickup"
|
||||
:permissionCheckFunction="(bookingobj) => true"
|
||||
:parse-function="(value) => value ? 'Ja' : 'Nej'"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Items -->
|
||||
<EditableTableColumn
|
||||
:object="booking"
|
||||
:loadList="fetch"
|
||||
column="items"
|
||||
:permissionCheckFunction = "(bookingobj) => booking.items.length > 0"
|
||||
:parse-function="(bookingobj) => formatSummaryString(booking.items)"
|
||||
:edit-function="SessionUser.objects.order_bookings.showEditObjectFieldForm"
|
||||
/>
|
||||
<!-- Actions -->
|
||||
<td>
|
||||
<ActionSettingsWheelButton :order_booking_id="booking.id" :order_id="booking.order_id" :customer_number="booking.customer_number" :department_id="booking.department" :refresh-function="fetch">
|
||||
<template #actions>
|
||||
</template>
|
||||
</ActionSettingsWheelButton>
|
||||
</td>
|
||||
<!-- TODO: Complete implementation! -->
|
||||
</tr>
|
||||
/>
|
||||
<!-- Actions -->
|
||||
<td>
|
||||
<ActionSettingsWheelButton :order_booking_id="booking.id" :order_id="booking.order_id" :customer_number="booking.customer_number" :department_id="booking.department" :refresh-function="fetch">
|
||||
<template #actions>
|
||||
</template>
|
||||
</ActionSettingsWheelButton>
|
||||
</td>
|
||||
<!-- TODO: Complete implementation! -->
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
|
||||
<!-- Pagination Controls -->
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<nav class="pagination is-centered" role="navigation" aria-label="pagination">
|
||||
<a class="pagination-previous" :class="{ 'is-disabled': page === 1 || loading }" @click="prevPage">Forrige</a>
|
||||
<a class="pagination-next" :class="{ 'is-disabled': isLastPage || loading }" @click="nextPage">Næste</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<div class="select">
|
||||
<select v-model.number="limit" @change="onLimitChange" :disabled="loading">
|
||||
<option :value="5">5</option>
|
||||
<option :value="10">10</option>
|
||||
<option :value="20">20</option>
|
||||
<option :value="50">50</option>
|
||||
</select>
|
||||
</div>
|
||||
<span class="ml-3">Side {{ page }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user