diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2015-03-06 10:44:45 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2015-03-06 10:44:45 +0100 |
commit | 9f6c589ed8c8c03d4f93bad772a91941a2f62cb3 (patch) | |
tree | 21d7bb776c6e119dd0f5c1db35bce5cbc7c10c10 /server/sonar-web/src/main/js | |
parent | 1432f744dbff4834badc39fd66fe19268712a1a5 (diff) | |
parent | 4cbfea9653a895bafb1ee7d2de521b7d78345320 (diff) | |
download | sonarqube-9f6c589ed8c8c03d4f93bad772a91941a2f62cb3.tar.gz sonarqube-9f6c589ed8c8c03d4f93bad772a91941a2f62cb3.zip |
Merge remote-tracking branch 'remotes/origin/feature/workspace' into branch-5.2
Conflicts:
server/sonar-web/Gruntfile.coffee
server/sonar-web/src/main/hbs/source-viewer/source-viewer-duplication-popup.hbs
server/sonar-web/src/main/less/components.less
Diffstat (limited to 'server/sonar-web/src/main/js')
13 files changed, 448 insertions, 36 deletions
diff --git a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js index dda154b3717..0296b1589aa 100644 --- a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js +++ b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js @@ -87,16 +87,7 @@ define(function () { } }, - disablePointerEvents: function () { - clearTimeout(this.scrollTimer); - $('body').addClass('disabled-pointer-events'); - this.scrollTimer = setTimeout(function () { - $('body').removeClass('disabled-pointer-events'); - }, 250); - }, - onScroll: function () { - this.disablePointerEvents(); if ($(window).scrollTop() + $(window).height() >= this.ui.loadMore.offset().top) { this.loadMoreThrottled(); } diff --git a/server/sonar-web/src/main/js/nav/app.js b/server/sonar-web/src/main/js/nav/app.js index 0a67c7bf979..9d495f433b1 100644 --- a/server/sonar-web/src/main/js/nav/app.js +++ b/server/sonar-web/src/main/js/nav/app.js @@ -20,7 +20,8 @@ define([ 'nav/global-navbar-view', 'nav/context-navbar-view', - 'nav/settings-navbar-view' + 'nav/settings-navbar-view', + 'workspace/main' ], function (GlobalNavbarView, ContextNavbarView, SettingsNavbarView) { var $ = jQuery, 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 fd96c43ffa4..fc3f4048076 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 @@ -18,8 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ define([ + 'workspace/main', 'templates/source-viewer' -], function () { +], function (Workspace) { var $ = jQuery; @@ -30,6 +31,7 @@ define([ events: { 'click .js-measures': 'showMeasures', 'click .js-new-window': 'openNewWindow', + 'click .js-workspace': 'openInWorkspace', 'click .js-raw-source': 'showRawSource' }, @@ -49,6 +51,14 @@ define([ this.options.parent.getPermalink(); }, + openInWorkspace: function () { + var uuid = this.options.parent.model.id; + if (Workspace == null) { + Workspace = require('workspace/main'); + } + Workspace.openComponent({ uuid: uuid }); + }, + showRawSource: function () { this.options.parent.showRawSources(); } diff --git a/server/sonar-web/src/main/js/source-viewer/popups/coverage-popup.js b/server/sonar-web/src/main/js/source-viewer/popups/coverage-popup.js index 96afb6ff4ed..34f080e9655 100644 --- a/server/sonar-web/src/main/js/source-viewer/popups/coverage-popup.js +++ b/server/sonar-web/src/main/js/source-viewer/popups/coverage-popup.js @@ -19,8 +19,9 @@ */ define([ 'common/popup', + 'workspace/main', 'templates/source-viewer' -], function (Popup) { +], function (Popup, Workspace) { var $ = jQuery; @@ -28,7 +29,7 @@ define([ template: Templates['source-viewer-coverage-popup'], events: { - 'click a[data-key]': 'goToFile' + 'click a[data-uuid]': 'goToFile' }, onRender: function () { @@ -37,10 +38,11 @@ define([ }, goToFile: function (e) { - var key = $(e.currentTarget).data('key'), - url = baseUrl + '/component/index?id=' + encodeURIComponent(key), - windowParams = 'resizable=1,scrollbars=1,status=1'; - window.open(url, key, windowParams); + var uuid = $(e.currentTarget).data('uuid'); + if (Workspace == null) { + Workspace = require('workspace/main'); + } + Workspace.openComponent({ uuid: uuid }); }, serializeData: function () { diff --git a/server/sonar-web/src/main/js/source-viewer/popups/duplication-popup.js b/server/sonar-web/src/main/js/source-viewer/popups/duplication-popup.js index a00749fcedc..e1479daa14d 100644 --- a/server/sonar-web/src/main/js/source-viewer/popups/duplication-popup.js +++ b/server/sonar-web/src/main/js/source-viewer/popups/duplication-popup.js @@ -19,8 +19,9 @@ */ define([ 'common/popup', + 'workspace/main', 'templates/source-viewer' -], function (Popup) { +], function (Popup, Workspace) { var $ = jQuery; @@ -28,15 +29,17 @@ define([ template: Templates['source-viewer-duplication-popup'], events: { - 'click a[data-key]': 'goToFile' + 'click a[data-uuid]': 'goToFile' }, goToFile: function (e) { - var key = $(e.currentTarget).data('key'), - line = $(e.currentTarget).data('line'), - url = baseUrl + '/component/index?id=' + encodeURIComponent(key) + (line ? ('&line=' + line) : ''), - windowParams = 'resizable=1,scrollbars=1,status=1'; - window.open(url, key, windowParams); + var uuid = $(e.currentTarget).data('uuid'), + line = $(e.currentTarget).data('line'); + console.log(uuid); + if (Workspace == null) { + Workspace = require('workspace/main'); + } + Workspace.openComponent({ uuid: uuid, line: line }); }, serializeData: function () { 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 84f635b9ae9..d177c92d9a3 100644 --- a/server/sonar-web/src/main/js/source-viewer/viewer.js +++ b/server/sonar-web/src/main/js/source-viewer/viewer.js @@ -27,6 +27,7 @@ define([ 'source-viewer/popups/coverage-popup', 'source-viewer/popups/duplication-popup', 'source-viewer/popups/line-actions-popup', + 'workspace/main', 'templates/source-viewer' ], function (Source, @@ -37,7 +38,8 @@ define([ SCMPopupView, CoveragePopupView, DuplicationPopupView, - LineActionsPopupView) { + LineActionsPopupView, + Workspace) { var $ = jQuery, HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted'; @@ -234,7 +236,7 @@ define([ requestDuplications: function () { var that = this, url = baseUrl + '/api/duplications/show', - options = {key: this.model.key()}; + options = { uuid : this.model.id }; return $.get(url, options, function (data) { var hasDuplications = (data != null) && (data.duplications != null), duplications = []; @@ -392,7 +394,7 @@ define([ row = _.findWhere(this.model.get('source'), { line: line }), url = baseUrl + '/api/tests/test_cases', options = { - key: this.model.key(), + uuid: this.model.id, line: line }; return $.get(url, options).done(function (data) { @@ -504,16 +506,7 @@ define([ this.$el.scrollParent().off('scroll.source-viewer'); }, - disablePointerEvents: function () { - clearTimeout(this.scrollTimer); - $('body').addClass('disabled-pointer-events'); - this.scrollTimer = setTimeout((function () { - $('body').removeClass('disabled-pointer-events'); - }), 250); - }, - onScroll: function () { - this.disablePointerEvents(); var p = this.$el.scrollParent(); if (p.is(document)) { p = $(window); diff --git a/server/sonar-web/src/main/js/workspace/main.js b/server/sonar-web/src/main/js/workspace/main.js new file mode 100644 index 00000000000..77993cb5c85 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/main.js @@ -0,0 +1,114 @@ +/* + * 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. + */ +define([ + 'workspace/models/item', + 'workspace/models/items', + 'workspace/views/items-view', + 'workspace/views/viewer-view' +], function (Item, Items, ItemsView, ViewerView) { + + var $ = jQuery, + + instance = null, + + Workspace = function () { + if (instance != null) { + throw new Error('Cannot instantiate more than one Workspace, use Workspace.getInstance()'); + } + this.initialize(); + }; + + Workspace.prototype = { + initialize: function () { + var that = this; + + this.items = new Items(); + this.items.load(); + + 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()); + }); + }, + + save: function () { + this.items.save(); + }, + + load: function () { + 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); + this.save(); + }, + + openComponent: function (options) { + if (options == null || typeof options.uuid !== 'string') { + throw new Error('You must specify the component\'s uuid'); + } + this.showComponentViewer(options); + }, + + showComponentViewer: function (options) { + var that = this, + model = new Item(options); + if (this.viewerView != null) { + this.viewerView.close(); + } + $('.source-viewer').addClass('with-workspace'); + this.viewerView = new ViewerView({ + model: model + }); + model + .on('minimize', function () { + that.addComponent(model.toJSON()); + that.closeComponentViewer(); + }) + .on('close', function () { + that.closeComponentViewer(); + }); + this.viewerView.render().$el.appendTo(document.body); + }, + + closeComponentViewer: function () { + if (this.viewerView != null) { + this.viewerView.close(); + $('.with-workspace').removeClass('with-workspace'); + } + } + }; + + Workspace.getInstance = function () { + if (instance == null) { + instance = new Workspace(); + } + return instance; + }; + + return Workspace.getInstance(); + +}); diff --git a/server/sonar-web/src/main/js/workspace/models/item.js b/server/sonar-web/src/main/js/workspace/models/item.js new file mode 100644 index 00000000000..076f57a3e36 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/models/item.js @@ -0,0 +1,37 @@ +/* + * 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. + */ +define(function () { + + return Backbone.Model.extend({ + idAttribute: 'uuid', + + validate: function () { + if (!this.has('uuid')) { + return 'uuid is missing'; + } + }, + + destroy: function (options) { + this.stopListening(); + this.trigger('destroy', this, this.collection, options); + } + }); + +}); diff --git a/server/sonar-web/src/main/js/workspace/models/items.js b/server/sonar-web/src/main/js/workspace/models/items.js new file mode 100644 index 00000000000..f582af5709d --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/models/items.js @@ -0,0 +1,47 @@ +/* + * 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. + */ +define(['workspace/models/item'], function (Item) { + + var STORAGE_KEY = 'sonarqube-workspace'; + + return Backbone.Collection.extend({ + model: Item, + + initialize: function () { + this.on('remove', this.save); + }, + + save: function () { + var dump = JSON.stringify(this.toJSON()); + window.localStorage.setItem(STORAGE_KEY, dump); + }, + + load: function () { + var dump = window.localStorage.getItem(STORAGE_KEY); + if (dump != null) { + try { + var parsed = JSON.parse(dump); + this.reset(parsed); + } catch (err) { } + } + } + }); + +}); 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 new file mode 100644 index 00000000000..cbc5919ba60 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/views/item-view.js @@ -0,0 +1,46 @@ +/* + * 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. + */ +define([ + 'templates/workspace' +], function () { + + return Marionette.ItemView.extend({ + tagName: 'li', + className: 'workspace-nav-item', + template: Templates['workspace-item'], + + events: { + 'click': 'onClick', + 'click .js-close': 'onCloseClick' + }, + + onClick: function (e) { + e.preventDefault(); + this.options.collectionView.trigger('click', this.model.id, this.model); + }, + + onCloseClick: function (e) { + e.preventDefault(); + e.stopPropagation(); + this.model.destroy(); + } + }); + +}); diff --git a/server/sonar-web/src/main/js/workspace/views/items-view.js b/server/sonar-web/src/main/js/workspace/views/items-view.js new file mode 100644 index 00000000000..e6c721bf089 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/views/items-view.js @@ -0,0 +1,36 @@ +/* + * 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. + */ +define([ + 'workspace/views/item-view', + 'templates/workspace' +], function (ItemView) { + + return Marionette.CompositeView.extend({ + className: 'workspace-nav', + template: Templates['workspace-items'], + itemViewContainer: '.workspace-nav-list', + itemView: ItemView, + + itemViewOptions: function () { + return { collectionView: this }; + } + }); + +}); 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 new file mode 100644 index 00000000000..052550f1642 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/views/viewer-header-view.js @@ -0,0 +1,68 @@ +/* + * 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. + */ +define([ + 'templates/workspace' +], function () { + + return Marionette.ItemView.extend({ + template: Templates['workspace-viewer-header'], + + modelEvents: { + 'change': 'render' + }, + + events: { + 'click .js-minimize': 'onMinimizeClick', + 'click .js-full-screen': 'onFullScreenClick', + 'click .js-normal-size': 'onNormalSizeClick', + 'click .js-close': 'onCloseClick' + }, + + onMinimizeClick: function (e) { + e.preventDefault(); + this.model.trigger('minimize'); + }, + + onFullScreenClick: function (e) { + e.preventDefault(); + this.toFullScreen(); + }, + + onNormalSizeClick: function (e) { + e.preventDefault(); + this.toNormalSize(); + }, + + onCloseClick: function (e) { + e.preventDefault(); + this.model.trigger('close'); + }, + + + toFullScreen: function () { + this.$el.closest('.workspace-viewer').addClass('workspace-viewer-full-screen'); + }, + + toNormalSize: function () { + this.$el.closest('.workspace-viewer').removeClass('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 new file mode 100644 index 00000000000..19f772facc0 --- /dev/null +++ b/server/sonar-web/src/main/js/workspace/views/viewer-view.js @@ -0,0 +1,64 @@ +/* + * 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. + */ +define([ + 'workspace/views/viewer-header-view', + 'source-viewer/viewer', + 'templates/workspace' +], function (HeaderView, SourceViewer) { + + return Marionette.Layout.extend({ + className: 'workspace-viewer', + template: Templates['workspace-viewer'], + + regions: { + headerRegion: '.workspace-viewer-header', + viewerRegion: '.workspace-viewer-container' + }, + + onRender: function () { + this.showHeader(); + this.showViewer(); + }, + + showHeader: function () { + var headerView = new HeaderView({ model: this.model }); + this.headerRegion.show(headerView); + }, + + showViewer: function () { + if (SourceViewer == null) { + SourceViewer = require('source-viewer/viewer'); + } + var that = this, + viewer = new SourceViewer(), + options = this.model.toJSON(); + viewer.open(this.model.id); + viewer.on('loaded', function () { + that.model.set(viewer.model.toJSON()); + if (options.line != null) { + viewer.highlightLine(options.line); + viewer.scrollToLine(options.line); + } + }); + this.viewerRegion.show(viewer); + } + }); + +}); |