Reduce API calls on FE (#258)
* remove unnecessary /branches call * remove unnecessary dependency on active tab and user selected tab * remove duplicate fetch attempt data and execution state
This commit is contained in:
@@ -38,19 +38,13 @@ const TaskDetailsProvider: FC<{
|
||||
task: TaskWithAttemptStatus;
|
||||
projectId: string;
|
||||
children: ReactNode;
|
||||
activeTab: 'logs' | 'diffs' | 'related';
|
||||
setActiveTab: Dispatch<SetStateAction<'logs' | 'diffs' | 'related'>>;
|
||||
setShowEditorDialog: Dispatch<SetStateAction<boolean>>;
|
||||
userSelectedTab: boolean;
|
||||
projectHasDevScript?: boolean;
|
||||
}> = ({
|
||||
task,
|
||||
projectId,
|
||||
children,
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
setShowEditorDialog,
|
||||
userSelectedTab,
|
||||
projectHasDevScript,
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -84,7 +78,6 @@ const TaskDetailsProvider: FC<{
|
||||
allLogs: [], // new field for all logs
|
||||
});
|
||||
|
||||
const diffLoadingRef = useRef(false);
|
||||
const relatedTasksLoadingRef = useRef(false);
|
||||
|
||||
const fetchRelatedTasks = useCallback(async () => {
|
||||
@@ -127,12 +120,6 @@ const TaskDetailsProvider: FC<{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent multiple concurrent requests
|
||||
if (diffLoadingRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
diffLoadingRef.current = true;
|
||||
if (isBackgroundRefresh) {
|
||||
setIsBackgroundRefreshing(true);
|
||||
} else {
|
||||
@@ -154,7 +141,6 @@ const TaskDetailsProvider: FC<{
|
||||
console.error('Failed to load diff:', err);
|
||||
setDiffError('Failed to load diff');
|
||||
} finally {
|
||||
diffLoadingRef.current = false;
|
||||
if (isBackgroundRefresh) {
|
||||
setIsBackgroundRefreshing(false);
|
||||
} else {
|
||||
@@ -165,10 +151,6 @@ const TaskDetailsProvider: FC<{
|
||||
[projectId, selectedAttempt?.id, selectedAttempt?.task_id]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchDiff();
|
||||
}, [fetchDiff]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedAttempt && task) {
|
||||
fetchRelatedTasks();
|
||||
@@ -318,7 +300,7 @@ const TaskDetailsProvider: FC<{
|
||||
fetchAttemptData(selectedAttempt.id, selectedAttempt.task_id);
|
||||
fetchExecutionState(selectedAttempt.id, selectedAttempt.task_id);
|
||||
}
|
||||
}, 2000);
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [
|
||||
@@ -355,32 +337,12 @@ const TaskDetailsProvider: FC<{
|
||||
useEffect(() => {
|
||||
if (!executionState?.execution_state || !selectedAttempt) return;
|
||||
|
||||
const isCodingAgentComplete =
|
||||
executionState.execution_state === 'CodingAgentComplete';
|
||||
const isCodingAgentFailed =
|
||||
executionState.execution_state === 'CodingAgentFailed';
|
||||
const isComplete = executionState.execution_state === 'Complete';
|
||||
const hasChanges = executionState.has_changes;
|
||||
|
||||
// Fetch diff when coding agent completes, fails, or task is complete and has changes
|
||||
if (
|
||||
(isCodingAgentComplete || isCodingAgentFailed || isComplete) &&
|
||||
hasChanges
|
||||
) {
|
||||
fetchDiff();
|
||||
// Auto-switch to diffs tab when changes are detected, but only if user hasn't manually selected a tab
|
||||
if (activeTab === 'logs' && !userSelectedTab) {
|
||||
setActiveTab('diffs');
|
||||
}
|
||||
}
|
||||
fetchDiff();
|
||||
}, [
|
||||
executionState?.execution_state,
|
||||
executionState?.has_changes,
|
||||
selectedAttempt,
|
||||
fetchDiff,
|
||||
activeTab,
|
||||
userSelectedTab,
|
||||
setActiveTab,
|
||||
]);
|
||||
|
||||
const value = useMemo(
|
||||
|
||||
@@ -8,10 +8,9 @@ import {
|
||||
type Props = {
|
||||
activeTab: 'logs' | 'diffs' | 'related';
|
||||
setActiveTab: (tab: 'logs' | 'diffs' | 'related') => void;
|
||||
setUserSelectedTab: (tab: boolean) => void;
|
||||
};
|
||||
|
||||
function TabNavigation({ activeTab, setActiveTab, setUserSelectedTab }: Props) {
|
||||
function TabNavigation({ activeTab, setActiveTab }: Props) {
|
||||
const { diff } = useContext(TaskDiffContext);
|
||||
const { totalRelatedCount } = useContext(TaskRelatedTasksContext);
|
||||
return (
|
||||
@@ -19,9 +18,7 @@ function TabNavigation({ activeTab, setActiveTab, setUserSelectedTab }: Props) {
|
||||
<div className="flex px-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
console.log('Logs tab clicked - setting activeTab to logs');
|
||||
setActiveTab('logs');
|
||||
setUserSelectedTab(true);
|
||||
}}
|
||||
className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
||||
activeTab === 'logs'
|
||||
@@ -34,9 +31,7 @@ function TabNavigation({ activeTab, setActiveTab, setUserSelectedTab }: Props) {
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
console.log('Diffs tab clicked - setting activeTab to diffs');
|
||||
setActiveTab('diffs');
|
||||
setUserSelectedTab(true);
|
||||
}}
|
||||
className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
||||
activeTab === 'diffs'
|
||||
@@ -54,11 +49,7 @@ function TabNavigation({ activeTab, setActiveTab, setUserSelectedTab }: Props) {
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
console.log(
|
||||
'Related Tasks tab clicked - setting activeTab to related'
|
||||
);
|
||||
setActiveTab('related');
|
||||
setUserSelectedTab(true);
|
||||
}}
|
||||
className={`flex items-center px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
||||
activeTab === 'related'
|
||||
|
||||
@@ -40,13 +40,11 @@ export function TaskDetailsPanel({
|
||||
const [activeTab, setActiveTab] = useState<'logs' | 'diffs' | 'related'>(
|
||||
'logs'
|
||||
);
|
||||
const [userSelectedTab, setUserSelectedTab] = useState<boolean>(false);
|
||||
|
||||
// Reset to logs tab when task changes
|
||||
useEffect(() => {
|
||||
if (task?.id) {
|
||||
setActiveTab('logs');
|
||||
setUserSelectedTab(true); // Treat this as a user selection to prevent auto-switching
|
||||
}
|
||||
}, [task?.id]);
|
||||
|
||||
@@ -74,9 +72,6 @@ export function TaskDetailsPanel({
|
||||
task={task}
|
||||
projectId={projectId}
|
||||
setShowEditorDialog={setShowEditorDialog}
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
userSelectedTab={userSelectedTab}
|
||||
projectHasDevScript={projectHasDevScript}
|
||||
>
|
||||
{/* Backdrop - only on smaller screens (overlay mode) */}
|
||||
@@ -96,7 +91,6 @@ export function TaskDetailsPanel({
|
||||
<TabNavigation
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
setUserSelectedTab={setUserSelectedTab}
|
||||
/>
|
||||
|
||||
{/* Tab Content */}
|
||||
|
||||
@@ -5,13 +5,12 @@ import { Button } from '@/components/ui/button';
|
||||
import { useConfig } from '@/components/config-provider';
|
||||
import { attemptsApi, projectsApi } from '@/lib/api';
|
||||
import type { GitBranch, TaskAttempt } from 'shared/types';
|
||||
import { EXECUTOR_TYPES, EXECUTOR_LABELS } from 'shared/types';
|
||||
import { EXECUTOR_LABELS, EXECUTOR_TYPES } from 'shared/types';
|
||||
import {
|
||||
TaskAttemptDataContext,
|
||||
TaskAttemptLoadingContext,
|
||||
TaskAttemptStoppingContext,
|
||||
TaskDetailsContext,
|
||||
TaskExecutionStateContext,
|
||||
TaskSelectedAttemptContext,
|
||||
} from '@/components/context/taskDetailsContext.ts';
|
||||
import CreatePRDialog from '@/components/tasks/Toolbar/CreatePRDialog.tsx';
|
||||
@@ -31,10 +30,9 @@ function TaskDetailsToolbar() {
|
||||
);
|
||||
|
||||
const { isStopping } = useContext(TaskAttemptStoppingContext);
|
||||
const { fetchAttemptData, setAttemptData, isAttemptRunning } = useContext(
|
||||
const { setAttemptData, isAttemptRunning } = useContext(
|
||||
TaskAttemptDataContext
|
||||
);
|
||||
const { fetchExecutionState } = useContext(TaskExecutionStateContext);
|
||||
|
||||
const [taskAttempts, setTaskAttempts] = useState<TaskAttempt[]>([]);
|
||||
const location = useLocation();
|
||||
@@ -67,10 +65,10 @@ function TaskDetailsToolbar() {
|
||||
setBranches(result);
|
||||
// Set current branch as default
|
||||
const currentBranch = result.find((b) => b.is_current);
|
||||
if (currentBranch && !selectedBranch) {
|
||||
setSelectedBranch(currentBranch.name);
|
||||
if (currentBranch) {
|
||||
setSelectedBranch((prev) => (!prev ? currentBranch.name : prev));
|
||||
}
|
||||
}, [projectId, selectedBranch]);
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchProjectBranches();
|
||||
@@ -163,11 +161,6 @@ function TaskDetailsToolbar() {
|
||||
return prev;
|
||||
return selectedAttemptToUse;
|
||||
});
|
||||
fetchAttemptData(selectedAttemptToUse.id, selectedAttemptToUse.task_id);
|
||||
fetchExecutionState(
|
||||
selectedAttemptToUse.id,
|
||||
selectedAttemptToUse.task_id
|
||||
);
|
||||
} else {
|
||||
setSelectedAttempt(null);
|
||||
setAttemptData({
|
||||
@@ -181,7 +174,7 @@ function TaskDetailsToolbar() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [task, projectId, fetchAttemptData, fetchExecutionState, location.search]);
|
||||
}, [task, projectId, location.search]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTaskAttempts();
|
||||
|
||||
Reference in New Issue
Block a user