Merge branch 'feat/marketing-table-order' into 'development'

[FEAT/FE] Marketing Table Order

See merge request mbugroup/lti-web-client!467
This commit is contained in:
Rivaldi A N S
2026-05-09 03:57:29 +00:00
4 changed files with 10 additions and 10 deletions
+4 -2
View File
@@ -192,12 +192,14 @@ Data tables use TanStack Table's `SortingState` wired to `useTableFilter` so tha
4. **SWR key** — SWR uses `getTableFilterToQueryString()` as its key, so any filter change (including sort) automatically re-fetches with the new query params. TanStack Table's built-in client sorting is effectively disabled; the server does the sorting. 4. **SWR key** — SWR uses `getTableFilterToQueryString()` as its key, so any filter change (including sort) automatically re-fetches with the new query params. TanStack Table's built-in client sorting is effectively disabled; the server does the sorting.
**Pass `sorting` / `setSorting` to `<Table>`:** **Pass `sorting`, `setSorting`, and `manualSorting` to `<Table>`:**
```tsx ```tsx
<Table sorting={sorting} setSorting={setSorting} ... /> <Table sorting={sorting} setSorting={handleSortingChange} manualSorting={true} ... />
``` ```
`manualSorting={true}` is required — without it TanStack Table still applies its own client-side sort pass on top of the server-sorted data, producing incorrect order.
**Reference implementation:** `MarketingTable` in [src/components/pages/marketing/MarketingTable.tsx](src/components/pages/marketing/MarketingTable.tsx). **Reference implementation:** `MarketingTable` in [src/components/pages/marketing/MarketingTable.tsx](src/components/pages/marketing/MarketingTable.tsx).
## Server-side file export pattern ## Server-side file export pattern
@@ -548,21 +548,15 @@ const ExpenseRequestContent = ({
<ul className='list-disc'> <ul className='list-disc'>
{initialValues?.documents.map( {initialValues?.documents.map(
(requestDocument, requestDocumentIdx) => { (requestDocument, requestDocumentIdx) => {
const path = requestDocument.path.startsWith(
'/'
)
? requestDocument.path.slice(1)
: requestDocument.path;
const documentUrl = `${S3_PUBLIC_BASE_URL}/${path}`;
return ( return (
<li key={requestDocumentIdx}> <li key={requestDocumentIdx}>
<Link <Link
href={documentUrl} href={requestDocument.path}
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
className='text-blue-500 underline' className='text-blue-500 underline'
> >
{requestDocument.path}{' '} {requestDocument.name}{' '}
<Icon <Icon
icon='cuida:open-in-new-tab-outline' icon='cuida:open-in-new-tab-outline'
width={12} width={12}
@@ -883,6 +883,8 @@ const MarketingTable = () => {
'customer_name', 'customer_name',
'project_flock_name', 'project_flock_name',
'project_flock_kandang_name', 'project_flock_kandang_name',
'sort_by',
'order_by',
]} ]}
onClick={() => { onClick={() => {
filterModal.openModal(); filterModal.openModal();
@@ -975,6 +977,7 @@ const MarketingTable = () => {
page={isResponseSuccess(marketing) ? marketing?.meta?.page : 1} page={isResponseSuccess(marketing) ? marketing?.meta?.page : 1}
sorting={sorting} sorting={sorting}
setSorting={handleSortingChange} setSorting={handleSortingChange}
manualSorting
totalItems={ totalItems={
isResponseSuccess(marketing) isResponseSuccess(marketing)
? marketing?.meta?.total_results ? marketing?.meta?.total_results
+1
View File
@@ -10,6 +10,7 @@ export type BaseExpense = {
category: 'BOP' | 'NON-BOP'; category: 'BOP' | 'NON-BOP';
documents?: { documents?: {
id: number; id: number;
name: string;
path: string; path: string;
}[]; }[];
realization_docs?: { realization_docs?: {