diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2014-06-18 16:42:34 +0600 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2014-06-18 16:42:44 +0600 |
commit | b18f1b7906ef706a0f13cf642b7bc48cee1dfeef (patch) | |
tree | d54cc5bcc13a7185cfffcd6cb4f01e40b280fbe1 /sonar-server | |
parent | 5214bb3dcde1171a6ae8aa289c46eb9d44e417af (diff) | |
download | sonarqube-b18f1b7906ef706a0f13cf642b7bc48cee1dfeef.tar.gz sonarqube-b18f1b7906ef706a0f13cf642b7bc48cee1dfeef.zip |
SONAR-5209 Add ability to create manual issues
Diffstat (limited to 'sonar-server')
8 files changed, 214 insertions, 7 deletions
diff --git a/sonar-server/src/main/coffee/component-viewer/line-actions-popup.coffee b/sonar-server/src/main/coffee/component-viewer/line-actions-popup.coffee new file mode 100644 index 00000000000..156ef178544 --- /dev/null +++ b/sonar-server/src/main/coffee/component-viewer/line-actions-popup.coffee @@ -0,0 +1,43 @@ +define [ + 'backbone.marionette' + 'templates/component-viewer' + 'component-viewer/popup' + 'issues/manual-issue-view' +], ( + Marionette + Templates + Popup + ManualIssueView +) -> + + $ = jQuery + + + class extends Popup + template: Templates['line-options-popup'] + + + events: + 'click .js-add-manual-issue': 'addManualIssue' + + + addManualIssue: (e) -> + e.preventDefault() + line = @options.row.data 'line-number' + component = @options.main.component.get 'key' + manualIssueView = new ManualIssueView + line: line + component: component + manualIssueView.render().$el.appendTo @options.row.find('.line') + manualIssueView.on 'add', (issue) => + issues = @options.main.source.get('issues') || [] + activeIssues = @options.main.source.get('activeIssues') || [] + showIssues = @options.main.settings.get 'issues' + issues.push issue + if showIssues then activeIssues.push issue else activeIssues = [issue] + @options.main.source.set 'issues', issues + @options.main.source.set 'activeIssues', activeIssues + @options.main.settings.set 'issues', true + @options.main.sourceView.render() + + diff --git a/sonar-server/src/main/coffee/component-viewer/source.coffee b/sonar-server/src/main/coffee/component-viewer/source.coffee index ba33b45e391..7d2070fc09f 100644 --- a/sonar-server/src/main/coffee/component-viewer/source.coffee +++ b/sonar-server/src/main/coffee/component-viewer/source.coffee @@ -4,6 +4,7 @@ define [ 'component-viewer/coverage-popup' 'component-viewer/duplication-popup' 'component-viewer/time-changes-popup' + 'component-viewer/line-actions-popup' 'issues/issue-view' 'issues/models/issue' 'common/handlebars-extensions' @@ -13,6 +14,7 @@ define [ CoveragePopupView DuplicationPopupView TimeChangesPopupView + LineActionsPopupView IssueView Issue ) -> @@ -69,6 +71,7 @@ define [ @showSettings = false @renderExpandButtons() @renderIssues() if @options.main.settings.get('issues') && @model.has('activeIssues') + @highlightCurrentLine() renderExpandButtons: -> @@ -114,9 +117,27 @@ define [ @$el.html '<div style="padding: 10px;"><i class="spinner"></i></div>' + showLineActionsPopup: (e) -> + e.stopPropagation() + $('body').click() + popup = new LineActionsPopupView + triggerEl: $(e.currentTarget) + main: @options.main + row: $(e.currentTarget).closest '.row' + popup.render() + + highlightLine: (e) -> @$(".#{HIGHLIGHTED_ROW_CLASS}").removeClass HIGHLIGHTED_ROW_CLASS - $(e.currentTarget).closest('.row').addClass HIGHLIGHTED_ROW_CLASS + row = $(e.currentTarget).closest('.row') + row.addClass HIGHLIGHTED_ROW_CLASS + @highlightedLine = row.data 'line-number' + @showLineActionsPopup(e) + + + highlightCurrentLine: -> + if @highlightedLine? + @$("[data-line-number=#{@highlightedLine}]").addClass HIGHLIGHTED_ROW_CLASS highlightUsages: (e) -> diff --git a/sonar-server/src/main/coffee/issues/manual-issue-view.coffee b/sonar-server/src/main/coffee/issues/manual-issue-view.coffee new file mode 100644 index 00000000000..6b82f166017 --- /dev/null +++ b/sonar-server/src/main/coffee/issues/manual-issue-view.coffee @@ -0,0 +1,79 @@ +define [ + 'backbone.marionette' + 'templates/issues' +], ( + Marionette + Templates +) -> + + $ = jQuery + API_ISSUE = "#{baseUrl}/api/issues/show" + API_ADD_MANUAL_ISSUE = "#{baseUrl}/api/issues/create" + + + class extends Marionette.ItemView + template: Templates['manual-issue'] + + + events: + 'submit .js-manual-issue-form': 'formSubmit' + 'click .js-cancel': 'cancel' + + + onRender: -> + @delegateEvents() + @$('[name=rule]').select2 + width: '250px' + minimumResultsForSearch: 10 + + + showSpinner: -> + @$('.js-submit').hide() + @$('.js-spinner').show() + + + hideSpinner: -> + @$('.js-submit').show() + @$('.js-spinner').hide() + + + validateFields: -> + message = @$('[name=message]') + unless message.val() + message.addClass('invalid').focus() + return false + return true + + + formSubmit: (e) -> + e.preventDefault() + return unless @validateFields() + @showSpinner() + data = $(e.currentTarget).serialize() + $.post API_ADD_MANUAL_ISSUE, data + .done (r) => + @addIssue r.issue.key + .fail (r) => + @hideSpinner() + if r.responseJSON?.errors? + @showError _.pluck(r.responseJSON.errors, 'msg').join '. ' + + + addIssue: (key) -> + $.get API_ISSUE, key: key, (r) => + @trigger 'add', r.issue + @close() + + + showError: (msg) -> + @$('.code-issue-errors').removeClass('hidden').text msg + + + cancel: -> + @close() + + + serializeData: -> + _.extend super, + line: @options.line + component: @options.component diff --git a/sonar-server/src/main/hbs/component-viewer/line-options-popup.hbs b/sonar-server/src/main/hbs/component-viewer/line-options-popup.hbs new file mode 100644 index 00000000000..eccd2e20a09 --- /dev/null +++ b/sonar-server/src/main/hbs/component-viewer/line-options-popup.hbs @@ -0,0 +1,9 @@ +<div class="component-viewer-popup-container"> + <div class="component-viewer-popup-title">{{t 'component_viewer.line_actions'}}</div> + + <div class="component-viewer-popup-section"> + <a href="#" class="js-add-manual-issue link-action">{{t 'component_viewer.add_manual_issue'}}</a> + </div> +</div> + +<div class="component-viewer-popup-arrow"></div>
\ No newline at end of file diff --git a/sonar-server/src/main/hbs/issues/manual-issue.hbs b/sonar-server/src/main/hbs/issues/manual-issue.hbs new file mode 100644 index 00000000000..bb6fcc105c4 --- /dev/null +++ b/sonar-server/src/main/hbs/issues/manual-issue.hbs @@ -0,0 +1,47 @@ +<form action="" class="js-manual-issue-form code-issue-create-form"> + {{! no manual rules }} + {{! <div class="warning" style="margin: 10px"> }} + {{! <% if is_admin %> }} + {{! <%= message('issue.manual.no_rules.admin') -%> }} + {{! <a href="<%= ApplicationController.root_context -%>/manual_rules/index"><%= message('manage') -%></a> }} + {{! <% else %> }} + {{! <%= message('issue.manual.no_rules.non_admin') -%> }} + {{! <% end %> }} + {{! <%= link_to_function message('cancel'), 'closeCreateIssueForm(this)' -%> }} + {{! </div> }} + + <input type="hidden" name="line" value="{{line}}"> + <input type="hidden" name="component" value="{{component}}"> + + <div class="code-issue-name"> + {{! TODO: replace mock data }} + <select name="rule"> + <option value="manual:api">API</option> + <option value="manual:design">Design</option> + <option value="manual:error_handling">Error handling</option> + <option value="manual:performance">Performance</option> + <option value="manual:sql_pitfalls">SQL Pitfall</option> + </select> + </div> + + <div class="code-issue-msg"> + <table class="width100"> + <tr> + <td> + <textarea rows="4" name="message" class="width100 marginbottom5"></textarea> + </td> + </tr> + <tr> + <td class="js-submit"> + <input type="submit" value="{{t 'create'}}"> + <a class="js-cancel" href="#">{{t 'cancel'}}</a> + </td> + <td class="js-spinner" style="display: none;"> + <i class="spinner"></i> + </td> + </tr> + </table> + <div class="code-issue-errors error hidden"></div> + </div> + +</form> diff --git a/sonar-server/src/main/less/component-viewer.less b/sonar-server/src/main/less/component-viewer.less index 6cae4991a82..30f0434027a 100644 --- a/sonar-server/src/main/less/component-viewer.less +++ b/sonar-server/src/main/less/component-viewer.less @@ -155,9 +155,10 @@ td.line { background-color: @barBackgroundColor; } } - .code .row-highlighted { - td.stat { background-color: #e9e94d !important; } - td.line { background-color: #f1f1a3 !important; } + .code .row-highlighted, + .code .row-highlighted:hover { + td.stat { background-color: #e9e94d; } + td.line { background-color: #f1f1a3; } } .code td.line { @@ -255,17 +256,17 @@ .code .stat { &.coverage-green { - background-color: lighten(@green, 15%); + background-color: lighten(@green, 15%) !important; color: @baseFontColor; } &.coverage-orange { - background-color: lighten(@orange, 15%); + background-color: lighten(@orange, 15%) !important; color: @baseFontColor; } &.coverage-red { - background-color: lighten(@red, 15%); + background-color: lighten(@red, 15%) !important; color: @baseFontColor; } } @@ -624,6 +625,7 @@ .component-viewer-popup-section { width: 450px; + padding-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; diff --git a/sonar-server/src/main/less/style.less b/sonar-server/src/main/less/style.less index 85f9005f502..4581fd64b16 100644 --- a/sonar-server/src/main/less/style.less +++ b/sonar-server/src/main/less/style.less @@ -1011,6 +1011,10 @@ th.operations, td.operations { display: none; } +.code-issue-errors { + margin-top: 10px; +} + .tab_header { border-bottom: 1px solid #DDD; background-color: #EFEFEF; diff --git a/sonar-server/src/main/less/ui.less b/sonar-server/src/main/less/ui.less index 67a4ab3e781..bdab9e2c935 100644 --- a/sonar-server/src/main/less/ui.less +++ b/sonar-server/src/main/less/ui.less @@ -151,6 +151,8 @@ textarea { box-shadow: none; outline: none; } + + &.invalid { border-color: @red; } } input[type=text], |