diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-02-25 19:08:22 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-02-29 14:13:36 +0100 |
commit | 7e1bd1a88c7b36d2dd7a678423705d2efddb5d83 (patch) | |
tree | 46c67aee74a39a735faeb7324dbf811bbc749db7 /server/sonar-web/src/main/js/apps | |
parent | 9c4e7a049ce145694c76307dcb6868be4fd9e8d2 (diff) | |
download | sonarqube-7e1bd1a88c7b36d2dd7a678423705d2efddb5d83.tar.gz sonarqube-7e1bd1a88c7b36d2dd7a678423705d2efddb5d83.zip |
SONAR-7074 SONAR-7310 SONAR-7357 SONAR-7395 refactor web api page
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
26 files changed, 772 insertions, 705 deletions
diff --git a/server/sonar-web/src/main/js/apps/api-documentation/action-view.js b/server/sonar-web/src/main/js/apps/api-documentation/action-view.js deleted file mode 100644 index 90969fe6e5d..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/action-view.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 $ from 'jquery'; -import Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-action.hbs'; - -export default Marionette.ItemView.extend({ - className: 'panel panel-vertical', - template: Template, - - modelEvents: { - 'change': 'render' - }, - - events: { - 'click .js-show-response-example': 'onShowResponseExampleClick', - 'click .js-hide-response-example': 'onHideResponseExampleClick' - }, - - initialize () { - this.listenTo(this.options.state, 'change', this.toggleHidden); - }, - - onRender () { - this.$el.attr('data-web-service', this.model.get('path')); - this.$el.attr('data-action', this.model.get('key')); - this.toggleHidden(); - this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); - }, - - onShowResponseExampleClick (e) { - e.preventDefault(); - this.fetchResponse(); - }, - - onHideResponseExampleClick (e) { - e.preventDefault(); - this.model.unset('responseExample'); - }, - - fetchResponse () { - const url = '/api/webservices/response_example'; - const options = { controller: this.model.get('path'), action: this.model.get('key') }; - return $.get(url, options).done(r => { - this.model.set({ responseExample: r.example }); - }); - }, - - toggleHidden () { - const test = this.model.get('path') + '/' + this.model.get('key'); - this.$el.toggleClass('hidden', !this.options.state.match(test, this.model.get('internal'))); - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/actions-view.js b/server/sonar-web/src/main/js/apps/api-documentation/actions-view.js deleted file mode 100644 index c403aed7d6b..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/actions-view.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 $ from 'jquery'; -import Marionette from 'backbone.marionette'; -import ActionView from './action-view'; - -export default Marionette.CollectionView.extend({ - childView: ActionView, - - childViewOptions () { - return { - state: this.options.state - }; - }, - - scrollToTop () { - let parent = this.$el.scrollParent(); - if (parent.is(document)) { - parent = $(window); - } - parent.scrollTop(0); - }, - - scrollToAction (action) { - const model = this.collection.findWhere({ key: action }); - if (model != null) { - const view = this.children.findByModel(model); - if (view != null) { - this.scrollToView(view); - } - } - }, - - scrollToView (view) { - const elOffset = view.el.getBoundingClientRect(); - if (elOffset != null) { - const scrollTop = elOffset.top - 70; - window.scrollTo(0, scrollTop); - } - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/app.js b/server/sonar-web/src/main/js/apps/api-documentation/app.js deleted file mode 100644 index 7de5702240f..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/app.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 $ from 'jquery'; -import Backbone from 'backbone'; -import Marionette from 'backbone.marionette'; -import Router from './router'; -import Controller from './controller'; -import Layout from './layout'; -import List from './list'; -import ListView from './list-view'; -import FiltersView from './filters-view'; -import SearchView from './search-view'; - -const App = new Marionette.Application(); -const init = function () { - const options = window.sonarqube; - - // State - this.state = new Backbone.Model({ internal: false }); - this.state.match = function (test, internal) { - const pattern = new RegExp(this.get('query'), 'i'); - const internalCheck = !this.get('internal') && internal; - return test.search(pattern) !== -1 && !internalCheck; - }; - - // 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); - - // Search View - this.searchView = new SearchView({ - state: this.state - }); - this.layout.searchRegion.show(this.searchView); - - // Router - this.router = new Router({ app: this }); - Backbone.history.start({ - pushState: true, - root: options.urlRoot - }); -}; - -App.on('start', function (options) { - init.call(App, options); -}); - -window.sonarqube.appStarted.then(options => App.start(options)); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/controller.js b/server/sonar-web/src/main/js/apps/api-documentation/controller.js deleted file mode 100644 index db088e1d86a..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/controller.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 _ from 'underscore'; -import Backbone from 'backbone'; -import Marionette from 'backbone.marionette'; -import ActionsView from './actions-view'; -import HeaderView from './header-view'; - -export default Marionette.Controller.extend({ - initialize (options) { - this.list = options.app.list; - this.listenTo(this.list, 'select', this.onItemSelect); - }, - - show (path) { - const that = this; - this.fetchList().done(function () { - if (path) { - const item = that.list.findWhere({ path }); - if (item != null) { - that.showWebService(path); - } else { - that.showAction(path); - } - } - }); - }, - - showWebService (path) { - const item = this.list.findWhere({ path }); - if (item != null) { - item.trigger('select', item); - } - }, - - showAction (path) { - const webService = this.list.find(function (item) { - return path.indexOf(item.get('path')) === 0; - }); - if (webService != null) { - const action = path.substr(webService.get('path').length + 1); - webService.trigger('select', webService, { trigger: false, action }); - } - }, - - onItemSelect (item, options) { - const path = item.get('path'); - const 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 }); - } - - const actions = new Backbone.Collection(item.get('actions')); - const actionsView = new ActionsView({ - collection: actions, - state: this.options.state - }); - this.options.app.layout.detailsRegion.show(actionsView); - this.options.app.layout.headerRegion.show(new HeaderView({ model: item })); - - if (opts.action != null) { - const model = actions.findWhere({ key: opts.action }); - if (model) { - if (model.get('internal')) { - this.options.state.set({ internal: true }); - } - actionsView.scrollToAction(opts.action); - } - } else { - actionsView.scrollToTop(); - } - }, - - fetchList () { - return this.list.fetch({ data: { 'include_internals': true } }); - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js b/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js deleted file mode 100644 index 5e835c3b462..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/filters-view.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 _ from 'underscore'; -import Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-filters.hbs'; - -export default Marionette.ItemView.extend({ - template: Template, - - events: { - 'change .js-toggle-internal': 'toggleInternal' - }, - - initialize () { - this.listenTo(this.options.state, 'change:internal', this.render); - }, - - toggleInternal () { - this.options.state.set({ internal: !this.options.state.get('internal') }); - }, - - serializeData () { - return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { - state: this.options.state.toJSON() - }); - } -}); - - diff --git a/server/sonar-web/src/main/js/apps/api-documentation/item-view.js b/server/sonar-web/src/main/js/apps/api-documentation/item-view.js deleted file mode 100644 index 2c6e4f121af..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/item-view.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 _ from 'underscore'; -import Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-web-service.hbs'; - -export default Marionette.ItemView.extend({ - tagName: 'a', - className: 'list-group-item', - template: Template, - - modelEvents: { - 'change': 'render' - }, - - events: { - 'click': 'onClick' - }, - - initialize () { - this.listenTo(this.options.state, 'change:query', this.toggleHidden); - this.listenTo(this.options.state, 'change:internal', this.toggleHidden); - }, - - shouldBeHidden () { - const that = this; - const match = this.options.state.match(this.model.get('path')) || - _.some(this.model.get('actions'), function (action) { - const test = action.path + '/' + action.key; - return that.options.state.match(test, action.internal); - }); - - const showInternal = this.options.state.get('internal'); - const hideMe = this.model.get('internal') && !showInternal; - return !match || hideMe; - }, - - onRender () { - this.$el.attr('data-path', this.model.get('path')); - this.$el.toggleClass('active', this.options.highlighted); - this.toggleHidden(); - this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'right' }); - }, - - onClick (e) { - e.preventDefault(); - this.model.trigger('select', this.model); - }, - - toggleHidden () { - this.$el.toggleClass('hidden', this.shouldBeHidden()); - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/layout.js b/server/sonar-web/src/main/js/apps/api-documentation/layout.js deleted file mode 100644 index 51d449a989d..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/layout.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-layout.hbs'; - -export default Marionette.LayoutView.extend({ - template: Template, - - regions: { - headerRegion: '.search-navigator-workspace-header', - actionsRegion: '.search-navigator-filters', - searchRegion: '.api-documentation-search', - resultsRegion: '.api-documentation-results', - detailsRegion: '.search-navigator-workspace-details' - }, - - onRender () { - const navigator = this.$('.search-navigator'); - navigator.addClass('sticky search-navigator-extended-view'); - const top = navigator.offset().top; - this.$('.search-navigator-workspace-header').css({ top }); - this.$('.search-navigator-side').css({ top }).isolatedScroll(); - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/search-view.js b/server/sonar-web/src/main/js/apps/api-documentation/search-view.js deleted file mode 100644 index b837e3f5f89..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/search-view.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program 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. - * - * This program 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 _ from 'underscore'; -import Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-search.hbs'; - -export default Marionette.ItemView.extend({ - template: Template, - - ui: { - input: '.search-box-input' - }, - - events: { - 'keyup @ui.input': 'onChange', - 'search @ui.input': 'onChange' - }, - - initialize () { - this.query = ''; - this.debouncedFilter = _.debounce(this.filter, 250); - }, - - onChange () { - const query = this.ui.input.val(); - if (query === this.query) { - return; - } - this.query = this.ui.input.val(); - this.debouncedFilter(query); - }, - - filter (query) { - this.options.state.set({ query }); - } -}); diff --git a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-action.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-action.hbs deleted file mode 100644 index bf2e964eab5..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-action.hbs +++ /dev/null @@ -1,90 +0,0 @@ -<header class="page-header"> - <h3 class="page-title big">{{#if post}}POST{{else}}GET{{/if}} {{this.path}}/{{key}}</h3> - - <div class="page-actions"> - {{#if internal}} - <span class="spacer-right"> - <span class="badge" data-toggle="tooltip" title="{{t 'api_documentation.internal_tooltip'}}">internal</span> - </span> - {{/if}} - {{#if deprecatedSince}} - <span class="spacer-right"> - <span class="badge badge-danger" data-toggle="tooltip" - title="{{t 'api_documentation.deprecation_tooltip'}}">Deprecated since {{deprecatedSince}}</span> - </span> - {{/if}} - {{#if since}} - <span class="spacer-right"> - <span class="note">Since {{since}}</span> - </span> - {{/if}} - - <a class="js-permalink icon-link" href="{{link '/api_documentation/' this.path '/' key}}" target="_blank"></a> - </div> -</header> - -<div class="markdown">{{{description}}}</div> - -{{#if params}} - <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> - {{#if since}} - <div class="note">since {{since}}</div> - {{/if}} - {{#if deprecatedSince}} - <span class="badge badge-danger little-spacer-top" data-toggle="tooltip" - title="{{t 'api_documentation.deprecation_tooltip'}}">deprecated since {{deprecatedSince}}</span> - {{/if}} - </td> - <td> - <div class="markdown">{{{description}}}</div> - - {{#if possibleValues}} - <p class="little-spacer-top"> - <strong>Possible values:</strong> - </p> - <ul class="list-styled"> - {{#each possibleValues}} - <li class="little-spacer-top"><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}} - <h4 class="spacer-top"> - Example Response - {{#if responseExample}} - <a class="js-hide-response-example little-spacer-left" href="#">Hide</a> - {{else}} - <a class="js-show-response-example little-spacer-left" href="#">Show</a> - {{/if}} - </h4> - - {{#if responseExample}} - <div class="little-spacer-top"> - <pre style="white-space: pre-wrap;">{{responseExample}}</pre> - </div> - {{/if}} -{{/if}} diff --git a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-filters.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-filters.hbs deleted file mode 100644 index 5941110db0a..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-filters.hbs +++ /dev/null @@ -1,6 +0,0 @@ -<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/js/apps/api-documentation/templates/api-documentation-header.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-header.hbs deleted file mode 100644 index f0d5078b9a0..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-header.hbs +++ /dev/null @@ -1 +0,0 @@ -<h2 class="search-navigator-header-component">{{this.path}}</h2> diff --git a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-layout.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-layout.hbs deleted file mode 100644 index f530a848360..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-layout.hbs +++ /dev/null @@ -1,12 +0,0 @@ -<div class="search-navigator sticky"> - <div class="search-navigator-side search-navigator-side-light"> - <div class="search-navigator-filters"></div> - <div class="api-documentation-search"></div> - <div class="api-documentation-results panel"></div> - </div> - - <div class="search-navigator-workspace"> - <div class="search-navigator-workspace-header"></div> - <div class="search-navigator-workspace-details"></div> - </div> -</div> diff --git a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-search.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-search.hbs deleted file mode 100644 index 6cad4e381b9..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-search.hbs +++ /dev/null @@ -1,4 +0,0 @@ -<form id="api-documentation-search-form" class="search-box"> - <span id="api-documentation-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i></span> - <input id="api-documentation-search-query" class="search-box-input" type="search" name="q" placeholder="Search" maxlength="100"> -</form> diff --git a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-web-service.hbs b/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-web-service.hbs deleted file mode 100644 index 5d8fc4b22a7..00000000000 --- a/server/sonar-web/src/main/js/apps/api-documentation/templates/api-documentation-web-service.hbs +++ /dev/null @@ -1,7 +0,0 @@ -<h3 class="list-group-item-heading"> - {{this.path}} - {{#if internal}} - <span class="badge" data-toggle="tooltip" title="{{t 'api_documentation.internal_tooltip'}}">internal</span> - {{/if}} -</h3> -<p class="list-group-item-text">{{{description}}}</p> diff --git a/server/sonar-web/src/main/js/apps/api-documentation/list.js b/server/sonar-web/src/main/js/apps/web-api/app.js index 3ecd8fda7e1..0ff00d28a30 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/list.js +++ b/server/sonar-web/src/main/js/apps/web-api/app.js @@ -17,25 +17,25 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import _ from 'underscore'; -import Backbone from 'backbone'; +import React from 'react'; +import { render } from 'react-dom'; +import { Router, Route, Redirect, useRouterHistory } from 'react-router'; +import { createHistory } from 'history'; -export default Backbone.Collection.extend({ - url: '/api/webservices/list', - comparator: 'path', +import WebApiApp from './components/WebApiApp'; +import './styles/web-api.css'; - parse (r) { - return r.webServices.map(function (webService) { - const internal = _.every(webService.actions, function (action) { - return action.internal; - }); - const actions = webService.actions.map(function (action) { - return _.extend(action, { path: webService.path }); - }); - return _.extend(webService, { - internal, - actions - }); - }); - } +window.sonarqube.appStarted.then(options => { + const el = document.querySelector(options.el); + + const history = useRouterHistory(createHistory)({ + basename: window.sonarqube.urlRoot + }); + + render(( + <Router history={history}> + <Redirect from="/index" to="/"/> + <Route path="/**" component={WebApiApp}/> + </Router> + ), el); }); diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Action.js b/server/sonar-web/src/main/js/apps/web-api/components/Action.js new file mode 100644 index 00000000000..7e9c41cbc43 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/Action.js @@ -0,0 +1,117 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; +import { Link } from 'react-router'; + +import { getActionKey } from '../utils'; +import Params from './Params'; +import ResponseExample from './ResponseExample'; +import DeprecatedBadge from './DeprecatedBadge'; +import InternalBadge from './InternalBadge'; + +export default class Action extends React.Component { + state = { + showParams: false, + showResponse: false + }; + + handleShowParamsClick (e) { + e.preventDefault(); + this.refs.toggleParameters.blur(); + this.setState({ showParams: !this.state.showParams }); + } + + handleShowResponseClick (e) { + e.preventDefault(); + this.refs.toggleResponse.blur(); + this.setState({ showResponse: !this.state.showResponse }); + } + + render () { + const { action, domain } = this.props; + const { showParams, showResponse } = this.state; + const verb = action.post ? 'POST' : 'GET'; + const actionKey = getActionKey(domain.path, action.key); + + return ( + <div id={actionKey} className="web-api-action"> + <header className="web-api-action-header"> + <Link + to={{ pathname: '/' + actionKey }} + className="spacer-right icon-link"/> + + <h3 className="web-api-action-title"> + {verb} {actionKey} + </h3> + + {action.internal && ( + <span className="spacer-left"> + <InternalBadge/> + </span> + )} + + {action.since && ( + <span className="spacer-left badge">since {action.since}</span> + )} + + {action.deprecatedSince && ( + <span className="spacer-left"> + <DeprecatedBadge since={action.deprecatedSince}/> + </span> + )} + </header> + + <div + className="web-api-action-description markdown" + dangerouslySetInnerHTML={{ __html: action.description }}/> + + {(action.params || action.hasResponseExample) && ( + <ul className="web-api-action-actions list-inline"> + {action.params && ( + <li> + <a + ref="toggleParameters" + onClick={this.handleShowParamsClick.bind(this)} + href="#"> + {showParams ? 'Hide Parameters' : 'Show Parameters'} + </a> + </li> + )} + + {action.hasResponseExample && ( + <li> + <a + ref="toggleResponse" + onClick={this.handleShowResponseClick.bind(this)} + href="#"> + {showResponse ? 'Hide Response Example' : 'Show Response Example'} + </a> + </li> + )} + </ul> + )} + + {showParams && action.params && <Params params={action.params}/>} + + {showResponse && action.hasResponseExample && <ResponseExample domain={domain} action={action}/>} + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/api-documentation/list-view.js b/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js index c6319e58236..212e6622420 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/list-view.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js @@ -17,23 +17,18 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import Marionette from 'backbone.marionette'; -import ItemView from './item-view'; +import React from 'react'; -export default Marionette.CollectionView.extend({ - className: 'list-group', - childView: ItemView, +import { translate } from '../../../helpers/l10n'; - childViewOptions (model) { - return { - collectionView: this, - highlighted: model.get('path') === this.highlighted, - state: this.options.state - }; - }, +export default function DeprecatedBadge ({ since }) { + const label = since ? `deprecated since ${since}` : 'deprecated'; - highlight (path) { - this.highlighted = path; - this.render(); - } -}); + return ( + <span + className="badge badge-warning" + title={translate('api_documentation.deprecation_tooltip')}> + {label} + </span> + ); +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Domain.js b/server/sonar-web/src/main/js/apps/web-api/components/Domain.js new file mode 100644 index 00000000000..df212f6df13 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/Domain.js @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; + +import Action from './Action'; +import InternalBadge from './InternalBadge'; +import { getActionKey } from '../utils'; + +export default function Domain ({ domain, showInternal, showOnlyDeprecated, searchQuery }) { + const filteredActions = domain.actions + .filter(action => { + return showInternal || !action.internal; + }) + .filter(action => { + return !showOnlyDeprecated || (showOnlyDeprecated && action.deprecatedSince); + }) + .filter(action => { + const actionKey = getActionKey(domain.path, action.key); + return actionKey.indexOf(searchQuery) !== -1; + }); + + return ( + <div className="web-api-domain"> + <header className="web-api-domain-header"> + <h2 className="web-api-domain-title">{domain.path}</h2> + + {domain.internal && ( + <span className="spacer-left"> + <InternalBadge/> + </span> + )} + </header> + + {domain.description && ( + <p className="web-api-domain-description">{domain.description}</p> + )} + + <div className="web-api-domain-actions"> + {filteredActions.map(action => ( + <Action + key={getActionKey(domain.path, action.key)} + action={action} + domain={domain} + location={location}/> + ))} + </div> + </div> + ); +} diff --git a/server/sonar-web/src/main/js/apps/api-documentation/router.js b/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js index 45193995ad9..cfb87e6c841 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/router.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js @@ -17,18 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import Backbone from 'backbone'; +import React from 'react'; -export default Backbone.Router.extend({ - routes: { - '*path': 'show' - }, +import { translate } from '../../../helpers/l10n'; - initialize (options) { - this.app = options.app; - }, - - show (path) { - this.app.controller.show(path); - } -}); +export default function InternalBadge () { + return ( + <span + className="badge badge-danger" + title={translate('api_documentation.internal_tooltip')}> + internal + </span> + ); +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Menu.js b/server/sonar-web/src/main/js/apps/web-api/components/Menu.js new file mode 100644 index 00000000000..e5d58f5de94 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/Menu.js @@ -0,0 +1,68 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; +import { Link } from 'react-router'; +import classNames from 'classnames'; + +import InternalBadge from './InternalBadge'; +import { getActionKey } from '../utils'; + +export default function Menu ({ domains, showInternal, showOnlyDeprecated, searchQuery, splat }) { + const filteredDomains = (domains || []) + .map(domain => { + const filteredActions = domain.actions + .filter(action => { + return showInternal || !action.internal; + }) + .filter(action => { + return !showOnlyDeprecated || (showOnlyDeprecated && action.deprecatedSince); + }) + .filter(action => { + const actionKey = getActionKey(domain.path, action.key); + return actionKey.indexOf(searchQuery) !== -1; + }); + return { ...domain, filteredActions }; + }) + .filter(domain => domain.filteredActions.length); + + + return ( + <div className="api-documentation-results panel"> + <div className="list-group"> + {filteredDomains.map(domain => ( + <Link + key={domain.path} + className={classNames('list-group-item', { 'active': splat.indexOf(domain.path) === 0 })} + to={domain.path}> + <h3 className="list-group-item-heading"> + {domain.path} + {domain.internal && ( + <InternalBadge/> + )} + </h3> + <p className="list-group-item-text"> + {domain.description} + </p> + </Link> + ))} + </div> + </div> + ); +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Params.js b/server/sonar-web/src/main/js/apps/web-api/components/Params.js new file mode 100644 index 00000000000..66018f8ab26 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/Params.js @@ -0,0 +1,91 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; + +export default function Params ({ params }) { + return ( + <div className="web-api-params"> + <table> + <tbody> + {params.map(param => ( + <tr key={param.key}> + <td style={{ width: 150 }}> + <code>{param.key}</code> + + <div className="note little-spacer-top"> + {param.required ? 'required' : 'optional'} + </div> + + {param.since && ( + <div className="note little-spacer-top"> + since {param.since} + </div> + )} + + {param.deprecatedSince && ( + <div className="little-spacer-top"> + <span className="badge badge-danger"> + deprecated since {param.deprecatedSince} + </span> + </div> + )} + </td> + + <td> + <div + className="markdown" + dangerouslySetInnerHTML={{ __html: param.description }}/> + </td> + + <td style={{ width: 250 }}> + {param.possibleValues && ( + <div> + <h4>Possible values</h4> + <ul className="list-styled"> + {param.possibleValues.map(value => ( + <li key={value} className="little-spacer-top"> + <code>{value}</code> + </li> + ))} + </ul> + </div> + )} + + {param.defaultValue && ( + <div className="little-spacer-top"> + <h4>Default value</h4> + <code>{param.defaultValue}</code> + </div> + )} + + {param.exampleValue && ( + <div className="little-spacer-top"> + <h4>Example value</h4> + <code>{param.exampleValue}</code> + </div> + )} + </td> + </tr> + ))} + </tbody> + </table> + </div> + ); +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js b/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js new file mode 100644 index 00000000000..70e1791c5b2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; + +import { fetchResponseExample as fetchResponseExampleApi } from '../../../api/web-api'; + +export default class ResponseExample extends React.Component { + state = {}; + + componentDidMount () { + this.mounted = true; + this.fetchResponseExample(); + } + + componentDidUpdate (nextProps) { + if (nextProps.action !== this.props.action) { + this.fetchResponseExample(); + } + } + + componentWillUnmount () { + this.mounted = false; + } + + fetchResponseExample () { + const { domain, action } = this.props; + fetchResponseExampleApi(domain.path, action.key) + .then(responseExample => this.setState({ responseExample })); + } + + render () { + const { responseExample } = this.state; + + return ( + <div className="web-api-response"> + {responseExample && ( + <pre style={{ whiteSpace: 'pre-wrap' }}>{responseExample.example}</pre> + )} + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Search.js b/server/sonar-web/src/main/js/apps/web-api/components/Search.js new file mode 100644 index 00000000000..9ff60270d1b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/Search.js @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 _ from 'underscore'; +import React from 'react'; + +import DeprecatedBadge from './DeprecatedBadge'; +import InternalBadge from './InternalBadge'; +import Checkbox from '../../../components/shared/checkbox'; + +export default class Search extends React.Component { + constructor (props) { + super(props); + this.state = { query: '' }; + this.actuallySearch = _.debounce(this.actuallySearch.bind(this), 250); + } + + handleSearch (e) { + const { value } = e.target; + this.setState({ query: value }); + this.actuallySearch(); + } + + actuallySearch () { + const { onSearch } = this.props; + onSearch(this.state.query); + } + + render () { + const { showInternal, showOnlyDeprecated, onToggleInternal, onToggleDeprecated } = this.props; + + return ( + <div className="web-api-search"> + <div> + <i className="icon-search"/> + <input + className="spacer-left input-large" + type="search" + value={this.state.query} + placeholder="Search..." + onChange={this.handleSearch.bind(this)}/> + </div> + + <div className="big-spacer-top"> + <Checkbox + initiallyChecked={showInternal} + onCheck={onToggleInternal}/> + {' '} + <span + style={{ cursor: 'pointer' }} + onClick={onToggleInternal}> + <InternalBadge/> + </span> + </div> + + <div className="spacer-top"> + <Checkbox + initiallyChecked={showOnlyDeprecated} + onCheck={onToggleDeprecated}/> + {' '} + <span + style={{ cursor: 'pointer' }} + onClick={onToggleDeprecated}> + Only <DeprecatedBadge/> + </span> + </div> + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js new file mode 100644 index 00000000000..332d18f1399 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js @@ -0,0 +1,168 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 React from 'react'; +import { Link } from 'react-router'; + +import { fetchWebApi } from '../../../api/web-api'; +import Menu from './Menu'; +import Search from './Search'; +import Domain from './Domain'; +import { getActionKey } from '../utils'; + +export default class WebApiApp extends React.Component { + state = { + domains: [], + searchQuery: '', + showInternal: false, + showOnlyDeprecated: false + }; + + componentDidMount () { + this.mounted = true; + this.scrollToAction = this.scrollToAction.bind(this); + this.fetchList(); + document.getElementById('footer').classList.add('search-navigator-footer'); + } + + componentDidUpdate () { + this.toggleInternalInitially(); + this.scrollToAction(); + } + + componentWillUnmount () { + this.mounted = false; + document.getElementById('footer').classList.delete('search-navigator-footer'); + } + + fetchList (cb) { + fetchWebApi().then(domains => { + if (this.mounted) { + this.setState({ domains }, cb); + } + }); + } + + scrollToAction () { + const { splat } = this.props.params; + this.scrollToElement(splat); + } + + scrollToElement (id) { + const element = document.getElementById(id); + + if (element) { + const rect = element.getBoundingClientRect(); + const top = rect.top + window.pageYOffset - 20; + + window.scrollTo(0, top); + } else { + window.scrollTo(0, 0); + } + } + + toggleInternalInitially () { + const { splat } = this.props.params; + const { domains, showInternal } = this.state; + + if (!showInternal) { + domains.forEach(domain => { + if (domain.path === splat && domain.internal) { + this.setState({ showInternal: true }); + } + domain.actions.forEach(action => { + const actionKey = getActionKey(domain.path, action.key); + if (actionKey === splat && action.internal) { + this.setState({ showInternal: true }); + } + }); + }); + } + } + + handleSearch (searchQuery) { + this.setState({ searchQuery }); + } + + handleToggleInternal () { + const { splat } = this.props.params; + const { router } = this.context; + const { domains } = this.state; + const domain = domains.find(domain => splat.indexOf(domain.path) === 0); + const showInternal = !this.state.showInternal; + + if (domain && domain.internal && !showInternal) { + router.push('/'); + } + + this.setState({ showInternal }); + } + + handleToggleDeprecated () { + this.setState({ showOnlyDeprecated: !this.state.showOnlyDeprecated }); + } + + render () { + const { splat } = this.props.params; + const { domains, showInternal, showOnlyDeprecated, searchQuery } = this.state; + + const domain = domains.find(domain => splat.indexOf(domain.path) === 0); + + return ( + <div className="search-navigator sticky"> + <div className="search-navigator-side search-navigator-side-light" style={{ top: 30 }}> + <div className="web-api-page-header"> + <Link to="/"> + <h1>Web API</h1> + </Link> + </div> + + <Search + showInternal={showInternal} + showOnlyDeprecated={showOnlyDeprecated} + onSearch={this.handleSearch.bind(this)} + onToggleInternal={this.handleToggleInternal.bind(this)} + onToggleDeprecated={this.handleToggleDeprecated.bind(this)}/> + + <Menu + domains={this.state.domains} + showInternal={showInternal} + showOnlyDeprecated={showOnlyDeprecated} + searchQuery={searchQuery} + splat={splat}/> + </div> + + <div className="search-navigator-workspace"> + {domain && ( + <Domain + key={domain.path} + domain={domain} + showInternal={showInternal} + showOnlyDeprecated={showOnlyDeprecated} + searchQuery={searchQuery}/> + )} + </div> + </div> + ); + } +} + +WebApiApp.contextTypes = { + router: React.PropTypes.object.isRequired +}; diff --git a/server/sonar-web/src/main/js/apps/web-api/styles/web-api.css b/server/sonar-web/src/main/js/apps/web-api/styles/web-api.css new file mode 100644 index 00000000000..e5b572953b1 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/styles/web-api.css @@ -0,0 +1,72 @@ +.web-api-page-header { + margin: 10px 20px; +} + +.web-api-search { + margin: 20px 10px 0; + padding: 0 10px 20px; + border-bottom: 1px solid #e6e6e6; +} + +.web-api-search .icon-search { + color: #cdcdcd; +} + +.web-api-domain { + padding: 10px 20px; +} + +.web-api-domain-header, +.web-api-action-header { + display: flex; + align-items: center; +} + +.web-api-domain-title { + font-size: 18px; + font-weight: 400; +} + +.web-api-domain-description { + margin-top: 10px; + line-height: 1.5; +} + +.web-api-domain-actions { +} + +.web-api-action { + padding-top: 30px; +} + +.web-api-action-title { + font-weight: 500; +} + +.web-api-action-description { + margin-top: 10px; +} + +.web-api-action-actions { + margin-top: 10px; +} + +.web-api-params, +.web-api-response { + margin-top: 10px; +} + +.web-api-params > table { + width: 100%; + table-layout: fixed; +} + +.web-api-params td { + vertical-align: top; + padding: 8px 10px; + border-top: 1px solid #e6e6e6; +} + +.web-api-params tr:first-child td { + border-top: none; +} diff --git a/server/sonar-web/src/main/js/apps/api-documentation/header-view.js b/server/sonar-web/src/main/js/apps/web-api/utils.js index c90eb05db73..6e6de08af2d 100644 --- a/server/sonar-web/src/main/js/apps/api-documentation/header-view.js +++ b/server/sonar-web/src/main/js/apps/web-api/utils.js @@ -17,13 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import Marionette from 'backbone.marionette'; -import Template from './templates/api-documentation-header.hbs'; - -export default Marionette.ItemView.extend({ - template: Template, - - modelEvents: { - 'change': 'render' - } -}); +export function getActionKey (domain, action) { + return domain + '/' + action; +} |