# 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