Browse Source

improve the web build system, introduce gulp and browserify

tags/5.3-RC1
Stas Vilchik 8 years ago
parent
commit
15b2160bab
100 changed files with 730 additions and 684 deletions
  1. 9
    10
      server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb
  2. 14
    15
      server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb
  3. 0
    2
      server/sonar-web/.eslintrc
  4. 0
    383
      server/sonar-web/Gruntfile.coffee
  5. 189
    0
      server/sonar-web/gulpfile.js
  6. 47
    28
      server/sonar-web/package.json
  7. 5
    5
      server/sonar-web/pom.xml
  8. 2
    1
      server/sonar-web/src/main/js/api/ce.js
  9. 13
    2
      server/sonar-web/src/main/js/api/nav.js
  10. 0
    0
      server/sonar-web/src/main/js/api/permissions.js
  11. 6
    3
      server/sonar-web/src/main/js/apps/account/app.js
  12. 2
    2
      server/sonar-web/src/main/js/apps/account/change-password-view.js
  13. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/action-view.js
  14. 6
    5
      server/sonar-web/src/main/js/apps/api-documentation/app.js
  15. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/filters-view.js
  16. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/header-view.js
  17. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/item-view.js
  18. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/layout.js
  19. 2
    2
      server/sonar-web/src/main/js/apps/api-documentation/search-view.js
  20. 4
    8
      server/sonar-web/src/main/js/apps/background-tasks/app.js
  21. 2
    2
      server/sonar-web/src/main/js/apps/background-tasks/main.js
  22. 9
    5
      server/sonar-web/src/main/js/apps/coding-rules/app.js
  23. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js
  24. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js
  25. 43
    0
      server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js
  26. 1
    1
      server/sonar-web/src/main/js/apps/coding-rules/controller.js
  27. 1
    1
      server/sonar-web/src/main/js/apps/coding-rules/facets-view.js
  28. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js
  29. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js
  30. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js
  31. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js
  32. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js
  33. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js
  34. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js
  35. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js
  36. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js
  37. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js
  38. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js
  39. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/filters-view.js
  40. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/layout.js
  41. 1
    1
      server/sonar-web/src/main/js/apps/coding-rules/models/state.js
  42. 8
    0
      server/sonar-web/src/main/js/apps/coding-rules/partials.js
  43. 4
    3
      server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js
  44. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js
  45. 7
    5
      server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js
  46. 4
    3
      server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js
  47. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js
  48. 5
    4
      server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js
  49. 5
    4
      server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js
  50. 4
    3
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js
  51. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js
  52. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js
  53. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js
  54. 5
    4
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js
  55. 2
    2
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js
  56. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js
  57. 5
    4
      server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js
  58. 3
    3
      server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js
  59. 18
    18
      server/sonar-web/src/main/js/apps/component-issues/app.js
  60. 5
    6
      server/sonar-web/src/main/js/apps/custom-measures/app.js
  61. 3
    3
      server/sonar-web/src/main/js/apps/custom-measures/delete-view.js
  62. 4
    4
      server/sonar-web/src/main/js/apps/custom-measures/form-view.js
  63. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/header-view.js
  64. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/layout.js
  65. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js
  66. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js
  67. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/list-view.js
  68. 152
    0
      server/sonar-web/src/main/js/apps/dashboard/app.js
  69. 5
    5
      server/sonar-web/src/main/js/apps/drilldown/app.js
  70. 8
    0
      server/sonar-web/src/main/js/apps/global-permissions/app.js
  71. 0
    11
      server/sonar-web/src/main/js/apps/global-permissions/app.jsx
  72. 4
    4
      server/sonar-web/src/main/js/apps/global-permissions/groups-view.js
  73. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/main.js
  74. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/permission-groups.js
  75. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.js
  76. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/permission-users.js
  77. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/permission.js
  78. 0
    0
      server/sonar-web/src/main/js/apps/global-permissions/permissions-list.js
  79. 4
    4
      server/sonar-web/src/main/js/apps/global-permissions/users-view.js
  80. 7
    6
      server/sonar-web/src/main/js/apps/groups/app.js
  81. 3
    3
      server/sonar-web/src/main/js/apps/groups/delete-view.js
  82. 3
    3
      server/sonar-web/src/main/js/apps/groups/form-view.js
  83. 2
    2
      server/sonar-web/src/main/js/apps/groups/header-view.js
  84. 2
    2
      server/sonar-web/src/main/js/apps/groups/layout.js
  85. 2
    2
      server/sonar-web/src/main/js/apps/groups/list-footer-view.js
  86. 2
    2
      server/sonar-web/src/main/js/apps/groups/list-item-view.js
  87. 0
    1
      server/sonar-web/src/main/js/apps/groups/list-view.js
  88. 2
    2
      server/sonar-web/src/main/js/apps/groups/search-view.js
  89. 4
    4
      server/sonar-web/src/main/js/apps/groups/users-view.js
  90. 9
    7
      server/sonar-web/src/main/js/apps/issues/app.js
  91. 1
    2
      server/sonar-web/src/main/js/apps/issues/component-viewer/main.js
  92. 1
    1
      server/sonar-web/src/main/js/apps/issues/controller.js
  93. 1
    1
      server/sonar-web/src/main/js/apps/issues/facets-view.js
  94. 2
    2
      server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js
  95. 2
    2
      server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js
  96. 3
    3
      server/sonar-web/src/main/js/apps/issues/facets/base-facet.js
  97. 2
    2
      server/sonar-web/src/main/js/apps/issues/facets/context-facet.js
  98. 2
    2
      server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js
  99. 2
    2
      server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js
  100. 0
    0
      server/sonar-web/src/main/js/apps/issues/facets/file-facet.js

+ 9
- 10
server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb View File

@@ -18,7 +18,7 @@

