94 lines
3.6 KiB
Markdown
94 lines
3.6 KiB
Markdown
# ShotsDataTable Checkbox Selection Fix
|
|
|
|
## Issue
|
|
The shot table multi-selection wasn't working. Investigation revealed that the actual component being used is `ShotsDataTable.vue` (not `ShotsTableView.vue`), which uses TanStack Table with render functions.
|
|
|
|
## Root Cause
|
|
The checkbox columns in `columns.ts` were using the wrong event binding:
|
|
- Used: `'onUpdate:checked'`
|
|
- Should use: `'onUpdate:modelValue'` (for v-model binding in render functions)
|
|
|
|
Additionally, the value parameter type needed to handle both `boolean` and `'indeterminate'` values.
|
|
|
|
## Fix Applied
|
|
|
|
### File: `frontend/src/components/shot/columns.ts`
|
|
|
|
**Before:**
|
|
```typescript
|
|
header: ({ table }) =>
|
|
h(Checkbox, {
|
|
checked: table.getIsAllPageRowsSelected(),
|
|
indeterminate: table.getIsSomePageRowsSelected(),
|
|
'onUpdate:checked': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
|
ariaLabel: 'Select all',
|
|
}),
|
|
cell: ({ row }) =>
|
|
h(Checkbox, {
|
|
checked: row.getIsSelected(),
|
|
'onUpdate:checked': (value: boolean) => row.toggleSelected(!!value),
|
|
ariaLabel: 'Select row',
|
|
onClick: (e: Event) => e.stopPropagation(),
|
|
}),
|
|
```
|
|
|
|
**After:**
|
|
```typescript
|
|
header: ({ table }) =>
|
|
h(Checkbox, {
|
|
modelValue: table.getIsAllPageRowsSelected(),
|
|
'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(value === true),
|
|
ariaLabel: 'Select all',
|
|
}),
|
|
cell: ({ row }) =>
|
|
h(Checkbox, {
|
|
modelValue: row.getIsSelected(),
|
|
'onUpdate:modelValue': (value: boolean | 'indeterminate') => row.toggleSelected(value === true),
|
|
ariaLabel: 'Select row',
|
|
onClick: (e: Event) => e.stopPropagation(),
|
|
}),
|
|
```
|
|
|
|
## Key Changes
|
|
|
|
1. **Event Binding**: Changed from `'onUpdate:checked'` to `'onUpdate:modelValue'`
|
|
- When using `h()` render function, v-model binds to `modelValue` prop and `onUpdate:modelValue` event
|
|
|
|
2. **Prop Binding**: Changed from `checked` to `modelValue`
|
|
- Matches the v-model convention for render functions
|
|
|
|
3. **Type Handling**: Updated value parameter type to `boolean | 'indeterminate'`
|
|
- Checkbox component can emit 'indeterminate' state
|
|
- Convert to boolean with `value === true` before passing to TanStack Table
|
|
|
|
4. **Removed Indeterminate Prop**: No longer needed as separate prop
|
|
- TanStack Table's `getIsSomePageRowsSelected()` is handled internally
|
|
|
|
## Why This Works
|
|
|
|
When using Vue's `h()` render function to create components:
|
|
- v-model translates to `modelValue` prop + `onUpdate:modelValue` event
|
|
- This is different from template syntax where you can use `v-model` directly
|
|
- The Checkbox component from shadcn-vue/reka-ui expects this pattern
|
|
|
|
## Testing
|
|
|
|
Test the following scenarios:
|
|
1. ✅ Click individual checkboxes to select/deselect shots
|
|
2. ✅ Click the header checkbox to select all shots
|
|
3. ✅ Click the header checkbox again to deselect all shots
|
|
4. ✅ Select some shots, verify header shows indeterminate state
|
|
5. ✅ With some selected, click header to select all
|
|
6. ✅ Verify row highlighting reflects selection state
|
|
7. ✅ Verify TanStack Table's selection state is properly maintained
|
|
|
|
## Related Files
|
|
- `frontend/src/components/shot/columns.ts` - Fixed checkbox column definitions
|
|
- `frontend/src/components/shot/ShotsDataTable.vue` - Table component using the columns
|
|
- `frontend/src/components/shot/ShotBrowser.vue` - Parent component that uses ShotsDataTable
|
|
|
|
## Notes
|
|
- `ShotsTableView.vue` exists but is NOT currently being used in the application
|
|
- The actual table implementation uses TanStack Table via `ShotsDataTable.vue`
|
|
- This fix is specific to render function usage with TanStack Table
|