Skip to content

Commit d4c6c67

Browse files
committed
feat(pagination): Add the default value of page_size from options if not specified in formSchema
1 parent 2a44c00 commit d4c6c67

File tree

7 files changed

+137
-119
lines changed

7 files changed

+137
-119
lines changed

src/useDatatableUrlSync.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ export default function useDatatableUrlSync(route: any, router: any, form: Ref<G
4141
ordering: [],
4242
...options.value
4343
}
44+
// This is just a convenient shortcut. You should speicify the page_size default in formSchema. But as it is already passed in options in the first call we can guess it. As you may pass a non default value on the first call you still can override the formSchema for more complex use case
45+
const frontDefaultPageSize = options.value.page_size ?? configurations.serveurDefaultPageSize
4446
formSchema = {
4547
page: { type: "integer", default: 1 },
46-
page_size: { type: "integer", default: 10 },
48+
page_size: { type: "integer", default: frontDefaultPageSize },
4749
ordering: { type: "arrayString", default: [] },
4850
...formSchema || {}
4951
}

src/utils/VDUSTypes.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ type VDUSConfiguration = {
2727
}
2828

2929
type VuetifySortArraysObject = {
30-
sortBy: Array<string | { key: string; order: 'asc' | 'desc'; }>;
31-
sortDesc: Array<boolean>;
30+
sortBy: Array<string | { key: string; order: 'asc' | 'desc'; }>; // depending if vuetify 2 or 3
31+
sortDesc: Array<boolean>; // not existing in vuetify 3
3232
}
3333