<div id="<%= container_id -%>"></div>
<script>
(function () {
jQuery(function () {
var query = '<%= filter.data -%>';

// do not show widget if the filter contains "my" criterion,
@@ -28,17 +28,16 @@
return;
}

require(['widgets/issue-filter/widget'], function (IssueFilter) {
window.requestMessages().done(function () {
new IssueFilter({
el: '#<%= container_id -%>',
query: query,
distributionAxis: '<%= distribution_axis -%>',
displayMode: '<%= display_mode -%>'
});
var IssueFilterWidget = require('issue-filter-widget');
window.requestMessages().done(function () {
new IssueFilterWidget({
el: '#<%= container_id -%>',
query: query,
distributionAxis: '<%= distribution_axis -%>',
displayMode: '<%= display_mode -%>'
});
});
})();
});
</script>

<% else %>

+ 14
- 15
server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb View File

@@ -24,7 +24,7 @@

<div id="<%= container_id -%>"></div>
<script>
(function () {
jQuery(function () {
var query = '<%= filter.data -%>';

// do not show widget if the filter contains "my" criterion,
@@ -34,22 +34,21 @@
return;
}

require(['widgets/issue-filter/widget'], function (IssueFilter) {
window.requestMessages().done(function () {
new IssueFilter({
el: '#<%= container_id -%>',
query: query,
distributionAxis: '<%= distribution_axis -%>',
displayMode: '<%= display_mode -%>',
<% if period_date %>
periodDate: '<%= period_date -%>',
<% end %>
componentUuid: '<%= @project.uuid -%>',
componentKey: '<%= @project.key -%>'
});
var IssueFilterWidget = require('issue-filter-widget');
window.requestMessages().done(function () {
new IssueFilterWidget({
el: '#<%= container_id -%>',
query: query,
distributionAxis: '<%= distribution_axis -%>',
displayMode: '<%= display_mode -%>',
<% if period_date %>
periodDate: '<%= period_date -%>',
<% end %>
componentUuid: '<%= @project.uuid -%>',
componentKey: '<%= @project.key -%>'
});
});
})();
});
</script>

<% else %>

+ 0
- 2
server/sonar-web/.eslintrc View File

@@ -188,8 +188,6 @@
"globals": {
"define": true,
"require": true,
"Templates": true,
"Handlebars": true,
"moment": true,
"numeral": true,
"key": true,

+ 0
- 383
server/sonar-web/Gruntfile.coffee View File

@@ -1,383 +0,0 @@
module.exports = (grunt) ->
require('jit-grunt')(grunt, {
unzip: 'grunt-zip'
replace: 'grunt-text-replace'
});
require('time-grunt')(grunt);

useBrowserStack = !!process.env['BROWSERSTACK_USERNAME'] && !!process.env['BROWSERSTACK_ACCESS_KEY']
expressPort = '<%= grunt.option("port") || 3000 %>'
internPort = '<%= grunt.option("internPort") || 9100 %>'

grunt.initConfig
pkg: grunt.file.readJSON('package.json')

SOURCE_PATH: './src/main'
ASSETS_PATH: grunt.option("assetsDir") || './src/main/webapp'
BUILD_PATH: './build'

less:
build:
options:
cleancss: true
files:
'<%= BUILD_PATH %>/css/sonar.css': [
'<%= SOURCE_PATH %>/less/jquery-ui.less'
'<%= SOURCE_PATH %>/less/select2.less'
'<%= SOURCE_PATH %>/less/select2-sonar.less'

'<%= SOURCE_PATH %>/less/init.less'
'<%= SOURCE_PATH %>/less/components.less'
'<%= SOURCE_PATH %>/less/pages.less'

'<%= SOURCE_PATH %>/less/style.less'

'<%= SOURCE_PATH %>/less/*.less'
]


babel:
build:
options:
modules: 'amd'
files: [
expand: true
cwd: '<%= SOURCE_PATH %>/js'
src: [
'**/*.jsx'
'**/api/**/*.js'
'**/apps/**/*.js'
'**/components/**/*.js'
]
dest: '<%= BUILD_PATH %>/js'
ext: '.js'
]


concat:
build:
files:
'<%= BUILD_PATH %>/js/sonar.js': [
'<%= BUILD_PATH %>/js/libs/translate.js'
'<%= BUILD_PATH %>/js/libs/third-party/jquery.js'
'<%= BUILD_PATH %>/js/libs/third-party/jquery-ui.js'
'<%= BUILD_PATH %>/js/libs/third-party/d3.js'
'<%= BUILD_PATH %>/js/libs/third-party/latinize.js'
'<%= BUILD_PATH %>/js/libs/third-party/underscore.js'
'<%= BUILD_PATH %>/js/libs/third-party/backbone.js'
'<%= BUILD_PATH %>/js/libs/third-party/backbone-super.js'
'<%= BUILD_PATH %>/js/libs/third-party/backbone.marionette.js'
'<%= BUILD_PATH %>/js/libs/third-party/handlebars.js'
'<%= BUILD_PATH %>/js/libs/third-party/select2.js'
'<%= BUILD_PATH %>/js/libs/third-party/keymaster.js'
'<%= BUILD_PATH %>/js/libs/third-party/moment.js'
'<%= BUILD_PATH %>/js/libs/third-party/numeral.js'
'<%= BUILD_PATH %>/js/libs/third-party/numeral-languages.js'
'<%= BUILD_PATH %>/js/libs/third-party/bootstrap/tooltip.js'
'<%= BUILD_PATH %>/js/libs/third-party/bootstrap/dropdown.js'
'<%= BUILD_PATH %>/js/libs/third-party/md5.js'
'<%= BUILD_PATH %>/js/libs/select2-jquery-ui-fix.js'

'<%= BUILD_PATH %>/js/libs/widgets/base.js'
'<%= BUILD_PATH %>/js/libs/widgets/widget.js'
'<%= BUILD_PATH %>/js/libs/widgets/bubble-chart.js'
'<%= BUILD_PATH %>/js/libs/widgets/timeline.js'
'<%= BUILD_PATH %>/js/libs/widgets/stack-area.js'
'<%= BUILD_PATH %>/js/libs/widgets/pie-chart.js'
'<%= BUILD_PATH %>/js/libs/widgets/histogram.js'
'<%= BUILD_PATH %>/js/libs/widgets/word-cloud.js'
'<%= BUILD_PATH %>/js/libs/widgets/tag-cloud.js'
'<%= BUILD_PATH %>/js/libs/widgets/treemap.js'

'<%= BUILD_PATH %>/js/libs/graphics/pie-chart.js'
'<%= BUILD_PATH %>/js/libs/graphics/barchart.js'
'<%= BUILD_PATH %>/js/libs/sortable.js'

'<%= BUILD_PATH %>/js/libs/inputs.js'
'<%= BUILD_PATH %>/js/libs/dialogs.js'
'<%= BUILD_PATH %>/js/libs/processes.js'
'<%= BUILD_PATH %>/js/libs/jquery-isolated-scroll.js'
'<%= BUILD_PATH %>/js/libs/handlebars-extensions.js'

'<%= BUILD_PATH %>/js/libs/application.js'
'<%= BUILD_PATH %>/js/libs/csv.js'
'<%= BUILD_PATH %>/js/libs/dashboard.js'
'<%= BUILD_PATH %>/js/libs/recent-history.js'
'<%= BUILD_PATH %>/js/libs/third-party/require.js'
]


requirejs:
options:
baseUrl: '<%= BUILD_PATH %>/js/'
preserveLicenseComments: false
paths:
'react': 'libs/third-party/react.min'
'underscore': 'libs/third-party/shim/underscore-shim'
'jquery': 'libs/third-party/shim/jquery-shim'
'backbone': 'libs/third-party/shim/backbone-shim'
'backbone.marionette': 'libs/third-party/shim/marionette-shim'
'moment': 'libs/third-party/shim/moment-shim'

issuesContext: options:
name: 'apps/issues/app-context'
out: '<%= ASSETS_PATH %>/js/apps/issues/app-context.js'

selectList: options:
name: 'components/common/select-list'
out: '<%= ASSETS_PATH %>/js/components/common/select-list.js'

app: options:
name: 'apps/<%= grunt.option("app") %>/app'
out: '<%= ASSETS_PATH %>/js/apps/<%= grunt.option("app") %>/app.js'

widget: options:
name: 'widgets/<%= grunt.option("widget") %>/widget'
out: '<%= ASSETS_PATH %>/js/widgets/<%= grunt.option("widget") %>/widget.js'


concurrent:
build:
tasks: [
'uglify:build'
# apps
'build-app:account'
'build-app:api-documentation'
'build-app:background-tasks'
'build-app:coding-rules'
'build-app:custom-measures'
'build-app:drilldown'
'build-app:global-permissions'
'build-app:groups'
'build-app:issues'
'build-app:maintenance'
'build-app:markdown'
'build-app:measures'
'build-app:metrics'
'build-app:nav'
'build-app:permission-templates'
'build-app:projects'
'build-app:project-permissions'
'build-app:quality-gates'
'build-app:quality-profiles'
'build-app:source-viewer'
'build-app:system'
'build-app:users'
'build-app:update-center'
# widgets
'build-widget:issue-filter'
# other
'requirejs:issuesContext'
'requirejs:selectList'
]


handlebars:
options:
namespace: 'Templates'
processName: (name) ->
pieces = name.split '/'
fileName = pieces[pieces.length - 1]
fileName.split('.')[0]
processPartialName: (name) ->
pieces = name.split '/'
fileName = pieces[pieces.length - 1]
fileName.split('.')[0]
build:
files:
'<%= BUILD_PATH %>/js/components/navigator/templates.js': [
'<%= SOURCE_PATH %>/js/components/navigator/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/coding-rules/templates.js': [
'<%= SOURCE_PATH %>/js/components/common/templates/**/*.hbs'
'<%= SOURCE_PATH %>/js/apps/coding-rules/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/quality-gates/templates.js': [
'<%= SOURCE_PATH %>/js/apps/quality-gates/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/quality-profiles/templates.js': [
'<%= SOURCE_PATH %>/js/apps/quality-profiles/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/components/source-viewer/templates.js': [
'<%= SOURCE_PATH %>/js/components/source-viewer/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/components/issue/templates.js': [
'<%= SOURCE_PATH %>/js/components/common/templates/**/*.hbs'
'<%= SOURCE_PATH %>/js/components/issue/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/issues/templates.js': [
'<%= SOURCE_PATH %>/js/apps/issues/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/api-documentation/templates.js': [
'<%= SOURCE_PATH %>/js/apps/api-documentation/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/nav/templates.js': [
'<%= SOURCE_PATH %>/js/apps/nav/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/widgets/issue-filter/templates.js': [
'<%= SOURCE_PATH %>/js/widgets/issue-filter/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/components/workspace/templates.js': [
'<%= SOURCE_PATH %>/js/components/workspace/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/markdown/templates.js': [
'<%= SOURCE_PATH %>/js/apps/markdown/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/users/templates.js': [
'<%= SOURCE_PATH %>/js/apps/users/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/groups/templates.js': [
'<%= SOURCE_PATH %>/js/apps/groups/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/metrics/templates.js': [
'<%= SOURCE_PATH %>/js/apps/metrics/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/maintenance/templates.js': [
'<%= SOURCE_PATH %>/js/apps/maintenance/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/account/templates.js': [
'<%= SOURCE_PATH %>/js/apps/account/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/update-center/templates.js': [
'<%= SOURCE_PATH %>/js/apps/update-center/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/custom-measures/templates.js': [
'<%= SOURCE_PATH %>/js/apps/custom-measures/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/global-permissions/templates.js': [
'<%= SOURCE_PATH %>/js/apps/global-permissions/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/project-permissions/templates.js': [
'<%= SOURCE_PATH %>/js/apps/project-permissions/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/permission-templates/templates.js': [
'<%= SOURCE_PATH %>/js/apps/permission-templates/templates/**/*.hbs'
]
'<%= BUILD_PATH %>/js/apps/projects/templates.js': [
'<%= SOURCE_PATH %>/js/apps/projects/templates/**/*.hbs'
]


clean:
options:
force: true
css: ['<%= ASSETS_PATH %>/css']
js: ['<%= ASSETS_PATH %>/js']
build: ['<%= BUILD_PATH %>']


copy:
js:
expand: true, cwd: '<%= SOURCE_PATH %>/js', src: ['**/*.js'], dest: '<%= BUILD_PATH %>/js'
'assets-js':
src: '<%= BUILD_PATH %>/js/sonar.js', dest: '<%= ASSETS_PATH %>/js/sonar.js'
'assets-all-js':
expand: true, cwd: '<%= BUILD_PATH %>/js', src: ['**/*.js'], dest: '<%= ASSETS_PATH %>/js'
'assets-css':
src: '<%= BUILD_PATH %>/css/sonar.css', dest: '<%= ASSETS_PATH %>/css/sonar.css'


uglify:
build:
src: '<%= ASSETS_PATH %>/js/sonar.js'
dest: '<%= ASSETS_PATH %>/js/sonar.js'


replace:
lcov:
src: 'target/web-tests/lcov.info'
dest: 'target/web-tests/lcov.info'
replacements: [
{ from: '/build/', to: '/src/main/' }
]


rename:
lcov:
src: 'lcov.info'
dest: 'target/web-tests/lcov.info'


intern:
test:
options:
runType: 'runner'
config: 'test/intern'
proxyPort: expressPort
proxyUrl: 'http://localhost:' + expressPort + '/'
useBrowserStack: useBrowserStack


watch:
options:
spawn: false

less:
files: '<%= SOURCE_PATH %>/less/**/*.less'
tasks: ['less:build', 'copy:assets-css']

js:
files: ['<%= SOURCE_PATH %>/js/**/*.js', '<%= SOURCE_PATH %>/js/**/*.jsx']
tasks: ['copy:js', 'babel:build', 'concat:build', 'copy:assets-all-js']

handlebars:
files: '<%= SOURCE_PATH %>/**/*.hbs'
tasks: ['handlebars:build', 'copy:assets-all-js']


# Basic tasks
grunt.registerTask 'prepare',
['clean:css', 'clean:js', 'clean:build', 'less:build', 'handlebars:build', 'copy:js', 'babel:build', 'concat:build']

grunt.registerTask 'build-fast-suffix',
['copy:assets-css', 'copy:assets-all-js']

grunt.registerTask 'build-suffix',
['copy:assets-css', 'copy:assets-js', 'concurrent:build']

grunt.registerTask 'test-suffix',
['intern:test', 'rename:lcov', 'replace:lcov']

grunt.registerTask 'coverage-suffix',
['test-suffix']

grunt.registerTask 'build-app', (app) ->
grunt.option 'app', app
grunt.task.run 'requirejs:app'

grunt.registerTask 'build-widget', (widget) ->
grunt.option 'widget', widget
grunt.task.run 'requirejs:widget'

# Output tasks
grunt.registerTask 'build-fast',
['prepare', 'build-fast-suffix']

grunt.registerTask 'build',
['prepare', 'build-suffix']

grunt.registerTask 'build-test',
['prepare', 'build-suffix', 'test-suffix']

grunt.registerTask 'build-coverage',
['prepare', 'build-suffix', 'coverage-suffix']

grunt.registerTask 'test',
['prepare', 'test-suffix']

grunt.registerTask 'coverage',
['prepare', 'coverage-suffix']

grunt.registerTask 'default',
['build']

# Development
grunt.registerTask 'dw',
['build-fast', 'watch']

# tasks used by Maven build (see pom.xml)
grunt.registerTask 'maven-quick-build',
['build-fast']

grunt.registerTask 'maven-build',
['build']

+ 189
- 0
server/sonar-web/gulpfile.js View File

@@ -0,0 +1,189 @@
var path = require('path');

var glob = require('glob');
var del = require('del');
var browserify = require('browserify');
var watchify = require('watchify');
var es = require('event-stream');

var gulp = require('gulp');
var buffer = require('vinyl-buffer');
var concat = require('gulp-concat');
var gulpif = require('gulp-if');
var less = require('gulp-less');
var minifyCss = require('gulp-minify-css');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');

var source = require('vinyl-source-stream');

var argv = require('yargs').argv;
var production = !argv.dev && !argv.fast;
var dev = !!argv.dev && !argv.fast;
var watch = !!argv.watch;
var output = argv.output || './src/main/webapp';


function getAppName (file) {
return file
.substr(0, file.length - 7)
.substr(17);
}


function doBrowserify (entry, sourceName, dest, customize) {
var bundler = browserify({
entries: [entry],
debug: dev,
cache: {},
packageCache: {}
});

// do all .require(), .external()
if (typeof customize === 'function') {
bundler = customize(bundler);
}

if (watch) {
bundler = watchify(bundler);
}

var rebundle = function (ids) {
if (ids) {
/* eslint no-console: 0 */
console.log(ids);
}
return bundler.bundle()
.pipe(source(sourceName))
.pipe(gulpif(production, buffer()))
.pipe(gulpif(production, uglify()))
.pipe(gulp.dest(path.join(output, dest)));
};

bundler.on('update', rebundle);

return rebundle();
}


gulp.task('scripts-sonar', function () {
return gulp.src([
'src/main/js/libs/translate.js',
'src/main/js/libs/third-party/jquery.js',
'src/main/js/libs/third-party/jquery-ui.js',
'src/main/js/libs/third-party/d3.js',
'src/main/js/libs/third-party/underscore.js',
'src/main/js/libs/third-party/select2.js',
'src/main/js/libs/third-party/keymaster.js',
'src/main/js/libs/third-party/moment.js',
'src/main/js/libs/third-party/numeral.js',
'src/main/js/libs/third-party/numeral-languages.js',
'src/main/js/libs/third-party/bootstrap/tooltip.js',
'src/main/js/libs/third-party/bootstrap/dropdown.js',
'src/main/js/libs/select2-jquery-ui-fix.js',

'src/main/js/libs/graphics/pie-chart.js',
'src/main/js/libs/graphics/barchart.js',
'src/main/js/libs/sortable.js',

'src/main/js/libs/inputs.js',
'src/main/js/libs/jquery-isolated-scroll.js',

'src/main/js/libs/application.js'
])
.pipe(concat('sonar.js'))
.pipe(gulpif(production, buffer()))
.pipe(gulpif(production, uglify()))
.pipe(gulp.dest(path.join(output, 'js')));
});


gulp.task('scripts-main', function () {
return doBrowserify(
'src/main/js/main/app.js',
'main.js',
'js/bundles',
function (bundle) {
return bundle
.require('react', { expose: 'react' })
.require('backbone', { expose: 'backbone' })
.require('backbone.marionette', { expose: 'backbone.marionette' });
});
});


gulp.task('scripts-apps', function (done) {
glob('src/main/js/apps/*/app.js', function (err, files) {
if (err) {
done(err);
}

var tasks = files.map(function (entry) {
return doBrowserify(
entry,
getAppName(entry) + '.js',
'js/bundles',
function (bundle) {
return bundle
.external('react')
.external('backbone')
.external('backbone.marionette');
}
);
});
es.merge(tasks).on('end', done);
});
});

gulp.task('scripts-widgets', function () {
return doBrowserify(
'src/main/js/widgets/widgets.js',
'widgets.js',
'js/bundles',
function (bundle) {
return bundle
.external('react')
.external('backbone')
.external('backbone.marionette')
.require('./src/main/js/widgets/issue-filter/widget.js', { expose: 'issue-filter-widget' });
});
});

gulp.task('styles', function () {
return gulp.src([
'src/main/less/jquery-ui.less',
'src/main/less/select2.less',
'src/main/less/select2-sonar.less',

'src/main/less/init.less',
'src/main/less/components.less',
'src/main/less/pages.less',

'src/main/less/style.less',

'src/main/less/*.less'
])
.pipe(gulpif(dev, sourcemaps.init()))
.pipe(less())
.pipe(gulpif(production, minifyCss()))
.pipe(concat('sonar.css'))
.pipe(gulpif(dev, sourcemaps.write({ includeContent: true })))
.pipe(gulp.dest(path.join(output, 'css')));
});

gulp.task('clean', function (done) {
del([
path.join(output, 'js'),
path.join(output, 'css')
], done);
});

gulp.task('scripts', ['scripts-sonar', 'scripts-main', 'scripts-apps', 'scripts-widgets']);

gulp.task('build', ['clean', 'scripts', 'styles'], function () {
if (watch) {
gulp.watch('src/main/less/**/*.less', ['styles']);
}
});

gulp.task('default', ['build']);

+ 47
- 28
server/sonar-web/package.json View File

@@ -5,40 +5,59 @@
"repository": "SonarSource/sonarqube",
"license": "LGPL-3.0",
"devDependencies": {
"babel": "^5.8.23",
"backbone": "^1.1.2",
"chai": "^3.3.0",
"grunt": "0.4.5",
"grunt-babel": "5.0.1",
"grunt-cli": "0.1.13",
"grunt-concurrent": "1.0.0",
"grunt-contrib-clean": "0.6.0",
"grunt-contrib-concat": "0.5.1",
"grunt-contrib-copy": "0.8.0",
"grunt-contrib-handlebars": "0.9.2",
"grunt-contrib-less": "1.0.1",
"grunt-contrib-requirejs": "0.4.4",
"grunt-contrib-uglify": "0.9.1",
"grunt-contrib-watch": "0.6.1",
"grunt-rename": "^0.1.4",
"grunt-text-replace": "0.4.0",
"babel": "5.8.23",
"babelify": "6.3.0",
"backbone": "1.2.3",
"backbone.marionette": "2.4.3",
"blueimp-md5": "1.1.1",
"browserify": "11.2.0",
"browserify-shim": "3.8.10",
"chai": "3.3.0",
"del": "2.0.2",
"event-stream": "3.3.1",
"glob": "5.0.15",
"gulp": "3.9.0",
"gulp-browserify": "0.5.1",
"gulp-concat": "2.6.0",
"gulp-if": "2.0.0",
"gulp-less": "3.0.3",
"gulp-minify-css": "1.2.1",
"gulp-rename": "1.2.2",
"gulp-sourcemaps": "1.6.0",
"gulp-uglify": "1.4.2",
"handlebars": "2.0.0",
"hbsfy": "2.3.1",
"intern": "3.0.0",
"isparta": "^3.0.4",
"jit-grunt": "0.9.1",
"isparta": "3.0.4",
"jquery": "2.1.4",
"jsdom": "^6.5.1",
"mocha": "^2.3.3",
"moment": "^2.10.6",
"jsdom": "6.5.1",
"mocha": "2.3.3",
"moment": "2.10.6",
"react": "0.13.3",
"sinon": "^1.15.4",
"sinon-chai": "^2.8.0",
"time-grunt": "1.2.1",
"underscore": "1.8.3"
"sinon": "1.15.4",
"sinon-chai": "2.8.0",
"underscore": "1.8.3",
"vinyl-buffer": "1.0.0",
"vinyl-source-stream": "1.1.0",
"watchify": "3.4.0",
"whatwg-fetch": "0.10.0",
"yargs": "3.27.0"
},
"scripts": {
"build-fast": "./node_modules/.bin/grunt build-fast",
"build": "./node_modules/.bin/grunt build",
"build-fast": "gulp --fast",
"build": "gulp",
"test": "./node_modules/.bin/mocha --opts tests/mocha.opts tests",
"coverage": "./node_modules/.bin/babel-node ./node_modules/.bin/isparta cover --dir './target/coverage' --include '**/*.js' --include '**/*.jsx' ./node_modules/.bin/_mocha -- --opts tests/mocha.opts tests"
},
"browserify-shim": {
"jquery": "global:jQuery",
"underscore": "global:_"
},
"browserify": {
"transform": [
"hbsfy",
"babelify",
"browserify-shim"
]
}
}

+ 5
- 5
server/sonar-web/pom.xml View File

@@ -15,7 +15,7 @@
<!-- self-analysis -->
<sonar.sources>src/main/js,src/main/less</sonar.sources>
<sonar.exclusions>src/main/js/libs/third-party/**/*,src/main/js/libs/require.js</sonar.exclusions>
<grunt.arguments>maven-build --no-color</grunt.arguments>
<npm.script>build</npm.script>
</properties>
<dependencies>
@@ -117,12 +117,12 @@
</execution>
<execution>
<phase>generate-resources</phase>
<id>grunt build</id>
<id>npm script</id>
<goals>
<goal>grunt</goal>
<goal>npm</goal>
</goals>
<configuration>
<arguments>${grunt.arguments}</arguments>
<arguments>run-script ${npm.script}</arguments>
</configuration>
</execution>
</executions>
@@ -222,7 +222,7 @@
<profile>
<id>dev</id>
<properties>
<grunt.arguments>maven-quick-build</grunt.arguments>
<npm.script>build-fast</npm.script>
</properties>
</profile>
</profiles>

+ 2
- 1
server/sonar-web/src/main/js/api/ce.js View File

@@ -27,5 +27,6 @@ export function cancelAllTasks () {

export function getTasksForComponent(componentId) {
let url = baseUrl + '/api/ce/component';
return $.get(url, { componentId });
let data = { componentId };
return new Promise((resolve) => $.get(url, data).done(resolve));
}

+ 13
- 2
server/sonar-web/src/main/js/api/nav.js View File

@@ -1,6 +1,17 @@
import $ from 'jquery';
import { getJSON } from '../helpers/request.js';

export function getGlobalNavigation () {
let url = baseUrl + '/api/navigation/global';
return $.get(url);
return getJSON(url);
}

export function getComponentNavigation (componentKey) {
let url = baseUrl + '/api/navigation/component';
let data = { componentKey };
return getJSON(url, data);
}

export function getSettingsNavigation () {
let url = baseUrl + '/api/navigation/settings';
return getJSON(url);
}

server/sonar-web/src/main/js/api/permissions.jsx → server/sonar-web/src/main/js/api/permissions.js View File


+ 6
- 3
server/sonar-web/src/main/js/apps/account/app.js View File

@@ -1,5 +1,6 @@
import $ from 'jquery';
import ChangePasswordView from './change-password-view';
import '../../helpers/handlebars-helpers';

var shouldShowAvatars = window.SS && window.SS.lf && window.SS.lf.enableGravatar;
var favorites = $('.js-account-favorites tr');
@@ -8,8 +9,8 @@ function showExtraFavorites () {
favorites.removeClass('hidden');
}

export default {
start: function () {
class App {
start () {
$('html').addClass('dashboard-page');

if (shouldShowAvatars) {
@@ -28,4 +29,6 @@ export default {
new ChangePasswordView().render();
});
}
};
}

window.sonarqube.appStarted.then(options => new App().start(options));

+ 2
- 2
server/sonar-web/src/main/js/apps/account/change-password-view.js View File

@@ -1,9 +1,9 @@
import $ from 'jquery';
import ModalForm from '../../components/common/modal-form';
import './templates';
import Template from './templates/account-change-password.hbs';

export default ModalForm.extend({
template: Templates['account-change-password'],
template: Template,

onFormSubmit: function (e) {
this._super(e);

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/action-view.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-action.hbs';

export default Marionette.ItemView.extend({
className: 'panel panel-vertical',
template: Templates['api-documentation-action'],
template: Template,

modelEvents: {
'change': 'render'

+ 6
- 5
server/sonar-web/src/main/js/apps/api-documentation/app.js View File

@@ -8,9 +8,12 @@ import List from './list';
import ListView from './list-view';
import FiltersView from './filters-view';
import SearchView from './search-view';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;

// State
this.state = new Backbone.Model({ internal: false });
this.state.match = function (test) {
@@ -61,9 +64,7 @@ var App = new Marionette.Application(),
};

App.on('start', function (options) {
window.requestMessages().done(function () {
init.call(App, options);
});
init.call(App, options);
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/filters-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-filters.hbs';

export default Marionette.ItemView.extend({
template: Templates['api-documentation-filters'],
template: Template,

events: {
'change .js-toggle-internal': 'toggleInternal'

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/header-view.js View File

@@ -1,8 +1,8 @@
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-header.hbs';

export default Marionette.ItemView.extend({
template: Templates['api-documentation-header'],
template: Template,

modelEvents: {
'change': 'render'

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/item-view.js View File

@@ -1,11 +1,11 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-web-service.hbs';

export default Marionette.ItemView.extend({
tagName: 'a',
className: 'list-group-item',
template: Templates['api-documentation-web-service'],
template: Template,

modelEvents: {
'change': 'render'

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/layout.js View File

@@ -1,8 +1,8 @@
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-layout.hbs';

export default Marionette.LayoutView.extend({
template: Templates['api-documentation-layout'],
template: Template,

regions: {
headerRegion: '.search-navigator-workspace-header',

+ 2
- 2
server/sonar-web/src/main/js/apps/api-documentation/search-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/api-documentation-search.hbs';

export default Marionette.ItemView.extend({
template: Templates['api-documentation-search'],
template: Template,

ui: {
input: '.search-box-input'

+ 4
- 8
server/sonar-web/src/main/js/apps/background-tasks/app.js View File

@@ -1,11 +1,7 @@
import React from 'react';
import Main from './main';

export default {
start (options) {
window.requestMessages().done(() => {
let el = document.querySelector(options.el);
React.render(<Main options={options}/>, el);
});
}
};
window.sonarqube.appStarted.then(options => {
let el = document.querySelector(options.el);
React.render(<Main options={options}/>, el);
});

+ 2
- 2
server/sonar-web/src/main/js/apps/background-tasks/main.js View File

@@ -29,8 +29,8 @@ export default React.createClass({
},

getComponentFilter() {
if (this.props.options.componentId) {
return { componentId: this.props.options.componentId };
if (this.props.options.component) {
return { componentId: this.props.options.component.id };
} else {
return {};
}

+ 9
- 5
server/sonar-web/src/main/js/apps/coding-rules/app.js View File

@@ -5,16 +5,20 @@ import Marionette from 'backbone.marionette';
import State from './models/state';
import Layout from './layout';
import Rules from './models/rules';
import Facets from 'components/navigator/models/facets';
import Facets from '../../components/navigator/models/facets';
import Controller from './controller';
import Router from 'components/navigator/router';
import Router from '../../components/navigator/router';
import WorkspaceListView from './workspace-list-view';
import WorkspaceHeaderView from './workspace-header-view';
import FacetsView from './facets-view';
import FiltersView from './filters-view';
import './partials';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;

this.layout = new Layout({ el: options.el });
this.layout.render();
$('#footer').addClass('search-navigator-footer');
@@ -92,9 +96,9 @@ var appXHR = $.get(baseUrl + '/api/rules/app').done(function (r) {
});

App.on('start', function (options) {
$.when(window.requestMessages(), appXHR).done(function () {
appXHR.done(function () {
init.call(App, options);
});
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));

+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import ModalFormView from 'components/common/modal-form';
import './templates';
import ModalFormView from '../../components/common/modal-form';
import Template from './templates/coding-rules-bulk-change-modal.hbs';

export default ModalFormView.extend({
template: Templates['coding-rules-bulk-change-modal'],
template: Template,

ui: function () {
return _.extend(ModalFormView.prototype.ui.apply(this, arguments), {

+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js View File

@@ -1,11 +1,11 @@
import $ from 'jquery';
import _ from 'underscore';
import PopupView from 'components/common/popup';
import PopupView from '../../components/common/popup';
import BulkChangeModalView from './bulk-change-modal-view';
import './templates';
import Template from './templates/coding-rules-bulk-change-popup.hbs';

export default PopupView.extend({
template: Templates['coding-rules-bulk-change-popup'],
template: Template,

events: {
'click .js-bulk-change': 'doAction'

+ 43
- 0
server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js View File

@@ -0,0 +1,43 @@
import $ from 'jquery';
import _ from 'underscore';

const DEFAULTS = {
title: 'Confirmation',
html: '',
yesLabel: 'Yes',
noLabel: 'Cancel',
yesHandler: function () {
// no op
},
noHandler: function () {
// no op
},
always: function () {
// no op
}
};

export default function (options) {
var settings = _.extend({}, DEFAULTS, options),
dialog = $('<div><div class="modal-head"><h2>' + settings.title + '</h2></div><div class="modal-body">' +
settings.html + '</div><div class="modal-foot"><button data-confirm="yes">' + settings.yesLabel +
'</button> <a data-confirm="no" class="action">' + settings.noLabel + '</a></div></div>');

$('[data-confirm=yes]', dialog).on('click', function () {
dialog.dialog('close');
settings.yesHandler();
return settings.always();
});

$('[data-confirm=no]', dialog).on('click', function () {
dialog.dialog('close');
settings.noHandler();
return settings.always();
});

return dialog.dialog({
modal: true,
minHeight: null,
width: 540
});
}

+ 1
- 1
server/sonar-web/src/main/js/apps/coding-rules/controller.js View File

@@ -1,6 +1,6 @@
import $ from 'jquery';
import _ from 'underscore';
import Controller from 'components/navigator/controller';
import Controller from '../../components/navigator/controller';
import Rule from './models/rule';
import RuleDetailsView from './rule-details-view';


+ 1
- 1
server/sonar-web/src/main/js/apps/coding-rules/facets-view.js View File

@@ -1,4 +1,4 @@
import FacetsView from 'components/navigator/facets-view';
import FacetsView from '../../components/navigator/facets-view';
import BaseFacet from './facets/base-facet';
import QueryFacet from './facets/query-facet';
import KeyFacet from './facets/key-facet';

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-severity-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-severity-facet'],
template: Template,
severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'],

initialize: function (options) {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-available-since-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-available-since-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/facets/base-facet.js View File

@@ -1,9 +1,9 @@
import BaseFacet from 'components/navigator/facets/base-facet';
import '../templates';
import BaseFacet from '../../../components/navigator/facets/base-facet';
import Template from '../templates/facets/coding-rules-base-facet.hbs';

export default BaseFacet.extend({
className: 'search-navigator-facet-box',
template: Templates['coding-rules-base-facet']
template: Template
});



+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/characteristic-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-characteristic-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-characteristic-facet'],
template: Template,

onRender: function () {
BaseFacet.prototype.onRender.apply(this, arguments);

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-custom-values-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-custom-values-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-inheritance-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-inheritance-facet'],
template: Template,

initialize: function (options) {
this.listenTo(options.app.state, 'change:query', this.onQueryChange);

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js View File

@@ -1,9 +1,9 @@
import BaseFacet from './base-facet';
import _ from 'underscore';
import '../templates';
import Template from '../templates/facets/coding-rules-key-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-key-facet'],
template: Template,

onRender: function () {
this.$el.toggleClass('hidden', !this.options.app.state.get('query').rule_key);

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-quality-profile-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-quality-profile-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-query-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-query-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-severity-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-severity-facet'],
template: Template,
severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'],

sortValues: function (values) {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js View File

@@ -1,9 +1,9 @@
import $ from 'jquery';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/coding-rules-template-facet.hbs';

export default BaseFacet.extend({
template: Templates['coding-rules-template-facet'],
template: Template,

onRender: function () {
BaseFacet.prototype.onRender.apply(this, arguments);

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/filters-view.js View File

@@ -1,10 +1,10 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import ManualRuleCreationView from './rule/manual-rule-creation-view';
import './templates';
import Template from './templates/coding-rules-filters.hbs';

export default Marionette.ItemView.extend({
template: Templates['coding-rules-filters'],
template: Template,

events: {
'click .js-create-manual-rule': 'createManualRule'

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/layout.js View File

@@ -1,9 +1,9 @@
import $ from 'jquery';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/coding-rules-layout.hbs';

export default Marionette.LayoutView.extend({
template: Templates['coding-rules-layout'],
template: Template,

regions: {
filtersRegion: '.search-navigator-filters',

+ 1
- 1
server/sonar-web/src/main/js/apps/coding-rules/models/state.js View File

@@ -1,4 +1,4 @@
import State from 'components/navigator/models/state';
import State from '../../../components/navigator/models/state';

export default State.extend({
defaults: {

+ 8
- 0
server/sonar-web/src/main/js/apps/coding-rules/partials.js View File

@@ -0,0 +1,8 @@
import Handlebars from 'hbsfy/runtime';
import ActivationPartial from './templates/_coding-rules-workspace-list-item-activation.hbs';
import FacetHeaderPartial from './templates/facets/_coding-rules-facet-header.hbs';
import MarkdownTipsPartial from '../../components/common/templates/_markdown-tips.hbs';

Handlebars.registerPartial('_coding-rules-workspace-list-item-activation', ActivationPartial);
Handlebars.registerPartial('_coding-rules-facet-header', FacetHeaderPartial);
Handlebars.registerPartial('_markdown-tips', MarkdownTipsPartial);

+ 4
- 3
server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js View File

@@ -11,11 +11,12 @@ import CustomRulesView from './rule/custom-rules-view';
import ManualRuleCreationView from './rule/manual-rule-creation-view';
import CustomRuleCreationView from './rule/custom-rule-creation-view';
import IssuesView from './rule/rule-issues-view';
import './templates';
import Template from './templates/coding-rules-rule-details.hbs';
import confirmDialog from './confirm-dialog';

export default Marionette.LayoutView.extend({
className: 'coding-rule-details',
template: Templates['coding-rules-rule-details'],
template: Template,

regions: {
metaRegion: '.js-rule-meta',
@@ -128,7 +129,7 @@ export default Marionette.LayoutView.extend({
deleteRule: function () {
var that = this,
ruleType = this.model.has('templateKey') ? 'custom' : 'manual';
window.confirmDialog({
confirmDialog({
title: t('delete'),
html: tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')),
yesHandler: function () {

+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import ActionOptionsView from 'components/common/action-options-view';
import './templates';
import ActionOptionsView from '../../components/common/action-options-view';
import Template from './templates/coding-rules-rule-filter-form.hbs';

export default ActionOptionsView.extend({
template: Templates['coding-rules-rule-filter-form'],
template: Template,

selectOption: function (e) {
var property = $(e.currentTarget).data('property'),

+ 7
- 5
server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js View File

@@ -1,10 +1,12 @@
import $ from 'jquery';
import _ from 'underscore';
import ModalFormView from 'components/common/modal-form';
import '../templates';
import ModalFormView from '../../../components/common/modal-form';
import Template from '../templates/rule/coding-rules-custom-rule-creation.hbs';
import {csvEscape} from '../../../helpers/csv';
import latinize from '../../../helpers/latinize';

export default ModalFormView.extend({
template: Templates['coding-rules-custom-rule-creation'],
template: Template,

ui: function () {
return _.extend(ModalFormView.prototype.ui.apply(this, arguments), {
@@ -38,7 +40,7 @@ export default ModalFormView.extend({

generateKey: function () {
if (!this.keyModifiedByUser && this.ui.customRuleCreationKey) {
var generatedKey = this.ui.customRuleCreationName.val().latinize().replace(/[^A-Za-z0-9]/g, '_');
var generatedKey = latinize(this.ui.customRuleCreationName.val()).replace(/[^A-Za-z0-9]/g, '_');
this.ui.customRuleCreationKey.val(generatedKey);
}
},
@@ -107,7 +109,7 @@ export default ModalFormView.extend({
};
}).get();
options.params = params.map(function (param) {
return param.key + '=' + window.csvEscape(param.value);
return param.key + '=' + csvEscape(param.value);
}).join(';');
this.sendRequest(action, options);
},

+ 4
- 3
server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js View File

@@ -1,11 +1,12 @@
import $ from 'jquery';
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import '../templates';
import Template from '../templates/rule/coding-rules-custom-rule.hbs';
import confirmDialog from '../confirm-dialog';

export default Marionette.ItemView.extend({
tagName: 'tr',
template: Templates['coding-rules-custom-rule'],
template: Template,

modelEvents: {
'change': 'render'
@@ -17,7 +18,7 @@ export default Marionette.ItemView.extend({

deleteRule: function () {
var that = this;
window.confirmDialog({
confirmDialog({
title: t('delete'),
html: t('are_you_sure'),
yesHandler: function () {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js View File

@@ -2,10 +2,10 @@ import _ from 'underscore';
import Marionette from 'backbone.marionette';
import CustomRuleView from './custom-rule-view';
import CustomRuleCreationView from './custom-rule-creation-view';
import '../templates';
import Template from '../templates/rule/coding-rules-custom-rules.hbs';

export default Marionette.CompositeView.extend({
template: Templates['coding-rules-custom-rules'],
template: Template,
childView: CustomRuleView,
childViewContainer: '#coding-rules-detail-custom-rules',


+ 5
- 4
server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js View File

@@ -1,10 +1,11 @@
import $ from 'jquery';
import _ from 'underscore';
import ModalFormView from 'components/common/modal-form';
import '../templates';
import ModalFormView from '../../../components/common/modal-form';
import Template from '../templates/rule/coding-rules-manual-rule-creation.hbs';
import latinize from '../../../helpers/latinize';

export default ModalFormView.extend({
template: Templates['coding-rules-manual-rule-creation'],
template: Template,

ui: function () {
return _.extend(ModalFormView.prototype.ui.apply(this.arguments), {
@@ -44,7 +45,7 @@ export default ModalFormView.extend({

generateKey: function () {
if (!this.keyModifiedByUser && this.ui.manualRuleCreationKey) {
var generatedKey = this.ui.manualRuleCreationName.val().latinize().replace(/[^A-Za-z0-9]/g, '_');
var generatedKey = latinize(this.ui.manualRuleCreationName.val()).replace(/[^A-Za-z0-9]/g, '_');
this.ui.manualRuleCreationKey.val(generatedKey);
}
},

+ 5
- 4
server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js View File

@@ -1,11 +1,12 @@
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import ModalForm from 'components/common/modal-form';
import '../templates';
import ModalForm from '../../../components/common/modal-form';
import Template from '../templates/rule/coding-rules-profile-activation.hbs';
import {csvEscape} from '../../../helpers/csv';

export default ModalForm.extend({
template: Templates['coding-rules-profile-activation'],
template: Template,

ui: function () {
return _.extend(this._super(), {
@@ -62,7 +63,7 @@ export default ModalForm.extend({
};
}).get(),
paramsHash = (params.map(function (param) {
return param.key + '=' + window.csvEscape(param.value);
return param.key + '=' + csvEscape(param.value);
})).join(';');

if (this.model) {

+ 4
- 3
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js View File

@@ -1,10 +1,11 @@
import $ from 'jquery';
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-description.hbs';
import confirmDialog from '../confirm-dialog';

export default Marionette.ItemView.extend({
template: Templates['coding-rules-rule-description'],
template: Template,

modelEvents: {
'change': 'render'
@@ -62,7 +63,7 @@ export default Marionette.ItemView.extend({

removeExtendedDescription: function () {
var that = this;
window.confirmDialog({
confirmDialog({
html: t('coding_rules.remove_extended_description.confirm'),
yesHandler: function () {
that.ui.extendDescriptionText.val('');

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-issues.hbs';

export default Marionette.ItemView.extend({
template: Templates['coding-rules-rule-issues'],
template: Template,

initialize: function () {
var that = this;

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js View File

@@ -2,10 +2,10 @@ import $ from 'jquery';
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import RuleFilterMixin from './rule-filter-mixin';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-meta.hbs';

export default Marionette.ItemView.extend(RuleFilterMixin).extend({
template: Templates['coding-rules-rule-meta'],
template: Template,

modelEvents: {
'change': 'render'

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-parameters.hbs';

export default Marionette.ItemView.extend({
template: Templates['coding-rules-rule-parameters'],
template: Template,

modelEvents: {
'change': 'render'

+ 5
- 4
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js View File

@@ -3,11 +3,12 @@ import _ from 'underscore';
import Backbone from 'backbone';
import Marionette from 'backbone.marionette';
import ProfileActivationView from './profile-activation-view';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-profile.hbs';
import confirmDialog from '../confirm-dialog';

export default Marionette.ItemView.extend({
tagName: 'tr',
template: Templates['coding-rules-rule-profile'],
template: Template,

modelEvents: {
'change': 'render'
@@ -48,7 +49,7 @@ export default Marionette.ItemView.extend({
revert: function () {
var that = this,
ruleKey = this.options.rule.get('key');
window.confirmDialog({
confirmDialog({
title: t('coding_rules.revert_to_parent_definition'),
html: tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name),
yesHandler: function () {
@@ -70,7 +71,7 @@ export default Marionette.ItemView.extend({
deactivate: function () {
var that = this,
ruleKey = this.options.rule.get('key');
window.confirmDialog({
confirmDialog({
title: t('coding_rules.deactivate'),
html: tp('coding_rules.deactivate.confirm'),
yesHandler: function () {

+ 2
- 2
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js View File

@@ -2,10 +2,10 @@ import _ from 'underscore';
import Marionette from 'backbone.marionette';
import ProfileView from './rule-profile-view';
import ProfileActivationView from './profile-activation-view';
import '../templates';
import Template from '../templates/rule/coding-rules-rule-profiles.hbs';

export default Marionette.CompositeView.extend({
template: Templates['coding-rules-rule-profiles'],
template: Template,
childView: ProfileView,
childViewContainer: '#coding-rules-detail-quality-profiles',


+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js View File

@@ -1,11 +1,11 @@
import $ from 'jquery';
import _ from 'underscore';
import WorkspaceHeaderView from 'components/navigator/workspace-header-view';
import WorkspaceHeaderView from '../../components/navigator/workspace-header-view';
import BulkChangePopup from './bulk-change-popup-view';
import './templates';
import Template from './templates/coding-rules-workspace-header.hbs';

export default WorkspaceHeaderView.extend({
template: Templates['coding-rules-workspace-header'],
template: Template,

events: function () {
return _.extend(WorkspaceHeaderView.prototype.events.apply(this, arguments), {

+ 5
- 4
server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js View File

@@ -1,14 +1,15 @@
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import WorkspaceListItemView from 'components/navigator/workspace-list-item-view';
import WorkspaceListItemView from '../../components/navigator/workspace-list-item-view';
import ProfileActivationView from './rule/profile-activation-view';
import RuleFilterMixin from './rule/rule-filter-mixin';
import './templates';
import Template from './templates/coding-rules-workspace-list-item.hbs';
import confirmDialog from './confirm-dialog';

export default WorkspaceListItemView.extend(RuleFilterMixin).extend({
className: 'coding-rule',
template: Templates['coding-rules-workspace-list-item'],
template: Template,

modelEvents: {
'change': 'render'
@@ -60,7 +61,7 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({
var that = this,
ruleKey = this.model.get('key'),
activation = this.model.get('activation');
window.confirmDialog({
confirmDialog({
title: t('coding_rules.deactivate'),
html: tp('coding_rules.deactivate.confirm'),
yesHandler: function () {

+ 3
- 3
server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js View File

@@ -1,10 +1,10 @@
import WorkspaceListView from 'components/navigator/workspace-list-view';
import WorkspaceListView from '../../components/navigator/workspace-list-view';
import WorkspaceListItemView from './workspace-list-item-view';
import WorkspaceListEmptyView from './workspace-list-empty-view';
import './templates';
import Template from './templates/coding-rules-workspace-list.hbs';

export default WorkspaceListView.extend({
template: Templates['coding-rules-workspace-list'],
template: Template,
childView: WorkspaceListItemView,
childViewContainer: '.js-list',
emptyView: WorkspaceListEmptyView,

server/sonar-web/src/main/js/apps/issues/app-context.js → server/sonar-web/src/main/js/apps/component-issues/app.js View File

@@ -2,20 +2,24 @@ import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import Marionette from 'backbone.marionette';
import State from './models/state';
import Layout from './layout';
import Issues from './models/issues';
import Facets from 'components/navigator/models/facets';
import Filters from './models/filters';
import Controller from './controller';
import Router from './router';
import WorkspaceListView from './workspace-list-view';
import WorkspaceHeaderView from './workspace-header-view';
import FacetsView from './facets-view';
import './helpers/format-facet-value';
import State from '../issues/models/state';
import Layout from '../issues/layout';
import Issues from '../issues/models/issues';
import Facets from '../../components/navigator/models/facets';
import Filters from '../issues/models/filters';
import Controller from '../issues/controller';
import Router from '../issues/router';
import WorkspaceListView from '../issues/workspace-list-view';
import WorkspaceHeaderView from '../issues/workspace-header-view';
import FacetsView from './../issues/facets-view';
import './../issues/helpers/format-facet-value';
import '../issues/partials';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;

this.config = options.config;
this.state = new State({
isContext: true,
@@ -87,11 +91,7 @@ App.updateContextFacets = function () {
};

App.on('start', function (options) {
$.when(window.requestMessages()).done(function () {
init.call(App, options);
});
init.call(App, options);
});

export default App;


window.sonarqube.appStarted.then(options => App.start(options));

+ 5
- 6
server/sonar-web/src/main/js/apps/custom-measures/app.js View File

@@ -4,6 +4,7 @@ import CustomMeasures from './custom-measures';
import HeaderView from './header-view';
import ListView from './list-view';
import ListFooterView from './list-footer-view';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
@@ -15,13 +16,13 @@ var App = new Marionette.Application(),

// Collection
this.customMeasures = new CustomMeasures({
projectId: options.projectId
projectId: options.component.id
});

// Header View
this.headerView = new HeaderView({
collection: this.customMeasures,
projectId: options.projectId
projectId: options.component.id
});
this.layout.headerRegion.show(this.headerView);

@@ -42,10 +43,8 @@ var App = new Marionette.Application(),
};

App.on('start', function (options) {
window.requestMessages().done(function () {
init.call(App, options);
});
init.call(App, options);
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));


+ 3
- 3
server/sonar-web/src/main/js/apps/custom-measures/delete-view.js View File

@@ -1,8 +1,8 @@
import ModalForm from 'components/common/modal-form';
import './templates';
import ModalForm from '../../components/common/modal-form';
import Template from './templates/custom-measures-delete.hbs';

export default ModalForm.extend({
template: Templates['custom-measures-delete'],
template: Template,

onFormSubmit: function (e) {
this._super(e);

+ 4
- 4
server/sonar-web/src/main/js/apps/custom-measures/form-view.js View File

@@ -1,10 +1,10 @@
import _ from 'underscore';
import ModalForm from 'components/common/modal-form';
import Metrics from 'apps/metrics/metrics';
import './templates';
import ModalForm from '../../components/common/modal-form';
import Metrics from '../metrics/metrics';
import Template from './templates/custom-measures-form.hbs';

export default ModalForm.extend({
template: Templates['custom-measures-form'],
template: Template,

initialize: function () {
this.metrics = new Metrics();

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/header-view.js View File

@@ -1,9 +1,9 @@
import Marionette from 'backbone.marionette';
import CreateView from './create-view';
import './templates';
import Template from './templates/custom-measures-header.hbs';

export default Marionette.ItemView.extend({
template: Templates['custom-measures-header'],
template: Template,

events: {
'click #custom-measures-create': 'onCreateClick'

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/layout.js View File

@@ -1,8 +1,8 @@
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/custom-measures-layout.hbs';

export default Marionette.LayoutView.extend({
template: Templates['custom-measures-layout'],
template: Template,

regions: {
headerRegion: '#custom-measures-header',

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/custom-measures-list-footer.hbs';

export default Marionette.ItemView.extend({
template: Templates['custom-measures-list-footer'],
template: Template,

collectionEvents: {
'all': 'render'

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js View File

@@ -1,11 +1,11 @@
import Marionette from 'backbone.marionette';
import UpdateView from './update-view';
import DeleteView from './delete-view';
import './templates';
import Template from './templates/custom-measures-list-item.hbs';

export default Marionette.ItemView.extend({
tagName: 'tr',
template: Templates['custom-measures-list-item'],
template: Template,

events: {
'click .js-custom-measure-update': 'onUpdateClick',

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/list-view.js View File

@@ -1,9 +1,9 @@
import Marionette from 'backbone.marionette';
import ListItemView from './list-item-view';
import './templates';
import Template from './templates/custom-measures-list.hbs';

export default Marionette.CompositeView.extend({
template: Templates['custom-measures-list'],
template: Template,
childView: ListItemView,
childViewContainer: 'tbody'
});

+ 152
- 0
server/sonar-web/src/main/js/apps/dashboard/app.js View File

@@ -0,0 +1,152 @@
import $ from 'jquery';

window.Portal = function (options) {
this.initialize(options);
};

window.Portal.prototype = {

initialize: function (options) {
this.options = options;
if (!this.options.editorEnabled) {
return;
}
this.createAllSortables();
this.lastSaveString = '';
this.saveDashboardsState();
},


createAllSortables: function () {
var that = this,
blocks = $('.' + this.options.block),
columnHandle = $('.' + this.options.columnHandle),
draggable,

onDragLeave = function (e) {
$(e.currentTarget).removeClass(that.options.hoverClass);
},

onDrop = function (e) {
e.preventDefault();
draggable.detach().insertBefore($(e.currentTarget));
onDragLeave(e);
that.saveDashboardsState();
};

blocks
.prop('draggable', true)
.on('selectstart', function () {
this.dragDrop();
return false;
})
.on('dragstart', function (e) {
e.originalEvent.dataTransfer.setData('Text', 'drag');
draggable = $(this);
columnHandle.show();
})
.on('dragover', function (e) {
if (draggable.prop('id') !== $(this).prop('id')) {
e.preventDefault();
$(e.currentTarget).addClass(that.options.hoverClass);
}
})
.on('drop', onDrop)
.on('dragleave', onDragLeave);

columnHandle
.on('dragover', function (e) {
e.preventDefault();
$(e.currentTarget).addClass(that.options.hoverClass);
})
.on('drop', onDrop)
.on('dragleave', onDragLeave);
},


highlightWidget: function (widgetId) {
var block = $('#block_' + widgetId),
options = this.options;
block.css('background-color', options.highlightStartColor);
setTimeout(function () {
block.css('background-color', options.highlightEndColor);
}, this.options.highlightDuration);
},


saveDashboardsState: function () {
var options = this.options,
result = $('.' + this.options.column).map(function () {
var blocks = $(this).find('.' + options.block);
$(this).find('.' + options.columnHandle).toggle(blocks.length === 0);

return blocks.map(function () {
return $(this).prop('id').substring(options.block.length + 1);
}).get().join(',');
}).get().join(';');

if (result === this.lastSaveString) {
return;
}

var firstTime = this.lastSaveString === '';
this.lastSaveString = result;

if (firstTime) {
return;
}

if (this.options.saveUrl) {
var postBody = this.options.dashboardState + '=' + encodeURIComponent(result);

$.ajax({
url: this.options.saveUrl,
type: 'POST',
data: postBody
});
}
},


editWidget: function (widgetId) {
$('#widget_title_' + widgetId).hide();
$('#widget_' + widgetId).hide();
$('#widget_props_' + widgetId).show();
$($('#block_' + widgetId + ' a.link-action')[0]).hide();
},


cancelEditWidget: function (widgetId) {
$('widget_title_' + widgetId).show();
$('#widget_' + widgetId).show();
$('#widget_props_' + widgetId).hide();
$($('#block_' + widgetId + ' a.link-action')[0]).show();
},


deleteWidget: function (element) {
$(element).closest('.' + this.options.block).remove();
this.saveDashboardsState();
}
};


window.autoResize = function (everyMs, callback) {
var debounce = _.debounce(callback, everyMs);
$(window).on('resize', debounce);
};


$(function () {
var $sidebar = jQuery('#sidebar');
if ($sidebar.length > 0) {
var $window = jQuery(window),
topOffset = $sidebar.offset().top;
$window.on('scroll', function () {
var scrollTop = $window.scrollTop(),
scrollLeft = $window.scrollLeft();
$sidebar.toggleClass('sticky', scrollTop > topOffset);
$sidebar.css('left', -scrollLeft + 10);
});
}
});

+ 5
- 5
server/sonar-web/src/main/js/apps/drilldown/app.js View File

@@ -1,9 +1,11 @@
import $ from 'jquery';
import Marionette from 'backbone.marionette';
import SourceViewer from '../../components/source-viewer/main';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;
App.addRegions({ viewerRegion: options.el });
$('.js-drilldown-link').on('click', function (e) {
e.preventDefault();
@@ -22,9 +24,7 @@ var App = new Marionette.Application(),
};

App.on('start', function (options) {
window.requestMessages().done(function () {
init.call(App, options);
});
init.call(App, options);
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));

+ 8
- 0
server/sonar-web/src/main/js/apps/global-permissions/app.js View File

@@ -0,0 +1,8 @@
import React from 'react';
import Main from './main';
import '../../helpers/handlebars-helpers';

window.sonarqube.appStarted.then(options => {
var el = document.querySelector(options.el);
React.render(<Main/>, el);
});

+ 0
- 11
server/sonar-web/src/main/js/apps/global-permissions/app.jsx View File

@@ -1,11 +0,0 @@
import React from 'react';
import Main from './main';

export default {
start(options) {
window.requestMessages().done(() => {
var el = document.querySelector(options.el);
React.render(<Main/>, el);
});
}
};

+ 4
- 4
server/sonar-web/src/main/js/apps/global-permissions/groups-view.js View File

@@ -1,6 +1,6 @@
import Modal from 'components/common/modals';
import 'components/common/select-list';
import './templates';
import Modal from '../../components/common/modals';
import Template from './templates/global-permissions-groups.hbs';
import '../../components/common/select-list';

function getSearchUrl (permission, project) {
var url = baseUrl + '/api/permissions/groups?ps=100&permission=' + permission;
@@ -19,7 +19,7 @@ function getExtra (permission, project) {
}

export default Modal.extend({
template: Templates['global-permissions-groups'],
template: Template,

onRender: function () {
this._super();

server/sonar-web/src/main/js/apps/global-permissions/main.jsx → server/sonar-web/src/main/js/apps/global-permissions/main.js View File


server/sonar-web/src/main/js/apps/global-permissions/permission-groups.jsx → server/sonar-web/src/main/js/apps/global-permissions/permission-groups.js View File


server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.jsx → server/sonar-web/src/main/js/apps/global-permissions/permission-users-groups-mixin.js View File


server/sonar-web/src/main/js/apps/global-permissions/permission-users.jsx → server/sonar-web/src/main/js/apps/global-permissions/permission-users.js View File


server/sonar-web/src/main/js/apps/global-permissions/permission.jsx → server/sonar-web/src/main/js/apps/global-permissions/permission.js View File


server/sonar-web/src/main/js/apps/global-permissions/permissions-list.jsx → server/sonar-web/src/main/js/apps/global-permissions/permissions-list.js View File


+ 4
- 4
server/sonar-web/src/main/js/apps/global-permissions/users-view.js View File

@@ -1,6 +1,6 @@
import Modal from 'components/common/modals';
import 'components/common/select-list';
import './templates';
import Modal from '../../components/common/modals';
import Template from './templates/global-permissions-users.hbs';
import '../../components/common/select-list';

function getSearchUrl (permission, project) {
var url = baseUrl + '/api/permissions/users?ps=100&permission=' + permission;
@@ -19,7 +19,7 @@ function getExtra (permission, project) {
}

export default Modal.extend({
template: Templates['global-permissions-users'],
template: Template,

onRender: function () {
this._super();

+ 7
- 6
server/sonar-web/src/main/js/apps/groups/app.js View File

@@ -5,9 +5,12 @@ import HeaderView from './header-view';
import SearchView from './search-view';
import ListView from './list-view';
import ListFooterView from './list-footer-view';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;

// Layout
this.layout = new Layout({ el: options.el });
this.layout.render();
@@ -35,12 +38,10 @@ var App = new Marionette.Application(),
this.groups.fetch();
};

App.on('start', function (options) {
window.requestMessages().done(function () {
init.call(App, options);
});
App.on('start', function () {
init.call(App);
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));



+ 3
- 3
server/sonar-web/src/main/js/apps/groups/delete-view.js View File

@@ -1,8 +1,8 @@
import ModalForm from 'components/common/modal-form';
import './templates';
import ModalForm from '../../components/common/modal-form';
import Template from './templates/groups-delete.hbs';

export default ModalForm.extend({
template: Templates['groups-delete'],
template: Template,

onFormSubmit: function (e) {
this._super(e);

+ 3
- 3
server/sonar-web/src/main/js/apps/groups/form-view.js View File

@@ -1,8 +1,8 @@
import ModalForm from 'components/common/modal-form';
import './templates';
import ModalForm from '../../components/common/modal-form';
import Template from './templates/groups-form.hbs';

export default ModalForm.extend({
template: Templates['groups-form'],
template: Template,

onRender: function () {
this._super();

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/header-view.js View File

@@ -1,9 +1,9 @@
import Marionette from 'backbone.marionette';
import CreateView from './create-view';
import './templates';
import Template from './templates/groups-header.hbs';

export default Marionette.ItemView.extend({
template: Templates['groups-header'],
template: Template,

events: {
'click #groups-create': 'onCreateClick'

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/layout.js View File

@@ -1,8 +1,8 @@
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/groups-layout.hbs';

export default Marionette.LayoutView.extend({
template: Templates['groups-layout'],
template: Template,

regions: {
headerRegion: '#groups-header',

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/list-footer-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/groups-list-footer.hbs';

export default Marionette.ItemView.extend({
template: Templates['groups-list-footer'],
template: Template,

collectionEvents: {
'all': 'render'

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/list-item-view.js View File

@@ -3,12 +3,12 @@ import Marionette from 'backbone.marionette';
import UpdateView from './update-view';
import DeleteView from './delete-view';
import UsersView from './users-view';
import './templates';
import Template from './templates/groups-list-item.hbs';

export default Marionette.ItemView.extend({
tagName: 'li',
className: 'panel panel-vertical',
template: Templates['groups-list-item'],
template: Template,

events: {
'click .js-group-update': 'onUpdateClick',

+ 0
- 1
server/sonar-web/src/main/js/apps/groups/list-view.js View File

@@ -1,6 +1,5 @@
import Marionette from 'backbone.marionette';
import ListItemView from './list-item-view';
import './templates';

export default Marionette.CollectionView.extend({
tagName: 'ul',

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/search-view.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import Marionette from 'backbone.marionette';
import './templates';
import Template from './templates/groups-search.hbs';

export default Marionette.ItemView.extend({
template: Templates['groups-search'],
template: Template,

events: {
'submit #groups-search-form': 'onFormSubmit',

+ 4
- 4
server/sonar-web/src/main/js/apps/groups/users-view.js View File

@@ -1,9 +1,9 @@
import Modal from 'components/common/modals';
import 'components/common/select-list';
import './templates';
import Modal from '../../components/common/modals';
import '../../components/common/select-list';
import Template from './templates/groups-users.hbs';

export default Modal.extend({
template: Templates['groups-users'],
template: Template,

onRender: function () {
this._super();

+ 9
- 7
server/sonar-web/src/main/js/apps/issues/app.js View File

@@ -4,7 +4,7 @@ import Marionette from 'backbone.marionette';
import State from './models/state';
import Layout from './layout';
import Issues from './models/issues';
import Facets from 'components/navigator/models/facets';
import Facets from '../../components/navigator/models/facets';
import Filters from './models/filters';
import Controller from './controller';
import Router from './router';
@@ -13,9 +13,13 @@ import WorkspaceHeaderView from './workspace-header-view';
import FacetsView from './facets-view';
import FiltersView from './filters-view';
import './helpers/format-facet-value';
import './partials';
import '../../helpers/handlebars-helpers';

var App = new Marionette.Application(),
init = function (options) {
init = function () {
let options = window.sonarqube;

this.state = new State();
this.list = new Issues();
this.facets = new Facets();
@@ -59,12 +63,10 @@ var App = new Marionette.Application(),
});
};

App.on('start', function (options) {
$.when(window.requestMessages()).done(function () {
init.call(App, options);
});
App.on('start', function () {
init.call(App);
});

export default App;
window.sonarqube.appStarted.then(options => App.start(options));



+ 1
- 2
server/sonar-web/src/main/js/apps/issues/component-viewer/main.js View File

@@ -1,8 +1,7 @@
import $ from 'jquery';
import _ from 'underscore';
import SourceViewer from 'components/source-viewer/main';
import SourceViewer from '../../../components/source-viewer/main';
import IssueView from './issue-view';
import '../templates';

export default SourceViewer.extend({
events: function () {

+ 1
- 1
server/sonar-web/src/main/js/apps/issues/controller.js View File

@@ -1,7 +1,7 @@
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import Controller from 'components/navigator/controller';
import Controller from '../../components/navigator/controller';
import ComponentViewer from './component-viewer/main';
import HomeView from './workspace-home-view';


+ 1
- 1
server/sonar-web/src/main/js/apps/issues/facets-view.js View File

@@ -1,4 +1,4 @@
import FacetsView from 'components/navigator/facets-view';
import FacetsView from '../../components/navigator/facets-view';
import BaseFacet from './facets/base-facet';
import SeverityFacet from './facets/severity-facet';
import StatusFacet from './facets/status-facet';

+ 2
- 2
server/sonar-web/src/main/js/apps/issues/facets/action-plan-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/issues-action-plan-facet.hbs';

export default BaseFacet.extend({
template: Templates['issues-action-plan-facet'],
template: Template,

onRender: function () {
BaseFacet.prototype.onRender.apply(this, arguments);

+ 2
- 2
server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import CustomValuesFacet from './custom-values-facet';
import '../templates';
import Template from '../templates/facets/issues-assignee-facet.hbs';

export default CustomValuesFacet.extend({
template: Templates['issues-assignee-facet'],
template: Template,

getUrl: function () {
return baseUrl + '/api/users/search';

+ 3
- 3
server/sonar-web/src/main/js/apps/issues/facets/base-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from 'components/navigator/facets/base-facet';
import '../templates';
import BaseFacet from '../../../components/navigator/facets/base-facet';
import Template from '../templates/facets/issues-base-facet.hbs';

export default BaseFacet.extend({
template: Templates['issues-base-facet'],
template: Template,

onRender: function () {
BaseFacet.prototype.onRender.apply(this, arguments);

+ 2
- 2
server/sonar-web/src/main/js/apps/issues/facets/context-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/issues-context-facet.hbs';

export default BaseFacet.extend({
template: Templates['issues-context-facet'],
template: Template,

serializeData: function () {
return _.extend(BaseFacet.prototype.serializeData.apply(this, arguments), {

+ 2
- 2
server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js View File

@@ -1,10 +1,10 @@
import $ from 'jquery';
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/issues-creation-date-facet.hbs';

export default BaseFacet.extend({
template: Templates['issues-creation-date-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 2
- 2
server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js View File

@@ -1,9 +1,9 @@
import _ from 'underscore';
import BaseFacet from './base-facet';
import '../templates';
import Template from '../templates/facets/issues-custom-values-facet.hbs';

export default BaseFacet.extend({
template: Templates['issues-custom-values-facet'],
template: Template,

events: function () {
return _.extend(BaseFacet.prototype.events.apply(this, arguments), {

+ 0
- 0
server/sonar-web/src/main/js/apps/issues/facets/file-facet.js View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save