diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2014-08-12 16:43:48 +0600 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2014-08-12 16:43:55 +0600 |
commit | 1ca0cfca4d9e7c5c1a45c09a6b59912b93f21273 (patch) | |
tree | 3de3bd1b63b544e9a54f3e81400ce1fdbd12f9be /server/sonar-web | |
parent | 2d6a169ec764e30415520ddb51d15506a0727501 (diff) | |
download | sonarqube-1ca0cfca4d9e7c5c1a45c09a6b59912b93f21273.tar.gz sonarqube-1ca0cfca4d9e7c5c1a45c09a6b59912b93f21273.zip |
SONAR-4406 The first shot of a new design page
Diffstat (limited to 'server/sonar-web')
8 files changed, 307 insertions, 0 deletions
diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee index f905e6201af..6221292a235 100644 --- a/server/sonar-web/Gruntfile.coffee +++ b/server/sonar-web/Gruntfile.coffee @@ -198,6 +198,10 @@ module.exports = (grunt) -> name: 'component-viewer/app' out: '<%= pkg.assets %>build/js/component-viewer/app.js' + design: options: + name: 'design/app' + out: '<%= pkg.assets %>build/js/design/app.js' + handlebars: options: @@ -237,6 +241,9 @@ module.exports = (grunt) -> '<%= pkg.assets %>js/templates/api-documentation.js': [ '<%= pkg.sources %>hbs/api-documentation/**/*.hbs' ] + '<%= pkg.assets %>js/templates/design.js': [ + '<%= pkg.sources %>hbs/design/**/*.hbs' + ] clean: diff --git a/server/sonar-web/src/main/coffee/design/app.coffee b/server/sonar-web/src/main/coffee/design/app.coffee new file mode 100644 index 00000000000..278196d65ed --- /dev/null +++ b/server/sonar-web/src/main/coffee/design/app.coffee @@ -0,0 +1,51 @@ +requirejs.config + baseUrl: "#{baseUrl}/js" + + paths: + 'backbone': 'third-party/backbone' + 'backbone.marionette': 'third-party/backbone.marionette' + 'handlebars': 'third-party/handlebars' + + shim: + 'backbone.marionette': + deps: ['backbone'] + exports: 'Marionette' + 'backbone': + exports: 'Backbone' + 'handlebars': + exports: 'Handlebars' + + +requirejs [ + 'backbone', 'backbone.marionette' + 'design/view' + 'common/handlebars-extensions' +], ( + Backbone, Marionette + DesignView +) -> + + $ = jQuery + RESOURCES_URL = "#{baseUrl}/api/resources" + App = new Marionette.Application + + + App.addInitializer -> + $.get RESOURCES_URL, resource: window.resourceKey, metrics: 'dsm', (rawData) -> + data = JSON.parse rawData[0].msr[0].data + data.forEach (row, rowIndex) -> + row.v.forEach (cell, columnIndex) -> + if cell.w? && cell.w > 0 + if rowIndex < columnIndex + cell.status = 'cycle' + else + cell.status = 'dependency' + @view = new DesignView app: @, collection: new Backbone.Collection data + $('#project-design').empty().append @view.render().el + + + # Message bundles + l10nXHR = window.requestMessages() + + + jQuery.when(l10nXHR).done -> App.start() diff --git a/server/sonar-web/src/main/coffee/design/view.coffee b/server/sonar-web/src/main/coffee/design/view.coffee new file mode 100644 index 00000000000..6d788a39bbb --- /dev/null +++ b/server/sonar-web/src/main/coffee/design/view.coffee @@ -0,0 +1,58 @@ +define [ + 'backbone.marionette', + 'templates/design' +], ( + Marionette, + Templates +) -> + + $ = jQuery + + + + class AppLayout extends Marionette.Layout + template: Templates['design'] + className: 'dsm' + + + ui: + titles: '.dsm-body-title' + + + events: + 'click @ui.titles': 'highlightComponent' + + + highlightComponent: (e) -> + e.preventDefault() + index = @ui.titles.index $(e.currentTarget) + @$('.dsm-body-highlighted').removeClass 'dsm-body-highlighted' + @$('.dsm-body-usage').removeClass 'dsm-body-usage' + @$('.dsm-body-dependency').removeClass 'dsm-body-dependency' + @highlightRow index + @highlightColumn index + @highlightUsages index + @highlightDependencies index + + + + highlightRow: (index) -> + @$(".dsm-body tr:eq(#{index}) td").addClass 'dsm-body-highlighted' + + + highlightColumn: (index) -> + @$(".dsm-body tr").each -> + $(this).find("td:eq(#{index + 1})").addClass 'dsm-body-highlighted' + + + highlightUsages: (index) -> + @collection.at(index).get('v').forEach (d, i) => + if i < index && d.w? + @$("tr:eq(#{i})").addClass 'dsm-body-usage' + + + highlightDependencies: (index) -> + @collection.forEach (model, i) => + if model.get('v')[index].w? + @$("tr:eq(#{i})").addClass 'dsm-body-dependency' + diff --git a/server/sonar-web/src/main/hbs/design/design.hbs b/server/sonar-web/src/main/hbs/design/design.hbs new file mode 100644 index 00000000000..cbb30d4f668 --- /dev/null +++ b/server/sonar-web/src/main/hbs/design/design.hbs @@ -0,0 +1,45 @@ +<div class="dsm-header"> + <i class="icon-help"></i> <a href="http://docs.codehaus.org/x/QQFhC">{{t 'help'}}</a> +</div> + +<ul class="dsm-legend"> + <li> + <span class="dsm-legend-square gray"></span> + <span class="dsm-legend-label">Dependency</span> + </li> + <li> + <span class="dsm-legend-square red"></span> + <span class="dsm-legend-label">Suspect dependency (cycle)</span> + </li> + <li> + <span class="dsm-legend-square green"></span> + <span class="dsm-legend-label">uses</span> + <span class="dsm-legend-square blue"></span> + <span class="dsm-legend-label">uses</span> + <span class="dsm-legend-square yellow"></span> + </li> +</ul> + +<div class="dsm-body"> + <table> + <tbody> + {{#each items}} + <tr> + <td> + <a class="dsm-body-title"> + {{qualifierIcon q}} {{n}} + <span class="dsm-body-title-indicator"></span> + </a> + </td> + {{#each v}} + <td> + <div class="dsm-body-cell {{#if status}}dsm-body-cell-{{status}}{{/if}}"> + {{w}} + </div> + </td> + {{/each}} + </tr> + {{/each}} + </tbody> + </table> +</div> diff --git a/server/sonar-web/src/main/less/dsm.less b/server/sonar-web/src/main/less/dsm.less new file mode 100644 index 00000000000..5f7d1ef8511 --- /dev/null +++ b/server/sonar-web/src/main/less/dsm.less @@ -0,0 +1,93 @@ +@import (reference) 'variables'; +@import (reference) 'mixins'; +@import (reference) 'ui'; + +@cellSize: 18px; + +.dsm { + +} + + +.dsm-legend { + margin: 10px 0; + + & > li { + display: inline-block; + } + + & > li + li { + margin-left: 20px; + } +} + +.dsm-legend-square { + display: inline-block; + vertical-align: middle; + .size(14px, 14px); + + &.gray { background-color: @grey; } + &.red { background-color: @red; } + &.green { background-color: @green; } + &.blue { background-color: @blue; } + &.yellow { background-color: @orange; } +} + +.dsm-legend-label { + display: inline-block; + vertical-align: middle; + font-size: @baseFontSize; +} + + +.dsm-body { + td { + padding: 4px; + border: 1px solid @barBorderColor; + .trans(background-color); + } +} + +.dsm-body-title { + position: relative; + display: block; + height: @cellSize + 8px; + line-height: @cellSize + 8px; + margin: -4px; + padding: 0 15px 0 5px; + color: @baseFontColor; + .link-no-underline; + + &:hover, &:focus { background-color: @barBackgroundColor; } +} + +.dsm-body-title-indicator { + position: absolute; + top: 0; right: 0; + .size(10px, 26px); + + .dsm-body-usage & { background-color: @green; } + .dsm-body-dependency & { background-color: @orange; } + .dsm-body-usage.dsm-body-dependency & { background-color: @red; } +} + +.dsm-body-cell { + min-width: @cellSize; + height: @cellSize; + line-height: @cellSize; + padding: 0 2px; + .box-sizing(border-box); + text-align: center; +} + +.dsm-body-cell-dependency { background-color: @grey; } +.dsm-body-cell-cycle { background-color: @red; color: #fff; } + +.dsm-body-highlighted { + background-color: @lightBlue; + + .dsm-body-title:hover, + .dsm-body-title:focus { + background-color: @lightBlue; + } +} diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/design_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/design_controller.rb new file mode 100644 index 00000000000..7ab8c83c379 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/design_controller.rb @@ -0,0 +1,39 @@ +# +# 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. +# +class DesignController < ApplicationController + + SECTION=Navigation::SECTION_RESOURCE + before_filter :load_resource + + def index + + end + + + private + + def load_resource + @resource=Project.by_key(params[:id]) + return redirect_to(home_path) unless @resource + access_denied unless has_role?(:admin, @resource) + @snapshot=@resource.last_snapshot + end + +end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/design/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/design/index.html.erb new file mode 100644 index 00000000000..b3cc6bdd839 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/design/index.html.erb @@ -0,0 +1,11 @@ +<% content_for :script do %> + <script data-main="<%= ApplicationController.root_context -%>/js/design/app" src="<%= ApplicationController.root_context -%>/js/require.js"></script> + <script> + window.resourceKey = '<%= @resource.key -%>'; + </script> +<% end %> + + +<div id="project-design"> + <i class="spinner"></i> +</div> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 934cb04c518..f200186bcb2 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -105,6 +105,9 @@ <a href="<%= ApplicationController.root_context -%><%= page_url -%>"><%= h message(page.getId() + '.page', :default => page.getTitle()) -%></a> </li> <% end %> + <li class="<%= 'active' if request.request_uri.include?('/design/index') -%>"> + <a href="<%= ApplicationController.root_context -%>/design/index/<%= @project.key -%>">Design (NEW)</a> + </li> <% if controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'comparable') %> <li class="<%= 'active' if request.request_uri.include?('/comparison/index') -%>"> <a href="<%= ApplicationController.root_context -%>/comparison/index?resource=<%= @project.key -%>"><%= message('comparison.page') -%></a> |