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:
'<%= 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:
--- /dev/null
+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()
--- /dev/null
+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'
+
--- /dev/null
+<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>
--- /dev/null
+@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;
+ }
+}
--- /dev/null
+#
+# 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
--- /dev/null
+<% 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>
<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>
filter_verb=Filter
follow=Follow
global=Global
+help=Help
hide=Hide
identifier_abbreviated=Id
inactive=Inactive