mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-22 06:15:47 +00:00
feat: implement server-side sorting
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import axios from 'axios';
|
||||
import Button from '@/components/Button';
|
||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||
import DateInput from '@/components/input/DateInput';
|
||||
@@ -27,7 +26,13 @@ import {
|
||||
MarketingFilter,
|
||||
} from '@/types/api/marketing/marketing';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { CellContext, ColumnDef, Row } from '@tanstack/react-table';
|
||||
import {
|
||||
CellContext,
|
||||
ColumnDef,
|
||||
Row,
|
||||
SortingState,
|
||||
Updater,
|
||||
} from '@tanstack/react-table';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
@@ -198,6 +203,8 @@ const MarketingTable = () => {
|
||||
project_flock_name: '',
|
||||
project_flock_kandang_id: '',
|
||||
project_flock_kandang_name: '',
|
||||
sort_by: '',
|
||||
order_by: '',
|
||||
},
|
||||
paramMap: {
|
||||
page: 'page',
|
||||
@@ -207,6 +214,8 @@ const MarketingTable = () => {
|
||||
customer_id: 'customer_id',
|
||||
project_flock_id: 'project_flock_id',
|
||||
project_flock_kandang_id: 'project_flock_kandang_id',
|
||||
sort_by: 'sort_by',
|
||||
order_by: 'sort_order',
|
||||
},
|
||||
excludeKeysFromUrl: [
|
||||
'product_names',
|
||||
@@ -220,6 +229,26 @@ const MarketingTable = () => {
|
||||
storeName: 'marketing-table',
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
// ===== FETCH DATA =====
|
||||
const {
|
||||
data: marketing,
|
||||
@@ -359,55 +388,50 @@ const MarketingTable = () => {
|
||||
? 'DELIVERY_ORDER'
|
||||
: null;
|
||||
|
||||
const marketingFilterInitialValues = useMemo(() => {
|
||||
const productIds = tableFilterState.product_ids
|
||||
? tableFilterState.product_ids
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
const productIds = tableFilterState.product_ids
|
||||
? tableFilterState.product_ids
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
const productLabels = tableFilterState.product_names
|
||||
? tableFilterState.product_names
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
const productLabels = tableFilterState.product_names
|
||||
? tableFilterState.product_names
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
return {
|
||||
product_ids: productIds.map((value, idx) => ({
|
||||
value: Number(value),
|
||||
label: productLabels[idx] || '-',
|
||||
})),
|
||||
status: tableFilterState.status
|
||||
? {
|
||||
value: tableFilterState.status,
|
||||
label: tableFilterState.status_name,
|
||||
}
|
||||
: null,
|
||||
|
||||
customer: tableFilterState.customer_id
|
||||
? {
|
||||
value: Number(tableFilterState.customer_id),
|
||||
label: tableFilterState.customer_name,
|
||||
}
|
||||
: null,
|
||||
|
||||
project_flock: tableFilterState.project_flock_id
|
||||
? {
|
||||
value: Number(tableFilterState.project_flock_id),
|
||||
label: tableFilterState.project_flock_name,
|
||||
}
|
||||
: null,
|
||||
|
||||
project_flock_kandang: tableFilterState.project_flock_kandang_id
|
||||
? {
|
||||
value: Number(tableFilterState.project_flock_kandang_id),
|
||||
label: tableFilterState.project_flock_kandang_name,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
}, [tableFilterState]);
|
||||
const marketingFilterInitialValues = {
|
||||
product_ids: productIds.map((value, idx) => ({
|
||||
value: Number(value),
|
||||
label: productLabels[idx] || '-',
|
||||
})),
|
||||
status: tableFilterState.status
|
||||
? {
|
||||
value: tableFilterState.status,
|
||||
label: tableFilterState.status_name,
|
||||
}
|
||||
: null,
|
||||
customer: tableFilterState.customer_id
|
||||
? {
|
||||
value: Number(tableFilterState.customer_id),
|
||||
label: tableFilterState.customer_name,
|
||||
}
|
||||
: null,
|
||||
project_flock: tableFilterState.project_flock_id
|
||||
? {
|
||||
value: Number(tableFilterState.project_flock_id),
|
||||
label: tableFilterState.project_flock_name,
|
||||
}
|
||||
: null,
|
||||
project_flock_kandang: tableFilterState.project_flock_kandang_id
|
||||
? {
|
||||
value: Number(tableFilterState.project_flock_kandang_id),
|
||||
label: tableFilterState.project_flock_kandang_name,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
|
||||
const approveMarketingHandler = async (notes: string) => {
|
||||
if (idsToProcess.length === 0) {
|
||||
@@ -542,27 +566,29 @@ const MarketingTable = () => {
|
||||
setIsLoadingExportingToExcel(false);
|
||||
};
|
||||
|
||||
const resetExportProgressForm = useCallback(() => {
|
||||
const resetExportProgressForm = () => {
|
||||
setExportProgressStartDate('');
|
||||
setExportProgressEndDate('');
|
||||
}, []);
|
||||
};
|
||||
|
||||
const exportProgressStartDateChangeHandler: ChangeEventHandler<HTMLInputElement> =
|
||||
useCallback((e) => {
|
||||
setExportProgressStartDate(e.target.value);
|
||||
}, []);
|
||||
const exportProgressStartDateChangeHandler: ChangeEventHandler<
|
||||
HTMLInputElement
|
||||
> = (e) => {
|
||||
setExportProgressStartDate(e.target.value);
|
||||
};
|
||||
|
||||
const exportProgressEndDateChangeHandler: ChangeEventHandler<HTMLInputElement> =
|
||||
useCallback((e) => {
|
||||
setExportProgressEndDate(e.target.value);
|
||||
}, []);
|
||||
const exportProgressEndDateChangeHandler: ChangeEventHandler<
|
||||
HTMLInputElement
|
||||
> = (e) => {
|
||||
setExportProgressEndDate(e.target.value);
|
||||
};
|
||||
|
||||
const exportProgressInputToExcelClickHandler = useCallback(() => {
|
||||
const exportProgressInputToExcelClickHandler = () => {
|
||||
resetExportProgressForm();
|
||||
exportProgressInputModal.openModal();
|
||||
}, [exportProgressInputModal, resetExportProgressForm]);
|
||||
};
|
||||
|
||||
const submitExportProgressInputHandler = useCallback(async () => {
|
||||
const submitExportProgressInputHandler = async () => {
|
||||
if (!exportProgressStartDate || !exportProgressEndDate) {
|
||||
return;
|
||||
}
|
||||
@@ -585,12 +611,7 @@ const MarketingTable = () => {
|
||||
} finally {
|
||||
setIsExportProgressLoading(false);
|
||||
}
|
||||
}, [
|
||||
exportProgressEndDate,
|
||||
exportProgressInputModal,
|
||||
exportProgressStartDate,
|
||||
resetExportProgressForm,
|
||||
]);
|
||||
};
|
||||
|
||||
const columns = useMemo<ColumnDef<Marketing>[]>(() => {
|
||||
return [
|
||||
@@ -656,7 +677,7 @@ const MarketingTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'so_do_number',
|
||||
accessorKey: 'so_number',
|
||||
header: 'No. Order',
|
||||
cell: (props) => {
|
||||
return props.row.original.do_number
|
||||
@@ -672,7 +693,7 @@ const MarketingTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'approval.step_name',
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: (props) => {
|
||||
const approval = props.row.original.latest_approval;
|
||||
@@ -707,10 +728,12 @@ const MarketingTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: 'customer.name',
|
||||
accessorKey: 'customer',
|
||||
header: 'Customer',
|
||||
cell: (props) => props.row.original.customer.name,
|
||||
},
|
||||
{
|
||||
accessorKey: 'grand_total',
|
||||
accessorFn: (row) =>
|
||||
row.sales_order
|
||||
?.map((product) => product.total_price)
|
||||
@@ -727,6 +750,7 @@ const MarketingTable = () => {
|
||||
{
|
||||
accessorKey: 'marketing_products.length',
|
||||
header: 'Product Details',
|
||||
enableSorting: false,
|
||||
cell: (props) => {
|
||||
if (props?.row?.original?.sales_order?.length) {
|
||||
if (props?.row?.original?.sales_order?.length > 1) {
|
||||
@@ -949,6 +973,8 @@ const MarketingTable = () => {
|
||||
columns={columns}
|
||||
pageSize={tableFilterState.pageSize}
|
||||
page={isResponseSuccess(marketing) ? marketing?.meta?.page : 1}
|
||||
sorting={sorting}
|
||||
setSorting={handleSortingChange}
|
||||
totalItems={
|
||||
isResponseSuccess(marketing)
|
||||
? marketing?.meta?.total_results
|
||||
|
||||
Reference in New Issue
Block a user