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 | |
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')
31 files changed, 620 insertions, 41 deletions
diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee index 57b0b7f30dc..f306c495a9d 100644 --- a/server/sonar-web/Gruntfile.coffee +++ b/server/sonar-web/Gruntfile.coffee @@ -305,6 +305,9 @@ module.exports = (grunt) -> '<%= grunt.option("assetsDir") || pkg.assets %>js/templates/widgets.js': [ '<%= pkg.sources %>hbs/widgets/**/*.hbs' ] + '<%= grunt.option("assetsDir") || pkg.assets %>js/templates/workspace.js': [ + '<%= pkg.sources %>hbs/workspace/**/*.hbs' + ] clean: diff --git a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-coverage-popup.hbs b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-coverage-popup.hbs index df7cfc0388a..c30e1f500a9 100644 --- a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-coverage-popup.hbs +++ b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-coverage-popup.hbs @@ -15,7 +15,7 @@ {{#each testFiles}} <div class="bubble-popup-section"> - <a class="component-viewer-popup-test-file link-action" data-key="{{file.key}}" title="{{file.longName}}"> + <a class="component-viewer-popup-test-file link-action" data-uuid="{{file.uuid}}" title="{{file.longName}}"> {{file.longName}} </a> <ul class="bubble-popup-list"> @@ -24,7 +24,7 @@ <i class="component-viewer-popup-test-status {{testStatusIconClass status}}"></i> <span class="component-viewer-popup-test-name"> <a class="component-viewer-popup-test-file link-action" title="{{name}}" - data-key="{{../file.key}}" data-method="{{name}}"> + data-uuid="{{../file.uuid}}" data-method="{{name}}"> {{name}} </a> </span> diff --git a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-duplication-popup.hbs b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-duplication-popup.hbs index 79947f601c6..d3553ed3e58 100644 --- a/server/sonar-web/src/main/hbs/source-viewer/source-viewer-duplication-popup.hbs +++ b/server/sonar-web/src/main/hbs/source-viewer/source-viewer-duplication-popup.hbs @@ -17,7 +17,7 @@ {{#notEq file.key ../component.key}} <div class="component-name-path"> - <a class="link-action" data-key="{{file.key}}" title="{{file.name}}"> + <a data-uuid="{{file.uuid}}" title="{{file.name}}"> <span>{{collapsedDirFromPath file.name}}</span><span class="component-name-file">{{fileFromPath file.name}}</span> </a> @@ -27,7 +27,7 @@ <div class="component-name-path"> Lines: {{#joinEach blocks ','}} - <a class="link-action" data-key="{{../file.key}}" data-line="{{from}}"> + <a class="link-action" data-uuid="{{../file.uuid}}" data-line="{{from}}"> {{from}} – {{sum from size -1}} </a> {{/joinEach}} 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 0538df1fcb6..f782b2da64e 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 @@ -2,4 +2,6 @@ <br> <a class="js-new-window">{{t 'component_viewer.new_window'}}</a> <br> +<a class="js-workspace">{{t 'component_viewer.open_in_workspace'}}</a> +<br> <a class="js-raw-source">{{t 'component_viewer.show_raw_source'}}</a> diff --git a/server/sonar-web/src/main/hbs/workspace/workspace-item.hbs b/server/sonar-web/src/main/hbs/workspace/workspace-item.hbs new file mode 100644 index 00000000000..24cf2862541 --- /dev/null +++ b/server/sonar-web/src/main/hbs/workspace/workspace-item.hbs @@ -0,0 +1,7 @@ +{{#if q}} + {{qualifierIcon q}} +{{/if}} + +{{default name uuid}} + +<button class="js-close button-clean" style="color: #fff;">×</button> diff --git a/server/sonar-web/src/main/hbs/workspace/workspace-items.hbs b/server/sonar-web/src/main/hbs/workspace/workspace-items.hbs new file mode 100644 index 00000000000..6fe99c04b19 --- /dev/null +++ b/server/sonar-web/src/main/hbs/workspace/workspace-items.hbs @@ -0,0 +1 @@ +<ul class="workspace-nav-list"></ul> diff --git a/server/sonar-web/src/main/hbs/workspace/workspace-viewer-header.hbs b/server/sonar-web/src/main/hbs/workspace/workspace-viewer-header.hbs new file mode 100644 index 00000000000..9e3984a8bfe --- /dev/null +++ b/server/sonar-web/src/main/hbs/workspace/workspace-viewer-header.hbs @@ -0,0 +1,8 @@ +<h6 class="workspace-viewer-name">{{qualifierIcon q}} {{name}}</h6> + +<div class="workspace-viewer-actions"> + <a href="#" class="js-minimize icon-minimize spacer-right"></a> + <a href="#" class="js-full-screen icon-bigger-size workspace-for-normal-size spacer-right"></a> + <a href="#" class="js-normal-size icon-smaller-size workspace-for-full-screen spacer-right"></a> + <a href="#" class="js-close icon-close"></a> +</div> diff --git a/server/sonar-web/src/main/hbs/workspace/workspace-viewer.hbs b/server/sonar-web/src/main/hbs/workspace/workspace-viewer.hbs new file mode 100644 index 00000000000..45515fbecb0 --- /dev/null +++ b/server/sonar-web/src/main/hbs/workspace/workspace-viewer.hbs @@ -0,0 +1,3 @@ +<div class="workspace-viewer-header"></div> + +<div class="workspace-viewer-container"></div> 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); + } + }); + +}); diff --git a/server/sonar-web/src/main/less/components.less b/server/sonar-web/src/main/less/components.less index 7907d0b7bde..650d6fcf2ce 100644 --- a/server/sonar-web/src/main/less/components.less +++ b/server/sonar-web/src/main/less/components.less @@ -42,3 +42,4 @@ @import "components/panels"; @import "components/badges"; @import "components/columns"; +@import "components/workspace"; diff --git a/server/sonar-web/src/main/less/components/source.less b/server/sonar-web/src/main/less/components/source.less index 0e1e0de3770..9b88fa38cde 100644 --- a/server/sonar-web/src/main/less/components/source.less +++ b/server/sonar-web/src/main/less/components/source.less @@ -29,6 +29,7 @@ width: 100%; border: 1px solid @barBorderColor; .box-sizing(border-box); + background-color: #fff; overflow-x: auto; overflow-y: hidden; } diff --git a/server/sonar-web/src/main/less/components/workspace.less b/server/sonar-web/src/main/less/components/workspace.less new file mode 100644 index 00000000000..20339d2995a --- /dev/null +++ b/server/sonar-web/src/main/less/components/workspace.less @@ -0,0 +1,111 @@ +/* + * 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. + */ +@import (reference) "../mixins"; +@import (reference) "../variables"; + +.workspace-nav { + position: fixed; + z-index: @workspace-nav-z-index; + bottom: 0; + right: 0; + height: 30px; +} + +.workspace-nav-list { + float: right; +} + +.workspace-nav-item { + float: left; + height: 30px; + line-height: 30px; + margin-right: 10px; + padding: 0 10px; + background-color: #404040; + color: #fff; + font-size: @smallFontSize; + font-weight: 300; + cursor: pointer; +} + +.workspace-viewer { + position: fixed; + z-index: @workspace-viewer-z-index; + bottom: 0; + left: 0; + right: 0; + .box-sizing(border-box); + background-color: #fff; + box-shadow: 0 -6px 12px rgba(0, 0, 0, .175); +} + +.workspace-viewer-full-screen { + .workspace-viewer-container { + height: ~"calc(100vh - 30px - @{navbarGlobalHeight} - 10px)"; + } + + .workspace-for-full-screen { + display: inline; + } + + .workspace-for-normal-size { + display: none; + } +} + +.workspace-viewer-header { + @topPadding: (30px - @formControlHeight) / 2; + height: 30px; + padding: @topPadding 10px; + .box-sizing(border-box); + background-color: #404040; + color: #fff; + font-weight: 300; +} + +.workspace-viewer-name { + float: left; + line-height: @formControlHeight; +} + +.workspace-viewer-actions { + float: right; + line-height: @formControlHeight; + + a { color: inherit; } +} + +.workspace-viewer-container { + height: ~"calc(40vh - 30px)"; + padding: 5px 10px; + overflow-y: scroll; + overflow-x: auto; + .box-sizing(border-box); +} + +.workspace-for-full-screen { + display: none; +} + + +// Misc +.with-workspace { + padding-bottom: 40vh; +} diff --git a/server/sonar-web/src/main/less/init/icons.less b/server/sonar-web/src/main/less/init/icons.less index ed82a9d84f0..f2b19caefdd 100644 --- a/server/sonar-web/src/main/less/init/icons.less +++ b/server/sonar-web/src/main/less/init/icons.less @@ -569,6 +569,18 @@ a[class^="icon-"], a[class*=" icon-"] { content: "\f141"; font-size: @iconSmallFontSize; } +.icon-bigger-size:before { + content: "\f065"; + font-size: @iconSmallFontSize; +} +.icon-smaller-size:before { + content: "\f066"; + font-size: @iconSmallFontSize; +} +.icon-minimize:before { + content: "\f068"; + font-size: @iconSmallFontSize; +} /* diff --git a/server/sonar-web/src/main/less/init/type.less b/server/sonar-web/src/main/less/init/type.less index 41c333ce123..f14c38ef8cb 100644 --- a/server/sonar-web/src/main/less/init/type.less +++ b/server/sonar-web/src/main/less/init/type.less @@ -52,13 +52,20 @@ h3, .h3 { font-weight: 500; } -h4, .h4, h5, .h5, h6, .h6 { +h4, .h4, h5, .h5 { line-height: @formControlHeight; color: @secondFontColor; font-size: @smallFontSize; font-weight: 400; } +h6 { + line-height: inherit; + color: inherit; + font-size: inherit; + font-weight: inherit; +} + h1 img, .h1 img, h2 img, .h2 img, h3 img, .h3 img, h4 img, .h4 img { vertical-align: middle; } diff --git a/server/sonar-web/src/main/less/variables.less b/server/sonar-web/src/main/less/variables.less index b8c6e9e6be2..08e1a0499d9 100644 --- a/server/sonar-web/src/main/less/variables.less +++ b/server/sonar-web/src/main/less/variables.less @@ -149,3 +149,11 @@ @navbarGlobalHeight: 30px; @navbarContextHeight: 60px; @pageFooterHeight: 60px; + + + +/* + * z-index + */ +@workspace-nav-z-index: 301; +@workspace-viewer-z-index: 300; diff --git a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.eot b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.eot Binary files differindex 8150a71a115..4e519106bb1 100755 --- a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.eot +++ b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.eot diff --git a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.svg b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.svg index 6ed29b1be77..3b377b7638f 100755 --- a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.svg +++ b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.svg @@ -55,7 +55,10 @@ <glyph unicode="" d="M841.143 411.429q0-30.857-21.143-52l-372-372q-22.286-21.143-52-21.143-29.143 0-51.429 21.143l-42.857 42.857q-21.714 21.714-21.714 52t21.714 52l167.429 167.429h-402.286q-29.714 0-48.286 21.429t-18.571 51.714v73.143q0 30.286 18.571 51.714t48.286 21.429h402.286l-167.429 168q-21.714 20.571-21.714 51.429t21.714 51.429l42.857 42.857q21.714 21.714 51.429 21.714 30.286 0 52-21.714l372-372q21.143-20 21.143-51.429z" /> <glyph unicode="" d="M920.571 405.143q0-29.143-21.143-51.429l-42.857-42.857q-21.714-21.714-52-21.714-30.857 0-51.429 21.714l-168 167.429v-402.286q0-29.714-21.429-48.286t-51.714-18.571h-73.143q-30.286 0-51.714 18.571t-21.429 48.286v402.286l-168-167.429q-20.571-21.714-51.429-21.714t-51.429 21.714l-42.857 42.857q-21.714 21.714-21.714 51.429 0 30.286 21.714 52l372 372q20 21.143 51.429 21.143 30.857 0 52-21.143l372-372q21.143-22.286 21.143-52z" horiz-adv-x="951" /> <glyph unicode="" d="M920.571 484.571q0-30.286-21.143-51.429l-372-372.571q-22.286-21.143-52-21.143-30.286 0-51.429 21.143l-372 372.571q-21.714 20.571-21.714 51.429 0 30.286 21.714 52l42.286 42.857q22.286 21.143 52 21.143 30.286 0 51.429-21.143l168-168v402.286q0 29.714 21.714 51.429t51.429 21.714h73.143q29.714 0 51.429-21.714t21.714-51.429v-402.286l168 168q21.143 21.143 51.429 21.143 29.714 0 52-21.143l42.857-42.857q21.143-22.286 21.143-52z" horiz-adv-x="951" /> +<glyph unicode="" d="M503.385 332.821q0-8.615-6.627-15.243l-220.023-220.023 95.433-95.433q12.592-12.592 12.592-29.822t-12.59-29.822-29.822-12.59h-296.899q-17.231 0-29.822 12.59t-12.59 29.822v296.899q0 17.231 12.59 29.822t29.822 12.592 29.822-12.592l95.433-95.433 220.023 220.023q6.627 6.627 15.243 6.627t15.243-6.627l75.55-75.55q6.627-6.627 6.627-15.243zM1020.969 905.413v-296.899q0-17.231-12.592-29.822t-29.822-12.592-29.822 12.592l-95.433 95.433-220.023-220.023q-6.627-6.627-15.243-6.627t-15.243 6.627l-75.55 75.55q-6.627 6.627-6.627 15.243t6.627 15.243l220.023 220.023-95.433 95.433q-12.59 12.592-12.59 29.822t12.59 29.822 29.822 12.592h296.899q17.231 0 29.822-12.592t12.592-29.822z" /> +<glyph unicode="" d="M438.857 402.286v-256q0-14.857-10.857-25.714t-25.714-10.857-25.714 10.857l-82.286 82.286-189.714-189.714q-5.714-5.714-13.143-5.714t-13.143 5.714l-65.143 65.143q-5.714 5.714-5.714 13.143t5.714 13.143l189.714 189.714-82.286 82.286q-10.857 10.857-10.857 25.714t10.857 25.714 25.714 10.857h256q14.857 0 25.714-10.857t10.857-25.714zM870.286 786.286q0-7.429-5.714-13.143l-189.714-189.714 82.286-82.286q10.857-10.857 10.857-25.714t-10.857-25.714-25.714-10.857h-256q-14.857 0-25.714 10.857t-10.857 25.714v256q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857l82.286-82.286 189.714 189.714q5.714 5.714 13.143 5.714t13.143-5.714l65.143-65.143q5.714-5.714 5.714-13.143z" /> <glyph unicode="" d="M804.571 539.429v-109.714q0-22.857-16-38.857t-38.857-16h-237.714v-237.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857v237.714h-237.714q-22.857 0-38.857 16t-16 38.857v109.714q0 22.857 16 38.857t38.857 16h237.714v237.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-237.714h237.714q22.857 0 38.857-16t16-38.857z" horiz-adv-x="805" /> +<glyph unicode="" d="M804.571 91.434v-109.714q0-22.857-16-38.857t-38.857-16h-694.857q-22.857 0-38.857 16t-16 38.857v109.714q0 22.857 16 38.857t38.857 16h694.857q22.857 0 38.857-16t16-38.857z" horiz-adv-x="805" /> <glyph unicode="" d="M846.857 360q26.286-14.857 34-44.286t-7.143-55.714l-36.571-62.857q-14.857-26.286-44.286-34t-55.714 7.143l-152 87.429v-175.429q0-29.714-21.714-51.429t-51.429-21.714h-73.143q-29.714 0-51.429 21.714t-21.714 51.429v175.429l-152-87.429q-26.286-14.857-55.714-7.143t-44.286 34l-36.571 62.857q-14.857 26.286-7.143 55.714t34 44.286l152 88-152 88q-26.286 14.857-34 44.286t7.143 55.714l36.571 62.857q14.857 26.286 44.286 34t55.714-7.143l152-87.429v175.429q0 29.714 21.714 51.429t51.429 21.714h73.143q29.714 0 51.429-21.714t21.714-51.429v-175.429l152 87.429q26.286 14.857 55.714 7.143t44.286-34l36.571-62.857q14.857-26.286 7.143-55.714t-34-44.286l-152-88z" horiz-adv-x="951" /> <glyph unicode="" d="M73.143 9.143h164.571v164.571h-164.571v-164.571zM274.286 9.143h182.857v164.571h-182.857v-164.571zM73.143 210.286h164.571v182.857h-164.571v-182.857zM274.286 210.286h182.857v182.857h-182.857v-182.857zM73.143 429.714h164.571v164.571h-164.571v-164.571zM493.714 9.143h182.857v164.571h-182.857v-164.571zM274.286 429.714h182.857v164.571h-182.857v-164.571zM713.143 9.143h164.571v164.571h-164.571v-164.571zM493.714 210.286h182.857v182.857h-182.857v-182.857zM292.571 704v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857zM713.143 210.286h164.571v182.857h-164.571v-182.857zM493.714 429.714h182.857v164.571h-182.857v-164.571zM713.143 429.714h164.571v164.571h-164.571v-164.571zM731.429 704v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857zM950.857 740.571v-731.429q0-29.714-21.714-51.429t-51.429-21.714h-804.571q-29.714 0-51.429 21.714t-21.714 51.429v731.429q0 29.714 21.714 51.429t51.429 21.714h73.143v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h219.429v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h73.143q29.714 0 51.429-21.714t21.714-51.429z" horiz-adv-x="951" /> <glyph unicode="" d="M1024 448q0-99.429-68.571-183.714t-186.286-133.143-257.143-48.857q-40 0-82.857 4.571-113.143-100-262.857-138.286-28-8-65.143-12.571-9.714-1.143-17.429 5.143t-10 16.571v0.571q-1.714 2.286-0.286 6.857t1.143 5.714 2.571 5.429l3.429 5.143t4 4.857 4.571 5.143q4 4.571 17.714 19.714t19.714 21.714 17.714 22.571 18.571 29.143 15.429 33.714 14.857 43.429q-89.714 50.857-141.429 125.714t-51.714 160.571q0 74.286 40.571 142t109.143 116.857 163.429 78 198.857 28.857q139.429 0 257.143-48.857t186.286-133.143 68.571-183.714z" /> diff --git a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.ttf b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.ttf Binary files differindex 86a81f3f492..903dd7bef1e 100755 --- a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.ttf +++ b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.ttf diff --git a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.woff b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.woff Binary files differindex 40582fe91e5..1d1d8b90d54 100755 --- a/server/sonar-web/src/main/webapp/fonts/sonar-5.1.woff +++ b/server/sonar-web/src/main/webapp/fonts/sonar-5.1.woff |