Skip to content

Pull master #121

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 7 commits into from
Jan 14, 2025
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
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default typescriptEslint.config(
rules: {
'vue/require-default-prop': 'off',
'vue/attribute-hyphenation': 'off',
'vue/v-on-event-hyphenation': 'off',
'vue/multi-word-component-names': 'off',
'vue/block-lang': 'off',
'@typescript-eslint/no-explicit-any': 'off',
Expand Down
36 changes: 25 additions & 11 deletions resources/js/Composables/useLazyDataTable.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { usePaginatedData } from './usePaginatedData';
import * as PrimeVue from '@/types/primevue';
import cloneDeep from 'lodash-es/cloneDeep';
import {
DataTableFilterMetaData,
DataTableFilterEvent,
DataTableSortEvent,
} from 'primevue';
import { PrimeVueDataFilters } from '@/types';

export function useLazyDataTable(
initialFilters: PrimeVue.PaginatedDataFilters = {},
initialFilters: PrimeVueDataFilters = {},
only: string[] = ['request'],
initialsRows: number = 20
) {
const defaultFilters = initialFilters;
const defaultRows = initialsRows;

const {
processing,
filters,
Expand Down Expand Up @@ -36,19 +39,29 @@ export function useLazyDataTable(
* "Override" parent composable function
* Event driven filtering rather than reactive state
*/
function filter(event: { filters: PrimeVue.PaginatedDataFilters }) {
function filter(event: DataTableFilterEvent) {
pagination.value.page = 1;
filters.value = { ...event.filters };
const newFilters: PrimeVueDataFilters = {};
Object.entries(event.filters).forEach(([key, rawFilter]) => {
if (
rawFilter &&
typeof rawFilter === 'object' &&
'matchMode' in rawFilter
) {
newFilters[key] = rawFilter as DataTableFilterMetaData;
}
});
filters.value = newFilters;
parseEventFilterValues();
fetchData().then(() => {
scrollToTop();
});
}

function sort(event: PrimeVue.SortEvent) {
function sort(event: DataTableSortEvent) {
pagination.value.page = 1;
sorting.value.field = event.sortField;
sorting.value.order = event.sortOrder;
sorting.value.field = String(event.sortField);
sorting.value.order = event.sortOrder || 1;
fetchData().then(() => {
scrollToTop();
});
Expand All @@ -59,14 +72,15 @@ export function useLazyDataTable(
* usePaginatedData() resets sorting.value state as a new object, this will not work for DataTable's
*/
function reset() {
const defaultFilters = cloneDeep(initialFilters);
Object.keys(defaultFilters).forEach((key) => {
filters.value[key].value = defaultFilters[key].value;
});
sorting.value.field = '';
sorting.value.order = 1;
pagination.value = {
page: 1,
rows: defaultRows,
rows: initialsRows,
};
fetchData().then(() => {
window.history.replaceState(null, '', window.location.pathname);
Expand Down
48 changes: 24 additions & 24 deletions resources/js/Composables/usePaginatedData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,39 @@ import { ref, computed, onMounted } from 'vue';
import { router, usePage } from '@inertiajs/vue3';
import { FilterMatchMode } from '@primevue/core/api';
import debounce from 'lodash-es/debounce';
import * as PrimeVue from '@/types/primevue';

interface PageStateEvent {
first: number;
rows: number;
page: number;
pageCount: number;
import cloneDeep from 'lodash-es/cloneDeep';
import { PageState, DataTablePageEvent } from 'primevue';
import { PrimeVueDataFilters } from '@/types';

interface PaginatedFilteredSortedQueryParams {
filters?: PrimeVueDataFilters;
page?: string;
rows?: string;
sortField?: string;
sortOrder?: string;
}
interface PaginationState {
page: number;
rows: number;
}
interface SortState {
field: undefined | string;
order: undefined | null | 0 | 1 | -1;
field: string;
order: number;
}

export function usePaginatedData(
initialFilters: PrimeVue.PaginatedDataFilters = {},
initialFilters: PrimeVueDataFilters = {},
only: string[] = ['request'],
initialsRows: number = 20
) {
const defaultFilters = initialFilters;
const defaultRows = initialsRows;

const page = usePage<{
request: {
urlParams: PrimeVue.PaginatedDataUrlParams;
urlParams: PaginatedFilteredSortedQueryParams;
};
}>();

const processing = ref<boolean>(false);
const filters = ref<PrimeVue.PaginatedDataFilters>(initialFilters);
const filters = ref<PrimeVueDataFilters>(cloneDeep(initialFilters));
const sorting = ref<SortState>({
field: '',
order: 1,
Expand Down Expand Up @@ -76,7 +76,7 @@ export function usePaginatedData(
router.reload({
only: ['request', ...new Set(only)],
data: {
filters: filters.value,
filters: filters.value as any,
...pagination.value,
sortField: sorting.value.field,
sortOrder: sorting.value.order,
Expand All @@ -95,9 +95,9 @@ export function usePaginatedData(
});
}

function paginate(pageStateEvent: PageStateEvent) {
pagination.value.page = pageStateEvent.page + 1;
pagination.value.rows = pageStateEvent.rows;
function paginate(event: PageState | DataTablePageEvent) {
pagination.value.page = event.page + 1;
pagination.value.rows = event.rows;
fetchData().then(() => {
scrollToTop();
});
Expand All @@ -114,6 +114,7 @@ export function usePaginatedData(
// Alternatively just use: router.get(window.location.pathname);
// Caveat to the above approach, we would lose state from our page not related to pagination/filtering/sorting

const defaultFilters = cloneDeep(initialFilters);
Object.keys(defaultFilters).forEach((key) => {
filters.value[key].value = defaultFilters[key].value;
});
Expand All @@ -123,7 +124,7 @@ export function usePaginatedData(
};
pagination.value = {
page: 1,
rows: defaultRows,
rows: initialsRows,
};
fetchData().then(() => {
window.history.replaceState(null, '', window.location.pathname);
Expand Down Expand Up @@ -167,18 +168,17 @@ export function usePaginatedData(
});
}

function parseUrlParams(urlParams: PrimeVue.PaginatedDataUrlParams) {
function parseUrlParams(urlParams: PaginatedFilteredSortedQueryParams) {
filters.value = {
...defaultFilters,
...cloneDeep(initialFilters),
...urlParams?.filters,
};
parseUrlFilterValues();
if (urlParams?.sortField) {
sorting.value.field = urlParams.sortField;
}
if (urlParams?.sortOrder) {
sorting.value.order =
(parseInt(urlParams.sortOrder) as 0 | 1 | -1) || null;
sorting.value.order = parseInt(urlParams.sortOrder);
}
if (urlParams?.page) {
pagination.value.page = parseInt(urlParams.page);
Expand Down
1 change: 0 additions & 1 deletion resources/js/Layouts/AuthenticatedLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { ref, useTemplateRef, onMounted, onUnmounted, watchEffect } from 'vue';
import { useForm } from '@inertiajs/vue3';
import ApplicationLogo from '@/Components/ApplicationLogo.vue';
import Container from '@/Components/Container.vue';
import LinksMenu from '@/Components/PrimeVue/LinksMenu.vue';
import LinksMenuBar from '@/Components/PrimeVue/LinksMenuBar.vue';
import LinksPanelMenu from '@/Components/PrimeVue/LinksPanelMenu.vue';
Expand Down
2 changes: 0 additions & 2 deletions resources/js/Pages/Dashboard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import Container from '@/Components/Container.vue';
import Heading from '@/Components/Heading.vue';
</script>

Expand Down
3 changes: 0 additions & 3 deletions resources/js/Pages/Profile/Edit.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import Container from '@/Components/Container.vue';
import Heading from '@/Components/Heading.vue';
import DeleteUserForm from './Partials/DeleteUserForm.vue';
import UpdatePasswordForm from './Partials/UpdatePasswordForm.vue';
import UpdateProfileInformationForm from './Partials/UpdateProfileInformationForm.vue';

defineProps({
auth: Object,
mustVerifyEmail: {
type: Boolean,
},
Expand Down
5 changes: 5 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import { ZiggyVue } from '../../vendor/tightenco/ziggy';
import PrimeVue from 'primevue/config';
import ToastService from 'primevue/toastservice';

import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import Container from '@/Components/Container.vue';

import { useDark } from '@vueuse/core';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
Expand All @@ -35,6 +38,8 @@ createInertiaApp({
.use(ToastService)
.component('Head', Head)
.component('Link', Link)
.component('AuthenticatedLayout', AuthenticatedLayout)
.component('Container', Container)
.mount(el);
},
progress: {
Expand Down
6 changes: 6 additions & 0 deletions resources/js/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DataTableFilterMetaData } from 'primevue';

export interface User {
id: number;
name: string;
Expand All @@ -8,3 +10,7 @@ export interface User {
export type PageProps<
T extends Record<string, unknown> = Record<string, unknown>
> = T;

export type PrimeVueDataFilters = {
[key: string]: DataTableFilterMetaData;
};
22 changes: 0 additions & 22 deletions resources/js/types/primevue.d.ts

This file was deleted.

Loading