From 4ecb6fc3ec08ee37a1bb5c19d8ca44e2b832b5a7 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Mon, 27 Jun 2016 16:08:44 +0200 Subject: refactor quality profiles page (#1056) --- .../apps/quality-profiles/__tests__/utils-test.js | 74 +++++++ .../main/js/apps/quality-profiles/actions-view.js | 114 ---------- .../src/main/js/apps/quality-profiles/app.js | 97 ++++----- .../quality-profiles/change-profile-parent-view.js | 80 ------- .../apps/quality-profiles/changelog/Changelog.js | 81 +++++++ .../changelog/ChangelogContainer.js | 128 +++++++++++ .../quality-profiles/changelog/ChangelogEmpty.js | 31 +++ .../quality-profiles/changelog/ChangelogSearch.js | 62 ++++++ .../apps/quality-profiles/changelog/ChangesList.js | 46 ++++ .../quality-profiles/changelog/ParameterChange.js | 53 +++++ .../quality-profiles/changelog/SeverityChange.js | 38 ++++ .../changelog/__tests__/Changelog-test.js | 84 ++++++++ .../changelog/__tests__/ChangelogSearch-test.js | 68 ++++++ .../changelog/__tests__/ChangesList-test.js | 54 +++++ .../changelog/__tests__/ParameterChange-test.js | 31 +++ .../changelog/__tests__/SeverityChange-test.js | 34 +++ .../compare/ComparisonContainer.js | 122 +++++++++++ .../quality-profiles/compare/ComparisonEmpty.js | 31 +++ .../quality-profiles/compare/ComparisonForm.js | 56 +++++ .../quality-profiles/compare/ComparisonResults.js | 176 +++++++++++++++ .../compare/__tests__/ComparisonForm-test.js | 49 +++++ .../compare/__tests__/ComparisonResults-test.js | 98 +++++++++ .../js/apps/quality-profiles/components/App.js | 97 +++++++++ .../components/ProfileContainer.js | 72 +++++++ .../quality-profiles/components/ProfileDate.js | 49 +++++ .../quality-profiles/components/ProfileLink.js | 37 ++++ .../quality-profiles/components/ProfileNotFound.js | 40 ++++ .../components/__tests__/ProfileContainer-test.js | 89 ++++++++ .../main/js/apps/quality-profiles/controller.js | 128 ----------- .../js/apps/quality-profiles/copy-profile-view.js | 65 ------ .../apps/quality-profiles/create-profile-view.js | 102 --------- .../apps/quality-profiles/delete-profile-view.js | 58 ----- .../quality-profiles/details/ProfileDetails.js | 52 +++++ .../quality-profiles/details/ProfileEvolution.js | 61 ++++++ .../quality-profiles/details/ProfileExporters.js | 64 ++++++ .../apps/quality-profiles/details/ProfileHeader.js | 183 ++++++++++++++++ .../quality-profiles/details/ProfileInheritance.js | 126 +++++++++++ .../details/ProfileInheritanceBox.js | 77 +++++++ .../quality-profiles/details/ProfileProjects.js | 148 +++++++++++++ .../apps/quality-profiles/details/ProfileRules.js | 237 +++++++++++++++++++++ .../quality-profiles/details/ProfileRulesRow.js | 54 +++++ .../apps/quality-profiles/details/ProgressBar.js | 54 +++++ .../js/apps/quality-profiles/home/Evolution.js | 40 ++++ .../quality-profiles/home/EvolutionDeprecated.js | 82 +++++++ .../apps/quality-profiles/home/EvolutionRules.js | 123 +++++++++++ .../quality-profiles/home/EvolutionStagnant.js | 71 ++++++ .../js/apps/quality-profiles/home/HomeContainer.js | 41 ++++ .../js/apps/quality-profiles/home/PageHeader.js | 114 ++++++++++ .../js/apps/quality-profiles/home/ProfilesList.js | 134 ++++++++++++ .../quality-profiles/home/ProfilesListHeader.js | 96 +++++++++ .../apps/quality-profiles/home/ProfilesListRow.js | 132 ++++++++++++ .../main/js/apps/quality-profiles/intro-view.js | 26 --- .../src/main/js/apps/quality-profiles/layout.js | 47 ---- .../quality-profiles/profile-changelog-view.js | 55 ----- .../quality-profiles/profile-comparison-view.js | 65 ------ .../apps/quality-profiles/profile-details-view.js | 181 ---------------- .../apps/quality-profiles/profile-header-view.js | 91 -------- .../main/js/apps/quality-profiles/profile-view.js | 60 ------ .../src/main/js/apps/quality-profiles/profile.js | 136 ------------ .../apps/quality-profiles/profiles-empty-view.js | 27 --- .../main/js/apps/quality-profiles/profiles-view.js | 84 -------- .../src/main/js/apps/quality-profiles/profiles.js | 43 ---- .../src/main/js/apps/quality-profiles/propTypes.js | 45 ++++ .../apps/quality-profiles/rename-profile-view.js | 56 ----- .../restore-built-in-profiles-view.js | 79 ------- .../apps/quality-profiles/restore-profile-view.js | 64 ------ .../src/main/js/apps/quality-profiles/router.js | 55 ----- .../src/main/js/apps/quality-profiles/styles.css | 149 +++++++++++++ .../templates/quality-profile-changelog.hbs | 66 ------ .../templates/quality-profile-comparison.hbs | 89 -------- .../templates/quality-profiles-actions.hbs | 40 ---- .../templates/quality-profiles-change-projects.hbs | 12 ++ .../templates/quality-profiles-create-profile.hbs | 6 +- .../templates/quality-profiles-delete-profile.hbs | 4 +- .../templates/quality-profiles-empty.hbs | 1 - .../templates/quality-profiles-intro.hbs | 4 - .../templates/quality-profiles-layout.hbs | 11 - .../templates/quality-profiles-profile-details.hbs | 134 ------------ .../templates/quality-profiles-profile-header.hbs | 19 -- .../templates/quality-profiles-profile.hbs | 21 -- .../quality-profiles-profiles-language.hbs | 1 - .../templates/quality-profiles-profiles.hbs | 1 - ...-profiles-restore-built-in-profiles-success.hbs | 2 +- .../quality-profiles-restore-built-in-profiles.hbs | 12 +- .../src/main/js/apps/quality-profiles/utils.js | 61 ++++++ .../quality-profiles/views/ChangeParentView.js | 63 ++++++ .../quality-profiles/views/ChangeProjectsView.js | 70 ++++++ .../apps/quality-profiles/views/CopyProfileView.js | 52 +++++ .../quality-profiles/views/CreateProfileView.js | 95 +++++++++ .../quality-profiles/views/DeleteProfileView.js | 55 +++++ .../quality-profiles/views/RenameProfileView.js | 51 +++++ .../views/RestoreBuiltInProfilesView.js | 56 +++++ .../quality-profiles/views/RestoreProfileView.js | 55 +++++ 93 files changed, 4398 insertions(+), 2079 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/App.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/controller.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/copy-profile-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/create-profile-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/delete-profile-view.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileEvolution.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/details/ProgressBar.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/intro-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/layout.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile-changelog-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile-comparison-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile-header-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profile.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profiles-empty-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profiles-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/profiles.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/propTypes.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/rename-profile-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/restore-built-in-profiles-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/restore-profile-view.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/router.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/styles.css delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profile-changelog.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profile-comparison.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-actions.hbs create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-change-projects.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-empty.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-intro.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-layout.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-profile-details.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-profile-header.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-profile.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-profiles-language.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-profiles.hbs create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/utils.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js (limited to 'server/sonar-web/src/main/js/apps') diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js new file mode 100644 index 00000000000..97811993e43 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { sortProfiles } from '../utils'; + +function createProfile (key, parentKey) { + return { name: key, key, parentKey }; +} + +function checkOrder (list, order) { + const listKeys = list.map(item => item.key); + expect(listKeys).to.deep.equal(order); +} + +describe('Quality Profiles :: Utils', () => { + describe('#sortProfiles', () => { + it('should sort when no parents', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2'); + const profile3 = createProfile('profile3'); + checkOrder( + sortProfiles([profile1, profile2, profile3]), + ['profile1', 'profile2', 'profile3'] + ); + }); + + it('should sort by name', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2'); + const profile3 = createProfile('profile3'); + checkOrder( + sortProfiles([profile3, profile1, profile2]), + ['profile1', 'profile2', 'profile3'] + ); + }); + + it('should sort with children', () => { + const child1 = createProfile('child1', 'parent'); + const child2 = createProfile('child2', 'parent'); + const parent = createProfile('parent'); + checkOrder( + sortProfiles([child1, child2, parent]), + ['parent', 'child1', 'child2'] + ); + }); + + it('should sort single branch', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2', 'profile3'); + const profile3 = createProfile('profile3', 'profile1'); + checkOrder( + sortProfiles([profile3, profile2, profile1]), + ['profile1', 'profile3', 'profile2'] + ); + }); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js deleted file mode 100644 index ae5c603d3cb..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/actions-view.js +++ /dev/null @@ -1,114 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import $ from 'jquery'; -import _ from 'underscore'; -import Marionette from 'backbone.marionette'; -import CreateProfileView from './create-profile-view'; -import RestoreProfileView from './restore-profile-view'; -import RestoreBuiltInProfilesView from './restore-built-in-profiles-view'; -import Template from './templates/quality-profiles-actions.hbs'; - -export default Marionette.ItemView.extend({ - template: Template, - - events: { - 'click #quality-profiles-create': 'onCreateClick', - 'click #quality-profiles-restore': 'onRestoreClick', - 'click #quality-profiles-restore-built-in': 'onRestoreBuiltInClick', - - 'click .js-filter-by-language': 'onLanguageClick' - }, - - onCreateClick (e) { - e.preventDefault(); - this.create(); - }, - - onRestoreClick (e) { - e.preventDefault(); - this.restore(); - }, - - onRestoreBuiltInClick (e) { - e.preventDefault(); - this.restoreBuiltIn(); - }, - - onLanguageClick (e) { - e.preventDefault(); - const language = $(e.currentTarget).data('language'); - this.filterByLanguage(language); - }, - - create () { - const that = this; - this.requestImporters().done(function () { - new CreateProfileView({ - collection: that.collection, - languages: that.languages, - importers: that.importers - }).render(); - }); - }, - - restore () { - new RestoreProfileView({ - collection: this.collection - }).render(); - }, - - restoreBuiltIn () { - new RestoreBuiltInProfilesView({ - collection: this.collection, - languages: this.languages - }).render(); - }, - - requestLanguages () { - const that = this; - const url = window.baseUrl + '/api/languages/list'; - return $.get(url).done(function (r) { - that.languages = r.languages; - }); - }, - - requestImporters () { - const that = this; - const url = window.baseUrl + '/api/qualityprofiles/importers'; - return $.get(url).done(function (r) { - that.importers = r.importers; - }); - }, - - filterByLanguage (language) { - this.selectedLanguage = _.findWhere(this.languages, { key: language }); - this.render(); - this.collection.trigger('filter', language); - }, - - serializeData () { - return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { - canWrite: this.options.canWrite, - languages: this.languages, - selectedLanguage: this.selectedLanguage - }); - } -}); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/app.js b/server/sonar-web/src/main/js/apps/quality-profiles/app.js index 74a8511776c..cb998c8edfc 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/app.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/app.js @@ -17,66 +17,43 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import $ from 'jquery'; -import Backbone from 'backbone'; -import Marionette from 'backbone.marionette'; -import Router from './router'; -import Controller from './controller'; -import Layout from './layout'; -import Profiles from './profiles'; -import ActionsView from './actions-view'; -import ProfilesView from './profiles-view'; - -const App = new Marionette.Application(); -const requestUser = $.get(window.baseUrl + '/api/users/current').done(function (r) { - App.canWrite = r.permissions.global.indexOf('profileadmin') !== -1; -}); -const requestExporters = $.get(window.baseUrl + '/api/qualityprofiles/exporters').done(function (r) { - App.exporters = r.exporters; -}); -const init = function () { - const options = window.sonarqube; - - // Layout - this.layout = new Layout({ el: options.el }); - this.layout.render(); - $('#footer').addClass('search-navigator-footer'); - - // Profiles List - this.profiles = new Profiles(); - - // Controller - this.controller = new Controller({ app: this }); - - // Actions View - this.actionsView = new ActionsView({ - collection: this.profiles, - canWrite: this.canWrite - }); - this.actionsView.requestLanguages().done(function () { - App.layout.actionsRegion.show(App.actionsView); +import React from 'react'; +import { render } from 'react-dom'; +import { + Router, + Route, + IndexRoute, + Redirect, + useRouterHistory +} from 'react-router'; +import { createHistory } from 'history'; +import App from './components/App'; +import ProfileContainer from './components/ProfileContainer'; +import HomeContainer from './home/HomeContainer'; +import ProfileDetails from './details/ProfileDetails'; +import ChangelogContainer from './changelog/ChangelogContainer'; +import ComparisonContainer from './compare/ComparisonContainer'; + +window.sonarqube.appStarted.then(options => { + const el = document.querySelector(options.el); + + const history = useRouterHistory(createHistory)({ + basename: window.baseUrl + '/profiles' }); - // Profiles View - this.profilesView = new ProfilesView({ - collection: this.profiles, - canWrite: this.canWrite - }); - this.layout.resultsRegion.show(this.profilesView); - - // Router - this.router = new Router({ app: this }); - Backbone.history.start({ - pushState: true, - root: options.urlRoot - }); -}; - -App.on('start', function () { - $.when(requestUser, requestExporters).done(function () { - init.call(App); - }); + render(( + + + + + + + + + + + + + + ), el); }); - -window.sonarqube.appStarted.then(options => App.start(options)); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js deleted file mode 100644 index e86554b516e..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/change-profile-parent-view.js +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import $ from 'jquery'; -import _ from 'underscore'; -import Marionette from 'backbone.marionette'; -import ModalFormView from '../../components/common/modal-form'; -import Template from './templates/quality-profiles-change-profile-parent.hbs'; - -export default ModalFormView.extend({ - template: Template, - - onRender () { - ModalFormView.prototype.onRender.apply(this, arguments); - this.$('select').select2({ - width: '250px', - minimumResultsForSearch: 50 - }); - }, - - onFormSubmit () { - ModalFormView.prototype.onFormSubmit.apply(this, arguments); - this.disableForm(); - this.sendRequest(); - }, - - sendRequest () { - const that = this; - const url = window.baseUrl + '/api/qualityprofiles/change_parent'; - const parent = this.$('#change-profile-parent').val(); - const options = { - profileKey: this.model.get('key'), - parentKey: parent - }; - return $.ajax({ - url, - type: 'POST', - data: options, - statusCode: { - // do not show global error - 400: null - } - }).done(function () { - that.model.collection.fetch(); - that.model.trigger('select', that.model); - that.destroy(); - }).fail(function (jqXHR) { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - that.enableForm(); - }); - }, - - serializeData () { - const that = this; - const profilesData = this.model.collection.toJSON(); - const profiles = _.filter(profilesData, function (profile) { - return profile.language === that.model.get('language') && profile.key !== that.model.id; - }); - return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { - profiles - }); - } -}); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js new file mode 100644 index 00000000000..b7c8184d488 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js @@ -0,0 +1,81 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import moment from 'moment'; +import ChangesList from './ChangesList'; +import { translate } from '../../../helpers/l10n'; +import { getRulesUrl } from '../../../helpers/urls'; + +export default class Changelog extends React.Component { + static propTypes = { + events: React.PropTypes.array.isRequired + }; + + render () { + const rows = this.props.events.map((event, index) => ( + + + {moment(event.date).format('LLL')} + + + + {event.authorName ? ( + {event.authorName} + ) : ( + System + )} + + + + {translate('quality_profiles.changelog', event.action)} + + + + + {event.ruleName} + + + + + + + + )); + + return ( + + + + + + + + + + + {rows} +
+ {translate('date')} + {' '} + + {translate('user')}{translate('action')}{translate('rule')}{translate('parameters')}
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js new file mode 100644 index 00000000000..247b3a6f402 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js @@ -0,0 +1,128 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import Changelog from './Changelog'; +import ChangelogSearch from './ChangelogSearch'; +import ChangelogEmpty from './ChangelogEmpty'; +import { getProfileChangelog } from '../../../api/quality-profiles'; +import { ProfileType } from '../propTypes'; + +export default class ChangelogContainer extends React.Component { + static propTypes = { + location: React.PropTypes.object.isRequired, + profile: ProfileType + }; + + static contextTypes = { + router: React.PropTypes.object + }; + + state = { + loading: true + }; + + componentWillMount () { + this.handleFromDateChange = this.handleFromDateChange.bind(this); + this.handleToDateChange = this.handleToDateChange.bind(this); + this.handleReset = this.handleReset.bind(this); + } + + componentDidMount () { + this.mounted = true; + this.loadChangelog(); + } + + componentDidUpdate (prevProps) { + if (prevProps.location !== this.props.location) { + this.loadChangelog(); + } + } + + componentWillUnmount () { + this.mounted = false; + } + + loadChangelog () { + this.setState({ loading: true }); + const { query } = this.props.location; + const data = { profileKey: this.props.profile.key }; + if (query.since) { + data.since = query.since; + } + if (query.to) { + data.to = query.to; + } + + getProfileChangelog(data).then(r => { + if (this.mounted) { + this.setState({ + events: r.events, + total: r.total, + page: r.p, + loading: false + }); + } + }); + } + + handleFromDateChange (fromDate) { + const query = { ...this.props.location.query, since: fromDate }; + this.context.router.push({ pathname: '/changelog', query }); + } + + handleToDateChange (toDate) { + const query = { ...this.props.location.query, to: toDate }; + this.context.router.push({ pathname: '/changelog', query }); + } + + handleReset () { + const query = { key: this.props.profile.key }; + this.context.router.push({ pathname: '/changelog', query }); + } + + render () { + const { query } = this.props.location; + + return ( +
+
+ + + {this.state.loading && ( + + )} +
+ + {this.state.events != null && this.state.events.length === 0 && ( + + )} + + {this.state.events != null && this.state.events.length > 0 && ( + + )} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js new file mode 100644 index 00000000000..797e551454b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { translate } from '../../../helpers/l10n'; + +export default class ChangelogEmpty extends React.Component { + render () { + return ( +
+ {translate('no_results')} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js new file mode 100644 index 00000000000..1093f7fe3ac --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js @@ -0,0 +1,62 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import DateInput from '../../../components/controls/DateInput'; +import { translate } from '../../../helpers/l10n'; + +export default class ChangelogSearch extends React.Component { + static propTypes = { + fromDate: React.PropTypes.string, + toDate: React.PropTypes.string, + onFromDateChange: React.PropTypes.func.isRequired, + onToDateChange: React.PropTypes.func.isRequired, + onReset: React.PropTypes.func.isRequired + }; + + handleResetClick (e) { + e.preventDefault(); + e.target.blur(); + this.props.onReset(); + } + + render () { + return ( +
+ + {' — '} + + +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js new file mode 100644 index 00000000000..5a413b0a856 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import SeverityChange from './SeverityChange'; +import ParameterChange from './ParameterChange'; + +export default class ChangesList extends React.Component { + static propTypes = { + changes: React.PropTypes.object.isRequired + }; + + render () { + const { changes } = this.props; + + return ( +
    + {Object.keys(changes).map(key => ( +
  • + {key === 'severity' ? ( + + ) : ( + + )} +
  • + ))} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js new file mode 100644 index 00000000000..82e685af470 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { translateWithParameters } from '../../../helpers/l10n'; + +export default class ParameterChange extends React.Component { + static propTypes = { + name: React.PropTypes.string.isRequired, + value: React.PropTypes.any + }; + + render () { + const { name, value } = this.props; + + if (value == null) { + return ( +
+ {translateWithParameters( + 'quality_profiles.changelog.parameter_reset_to_default_value', + name + )} +
+ ); + } + + return ( +
+ {translateWithParameters( + 'quality_profiles.parameter_set_to', + name, + value + )} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js new file mode 100644 index 00000000000..2b854311455 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import SeverityHelper from '../../../components/shared/severity-helper'; +import { translate } from '../../../helpers/l10n'; + +export default class SeverityChange extends React.Component { + static propTypes = { + severity: React.PropTypes.string.isRequired + }; + + render () { + return ( +
+ {translate('quality_profiles.severity_set_to')} + {' '} + +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js new file mode 100644 index 00000000000..9a36c64207f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js @@ -0,0 +1,84 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { shallow } from 'enzyme'; +import React from 'react'; +import Changelog from '../Changelog'; +import ChangesList from '../ChangesList'; + +function createEvent (overrides) { + return { + date: '2016-01-01', + authorName: 'John', + action: 'ACTIVATED', + ruleKey: 'squid1234', + ruleName: 'Do not do this', + params: {}, + ...overrides + }; +} + +describe('Quality Profiles :: Changelog', () => { + it('should render events', () => { + const events = [createEvent(), createEvent()]; + const changelog = shallow(); + expect(changelog.find('tbody').find('tr')).to.have.length(2); + }); + + it('should render event date', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).to.include('2016'); + }); + + it('should render author', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).to.include('John'); + }); + + it('should render system author', () => { + const events = [createEvent({ authorName: undefined })]; + const changelog = shallow(); + expect(changelog.text()).to.include('System'); + }); + + it('should render action', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).to.include('ACTIVATED'); + }); + + it('should render rule', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).to.include('Do not do this'); + expect(changelog.find('a').prop('href')).to.include('rule_key=squid1234'); + }); + + it('should render ChangesList', () => { + const params = { severity: 'BLOCKER' }; + const events = [createEvent({ params })]; + const changelog = shallow(); + const changesList = changelog.find(ChangesList); + expect(changesList).to.have.length(1); + expect(changesList.prop('changes')).to.equal(params); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js new file mode 100644 index 00000000000..302273cedf4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js @@ -0,0 +1,68 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import React from 'react'; +import ChangelogSearch from '../ChangelogSearch'; +import DateInput from '../../../../components/controls/DateInput'; + +function click (element) { + return element.simulate('click', { + target: { blur () {} }, + preventDefault () {} + }); +} + +describe('Quality Profiles :: ChangelogSearch', () => { + it('should render DateInput', () => { + const onFromDateChange = sinon.spy(); + const onToDateChange = sinon.spy(); + const output = shallow( + + ); + const dateInputs = output.find(DateInput); + expect(dateInputs).to.have.length(2); + expect(dateInputs.at(0).prop('value')).to.equal('2016-01-01'); + expect(dateInputs.at(0).prop('onChange')).to.equal(onFromDateChange); + expect(dateInputs.at(1).prop('value')).to.equal('2016-05-05'); + expect(dateInputs.at(1).prop('onChange')).to.equal(onToDateChange); + }); + + it('should reset', () => { + const onReset = sinon.spy(); + const output = shallow( + + ); + expect(onReset.called).to.equal(false); + click(output.find('button')); + expect(onReset.called).to.equal(true); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js new file mode 100644 index 00000000000..86e194b22aa --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { shallow } from 'enzyme'; +import React from 'react'; +import ChangesList from '../ChangesList'; +import SeverityChange from '../SeverityChange'; +import ParameterChange from '../ParameterChange'; + +describe('Quality Profiles :: ChangesList', () => { + it('should render changes', () => { + const changes = { severity: 'BLOCKER', foo: 'bar' }; + const output = shallow( + + ); + expect(output.find('li')).to.have.length(2); + }); + + it('should render severity change', () => { + const changes = { severity: 'BLOCKER' }; + const output = shallow( + + ).find(SeverityChange); + expect(output).to.have.length(1); + expect(output.prop('severity')).to.equal('BLOCKER'); + }); + + it('should render parameter change', () => { + const changes = { foo: 'bar' }; + const output = shallow( + + ).find(ParameterChange); + expect(output).to.have.length(1); + expect(output.prop('name')).to.equal('foo'); + expect(output.prop('value')).to.equal('bar'); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js new file mode 100644 index 00000000000..1845b09c506 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { shallow } from 'enzyme'; +import React from 'react'; +import ParameterChange from '../ParameterChange'; + +describe('Quality Profiles :: ParameterChange', () => { + it('should render different messages', () => { + const first = shallow(); + const second = shallow(); + expect(first.text()).to.not.be.equal(second.text()); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js new file mode 100644 index 00000000000..3a7fcb37b29 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { expect } from 'chai'; +import { shallow } from 'enzyme'; +import React from 'react'; +import SeverityChange from '../SeverityChange'; +import SeverityHelper from '../../../../components/shared/severity-helper'; + +describe('Quality Profiles :: SeverityChange', () => { + it('should render SeverityHelper', () => { + const output = shallow( + + ).find(SeverityHelper); + expect(output).to.have.length(1); + expect(output.prop('severity')).to.equal('BLOCKER'); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js new file mode 100644 index 00000000000..03d5d145212 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js @@ -0,0 +1,122 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import ComparisonForm from './ComparisonForm'; +import ComparisonResults from './ComparisonResults'; +import { ProfileType, ProfilesListType } from '../propTypes'; +import { compareProfiles } from '../../../api/quality-profiles'; + +export default class ComparisonContainer extends React.Component { + static propTypes = { + profile: ProfileType, + profiles: ProfilesListType + }; + + static contextTypes = { + router: React.PropTypes.object + }; + + state = { + loading: false + }; + + componentWillMount () { + this.handleCompare = this.handleCompare.bind(this); + } + + componentDidMount () { + this.mounted = true; + this.loadResults(); + } + + componentDidUpdate (prevProps) { + if (prevProps.profile !== this.props.profile || + prevProps.location !== this.props.location) { + this.loadResults(); + } + } + + componentWillUnmount () { + this.mounted = false; + } + + loadResults () { + const { withKey } = this.props.location.query; + if (!withKey) { + this.setState({ left: null, loading: false }); + return; + } + + this.setState({ loading: true }); + compareProfiles(this.props.profile.key, withKey).then(r => { + if (this.mounted) { + this.setState({ + left: r.left, + right: r.right, + inLeft: r.inLeft, + inRight: r.inRight, + modified: r.modified, + loading: false + }); + } + }); + } + + handleCompare (withKey) { + this.context.router.push({ + pathname: '/compare', + query: { + key: this.props.profile.key, + withKey + } + }); + } + + render () { + const { profile, profiles, location } = this.props; + const { withKey } = location.query; + const { left, right, inLeft, inRight, modified } = this.state; + + return ( +
+
+ + + {this.state.loading && ( + + )} +
+ + {left != null && ( + + )} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js new file mode 100644 index 00000000000..d3e49aedf26 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { translate } from '../../../helpers/l10n'; + +export default class ComparisonEmpty extends React.Component { + render () { + return ( +
+ {translate('quality_profile.empty_comparison')} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js new file mode 100644 index 00000000000..149a8092066 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import Select from 'react-select'; +import { ProfileType, ProfilesListType } from '../propTypes'; +import { translate } from '../../../helpers/l10n'; + +export default class ComparisonForm extends React.Component { + static propTypes = { + profile: ProfileType.isRequired, + profiles: ProfilesListType.isRequired, + onCompare: React.PropTypes.func.isRequired + }; + + handleChange (option) { + this.props.onCompare(option.value); + } + + render () { + const { profile, profiles, withKey } = this.props; + const options = profiles + .filter(p => p.language === profile.language && p !== profile) + .map(p => ({ value: p.key, label: p.name })); + + return ( +
+ + - {{t 'to'}} - - - - -{{#notEmpty events}} - - - - - - - - - - - - {{#each events}} - - - - - - - - {{/each}} - -
{{t 'date'}}{{t 'user'}}{{t 'action'}}{{t 'rule'}}{{t 'parameters'}}
{{dt date}}{{default authorName 'System'}}{{t 'quality_profiles.changelog' action}}{{ruleName}} -
    - {{#each params}} -
  • - {{#eq @key 'severity'}} - {{severityChangelog this}} - {{else}} - {{parameterChangelog @key this}} - {{/eq}} -
  • - {{/each}} -
-
- - -

- {{#unlessLength events totalEvents}} - {{t 'show_more'}} - {{/unlessLength}} - {{t 'hide'}} -

- -{{else}} - {{#notNull totalEvents}} -
- {{t 'quality_profiles.changelog.empty'}} - {{t 'hide'}} -
- {{/notNull}} -{{/notEmpty}} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profile-comparison.hbs b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profile-comparison.hbs deleted file mode 100644 index e26259b6bad..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profile-comparison.hbs +++ /dev/null @@ -1,89 +0,0 @@ - - -{{#notEmpty profiles}} -
- - - -
-{{else}} -
{{t 'quality_profiles.no_profiles_for_comparison'}}
-{{/notEmpty}} - -{{#notNull comparison}} - - {{#notEmpty comparison.inLeft}} - - - - - {{#each comparison.inLeft}} - - - - - {{/each}} - {{/notEmpty}} - - {{#notEmpty comparison.inRight}} - - - - - {{#each comparison.inRight}} - - - - - {{/each}} - {{/notEmpty}} - - {{#notEmpty comparison.modified}} - - - - - - - - {{#each comparison.modified}} - - - - - {{/each}} - {{/notEmpty}} -
{{tp 'quality_profiles.x_rules_only_in' comparison.inLeftSize}} {{comparison.left.name}}
{{severityIcon severity}} {{name}}
{{tp 'quality_profiles.x_rules_only_in' comparison.inRightSize}} {{comparison.right.name}}
{{severityIcon severity}} {{name}}
-
{{tp 'quality_profiles.x_rules_have_different_configuration' comparison.modifiedSize}}
-
{{comparison.left.name}}
{{comparison.right.name}}
-

{{severityIcon left.severity}} {{name}}

- {{#notNull left.params}} -
    - {{#each left.params}} -
  • {{@key}}: {{this}}
  • - {{/each}} -
- {{/notNull}} -
-

{{severityIcon right.severity}} {{name}}

- {{#notNull right.params}} -
    - {{#each right.params}} -
  • {{@key}}: {{this}}
  • - {{/each}} -
- {{/notNull}} -
- -

- {{t 'hide'}} -

-{{/notNull}} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-actions.hbs b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-actions.hbs deleted file mode 100644 index 672a7a6ec17..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-actions.hbs +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-change-projects.hbs b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-change-projects.hbs new file mode 100644 index 00000000000..09e591327e2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-change-projects.hbs @@ -0,0 +1,12 @@ + + + + + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-create-profile.hbs b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-create-profile.hbs index 50fbc195fff..845e4843ef6 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-create-profile.hbs +++ b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-create-profile.hbs @@ -6,9 +6,9 @@ + {{tp 'quality_profiles.restore_built_in_profiles_confirmation' language.name}}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js new file mode 100644 index 00000000000..cba412ba81a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import sortBy from 'lodash/sortBy'; + +export function sortProfiles (profiles) { + const result = []; + const sorted = sortBy(profiles, 'name'); + + function retrieveChildren (parent) { + return sorted.filter(p => ( + (parent == null && p.parentKey == null) || + (parent != null && p.parentKey === parent.key) + )); + } + + function putProfile (profile = null, depth = 0) { + const children = retrieveChildren(profile); + + if (profile != null) { + result.push({ ...profile, childrenCount: children.length, depth }); + } + + children.forEach(child => putProfile(child, depth + 1)); + } + + putProfile(); + + return result; +} + +export function createFakeProfile (overrides) { + return { + key: 'key', + name: 'name', + isDefault: false, + isInherited: false, + language: 'js', + languageName: 'JavaScript', + activeRuleCount: 10, + activeDeprecatedRuleCount: 2, + projectCount: 3, + ...overrides + }; +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js new file mode 100644 index 00000000000..6b405179e44 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-change-profile-parent.hbs'; +import { changeProfileParent } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + onRender () { + ModalFormView.prototype.onRender.apply(this, arguments); + this.$('select').select2({ + width: '250px', + minimumResultsForSearch: 50 + }); + }, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + this.disableForm(); + this.sendRequest(); + }, + + sendRequest () { + const parent = this.$('#change-profile-parent').val(); + changeProfileParent(this.options.profile.key, parent) + .then(() => { + this.destroy(); + this.trigger('done'); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); + }, + + serializeData () { + const { profile } = this.options; + const profiles = this.options.profiles + .filter(p => p !== profile && p.language === profile.language); + return { ...profile, profiles }; + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js new file mode 100644 index 00000000000..5292bfa183e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js @@ -0,0 +1,70 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-change-projects.hbs'; +import { translate } from '../../../helpers/l10n'; +import '../../../components/SelectList'; + +export default ModalFormView.extend({ + template: Template, + + onRender () { + ModalFormView.prototype.onRender.apply(this, arguments); + + const { key } = this.options.profile; + + const searchUrl = window.baseUrl + '/api/qualityprofiles/projects?key=' + + encodeURIComponent(key); + + new window.SelectList({ + searchUrl, + el: this.$('#profile-projects'), + width: '100%', + readOnly: false, + focusSearch: false, + format (item) { + return item.name; + }, + selectUrl: window.baseUrl + '/api/qualityprofiles/add_project', + deselectUrl: window.baseUrl + '/api/qualityprofiles/remove_project', + extra: { + profileKey: key + }, + selectParameter: 'projectUuid', + selectParameterValue: 'uuid', + labels: { + selected: translate('quality_gates.projects.with'), + deselected: translate('quality_gates.projects.without'), + all: translate('quality_gates.projects.all'), + noResults: translate('quality_gates.projects.noResults') + }, + tooltips: { + select: translate('quality_profiles.projects.select_hint'), + deselect: translate('quality_profiles.projects.deselect_hint') + } + }); + }, + + onDestroy() { + this.options.loadProjects(); + ModalFormView.prototype.onDestroy.apply(this, arguments); + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js new file mode 100644 index 00000000000..5809894287e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-copy-profile.hbs'; +import { copyProfile } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + this.disableForm(); + this.sendRequest(); + }, + + sendRequest () { + const name = this.$('#copy-profile-name').val(); + copyProfile(this.options.profile.key, name) + .then(profile => { + this.destroy(); + this.trigger('done', profile); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); + }, + + serializeData () { + return this.options.profile; + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js new file mode 100644 index 00000000000..60d800bc9fa --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js @@ -0,0 +1,95 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import $ from 'jquery'; +import _ from 'underscore'; +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-create-profile.hbs'; +import { createQualityProfile } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + events () { + return _.extend(ModalFormView.prototype.events.apply(this, arguments), { + 'change #create-profile-language': 'onLanguageChange' + }); + }, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + + const form = this.$('form')[0]; + const data = new FormData(form); + + createQualityProfile(data) + .then(r => { + this.trigger('done', r.profile); + this.destroy(); + }) + .catch(e => { + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); + }, + + onRender () { + ModalFormView.prototype.onRender.apply(this, arguments); + this.$('select').select2({ + width: '250px', + minimumResultsForSearch: 50 + }); + this.onLanguageChange(); + }, + + onLanguageChange () { + const that = this; + const language = this.$('#create-profile-language').val(); + const importers = this.getImportersForLanguages(language); + this.$('.js-importer').each(function () { + that.emptyInput($(this)); + $(this).addClass('hidden'); + }); + importers.forEach(function (importer) { + that.$(`.js-importer[data-key="${importer.key}"]`).removeClass('hidden'); + }); + }, + + emptyInput (e) { + e.wrap('
').closest('form').get(0).reset(); + e.unwrap(); + }, + + getImportersForLanguages (language) { + if (language != null) { + return this.options.importers.filter(function (importer) { + return importer.languages.indexOf(language) !== -1; + }); + } else { + return []; + } + }, + + serializeData () { + return _.extend(ModalFormView.prototype.serializeData.apply(this, arguments), { + languages: this.options.languages, + importers: this.options.importers + }); + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js new file mode 100644 index 00000000000..b9bb6023c71 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-delete-profile.hbs'; +import { deleteProfile } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + modelEvents: { + 'destroy': 'destroy' + }, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + this.disableForm(); + this.sendRequest(); + }, + + sendRequest () { + deleteProfile(this.options.profile.key) + .then(() => { + this.destroy(); + this.trigger('done'); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); + }, + + serializeData () { + return this.options.profile; + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js new file mode 100644 index 00000000000..964a4b58115 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-rename-profile.hbs'; +import { renameProfile } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + this.sendRequest(); + }, + + sendRequest () { + const name = this.$('#rename-profile-name').val(); + renameProfile(this.options.profile.key, name) + .then(profile => { + this.destroy(); + this.trigger('done', profile); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); + }, + + serializeData () { + return this.options.profile; + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js new file mode 100644 index 00000000000..f71f85c06af --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-restore-built-in-profiles.hbs'; +import TemplateSuccess from '../templates/quality-profiles-restore-built-in-profiles-success.hbs'; +import { restoreBuiltInProfiles } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + successTemplate: TemplateSuccess, + + getTemplate () { + return this.done ? this.successTemplate : this.template; + }, + + onFormSubmit () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + this.disableForm(); + this.sendRequest(); + }, + + sendRequest () { + restoreBuiltInProfiles(this.options.language.key) + .then(() => { + this.done = true; + this.render(); + this.trigger('done'); + }) + .catch(e => { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); + }, + + serializeData () { + return { language: this.options.language }; + } +}); + diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js new file mode 100644 index 00000000000..4fceffda657 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import ModalFormView from '../../../components/common/modal-form'; +import Template from '../templates/quality-profiles-restore-profile.hbs'; +import { restoreQualityProfile } from '../../../api/quality-profiles'; + +export default ModalFormView.extend({ + template: Template, + + onFormSubmit (e) { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + const data = new FormData(e.currentTarget); + + this.disableForm(); + + restoreQualityProfile(data) + .then(r => { + this.profile = r.profile; + this.ruleSuccesses = r.ruleSuccesses; + this.ruleFailures = r.ruleFailures; + this.render(); + this.trigger('done'); + }) + .catch(e => { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); + }, + + serializeData() { + return { + ...ModalFormView.prototype.serializeData.apply(this, arguments), + profile: this.profile, + ruleSuccesses: this.ruleSuccesses, + ruleFailures: this.ruleFailures + }; + } +}); -- cgit v1.2.3