From: stanislavh Date: Wed, 17 Jan 2024 08:11:50 +0000 (+0100) Subject: SONAR-21368 Update component container to avoid infinite loop on tutorial page X-Git-Tag: 10.4.0.87286~163 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=eb3efb992b1828a04302c86abbaba03330c50e98;p=sonarqube.git SONAR-21368 Update component container to avoid infinite loop on tutorial page --- diff --git a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx index 886f1389dde..d21f6d24ce9 100644 --- a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx @@ -30,7 +30,7 @@ import { getComponentNavigation } from '../../api/navigation'; import { useLocation, useRouter } from '../../components/hoc/withRouter'; import { translateWithParameters } from '../../helpers/l10n'; import { HttpStatus } from '../../helpers/request'; -import { getPortfolioUrl, getProjectUrl } from '../../helpers/urls'; +import { getPortfolioUrl } from '../../helpers/urls'; import { useBranchesQuery } from '../../queries/branch'; import { ProjectAlmBindingConfigurationErrors } from '../../types/alm-settings'; import { Branch } from '../../types/branch-like'; @@ -98,22 +98,25 @@ function ComponentContainer({ hasFeature }: Readonly [key, branch, pullRequest], ); - const fetchStatus = React.useCallback(async (componentKey: string) => { - try { - const { current, queue } = await getTasksForComponent(componentKey); - const newCurrentTask = getCurrentTask(current); - const pendingTasks = getPendingTasksForBranchLike(queue); - const newTasksInProgress = getInProgressTasks(pendingTasks); - - const isPending = pendingTasks.some((task) => task.status === TaskStatuses.Pending); - - setPending(isPending); - setCurrentTask(newCurrentTask); - setTasksInProgress(newTasksInProgress); - } catch { - // noop - } - }, []); + const fetchStatus = React.useCallback( + async (componentKey: string) => { + try { + const { current, queue } = await getTasksForComponent(componentKey); + const newCurrentTask = getCurrentTask(current, branch, pullRequest); + const pendingTasks = getPendingTasksForBranchLike(queue, branch, pullRequest); + const newTasksInProgress = getInProgressTasks(pendingTasks); + + const isPending = pendingTasks.some((task) => task.status === TaskStatuses.Pending); + + setPending(isPending); + setCurrentTask(newCurrentTask); + setTasksInProgress(newTasksInProgress); + } catch { + // noop + } + }, + [branch, pullRequest], + ); const fetchProjectBindingErrors = React.useCallback( async (component: Component) => { @@ -189,8 +192,14 @@ function ComponentContainer({ hasFeature }: Readonly oldCurrentTask.current = currentTask; oldTasksInProgress.current = tasks; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [tasksInProgress, currentTask]); + }, [tasksInProgress, currentTask, component, fetchComponent, fetchStatus]); + + // Refetch component when a new branch is analyzed + React.useEffect(() => { + if (branchLike?.analysisDate && !component?.analysisDate) { + fetchComponent(); + } + }, [branchLike, component, fetchComponent]); // Refetch component when target branch for fixing pull request is fetched React.useEffect(() => { @@ -210,11 +219,6 @@ function ComponentContainer({ hasFeature }: Readonly */ if (pathname.includes('dashboard') && component && isPortfolioLike(component.qualifier)) { router.replace(getPortfolioUrl(component.key)); - return; - } - // Redirect from tutorials to to dashboard - if (component && !component.analysisDate && pathname.includes('tutorials')) { - router.replace(getProjectUrl(key)); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [component]); @@ -313,16 +317,20 @@ export function isSameBranch( return branch === task.branch; } -function getCurrentTask(current?: Task) { +function getCurrentTask(current?: Task, branch?: string, pullRequest?: string) { if (!current || !isReportRelatedTask(current)) { return undefined; } - return current.status === TaskStatuses.Failed || isSameBranch(current) ? current : undefined; + return current.status === TaskStatuses.Failed || isSameBranch(current, branch, pullRequest) + ? current + : undefined; } -function getPendingTasksForBranchLike(pendingTasks: Task[]) { - return pendingTasks.filter((task) => isReportRelatedTask(task) && isSameBranch(task)); +function getPendingTasksForBranchLike(pendingTasks: Task[], branch?: string, pullRequest?: string) { + return pendingTasks.filter( + (task) => isReportRelatedTask(task) && isSameBranch(task, branch, pullRequest), + ); } function getInProgressTasks(pendingTasks: Task[]) { diff --git a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx index d277bdd6709..8f1d7bf9281 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx @@ -391,31 +391,6 @@ describe('redirects', () => { expect(await ui.portfolioText.find()).toBeInTheDocument(); }); - - it('should redirect to project from tutorial when component is loaded', async () => { - const component = mockComponent({ - breadcrumbs: [{ key: 'project', name: 'Project', qualifier: ComponentQualifier.Project }], - key: 'project-key', - }); - - jest - .mocked(getComponentNavigation) - .mockResolvedValueOnce({} as unknown as Awaited>); - - jest - .mocked(getComponentData) - .mockResolvedValueOnce({ component } as unknown as Awaited< - ReturnType - >); - - renderComponentContainer( - { hasFeature: jest.fn().mockReturnValue(true) }, - 'tutorials?id=project-key', - '/tutorials', - ); - - expect(await ui.projectText.find()).toBeInTheDocument(); - }); }); it.each([