mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
feat: implement server-side sorting
This commit is contained in:
@@ -2,7 +2,12 @@
|
||||
|
||||
import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
import {
|
||||
CellContext,
|
||||
ColumnDef,
|
||||
SortingState,
|
||||
Updater,
|
||||
} from '@tanstack/react-table';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
import Link from 'next/link';
|
||||
@@ -34,6 +39,8 @@ import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
|
||||
|
||||
type PurchaseTableFilters = {
|
||||
search: string;
|
||||
sort_by: string;
|
||||
order_by: string;
|
||||
po_date: string;
|
||||
approval_status: string;
|
||||
product_category_id: string;
|
||||
@@ -157,18 +164,6 @@ const RowOptionsMenu = ({
|
||||
};
|
||||
|
||||
const PurchaseTable = () => {
|
||||
// ===== STATE MANAGEMENT =====
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
|
||||
useState(false);
|
||||
const [isExportProgressLoading, setIsExportProgressLoading] = useState(false);
|
||||
const [selectedPurchase, setSelectedPurchase] = useState<Purchase | null>(
|
||||
null
|
||||
);
|
||||
const [exportProgressStartDate, setExportProgressStartDate] = useState('');
|
||||
const [exportProgressEndDate, setExportProgressEndDate] = useState('');
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
|
||||
// ===== TABLE FILTER STATE =====
|
||||
const {
|
||||
state: tableFilterState,
|
||||
@@ -180,6 +175,8 @@ const PurchaseTable = () => {
|
||||
} = useTableFilter<PurchaseTableFilters>({
|
||||
initial: {
|
||||
search: '',
|
||||
sort_by: '',
|
||||
order_by: '',
|
||||
po_date: '',
|
||||
approval_status: '',
|
||||
product_category_id: '',
|
||||
@@ -198,6 +195,8 @@ const PurchaseTable = () => {
|
||||
paramMap: {
|
||||
page: 'page',
|
||||
pageSize: 'limit',
|
||||
sort_by: 'sort_by',
|
||||
order_by: 'sort_order',
|
||||
po_date: 'po_date',
|
||||
approval_status: 'approval_status',
|
||||
product_category_id: 'product_category_id',
|
||||
@@ -219,6 +218,36 @@ const PurchaseTable = () => {
|
||||
storeName: 'purchase-table',
|
||||
});
|
||||
|
||||
// ===== STATE MANAGEMENT =====
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
|
||||
useState(false);
|
||||
const [isExportProgressLoading, setIsExportProgressLoading] = useState(false);
|
||||
const [selectedPurchase, setSelectedPurchase] = useState<Purchase | null>(
|
||||
null
|
||||
);
|
||||
const [exportProgressStartDate, setExportProgressStartDate] = useState('');
|
||||
const [exportProgressEndDate, setExportProgressEndDate] = useState('');
|
||||
const sorting: SortingState = tableFilterState.sort_by
|
||||
? [
|
||||
{
|
||||
id: tableFilterState.sort_by,
|
||||
desc: tableFilterState.order_by === 'desc',
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
||||
const handleSortingChange = (updater: Updater<SortingState>) => {
|
||||
const next = typeof updater === 'function' ? updater(sorting) : updater;
|
||||
if (next.length > 0) {
|
||||
updateFilter('sort_by', next[0].id, true);
|
||||
updateFilter('order_by', next[0].desc ? 'desc' : 'asc', true);
|
||||
} else {
|
||||
updateFilter('sort_by', '', true);
|
||||
updateFilter('order_by', '', true);
|
||||
}
|
||||
};
|
||||
|
||||
// ===== MODAL HOOKS =====
|
||||
const filterModal = useModal();
|
||||
const deleteModal = useModal();
|
||||
@@ -238,6 +267,7 @@ const PurchaseTable = () => {
|
||||
const purchaseColumns: ColumnDef<Purchase>[] = [
|
||||
{
|
||||
header: 'No. PR/PO',
|
||||
enableSorting: false,
|
||||
cell: (props) => {
|
||||
const { pr_number, po_number } = props.row.original;
|
||||
return po_number ? po_number : pr_number;
|
||||
@@ -278,7 +308,7 @@ const PurchaseTable = () => {
|
||||
cell: (props) => props.row.original.requester_name || '-',
|
||||
},
|
||||
{
|
||||
accessorKey: 'products.name',
|
||||
accessorKey: 'products',
|
||||
header: 'Produk',
|
||||
cell: (props) => {
|
||||
const products = props.row.original.products;
|
||||
@@ -293,7 +323,7 @@ const PurchaseTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'location.name',
|
||||
accessorKey: 'location',
|
||||
header: 'Lokasi',
|
||||
cell: (props) => props.row.original.location?.name || '-',
|
||||
},
|
||||
@@ -323,6 +353,7 @@ const PurchaseTable = () => {
|
||||
},
|
||||
{
|
||||
header: 'Aging',
|
||||
enableSorting: false,
|
||||
cell: (props) => {
|
||||
const purchase = props.row.original;
|
||||
if (!purchase.po_date) return '-';
|
||||
@@ -334,6 +365,7 @@ const PurchaseTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'status',
|
||||
header: 'Status Approval',
|
||||
cell: (props) => {
|
||||
const approval = props.row.original.latest_approval;
|
||||
@@ -378,6 +410,14 @@ const PurchaseTable = () => {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
header: 'Tanggal Dibuat',
|
||||
cell: (props) =>
|
||||
props.row.original.created_at
|
||||
? formatDate(props.row.original.created_at, 'DD MMM YYYY')
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
header: 'Aksi',
|
||||
cell: (props) => {
|
||||
@@ -658,6 +698,7 @@ const PurchaseTable = () => {
|
||||
'search',
|
||||
'filter_by',
|
||||
'sort_by',
|
||||
'order_by',
|
||||
'product_category_name',
|
||||
'supplier_name',
|
||||
'area_name',
|
||||
@@ -771,7 +812,8 @@ const PurchaseTable = () => {
|
||||
onPageSizeChange={setPageSize}
|
||||
isLoading={isLoading}
|
||||
sorting={sorting}
|
||||
setSorting={setSorting}
|
||||
setSorting={handleSortingChange}
|
||||
manualSorting
|
||||
className={{
|
||||
containerClassName: cn('p-3 mb-0'),
|
||||
headerColumnClassName: 'text-nowrap',
|
||||
|
||||
Reference in New Issue
Block a user