LinkDesk/frontend/docs/shot-column-visibility-fix.md

104 lines
4.2 KiB
Markdown

# Shot Column Visibility Fix
## Issue Description
The Column Visibility Control in `ShotTableToolbar.vue` was not showing all task type columns, specifically missing custom task types. Users could only see and toggle standard columns and standard task types, but custom task types added to the project were not appearing in the column visibility popover.
## Root Cause
The problem was in the `allColumns` definition in `ShotTableToolbar.vue`. It was implemented as a static array that used `props.allTaskTypes` at component initialization time:
```typescript
// ❌ BEFORE: Static array (non-reactive)
const allColumns = [
{ id: 'thumbnail', label: 'Thumbnail' },
{ id: 'name', label: 'Shot Name' },
// ... other columns
...props.allTaskTypes.map(taskType => ({
id: taskType,
label: taskType.charAt(0).toUpperCase() + taskType.slice(1)
}))
]
```
### Why This Failed
1. **Timing Issue**: The component renders before task types are loaded asynchronously
2. **Non-Reactive**: Static arrays don't react to prop changes
3. **Initialization Problem**: `props.allTaskTypes` is empty during component setup
4. **No Updates**: When task types load later, the static array never updates
## Solution
Changed `allColumns` from a static array to a computed property to make it reactive to changes in `props.allTaskTypes`:
```typescript
// ✅ AFTER: Computed property (reactive)
const allColumns = computed(() => [
{ id: 'thumbnail', label: 'Thumbnail' },
{ id: 'name', label: 'Shot Name' },
// ... other columns
...props.allTaskTypes.map(taskType => ({
id: taskType,
label: taskType.charAt(0).toUpperCase() + taskType.slice(1)
}))
])
```
Also updated the `hiddenColumnsCount` computed property to use `allColumns.value`:
```typescript
// ✅ Updated to use computed property
const hiddenColumnsCount = computed(() => {
return allColumns.value.filter(col => props.columnVisibility[col.id] === false).length
})
```
## Data Flow (Fixed)
1. **Component Initialization**: ShotTableToolbar renders with empty `allTaskTypes`
2. **Computed Property**: `allColumns` computed returns basic columns only
3. **Async Loading**: ShotBrowser loads task types via `customTaskTypeService.getAllTaskTypes()`
4. **Prop Update**: `allTaskTypes` prop updates with loaded task types (standard + custom)
5. **Reactive Update**: `allColumns` computed automatically recalculates
6. **UI Update**: Column visibility popover shows all columns including custom types
## Files Modified
- `frontend/src/components/shot/ShotTableToolbar.vue`
- Changed `allColumns` from static array to computed property
- Updated `hiddenColumnsCount` to use `allColumns.value`
- No template changes needed (Vue automatically unwraps computed properties)
## Benefits
-**Reactive Updates**: Column list updates when task types are loaded
-**Custom Task Types**: All custom task types now appear in column visibility control
-**Real-time Changes**: Adding/removing custom task types updates columns immediately
-**Proper Initialization**: Works correctly regardless of loading timing
-**Vue 3 Best Practices**: Uses computed properties for reactive data
## Testing
To verify the fix works:
1. **Initial Load**: Column visibility should show all standard columns
2. **After Task Types Load**: Custom task type columns should appear in visibility control
3. **Add Custom Task Type**: New columns should appear immediately in visibility control
4. **Remove Custom Task Type**: Columns should be removed from visibility control
5. **Column Toggle**: All columns (standard + custom) should be toggleable
## Related Components
- **AssetBrowser ColumnVisibilityControl**: Already implemented correctly with reactive custom task types
- **TaskTableToolbar**: Uses static columns (no dynamic task types), so no similar issue
- **ShotBrowser**: Correctly loads and passes task types to ShotTableToolbar
## Prevention
When creating column visibility controls that depend on dynamic data:
1. Always use computed properties for column definitions that depend on props
2. Ensure reactive data sources for any dynamic column generation
3. Test with asynchronously loaded data to catch timing issues
4. Follow the pattern used in AssetBrowser's ColumnVisibilityControl for reference