From 120dc80f1074dbd533e05b33d5a7fd797702e701 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 8 Dec 2015 17:55:39 +0100 Subject: improve code quality --- server/sonar-web/.eslintrc | 18 +++++++------- server/sonar-web/package.json | 1 + .../main/js/apps/account/change-password-view.js | 2 +- .../sonar-web/src/main/js/apps/coding-rules/app.js | 2 +- .../js/apps/coding-rules/bulk-change-modal-view.js | 4 ++-- .../coding-rules/facets/active-severity-facet.js | 2 +- .../coding-rules/facets/custom-values-facet.js | 8 +++---- .../apps/coding-rules/facets/inheritance-facet.js | 4 ++-- .../js/apps/coding-rules/facets/status-facet.js | 2 +- .../main/js/apps/coding-rules/rule-details-view.js | 4 ++-- .../coding-rules/rule/custom-rule-creation-view.js | 4 ++-- .../js/apps/coding-rules/rule/custom-rule-view.js | 4 ++-- .../coding-rules/rule/manual-rule-creation-view.js | 2 +- .../coding-rules/rule/rule-description-view.js | 2 +- .../js/apps/coding-rules/rule/rule-profile-view.js | 10 ++++---- .../apps/coding-rules/workspace-list-empty-view.js | 4 +--- .../apps/coding-rules/workspace-list-item-view.js | 4 ++-- .../src/main/js/apps/issues/facets/author-facet.js | 8 +++---- .../js/apps/issues/facets/custom-values-facet.js | 8 +++---- .../main/js/apps/issues/facets/language-facet.js | 8 +++---- .../main/js/apps/issues/facets/project-facet.js | 8 +++---- .../src/main/js/apps/issues/facets/rule-facet.js | 8 +++---- .../src/main/js/apps/issues/facets/tag-facet.js | 6 ++--- .../js/apps/issues/workspace-list-empty-view.js | 4 +--- .../apps/overview/domains/duplications-domain.js | 3 +-- .../src/main/js/apps/projects/form-view.js | 5 +--- .../js/apps/quality-gates/gate-condition-view.js | 4 +--- .../js/apps/quality-gates/gate-conditions-view.js | 4 +--- .../js/apps/quality-gates/gate-projects-view.js | 14 +++++------ .../src/main/js/apps/quality-profiles/helpers.js | 12 ++++++---- .../apps/quality-profiles/profile-details-view.js | 14 +++++------ .../js/components/issue/views/assign-form-view.js | 4 +--- .../js/components/issue/views/plan-form-view.js | 4 +--- .../components/navigator/filters/choice-filters.js | 4 +--- .../src/main/js/components/source-viewer/main.js | 2 +- .../src/main/js/components/widgets/barchart.js | 1 + .../src/main/js/helpers/handlebars-helpers.js | 13 +++++----- .../src/main/js/main/nav/global/search-view.js | 28 ++++++++++------------ server/sonar-web/src/main/js/main/processes.js | 2 +- .../sonar-web/src/main/js/widgets/old/tag-cloud.js | 2 +- 40 files changed, 107 insertions(+), 136 deletions(-) diff --git a/server/sonar-web/.eslintrc b/server/sonar-web/.eslintrc index 19e2098c50f..77cfb1f6edd 100644 --- a/server/sonar-web/.eslintrc +++ b/server/sonar-web/.eslintrc @@ -14,21 +14,17 @@ }, "globals": { - "define": true, - "require": true, - "numeral": true, "key": true, "d3": true, - "baseUrl": true, - "t": true, - "tp": true + "baseUrl": true }, "parser": "babel-eslint", "plugins": [ "react", - "mocha" + "mocha", + "import" ], "rules": { @@ -74,6 +70,12 @@ "react/prop-types": 0, "react/react-in-jsx-scope": 2, "react/self-closing-comp": 2, - "react/sort-comp": 1 + "react/sort-comp": 1, + + "import/no-unresolved": 2, + "import/named": 2, + "import/export": 2, + "import/no-duplicates": 2, + "import/imports-first": 2 } } diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json index 38d0e420486..04d8169b95a 100644 --- a/server/sonar-web/package.json +++ b/server/sonar-web/package.json @@ -19,6 +19,7 @@ "d3": "3.5.6", "del": "2.0.2", "eslint": "^1.10.3", + "eslint-plugin-import": "^0.11.0", "eslint-plugin-mocha": "^1.1.0", "eslint-plugin-react": "^3.11.3", "event-stream": "3.3.1", diff --git a/server/sonar-web/src/main/js/apps/account/change-password-view.js b/server/sonar-web/src/main/js/apps/account/change-password-view.js index 6bd5d992b21..4df1c081161 100644 --- a/server/sonar-web/src/main/js/apps/account/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/account/change-password-view.js @@ -10,7 +10,7 @@ export default ModalForm.extend({ if (this.checkPasswords()) { this.sendRequest(); } else { - this.showErrors([{ msg: t('user.password_doesnt_match_confirmation') }]); + this.showErrors([{ msg: window.t('user.password_doesnt_match_confirmation') }]); } }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/app.js b/server/sonar-web/src/main/js/apps/coding-rules/app.js index 61089511594..feb040c3562 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/app.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/app.js @@ -63,7 +63,7 @@ var App = new Marionette.Application(), App.manualRepository = function () { return { key: 'manual', - name: t('coding_rules.manual_rule'), + name: window.t('coding_rules.manual_rule'), language: 'none' }; }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js index d816c21c219..453aa8fd107 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js @@ -15,14 +15,14 @@ export default ModalFormView.extend({ showSuccessMessage: function (profile, succeeded) { var profileBase = _.findWhere(this.options.app.qualityProfiles, { key: profile }), profileName = profileBase != null ? profileBase.name : profile, - message = tp('coding_rules.bulk_change.success', profileName, profileBase.language, succeeded); + message = window.tp('coding_rules.bulk_change.success', profileName, profileBase.language, succeeded); this.ui.messagesContainer.append('
' + message + '
'); }, showWarnMessage: function (profile, succeeded, failed) { var profileBase = _.findWhere(this.options.app.qualityProfiles, { key: profile }), profileName = profileBase != null ? profileBase.name : profile, - message = tp('coding_rules.bulk_change.warning', profileName, profileBase.language, succeeded, failed); + message = window.tp('coding_rules.bulk_change.warning', profileName, profileBase.language, succeeded, failed); this.ui.messagesContainer.append('
' + message + '
'); }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js index 2062e292b99..2ab853c763a 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js @@ -26,7 +26,7 @@ export default BaseFacet.extend({ forbid: function () { BaseFacet.prototype.forbid.apply(this, arguments); - this.$el.prop('title', t('coding_rules.filters.active_severity.inactive')); + this.$el.prop('title', window.t('coding_rules.filters.active_severity.inactive')); }, allow: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js index 9b2e01ef70a..bf3739cf70c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js @@ -22,17 +22,17 @@ export default BaseFacet.extend({ prepareSearch: function () { this.$('.js-custom-value').select2({ - placeholder: t('search_verb'), + placeholder: window.t('search_verb'), minimumInputLength: 1, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 1); + return window.tp('select2.tooShort', 1); }, width: '100%', ajax: this.prepareAjaxSearch() diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js index d72f47e4584..490498a13cb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js @@ -30,7 +30,7 @@ export default BaseFacet.extend({ forbid: function () { BaseFacet.prototype.forbid.apply(this, arguments); - this.$el.prop('title', t('coding_rules.filters.inheritance.inactive')); + this.$el.prop('title', window.t('coding_rules.filters.inheritance.inactive')); }, allow: function () { @@ -42,7 +42,7 @@ export default BaseFacet.extend({ var values = ['NONE', 'INHERITED', 'OVERRIDES']; return values.map(function (key) { return { - label: t('coding_rules.filters.inheritance', key.toLowerCase()), + label: window.t('coding_rules.filters.inheritance', key.toLowerCase()), val: key }; }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js index 23b0e41e089..fa453552567 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js @@ -7,7 +7,7 @@ export default BaseFacet.extend({ getValues: function () { var values = this.model.getValues(); var x = values.map(function (value) { - return _.extend(value, { label: t('rules.status', value.val.toLowerCase()) }); + return _.extend(value, { label: window.t('rules.status', value.val.toLowerCase()) }); }); return x; }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index f8dee5b02cd..87ae705c660 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -130,8 +130,8 @@ export default Marionette.LayoutView.extend({ var that = this, ruleType = this.model.has('templateKey') ? 'custom' : 'manual'; confirmDialog({ - title: t('delete'), - html: tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')), + title: window.t('delete'), + html: window.tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')), yesHandler: function () { var url = baseUrl + '/api/rules/delete', options = { key: that.model.id }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js index ff0da3c7803..b4712e1c15e 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js @@ -153,7 +153,7 @@ export default ModalFormView.extend({ }).fail(function (jqXHR) { if (jqXHR.status === 409) { that.existingRule = jqXHR.responseJSON.rule; - that.showErrors([], [{ msg: t('coding_rules.reactivate.help') }]); + that.showErrors([], [{ msg: window.t('coding_rules.reactivate.help') }]); that.ui.customRuleCreationCreate.addClass('hidden'); that.ui.customRuleCreationReactivate.removeClass('hidden'); } else { @@ -175,7 +175,7 @@ export default ModalFormView.extend({ var statuses = ['READY', 'BETA', 'DEPRECATED'].map(function (status) { return { id: status, - text: t('rules.status', status.toLowerCase()) + text: window.t('rules.status', status.toLowerCase()) }; }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js index 6e7002ba587..791334b4a0f 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js @@ -19,8 +19,8 @@ export default Marionette.ItemView.extend({ deleteRule: function () { var that = this; confirmDialog({ - title: t('delete'), - html: t('are_you_sure'), + title: window.t('delete'), + html: window.t('are_you_sure'), yesHandler: function () { var url = baseUrl + '/api/rules/delete', options = { key: that.model.id }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js index cb0869490d0..dab19f1fb13 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js @@ -99,7 +99,7 @@ export default ModalFormView.extend({ }).fail(function (jqXHR) { if (jqXHR.status === 409) { that.existingRule = jqXHR.responseJSON.rule; - that.showErrors([], [{ msg: t('coding_rules.reactivate.help') }]); + that.showErrors([], [{ msg: window.t('coding_rules.reactivate.help') }]); that.ui.manualRuleCreationCreate.addClass('hidden'); that.ui.manualRuleCreationReactivate.removeClass('hidden'); } else { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js index c1a2bc458e5..9b88e3267ce 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js @@ -64,7 +64,7 @@ export default Marionette.ItemView.extend({ removeExtendedDescription: function () { var that = this; confirmDialog({ - html: t('coding_rules.remove_extended_description.confirm'), + html: window.t('coding_rules.remove_extended_description.confirm'), yesHandler: function () { that.ui.extendDescriptionText.val(''); that.submitExtendDescription(); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index 1c74fc9dd63..6139044cbf6 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -50,8 +50,8 @@ export default Marionette.ItemView.extend({ var that = this, ruleKey = this.options.rule.get('key'); confirmDialog({ - title: t('coding_rules.revert_to_parent_definition'), - html: tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), + title: window.t('coding_rules.revert_to_parent_definition'), + html: window.tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), yesHandler: function () { return $.ajax({ type: 'POST', @@ -72,8 +72,8 @@ export default Marionette.ItemView.extend({ var that = this, ruleKey = this.options.rule.get('key'); confirmDialog({ - title: t('coding_rules.deactivate'), - html: tp('coding_rules.deactivate.confirm'), + title: window.t('coding_rules.deactivate'), + html: window.tp('coding_rules.deactivate.confirm'), yesHandler: function () { return $.ajax({ type: 'POST', @@ -137,5 +137,3 @@ export default Marionette.ItemView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js index 6563efc2e3a..5045ff3891d 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js @@ -4,8 +4,6 @@ export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', template: function () { - return t('coding_rules.no_results'); + return window.t('coding_rules.no_results'); } }); - - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js index 5897372020b..05e54964103 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js @@ -62,8 +62,8 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ ruleKey = this.model.get('key'), activation = this.model.get('activation'); confirmDialog({ - title: t('coding_rules.deactivate'), - html: tp('coding_rules.deactivate.confirm'), + title: window.t('coding_rules.deactivate'), + html: window.tp('coding_rules.deactivate.confirm'), yesHandler: function () { return $.ajax({ type: 'POST', diff --git a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js index 6567912ab1e..ec9d1a2966e 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js @@ -11,13 +11,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 2); + return window.tp('select2.tooShort', 2); }, width: '100%', ajax: { @@ -38,5 +38,3 @@ export default CustomValuesFacet.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js index bf86b4970fb..e9bb08d5853 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js @@ -26,13 +26,13 @@ export default BaseFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 2); + return window.tp('select2.tooShort', 2); }, width: '100%', ajax: this.prepareAjaxSearch() @@ -65,5 +65,3 @@ export default BaseFacet.extend({ return this.options.app.state.updateFilter(obj); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js index c3d6f274420..e1d48fd5ac2 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js @@ -12,13 +12,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 2); + return window.tp('select2.tooShort', 2); }, width: '100%', ajax: { @@ -62,5 +62,3 @@ export default CustomValuesFacet.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js index 5c8eef0fd0e..b4657f808df 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js @@ -28,13 +28,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 2); + return window.tp('select2.tooShort', 2); }, width: '100%', ajax: { @@ -78,5 +78,3 @@ export default CustomValuesFacet.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js index 8d50f462c0e..d049890807b 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js @@ -13,13 +13,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, formatInputTooShort: function () { - return tp('select2.tooShort', 2); + return window.tp('select2.tooShort', 2); }, width: '100%', ajax: { @@ -74,5 +74,3 @@ export default CustomValuesFacet.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js index 291bcf6f393..52b0a49c5bb 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js @@ -13,10 +13,10 @@ export default CustomValuesFacet.extend({ minimumInputLength: 0, allowClear: false, formatNoMatches: function () { - return t('select2.noMatches'); + return window.t('select2.noMatches'); }, formatSearching: function () { - return t('select2.searching'); + return window.t('select2.searching'); }, width: '100%', ajax: { @@ -50,5 +50,3 @@ export default CustomValuesFacet.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js index b40c68d0ab6..391dbbfd461 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js @@ -4,8 +4,6 @@ export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', template: function () { - return t('issue_filter.no_issues'); + return window.t('issue_filter.no_issues'); } }); - - diff --git a/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js index 2223139a760..861e82ad2b5 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js @@ -8,13 +8,12 @@ import { DomainTreemap } from '../components/domain-treemap'; import { DomainBubbleChart } from '../components/domain-bubble-chart'; import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; -import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; +import { filterMetrics, filterMetricsForDomains, getMetricName } from '../helpers/metrics'; import { DomainLeakTitle } from '../main/components'; import { CHART_COLORS_RANGE_PERCENT } from '../../../helpers/constants'; import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; import { DonutChart } from '../../../components/charts/donut-chart'; import { DrilldownLink } from '../../../components/shared/drilldown-link'; -import { getMetricName } from '../helpers/metrics'; export const DuplicationsMain = React.createClass({ diff --git a/server/sonar-web/src/main/js/apps/projects/form-view.js b/server/sonar-web/src/main/js/apps/projects/form-view.js index c5e12ab40d8..8f8951c7b1a 100644 --- a/server/sonar-web/src/main/js/apps/projects/form-view.js +++ b/server/sonar-web/src/main/js/apps/projects/form-view.js @@ -1,5 +1,4 @@ -import ModalForm from 'components/common/modal-form'; -import './templates'; +import ModalForm from '../../components/common/modal-form'; export default ModalForm.extend({ @@ -19,5 +18,3 @@ export default ModalForm.extend({ } }); - - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js index 9ab319a78e7..fef2d7638ac 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js @@ -90,11 +90,9 @@ export default Marionette.ItemView.extend({ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { canEdit: this.options.canEdit, periods: this.options.periods, - periodText: period ? period.text : t('value'), + periodText: period ? period.text : window.t('value'), metric: this.getMetric(), isDiffMetric: this.isDiffMetric() }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js index 4994a9da37b..e7f75a33107 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js @@ -34,7 +34,7 @@ export default Marionette.CompositeView.extend({ this.ui.metricSelect.select2({ allowClear: false, width: '250px', - placeholder: t('alerts.select_metric') + placeholder: window.t('alerts.select_metric') }); }, @@ -71,5 +71,3 @@ export default Marionette.CompositeView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js index ff7816bd659..5d0493a59f5 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js @@ -25,14 +25,14 @@ export default Marionette.ItemView.extend({ selectParameter: 'projectId', selectParameterValue: 'id', labels: { - selected: t('quality_gates.projects.with'), - deselected: t('quality_gates.projects.without'), - all: t('quality_gates.projects.all'), - noResults: t('quality_gates.projects.noResults') + selected: window.t('quality_gates.projects.with'), + deselected: window.t('quality_gates.projects.without'), + all: window.t('quality_gates.projects.all'), + noResults: window.t('quality_gates.projects.noResults') }, tooltips: { - select: t('quality_gates.projects.select_hint'), - deselect: t('quality_gates.projects.deselect_hint') + select: window.t('quality_gates.projects.select_hint'), + deselect: window.t('quality_gates.projects.deselect_hint') } }); } @@ -44,5 +44,3 @@ export default Marionette.ItemView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js b/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js index 7e060b9599b..479b9b18299 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/helpers.js @@ -15,15 +15,19 @@ Handlebars.registerHelper('exporterUrl', function (profile, exporterKey) { }); Handlebars.registerHelper('severityChangelog', function (severity) { - var label = ' ' + t('severity', severity), - message = tp('quality_profiles.severity_set_to_x', label); + var label = ' ' + window.t('severity', severity), + message = window.tp('quality_profiles.severity_set_to_x', label); return new Handlebars.SafeString(message); }); Handlebars.registerHelper('parameterChangelog', function (value, parameter) { if (parameter) { - return new Handlebars.SafeString(tp('quality_profiles.parameter_set_to_x', value, parameter)); + return new Handlebars.SafeString( + window.tp('quality_profiles.parameter_set_to_x', value, parameter) + ); } else { - return new Handlebars.SafeString(tp('quality_profiles.changelog.parameter_reset_to_default_value_x', parameter)); + return new Handlebars.SafeString( + window.tp('quality_profiles.changelog.parameter_reset_to_default_value_x', parameter) + ); } }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js index b5f9167033d..10fc51c4a30 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js @@ -74,14 +74,14 @@ export default Marionette.LayoutView.extend({ selectParameter: 'projectUuid', selectParameterValue: 'uuid', labels: { - selected: t('quality_gates.projects.with'), - deselected: t('quality_gates.projects.without'), - all: t('quality_gates.projects.all'), - noResults: t('quality_gates.projects.noResults') + selected: window.t('quality_gates.projects.with'), + deselected: window.t('quality_gates.projects.without'), + all: window.t('quality_gates.projects.all'), + noResults: window.t('quality_gates.projects.noResults') }, tooltips: { - select: t('quality_profiles.projects.select_hint'), - deselect: t('quality_profiles.projects.deselect_hint') + select: window.t('quality_profiles.projects.select_hint'), + deselect: window.t('quality_profiles.projects.deselect_hint') } }); this.listenTo(this.projectsSelectList.collection, 'change:selected', this.onProjectsChange); @@ -158,5 +158,3 @@ export default Marionette.LayoutView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js index e732493b89a..76f1ea1eb1a 100644 --- a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js @@ -122,7 +122,7 @@ export default ActionOptionsView.extend({ if (this.assignees) { return this.assignees; } - var assignees = [{ id: '', text: t('unassigned') }], + var assignees = [{ id: '', text: window.t('unassigned') }], currentUser = window.SS.user, currentUserName = window.SS.userName; assignees.push({ id: currentUser, text: currentUserName }); @@ -138,5 +138,3 @@ export default ActionOptionsView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js index 244d65e6a79..ad924a6302e 100644 --- a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js @@ -26,7 +26,7 @@ export default ActionOptionsView.extend({ }, getActionPlans: function () { - return [{ key: '', name: t('issue.unplanned') }].concat(this.collection.toJSON()); + return [{ key: '', name: window.t('issue.unplanned') }].concat(this.collection.toJSON()); }, serializeData: function () { @@ -35,5 +35,3 @@ export default ActionOptionsView.extend({ }); } }); - - diff --git a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js index 153cae4fc9e..f3df5eea122 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js @@ -250,7 +250,7 @@ var ChoiceFilterView = BaseFilters.BaseFilterView.extend({ }), defaultValue = this.model.has('defaultValue') ? this.model.get('defaultValue') : - this.model.get('multiple') ? t('all') : t('any'); + this.model.get('multiple') ? window.t('all') : window.t('any'); return this.isDefaultValue() ? defaultValue : value.join(', '); }, @@ -387,5 +387,3 @@ export default { DetailsChoiceFilterView: DetailsChoiceFilterView, ChoiceFilterView: ChoiceFilterView }; - - diff --git a/server/sonar-web/src/main/js/components/source-viewer/main.js b/server/sonar-web/src/main/js/components/source-viewer/main.js index cf0ef14db0a..27b9af66d37 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/main.js +++ b/server/sonar-web/src/main/js/components/source-viewer/main.js @@ -712,7 +712,7 @@ export default Marionette.LayoutView.extend({ $(e.currentTarget).tooltip({ container: 'body', placement: 'right', - title: tp('source_viewer.tooltip.new_code', this.sinceLabel), + title: window.tp('source_viewer.tooltip.new_code', this.sinceLabel), trigger: 'manual' }).tooltip('show'); }, diff --git a/server/sonar-web/src/main/js/components/widgets/barchart.js b/server/sonar-web/src/main/js/components/widgets/barchart.js index ea15e5ea684..03fca21da0d 100644 --- a/server/sonar-web/src/main/js/components/widgets/barchart.js +++ b/server/sonar-web/src/main/js/components/widgets/barchart.js @@ -1,6 +1,7 @@ import $ from 'jquery'; import _ from 'underscore'; import moment from 'moment'; +import d3 from 'd3'; function trans (left, top) { return 'translate(' + left + ', ' + top + ')'; diff --git a/server/sonar-web/src/main/js/helpers/handlebars-helpers.js b/server/sonar-web/src/main/js/helpers/handlebars-helpers.js index e2a5110ee74..b9c54ea4562 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars-helpers.js +++ b/server/sonar-web/src/main/js/helpers/handlebars-helpers.js @@ -1,5 +1,6 @@ import _ from 'underscore'; import moment from 'moment'; +import numeral from 'numeral'; import Handlebars from 'hbsfy/runtime'; import md5 from 'blueimp-md5'; import { formatMeasure, formatMeasureVariation } from './measures'; @@ -77,7 +78,7 @@ Handlebars.registerHelper('severityIcon', function (severity) { Handlebars.registerHelper('severityHelper', function (severity) { return new Handlebars.SafeString( - ' ' + t('severity', severity) + ' ' + window.t('severity', severity) ); }); @@ -88,9 +89,9 @@ Handlebars.registerHelper('statusIcon', function (status) { }); Handlebars.registerHelper('statusHelper', function (status, resolution) { - var s = ' ' + t('issue.status', status); + var s = ' ' + window.t('issue.status', status); if (resolution != null) { - s = s + ' (' + t('issue.resolution', resolution) + ')'; + s = s + ' (' + window.t('issue.resolution', resolution) + ')'; } return new Handlebars.SafeString(s); }); @@ -450,13 +451,13 @@ Handlebars.registerHelper('operators', function (options) { Handlebars.registerHelper('changelog', function (diff) { var message = ''; if (diff.newValue != null) { - message = tp('issue.changelog.changed_to', t('issue.changelog.field', diff.key), diff.newValue); + message = window.tp('issue.changelog.changed_to', window.t('issue.changelog.field', diff.key), diff.newValue); } else { - message = tp('issue.changelog.removed', t('issue.changelog.field', diff.key)); + message = window.tp('issue.changelog.removed', window.t('issue.changelog.field', diff.key)); } if (diff.oldValue != null) { message += ' ('; - message += tp('issue.changelog.was', diff.oldValue); + message += window.tp('issue.changelog.was', diff.oldValue); message += ')'; } return message; diff --git a/server/sonar-web/src/main/js/main/nav/global/search-view.js b/server/sonar-web/src/main/js/main/nav/global/search-view.js index 65a3a4a7740..fbe9f3bcddc 100644 --- a/server/sonar-web/src/main/js/main/nav/global/search-view.js +++ b/server/sonar-web/src/main/js/main/nav/global/search-view.js @@ -155,16 +155,16 @@ export default Marionette.LayoutView.extend({ url: url, name: historyItem.name, q: historyItem.icon, - extra: index === 0 ? t('browsed_recently') : null + extra: index === 0 ? window.t('browsed_recently') : null }; }), favorite = _.first(this.favorite, 6).map(function (f, index) { - return _.extend(f, { extra: index === 0 ? t('favorite') : null }); + return _.extend(f, { extra: index === 0 ? window.t('favorite') : null }); }), qualifiers = this.model.get('qualifiers').map(function (q, index) { return { url: baseUrl + '/all_projects?qualifier=' + encodeURIComponent(q), - name: t('qualifiers.all', q), + name: window.t('qualifiers.all', q), extra: index === 0 ? '' : null }; }); @@ -201,22 +201,22 @@ export default Marionette.LayoutView.extend({ getNavigationFindings: function (q) { var DEFAULT_ITEMS = [ - { name: t('issues.page'), url: baseUrl + '/issues/search' }, - { name: t('layout.measures'), url: baseUrl + '/measures/search?qualifiers[]=TRK' }, - { name: t('coding_rules.page'), url: baseUrl + '/coding_rules' }, - { name: t('quality_profiles.page'), url: baseUrl + '/profiles' }, - { name: t('quality_gates.page'), url: baseUrl + '/quality_gates' }, - { name: t('comparison_global.page'), url: baseUrl + '/comparison' } + { name: window.t('issues.page'), url: baseUrl + '/issues/search' }, + { name: window.t('layout.measures'), url: baseUrl + '/measures/search?qualifiers[]=TRK' }, + { name: window.t('coding_rules.page'), url: baseUrl + '/coding_rules' }, + { name: window.t('quality_profiles.page'), url: baseUrl + '/profiles' }, + { name: window.t('quality_gates.page'), url: baseUrl + '/quality_gates' }, + { name: window.t('comparison_global.page'), url: baseUrl + '/comparison' } ], customItems = []; if (window.SS.isUserAdmin) { - customItems.push({ name: t('layout.settings'), url: baseUrl + '/settings' }); + customItems.push({ name: window.t('layout.settings'), url: baseUrl + '/settings' }); } var findings = [].concat(DEFAULT_ITEMS, customItems).filter(function (f) { return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = t('navigation'); + findings[0].extra = window.t('navigation'); } return _.first(findings, 6); }, @@ -230,7 +230,7 @@ export default Marionette.LayoutView.extend({ return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = t('dashboard.global_dashboards'); + findings[0].extra = window.t('dashboard.global_dashboards'); } return _.first(findings, 6); }, @@ -240,10 +240,8 @@ export default Marionette.LayoutView.extend({ return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = t('favorite'); + findings[0].extra = window.t('favorite'); } return _.first(findings, 6); } }); - - diff --git a/server/sonar-web/src/main/js/main/processes.js b/server/sonar-web/src/main/js/main/processes.js index 1d685ab953d..af67b1b6197 100644 --- a/server/sonar-web/src/main/js/main/processes.js +++ b/server/sonar-web/src/main/js/main/processes.js @@ -30,7 +30,7 @@ var Process = Backbone.Model.extend({ fail: function (message) { var that = this, - msg = message || t('process.fail'); + msg = message || window.t('process.fail'); if (msg === 'process.fail') { // no translation msg = 'An error happened, some parts of the page might not render correctly. ' + diff --git a/server/sonar-web/src/main/js/widgets/old/tag-cloud.js b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js index d09f38b55bb..cd2851ab8a2 100644 --- a/server/sonar-web/src/main/js/widgets/old/tag-cloud.js +++ b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js @@ -64,7 +64,7 @@ TagCloud.prototype.tooltip = function (d) { var suffixKey = d.value === 1 ? 'issue' : 'issues', - suffix = t(suffixKey); + suffix = window.t(suffixKey); return (d.value + '\u00a0') + suffix; }; -- cgit v1.2.3 From 1b46233a42f2f36f8e4dace604dbe88510966ace Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 09:50:19 +0100 Subject: normalize overview pages urls and titles --- .../test_it_coverage_on_project_overview.html | 2 +- .../test_overall_coverage_on_project_overview.html | 2 +- .../test_ut_coverage_on_project_overview.html | 2 +- .../main/js/apps/overview/domains/debt-domain.js | 2 +- .../main/js/apps/overview/domains/size-domain.js | 193 --------------------- .../js/apps/overview/domains/structure-domain.js | 193 +++++++++++++++++++++ .../src/main/js/apps/overview/main/coverage.js | 6 +- .../src/main/js/apps/overview/main/debt.js | 98 +++++++++++ .../src/main/js/apps/overview/main/duplications.js | 5 +- .../src/main/js/apps/overview/main/issues.js | 96 ---------- .../src/main/js/apps/overview/main/main.js | 8 +- .../src/main/js/apps/overview/main/size.js | 72 -------- .../src/main/js/apps/overview/main/structure.js | 74 ++++++++ .../src/main/js/apps/overview/overview.js | 14 +- .../js/main/nav/component/component-nav-menu.js | 6 +- .../main/resources/org/sonar/l10n/core.properties | 2 +- 16 files changed, 391 insertions(+), 384 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/overview/domains/size-domain.js create mode 100644 server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js create mode 100644 server/sonar-web/src/main/js/apps/overview/main/debt.js delete mode 100644 server/sonar-web/src/main/js/apps/overview/main/issues.js delete mode 100644 server/sonar-web/src/main/js/apps/overview/main/size.js create mode 100644 server/sonar-web/src/main/js/apps/overview/main/structure.js diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html index db38e860191..f5788966cbd 100644 --- a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html +++ b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_it_coverage_on_project_overview.html @@ -26,7 +26,7 @@ open - /sonar/overview/tests?id=project-for-overview-it-coverage + /sonar/overview/coverage?id=project-for-overview-it-coverage diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html index 9d5fd67fee2..96b6bba216f 100644 --- a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html +++ b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_overall_coverage_on_project_overview.html @@ -26,7 +26,7 @@ open - /sonar/overview/tests?id=project-for-overview-overall-coverage + /sonar/overview/coverage?id=project-for-overview-overall-coverage diff --git a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html index fd88d0fc0aa..1dd3c9ccd27 100644 --- a/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html +++ b/it/it-tests/src/test/resources/projectOverview/ProjectOverviewTest/test_ut_coverage_on_project_overview.html @@ -26,7 +26,7 @@ open - /sonar/overview/tests?id=project-for-overview-ut-coverage + /sonar/overview/coverage?id=project-for-overview-ut-coverage diff --git a/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js index 4ee8ce45476..d87d3dc5e70 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js @@ -27,7 +27,7 @@ const KNOWN_METRICS = ['violations', 'sqale_index', 'sqale_rating', 'sqale_debt_ 'critical_violations', 'major_violations', 'minor_violations', 'info_violations', 'confirmed_issues']; -export const IssuesMain = React.createClass({ +export const DebtMain = React.createClass({ mixins: [TooltipsMixin], getInitialState() { diff --git a/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js deleted file mode 100644 index 05a23ae3d51..00000000000 --- a/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js +++ /dev/null @@ -1,193 +0,0 @@ -import React from 'react'; - -import { LanguageDistribution } from './../components/language-distribution'; -import { ComplexityDistribution } from './../components/complexity-distribution'; -import { NclocDistribution } from '../components/ncloc-distribution'; -import { getMeasuresAndVariations } from '../../../api/measures'; -import { DetailedMeasure } from '../components/detailed-measure'; -import { DomainTimeline } from '../components/domain-timeline'; -import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; -import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; -import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; -import { DomainLeakTitle } from '../main/components'; - - -export const SizeMain = React.createClass({ - mixins: [TooltipsMixin], - - getInitialState() { - return { - ready: false, - leakPeriodLabel: getPeriodLabel(this.props.component.periods, this.props.leakPeriodIndex), - leakPeriodDate: getPeriodDate(this.props.component.periods, this.props.leakPeriodIndex) - }; - }, - - componentDidMount() { - this.requestMeasures().then(r => { - let measures = this.getMeasuresValues(r, 'value'); - let leak = this.getMeasuresValues(r, 'var' + this.props.leakPeriodIndex); - this.setState({ ready: true, measures, leak }); - }); - }, - - getMeasuresValues (measures, fieldKey) { - let values = {}; - Object.keys(measures).forEach(measureKey => { - values[measureKey] = measures[measureKey][fieldKey]; - }); - return values; - }, - - getMetricsForDomain() { - return this.props.metrics - .filter(metric => ['Size', 'Complexity', 'Documentation'].indexOf(metric.domain) !== -1) - .map(metric => metric.key); - }, - - getMetricsForTimeline() { - return filterMetricsForDomains(this.props.metrics, ['Size', 'Complexity', 'Documentation']); - }, - - getAllMetricsForTimeline() { - return filterMetrics(this.props.metrics); - }, - - requestMeasures () { - return getMeasuresAndVariations(this.props.component.key, this.getMetricsForDomain()); - }, - - renderLoading () { - return
- -
; - }, - - renderLegend () { - return ; - }, - - renderOtherMeasures(domain, hiddenMetrics) { - let metrics = filterMetricsForDomains(this.props.metrics, [domain]) - .filter(metric => hiddenMetrics.indexOf(metric.key) === -1) - .map(metric => { - return ; - }); - return
{metrics}
; - }, - - renderOtherSizeMeasures() { - return this.renderOtherMeasures('Size', ['ncloc']); - }, - - renderOtherComplexityMeasures() { - return this.renderOtherMeasures('Complexity', - ['complexity', 'function_complexity', 'file_complexity', 'class_complexity']); - }, - - renderOtherDocumentationMeasures() { - return this.renderOtherMeasures('Documentation', []); - }, - - renderLanguageDistribution() { - let distribution = this.state.measures['ncloc_language_distribution']; - if (distribution == null) { - return null; - } - return ; - }, - - renderComplexityDistribution(distribution, props) { - if (distribution == null) { - return null; - } - return ; - }, - - renderComplexityCard() { - if (this.state.measures['complexity'] == null) { - return null; - } - - return
-
- - - {this.renderComplexityDistribution(this.state.measures['function_complexity_distribution'], - { of: 'function' })} - - - {this.renderComplexityDistribution(this.state.measures['file_complexity_distribution'], - { of: 'file' })} - - - {this.renderOtherComplexityMeasures()} -
-
; - }, - - render () { - if (!this.state.ready) { - return this.renderLoading(); - } - return
-
-
-
{window.t('overview.domain.size')}
- {this.renderLegend()} -
- -
-
-
- - {this.renderLanguageDistribution()} - - {this.renderOtherSizeMeasures()} -
-
- - {this.renderComplexityCard()} - -
-
- {this.renderOtherDocumentationMeasures()} -
-
-
-
- -
-
- -
-
- -
-
-
; - - } -}); diff --git a/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js new file mode 100644 index 00000000000..3c1563bde01 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js @@ -0,0 +1,193 @@ +import React from 'react'; + +import { LanguageDistribution } from './../components/language-distribution'; +import { ComplexityDistribution } from './../components/complexity-distribution'; +import { NclocDistribution } from '../components/ncloc-distribution'; +import { getMeasuresAndVariations } from '../../../api/measures'; +import { DetailedMeasure } from '../components/detailed-measure'; +import { DomainTimeline } from '../components/domain-timeline'; +import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; +import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; +import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; +import { DomainLeakTitle } from '../main/components'; + + +export const StructureMain = React.createClass({ + mixins: [TooltipsMixin], + + getInitialState() { + return { + ready: false, + leakPeriodLabel: getPeriodLabel(this.props.component.periods, this.props.leakPeriodIndex), + leakPeriodDate: getPeriodDate(this.props.component.periods, this.props.leakPeriodIndex) + }; + }, + + componentDidMount() { + this.requestMeasures().then(r => { + let measures = this.getMeasuresValues(r, 'value'); + let leak = this.getMeasuresValues(r, 'var' + this.props.leakPeriodIndex); + this.setState({ ready: true, measures, leak }); + }); + }, + + getMeasuresValues (measures, fieldKey) { + let values = {}; + Object.keys(measures).forEach(measureKey => { + values[measureKey] = measures[measureKey][fieldKey]; + }); + return values; + }, + + getMetricsForDomain() { + return this.props.metrics + .filter(metric => ['Size', 'Complexity', 'Documentation'].indexOf(metric.domain) !== -1) + .map(metric => metric.key); + }, + + getMetricsForTimeline() { + return filterMetricsForDomains(this.props.metrics, ['Size', 'Complexity', 'Documentation']); + }, + + getAllMetricsForTimeline() { + return filterMetrics(this.props.metrics); + }, + + requestMeasures () { + return getMeasuresAndVariations(this.props.component.key, this.getMetricsForDomain()); + }, + + renderLoading () { + return
+ +
; + }, + + renderLegend () { + return ; + }, + + renderOtherMeasures(domain, hiddenMetrics) { + let metrics = filterMetricsForDomains(this.props.metrics, [domain]) + .filter(metric => hiddenMetrics.indexOf(metric.key) === -1) + .map(metric => { + return ; + }); + return
{metrics}
; + }, + + renderOtherSizeMeasures() { + return this.renderOtherMeasures('Size', ['ncloc']); + }, + + renderOtherComplexityMeasures() { + return this.renderOtherMeasures('Complexity', + ['complexity', 'function_complexity', 'file_complexity', 'class_complexity']); + }, + + renderOtherDocumentationMeasures() { + return this.renderOtherMeasures('Documentation', []); + }, + + renderLanguageDistribution() { + let distribution = this.state.measures['ncloc_language_distribution']; + if (distribution == null) { + return null; + } + return ; + }, + + renderComplexityDistribution(distribution, props) { + if (distribution == null) { + return null; + } + return ; + }, + + renderComplexityCard() { + if (this.state.measures['complexity'] == null) { + return null; + } + + return
+
+ + + {this.renderComplexityDistribution(this.state.measures['function_complexity_distribution'], + { of: 'function' })} + + + {this.renderComplexityDistribution(this.state.measures['file_complexity_distribution'], + { of: 'file' })} + + + {this.renderOtherComplexityMeasures()} +
+
; + }, + + render () { + if (!this.state.ready) { + return this.renderLoading(); + } + return
+
+
+
{window.t('overview.domain.structure')}
+ {this.renderLegend()} +
+ +
+
+
+ + {this.renderLanguageDistribution()} + + {this.renderOtherSizeMeasures()} +
+
+ + {this.renderComplexityCard()} + +
+
+ {this.renderOtherDocumentationMeasures()} +
+
+
+
+ +
+
+ +
+
+ +
+
+
; + + } +}); diff --git a/server/sonar-web/src/main/js/apps/overview/main/coverage.js b/server/sonar-web/src/main/js/apps/overview/main/coverage.js index 07aaff0c383..7755cb28df7 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/coverage.js +++ b/server/sonar-web/src/main/js/apps/overview/main/coverage.js @@ -85,9 +85,11 @@ export const GeneralCoverage = React.createClass({ ]; return - + - + diff --git a/server/sonar-web/src/main/js/apps/overview/main/debt.js b/server/sonar-web/src/main/js/apps/overview/main/debt.js new file mode 100644 index 00000000000..490eadc22c8 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/main/debt.js @@ -0,0 +1,98 @@ +import moment from 'moment'; +import React from 'react'; + +import { Domain, + DomainHeader, + DomainPanel, + DomainNutshell, + DomainLeak, + MeasuresList, + Measure, + DomainMixin } from './components'; +import { Rating } from './../../../components/shared/rating'; +import { IssuesLink } from '../../../components/shared/issues-link'; +import { DrilldownLink } from '../../../components/shared/drilldown-link'; +import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; +import { Legend } from '../components/legend'; +import { getMetricName } from '../helpers/metrics'; +import { formatMeasure } from '../../../helpers/measures'; + + +export const GeneralDebt = React.createClass({ + propTypes: { + leakPeriodLabel: React.PropTypes.string, + leakPeriodDate: React.PropTypes.object + }, + + mixins: [TooltipsMixin, DomainMixin], + + renderLeak () { + if (!this.hasLeakPeriod()) { + return null; + } + + let createdAfter = moment(this.props.leakPeriodDate).format('YYYY-MM-DDTHH:mm:ssZZ'); + + return + + + + + + {formatMeasure(this.props.leak.debt, 'SHORT_WORK_DUR')} + + + + + {formatMeasure(this.props.leak.issues, 'SHORT_INT')} + + + + {this.renderTimeline('after')} + ; + }, + + render () { + return + + + + + + + +
+
+ + + +
+
+
+
+ + {formatMeasure(this.props.measures.debt, 'SHORT_WORK_DUR')} + +
+
{getMetricName('debt')}
+
+
+ + + + {formatMeasure(this.props.measures.issues, 'SHORT_INT')} + + +
+ {this.renderTimeline('before', true)} +
+ {this.renderLeak()} +
+
; + } +}); diff --git a/server/sonar-web/src/main/js/apps/overview/main/duplications.js b/server/sonar-web/src/main/js/apps/overview/main/duplications.js index 64cafcf8932..6240df80417 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/duplications.js +++ b/server/sonar-web/src/main/js/apps/overview/main/duplications.js @@ -57,10 +57,11 @@ export const GeneralDuplications = React.createClass({ ]; return - - + diff --git a/server/sonar-web/src/main/js/apps/overview/main/issues.js b/server/sonar-web/src/main/js/apps/overview/main/issues.js deleted file mode 100644 index 86a145596e2..00000000000 --- a/server/sonar-web/src/main/js/apps/overview/main/issues.js +++ /dev/null @@ -1,96 +0,0 @@ -import moment from 'moment'; -import React from 'react'; - -import { Domain, - DomainHeader, - DomainPanel, - DomainNutshell, - DomainLeak, - MeasuresList, - Measure, - DomainMixin } from './components'; -import { Rating } from './../../../components/shared/rating'; -import { IssuesLink } from '../../../components/shared/issues-link'; -import { DrilldownLink } from '../../../components/shared/drilldown-link'; -import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; -import { Legend } from '../components/legend'; -import { getMetricName } from '../helpers/metrics'; -import { formatMeasure } from '../../../helpers/measures'; - - -export const GeneralIssues = React.createClass({ - propTypes: { - leakPeriodLabel: React.PropTypes.string, - leakPeriodDate: React.PropTypes.object - }, - - mixins: [TooltipsMixin, DomainMixin], - - renderLeak () { - if (!this.hasLeakPeriod()) { - return null; - } - - let createdAfter = moment(this.props.leakPeriodDate).format('YYYY-MM-DDTHH:mm:ssZZ'); - - return - - - - - - {formatMeasure(this.props.leak.debt, 'SHORT_WORK_DUR')} - - - - - {formatMeasure(this.props.leak.issues, 'SHORT_INT')} - - - - {this.renderTimeline('after')} - ; - }, - - render () { - return - - - - - - - -
-
- - - -
-
-
-
- - {formatMeasure(this.props.measures.debt, 'SHORT_WORK_DUR')} - -
-
{getMetricName('debt')}
-
-
- - - - {formatMeasure(this.props.measures.issues, 'SHORT_INT')} - - -
- {this.renderTimeline('before', true)} -
- {this.renderLeak()} -
-
; - } -}); diff --git a/server/sonar-web/src/main/js/apps/overview/main/main.js b/server/sonar-web/src/main/js/apps/overview/main/main.js index 39e17057257..81eabb769f4 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/main.js +++ b/server/sonar-web/src/main/js/apps/overview/main/main.js @@ -2,10 +2,10 @@ import _ from 'underscore'; import moment from 'moment'; import React from 'react'; -import { GeneralIssues } from './issues'; +import { GeneralDebt } from './debt'; import { GeneralCoverage } from './coverage'; import { GeneralDuplications } from './duplications'; -import { GeneralSize } from './size'; +import { GeneralStructure } from './structure'; import { CoverageSelectionMixin } from '../components/coverage-selection-mixin'; import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; import { getMeasuresAndVariations } from '../../../api/measures'; @@ -146,11 +146,11 @@ export default React.createClass({ let props = _.extend({}, this.props, this.state); return
- + - +
; } }); diff --git a/server/sonar-web/src/main/js/apps/overview/main/size.js b/server/sonar-web/src/main/js/apps/overview/main/size.js deleted file mode 100644 index d1138a87f13..00000000000 --- a/server/sonar-web/src/main/js/apps/overview/main/size.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; - -import { Domain, - DomainHeader, - DomainPanel, - DomainNutshell, - DomainLeak, - MeasuresList, - Measure, - DomainMixin } from './components'; -import { DrilldownLink } from '../../../components/shared/drilldown-link'; -import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; -import { getMetricName } from '../helpers/metrics'; -import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; -import { LanguageDistribution } from '../components/language-distribution'; - - -export const GeneralSize = React.createClass({ - propTypes: { - leakPeriodLabel: React.PropTypes.string, - leakPeriodDate: React.PropTypes.object - }, - - mixins: [TooltipsMixin, DomainMixin], - - renderLeak () { - if (!this.hasLeakPeriod()) { - return null; - } - let measure = this.props.leak['ncloc']; - let formatted = measure != null ? formatMeasureVariation(measure, 'SHORT_INT') : '—'; - return - - {formatted} - - {this.renderTimeline('after')} - ; - }, - - renderLanguageDistribution() { - if (!this.props.measures['ncloc'] || !this.props.measures['ncloc_language_distribution']) { - return null; - } - return -
- -
-
; - }, - - render () { - return - - - - - - {this.renderLanguageDistribution()} - - - {formatMeasure(this.props.measures['ncloc'], 'SHORT_INT')} - - - - {this.renderTimeline('before')} - - {this.renderLeak()} - - ; - } -}); diff --git a/server/sonar-web/src/main/js/apps/overview/main/structure.js b/server/sonar-web/src/main/js/apps/overview/main/structure.js new file mode 100644 index 00000000000..a823614a498 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/main/structure.js @@ -0,0 +1,74 @@ +import React from 'react'; + +import { Domain, + DomainHeader, + DomainPanel, + DomainNutshell, + DomainLeak, + MeasuresList, + Measure, + DomainMixin } from './components'; +import { DrilldownLink } from '../../../components/shared/drilldown-link'; +import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; +import { getMetricName } from '../helpers/metrics'; +import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; +import { LanguageDistribution } from '../components/language-distribution'; + + +export const GeneralStructure = React.createClass({ + propTypes: { + leakPeriodLabel: React.PropTypes.string, + leakPeriodDate: React.PropTypes.object + }, + + mixins: [TooltipsMixin, DomainMixin], + + renderLeak () { + if (!this.hasLeakPeriod()) { + return null; + } + let measure = this.props.leak['ncloc']; + let formatted = measure != null ? formatMeasureVariation(measure, 'SHORT_INT') : '—'; + return + + {formatted} + + {this.renderTimeline('after')} + ; + }, + + renderLanguageDistribution() { + if (!this.props.measures['ncloc'] || !this.props.measures['ncloc_language_distribution']) { + return null; + } + return +
+ +
+
; + }, + + render () { + return + + + + + + {this.renderLanguageDistribution()} + + + {formatMeasure(this.props.measures['ncloc'], 'SHORT_INT')} + + + + {this.renderTimeline('before')} + + {this.renderLeak()} + + ; + } +}); diff --git a/server/sonar-web/src/main/js/apps/overview/overview.js b/server/sonar-web/src/main/js/apps/overview/overview.js index 8301fd6add4..706f8b68d2e 100644 --- a/server/sonar-web/src/main/js/apps/overview/overview.js +++ b/server/sonar-web/src/main/js/apps/overview/overview.js @@ -3,10 +3,10 @@ import React from 'react'; import Gate from './gate/gate'; import GeneralMain from './main/main'; import Meta from './meta'; -import { SizeMain } from './domains/size-domain'; +import { StructureMain } from './domains/structure-domain'; import { DuplicationsMain } from './domains/duplications-domain'; import { CoverageMain } from './domains/coverage-domain'; -import { IssuesMain } from './domains/debt-domain'; +import { DebtMain } from './domains/debt-domain'; import { getMetrics } from '../../api/metrics'; import { RouterMixin } from '../../components/router/router'; @@ -45,7 +45,7 @@ export const Overview = React.createClass({ renderSize () { return
- +
; }, @@ -63,7 +63,7 @@ export const Overview = React.createClass({ renderIssues () { return
- +
; }, @@ -74,13 +74,13 @@ export const Overview = React.createClass({ switch (this.state.route) { case '': return this.renderMain(); - case '/size': + case '/structure': return this.renderSize(); case '/duplications': return this.renderDuplications(); - case '/tests': + case '/coverage': return this.renderTests(); - case '/issues': + case '/debt': return this.renderIssues(); default: throw new Error('Unknown route: ' + this.state.route); diff --git a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js index bffbb2ba094..b55e44cc2b3 100644 --- a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js @@ -14,10 +14,10 @@ import { const FIXED_DASHBOARDS = [ { link: '', name: 'overview.page' }, - { link: '/issues', name: 'overview.domain.debt' }, - { link: '/tests', name: 'overview.domain.coverage' }, + { link: '/debt', name: 'overview.domain.debt' }, + { link: '/coverage', name: 'overview.domain.coverage' }, { link: '/duplications', name: 'overview.domain.duplications' }, - { link: '/size', name: 'overview.domain.size' } + { link: '/structure', name: 'overview.domain.structure' } ]; const SETTINGS_URLS = [ 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 033d44b6fd4..01d36315595 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -3146,7 +3146,7 @@ overview.gate.view.errors=The view failed the quality gate on the following cond overview.domain.debt=Technical Debt overview.domain.coverage=Coverage overview.domain.duplications=Duplications -overview.domain.size=Size +overview.domain.structure=Structure overview.chart.files=Files overview.chart.files.limit_message=Only {0} files are displayed. -- cgit v1.2.3 From 2d5660a9a61d4074644fed44ff535107e714b6d3 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 09:57:23 +0100 Subject: filter out empty components on the overview treemap --- .../js/apps/overview/components/domain-treemap.js | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js b/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js index 033a791ead4..03253cbcf5a 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js +++ b/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js @@ -95,20 +95,21 @@ export class DomainTreemap extends React.Component { return this.renderLoading(); } - // TODO filter out zero sized components - let items = this.state.components.map(component => { - let colorMeasure = this.props.colorMetric ? component.measures[this.props.colorMetric] : null; - return { - key: component.key, - name: component.name, - qualifier: component.qualifier, - size: component.measures[this.props.sizeMetric], - color: colorMeasure != null ? this.props.scale(colorMeasure) : '#777', - tooltip: this.getTooltip(component), - label: component.name, - link: getComponentUrl(component.key) - }; - }); + let items = this.state.components + .filter(component => component.measures[this.props.sizeMetric]) + .map(component => { + let colorMeasure = this.props.colorMetric ? component.measures[this.props.colorMetric] : null; + return { + key: component.key, + name: component.name, + qualifier: component.qualifier, + size: component.measures[this.props.sizeMetric], + color: colorMeasure != null ? this.props.scale(colorMeasure) : '#777', + tooltip: this.getTooltip(component), + label: component.name, + link: getComponentUrl(component.key) + }; + }); const canBeClicked = node => node.qualifier !== 'FIL' && node.qualifier !== 'UTS'; -- cgit v1.2.3 From 6f53fe94310099647638c7c41a45c8ce04789511 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 10:13:17 +0100 Subject: fix tooltips on the overview treemap --- server/sonar-web/src/main/js/components/charts/treemap.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/sonar-web/src/main/js/components/charts/treemap.js b/server/sonar-web/src/main/js/components/charts/treemap.js index 63e974f5995..44d54dd698f 100644 --- a/server/sonar-web/src/main/js/components/charts/treemap.js +++ b/server/sonar-web/src/main/js/components/charts/treemap.js @@ -56,7 +56,7 @@ export const TreemapRect = React.createClass({ if (this.props.tooltip) { tooltipAttrs = { 'data-toggle': 'tooltip', - 'title': this.props.tooltip + 'data-title': this.props.tooltip }; } let cellStyles = { @@ -126,10 +126,11 @@ export const Treemap = React.createClass({ let prefix = mostCommitPrefix(this.props.items.map(item => item.label)); let prefixLength = prefix.length; - let rectangles = nodes.map((node, index) => { + let rectangles = nodes.map(node => { + const key = node.label; let label = prefixLength ? `${prefix}
${node.label.substr(prefixLength)}` : node.label; const onClick = this.props.canBeClicked(node) ? () => this.props.onRectangleClick(node) : null; - return Date: Wed, 9 Dec 2015 10:53:34 +0100 Subject: improve scales of the bubble chart on the overview page --- .../src/main/js/components/charts/bubble-chart.js | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/server/sonar-web/src/main/js/components/charts/bubble-chart.js b/server/sonar-web/src/main/js/components/charts/bubble-chart.js index 270bec31d12..9df80a47cf6 100644 --- a/server/sonar-web/src/main/js/components/charts/bubble-chart.js +++ b/server/sonar-web/src/main/js/components/charts/bubble-chart.js @@ -6,6 +6,9 @@ import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; +const TICKS_COUNT = 5; + + export const Bubble = React.createClass({ propTypes: { x: React.PropTypes.number.isRequired, @@ -85,12 +88,19 @@ export const BubbleChart = React.createClass({ return [availableHeight - dMaxY, dMinY]; }, - renderXGrid (xScale, yScale) { + getTicks(scale, format) { + let ticks = scale.ticks(TICKS_COUNT).map(tick => format(tick)); + const uniqueTicksCount = _.uniq(ticks).length; + const ticksCount = uniqueTicksCount < TICKS_COUNT ? uniqueTicksCount - 1 : TICKS_COUNT; + return scale.ticks(ticksCount); + }, + + renderXGrid (ticks, xScale, yScale) { if (!this.props.displayXGrid) { return null; } - let lines = xScale.ticks().map((tick, index) => { + let lines = ticks.map((tick, index) => { let x = xScale(tick); let y1 = yScale.range()[0]; let y2 = yScale.range()[1]; @@ -105,12 +115,12 @@ export const BubbleChart = React.createClass({ return {lines}; }, - renderYGrid (xScale, yScale) { + renderYGrid (ticks, xScale, yScale) { if (!this.props.displayYGrid) { return null; } - let lines = yScale.ticks(5).map((tick, index) => { + let lines = ticks.map((tick, index) => { let y = yScale(tick); let x1 = xScale.range()[0]; let x2 = xScale.range()[1]; @@ -125,12 +135,12 @@ export const BubbleChart = React.createClass({ return {lines}; }, - renderXTicks (xScale, yScale) { + renderXTicks (xTicks, xScale, yScale) { if (!this.props.displayXTicks) { return null; } - let ticks = xScale.ticks().map((tick, index) => { + let ticks = xTicks.map((tick, index) => { let x = xScale(tick); let y = yScale.range()[0]; let innerText = this.props.formatXTick(tick); @@ -144,12 +154,12 @@ export const BubbleChart = React.createClass({ return {ticks}; }, - renderYTicks (xScale, yScale) { + renderYTicks (yTicks, xScale, yScale) { if (!this.props.displayYTicks) { return null; } - let ticks = yScale.ticks(5).map((tick, index) => { + let ticks = yTicks.map((tick, index) => { let x = xScale.range()[0]; let y = yScale(tick); let innerText = this.props.formatYTick(tick); @@ -198,12 +208,15 @@ export const BubbleChart = React.createClass({ x={xScale(item.x)} y={yScale(item.y)} r={sizeScale(item.size)}/>; }); + let xTicks = this.getTicks(xScale, this.props.formatXTick); + let yTicks = this.getTicks(yScale, this.props.formatYTick); + return - {this.renderXGrid(xScale, yScale)} - {this.renderXTicks(xScale, yScaleOriginal)} - {this.renderYGrid(xScale, yScale)} - {this.renderYTicks(xScaleOriginal, yScale)} + {this.renderXGrid(xTicks, xScale, yScale)} + {this.renderXTicks(xTicks, xScale, yScaleOriginal)} + {this.renderYGrid(yTicks, xScale, yScale)} + {this.renderYTicks(yTicks, xScaleOriginal, yScale)} {bubbles} ; -- cgit v1.2.3 From 1c904284e4cc11d11a7310baa269185eff8f5bd2 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 11:27:20 +0100 Subject: love ie11 --- .../sonar-web/src/main/js/apps/overview/components/domain-timeline.js | 4 ++-- server/sonar-web/src/main/less/pages/overview.less | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js b/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js index 25db1cddea3..6400d512f54 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js +++ b/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js @@ -177,7 +177,7 @@ export const DomainTimeline = React.createClass({ ; }, diff --git a/server/sonar-web/src/main/less/pages/overview.less b/server/sonar-web/src/main/less/pages/overview.less index 1f4b4793bb9..633ae90e72e 100644 --- a/server/sonar-web/src/main/less/pages/overview.less +++ b/server/sonar-web/src/main/less/pages/overview.less @@ -290,9 +290,10 @@ flex-flow: column nowrap; justify-content: flex-start; align-items: stretch; + flex: 3 0 auto; .overview-detailed-measure-value { - flex: 1; + flex: 1 0 auto; display: flex; justify-content: center; align-items: center; -- cgit v1.2.3 From e450db4e1969069d82574f77b5978e9dad975787 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 15:25:55 +0100 Subject: add tooltips for ncloc distribution chart --- .../apps/overview/components/ncloc-distribution.js | 7 +++++- .../src/main/js/components/charts/histogram.js | 29 ++++++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js index 764457ad403..0a24b77c65d 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js +++ b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js @@ -65,7 +65,12 @@ export const NclocDistribution = React.createClass({ data = _.sortBy(data, d => -d.x); - let yTicks = data.map(d => collapsePath(d.value, 20)); + let yTicks = data.map(d => { + return { + label: collapsePath(d.value, 20), + tooltip: d.value + }; + }); let yValues = data.map(d => formatMeasure(d.x, 'SHORT_INT')); diff --git a/server/sonar-web/src/main/js/components/charts/histogram.js b/server/sonar-web/src/main/js/components/charts/histogram.js index ffac187583c..c64146f2d28 100644 --- a/server/sonar-web/src/main/js/components/charts/histogram.js +++ b/server/sonar-web/src/main/js/components/charts/histogram.js @@ -40,17 +40,24 @@ export const Histogram = React.createClass({ return null; } let ticks = this.props.yTicks.map((tick, index) => { - let point = this.props.data[index]; - let x = xScale.range()[0]; - let y = Math.round(yScale(point.y) + yScale.rangeBand() / 2 + this.props.barsHeight / 2); - return {tick}; + const point = this.props.data[index]; + const x = xScale.range()[0]; + const y = Math.round(yScale(point.y) + yScale.rangeBand() / 2 + this.props.barsHeight / 2); + const label = tick.label ? tick.label : tick; + const tooltip = tick.tooltip ? tick.tooltip : null; + return + {label} + ; }); return {ticks}; }, -- cgit v1.2.3 From 3d52bb89abbd797f1188861dab6fb5679e31a2a2 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 15:35:38 +0100 Subject: improve display of leak period caption --- server/sonar-web/src/main/less/pages/overview.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/sonar-web/src/main/less/pages/overview.less b/server/sonar-web/src/main/less/pages/overview.less index 633ae90e72e..2debae833ce 100644 --- a/server/sonar-web/src/main/less/pages/overview.less +++ b/server/sonar-web/src/main/less/pages/overview.less @@ -250,6 +250,7 @@ .overview-domain-leak-title { padding: 0 10px; + border: 1px solid @barBorderColor; background: #fffae7; } } @@ -374,9 +375,9 @@ right: -1px; padding: 5px 0 2px; border: 1px solid @barBorderColor; - border-bottom: none; font-size: 14px; text-align: center; + transform: translateY(-4px); } /* -- cgit v1.2.3 From 401f3be5872948e704dc84befe38791d9e6242e7 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 15:46:56 +0100 Subject: increase contract of leak period background --- .../src/main/js/apps/overview/components/timeline-chart.js | 2 +- server/sonar-web/src/main/less/pages/overview.less | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/overview/components/timeline-chart.js b/server/sonar-web/src/main/js/apps/overview/components/timeline-chart.js index e82f5a3c457..83b0f711b6b 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/timeline-chart.js +++ b/server/sonar-web/src/main/js/apps/overview/components/timeline-chart.js @@ -111,7 +111,7 @@ export const Timeline = React.createClass({ y: _.last(yScale.range()), width: xScale.range()[1] - xScale(this.props.leakPeriodDate), height: _.first(yScale.range()) - _.last(yScale.range()), - fill: '#fffae7' + fill: '#fbf3d5' }; return ; }, diff --git a/server/sonar-web/src/main/less/pages/overview.less b/server/sonar-web/src/main/less/pages/overview.less index 2debae833ce..2c283b1fefe 100644 --- a/server/sonar-web/src/main/less/pages/overview.less +++ b/server/sonar-web/src/main/less/pages/overview.less @@ -167,10 +167,10 @@ .overview-domain-leak { flex: 1; - background-color: #fffae7; + background-color: #fbf3d5; .line-chart-backdrop { - fill: #f1ecd1; + fill: #efe7b8; } } @@ -251,7 +251,7 @@ .overview-domain-leak-title { padding: 0 10px; border: 1px solid @barBorderColor; - background: #fffae7; + background: #fbf3d5; } } @@ -341,7 +341,7 @@ .overview-detailed-measure-leak { flex: 1; - background-color: #fffae7; + background-color: #fbf3d5; text-align: center; } @@ -438,7 +438,7 @@ } .line-chart-backdrop { - fill: #fffae7; + fill: #fbf3d5; } .line-chart-tick { @@ -568,7 +568,7 @@ } .overview-leak { - background-color: #fffae7; + background-color: #fbf3d5; } /* -- cgit v1.2.3 From a789f25232f010dfcbbed6f5133f156435b6199c Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Tue, 8 Dec 2015 14:59:13 +0100 Subject: SONAR-6900 Add IT to simulate a build breaker strategy --- .../test/java/it/qualityGate/QualityGateTest.java | 75 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/it/it-tests/src/test/java/it/qualityGate/QualityGateTest.java b/it/it-tests/src/test/java/it/qualityGate/QualityGateTest.java index 39006cc4c09..21f68c4cba9 100644 --- a/it/it-tests/src/test/java/it/qualityGate/QualityGateTest.java +++ b/it/it-tests/src/test/java/it/qualityGate/QualityGateTest.java @@ -8,7 +8,14 @@ package it.qualityGate; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; import it.Category1Suite; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.Properties; +import org.apache.commons.io.FileUtils; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.sonar.wsclient.project.NewProject; @@ -18,23 +25,37 @@ import org.sonar.wsclient.qualitygate.QualityGateClient; import org.sonar.wsclient.services.Measure; import org.sonar.wsclient.services.Resource; import org.sonar.wsclient.services.ResourceQuery; +import org.sonarqube.ws.MediaTypes; +import org.sonarqube.ws.WsCe; +import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse; +import org.sonarqube.ws.client.GetRequest; +import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.client.WsResponse; +import org.sonarqube.ws.client.qualitygate.ProjectStatusWsRequest; import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.newAdminWsClient; import static util.ItUtils.projectDir; public class QualityGateTest { private static final String PROJECT_KEY = "sample"; - private long provisionnedProjectId = -1L; + private long provisionedProjectId = -1L; @ClassRule public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + static WsClient wsClient; + + @BeforeClass + public static void startOrchestrator() { + wsClient = newAdminWsClient(orchestrator); + } @Before public void cleanUp() { orchestrator.resetData(); - provisionnedProjectId = Long.parseLong(orchestrator.getServer().adminWsClient().projectClient().create(NewProject.create().key(PROJECT_KEY).name("Sample")).id()); + provisionedProjectId = Long.parseLong(orchestrator.getServer().adminWsClient().projectClient().create(NewProject.create().key(PROJECT_KEY).name("Sample")).id()); } @Test @@ -121,7 +142,7 @@ public class QualityGateTest { qgClient().createCondition(NewCondition.create(error.id()).metricKey("ncloc").operator("GT").errorThreshold("10")); qgClient().setDefault(alert.id()); - qgClient().selectProject(error.id(), provisionnedProjectId); + qgClient().selectProject(error.id(), provisionedProjectId); try { SonarRunner build = SonarRunner.create(projectDir("qualitygate/xoo-sample")); @@ -159,6 +180,54 @@ public class QualityGateTest { } } + @Test + public void ad_hoc_build_break_strategy() throws IOException { + QualityGate simple = qgClient().create("SimpleWithLowThresholdForBuildBreakStrategy"); + qgClient().setDefault(simple.id()); + qgClient().createCondition(NewCondition.create(simple.id()).metricKey("ncloc").operator("GT").errorThreshold("7")); + + try { + File projectDir = projectDir("qualitygate/xoo-sample"); + SonarRunner build = SonarRunner.create(projectDir); + orchestrator.executeBuild(build); + + String taskId = getTaskIdInLocalReport(projectDir); + String analysisId = getAnalysisId(taskId); + + ProjectStatusWsResponse projectStatusWsResponse = wsClient.qualityGates().projectStatus(new ProjectStatusWsRequest().setAnalysisId(analysisId)); + ProjectStatusWsResponse.ProjectStatus projectStatus = projectStatusWsResponse.getProjectStatus(); + assertThat(projectStatus.getStatus()).isEqualTo(ProjectStatusWsResponse.Status.ERROR); + assertThat(projectStatus.getConditionsCount()).isEqualTo(1); + ProjectStatusWsResponse.Condition condition = projectStatus.getConditionsList().get(0); + assertThat(condition.getMetricKey()).isEqualTo("ncloc"); + assertThat(condition.getErrorThreshold()).isEqualTo("7"); + } finally { + qgClient().unsetDefault(); + qgClient().destroy(simple.id()); + } + } + + private String getAnalysisId(String taskId) throws IOException { + WsResponse activity = wsClient + .wsConnector() + .call(new GetRequest("api/ce/task") + .setParam("id", taskId) + .setMediaType(MediaTypes.PROTOBUF)); + WsCe.TaskResponse activityWsResponse = WsCe.TaskResponse.parseFrom(activity.contentStream()); + return activityWsResponse.getTask().getAnalysisId(); + } + + private String getTaskIdInLocalReport(File projectDirectory) throws IOException { + File metadata = new File(projectDirectory, ".sonar/report-task.txt"); + assertThat(metadata).exists().isFile(); + // verify properties + Properties props = new Properties(); + props.load(new StringReader(FileUtils.readFileToString(metadata, StandardCharsets.UTF_8))); + assertThat(props.getProperty("ceTaskId")).isNotEmpty(); + + return props.getProperty("ceTaskId"); + } + private Measure fetchGateStatus() { return fetchResourceWithGateStatus().getMeasure("alert_status"); } -- cgit v1.2.3 From 02dbaef58e3ef830faec084461bb8295a11a6769 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Wed, 9 Dec 2015 11:51:24 +0100 Subject: SONAR-6887 Improve message when missing revision or date on blame --- .../java/org/sonar/batch/scm/DefaultBlameOutput.java | 16 +++++++++------- .../java/org/sonar/batch/scm/DefaultBlameOutputTest.java | 14 ++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java b/sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java index 24e1783e97b..00a4029330f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java @@ -70,10 +70,10 @@ class DefaultBlameOutput implements BlameOutput { public synchronized void blameResult(InputFile file, List lines) { Preconditions.checkNotNull(file); Preconditions.checkNotNull(lines); - Preconditions.checkArgument(allFilesToBlame.contains(file), "It was not expected to blame file " + file.relativePath()); + Preconditions.checkArgument(allFilesToBlame.contains(file), "It was not expected to blame file %s", file.relativePath()); if (lines.size() != file.lines()) { - LOG.debug("Ignoring blame result since provider returned " + lines.size() + " blame lines but file " + file.relativePath() + " has " + file.lines() + " lines"); + LOG.debug("Ignoring blame result since provider returned {} blame lines but file {} has {} lines", lines.size(), file.relativePath(), file.lines()); return; } @@ -82,8 +82,9 @@ class DefaultBlameOutput implements BlameOutput { scmBuilder.setComponentRef(batchComponent.batchId()); Map changesetsIdByRevision = new HashMap<>(); + int lineId = 1; for (BlameLine line : lines) { - validateLine(line); + validateLine(line, lineId, file); Integer changesetId = changesetsIdByRevision.get(line.revision()); if (changesetId == null) { addChangeset(scmBuilder, line); @@ -91,6 +92,7 @@ class DefaultBlameOutput implements BlameOutput { changesetsIdByRevision.put(line.revision(), changesetId); } scmBuilder.addChangesetIndexByLine(changesetId); + lineId++; } writer.writeComponentChangesets(scmBuilder.build()); allFilesToBlame.remove(file); @@ -98,9 +100,9 @@ class DefaultBlameOutput implements BlameOutput { progressReport.message(count + "/" + total + " files analyzed"); } - private static void validateLine(BlameLine line) { - Preconditions.checkNotNull(line.revision(), "Blame revision cannot be null"); - Preconditions.checkNotNull(line.date(), "Blame date cannot be null"); + private static void validateLine(BlameLine line, int lineId, InputFile file) { + Preconditions.checkArgument(StringUtils.isNotBlank(line.revision()), "Blame revision is blank for file %s at line %s", file.relativePath(), lineId); + Preconditions.checkArgument(line.date() != null, "Blame date is null for file %s at line %s", file.relativePath(), lineId); } private static void addChangeset(Builder scmBuilder, BlameLine line) { @@ -131,7 +133,7 @@ class DefaultBlameOutput implements BlameOutput { private static String removeNonAsciiCharacters(String inputString) { return NON_ASCII_CHARS.matcher(inputString).replaceAll("_"); } - + public void finish() { progressReport.stop(count + "/" + total + " files analyzed"); if (!allFilesToBlame.isEmpty()) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/scm/DefaultBlameOutputTest.java b/sonar-batch/src/test/java/org/sonar/batch/scm/DefaultBlameOutputTest.java index e7f00149111..3060951b4e9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scm/DefaultBlameOutputTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scm/DefaultBlameOutputTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.scm; +import java.util.Arrays; +import java.util.Date; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -30,11 +32,7 @@ import org.sonar.api.batch.scm.BlameLine; import org.sonar.batch.index.BatchComponent; import org.sonar.batch.index.BatchComponentCache; -import java.util.Arrays; -import java.util.Date; - import static org.mockito.Matchers.any; - import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -75,8 +73,8 @@ public class DefaultBlameOutputTest { public void shouldFailIfNullDate() { InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1); - thrown.expect(NullPointerException.class); - thrown.expectMessage("Blame date cannot be null"); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Blame date is null for file src/main/java/Foo.java at line 1"); new DefaultBlameOutput(null, componentCache, Arrays.asList(file)) .blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); @@ -86,8 +84,8 @@ public class DefaultBlameOutputTest { public void shouldFailIfNullRevision() { InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1); - thrown.expect(NullPointerException.class); - thrown.expectMessage("Blame revision cannot be null"); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Blame revision is blank for file src/main/java/Foo.java at line 1"); new DefaultBlameOutput(null, componentCache, Arrays.asList(file)) .blameResult(file, Arrays.asList(new BlameLine().date(new Date()).author("guy"))); -- cgit v1.2.3 From a749013e0af281ac0eb19f35fe9f282f3bc80121 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 9 Dec 2015 17:25:52 +0100 Subject: hide number of failing tasks on then project level page --- it/it-tests/src/test/java/it/Category1Suite.java | 2 + .../projectAdministration/BackgroundTasksTest.java | 55 ++++++++++++++++ ..._and_filter_elements_on_project_level_page.html | 75 ++++++++++++++++++++++ .../src/main/js/apps/background-tasks/main.js | 23 ++++--- .../src/main/js/apps/background-tasks/stats.js | 5 ++ 5 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java create mode 100644 it/it-tests/src/test/resources/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html diff --git a/it/it-tests/src/test/java/it/Category1Suite.java b/it/it-tests/src/test/java/it/Category1Suite.java index 97489650fcc..2bcf718ffa9 100644 --- a/it/it-tests/src/test/java/it/Category1Suite.java +++ b/it/it-tests/src/test/java/it/Category1Suite.java @@ -52,6 +52,7 @@ import it.measureHistory.HistoryUiTest; import it.measureHistory.SincePreviousVersionHistoryTest; import it.measureHistory.SinceXDaysHistoryTest; import it.measureHistory.TimeMachineTest; +import it.projectAdministration.BackgroundTasksTest; import it.projectAdministration.BulkDeletionTest; import it.projectAdministration.ProjectAdministrationTest; import it.projectOverview.ProjectOverviewTest; @@ -76,6 +77,7 @@ import static util.ItUtils.xooPlugin; // project administration BulkDeletionTest.class, ProjectAdministrationTest.class, + BackgroundTasksTest.class, // project pages ProjectOverviewTest.class, // settings diff --git a/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java b/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java new file mode 100644 index 00000000000..93b92400d90 --- /dev/null +++ b/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +package it.projectAdministration; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarRunner; +import com.sonar.orchestrator.selenium.Selenese; +import it.Category1Suite; +import org.junit.ClassRule; +import org.junit.Test; +import util.selenium.SeleneseTest; + +import static util.ItUtils.projectDir; + +public class BackgroundTasksTest { + + @ClassRule + public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + + @Test + public void should_not_display_failing_and_search_and_filter_elements_on_project_level_page() throws Exception { + executeBuild("test-project", "Test Project"); + executeBuild("test-project-2", "Another Test Project"); + + Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("should_not_display_failing_and_search_and_filter_elements_on_project_level_page", + "/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html" + ).build(); + new SeleneseTest(selenese).runOn(orchestrator); + } + + private void executeBuild(String projectKey, String projectName) { + orchestrator.executeBuild( + SonarRunner.create(projectDir("shared/xoo-sample")) + .setProjectKey(projectKey) + .setProjectName(projectName) + ); + } +} diff --git a/it/it-tests/src/test/resources/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html b/it/it-tests/src/test/resources/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html new file mode 100644 index 00000000000..06f59df2058 --- /dev/null +++ b/it/it-tests/src/test/resources/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html @@ -0,0 +1,75 @@ + + + + + + + should_not_display_failing_and_search_and_filter_elements_on_project_level_page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
should_not_display_failing_and_search_and_filter_elements_on_project_level_page
open/sonar/sessions/logout
open/sonar/sessions/login
typeloginadmin
typepasswordadmin
clickAndWaitcommit
open/sonar/project/background_tasks?id=test-project
waitForElementPresentcss=.background-tasks .badge
assertNotTextcss=.background-tasks*Another Test Project*
assertElementNotPresentcss=.search-box
assertNotTextcss=#content*still failing*
assertElementNotPresentcss=.icon-filter
+ + diff --git a/server/sonar-web/src/main/js/apps/background-tasks/main.js b/server/sonar-web/src/main/js/apps/background-tasks/main.js index 02fa64391e1..521d3e36556 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/main.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/main.js @@ -171,8 +171,7 @@ export default React.createClass({ statusFilter: STATUSES.FAILED, currentsFilter: CURRENTS.ONLY_CURRENTS, activityPage: 1 - }, - this.requestActivity); + }, this.requestActivity); }, onTaskCanceled(task) { @@ -192,23 +191,31 @@ export default React.createClass({
- + - - - +
); } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/stats.js b/server/sonar-web/src/main/js/apps/background-tasks/stats.js index 308d7e4d8a8..2383f8d76fa 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/stats.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/stats.js @@ -61,6 +61,11 @@ export default React.createClass({ if (this.props.failuresCount == null) { return null; } + + if (this.props.options.component) { + return null; + } + if (this.props.failuresCount > 0) { return ( -- cgit v1.2.3