From 9b9a2ae771838048b65c3bbda6a3709a4c40849c Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 18 Mar 2015 15:03:03 +0100 Subject: [PATCH] apply workspace feedback --- .../source-viewer-more-actions.hbs | 6 ++- .../src/main/js/source-viewer/more-actions.js | 7 +++ .../src/main/js/source-viewer/viewer.js | 8 +-- .../sonar-web/src/main/js/workspace/main.js | 44 +++++++++------- .../src/main/js/workspace/models/item.js | 17 ++++++- .../src/main/js/workspace/views/item-view.js | 6 ++- .../js/workspace/views/viewer-header-view.js | 5 +- .../main/js/workspace/views/viewer-view.js | 17 ++++++- server/sonar-web/src/test/js/workspace.js | 51 +++++++++++++++++++ .../resources/org/sonar/l10n/core.properties | 2 +- 10 files changed, 129 insertions(+), 34 deletions(-) create mode 100644 server/sonar-web/src/test/js/workspace.js diff --git a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-more-actions.hbs b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-more-actions.hbs index f782b2da64e..c5a85413424 100644 --- a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-more-actions.hbs +++ b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-more-actions.hbs @@ -1,7 +1,9 @@ {{t 'component_viewer.show_details'}}
{{t 'component_viewer.new_window'}} -
-{{t 'component_viewer.open_in_workspace'}} +{{#unless options.workspace}} +
+ {{t 'component_viewer.open_in_workspace'}} +{{/unless}}
{{t 'component_viewer.show_raw_source'}} diff --git a/server/sonar-web/src/main/js/source-viewer/more-actions.js b/server/sonar-web/src/main/js/source-viewer/more-actions.js index fc3f4048076..0d84d93c468 100644 --- a/server/sonar-web/src/main/js/source-viewer/more-actions.js +++ b/server/sonar-web/src/main/js/source-viewer/more-actions.js @@ -61,6 +61,13 @@ define([ showRawSource: function () { this.options.parent.showRawSources(); + }, + + serializeData: function () { + var options = this.options.parent.options.viewer.options; + return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { + options: options + }); } }); diff --git a/server/sonar-web/src/main/js/source-viewer/viewer.js b/server/sonar-web/src/main/js/source-viewer/viewer.js index d177c92d9a3..9dabf5698c8 100644 --- a/server/sonar-web/src/main/js/source-viewer/viewer.js +++ b/server/sonar-web/src/main/js/source-viewer/viewer.js @@ -27,7 +27,6 @@ define([ 'source-viewer/popups/coverage-popup', 'source-viewer/popups/duplication-popup', 'source-viewer/popups/line-actions-popup', - 'workspace/main', 'templates/source-viewer' ], function (Source, @@ -38,8 +37,7 @@ define([ SCMPopupView, CoveragePopupView, DuplicationPopupView, - LineActionsPopupView, - Workspace) { + LineActionsPopupView) { var $ = jQuery, HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted'; @@ -124,14 +122,16 @@ define([ this.bindScrollEvents(); }, - open: function (id) { + open: function (id, options) { var that = this, + opts = typeof options === 'object' ? options : {}, finalize = function () { that.requestIssues().done(function () { that.render(); that.trigger('loaded'); }); }; + _.extend(this.options, _.defaults(opts, { workspace: false })); this.model .clear() .set(_.result(this.model, 'defaults')) diff --git a/server/sonar-web/src/main/js/workspace/main.js b/server/sonar-web/src/main/js/workspace/main.js index 77993cb5c85..6a717fed39d 100644 --- a/server/sonar-web/src/main/js/workspace/main.js +++ b/server/sonar-web/src/main/js/workspace/main.js @@ -41,12 +41,14 @@ define([ this.items = new Items(); this.items.load(); + this.items.on('change', function () { + that.save(); + }); this.itemsView = new ItemsView({ collection: this.items }); this.itemsView.render().$el.appendTo(document.body); - this.itemsView.on('click', function (uuid, model) { - model.collection.remove(model); - that.showComponentViewer(model.toJSON()); + this.itemsView.on('click', function (model) { + that.open(model); }); }, @@ -58,24 +60,28 @@ define([ this.items.load(); }, - addComponent: function (options) { - if (options == null || typeof options.uuid !== 'string') { - throw new Error('You must specify the component\'s uuid'); - } - this.items.add(options); + addComponent: function (model) { + this.items.add(model); this.save(); }, - openComponent: function (options) { - if (options == null || typeof options.uuid !== 'string') { - throw new Error('You must specify the component\'s uuid'); + open: function (options) { + var model = typeof options.toJSON === 'function' ? options : new Item(options); + if (!model.isValid()) { + throw new Error(model.validationError); + } + this.addComponent(model); + if (model.isComponent()) { + this.showComponentViewer(model); } - this.showComponentViewer(options); }, - showComponentViewer: function (options) { - var that = this, - model = new Item(options); + openComponent: function (options) { + return this.open(_.extend(options, { type: 'component' })); + }, + + showComponentViewer: function (model) { + var that = this; if (this.viewerView != null) { this.viewerView.close(); } @@ -83,13 +89,13 @@ define([ this.viewerView = new ViewerView({ model: model }); - model - .on('minimize', function () { - that.addComponent(model.toJSON()); + this.viewerView + .on('viewerMinimize', function () { that.closeComponentViewer(); }) - .on('close', function () { + .on('viewerClose', function (model) { that.closeComponentViewer(); + model.destroy(); }); this.viewerView.render().$el.appendTo(document.body); }, diff --git a/server/sonar-web/src/main/js/workspace/models/item.js b/server/sonar-web/src/main/js/workspace/models/item.js index 076f57a3e36..9bbe1db8110 100644 --- a/server/sonar-web/src/main/js/workspace/models/item.js +++ b/server/sonar-web/src/main/js/workspace/models/item.js @@ -20,12 +20,25 @@ define(function () { return Backbone.Model.extend({ - idAttribute: 'uuid', validate: function () { - if (!this.has('uuid')) { + if (!this.has('type')) { + return 'type is missing'; + } + if (this.get('type') === 'component' && !this.has('uuid')) { return 'uuid is missing'; } + if (this.get('type') === 'rule' && !this.has('key')) { + return 'key is missing'; + } + }, + + isComponent: function () { + return this.get('type') === 'component'; + }, + + isRule: function () { + return this.get('type') === 'rule'; }, destroy: function (options) { diff --git a/server/sonar-web/src/main/js/workspace/views/item-view.js b/server/sonar-web/src/main/js/workspace/views/item-view.js index cbc5919ba60..fd176697611 100644 --- a/server/sonar-web/src/main/js/workspace/views/item-view.js +++ b/server/sonar-web/src/main/js/workspace/views/item-view.js @@ -26,6 +26,10 @@ define([ className: 'workspace-nav-item', template: Templates['workspace-item'], + modelEvents: { + 'change': 'render' + }, + events: { 'click': 'onClick', 'click .js-close': 'onCloseClick' @@ -33,7 +37,7 @@ define([ onClick: function (e) { e.preventDefault(); - this.options.collectionView.trigger('click', this.model.id, this.model); + this.options.collectionView.trigger('click', this.model); }, onCloseClick: function (e) { diff --git a/server/sonar-web/src/main/js/workspace/views/viewer-header-view.js b/server/sonar-web/src/main/js/workspace/views/viewer-header-view.js index 052550f1642..4b15a5bdbfc 100644 --- a/server/sonar-web/src/main/js/workspace/views/viewer-header-view.js +++ b/server/sonar-web/src/main/js/workspace/views/viewer-header-view.js @@ -37,7 +37,7 @@ define([ onMinimizeClick: function (e) { e.preventDefault(); - this.model.trigger('minimize'); + this.trigger('viewerMinimize'); }, onFullScreenClick: function (e) { @@ -52,10 +52,9 @@ define([ onCloseClick: function (e) { e.preventDefault(); - this.model.trigger('close'); + this.trigger('viewerClose'); }, - toFullScreen: function () { this.$el.closest('.workspace-viewer').addClass('workspace-viewer-full-screen'); }, diff --git a/server/sonar-web/src/main/js/workspace/views/viewer-view.js b/server/sonar-web/src/main/js/workspace/views/viewer-view.js index a459d0982b8..923b147e23f 100644 --- a/server/sonar-web/src/main/js/workspace/views/viewer-view.js +++ b/server/sonar-web/src/main/js/workspace/views/viewer-view.js @@ -38,8 +38,18 @@ define([ this.$('.workspace-viewer-container').isolatedScroll(); }, + onViewerMinimize: function () { + this.trigger('viewerMinimize'); + }, + + onViewerClose: function () { + this.trigger('viewerClose', this.model); + }, + showHeader: function () { var headerView = new HeaderView({ model: this.model }); + this.listenTo(headerView, 'viewerMinimize', this.onViewerMinimize); + this.listenTo(headerView, 'viewerClose', this.onViewerClose); this.headerRegion.show(headerView); }, @@ -50,9 +60,12 @@ define([ var that = this, viewer = new SourceViewer(), options = this.model.toJSON(); - viewer.open(this.model.id); + viewer.open(this.model.get('uuid'), { workspace: true }); viewer.on('loaded', function () { - that.model.set(viewer.model.toJSON()); + that.model.set({ + name: viewer.model.get('name'), + q: viewer.model.get('q') + }); if (options.line != null) { viewer.highlightLine(options.line); viewer.scrollToLine(options.line); diff --git a/server/sonar-web/src/test/js/workspace.js b/server/sonar-web/src/test/js/workspace.js new file mode 100644 index 00000000000..873d6701b81 --- /dev/null +++ b/server/sonar-web/src/test/js/workspace.js @@ -0,0 +1,51 @@ +/* + * 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. + */ +/* globals casper: false */ + +var lib = require('../lib'), + testName = lib.testName('Workspace'); + + +lib.initMessages(); +lib.configureCasper(); + + +casper.test.begin(testName('API'), function (test) { + casper + .start(lib.buildUrl('nav'), function () { + lib.setDefaultViewport(); + }) + + .then(function () { + test.assertNotEquals(casper.evaluate(function () { + window.workspace = require(['/js/workspace/main.js'])(); + console.log(window.workspace); + return window.workspace; + }), null); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); 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 4af59b66cbb..98c670389f7 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2899,7 +2899,7 @@ component_viewer.show_full_source=Show Full Source component_viewer.show_raw_source=Show Raw Source component_viewer.more_actions=More Actions component_viewer.new_window=Open in New Window -component_viewer.open_in_workspace=Open in Workspace +component_viewer.open_in_workspace=Pin This File component_viewer.get_permalink=Get Permalink component_viewer.covered_lines=Covered Lines component_viewer.issues_limit_reached=For usability reasons, only the {0} first issues will be fully displayed. Remaining issues will simply be underlined. -- 2.39.5