From b68ea730e96bed09e7a9dd4a102fa8cc94d8f416 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Fri, 20 Mar 2015 16:28:49 +0100 Subject: [PATCH] SONAR-6215 apply feedback --- .../hbs/workspace/workspace-viewer-header.hbs | 15 +- .../sonar-web/src/main/js/workspace/main.js | 4 +- .../src/main/js/workspace/models/items.js | 6 + .../js/workspace/views/viewer-header-view.js | 11 + .../main/js/workspace/views/viewer-view.js | 4 + server/sonar-web/src/test/js/workspace.js | 251 +++++++++++++++++- .../src/test/json/workspace/app.json | 24 ++ .../src/test/json/workspace/issues.json | 9 + .../src/test/json/workspace/lines.json | 72 +++++ .../resources/org/sonar/l10n/core.properties | 13 + 10 files changed, 398 insertions(+), 11 deletions(-) create mode 100644 server/sonar-web/src/test/json/workspace/app.json create mode 100644 server/sonar-web/src/test/json/workspace/issues.json create mode 100644 server/sonar-web/src/test/json/workspace/lines.json 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 index 9e3984a8bfe..e601ad66837 100644 --- a/server/sonar-web/src/main/hbs/workspace/workspace-viewer-header.hbs +++ b/server/sonar-web/src/main/hbs/workspace/workspace-viewer-header.hbs @@ -1,8 +1,15 @@
{{qualifierIcon q}} {{name}}
- - - - + + + + + + +
diff --git a/server/sonar-web/src/main/js/workspace/main.js b/server/sonar-web/src/main/js/workspace/main.js index 6a717fed39d..158089571b4 100644 --- a/server/sonar-web/src/main/js/workspace/main.js +++ b/server/sonar-web/src/main/js/workspace/main.js @@ -61,7 +61,9 @@ define([ }, addComponent: function (model) { - this.items.add(model); + if (!this.items.has(model)) { + this.items.add(model); + } this.save(); }, diff --git a/server/sonar-web/src/main/js/workspace/models/items.js b/server/sonar-web/src/main/js/workspace/models/items.js index f582af5709d..7a4bde3bd02 100644 --- a/server/sonar-web/src/main/js/workspace/models/items.js +++ b/server/sonar-web/src/main/js/workspace/models/items.js @@ -41,6 +41,12 @@ define(['workspace/models/item'], function (Item) { this.reset(parsed); } catch (err) { } } + }, + + has: function (model) { + var forComponent = model.isComponent() && this.findWhere({ uuid: model.get('uuid') }) != null, + forRule = model.isRule() && this.findWhere({ key: model.get('key') }) != null; + return forComponent || forRule; } }); 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 4b15a5bdbfc..1afebbdbc83 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 @@ -21,6 +21,8 @@ define([ 'templates/workspace' ], function () { + var $ = jQuery; + return Marionette.ItemView.extend({ template: Templates['workspace-viewer-header'], @@ -35,6 +37,15 @@ define([ 'click .js-close': 'onCloseClick' }, + onRender: function () { + this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); + }, + + onClose: function () { + this.$('[data-toggle="tooltip"]').tooltip('destroy'); + $('.tooltip').remove(); + }, + onMinimizeClick: function (e) { e.preventDefault(); this.trigger('viewerMinimize'); 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 923b147e23f..d294a56a83c 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 @@ -27,6 +27,10 @@ define([ className: 'workspace-viewer', template: Templates['workspace-viewer'], + modelEvents: { + 'destroy': 'close' + }, + regions: { headerRegion: '.workspace-viewer-header', viewerRegion: '.workspace-viewer-container' diff --git a/server/sonar-web/src/test/js/workspace.js b/server/sonar-web/src/test/js/workspace.js index 873d6701b81..b27862533a8 100644 --- a/server/sonar-web/src/test/js/workspace.js +++ b/server/sonar-web/src/test/js/workspace.js @@ -24,21 +24,260 @@ var lib = require('../lib'), lib.initMessages(); +lib.changeWorkingDirectory('workspace'); lib.configureCasper(); -casper.test.begin(testName('API'), function (test) { +casper.test.begin(testName('Open From Component Viewer'), 8, function (test) { + casper + .start(lib.buildUrl('source-viewer'), function () { + lib.setDefaultViewport(); + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + window.localStorage.removeItem('sonarqube-workspace'); + require(['/js/source-viewer/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.source-line'); + }) + + .then(function () { + casper.click('.js-actions'); + casper.waitForSelector('.js-workspace', function () { + casper.click('.js-workspace'); + }); + }) + + .then(function () { + casper.waitForSelector('.workspace-viewer .source-line'); + }) + + .then(function () { + test.assertElementCount('.workspace-nav-item', 1); + test.assertSelectorContains('.workspace-nav-item', 'Cache.java'); + test.assertExists('.workspace-nav-item .icon-qualifier-fil'); + + test.assertSelectorContains('.workspace-viewer-name', 'Cache.java'); + test.assertExists('.workspace-viewer-name .icon-qualifier-fil'); + + test.assertExists('.workspace-viewer .source-viewer'); + test.assertElementCount('.workspace-viewer .source-line', 11); + }) + + .then(function () { + casper.click('.workspace-viewer .js-close'); + test.assertDoesntExist('.workspace-viewer'); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); + + +casper.test.begin(testName('Load From Local Storage'), 7, function (test) { casper .start(lib.buildUrl('nav'), function () { lib.setDefaultViewport(); + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + window.localStorage.setItem('sonarqube-workspace', + '[{"uuid":"12345","type":"component","name":"Cache.java","q":"FIL"}]'); + window.SS.isUserAdmin = false; + window.navbarOptions = new Backbone.Model(); + require(['/js/nav/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.workspace-nav-item'); + }) + + .then(function () { + test.assertElementCount('.workspace-nav-item', 1); + test.assertSelectorContains('.workspace-nav-item', 'Cache.java'); + test.assertExists('.workspace-nav-item .icon-qualifier-fil'); }) .then(function () { - test.assertNotEquals(casper.evaluate(function () { - window.workspace = require(['/js/workspace/main.js'])(); - console.log(window.workspace); - return window.workspace; - }), null); + casper.click('.workspace-nav-item'); + casper.waitForSelector('.workspace-viewer .source-line'); + }) + + .then(function () { + test.assertSelectorContains('.workspace-viewer-name', 'Cache.java'); + test.assertExists('.workspace-viewer-name .icon-qualifier-fil'); + + test.assertExists('.workspace-viewer .source-viewer'); + test.assertElementCount('.workspace-viewer .source-line', 11); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); + + +casper.test.begin(testName('Close From Nav'), 2, function (test) { + casper + .start(lib.buildUrl('nav'), function () { + lib.setDefaultViewport(); + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + window.localStorage.setItem('sonarqube-workspace', + '[{"uuid":"12345","type":"component","name":"Cache.java","q":"FIL"}]'); + window.SS.isUserAdmin = false; + window.navbarOptions = new Backbone.Model(); + require(['/js/nav/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.workspace-nav-item'); + }) + + .then(function () { + casper.click('.workspace-nav-item'); + casper.waitForSelector('.workspace-viewer .source-line'); + }) + + .then(function () { + casper.click('.workspace-nav-item .js-close'); + test.assertDoesntExist('.workspace-nav-item'); + test.assertDoesntExist('.workspace-viewer'); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); + + +casper.test.begin(testName('Minimize'), 2, function (test) { + casper + .start(lib.buildUrl('source-viewer'), function () { + lib.setDefaultViewport(); + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + window.localStorage.removeItem('sonarqube-workspace'); + require(['/js/source-viewer/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.source-line'); + }) + + .then(function () { + casper.click('.js-actions'); + casper.waitForSelector('.js-workspace', function () { + casper.click('.js-workspace'); + }); + }) + + .then(function () { + casper.waitForSelector('.workspace-viewer .source-line'); + }) + + .then(function () { + casper.click('.workspace-viewer .js-minimize'); + test.assertDoesntExist('.workspace-viewer'); + test.assertElementCount('.workspace-nav-item', 1); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); + + +casper.test.begin(testName('Full Screen'), 8, function (test) { + casper + .start(lib.buildUrl('source-viewer'), function () { + lib.setDefaultViewport(); + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + window.localStorage.removeItem('sonarqube-workspace'); + require(['/js/source-viewer/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.source-line'); + }) + + .then(function () { + casper.click('.js-actions'); + casper.waitForSelector('.js-workspace', function () { + casper.click('.js-workspace'); + }); + }) + + .then(function () { + casper.waitForSelector('.workspace-viewer .source-line'); + }) + + .then(function () { + test.assertVisible('.workspace-viewer .js-full-screen'); + test.assertNotVisible('.workspace-viewer .js-normal-size'); + + casper.click('.workspace-viewer .js-full-screen'); + test.assertExists('.workspace-viewer.workspace-viewer-full-screen'); + test.assertNotVisible('.workspace-viewer .js-full-screen'); + test.assertVisible('.workspace-viewer .js-normal-size'); + + casper.click('.workspace-viewer .js-normal-size'); + test.assertDoesntExist('.workspace-viewer.workspace-viewer-full-screen'); + test.assertVisible('.workspace-viewer .js-full-screen'); + test.assertNotVisible('.workspace-viewer .js-normal-size'); }) .then(function () { diff --git a/server/sonar-web/src/test/json/workspace/app.json b/server/sonar-web/src/test/json/workspace/app.json new file mode 100644 index 00000000000..e8b7516ee3c --- /dev/null +++ b/server/sonar-web/src/test/json/workspace/app.json @@ -0,0 +1,24 @@ +{ + "uuid": "12345", + "key": "org.codehaus.sonar:sonar-batch:src/main/java/org/sonar/batch/index/Cache.java", + "path": "src/main/java/org/sonar/batch/index/Cache.java", + "name": "Cache.java", + "longName": "src/main/java/org/sonar/batch/index/Cache.java", + "q": "FIL", + "subProject": "org.codehaus.sonar:sonar-batch", + "subProjectName": "SonarQube :: Batch", + "project": "org.codehaus.sonar:sonar", + "projectName": "SonarQube", + "fav": false, + "canMarkAsFavourite": false, + "canCreateManualIssue": false, + "measures": { + "lines": "378", + "coverage": "74.3%", + "duplicationDensity": "5.8%", + "debt": "2h 10min", + "sqaleRating": "A", + "debtRatio": "1.1%", + "issues": "6" + } +} diff --git a/server/sonar-web/src/test/json/workspace/issues.json b/server/sonar-web/src/test/json/workspace/issues.json new file mode 100644 index 00000000000..bc18adc855a --- /dev/null +++ b/server/sonar-web/src/test/json/workspace/issues.json @@ -0,0 +1,9 @@ +{ + "total": 0, + "p": 1, + "ps": 100, + "issues": [], + "rules": [], + "users": [], + "languages": [] +} diff --git a/server/sonar-web/src/test/json/workspace/lines.json b/server/sonar-web/src/test/json/workspace/lines.json new file mode 100644 index 00000000000..ff06641ec93 --- /dev/null +++ b/server/sonar-web/src/test/json/workspace/lines.json @@ -0,0 +1,72 @@ +{"sources": [ + { + "line": 1, + "code": "/*", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 2, + "code": " * SonarQube, open source software quality management tool.", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "b1436788cfc71b23cc3e3c15400a6c630c914bec", + "scmDate": "2013-04-21T11:58:14+0200" + }, + { + "line": 3, + "code": " * Copyright (C) 2008-2014 SonarSource", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "57ae3026c36ae3b0b71756d6161124b1ae594c53", + "scmDate": "2014-03-11T17:52:41+0100" + }, + { + "line": 4, + "code": " * mailto:contact AT sonarsource DOT com", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 5, + "code": " *", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 6, + "code": " * SonarQube is free software; you can redistribute it and/or", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "b1436788cfc71b23cc3e3c15400a6c630c914bec", + "scmDate": "2013-04-21T11:58:14+0200" + }, + { + "line": 7, + "code": " * modify it under the terms of the GNU Lesser General Public", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 8, + "code": " * License as published by the Free Software Foundation; either", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 9, + "code": " * version 3 of the License, or (at your option) any later version.", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + }, + { + "line": 10, + "code": " *", + "scmAuthor": "simon.brandhof@gmail.com", + "scmRevision": "26edff10d133e29e7013f803e7ef0d69ff593aeb", + "scmDate": "2013-04-16T17:26:34+0200" + } +]} 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 b8a8104addc..ae9f609567a 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2971,3 +2971,16 @@ analysis_reports.show_past_reports=Show Past Reports analysis_reports.current_activity=Current Activity analysis_reports.show_current_activity=Show Current Activity analysis_reports.x_reports={0} reports + + + + +#------------------------------------------------------------------------------ +# +# WORKSPACE +# +#------------------------------------------------------------------------------ +workspace.minimize=Minimize +workspace.full_window=Expand to full window +workspace.normal_size=Collapse to normal size +workspace.close=Remove from the list of pinned files -- 2.39.5