UI/UX Specification: Mandatory Row Numbers (STT) and Pagination for All CMS Tables
Last Updated: 16/07/2026
Type: UI/UX Standardization Spec β Table Controls
Scope: All Swizzled CMS Data Tables (excluding CMS Articles/Events which already implement this)
Severity: π Medium β Critical for usability, listing clarity, and backend query optimization when datasets grow
Feedback Reference:
1. The Issue & Standard Requirementβ
Currently, only a few tables under the CMS group (Articles, Events, Banners) display row indices (STT) and footer pagination controls.
Most other system management tables under other sections lack these controls:
- Booking Group: Booking List (Danh sΓ‘ch booking), Spa Services (Dα»ch vα»₯ spa)
- Minigame Group: Spin History (Lα»ch sα» quay)
- Voucher Group: Vouchers list, Voucher Redemptions
- Membership Group: Membership tiers list, Point transfers
Standard Requirement:β
Every data table in the Admin CMS must implement:
- An Index Column (
STT) as the very first column. - A Pagination Footer supporting page index controls and total item count labels.
2. Table Layout Standard Specificationβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [π Search...] [+ Add Item] β
ββββββββ¬βββββββββββββββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬βββββββββ€
β STT β Main Identifier β Attribute 1 β Attribute 2 β Actionsβ
ββββββββΌβββββββββββββββββββββββββββΌβββββββββββββββΌβββββββββββββββΌβββββββββ€
β 1 β Item Name A β Value 1 β Value 2 β βοΈ π β
β 2 β Item Name B β Value 1 β Value 2 β βοΈ π β
ββββββββ΄βββββββββββββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββ€
β Hiα»n thα» 1β10 / 48 kαΊΏt quαΊ£ [TrΖ°α»c] [1] [2] [Sau] β β Standard Footer
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3. Implementation Detailsβ
3.1 First Column: STT (Row Index) Calculationβ
The row index should account for the current page number to prevent index resets when changing pages:
// Index calculator formula
const getRowIndex = (indexInCurrentPage: number, currentPage: number, pageSize: number): number => {
return (currentPage - 1) * pageSize + indexInCurrentPage + 1;
};
3.2 Pagination Footer Specsβ
The footer component must be rendered right below the table boundary and contain:
- Left Label:
"Hiα»n thα» [Start]β[End] / [Total] kαΊΏt quαΊ£"Start = (currentPage - 1) * pageSize + 1End = Math.min(currentPage * pageSize, totalItems)
- Right Page Buttons:
[TrΖ°α»c](Previous) button: disabled ifcurrentPage === 1.- Numbered page pills: e.g.,
[1],[2],[3](active page highlighted in brand color). [Sau](Next) button: disabled ifcurrentPage === totalPages.
4. API Pagination Requirements (Backend Integration)β
All backend fetch endpoints for lists must support offset-based pagination query parameters:
// GET /api/cms/services?page=2&pageSize=10
interface PaginatedResponse<T> {
items: T[];
totalCount: number;
totalPages: number;
currentPage: number;
pageSize: number;
}
5. Affected Screens Audit Listβ
Ensure the following screens are updated to comply with this layout standard:
| Section / Menu | View File / Component | Required Actions |
|---|---|---|
| Booking > Booking List | BookingListTable.tsx | Add STT column & Pagination footer |
| Booking > Spa Services | SpaServicesListTable.tsx | Add STT column & Pagination footer |
| Minigame > Spin History | SpinHistoryTable.tsx | Add STT column & Pagination footer |
| Voucher > Vouchers | VouchersTable.tsx | Add STT column & Pagination footer |
| Voucher > Redemptions | VoucherRedemptionsTable.tsx | Add STT column & Pagination footer |
| Membership > Tiers | MembershipTiersTable.tsx | Add STT column (Pagination optional if total tiers <= 10) |
| Point transfers | PointTransfersTable.tsx | Add STT column & Pagination footer |
Technical Checklistβ
- Build a reusable
<TablePaginationFooter />component in the CMS theme library. - Update the global list container layout template to always append the pagination footer.
- Go through the affected screens audit list one-by-one.
- Add the
STTheader block and render index calculations in the first cell of the rows. - Connect the
onChangePagecallback from the footer to trigger API calls with updated page offsets. - Verify sorting: ensure changing sort fields does not reset page indexes incorrectly.
- Run build validation to ensure consistent layout compile targets.