Merge branch 'feat/server-side-sorting' into 'development'

[FEAT/FE] Server-Side Sorting

See merge request mbugroup/lti-web-client!480
This commit is contained in:
Rivaldi A N S
2026-05-18 04:38:58 +00:00
+66 -18
View File
@@ -1,7 +1,12 @@
'use client'; 'use client';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { CellContext, ColumnDef } from '@tanstack/react-table'; import {
CellContext,
ColumnDef,
SortingState,
Updater,
} from '@tanstack/react-table';
import useSWR from 'swr'; import useSWR from 'swr';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
@@ -183,7 +188,8 @@ const FinanceTable = () => {
bankIds: '', bankIds: '',
customerIds: '', customerIds: '',
supplierIds: '', supplierIds: '',
sortBy: '', sort_by: '',
orderBy: '',
startDate: '', startDate: '',
endDate: '', endDate: '',
bankNames: '', bankNames: '',
@@ -197,7 +203,8 @@ const FinanceTable = () => {
bankIds: 'bank_ids', bankIds: 'bank_ids',
customerIds: 'customer_ids', customerIds: 'customer_ids',
supplierIds: 'supplier_ids', supplierIds: 'supplier_ids',
sortBy: 'sort_date', sort_by: 'sort_by',
orderBy: 'sort_order',
startDate: 'start_date', startDate: 'start_date',
endDate: 'end_date', endDate: 'end_date',
}, },
@@ -248,7 +255,7 @@ const FinanceTable = () => {
updateFilter('bankIds', values.bank_ids, true); updateFilter('bankIds', values.bank_ids, true);
updateFilter('customerIds', values.customer_ids, true); updateFilter('customerIds', values.customer_ids, true);
updateFilter('supplierIds', values.supplier_ids, true); updateFilter('supplierIds', values.supplier_ids, true);
updateFilter('sortBy', values.sort_by, true); updateFilter('sort_by', values.sort_by, true);
updateFilter('startDate', values.start_date, true); updateFilter('startDate', values.start_date, true);
updateFilter('endDate', values.end_date, true); updateFilter('endDate', values.end_date, true);
// Save display names for restoration on modal reopen // Save display names for restoration on modal reopen
@@ -276,7 +283,8 @@ const FinanceTable = () => {
updateFilter('bankIds', '', true); updateFilter('bankIds', '', true);
updateFilter('customerIds', '', true); updateFilter('customerIds', '', true);
updateFilter('supplierIds', '', true); updateFilter('supplierIds', '', true);
updateFilter('sortBy', '', true); updateFilter('sort_by', '', true);
updateFilter('orderBy', '', true);
updateFilter('startDate', '', true); updateFilter('startDate', '', true);
updateFilter('endDate', '', true); updateFilter('endDate', '', true);
updateFilter('bankNames', '', true); updateFilter('bankNames', '', true);
@@ -394,6 +402,26 @@ const FinanceTable = () => {
); );
}; };
const sorting: SortingState = tableFilterState.sort_by
? [
{
id: tableFilterState.sort_by,
desc: tableFilterState.orderBy === '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('orderBy', next[0].desc ? 'desc' : 'asc', true);
} else {
updateFilter('sort_by', '', true);
updateFilter('orderBy', '', true);
}
};
const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => { const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value; const value = e.target.value;
const endDate = filterFormik.values.end_date; const endDate = filterFormik.values.end_date;
@@ -505,7 +533,7 @@ const FinanceTable = () => {
// Restore sort by // Restore sort by
const restoredSortBy = const restoredSortBy =
sortByOptions.find( sortByOptions.find(
(opt) => String(opt.value) === tableFilterState.sortBy (opt) => String(opt.value) === tableFilterState.sort_by
) || null; ) || null;
setSelectedSortBy(restoredSortBy); setSelectedSortBy(restoredSortBy);
@@ -516,7 +544,7 @@ const FinanceTable = () => {
bank_ids: tableFilterState.bankIds || '', bank_ids: tableFilterState.bankIds || '',
customer_ids: tableFilterState.customerIds || '', customer_ids: tableFilterState.customerIds || '',
supplier_ids: tableFilterState.supplierIds || '', supplier_ids: tableFilterState.supplierIds || '',
sort_by: tableFilterState.sortBy || '', sort_by: tableFilterState.sort_by || '',
start_date: tableFilterState.startDate || '', start_date: tableFilterState.startDate || '',
end_date: tableFilterState.endDate || '', end_date: tableFilterState.endDate || '',
}); });
@@ -540,10 +568,12 @@ const FinanceTable = () => {
{ {
header: 'ID', header: 'ID',
accessorKey: 'payment_code', accessorKey: 'payment_code',
enableSorting: true,
}, },
{ {
header: 'References Number', header: 'References Number',
accessorKey: 'reference_number', accessorKey: 'reference_number',
enableSorting: true,
cell: (props: CellContext<Finance, unknown>) => { cell: (props: CellContext<Finance, unknown>) => {
const value = props.row.original.reference_number; const value = props.row.original.reference_number;
return <span>{value ?? '-'}</span>; return <span>{value ?? '-'}</span>;
@@ -552,6 +582,7 @@ const FinanceTable = () => {
{ {
header: 'Jenis Transaksi', header: 'Jenis Transaksi',
accessorKey: 'transaction_type', accessorKey: 'transaction_type',
enableSorting: true,
cell: (props: CellContext<Finance, unknown>) => { cell: (props: CellContext<Finance, unknown>) => {
const value = props.row.original.transaction_type const value = props.row.original.transaction_type
.split('_') .split('_')
@@ -561,7 +592,8 @@ const FinanceTable = () => {
}, },
{ {
header: 'Pihak', header: 'Pihak',
accessorFn: (finance: Finance) => finance.party?.name, accessorKey: 'customer_name',
enableSorting: true,
cell: (props: CellContext<Finance, unknown>) => { cell: (props: CellContext<Finance, unknown>) => {
if (props.row.original.party?.id) { if (props.row.original.party?.id) {
return <span>{props.row.original.party?.name}</span>; return <span>{props.row.original.party?.name}</span>;
@@ -571,16 +603,22 @@ const FinanceTable = () => {
}, },
{ {
header: 'Tanggal Pembayaran', header: 'Tanggal Pembayaran',
accessorFn: (finance: Finance) => accessorKey: 'payment_date',
formatDate(finance.payment_date, 'DD MMM YYYY'), enableSorting: true,
cell: (props) =>
formatDate(props.row.original.payment_date, 'DD MMM YYYY'),
}, },
{ {
header: 'Tanggal Dibuat', header: 'Tanggal Dibuat',
accessorFn: (finance) => formatDate(finance.created_at, 'DD MMM YYYY'), accessorKey: 'created_at',
enableSorting: true,
cell: (props) =>
formatDate(props.row.original.created_at, 'DD MMM YYYY'),
}, },
{ {
header: 'Metode Pembayaran', header: 'Metode Pembayaran',
accessorKey: 'payment_method', accessorKey: 'payment_method',
enableSorting: true,
cell: (props: CellContext<Finance, unknown>) => { cell: (props: CellContext<Finance, unknown>) => {
const value = props.row.original.payment_method.split('_').join(' '); const value = props.row.original.payment_method.split('_').join(' ');
return <span>{formatTitleCase(value)}</span>; return <span>{formatTitleCase(value)}</span>;
@@ -588,20 +626,26 @@ const FinanceTable = () => {
}, },
{ {
header: 'Bank', header: 'Bank',
accessorFn: (finance: Finance) => accessorKey: 'bank',
finance.bank enableSorting: true,
? `${finance.bank?.alias} - ${finance.bank?.account_number} - ${finance.bank?.owner}` cell: (props) =>
props.row.original.bank
? `${props.row.original.bank?.alias} - ${props.row.original.bank?.account_number} - ${props.row.original.bank?.owner}`
: '-', : '-',
}, },
{ {
header: 'Pengeluaran (Rp)', header: 'Pengeluaran (Rp)',
accessorFn: (finance: Finance) => accessorKey: 'expense_amount',
formatCurrency(Math.abs(finance.expense_amount)), enableSorting: true,
cell: (props) =>
formatCurrency(Math.abs(props.row.original.expense_amount)),
}, },
{ {
header: 'Pemasukan (Rp)', header: 'Pemasukan (Rp)',
accessorFn: (finance: Finance) => accessorKey: 'income_amount',
formatCurrency(Math.abs(finance.income_amount)), enableSorting: true,
cell: (props) =>
formatCurrency(Math.abs(props.row.original.income_amount)),
}, },
{ {
header: 'Aksi', header: 'Aksi',
@@ -707,6 +751,7 @@ const FinanceTable = () => {
'page', 'page',
'pageSize', 'pageSize',
'search', 'search',
'orderBy',
'bankNames', 'bankNames',
'customerNames', 'customerNames',
'supplierNames', 'supplierNames',
@@ -749,6 +794,9 @@ const FinanceTable = () => {
onPageChange={setPage} onPageChange={setPage}
onPageSizeChange={setPageSize} onPageSizeChange={setPageSize}
isLoading={isLoading} isLoading={isLoading}
sorting={sorting}
setSorting={handleSortingChange}
manualSorting
className={{ className={{
containerClassName: cn('p-3 mb-0'), containerClassName: cn('p-3 mb-0'),
headerColumnClassName: 'text-nowrap', headerColumnClassName: 'text-nowrap',