Skip to content

feat(pagination): Add the default value of page_size from options if … #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/useDatatableUrlSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ export default function useDatatableUrlSync(route: any, router: any, form: Ref<G
ordering: [],
...options.value
}
// 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
const frontDefaultPageSize = options.value.page_size ?? configurations.serveurDefaultPageSize
formSchema = {
page: { type: "integer", default: 1 },
page_size: { type: "integer", default: 10 },
page_size: { type: "integer", default: frontDefaultPageSize },
ordering: { type: "arrayString", default: [] },
...formSchema || {}
}
Expand Down
8 changes: 4 additions & 4 deletions src/utils/VDUSTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ type VDUSConfiguration = {
}

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

type VuetifyOptions = {
page: number;
itemsPerPage: number;
sortBy: Array<string>;
sortDesc: Array<boolean>;
sortBy: Array<string | { key: string; order: 'asc' | 'desc'; }>; // depending if vuetify 2 or 3
sortDesc: Array<boolean>; // not existing in vuetify 3
groupBy: Array<string>;
groupDesc: Array<boolean>;
multiSort: boolean;
Expand Down
19 changes: 9 additions & 10 deletions vue3-example/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@
<v-list-item
prepend-icon="mdi-gavel"
title="Multiple Datatable"
to="/multiple-datatable"
to="/multiple-vuetify"
/>
</v-list>

<template #append>
<div class="pa-2">
<v-btn block>
Logout
</v-btn>
</div>
</template>
</v-navigation-drawer>
<router-view />
<v-container class="fill-height">
<v-responsive
class="align-centerfill-height mx-auto"
max-width="900"
>
<router-view />
</v-responsive>
</v-container>
</v-main>
</v-app>
</template>
Expand Down
116 changes: 55 additions & 61 deletions vue3-example/src/components/SimpleDatatable.vue
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
<template>
<div class="container">
<div class="mt-8">
Datatable
</div>
<div class="mt-8 row">
<div
v-for="header in headers"
:key="header"
class="col width-30 border-right border-bottom"
>
<p>{{ header }}</p>
<BaseOrdering
:field="header"
:value="options.ordering"
@input="(value: string[]) => emitOptions('ordering', value)"
/>
</div>
<div class="mt-8">
Datatable
</div>
<div class="mt-8 row">
<div
v-for="header in headers"
:key="header"
class="col width-30 border-right border-bottom"
>
<p>{{ header }}</p>
<BaseOrdering
:field="header"
:value="options.ordering"
@input="(value: string[]) => emitOptions('ordering', value)"
/>
</div>
</div>
<div
v-for="item in currentItems"
:key="item[itemKey]"
class="row"
>
<div
v-for="item in currentItems"
:key="item[itemKey]"
class="row"
v-for="(value, key) in item"
:key="key"
class="col width-30 border-right"
>
<div
v-for="(value, key) in item"
:key="key"
class="col width-30 border-right"
>
<p>{{ value }}</p>
</div>
<p>{{ value }}</p>
</div>
<div class="mt-4 row">
<div class="col width-40">
<label>Item per page: </label>
<select
:value="options.page_size"
@change="($event) => emitOptions('page_size', parseInt($event.target?.value))"
</div>
<div class="mt-4 row">
<div class="col width-40">
<label>Item per page: </label>
<select
:value="options.page_size"
@change="($event) => emitOptions('page_size', parseInt($event.target?.value))"
>
<option
v-for="itemNumber in [5, 10, 20]"
:key="itemNumber"
:selected="options.page_size === itemNumber"
:value="itemNumber"
>
<option
v-for="itemNumber in [5, 10, 20]"
:key="itemNumber"
:selected="options.page_size === itemNumber"
:value="itemNumber"
>
{{ itemNumber }}
</option>
</select>
</div>
{{ itemNumber }}
</option>
</select>
</div>

<div class="col width-40">
<button
v-if="options.page > 1"
@click="emitOptions('page', options.page - 1)"
>
Prev. page
</button>
<button
v-if="lastVisibleIndex < items.length"
@click="emitOptions('page', options.page + 1)"
>
Next page
</button>
</div>
<div class="col width-40">
<button
v-if="options.page > 1"
@click="emitOptions('page', options.page - 1)"
>
Prev. page
</button>
<button
v-if="lastVisibleIndex < items.length"
@click="emitOptions('page', options.page + 1)"
>
Next page
</button>
</div>
</div>
</template>
Expand Down Expand Up @@ -126,10 +124,6 @@ function emitOptions<K extends keyof Options>(optionKey: K, value: Options[K]) {
</script>

<style scoped>
.container {
width: 600px;
margin: auto;
}
.row {
display: flex;
flex-wrap: wrap;
Expand Down
92 changes: 49 additions & 43 deletions vue3-example/src/components/VuetifyDatatable.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
<template>
<v-container class="fill-height">
<v-responsive
class="align-centerfill-height mx-auto"
max-width="900"
>
<v-row>
<v-col cols="12">
<v-form>
<v-text-field
v-model="form.search"
label="search"
/>
<v-checkbox
v-model="form.is_answered"
label="is Answered"
/>
</v-form>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-card
class="py-4"
rounded="lg"
variant="outlined"
>
<template #text>
<v-data-table
:items="items"
:page="vuetifyOptions.page"
:items-per-page="vuetifyOptions.itemsPerPage"
:sort-by="vuetifyOptions.sortBy"
v-model:options="vuetifyOptions"
/>
</template>
</v-card>
</v-col>
</v-row>
</v-responsive>
</v-container>
<v-row>
<v-col cols="12">
<v-form>
<v-text-field
v-model="form.search"
label="search"
/>
<v-checkbox
v-model="form.is_answered"
label="is Answered"
/>
</v-form>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-card
class="py-4"
rounded="lg"
variant="outlined"
>
<template #text>
<v-data-table
v-model:options="vuetifyOptions"
:items="items"
:page="vuetifyOptions.page"
:items-per-page="vuetifyOptions.itemsPerPage"
:sort-by="vuetifyOptions.sortBy"
/>
</template>
</v-card>
</v-col>
</v-row>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import useDatatableUrlSync from '../../../src/useDatatableUrlSync';
import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema } from '../../../src/utils/VDUSTypes';
import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema, VDUSConfiguration } from '../../../src/utils/VDUSTypes';
// import useDatatableUrlSync from 'vue-datatable-url-sync';
// import type { GenericDictionnary, VDUSDatatableOptions, VDUSFormSchema } from 'vue-datatable-url-sync/src/utils/VDUSTypes';
import fakeData from "../assets/data/data.js";
Expand All @@ -56,6 +49,14 @@ type FakeDataItem = {
is_answered: boolean;
};

// --------------------- PROPS ------------------------------------
const props = defineProps({
prefix: {
type: String,
default: ""
},
})

// --------------------- DATA ------------------------------------
const form = ref<GenericDictionnary>({
search: "",
Expand All @@ -68,10 +69,15 @@ const options = ref<VDUSDatatableOptions>({
ordering: []
});

const configurations = ref<VDUSConfiguration>({
prefix: props.prefix,
serveurDefaultPageSize: 10,
})

const items = ref<FakeDataItem[]>([]);

const formSchema = ref<VDUSFormSchema>({
is_answered: { type: "boolean" }
is_answered: { type: "boolean" },
});

// --------------------- METHODS ------------------------------------
Expand Down Expand Up @@ -121,5 +127,5 @@ const fetchDatas = (queryParams: string, queryAsObject: GenericDictionnary) => {
};

// --------------------- CREATED ------------------------------------
const {vuetifyOptions} = useDatatableUrlSync(useRoute(), useRouter(), form, fetchDatas, options, formSchema.value);
const {vuetifyOptions} = useDatatableUrlSync(useRoute(), useRouter(), form, fetchDatas, options, formSchema.value, null, configurations.value);
</script>
16 changes: 16 additions & 0 deletions vue3-example/src/pages/multiple-vuetify.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<v-row>
<v-col cols="12">
<VuetifyDatatable prefix="d1" />
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<VuetifyDatatable prefix="d2" />
</v-col>
</v-row>
</template>

<script lang="ts" setup>
//
</script>
1 change: 1 addition & 0 deletions vue3-example/typed-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ declare module 'vue-router/auto-routes' {
*/
export interface RouteNamedMap {
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
'/multiple-vuetify': RouteRecordInfo<'/multiple-vuetify', '/multiple-vuetify', Record<never, never>, Record<never, never>>,
'/simple': RouteRecordInfo<'/simple', '/simple', Record<never, never>, Record<never, never>>,
}
}
Loading