aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-04-20 17:31:42 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-04-21 15:40:34 +0200
commite2d3ac164a708d812f54d577592d9745d78f696c (patch)
tree85d49d6ecdd4aa4e681565214e0d540c77d2be25
parent9f71c4524a534a1e3307d8863b5874d10fc71a00 (diff)
downloadsonarqube-e2d3ac164a708d812f54d577592d9745d78f696c.tar.gz
sonarqube-e2d3ac164a708d812f54d577592d9745d78f696c.zip
refactor "Web Service API" page
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/app.coffee83
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/collections/web-service-actions.coffee33
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/collections/web-services.coffee47
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/layout.coffee52
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/models/web-service-action-response.coffee26
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/models/web-service-action.coffee23
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/models/web-service.coffee27
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/router.coffee50
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-response-view.coffee29
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-view.coffee53
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-actions-list-view.coffee40
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-list-view.coffee39
-rw-r--r--server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-web-service-view.coffee49
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-action-response.hbs1
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs118
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-actions.hbs5
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-filters.hbs6
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-header.hbs1
-rw-r--r--server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs13
-rw-r--r--server/sonar-web/src/main/js/api-documentation/action-view.js58
-rw-r--r--server/sonar-web/src/main/js/api-documentation/actions-view.js62
-rw-r--r--server/sonar-web/src/main/js/api-documentation/app.js87
-rw-r--r--server/sonar-web/src/main/js/api-documentation/controller.js93
-rw-r--r--server/sonar-web/src/main/js/api-documentation/filters-view.js46
-rw-r--r--server/sonar-web/src/main/js/api-documentation/header-view.js32
-rw-r--r--server/sonar-web/src/main/js/api-documentation/item-view.js59
-rw-r--r--server/sonar-web/src/main/js/api-documentation/layout.js45
-rw-r--r--server/sonar-web/src/main/js/api-documentation/list-view.js42
-rw-r--r--server/sonar-web/src/main/js/api-documentation/list.js42
-rw-r--r--server/sonar-web/src/main/js/api-documentation/router.js37
-rw-r--r--server/sonar-web/src/main/less/components/badges.less1
-rw-r--r--server/sonar-web/src/main/less/init/misc.less5
-rw-r--r--server/sonar-web/src/main/less/pages.less1
-rw-r--r--server/sonar-web/src/main/less/pages/api-documentation.less108
-rw-r--r--server/sonar-web/src/main/less/style.less4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb11
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb2
-rw-r--r--server/sonar-web/src/test/js/api-documentation-spec.js240
-rw-r--r--server/sonar-web/src/test/json/api-documentation/list.json52
-rw-r--r--server/sonar-web/src/test/json/api-documentation/response-example.json4
-rw-r--r--server/sonar-web/src/test/views/api_documentation.jade5
41 files changed, 1001 insertions, 730 deletions
diff --git a/server/sonar-web/src/main/coffee/api-documentation/app.coffee b/server/sonar-web/src/main/coffee/api-documentation/app.coffee
deleted file mode 100644
index ec6713598e1..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/app.coffee
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# 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.
-#
-
-requirejs.config
- baseUrl: "#{baseUrl}/js"
-
-requirejs [
- 'api-documentation/collections/web-services',
- 'api-documentation/views/api-documentation-list-view',
- 'api-documentation/router',
- 'api-documentation/layout'
-], (
- WebServices,
- ApiDocumentationListView,
- ApiDocumentationRouter,
- ApiDocumentationLayout
-) ->
-
- # Create a Quality Gate Application
- App = new Marionette.Application
-
- App.webServices = new WebServices
-
- App.openFirstWebService = ->
- if @webServices.length > 0
- @router.navigate "#{@webServices.models[0].get('path')}", trigger: true
- else
- App.layout.detailsRegion.reset()
-
- App.refresh = ->
- App.apiDocumentationListView = new ApiDocumentationListView
- collection: App.webServices
- app: App
- App.layout.resultsRegion.show App.apiDocumentationListView
- if (Backbone.history.fragment)
- App.router.show Backbone.history.fragment, trigger: true
-
- # Construct layout
- App.addInitializer ->
- @layout = new ApiDocumentationLayout app: App
- jQuery('#api-documentation').append @layout.render().el
- jQuery('#footer').addClass 'search-navigator-footer'
-
- # Construct sidebar
- App.addInitializer ->
- App.refresh()
-
- # Start router
- App.addInitializer ->
- @router = new ApiDocumentationRouter app: @
- Backbone.history.start()
-
- # Open first Web Service when page is opened
- App.addInitializer ->
- initial = Backbone.history.fragment == ''
- App.openFirstWebService() if initial
-
- webServicesXHR = App.webServices.fetch()
-
- jQuery.when(webServicesXHR)
- .done ->
- # Remove the initial spinner
- jQuery('#api-documentation-page-loader').remove()
-
- # Start the application
- App.start()
diff --git a/server/sonar-web/src/main/coffee/api-documentation/collections/web-service-actions.coffee b/server/sonar-web/src/main/coffee/api-documentation/collections/web-service-actions.coffee
deleted file mode 100644
index 810fc534ddf..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/collections/web-service-actions.coffee
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/models/web-service-action'
-], (
- WebServiceAction
-) ->
-
- class WebServiceActions extends Backbone.Collection
- model: WebServiceAction
- comparator: 'key'
-
- initialize: (models, options) ->
- _.each models, (model) ->
- model.path = options.path + '/' + model.key
diff --git a/server/sonar-web/src/main/coffee/api-documentation/collections/web-services.coffee b/server/sonar-web/src/main/coffee/api-documentation/collections/web-services.coffee
deleted file mode 100644
index 8829c43a7da..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/collections/web-services.coffee
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/models/web-service'
-], (
- WebService
-) ->
-
- class WebServices extends Backbone.Collection
- model: WebService
- comparator: 'path'
-
- initialize: ->
- @includeInternals = false
-
- url: ->
- "#{baseUrl}/api/webservices/list?include_internals=#{@includeInternals}"
-
- parse: (r) ->
- r.webServices.map (webService) ->
- _.extend webService
-
- toggleInternals: ->
- if @includeInternals
- @includeInternals = false
- else
- @includeInternals = true
-
- @fetch()
diff --git a/server/sonar-web/src/main/coffee/api-documentation/layout.coffee b/server/sonar-web/src/main/coffee/api-documentation/layout.coffee
deleted file mode 100644
index 60eb8a53a0f..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/layout.coffee
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'templates/api-documentation'
-], ->
-
- $ = jQuery
-
- class extends Marionette.Layout
- template: Templates['api-documentation-layout']
-
-
- regions:
- resultsRegion: '.api-documentation-results'
- detailsRegion: '.search-navigator-workspace'
-
-
- events:
- 'change #api-documentation-show-internals': 'toggleInternals'
-
-
- initialize: (app) ->
- @app = app.app
- @listenTo(@app.webServices, 'sync', @app.refresh)
-
-
- onRender: ->
- $('.search-navigator').addClass 'sticky'
- top = $('.search-navigator').offset().top
- @$('.search-navigator-side').css({ top: top }).isolatedScroll()
-
-
- toggleInternals: (event) ->
- @app.webServices.toggleInternals()
diff --git a/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action-response.coffee b/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action-response.coffee
deleted file mode 100644
index 8a467304229..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action-response.coffee
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define ->
-
- class WebServiceActionResponse extends Backbone.Model
-
- url: ->
- "#{baseUrl}/api/webservices/response_example?controller=#{@get('controller')}&action=#{@get('action')}"
diff --git a/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action.coffee b/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action.coffee
deleted file mode 100644
index 435792da7bf..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/models/web-service-action.coffee
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define ->
-
- class WebServiceAction extends Backbone.Model
diff --git a/server/sonar-web/src/main/coffee/api-documentation/models/web-service.coffee b/server/sonar-web/src/main/coffee/api-documentation/models/web-service.coffee
deleted file mode 100644
index e7a846ca4be..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/models/web-service.coffee
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define ->
-
- class WebService extends Backbone.Model
- idAttribute: 'path'
-
- initialize: (options) ->
- @set 'internal', _.every options.actions, (action) -> action.internal
diff --git a/server/sonar-web/src/main/coffee/api-documentation/router.coffee b/server/sonar-web/src/main/coffee/api-documentation/router.coffee
deleted file mode 100644
index c7f726ce559..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/router.coffee
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/collections/web-service-actions',
- 'api-documentation/views/api-documentation-actions-list-view',
-], (
- WebServiceActions,
- ApiDocumentationActionsListView
-) ->
-
- class ApiDocumentationRouter extends Backbone.Router
-
- routes:
- '*path': 'show'
-
-
- initialize: (options) ->
- @app = options.app
-
-
- show: (path) ->
- webService = @app.webServices.get path
- if webService
- @app.apiDocumentationListView.highlight path
-
- actions = new WebServiceActions webService.get('actions'), path: path
- actionsListView = new ApiDocumentationActionsListView
- app: @app
- collection: actions
- model: webService
-
- @app.layout.detailsRegion.show actionsListView
diff --git a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-response-view.coffee b/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-response-view.coffee
deleted file mode 100644
index 78ea94374e4..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-response-view.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'templates/api-documentation'
-], ->
-
- class ApiDocumentationActionResponseView extends Marionette.ItemView
- tagName: 'div'
- className: 'example-response-content'
- template: Templates['api-documentation-action-response']
- spinner: '<i class="spinner"></i>'
diff --git a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-view.coffee b/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-view.coffee
deleted file mode 100644
index 03cbf03ee43..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-view.coffee
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/models/web-service-action-response'
- 'api-documentation/views/api-documentation-action-response-view'
- 'templates/api-documentation'
-], (
- WebServiceActionResponse,
- ApiDocumentationActionResponseView
-) ->
-
- class ApiDocumentationActionView extends Marionette.ItemView
- className: 'api-documentation-action'
- template: Templates['api-documentation-action']
- spinner: '<i class="spinner"></i>'
-
- ui:
- displayLink: '.example-response'
-
- fetchExampleResponse: (event) ->
- exampleResponse = new WebServiceActionResponse
- controller: @model.get('path').substring(0, @model.get('path').length - @model.get('key').length - 1)
- action: @model.get('key')
- @listenTo(exampleResponse, 'change', @appendExampleView)
- exampleResponse.fetch()
-
- appendExampleView: (model) ->
- @ui.displayLink.hide()
- exampleView = new ApiDocumentationActionResponseView
- model: model
- exampleView.render()
- @$el.append exampleView.$el
-
- events:
- 'click .example-response': 'fetchExampleResponse'
diff --git a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-actions-list-view.coffee b/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-actions-list-view.coffee
deleted file mode 100644
index c5435a26b8b..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-actions-list-view.coffee
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/models/web-service-action'
- 'api-documentation/views/api-documentation-action-view'
- 'templates/api-documentation'
-], (
- WebServiceAction,
- ApiDocumentationActionView
-) ->
-
- $ = jQuery
-
- class extends Marionette.CompositeView
- className: 'api-documentation-actions'
- template: Templates['api-documentation-actions']
- itemView: ApiDocumentationActionView
- itemViewContainer: '.search-navigator-workspace-list'
-
- onRender: ->
- top = $('.search-navigator').offset().top
- @$('.search-navigator-workspace-header').css top: top
diff --git a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-list-view.coffee b/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-list-view.coffee
deleted file mode 100644
index 0ffeaaf7d49..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-list-view.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/views/api-documentation-web-service-view'
-], (
- ApiDocumentationWebServiceView
-) ->
-
- class extends Marionette.CollectionView
- className: 'list-group'
- itemView: ApiDocumentationWebServiceView
-
-
- itemViewOptions: (model) ->
- app: @options.app
- highlighted: model.get('path') == @highlighted
-
-
- highlight: (path) ->
- @highlighted = path
- @render()
diff --git a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-web-service-view.coffee b/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-web-service-view.coffee
deleted file mode 100644
index 226895ee88f..00000000000
--- a/server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-web-service-view.coffee
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 3 of the License, or (at your option) any later version.
-#
-# SonarQube is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-define [
- 'api-documentation/collections/web-service-actions'
- 'api-documentation/views/api-documentation-actions-list-view'
- 'templates/api-documentation'
-], (
- WebServiceActions,
- ApiDocumentationActionsListView
-) ->
-
- class extends Marionette.ItemView
- tagName: 'a'
- className: 'list-group-item'
- template: Templates['api-documentation-web-service']
-
-
- modelEvents:
- 'change': 'render'
-
-
- events:
- 'click': 'showWebService'
-
-
- onRender: ->
- @$el.toggleClass 'active', @options.highlighted
-
-
- showWebService: ->
- @options.app.router.navigate "#{@model.get('path')}", trigger: true
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action-response.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action-response.hbs
deleted file mode 100644
index 6253a6eb8d8..00000000000
--- a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action-response.hbs
+++ /dev/null
@@ -1 +0,0 @@
-<code>{{example}}</code> \ No newline at end of file
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs
index 656e2e7d7c3..e92501d5fb2 100644
--- a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs
+++ b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs
@@ -1,51 +1,75 @@
-<h3 class="big">
- {{#if post}}POST{{else}}GET{{/if}}
- {{path}}
-</h3>
-<span class="note">
- {{#if since}}Since {{since}}{{#if internal}} -{{/if}}{{/if}}
- {{#if internal}}<span class="badge">For internal use only</span>{{/if}}
-</span>
-<p>{{{description}}}</p>
+<header class="page-header">
+ <h3 class="page-title big">{{#if post}}POST{{else}}GET{{/if}} {{path}}/{{key}}</h3>
+
+ <div class="page-actions">
+ {{#if internal}}
+ <span class="badge spacer-right">internal</span>
+ {{/if}}
+ {{#if since}}
+ <span class="note spacer-right">Since {{since}}</span>
+ {{/if}}
+
+ <a class="js-permalink icon-link" href="{{link '/api_documentation/' path '/' key}}" target="_blank"></a>
+ </div>
+</header>
+
+<div class="markdown">{{{description}}}</div>
+
{{#if params}}
-<h3>Parameters</h3>
-<table>
- {{#each params}}
- <tr>
- <td style="width:10em">
- <code>{{key}}</code>
- <div class="note">{{#if required}}required{{else}}optional{{/if}}</div>
- </td>
- <td>
- <p>{{{description}}}</p>
-
- {{#if possibleValues}}
- <p>
- <em>Possible values:</em>
- <ul class="possible-values">
- {{#each possibleValues}}
- <li><code>{{this}}</code></li>
- {{/each}}
- </ul>
- </p>
- {{/if}}
-
- {{#if defaultValue}}
- <p>
- <em>Default value:</em> <code>{{defaultValue}}</code>
- </p>
- {{/if}}
-
- {{#if exampleValue}}
- <p>
- <em>Example value:</em> <code>{{exampleValue}}</code>
- </p>
- {{/if}}
- </td>
- </tr>
- {{/each}}
-</table>
+ <h4 class="spacer-top little-spacer-bottom">Parameters</h4>
+ <table class="width-100 data zebra">
+ {{#each params}}
+ <tr>
+ <td style="width: 10em;">
+ <code>{{key}}</code>
+ <div class="note">{{#if required}}required{{else}}optional{{/if}}</div>
+ </td>
+ <td>
+ <div class="markdown">{{{description}}}</div>
+
+ {{#if possibleValues}}
+ <ul class="list-inline little-spacer-top">
+ <li>
+ <strong>Possible values:</strong>
+ </li>
+ {{#each possibleValues}}
+ <li>
+ <code>{{this}}</code>
+ </li>
+ {{/each}}
+ </ul>
+ {{/if}}
+
+ {{#if defaultValue}}
+ <p class="little-spacer-top">
+ <strong>Default value:</strong> <code>{{defaultValue}}</code>
+ </p>
+ {{/if}}
+
+ {{#if exampleValue}}
+ <p class="little-spacer-top">
+ <strong>Example value:</strong> <code>{{exampleValue}}</code>
+ </p>
+ {{/if}}
+ </td>
+ </tr>
+ {{/each}}
+ </table>
{{/if}}
+
{{#if hasResponseExample}}
-<p><a name="example-key" class="example-response">Example response</a></p>
+ <h4 class="spacer-top">
+ Example Response
+ {{#unless responseExample}}
+ <a class="js-show-response-example little-spacer-left" href="#">Show</a>
+ {{/unless}}
+ </h4>
+
+ {{#if responseExample}}
+ <div class="little-spacer-top">
+ <pre>
+{{responseExample}}
+ </pre>
+ </div>
+ {{/if}}
{{/if}}
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-actions.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-actions.hbs
deleted file mode 100644
index 6c03ebefd07..00000000000
--- a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-actions.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-<div class="search-navigator-workspace-header">
- <h2 class="search-navigator-header-component">{{path}}</h2>
-</div>
-
-<div class="search-navigator-workspace-list"></div>
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-filters.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-filters.hbs
new file mode 100644
index 00000000000..5941110db0a
--- /dev/null
+++ b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-filters.hbs
@@ -0,0 +1,6 @@
+<h1 class="page-title">Web Service API</h1>
+
+<div class="page-actions">
+ <input class="js-toggle-internal" type="checkbox" id="api-documentation-show-internal" {{#if state.internal}}checked{{/if}}>
+ <label for="api-documentation-show-internal">Show Internal</label>
+</div>
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-header.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-header.hbs
new file mode 100644
index 00000000000..b652f85c9d4
--- /dev/null
+++ b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-header.hbs
@@ -0,0 +1 @@
+<h2 class="search-navigator-header-component">{{path}}</h2>
diff --git a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs
index 2527222fad2..4ef38c51b11 100644
--- a/server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs
+++ b/server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs
@@ -1,12 +1,9 @@
<div class="search-navigator-side search-navigator-side-light">
- <div class="search-navigator-filters">
- <h1 class="page-title">Web Service API</h1>
- <div class="page-actions">
- <input id="api-documentation-show-internals" type="checkbox">
- <label for="api-documentation-show-internals">Show Internals</label>
- </div>
- </div>
+ <div class="search-navigator-filters"></div>
<div class="api-documentation-results panel"></div>
</div>
-<div class="search-navigator-workspace"></div>
+<div class="search-navigator-workspace">
+ <div class="search-navigator-workspace-header"></div>
+ <div class="search-navigator-workspace-details"></div>
+</div>
diff --git a/server/sonar-web/src/main/js/api-documentation/action-view.js b/server/sonar-web/src/main/js/api-documentation/action-view.js
new file mode 100644
index 00000000000..fd972e14613
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/action-view.js
@@ -0,0 +1,58 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'templates/api-documentation'
+], function () {
+
+ var $ = jQuery;
+
+ return Marionette.ItemView.extend({
+ className: 'panel panel-vertical',
+ template: Templates['api-documentation-action'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ events: {
+ 'click .js-show-response-example': 'onShowResponseExampleClick'
+ },
+
+ onRender: function () {
+ this.$el.attr('data-web-service', this.model.get('path'));
+ this.$el.attr('data-action', this.model.get('key'));
+ },
+
+ onShowResponseExampleClick: function (e) {
+ e.preventDefault();
+ this.fetchResponse();
+ },
+
+ fetchResponse: function () {
+ var that = this,
+ url = baseUrl + '/api/webservices/response_example',
+ options = { controller: this.model.get('path'), action: this.model.get('key') };
+ return $.get(url, options).done(function (r) {
+ that.model.set({ responseExample: r.example });
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/actions-view.js b/server/sonar-web/src/main/js/api-documentation/actions-view.js
new file mode 100644
index 00000000000..04d9cbccb76
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/actions-view.js
@@ -0,0 +1,62 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'api-documentation/action-view'
+], function (ActionView) {
+
+ var $ = jQuery;
+
+ return Marionette.CollectionView.extend({
+ itemView: ActionView,
+
+ scrollToTop: function () {
+ var parent = this.$el.scrollParent();
+ if (parent.is(document)) {
+ parent = $(window);
+ }
+ parent.scrollTop(0);
+ },
+
+ scrollToAction: function (action) {
+ var model = this.collection.findWhere({ key: action });
+ if (model != null) {
+ var view = this.children.findByModel(model);
+ if (view != null) {
+ this.scrollToView(view);
+ }
+ }
+ },
+
+ scrollToView: function (view) {
+ var el = view.$el,
+ parent = el.scrollParent();
+ var elOffset = el.offset(),
+ parentOffset = parent.offset();
+ if (parent.is(document)) {
+ parentOffset = { top: 0 };
+ }
+ if (elOffset != null && parentOffset != null) {
+ var scrollTop = elOffset.top - parentOffset.top - 70;
+ parent.scrollTop(scrollTop);
+ }
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/app.js b/server/sonar-web/src/main/js/api-documentation/app.js
new file mode 100644
index 00000000000..31f3e60f368
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/app.js
@@ -0,0 +1,87 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'api-documentation/router',
+ 'api-documentation/controller',
+ 'api-documentation/layout',
+ 'api-documentation/list',
+ 'api-documentation/list-view',
+ 'api-documentation/filters-view'
+], function (Router, Controller, Layout, List, ListView, FiltersView) {
+
+ var $ = jQuery,
+ App = new Marionette.Application(),
+ init = function (options) {
+
+ // State
+ this.state = new Backbone.Model({ internal: false });
+
+ // Layout
+ this.layout = new Layout({ el: options.el });
+ this.layout.render();
+ $('#footer').addClass('search-navigator-footer');
+
+ // Web Services List
+ this.list = new List();
+
+ // Controller
+ this.controller = new Controller({
+ app: this,
+ state: this.state
+ });
+
+ // List View
+ this.listView = new ListView({
+ collection: this.list,
+ state: this.state
+ });
+ this.layout.resultsRegion.show(this.listView);
+
+ // Filters View
+ this.filtersView = new FiltersView({
+ collection: this.list,
+ state: this.state
+ });
+ this.layout.actionsRegion.show(this.filtersView);
+
+ // Router
+ this.router = new Router({ app: this });
+ Backbone.history.start({
+ pushState: true,
+ root: getRoot()
+ });
+ };
+
+ App.on('start', function (options) {
+ window.requestMessages().done(function () {
+ init.call(App, options);
+ });
+ });
+
+ function getRoot () {
+ var API_DOCUMENTATION = '/api_documentation',
+ path = window.location.pathname,
+ pos = path.indexOf(API_DOCUMENTATION);
+ return path.substr(0, pos + API_DOCUMENTATION.length);
+ }
+
+ return App;
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/controller.js b/server/sonar-web/src/main/js/api-documentation/controller.js
new file mode 100644
index 00000000000..3c3aba8c43c
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/controller.js
@@ -0,0 +1,93 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'api-documentation/actions-view',
+ 'api-documentation/header-view'
+], function (ActionsView, HeaderView) {
+
+ return Marionette.Controller.extend({
+
+ initialize: function (options) {
+ this.list = options.app.list;
+ this.listenTo(this.list, 'select', this.onItemSelect);
+ },
+
+ show: function (path) {
+ var that = this;
+ this.fetchList().done(function () {
+ if (path) {
+ var item = that.list.findWhere({ path: path });
+ if (item != null) {
+ that.showWebService(path);
+ } else {
+ that.showAction(path);
+ }
+ }
+ });
+ },
+
+ showWebService: function (path) {
+ var item = this.list.findWhere({ path: path });
+ if (item != null) {
+ item.trigger('select', item);
+ }
+ },
+
+ showAction: function (path) {
+ var webService = this.list.find(function (item) {
+ return path.indexOf(item.get('path')) === 0;
+ });
+ if (webService != null) {
+ var action = path.substr(webService.get('path').length + 1);
+ webService.trigger('select', webService, { trigger: false, action: action });
+ }
+ },
+
+ onItemSelect: function (item, options) {
+ var path = item.get('path'),
+ opts = _.defaults(options || {}, { trigger: true });
+ if (opts.trigger) {
+ this.options.app.router.navigate(path);
+ }
+ this.options.app.listView.highlight(path);
+
+ if (item.get('internal')) {
+ this.options.state.set({ internal: true });
+ }
+
+ var actions = new Backbone.Collection(item.get('actions')),
+ actionsView = new ActionsView({ collection: actions });
+ this.options.app.layout.detailsRegion.show(actionsView);
+ this.options.app.layout.headerRegion.show(new HeaderView({ model: item }));
+
+ if (opts.action != null) {
+ actionsView.scrollToAction(opts.action);
+ } else {
+ actionsView.scrollToTop();
+ }
+ },
+
+ fetchList: function () {
+ return this.list.fetch({ data: { 'include_internals': true } });
+ }
+
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/filters-view.js b/server/sonar-web/src/main/js/api-documentation/filters-view.js
new file mode 100644
index 00000000000..9c824dfd62b
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/filters-view.js
@@ -0,0 +1,46 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'templates/api-documentation'
+], function () {
+
+ return Marionette.ItemView.extend({
+ template: Templates['api-documentation-filters'],
+
+ events: {
+ 'change .js-toggle-internal': 'toggleInternal'
+ },
+
+ initialize: function () {
+ this.listenTo(this.options.state, 'change:internal', this.render);
+ },
+
+ toggleInternal: function () {
+ this.options.state.set({ internal: !this.options.state.get('internal')});
+ },
+
+ serializeData: function () {
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ state: this.options.state.toJSON()
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/header-view.js b/server/sonar-web/src/main/js/api-documentation/header-view.js
new file mode 100644
index 00000000000..17593155f8d
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/header-view.js
@@ -0,0 +1,32 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'templates/api-documentation'
+], function () {
+
+ return Marionette.ItemView.extend({
+ template: Templates['api-documentation-header'],
+
+ modelEvents: {
+ 'change': 'render'
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/item-view.js b/server/sonar-web/src/main/js/api-documentation/item-view.js
new file mode 100644
index 00000000000..e930b060d37
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/item-view.js
@@ -0,0 +1,59 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'templates/api-documentation'
+], function () {
+
+ return Marionette.ItemView.extend({
+ tagName: 'a',
+ className: 'list-group-item',
+ template: Templates['api-documentation-web-service'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ events: {
+ 'click': 'onClick'
+ },
+
+ initialize: function () {
+ this.listenTo(this.options.state, 'change:internal', this.toggleInternal);
+ },
+
+ onRender: function () {
+ this.$el.attr('data-path', this.model.get('path'));
+ this.$el.toggleClass('active', this.options.highlighted);
+ this.toggleInternal();
+ },
+
+ onClick: function (e) {
+ e.preventDefault();
+ this.model.trigger('select', this.model);
+ },
+
+ toggleInternal: function () {
+ var showInternal = this.options.state.get('internal'),
+ hideMe = this.model.get('internal') && !showInternal;
+ this.$el.toggleClass('hidden', hideMe);
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/layout.js b/server/sonar-web/src/main/js/api-documentation/layout.js
new file mode 100644
index 00000000000..b80e5aca0a2
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/layout.js
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'templates/api-documentation'
+], function () {
+
+ var $ = jQuery;
+
+ return Marionette.Layout.extend({
+ template: Templates['api-documentation-layout'],
+
+ regions: {
+ headerRegion: '.search-navigator-workspace-header',
+ actionsRegion: '.search-navigator-filters',
+ resultsRegion: '.api-documentation-results',
+ detailsRegion: '.search-navigator-workspace-details'
+ },
+
+ onRender: function () {
+ var navigator = $('.search-navigator');
+ navigator.addClass('sticky search-navigator-extended-view');
+ var top = navigator.offset().top;
+ this.$('.search-navigator-workspace-header').css({ top: top });
+ this.$('.search-navigator-side').css({ top: top }).isolatedScroll();
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/list-view.js b/server/sonar-web/src/main/js/api-documentation/list-view.js
new file mode 100644
index 00000000000..20d0e0b80e6
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/list-view.js
@@ -0,0 +1,42 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'api-documentation/item-view'
+], function (ItemView) {
+
+ return Marionette.CollectionView.extend({
+ className: 'list-group',
+ itemView: ItemView,
+
+ itemViewOptions: function (model) {
+ return {
+ collectionView: this,
+ highlighted: model.get('path') === this.highlighted,
+ state: this.options.state
+ };
+ },
+
+ highlight: function (path) {
+ this.highlighted = path;
+ this.render();
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/list.js b/server/sonar-web/src/main/js/api-documentation/list.js
new file mode 100644
index 00000000000..131b3352e8d
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/list.js
@@ -0,0 +1,42 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define(function () {
+
+ return Backbone.Collection.extend({
+ url: baseUrl + '/api/webservices/list',
+ comparator: 'path',
+
+ parse: function (r) {
+ return r.webServices.map(function (webService) {
+ var internal = _.every(webService.actions, function (action) {
+ return action.internal;
+ }),
+ actions = webService.actions.map(function (action) {
+ return _.extend(action, { path: webService.path });
+ });
+ return _.extend(webService, {
+ internal: internal,
+ actions: actions
+ });
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/api-documentation/router.js b/server/sonar-web/src/main/js/api-documentation/router.js
new file mode 100644
index 00000000000..fee3493fb18
--- /dev/null
+++ b/server/sonar-web/src/main/js/api-documentation/router.js
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define(function () {
+
+ return Backbone.Router.extend({
+
+ routes: {
+ '*path': 'show'
+ },
+
+ initialize: function (options) {
+ this.app = options.app;
+ },
+
+ show: function (path) {
+ this.app.controller.show(path);
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/less/components/badges.less b/server/sonar-web/src/main/less/components/badges.less
index 856125aea62..755f9244034 100644
--- a/server/sonar-web/src/main/less/components/badges.less
+++ b/server/sonar-web/src/main/less/components/badges.less
@@ -43,6 +43,7 @@
.list-group-item > &,
.list-group-item-heading > & {
float: right;
+ margin-top: 3px;
}
.list-group-item > & + &,
diff --git a/server/sonar-web/src/main/less/init/misc.less b/server/sonar-web/src/main/less/init/misc.less
index 971ce0c2f2e..b766304822a 100644
--- a/server/sonar-web/src/main/less/init/misc.less
+++ b/server/sonar-web/src/main/less/init/misc.less
@@ -43,6 +43,11 @@
.spacer-bottom { margin-bottom: 8px; }
.spacer-top { margin-top: 8px; }
+.little-spacer-left { margin-left: 4px; }
+.little-spacer-right { margin-right: 4px; }
+.little-spacer-bottom { margin-bottom: 4px; }
+.little-spacer-top { margin-top: 4px; }
+
td.spacer-left { padding-left: 8px; }
td.spacer-right { padding-right: 8px; }
td.spacer-bottom { padding-bottom: 8px; }
diff --git a/server/sonar-web/src/main/less/pages.less b/server/sonar-web/src/main/less/pages.less
index a24699b5834..c9d1c235da9 100644
--- a/server/sonar-web/src/main/less/pages.less
+++ b/server/sonar-web/src/main/less/pages.less
@@ -18,7 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@import "pages/analysis-reports";
-@import "pages/api-documentation";
@import "pages/coding-rules";
@import "pages/dashboard";
@import "pages/dsm";
diff --git a/server/sonar-web/src/main/less/pages/api-documentation.less b/server/sonar-web/src/main/less/pages/api-documentation.less
deleted file mode 100644
index cb629a715ab..00000000000
--- a/server/sonar-web/src/main/less/pages/api-documentation.less
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-@import (reference) "../variables";
-@import (reference) "../mixins";
-@import (reference) "../components/navigator/config";
-
-@apiDocumentationSidebarWidth: 230px;
-
-.api-documentation-show-internals {
- margin: @navigatorPadding;
- padding: 0 @navigatorPadding;
-}
-
-.internal {
- color: @navigatorBarBackground;
- background-color: rgb(127, 127, 127);
- border-radius: 2px;
- padding: 1px 5px;
-}
-
-.api-documentation-actions {
-
- ol {
- li {
- list-style: decimal;
- margin-left: 2em;
- }
- }
-
-}
-
-.api-documentation-action {
- padding: 0 5px;
-
- & > p {
- margin-top: 5px;
- }
-
- table {
- width: 100%;
-
- tr {
- border-top: 1px solid @navigatorBorderLightColor;
-
- td {
- padding: 10px 0 10px 5px;
- margin: 5px;
- vertical-align: top;
-
- ul {
- li {
- list-style: square;
- margin-left: 2em;
- }
- }
-
- ul.possible-values {
- display: inline;
-
- li {
- display: inline;
- margin: 0;
-
- &:before {
- content: ', '
- }
-
- &:first-child:before {
- content: ''
- }
- }
- }
- }
- }
- }
-
- .example-response-content {
- margin: 10px 0;
- padding: 5px;
- background-color: @navigatorBarBackground;
- border: 1px solid @navigatorBorderLightColor;
-
- code {
- white-space: pre-wrap;
- }
- }
-}
-
-.api-documentation-action + .api-documentation-action {
- margin-top: 30px;
-}
diff --git a/server/sonar-web/src/main/less/style.less b/server/sonar-web/src/main/less/style.less
index 7114b2e2314..9f4c5b2205a 100644
--- a/server/sonar-web/src/main/less/style.less
+++ b/server/sonar-web/src/main/less/style.less
@@ -591,10 +591,6 @@ h1 strong, .dashbox .title {
font-weight: bold;
}
-h4 a, h4 a:visited, .gray {
- color: #777;
-}
-
.even, table.sortable tr.rowodd {
background-color: #f5f5f5;
}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb
index 56a3439dc88..c46a284b206 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb
@@ -1,5 +1,6 @@
-<% content_for :script do %>
- <script>require(['api-documentation/app']);</script>
-<% end %>
-
-<div id="api-documentation" class="search-navigator"></div>
+<div id="api-documentation" class="search-navigator sticky"></div>
+<script>
+ require(['api-documentation/app'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+</script>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb b/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb
index 72dbd1eb08b..6754a315d62 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb
@@ -43,6 +43,8 @@ ActionController::Routing::Routes.draw do |map|
map.connect 'charts/:action/:project_id/:metric_id', :controller => 'charts'
map.connect 'rules_configuration/:action/:language/:name/:plugin.:format', :controller => 'rules_configuration'
+ map.connect 'api_documentation/*other', :controller => 'api_documentation', :action => 'index'
+
# Install the default route as the lowest priority.
map.connect ':controller/:action/:id', :requirements => { :id => /.*/ }
diff --git a/server/sonar-web/src/test/js/api-documentation-spec.js b/server/sonar-web/src/test/js/api-documentation-spec.js
new file mode 100644
index 00000000000..587bff3a72a
--- /dev/null
+++ b/server/sonar-web/src/test/js/api-documentation-spec.js
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+/* global casper:false */
+
+var lib = require('../lib'),
+ testName = lib.testName('Web Service API');
+
+lib.initMessages();
+lib.changeWorkingDirectory('api-documentation');
+lib.configureCasper();
+
+
+casper.test.begin(testName('Should Show List'), 12, function (test) {
+ casper
+ .start(lib.buildUrl('api_documentation'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/webservices/list', 'list.json');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/api-documentation/app.js'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.api-documentation-results .list-group-item');
+ })
+
+ .then(function () {
+ test.assertElementCount('.api-documentation-results .list-group-item', 2);
+ test.assertSelectorContains('.list-group-item[data-path="api/public"] .list-group-item-heading', 'api/public');
+ test.assertSelectorContains('.list-group-item[data-path="api/public"] .list-group-item-text', 'api/public description');
+ test.assertSelectorContains('.list-group-item[data-path="api/internal"] .list-group-item-heading', 'api/internal');
+ test.assertSelectorContains('.list-group-item[data-path="api/internal"] .list-group-item-text', 'api/internal description');
+ test.assertSelectorContains('.list-group-item[data-path="api/internal"]', 'internal');
+ })
+
+ .then(function () {
+ test.assertVisible('.list-group-item[data-path="api/public"]');
+ test.assertNotVisible('.list-group-item[data-path="api/internal"]');
+ test.assertFail(casper.evaluate(function () {
+ return jQuery('#api-documentation-show-internal').is(':checked');
+ }));
+ })
+
+ .then(function () {
+ casper.click('#api-documentation-show-internal');
+
+ test.assertVisible('.list-group-item[data-path="api/public"]');
+ test.assertVisible('.list-group-item[data-path="api/internal"]');
+ test.assert(casper.evaluate(function () {
+ return jQuery('#api-documentation-show-internal').is(':checked');
+ }));
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
+casper.test.begin(testName('Should Show Actions'), 10, function (test) {
+ casper
+ .start(lib.buildUrl('api_documentation'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/webservices/list', 'list.json');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/api-documentation/app.js'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.api-documentation-results .list-group-item');
+ })
+
+ .then(function () {
+ casper.click('.list-group-item[data-path="api/public"]');
+
+ test.assertElementCount('.search-navigator-workspace-details .panel', 2);
+ test.assertSelectorContains('.panel[data-action="do"]', 'POST api/public/do');
+ test.assertSelectorContains('.panel[data-action="do"]', 'api/public/do description');
+ test.assertSelectorContains('.panel[data-action="do"]', 'Since 3.6');
+
+ test.assertElementCount('.panel[data-action="do"] table tr', 1);
+ test.assertSelectorContains('.panel[data-action="do"] table tr', 'format');
+ test.assertSelectorContains('.panel[data-action="do"] table tr', 'optional');
+ test.assertSelectorContains('.panel[data-action="do"] table tr', 'api/public/do format description');
+ test.assertSelectorContains('.panel[data-action="do"] table tr', 'json');
+ test.assertSelectorContains('.panel[data-action="do"] table tr', 'xml');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
+casper.test.begin(testName('Should Show Example Response'), 1, function (test) {
+ casper
+ .start(lib.buildUrl('api_documentation'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/webservices/list', 'list.json');
+ lib.mockRequestFromFile('/api/webservices/response_example', 'response-example.json',
+ { data: { controller: 'api/public', action: 'undo' } });
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/api-documentation/app.js'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.api-documentation-results .list-group-item');
+ })
+
+ .then(function () {
+ casper.click('.list-group-item[data-path="api/public"]');
+ casper.click('.panel[data-action="undo"] .js-show-response-example');
+ casper.waitForSelector('.panel[data-action="undo"] pre');
+ })
+
+ .then(function () {
+ test.assertSelectorContains('.panel[data-action="undo"] pre', 'leia.organa');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
+casper.test.begin(testName('Web Service Permalink'), 1, function (test) {
+ casper
+ .start(lib.buildUrl('api_documentation#api/public'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/webservices/list', 'list.json');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/api-documentation/app.js'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.panel[data-web-service="api/public"]');
+ })
+
+ .then(function () {
+ test.assertElementCount('.panel[data-web-service="api/public"]', 2);
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
+casper.test.begin(testName('Action Permalink'), 1, function (test) {
+ casper
+ .start(lib.buildUrl('api_documentation#api/internal/move'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/webservices/list', 'list.json');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/api-documentation/app.js'], function (App) {
+ App.start({ el: '#api-documentation' });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.panel[data-web-service="api/internal"]');
+ })
+
+ .then(function () {
+ test.assertExists('.panel[data-web-service="api/internal"][data-action="move"]');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
diff --git a/server/sonar-web/src/test/json/api-documentation/list.json b/server/sonar-web/src/test/json/api-documentation/list.json
new file mode 100644
index 00000000000..e9405f8aacd
--- /dev/null
+++ b/server/sonar-web/src/test/json/api-documentation/list.json
@@ -0,0 +1,52 @@
+{
+ "webServices": [
+ {
+ "path": "api/public",
+ "description": "api/public description",
+ "actions": [
+ {
+ "key": "do",
+ "description": "api/public/do description",
+ "since": "3.6",
+ "internal": false,
+ "post": true,
+ "hasResponseExample": false,
+ "params": [
+ {
+ "key": "format",
+ "description": "api/public/do format description",
+ "required": false,
+ "possibleValues": [
+ "json",
+ "xml"
+ ]
+ }
+ ]
+ },
+ {
+ "key": "undo",
+ "description": "api/public/undo description",
+ "internal": false,
+ "post": false,
+ "hasResponseExample": true,
+ "params": []
+ }
+ ]
+ },
+ {
+ "path": "api/internal",
+ "description": "api/internal description",
+ "actions": [
+ {
+ "key": "move",
+ "description": "api/internal/move description",
+ "since": "4.4",
+ "internal": true,
+ "post": false,
+ "hasResponseExample": false,
+ "params": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/api-documentation/response-example.json b/server/sonar-web/src/test/json/api-documentation/response-example.json
new file mode 100644
index 00000000000..c186f4c1e9a
--- /dev/null
+++ b/server/sonar-web/src/test/json/api-documentation/response-example.json
@@ -0,0 +1,4 @@
+{
+ "format": "json",
+ "example": "{\n \"authors\": {\n \"more\": true,\n \"results\": [\n {\n \"key\": \"leia.organa\",\n \"text\": \"leia.organa\"\n },\n {\n \"key\": \"luke@skywalker.name\",\n \"text\": \"luke@skywalker.name\"\n }\n ]\n }\n}"
+}
diff --git a/server/sonar-web/src/test/views/api_documentation.jade b/server/sonar-web/src/test/views/api_documentation.jade
new file mode 100644
index 00000000000..307df3dbd66
--- /dev/null
+++ b/server/sonar-web/src/test/views/api_documentation.jade
@@ -0,0 +1,5 @@
+extends layouts/main
+
+block body
+ #content
+ .search-navigator.sticky#api-documentation