From b0b438b44dc7f1f534fbcbfc58a07c83138957f2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Thu, 28 Sep 2017 14:25:14 +0200 Subject: [PATCH] SONAR-9792 The fail background task status is now more visible --- server/sonar-web/src/main/js/api/ce.ts | 31 ++++++++++++- .../components/nav/component/ComponentNav.tsx | 38 +++++++++------ .../nav/component/ComponentNavBgTaskNotif.tsx | 46 +++++++++++++++++++ .../nav/component/ComponentNavMeta.tsx | 15 ------ .../ComponentNavBgTaskNotif-test.tsx | 36 +++++++++++++++ .../__snapshots__/ComponentNav-test.tsx.snap | 1 - .../ComponentNavBgTaskNotif-test.tsx.snap | 15 ++++++ .../main/js/components/nav/ContextNavBar.css | 4 ++ .../src/main/js/components/nav/NavBar.css | 6 +++ .../src/main/js/components/nav/NavBar.tsx | 9 +++- .../main/js/components/nav/NavBarNotif.tsx | 39 ++++++++++++++++ server/sonar-web/src/main/js/helpers/urls.ts | 4 ++ .../resources/org/sonar/l10n/core.properties | 2 +- 13 files changed, 213 insertions(+), 33 deletions(-) create mode 100644 server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBgTaskNotif.tsx create mode 100644 server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBgTaskNotif-test.tsx create mode 100644 server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBgTaskNotif-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/components/nav/NavBarNotif.tsx diff --git a/server/sonar-web/src/main/js/api/ce.ts b/server/sonar-web/src/main/js/api/ce.ts index c0146360ada..01ed1a7a090 100644 --- a/server/sonar-web/src/main/js/api/ce.ts +++ b/server/sonar-web/src/main/js/api/ce.ts @@ -20,6 +20,30 @@ import { getJSON, post, RequestData } from '../helpers/request'; import throwGlobalError from '../app/utils/throwGlobalError'; +export interface PendingTask { + componentId: string; + componentKey: string; + componentName: string; + componentQualifier: string; + id: string; + logs: boolean; + organization: string; + status: string; + submittedAt: Date; + submitterLogin?: string; + type: string; +} + +export interface Task extends PendingTask { + analysisId?: string; + errorMessage?: string; + executionTimeMs: number; + executedAt: Date; + hasErrorStacktrace: boolean; + hasScannerContext: boolean; + startedAt: Date; +} + export function getActivity(data: RequestData): Promise { return getJSON('/api/ce/activity', data); } @@ -44,7 +68,12 @@ export function cancelAllTasks(): Promise { return post('/api/ce/cancel_all'); } -export function getTasksForComponent(componentKey: string): Promise { +export function getTasksForComponent( + componentKey: string +): Promise<{ + queue: PendingTask[]; + current: Task; +}> { return getJSON('/api/ce/component', { componentKey }); } diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.tsx index 27c39fa2a97..1a954a26d23 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.tsx @@ -19,14 +19,15 @@ */ import * as React from 'react'; import ComponentNavFavorite from './ComponentNavFavorite'; +import ComponentNavBranch from './ComponentNavBranch'; import ComponentNavBreadcrumbs from './ComponentNavBreadcrumbs'; import ComponentNavMeta from './ComponentNavMeta'; import ComponentNavMenu from './ComponentNavMenu'; -import ComponentNavBranch from './ComponentNavBranch'; +import ComponentNavBgTaskNotif from './ComponentNavBgTaskNotif'; import RecentHistory from '../../RecentHistory'; import { Branch, Component } from '../../../types'; import ContextNavBar from '../../../../components/nav/ContextNavBar'; -import { getTasksForComponent } from '../../../../api/ce'; +import { getTasksForComponent, PendingTask, Task } from '../../../../api/ce'; import { STATUSES } from '../../../../apps/background-tasks/constants'; import './ComponentNav.css'; @@ -38,7 +39,7 @@ interface Props { } interface State { - isFailed?: boolean; + currentTask?: Task; isInProgress?: boolean; isPending?: boolean; } @@ -54,17 +55,26 @@ export default class ComponentNav extends React.PureComponent { this.populateRecentHistory(); } + componentDidUpdate(prevProps: Props) { + if (this.props.component.key !== prevProps.component.key) { + this.loadStatus(); + this.populateRecentHistory(); + } + } + componentWillUnmount() { this.mounted = false; } loadStatus = () => { - getTasksForComponent(this.props.component.key).then((r: any) => { + getTasksForComponent( + this.props.component.key + ).then((r: { queue: PendingTask[]; current: Task }) => { if (this.mounted) { this.setState({ - isPending: r.queue.some((task: any) => task.status === STATUSES.PENDING), - isInProgress: r.queue.some((task: any) => task.status === STATUSES.IN_PROGRESS), - isFailed: r.current && r.current.status === STATUSES.FAILED + currentTask: r.current, + isInProgress: r.queue.some(task => task.status === STATUSES.IN_PROGRESS), + isPending: r.queue.some(task => task.status === STATUSES.PENDING) }); } }); @@ -84,18 +94,23 @@ export default class ComponentNav extends React.PureComponent { }; render() { + const { currentTask } = this.state; + const showNotif = currentTask && currentTask.status === STATUSES.FAILED; return ( - + : undefined + }> - - {this.props.currentBranch && ( { location={this.props.location} /> )} - - + + + ); +} diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx index ea33a7af4f8..2e0f3f2a560 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx @@ -30,7 +30,6 @@ interface Props { branch?: Branch; component: Component; isInProgress?: boolean; - isFailed?: boolean; isPending?: boolean; } @@ -73,20 +72,6 @@ export default function ComponentNavMeta(props: Props) { ); - } else if (props.isFailed) { - const tooltip = canSeeBackgroundTasks - ? translateWithParameters('component_navigation.status.failed.admin', backgroundTasksUrl) - : translate('component_navigation.status.failed'); - metaList.push( - } - mouseLeaveDelay={2}> -
  • - {translate('background_task.status.FAILED')} -
  • -
    - ); } if (props.component.analysisDate) { diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBgTaskNotif-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBgTaskNotif-test.tsx new file mode 100644 index 00000000000..7a4fe19162b --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBgTaskNotif-test.tsx @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import ComponentNavBgTaskNotif from '../ComponentNavBgTaskNotif'; + +const component = { + analysisDate: '2017-01-02T00:00:00.000Z', + breadcrumbs: [], + key: 'foo', + name: 'Foo', + organization: 'org', + qualifier: 'TRK', + version: '0.0.1' +}; + +it('renders background task notif correctly', () => { + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap index b110b9a507a..5222368fae8 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNav-test.tsx.snap @@ -50,7 +50,6 @@ exports[`renders 1`] = ` "qualifier": "TRK", } } - isFailed={true} isInProgress={true} isPending={true} /> diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBgTaskNotif-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBgTaskNotif-test.tsx.snap new file mode 100644 index 00000000000..de960261c68 --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBgTaskNotif-test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders background task notif correctly 1`] = ` + + + +`; diff --git a/server/sonar-web/src/main/js/components/nav/ContextNavBar.css b/server/sonar-web/src/main/js/components/nav/ContextNavBar.css index 25f9470753a..0e527545ca2 100644 --- a/server/sonar-web/src/main/js/components/nav/ContextNavBar.css +++ b/server/sonar-web/src/main/js/components/nav/ContextNavBar.css @@ -9,6 +9,10 @@ border-bottom: 1px solid #e6e6e6; } +.navbar-context .navbar-inner-with-notif { + border-bottom: none; +} + .navbar-context-header { float: left; line-height: 30px; diff --git a/server/sonar-web/src/main/js/components/nav/NavBar.css b/server/sonar-web/src/main/js/components/nav/NavBar.css index e37b1188948..fb9393dd02e 100644 --- a/server/sonar-web/src/main/js/components/nav/NavBar.css +++ b/server/sonar-web/src/main/js/components/nav/NavBar.css @@ -22,3 +22,9 @@ padding-left: 20px; padding-right: 20px; } + +.navbar-notif.alert { + border-left: none; + border-right: none; + padding: 6px 0; +} diff --git a/server/sonar-web/src/main/js/components/nav/NavBar.tsx b/server/sonar-web/src/main/js/components/nav/NavBar.tsx index bc760ba35a0..e44a3e9d722 100644 --- a/server/sonar-web/src/main/js/components/nav/NavBar.tsx +++ b/server/sonar-web/src/main/js/components/nav/NavBar.tsx @@ -19,19 +19,24 @@ */ import * as React from 'react'; import * as classNames from 'classnames'; +import NavBarNotif from './NavBarNotif'; import './NavBar.css'; interface Props { children?: any; className?: string; height: number; + notif?: React.ReactElement; } -export default function NavBar({ children, className, height, ...other }: Props) { +export default function NavBar({ children, className, height, notif, ...other }: Props) { return ( ); diff --git a/server/sonar-web/src/main/js/components/nav/NavBarNotif.tsx b/server/sonar-web/src/main/js/components/nav/NavBarNotif.tsx new file mode 100644 index 00000000000..9004c1b7fe9 --- /dev/null +++ b/server/sonar-web/src/main/js/components/nav/NavBarNotif.tsx @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import * as classNames from 'classnames'; + +interface Props { + children?: React.ReactNode; + className?: string; +} + +export default class NavBarNotif extends React.PureComponent { + render() { + if (!this.props.children) { + return null; + } + return ( +
    +
    {this.props.children}
    +
    + ); + } +} diff --git a/server/sonar-web/src/main/js/helpers/urls.ts b/server/sonar-web/src/main/js/helpers/urls.ts index 773448fad23..b125e48533d 100644 --- a/server/sonar-web/src/main/js/helpers/urls.ts +++ b/server/sonar-web/src/main/js/helpers/urls.ts @@ -43,6 +43,10 @@ export function getComponentUrl(componentKey: string, branch?: string): string { return getBaseUrl() + '/dashboard?id=' + encodeURIComponent(componentKey) + branchQuery; } +export function getComponentBackgroundTaskUrl(componentKey: string): string { + return getBaseUrl() + '/project/background_tasks?id=' + encodeURIComponent(componentKey); +} + export function getProjectUrl(key: string, branch?: string): Location { return { pathname: '/dashboard', query: { id: key, branch } }; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 7bf157dc139..07154513eba 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2776,7 +2776,7 @@ update_center.status.DEPS_REQUIRE_SYSTEM_UPGRADE=Some of dependencies requires s # #------------------------------------------------------------------------------ component_navigation.status.failed=The last analysis has failed. -component_navigation.status.failed.admin=The last analysis has failed.
    More details available on the Background Tasks page. +component_navigation.status.failed.admin=The last analysis has failed. More details available on the Background Tasks page. component_navigation.status.pending=There is a pending analysis. component_navigation.status.pending.admin=There is a pending analysis.
    More details available on the Background Tasks page. component_navigation.status.in_progress=The analysis is in progress. -- 2.39.5