]> source.dussan.org Git - sonarqube.git/commitdiff
refactor "Web Service API" page
authorStas Vilchik <vilchiks@gmail.com>
Mon, 20 Apr 2015 15:31:42 +0000 (17:31 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Tue, 21 Apr 2015 13:40:34 +0000 (15:40 +0200)
41 files changed:
server/sonar-web/src/main/coffee/api-documentation/app.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/collections/web-service-actions.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/collections/web-services.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/layout.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/models/web-service-action-response.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/models/web-service-action.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/models/web-service.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/router.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-response-view.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-action-view.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-actions-list-view.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-list-view.coffee [deleted file]
server/sonar-web/src/main/coffee/api-documentation/views/api-documentation-web-service-view.coffee [deleted file]
server/sonar-web/src/main/hbs/api-documentation/api-documentation-action-response.hbs [deleted file]
server/sonar-web/src/main/hbs/api-documentation/api-documentation-action.hbs
server/sonar-web/src/main/hbs/api-documentation/api-documentation-actions.hbs [deleted file]
server/sonar-web/src/main/hbs/api-documentation/api-documentation-filters.hbs [new file with mode: 0644]
server/sonar-web/src/main/hbs/api-documentation/api-documentation-header.hbs [new file with mode: 0644]
server/sonar-web/src/main/hbs/api-documentation/api-documentation-layout.hbs
server/sonar-web/src/main/js/api-documentation/action-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/actions-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/app.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/controller.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/filters-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/header-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/item-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/layout.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/list-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/list.js [new file with mode: 0644]
server/sonar-web/src/main/js/api-documentation/router.js [new file with mode: 0644]
server/sonar-web/src/main/less/components/badges.less
server/sonar-web/src/main/less/init/misc.less
server/sonar-web/src/main/less/pages.less
server/sonar-web/src/main/less/pages/api-documentation.less [deleted file]
server/sonar-web/src/main/less/style.less
server/sonar-web/src/main/webapp/WEB-INF/app/views/api_documentation/index.html.erb
server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb
server/sonar-web/src/test/js/api-documentation-spec.js [new file with mode: 0644]
server/sonar-web/src/test/json/api-documentation/list.json [new file with mode: 0644]
server/sonar-web/src/test/json/api-documentation/response-example.json [new file with mode: 0644]
server/sonar-web/src/test/views/api_documentation.jade [new file with mode: 0644]

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 (file)
index ec67135..0000000
+++ /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 (file)
index 810fc53..0000000
+++ /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 (file)
index 8829c43..0000000
+++ /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 (file)
index 60eb8a5..0000000
+++ /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 (file)
index 8a46730..0000000
+++ /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 (file)
index 435792d..0000000
+++ /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 (file)
index e7a846c..0000000
+++ /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 (file)
index c7f726c..0000000
+++ /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 (file)
index 78ea943..0000000
+++ /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 (file)
index 03cbf03..0000000
+++ /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 (file)
index c5435a2..0000000
+++ /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 (file)
index 0ffeaaf..0000000
+++ /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 (file)
index 226895e..0000000
+++ /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 (file)
index 6253a6e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<code>{{example}}</code>
\ No newline at end of file
index 656e2e7d7c3af5f192f188f3704f9b9e66d8a009..e92501d5fb220dddf71a913082cb4093934de658 100644 (file)
@@ -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 (file)
index 6c03ebe..0000000
+++ /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 (file)
index 0000000..5941110
--- /dev/null
@@ -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 (file)
index 0000000..b652f85
--- /dev/null
@@ -0,0 +1 @@
+<h2 class="search-navigator-header-component">{{path}}</h2>
index 2527222fad24261bdb4b51bf028f22e2b1d5589f..4ef38c51b11cd1514a4413d7326a013744b55892 100644 (file)
@@ -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 (file)
index 0000000..fd972e1
--- /dev/null
@@ -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 (file)
index 0000000..04d9cbc
--- /dev/null
@@ -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 (file)
index 0000000..31f3e60
--- /dev/null
@@ -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 (file)
index 0000000..3c3aba8
--- /dev/null
@@ -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 (file)
index 0000000..9c824df
--- /dev/null
@@ -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 (file)
index 0000000..1759315
--- /dev/null
@@ -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 (file)
index 0000000..e930b06
--- /dev/null
@@ -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 (file)
index 0000000..b80e5ac
--- /dev/null
@@ -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 (file)
index 0000000..20d0e0b
--- /dev/null
@@ -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 (file)
index 0000000..131b335
--- /dev/null
@@ -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 (file)
index 0000000..fee3493
--- /dev/null
@@ -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);
+    }
+  });
+
+});
index 856125aea62a1a72d63e9587e0852599cc1bf396..755f9244034f09b56fe66098026ddbd42c54f8ce 100644 (file)
@@ -43,6 +43,7 @@
   .list-group-item > &,
   .list-group-item-heading > & {
     float: right;
+    margin-top: 3px;
   }
 
   .list-group-item > & + &,
index 971ce0c2f2e92c7a5ba255f3183aa66ed5fa879b..b766304822a30289d311399619365d9dfbfc6f8b 100644 (file)
 .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; }
index a24699b58348383c8484a1969015c49202b74cb1..c9d1c235da9fe19afeead21357aa50879cbe08b1 100644 (file)
@@ -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 (file)
index cb629a7..0000000
+++ /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;
-}
index 7114b2e23140304a36e32c343e504640d543ae36..9f4c5b2205aa7c19284fde61d35a0b68a12bc174 100644 (file)
@@ -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;
 }
index 56a3439dc8808b022ec513a573310765127bd8f1..c46a284b20614b0f43c5bdb41dbe0fd542d3ec8a 100644 (file)
@@ -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>
index 72dbd1eb08bfd7a93f6744b27ec044c327de0abf..6754a315d627183b49f5ae38561918d4b106e9f8 100644 (file)
@@ -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 (file)
index 0000000..587bff3
--- /dev/null
@@ -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 (file)
index 0000000..e9405f8
--- /dev/null
@@ -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 (file)
index 0000000..c186f4c
--- /dev/null
@@ -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 (file)
index 0000000..307df3d
--- /dev/null
@@ -0,0 +1,5 @@
+extends layouts/main
+
+block body
+  #content
+    .search-navigator.sticky#api-documentation