feat(tables): implement sortable columns across various table components

- Added TableSortProvider to manage sorting state in AdminsTable, CmsTable, CompaniesTable, CustomersTable, TendersTable, and CompanyCategoriesTable.
- Enhanced TableHead component to support sortable columns with visual indicators for sort direction.
- Introduced columnSortKeys and columnDefaultOrder mappings in respective table presenters to define sortable fields and default sorting behavior.
- Updated useCompanyListPresenter, useCmsTablePresenter, useCustomerListPresenter, useTenderListPresenter, and useCompanyCategoriesPresenter to handle sorting logic and state management.
- Improved user experience by allowing dynamic sorting of table data based on user interactions.
This commit is contained in:
AmirReza Jamali
2026-05-31 10:48:08 +03:30
parent 5ef0298840
commit 46ddc018a6
16 changed files with 971 additions and 54 deletions
@@ -1,5 +1,6 @@
"use client";
import { ConfirmationModalProps } from "@/components/ui/ConfirmationModal";
import { SortDirection } from "@/components/ui/tableSortContext";
import { apiDefaultParams } from "@/constants/Api_Params";
import { useTendersQuery } from "@/hooks/queries";
import { useHybridPagination } from "@/hooks/useHybridPagination";
@@ -506,9 +507,50 @@ const useTenderListPresenter = () => {
"status",
"actions",
];
/** Column label → BSON `sort_by` field (see bp-panel-list-sorting.md). */
const columnSortKeys: Record<string, string> = {
title: "title",
"country code": "country_code",
"publication date": "publication_date",
"submission deadline": "submission_deadline",
"tender deadline": "tender_deadline",
"created at": "created_at",
status: "status",
};
/** First-click direction per column, following the BP sorting UX guide. */
const columnDefaultOrder: Record<string, SortDirection> = {
title: "asc",
"submission deadline": "asc",
"tender deadline": "asc",
};
const sortBy = (params.sort_by as string) ?? "created_at";
const sortOrder = (params.sort_order as SortDirection) ?? "desc";
const handleSortChange = useCallback(
(key: string, order: SortDirection) => {
const newParams = buildFirstPageParams({
...params,
sort_by: key,
sort_order: order,
});
const cleanedParams = deleteEmptyKeys(newParams);
const queryString = buildQueryString(cleanedParams);
router.push(`${pathName}?${queryString}`);
},
[buildFirstPageParams, params, pathName, router],
);
return {
currentTender,
columns,
columnSortKeys,
columnDefaultOrder,
sortBy,
sortOrder,
handleSortChange,
setCurrentTender,
router,
allTenders: data,