diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-08-22 15:15:28 +0200 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-08-23 12:08:51 +0200 |
commit | 4c2d7de3467a39db6a11452e7436929b67e2c875 (patch) | |
tree | 29f9baf8c64bb9fdf348019cd706e4e77a32021b /server/sonar-web/src/main/js/apps/background-tasks | |
parent | 87c95bc05d147ae016dd9ad5ea48961dec01de68 (diff) | |
download | sonarqube-4c2d7de3467a39db6a11452e7436929b67e2c875.tar.gz sonarqube-4c2d7de3467a39db6a11452e7436929b67e2c875.zip |
SONAR-7846 Display error of a failing CE task in the background page
Diffstat (limited to 'server/sonar-web/src/main/js/apps/background-tasks')
3 files changed, 104 insertions, 5 deletions
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js index 82be5d23870..d6de9d26c63 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js @@ -20,8 +20,9 @@ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import ScannerContextView from '../views/ScannerContextView'; +import StacktraceView from '../views/StacktraceView'; import { STATUSES } from './../constants'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default class TaskActions extends React.Component { shouldComponentUpdate (nextProps, nextState) { @@ -43,9 +44,23 @@ export default class TaskActions extends React.Component { new ScannerContextView({ task: this.props.task }).render(); } + handleShowStacktraceClick (e) { + e.preventDefault(); + new StacktraceView({ task: this.props.task }).render(); + } + render () { const { component, task } = this.props; + const canFilter = component == null; + const canCancel = task.status === STATUSES.PENDING; + const canShowStacktrace = task.errorMessage != null; + const hasActions = canFilter || canCancel || task.hasScannerContext || canShowStacktrace; + + if (!hasActions) { + return <td> </td>; + } + return ( <td className="thin nowrap"> <div className="dropdown js-task-action"> @@ -53,15 +68,15 @@ export default class TaskActions extends React.Component { <i className="icon-dropdown"/> </button> <ul className="dropdown-menu dropdown-menu-right"> - {!component && ( + {canFilter && ( <li> <a className="js-task-filter" href="#" onClick={this.handleFilterClick.bind(this)}> - <i className="spacer-right icon-filter icon-half-transparent"/> - Show only {task.componentName} tasks + <i className="spacer-right icon-filter icon-gray"/> + {translateWithParameters('background_tasks.filter_by_component_x', task.componentName)} </a> </li> )} - {task.status === STATUSES.PENDING && ( + {canCancel && ( <li> <a className="js-task-cancel" href="#" onClick={this.handleCancelClick.bind(this)}> <i className="spacer-right icon-delete"/> @@ -74,10 +89,21 @@ export default class TaskActions extends React.Component { <a className="js-task-show-scanner-context" href="#" onClick={this.handleShowScannerContextClick.bind(this)}> + <i className="spacer-right icon-list icon-gray"/> {translate('background_tasks.show_scanner_context')} </a> </li> )} + {canShowStacktrace && ( + <li> + <a className="js-task-show-stacktrace" + href="#" + onClick={this.handleShowStacktraceClick.bind(this)}> + <i className="spacer-right icon-list icon-red"/> + {translate('background_tasks.show_stacktrace')} + </a> + </li> + )} </ul> </div> </td> diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs new file mode 100644 index 00000000000..1a4d2eb4753 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs @@ -0,0 +1,23 @@ +<form id="deactivate-user-form" autocomplete="off"> + <div class="modal-head"> + <h2>{{t 'background_tasks.error_stacktrace'}}: {{task.componentName}} [{{t 'background_task.type' task.type}}]</h2> + </div> + <div class="modal-body modal-container"> + <div class="js-modal-messages"></div> + + {{#if loaded}} + <h4 class="spacer-bottom">{{t 'background_tasks.error_message'}}</h4> + <pre class="js-task-error-message">{{task.errorMessage}}</pre> + + {{#if stacktrace}} + <h4 class="huge-spacer-top spacer-bottom">{{t 'background_tasks.error_stacktrace'}}</h4> + <pre class="js-task-stacktrace">{{stacktrace}}</pre> + {{/if}} + {{else}} + <i class="spinner"></i> + {{/if}} + </div> + <div class="modal-foot"> + <a href="#" class="js-modal-close">{{t 'close'}}</a> + </div> +</form> diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js new file mode 100644 index 00000000000..809467dff01 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 Modal from '../../../components/common/modals'; +import Template from './StacktraceView.hbs'; +import { getTask } from '../../../api/ce'; + +export default Modal.extend({ + template: Template, + className: 'modal modal-large', + + initialize () { + this.loaded = false; + this.stacktrace = null; + this.loadStacktrace(); + }, + + loadStacktrace() { + getTask(this.options.task.id, ['stacktrace']).then(task => { + this.loaded = true; + this.stacktrace = task.errorStacktrace; + this.render(); + }); + }, + + serializeData() { + return { + task: this.options.task, + stacktrace: this.stacktrace, + loaded: this.loaded + }; + } +}); + |