@@ -19,15 +19,16 @@ | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import { Link, WithRouterProps } from 'react-router'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { hasMessage, translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { STATUSES } from '../../../../apps/background-tasks/constants'; | |||
import { withRouter } from '../../../../components/hoc/withRouter'; | |||
import { getComponentBackgroundTaskUrl } from '../../../../helpers/urls'; | |||
import { Task, TaskStatuses } from '../../../../types/tasks'; | |||
import ComponentNavLicenseNotif from './ComponentNavLicenseNotif'; | |||
interface Props { | |||
interface Props extends Pick<WithRouterProps, 'location'> { | |||
component: T.Component; | |||
currentTask?: Task; | |||
currentTaskOnSameBranch?: boolean; | |||
@@ -35,11 +36,13 @@ interface Props { | |||
isPending?: boolean; | |||
} | |||
export default class ComponentNavBgTaskNotif extends React.PureComponent<Props> { | |||
export class ComponentNavBgTaskNotif extends React.PureComponent<Props> { | |||
renderMessage(messageKey: string, status?: string, branch?: string) { | |||
const { component, currentTask } = this.props; | |||
const { component, currentTask, location } = this.props; | |||
const backgroundTaskUrl = getComponentBackgroundTaskUrl(component.key, status); | |||
const canSeeBackgroundTasks = | |||
component.configuration && component.configuration.showBackgroundTasks; | |||
const isOnBackgroundTaskPage = location.pathname === backgroundTaskUrl.pathname; | |||
let type; | |||
if (currentTask && hasMessage('background_task.type', currentTask.type)) { | |||
@@ -48,20 +51,24 @@ export default class ComponentNavBgTaskNotif extends React.PureComponent<Props> | |||
} | |||
let url; | |||
let stacktrace; | |||
if (canSeeBackgroundTasks) { | |||
messageKey += '.admin'; | |||
url = ( | |||
<Link to={getComponentBackgroundTaskUrl(component.key, status)}> | |||
{translate('background_tasks.page')} | |||
</Link> | |||
); | |||
if (isOnBackgroundTaskPage) { | |||
messageKey += '.help'; | |||
stacktrace = translate('background_tasks.show_stacktrace'); | |||
} else { | |||
messageKey += '.link'; | |||
url = <Link to={backgroundTaskUrl}>{translate('background_tasks.page')}</Link>; | |||
} | |||
} | |||
return ( | |||
<FormattedMessage | |||
defaultMessage={translate(messageKey)} | |||
id={messageKey} | |||
values={{ branch, url, type }} | |||
values={{ branch, url, stacktrace, type }} | |||
/> | |||
); | |||
} | |||
@@ -112,3 +119,5 @@ export default class ComponentNavBgTaskNotif extends React.PureComponent<Props> | |||
return null; | |||
} | |||
} | |||
export default withRouter(ComponentNavBgTaskNotif); |
@@ -20,9 +20,9 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockTask } from '../../../../../helpers/mocks/tasks'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import { mockComponent, mockLocation } from '../../../../../helpers/testMocks'; | |||
import { TaskStatuses } from '../../../../../types/tasks'; | |||
import ComponentNavBgTaskNotif from '../ComponentNavBgTaskNotif'; | |||
import { ComponentNavBgTaskNotif } from '../ComponentNavBgTaskNotif'; | |||
jest.mock('sonar-ui-common/helpers/l10n', () => ({ | |||
...jest.requireActual('sonar-ui-common/helpers/l10n'), | |||
@@ -56,6 +56,13 @@ it('renders correctly', () => { | |||
).toMatchSnapshot('branch'); | |||
expect( | |||
shallowRender({ | |||
currentTask: mockTask({ branch: 'my/branch', status: TaskStatuses.Failed }), | |||
currentTaskOnSameBranch: false | |||
}) | |||
).toMatchSnapshot('branch for admins'); | |||
expect( | |||
shallowRender({ | |||
component: mockComponent({ configuration: { showBackgroundTasks: true } }), | |||
currentTask: mockTask({ | |||
pullRequest: '650', | |||
pullRequestTitle: 'feature/my_pr', | |||
@@ -63,7 +70,32 @@ it('renders correctly', () => { | |||
}), | |||
currentTaskOnSameBranch: false | |||
}) | |||
).toMatchSnapshot('pul request'); | |||
).toMatchSnapshot('pull request'); | |||
expect( | |||
shallowRender({ | |||
component: mockComponent({ configuration: { showBackgroundTasks: true } }), | |||
currentTask: mockTask({ | |||
pullRequest: '650', | |||
pullRequestTitle: 'feature/my_pr', | |||
status: TaskStatuses.Failed | |||
}), | |||
currentTaskOnSameBranch: false | |||
}) | |||
).toMatchSnapshot('pull request for admins'); | |||
expect( | |||
shallowRender({ | |||
component: mockComponent({ configuration: { showBackgroundTasks: true } }), | |||
location: mockLocation({ pathname: '/project/background_tasks' }) | |||
}) | |||
).toMatchSnapshot('on background task page'); | |||
expect( | |||
shallowRender({ | |||
component: mockComponent({ configuration: { showBackgroundTasks: true } }), | |||
currentTask: mockTask({ branch: 'my/branch', status: TaskStatuses.Failed }), | |||
currentTaskOnSameBranch: false, | |||
location: mockLocation({ pathname: '/project/background_tasks' }) | |||
}) | |||
).toMatchSnapshot('on background task page for branch'); | |||
expect(shallowRender({ currentTask: undefined })).toMatchSnapshot('no current task'); | |||
}); | |||
@@ -72,6 +104,7 @@ function shallowRender(props: Partial<ComponentNavBgTaskNotif['props']> = {}) { | |||
<ComponentNavBgTaskNotif | |||
component={mockComponent()} | |||
currentTask={mockTask({ status: TaskStatuses.Failed })} | |||
location={mockLocation()} | |||
{...props} | |||
/> | |||
); |
@@ -151,7 +151,7 @@ exports[`renders correctly: has failed notification 1`] = ` | |||
height={102} | |||
id="context-navigation" | |||
notif={ | |||
<ComponentNavBgTaskNotif | |||
<withRouter(ComponentNavBgTaskNotif) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [ | |||
@@ -343,7 +343,7 @@ exports[`renders correctly: has in progress notification 1`] = ` | |||
height={102} | |||
id="context-navigation" | |||
notif={ | |||
<ComponentNavBgTaskNotif | |||
<withRouter(ComponentNavBgTaskNotif) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [ | |||
@@ -523,7 +523,7 @@ exports[`renders correctly: has pending notification 1`] = ` | |||
height={102} | |||
id="context-navigation" | |||
notif={ | |||
<ComponentNavBgTaskNotif | |||
<withRouter(ComponentNavBgTaskNotif) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [ |
@@ -11,6 +11,27 @@ exports[`renders correctly: branch 1`] = ` | |||
values={ | |||
Object { | |||
"branch": "my/branch", | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
`; | |||
exports[`renders correctly: branch for admins 1`] = ` | |||
<Alert | |||
display="banner" | |||
variant="error" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.failed_branch_X" | |||
id="component_navigation.status.failed_branch_X" | |||
values={ | |||
Object { | |||
"branch": "my/branch", | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
@@ -30,6 +51,7 @@ exports[`renders correctly: default 1`] = ` | |||
values={ | |||
Object { | |||
"branch": undefined, | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
@@ -49,6 +71,7 @@ exports[`renders correctly: in progress 1`] = ` | |||
values={ | |||
Object { | |||
"branch": undefined, | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
@@ -78,6 +101,46 @@ exports[`renders correctly: license issue 1`] = ` | |||
exports[`renders correctly: no current task 1`] = `""`; | |||
exports[`renders correctly: on background task page 1`] = ` | |||
<Alert | |||
display="banner" | |||
variant="error" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.failed_X.admin.help" | |||
id="component_navigation.status.failed_X.admin.help" | |||
values={ | |||
Object { | |||
"branch": undefined, | |||
"stacktrace": "background_tasks.show_stacktrace", | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
`; | |||
exports[`renders correctly: on background task page for branch 1`] = ` | |||
<Alert | |||
display="banner" | |||
variant="error" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.failed_branch_X.admin.help" | |||
id="component_navigation.status.failed_branch_X.admin.help" | |||
values={ | |||
Object { | |||
"branch": "my/branch", | |||
"stacktrace": "background_tasks.show_stacktrace", | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
`; | |||
exports[`renders correctly: pending 1`] = ` | |||
<Alert | |||
display="banner" | |||
@@ -89,6 +152,7 @@ exports[`renders correctly: pending 1`] = ` | |||
values={ | |||
Object { | |||
"branch": undefined, | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
} | |||
@@ -103,11 +167,12 @@ exports[`renders correctly: pending for admins 1`] = ` | |||
variant="info" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.pending_X.admin" | |||
id="component_navigation.status.pending_X.admin" | |||
defaultMessage="component_navigation.status.pending_X.admin.link" | |||
id="component_navigation.status.pending_X.admin.link" | |||
values={ | |||
Object { | |||
"branch": undefined, | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": <Link | |||
onlyActiveOnIndex={false} | |||
@@ -130,19 +195,68 @@ exports[`renders correctly: pending for admins 1`] = ` | |||
</Alert> | |||
`; | |||
exports[`renders correctly: pul request 1`] = ` | |||
exports[`renders correctly: pull request 1`] = ` | |||
<Alert | |||
display="banner" | |||
variant="error" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.failed_branch_X" | |||
id="component_navigation.status.failed_branch_X" | |||
defaultMessage="component_navigation.status.failed_branch_X.admin.link" | |||
id="component_navigation.status.failed_branch_X.admin.link" | |||
values={ | |||
Object { | |||
"branch": "650 - feature/my_pr", | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": undefined, | |||
"url": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/project/background_tasks", | |||
"query": Object { | |||
"id": "my-project", | |||
"status": undefined, | |||
}, | |||
} | |||
} | |||
> | |||
background_tasks.page | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</Alert> | |||
`; | |||
exports[`renders correctly: pull request for admins 1`] = ` | |||
<Alert | |||
display="banner" | |||
variant="error" | |||
> | |||
<FormattedMessage | |||
defaultMessage="component_navigation.status.failed_branch_X.admin.link" | |||
id="component_navigation.status.failed_branch_X.admin.link" | |||
values={ | |||
Object { | |||
"branch": "650 - feature/my_pr", | |||
"stacktrace": undefined, | |||
"type": "background_task.type.REPORT", | |||
"url": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/project/background_tasks", | |||
"query": Object { | |||
"id": "my-project", | |||
"status": undefined, | |||
}, | |||
} | |||
} | |||
> | |||
background_tasks.page | |||
</Link>, | |||
} | |||
} | |||
/> |
@@ -2708,12 +2708,16 @@ marketplace.search=Search by features, tags, or categories... | |||
#------------------------------------------------------------------------------ | |||
component_navigation.status.failed=The last background task has failed. | |||
component_navigation.status.failed_X=The {type} has failed. | |||
component_navigation.status.failed.admin=The last background task has failed. More details available on the {url} page. | |||
component_navigation.status.failed_X.admin=The {type} has failed. More details available on the {url} page. | |||
component_navigation.status.failed.admin.link=The last background task has failed. More details available on the {url} page. | |||
component_navigation.status.failed_X.admin.link=The {type} has failed. More details available on the {url} page. | |||
component_navigation.status.failed.admin.help=The last background task has failed. You can find more details below by clicking on the cog menu, and then "{stacktrace}". | |||
component_navigation.status.failed_X.admin.help=The {type} has failed. You can find more details below by clicking on the cog menu, and then "{stacktrace}". | |||
component_navigation.status.failed_branch=The last analysis on this project ({branch}) failed. | |||
component_navigation.status.failed_branch_X=The last {type} on this project ({branch}) failed. | |||
component_navigation.status.failed_branch.admin=The last analysis on this project ({branch}) failed. More details available on the {url} page. | |||
component_navigation.status.failed_branch_X.admin=The last {type} on this project ({branch}) failed. More details available on the {url} page. | |||
component_navigation.status.failed_branch.admin.link=The last analysis on this project ({branch}) failed. More details available on the {url} page. | |||
component_navigation.status.failed_branch_X.admin.link=The last {type} on this project ({branch}) failed. More details available on the {url} page. | |||
component_navigation.status.failed_branch.admin.help==The last analysis on this project ({branch}) failed. You can find more details below by clicking on the cog menu, and then "{stacktrace}". | |||
component_navigation.status.failed_branch_X.admin.help=The last {type} on this project ({branch}) failed. You can find more details below by clicking on the cog menu, and then "{stacktrace}". | |||
component_navigation.status.pending=There is a pending background task. | |||
component_navigation.status.pending_X=There is a pending {type}. | |||
component_navigation.status.pending.admin=There is a pending background task. More details available on the {url} page. |