3434
type VuetifyOptions = {
3535
page: number;
3636
itemsPerPage: number;
37-
sortBy: Array<string>;
38-
sortDesc: Array<boolean>;
37+
sortBy: Array<string | { key: string; order: 'asc' | 'desc'; }>; // depending if vuetify 2 or 3
38+
sortDesc: Array<boolean>; // not existing in vuetify 3
3939
groupBy: Array<string>;
4040
groupDesc: Array<boolean>;
4141
multiSort: boolean;

vue3-example/src/App.vue

+9-10
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,18 @@
1818
<v-list-item
1919
prepend-icon="mdi-gavel"
2020
title="Multiple Datatable"
21-
to="/multiple-datatable"
21+
to="/multiple-vuetify"
2222
/>
2323
</v-list>
24-
25-
<template #append>
26-
<div class="pa-2">
27-
<v-btn block>
28-
Logout
29-
</v-btn>
30-
</div>
31-
</template>
3224
</v-navigation-drawer>
33-
<router-view />
25+
<v-container class="fill-height">
26+
<v-responsive
27+
class="align-centerfill-height mx-auto"
28+
max-width="900"
29+
>
30+
<router-view />
31+
</v-responsive>
32+
</v-container>
3433
</v-main>
3534
</v-app>
3635
</template>

vue3-example/src/components/SimpleDatatable.vue

+55-61
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,65 @@
11
<template>
2-
<div class="container">
3-
<div class="mt-8">
4-
Datatable
5-
</div>
6-
<div class="mt-8 row">
7-
<div
8-
v-for="header in headers"
9-
:key="header"
10-
class="col width-30 border-right border-bottom"
11-
>
12-
<p>{{ header }}</p>
13-
<BaseOrdering
14-
:field="header"
15-
:value="options.ordering"
16-
@input="(value: string[]) => emitOptions('ordering', value)"
17-
/>
18-
</div>
2+
<div class="mt-8">
3+
Datatable
4+
</div>
5+
<div class="mt-8 row">
6+
<div
7+
v-for="header in headers"
8+
:key="header"
9+
class="col width-30 border-right border-bottom"
10+
>
11+
<p>{{ header }}</p>
12+
<BaseOrdering
13+
:field="header"
14+
:value="options.ordering"
15+
@input="(value: string[]) => emitOptions('ordering', value)"
16+
/>
1917
</div>
18+
</div>
19+
<div
20+
v-for="item in currentItems"
21+
:key="item[itemKey]"
22+
class="row"
23+
>
2024
<div
21-
v-for="item in currentItems"
22-
:key="item[itemKey]"
23-
class="row"
25+
v-for="(value, key) in item"
26+
:key="key"
27+
class="col width-30 border-right"
2428
>
25-
<div
26-
v-for="(value, key) in item"
27-
:key="key"
28-
class="col width-30 border-right"
29-
>
30-
<p>{{ value }}</p>
31-
</div>
29+
<p>{{ value }}</p>
3230
</div>
33-
<div class="mt-4 row">
34-
<div class="col width-40">
35-
<label>Item per page: </label>
36-
<select
37-
:value="options.page_size"
38-
@change="($event) => emitOptions('page_size', parseInt($event.target?.value))"
31+
</div>
32+
<div class="mt-4 row">
33+
<div class="col width-40">
34+
<label>Item per page: </label>
35+
<select
36+
:value="options.page_size"
37+
@change="($event) => emitOptions('page_size', parseInt($event.target?.value))"
38+
>
39+
<option
40+
v-for="itemNumber in [5, 10, 20]"
41+
:key="itemNumber"
42+
:selected="options.page_size === itemNumber"
43+
:value="itemNumber"
3944
>
40-
<option
41-
v-for="itemNumber in [5, 10, 20]"
42-
:key="itemNumber"
43-
:selected="options.page_size === itemNumber"
44-
:value="itemNumber"
45-
>
46-
{{ itemNumber }}
47-
</option>
48-
</select>
49-
</div>
45+
{{ itemNumber }}
46+
</option>
47+
</select>
48+
</div>
5049

51-
<div class="col width-40">
52-
<button
53-
v-if="options.page > 1"
54-
@click="emitOptions('page', options.page - 1)"
55-
>
56-
Prev. page
57-
</button>
58-
<button
59-
v-if="lastVisibleIndex < items.length"
60-
@click="emitOptions('page', options.page + 1)"
61-
>
62-
Next page
63-
</button>
64-
</div>
50+
<div class="col width-40">
51+
<button
52+
v-if="options.page > 1"
53+
@click="emitOptions('page', options.page - 1)"
54+
>
55+
Prev. page
56+
</button>
57+
<button
58+
v-if="lastVisibleIndex < items.length"
59+
@click="emitOptions('page', options.page + 1)"
60+
>
61+
Next page
62+
</button>
6563
</div>
6664
</div>
6765
</template>
@@ -126,10 +124,6 @@ function emitOptions<K extends keyof Options>(optionKey: K, value: Options[K]) {
126124
</script>
127125

128126
<style scoped>
129-
.container {
130-
width: 600px;
131-
margin: auto;
132-
}
133127
.row {
134128
display: flex;
135129
flex-wrap: wrap;

vue3-example/src/components/VuetifyDatatable.vue

+49-43
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,43 @@
11
<template>
2-
<v-container class="fill-height">
3-
<v-responsive
4-
class="align-centerfill-height mx-auto"
5-
max-width="900"
6-
>
7-
<v-row>
8-
<v-col cols="12">
9-
<v-form>
10-
<v-text-field
11-
v-model="form.search"
12-
label="search"
13-
/>
14-
<v-checkbox
15-
v-model="form.is_answered"
16-
label="is Answered"
17-
/>
18-
</v-form>
19-
</v-col>
20-
</v-row>
21-
<v-row>
22-
<v-col cols="12">
23-
<v-card
24-
class="py-4"
25-
rounded="lg"
26-
variant="outlined"
27-
>
28-
<template #text>
29-
<v-data-table
30-
:items="items"
31-
:page="vuetifyOptions.page"
32-
:items-per-page="vuetifyOptions.itemsPerPage"
33-
:sort-by="vuetifyOptions.sortBy"
34-
v-model:options="vuetifyOptions"
35-
/>
36-
</template>
37-
</v-card>
38-
</v-col>
39-
</v-row>
40-
</v-responsive>
41-
</v-container>
2+
<v-row>
3+
<v-col cols="12">
4+
<v-form>
5+
<v-text-field
6+
v-model="form.search"
7+
label="search"
8+
/>
9+
<v-checkbox
10+
v-model="form.is_answered"
11+
label="is Answered"
12+
/>
13+
</v-form>
14+
</v-col>
15+
</v-row>
16+
<v-row>
17+
<v-col cols="12">
18+
<v-card
19+
class="py-4"
20+
rounded="lg"
21+
variant="outlined"
22+
>
23+
<template #text>
24+
<v-data-table
25+
v-model:options="vuetifyOptions"
26+
:items="items"
27+
:page="vuetifyOptions.page"
28+
:items-per-page="vuetifyOptions.itemsPerPage"
29+
:sort-by="vuetifyOptions.sortBy"
30+
/>
31+
</template>
32+
</v-card>
33+
</v-col>
34+
</v-row>
4235
</template>
4336

4437
<script setup lang="ts">
4538
import { ref } from 'vue';
4639
import useDatatableUrlSync from '../../../src/useDatatableUrlSync';
47-
import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema } from '../../../src/utils/VDUSTypes';
40+
import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema, VDUSConfiguration } from '../../../src/utils/VDUSTypes';
4841
// import useDatatableUrlSync from 'vue-datatable-url-sync';
4942
// import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema } from 'vue-datatable-url-sync/src/utils/VDUSTypes';
5043
import fakeData from "../assets/data/data.js";
@@ -56,6 +49,14 @@ type FakeDataItem = {
5649
is_answered: boolean;
5750
};
5851
52+
// --------------------- PROPS ------------------------------------
53+
const props = defineProps({
54+
prefix: {
55+
type: String,
56+
default: ""
57+
},
58+
})
59+
5960
// --------------------- DATA ------------------------------------
6061
const form = ref<GenericDictionnary>({
6162
search: "",
@@ -68,10 +69,15 @@ const options = ref<VDUSDatatableOptions>({
6869
ordering: []
6970
});
7071
72+
const configurations = ref<VDUSConfiguration>({
73+
prefix: props.prefix,
74+
serveurDefaultPageSize: 10,
75+
})
76+
7177
const items = ref<FakeDataItem[]>([]);
7278
7379
const formSchema = ref<VDUSFormSchema>({
74-
is_answered: { type: "boolean" }
80+
is_answered: { type: "boolean" },
7581
});
7682
7783
// --------------------- METHODS ------------------------------------
@@ -121,5 +127,5 @@ const fetchDatas = (queryParams: string, queryAsObject: GenericDictionnary) => {
121127
};
122128
123129
// --------------------- CREATED ------------------------------------
124-
const {vuetifyOptions} = useDatatableUrlSync(useRoute(), useRouter(), form, fetchDatas, options, formSchema.value);
130+
const {vuetifyOptions} = useDatatableUrlSync(useRoute(), useRouter(), form, fetchDatas, options, formSchema.value, null, configurations.value);
125131
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<v-row>
3+
<v-col cols="12">
4+
<VuetifyDatatable prefix="d1" />
5+
</v-col>
6+
</v-row>
7+
<v-row>
8+
<v-col cols="12">
9+
<VuetifyDatatable prefix="d2" />
10+
</v-col>
11+
</v-row>
12+
</template>
13+
14+
<script lang="ts" setup>
15+
//
16+
</script>

vue3-example/typed-router.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ declare module 'vue-router/auto-routes' {
1919
*/
2020
export interface RouteNamedMap {
2121
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
22+
'/multiple-vuetify': RouteRecordInfo<'/multiple-vuetify', '/multiple-vuetify', Record<never, never>, Record<never, never>>,
2223
'/simple': RouteRecordInfo<'/simple', '/simple', Record<never, never>, Record<never, never>>,
2324
}
2425
}

0 commit comments

Comments
 (0)