3.6 KiB
3.6 KiB
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:
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:
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
-
Event Binding: Changed from
'onUpdate:checked'to'onUpdate:modelValue'- When using
h()render function, v-model binds tomodelValueprop andonUpdate:modelValueevent
- When using
-
Prop Binding: Changed from
checkedtomodelValue- Matches the v-model convention for render functions
-
Type Handling: Updated value parameter type to
boolean | 'indeterminate'- Checkbox component can emit 'indeterminate' state
- Convert to boolean with
value === truebefore passing to TanStack Table
-
Removed Indeterminate Prop: No longer needed as separate prop
- TanStack Table's
getIsSomePageRowsSelected()is handled internally
- TanStack Table's
Why This Works
When using Vue's h() render function to create components:
- v-model translates to
modelValueprop +onUpdate:modelValueevent - This is different from template syntax where you can use
v-modeldirectly - The Checkbox component from shadcn-vue/reka-ui expects this pattern
Testing
Test the following scenarios:
- ✅ Click individual checkboxes to select/deselect shots
- ✅ Click the header checkbox to select all shots
- ✅ Click the header checkbox again to deselect all shots
- ✅ Select some shots, verify header shows indeterminate state
- ✅ With some selected, click header to select all
- ✅ Verify row highlighting reflects selection state
- ✅ Verify TanStack Table's selection state is properly maintained
Related Files
frontend/src/components/shot/columns.ts- Fixed checkbox column definitionsfrontend/src/components/shot/ShotsDataTable.vue- Table component using the columnsfrontend/src/components/shot/ShotBrowser.vue- Parent component that uses ShotsDataTable
Notes
ShotsTableView.vueexists 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