Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 39 additions & 14 deletions frontend/src/features/tasks/components/TeamSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,61 @@ export default function TeamSelector({
useEffect(() => {
console.log('[TeamSelector] Effect triggered', {
hasSelectedTaskDetail: !!selectedTaskDetail,
taskDetailTeamId: selectedTaskDetail?.team?.id || 'null',
taskDetailTeamName: selectedTaskDetail?.team?.name || 'null',
selectedTeam: selectedTeam?.name || 'null',
selectedTeamId: selectedTeam?.id || 'null',
teamsLength: teams.length,
});
Comment on lines 42 to 49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove console.log statements or make them development-only.

Console logs should not be present in production code as they clutter the browser console and may expose internal logic. Consider removing them entirely or wrapping them in a development check.

Apply this pattern to conditionally log only in development:

-    console.log('[TeamSelector] Effect triggered', {
-      hasSelectedTaskDetail: !!selectedTaskDetail,
-      taskDetailTeamId: selectedTaskDetail?.team?.id || 'null',
-      taskDetailTeamName: selectedTaskDetail?.team?.name || 'null',
-      selectedTeam: selectedTeam?.name || 'null',
-      selectedTeamId: selectedTeam?.id || 'null',
-      teamsLength: teams.length,
-    });
+    if (process.env.NODE_ENV === 'development') {
+      console.log('[TeamSelector] Effect triggered', {
+        hasSelectedTaskDetail: !!selectedTaskDetail,
+        taskDetailTeamId: selectedTaskDetail?.team?.id || 'null',
+        taskDetailTeamName: selectedTaskDetail?.team?.name || 'null',
+        selectedTeam: selectedTeam?.name || 'null',
+        selectedTeamId: selectedTeam?.id || 'null',
+        teamsLength: teams.length,
+      })
+    }

Apply the same pattern to all other console.log statements in the effect (lines 53, 69, 75, 83, 95).

Also applies to: 53-53, 69-69, 75-75, 83-83, 95-95

🤖 Prompt for AI Agents
In frontend/src/features/tasks/components/TeamSelector.tsx around lines 42-95,
there are console.log calls used for debugging (lines 42, 53, 69, 75, 83, 95);
remove these console.log statements from production by either deleting them or
wrapping each in a development-only guard (e.g., check process.env.NODE_ENV ===
'development' or your app's equivalent) so logs only run in development, or
replace with a centralized dev-only logger helper and use it for all the logs in
this effect.


// Wait for teams to load before syncing
if (teams.length === 0) {
console.log('[TeamSelector] Teams not loaded yet, skipping sync');
return;
}
Comment on lines +51 to +55
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard may prevent sync when teams load after task detail.

The teams.length === 0 check assumes teams always load before selectedTaskDetail. If task detail arrives first (e.g., from URL navigation), the effect will skip synchronization even after teams eventually load, because the effect doesn't re-run when teams goes from empty to populated if other dependencies haven't changed.

Consider using the isLoading prop to determine data readiness:

-    // Wait for teams to load before syncing
-    if (teams.length === 0) {
-      console.log('[TeamSelector] Teams not loaded yet, skipping sync');
-      return;
-    }
+    // Skip sync while teams are still loading
+    if (isLoading) {
+      return;
+    }

This ensures the effect waits for loading to complete rather than checking array length, which handles both the loading state and the legitimate "no teams" case correctly.

🤖 Prompt for AI Agents
In frontend/src/features/tasks/components/TeamSelector.tsx around lines 51-55,
the effect currently guards with teams.length === 0 which can skip sync
permanently if selectedTaskDetail arrives before teams; replace that guard with
the teams loading flag (e.g., isLoading or teamsIsLoading) so the effect waits
for loading to complete and still re-runs when teams transition from loading to
loaded, and ensure the effect's dependency array includes the loading flag (and
selectedTaskDetail) so synchronization runs after teams finish loading and
correctly handles both "still loading" and "loaded but empty" cases.


// Priority 1: Set team from task detail if viewing a task
if (
selectedTaskDetail &&
'team' in selectedTaskDetail &&
selectedTaskDetail.team &&
teams.length > 0
) {
const foundTeam =
teams.find(t => t.id === (selectedTaskDetail.team as { id: number }).id) || null;
if (foundTeam && (!selectedTeam || selectedTeam.id !== foundTeam.id)) {
console.log('[TeamSelector] Setting team from task detail:', foundTeam.name, foundTeam.id);
setSelectedTeam(foundTeam);
if (selectedTaskDetail && 'team' in selectedTaskDetail) {
const taskTeam = selectedTaskDetail.team;

// Case 1: Task has a valid team
if (taskTeam && typeof taskTeam === 'object' && 'id' in taskTeam) {
const taskTeamId = (taskTeam as { id: number }).id;
const foundTeam = teams.find(t => t.id === taskTeamId) || null;

if (foundTeam) {
// Only update if team changed to avoid unnecessary re-renders
if (!selectedTeam || selectedTeam.id !== foundTeam.id) {
console.log('[TeamSelector] Setting team from task detail:', foundTeam.name, foundTeam.id);
setSelectedTeam(foundTeam);
}
return; // Team synced successfully, exit early
} else {
// Team exists in task detail but not in user's team list (deleted or no access)
console.log('[TeamSelector] Task team not found in user teams, keeping current selection');
// Keep current selectedTeam unchanged - don't clear it
return;
}
}

// Case 2: Task has no team (team was deleted or never set)
if (taskTeam === null) {
console.log('[TeamSelector] Task has no team, clearing team selection');
if (selectedTeam !== null) {
setSelectedTeam(null);
}
return;
}
}

// Priority 2: Validate selected team still exists in list
if (selectedTeam && teams.length > 0) {
// Priority 2: Validate selected team still exists in list (only when not viewing a task detail)
if (!selectedTaskDetail && selectedTeam && teams.length > 0) {
const exists = teams.some(team => team.id === selectedTeam.id);
if (!exists) {
console.log('[TeamSelector] Selected team not in list, clearing selection');
setSelectedTeam(null);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedTaskDetail, teams]);

const handleChange = (value: string) => {
Expand Down