feat: add server-side table sorting
This commit is contained in:
@@ -65,6 +65,7 @@ export function usePlanColumns({
|
||||
{
|
||||
id: 'limits',
|
||||
header: 'Limits',
|
||||
enableSorting: false,
|
||||
cell: ({ row }) => (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
<p>{row.original.max_projects} projects</p>
|
||||
@@ -96,6 +97,7 @@ export function usePlanColumns({
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <div className="text-right">Actions</div>,
|
||||
enableSorting: false,
|
||||
cell: ({ row }) => {
|
||||
const plan = row.original;
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import type { ColumnDef } from '@tanstack/react-table';
|
||||
import type { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { DataTable } from '@/components/data-table';
|
||||
import type { Plan } from '@/types';
|
||||
@@ -14,8 +14,10 @@ interface PlanTableProps {
|
||||
skip: number;
|
||||
limit: number;
|
||||
total: number;
|
||||
sorting: SortingState;
|
||||
onPageChange: (skip: number) => void;
|
||||
onLimitChange: (limit: number) => void;
|
||||
onSortingChange: (sorting: SortingState) => void;
|
||||
}
|
||||
|
||||
export function PlanTable({
|
||||
@@ -26,8 +28,10 @@ export function PlanTable({
|
||||
skip,
|
||||
limit,
|
||||
total,
|
||||
sorting,
|
||||
onPageChange,
|
||||
onLimitChange,
|
||||
onSortingChange,
|
||||
}: PlanTableProps) {
|
||||
return (
|
||||
<DataTable
|
||||
@@ -44,6 +48,8 @@ export function PlanTable({
|
||||
onPageChange,
|
||||
onLimitChange,
|
||||
}}
|
||||
sorting={sorting}
|
||||
onSortingChange={onSortingChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import type { SortingState } from '@tanstack/react-table';
|
||||
import { useDebounce } from '@/hooks/useDebounce';
|
||||
|
||||
export type PlanStatusFilter = 'all' | 'active' | 'inactive';
|
||||
@@ -8,6 +9,7 @@ export type PlanStatusFilter = 'all' | 'active' | 'inactive';
|
||||
export function usePlanFilters() {
|
||||
const [skip, setSkip] = useState(0);
|
||||
const [limit, setLimitValue] = useState(10);
|
||||
const [sorting, setSortingValue] = useState<SortingState>([]);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [statusFilter, setStatusFilter] = useState<PlanStatusFilter>('all');
|
||||
const debouncedSearchTerm = useDebounce(searchTerm, 400);
|
||||
@@ -27,11 +29,18 @@ export function usePlanFilters() {
|
||||
setSkip(0);
|
||||
};
|
||||
|
||||
const setSorting = (value: SortingState) => {
|
||||
setSortingValue(value);
|
||||
setSkip(0);
|
||||
};
|
||||
|
||||
return {
|
||||
skip,
|
||||
setSkip,
|
||||
limit,
|
||||
setLimit,
|
||||
sorting,
|
||||
setSorting,
|
||||
searchTerm,
|
||||
debouncedSearchTerm,
|
||||
setSearchTerm: updateSearchTerm,
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import type { SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { getServerSortParams } from '@/components/data-table/sorting';
|
||||
import { mapPermissionTree } from '@/components/permission-tree';
|
||||
import { permissionService, planService } from '@/services/api';
|
||||
import type { PlanListParams } from '@/types';
|
||||
@@ -15,6 +17,7 @@ interface UsePlansQueryParams {
|
||||
limit: number;
|
||||
searchTerm: string;
|
||||
statusFilter: PlanStatusFilter;
|
||||
sorting: SortingState;
|
||||
}
|
||||
|
||||
function buildPlanListParams({
|
||||
@@ -22,14 +25,14 @@ function buildPlanListParams({
|
||||
limit,
|
||||
searchTerm,
|
||||
statusFilter,
|
||||
sorting,
|
||||
}: UsePlansQueryParams): PlanListParams {
|
||||
return {
|
||||
skip,
|
||||
limit,
|
||||
search_term: searchTerm || undefined,
|
||||
is_active: statusFilter === 'all' ? undefined : statusFilter === 'active',
|
||||
sort_by: 'created_at',
|
||||
sort_order: 'desc',
|
||||
...getServerSortParams(sorting),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ export default function PlansPage() {
|
||||
setSkip,
|
||||
limit,
|
||||
setLimit,
|
||||
sorting,
|
||||
setSorting,
|
||||
searchTerm,
|
||||
debouncedSearchTerm,
|
||||
setSearchTerm,
|
||||
@@ -40,6 +42,7 @@ export default function PlansPage() {
|
||||
limit,
|
||||
searchTerm: debouncedSearchTerm,
|
||||
statusFilter,
|
||||
sorting,
|
||||
});
|
||||
const permissionsQuery = useOrganizationPermissionTreeQuery(isSheetOpen);
|
||||
|
||||
@@ -166,8 +169,10 @@ export default function PlansPage() {
|
||||
skip={skip}
|
||||
limit={limit}
|
||||
total={total}
|
||||
sorting={sorting}
|
||||
onPageChange={setSkip}
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
|
||||
Reference in New Issue
Block a user