123 lines
3.1 KiB
Markdown
123 lines
3.1 KiB
Markdown
|
|
# Time Entries Sorting Fix
|
||
|
|
|
||
|
|
## Problem
|
||
|
|
The sort buttons on the time entries data browser page were not working. Clicking column headers to sort had no effect.
|
||
|
|
|
||
|
|
## Root Cause
|
||
|
|
The `DataTable` component expects an `onSort` callback prop, but the time-entries page was not providing it.
|
||
|
|
|
||
|
|
**Missing in original code:**
|
||
|
|
```typescript
|
||
|
|
<DataTable
|
||
|
|
data={timeEntries}
|
||
|
|
columns={columns}
|
||
|
|
// ... other props
|
||
|
|
// ❌ onSort prop was missing
|
||
|
|
/>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Solution
|
||
|
|
|
||
|
|
### 1. Added Sort State
|
||
|
|
```typescript
|
||
|
|
// Sort states
|
||
|
|
const [sortBy, setSortBy] = useState('entry_date');
|
||
|
|
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Updated fetchTimeEntries to Include Sort Parameters
|
||
|
|
```typescript
|
||
|
|
params.append('sort_by', sortBy);
|
||
|
|
params.append('sort_order', sortOrder);
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Created handleSort Function
|
||
|
|
```typescript
|
||
|
|
const handleSort = async (column: string, direction: 'asc' | 'desc') => {
|
||
|
|
setSortBy(column);
|
||
|
|
setSortOrder(direction);
|
||
|
|
|
||
|
|
// Fetch with new sort parameters
|
||
|
|
// ... builds params with new sort values
|
||
|
|
// Resets to page 1 when sorting changes
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Passed onSort to DataTable
|
||
|
|
```typescript
|
||
|
|
<DataTable
|
||
|
|
data={timeEntries}
|
||
|
|
columns={columns}
|
||
|
|
isLoading={loading}
|
||
|
|
onRowClick={handleRowClick}
|
||
|
|
totalCount={totalCount}
|
||
|
|
page={currentPage}
|
||
|
|
pageSize={pageSize}
|
||
|
|
onPageChange={handlePageChange}
|
||
|
|
onSort={handleSort} // ✅ Now provided
|
||
|
|
/>
|
||
|
|
```
|
||
|
|
|
||
|
|
## How It Works
|
||
|
|
|
||
|
|
1. **User clicks column header** → DataTable calls `onSort(columnKey, direction)`
|
||
|
|
2. **handleSort updates state** → Sets `sortBy` and `sortOrder`
|
||
|
|
3. **handleSort fetches data** → Calls API with `sort_by` and `sort_order` params
|
||
|
|
4. **Page resets to 1** → Sorting always shows results from the first page
|
||
|
|
5. **Table updates** → New sorted data is displayed
|
||
|
|
|
||
|
|
## API Parameters
|
||
|
|
|
||
|
|
The API endpoint `/api/data/time-entries` accepts:
|
||
|
|
- `sort_by` - Column name to sort by (e.g., 'entry_date', 'hours_worked', 'resource_id')
|
||
|
|
- `sort_order` - Sort direction: 'asc' or 'desc'
|
||
|
|
|
||
|
|
**Valid sort columns:**
|
||
|
|
- `entry_date`
|
||
|
|
- `hours_worked`
|
||
|
|
- `created_at`
|
||
|
|
- `updated_at`
|
||
|
|
- `resource_id`
|
||
|
|
- `ticket_id`
|
||
|
|
- `task_id`
|
||
|
|
- `project_id`
|
||
|
|
- `company_id`
|
||
|
|
- `title`
|
||
|
|
- `billable`
|
||
|
|
- `approved`
|
||
|
|
|
||
|
|
## Default Sorting
|
||
|
|
- **Column**: `entry_date`
|
||
|
|
- **Order**: `desc` (newest first)
|
||
|
|
|
||
|
|
## User Experience
|
||
|
|
|
||
|
|
### Before Fix
|
||
|
|
- ❌ Clicking column headers did nothing
|
||
|
|
- ❌ No visual feedback
|
||
|
|
- ❌ Data remained in default order
|
||
|
|
|
||
|
|
### After Fix
|
||
|
|
- ✅ Clicking column headers sorts the data
|
||
|
|
- ✅ Arrow icons show current sort direction
|
||
|
|
- ✅ Data updates immediately
|
||
|
|
- ✅ Resets to page 1 when sorting changes
|
||
|
|
- ✅ Loading indicator shows during fetch
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
To test sorting:
|
||
|
|
1. Navigate to `/admin/data-browser/time-entries`
|
||
|
|
2. Click any column header with a sort icon
|
||
|
|
3. Verify data is sorted correctly
|
||
|
|
4. Click again to reverse sort direction
|
||
|
|
5. Verify arrow icon changes direction
|
||
|
|
6. Verify page resets to 1 when sorting
|
||
|
|
|
||
|
|
## Files Modified
|
||
|
|
- `/app/admin/data-browser/time-entries/page.tsx` - Added sort state and handler
|
||
|
|
|
||
|
|
## Related Components
|
||
|
|
- `/components/admin/DataTable.tsx` - Generic table component with sort support
|
||
|
|
- `/app/api/data/time-entries/route.ts` - API endpoint with sort parameters
|