nexmo-oas-renderer 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b5e0e8b5fa6f2398fce6e27b89653e00b1b6cf7b2fc0b89b00e466c59ff7010
4
- data.tar.gz: 899fd7a44676aef146f525466edb0bf0bcccd49accd2d4ebb04f21fb06f2318f
3
+ metadata.gz: e03a9fd43494edf725f3fa2ff814fdc7179aca5a0757137cee1062f9464ee158
4
+ data.tar.gz: 64b5fd5577bb7e1c7f0bb7b156e7f6eaf9360461d1e676eeec1adf237a56ed6a
5
5
  SHA512:
6
- metadata.gz: dea762339636ed621dbf8b44267fb6eeee6be97d8f20be236193ff2d8bdfc9e432cca22ec30ed150fa78c8f97d9e318ecc3ab1263c23f47bb54601f65edee995
7
- data.tar.gz: 8decb45d42b106fc52bc46e9f4575f2b58f4273e7d425ff9478259cb0c1ffd4603156957998abbb15d94515060f05e96a52960051dffc59610df8048ffd59dee
6
+ metadata.gz: c72918d4cc110e29cf09374336f14158fcf974beb435990abf7a0499aaa6293a6b315bdc4daca0700a6508eaf4938e62e3ac6021082e88ae96bc02b32b2002ab
7
+ data.tar.gz: c265eb36b5b81ceaf227c619518c7642b63f175dd84ff28f6184caab09ab37ebe787558aa8d72d9587d963b48af8ae9e74bc0a642fcb528923571b2fef49a094
@@ -0,0 +1,14 @@
1
+ name: Review App
2
+ on:
3
+ pull_request_target:
4
+ types: [opened, reopened, synchronize, labeled, closed]
5
+ jobs:
6
+ create-review-app:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Create Review App
10
+ uses: mheap/github-action-pr-heroku-review-app@v1
11
+ env:
12
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13
+ HEROKU_PIPELINE_ID: ${{ secrets.HEROKU_PIPELINE_ID }}
14
+ HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
@@ -1,3 +1,6 @@
1
+ # 2.2.0
2
+ * Add error list to API reference
3
+
1
4
  # 0.11.3
2
5
  * Change oas url constructor to be entire config parameter and not only partial
3
6
  * Bump websocket-extensions, fixes CVE-2020-7663
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nexmo-oas-renderer (2.1.0)
4
+ nexmo-oas-renderer (2.3.0)
5
5
  activemodel (~> 6.0)
6
6
  activesupport (~> 6.0)
7
7
  banzai (~> 0.1.2)
@@ -109,7 +109,7 @@ GEM
109
109
  hansi (~> 0.2.0)
110
110
  mustermann (= 1.1.1)
111
111
  neatjson (0.9)
112
- nexmo_markdown_renderer (0.4.0)
112
+ nexmo_markdown_renderer (0.4.2)
113
113
  activemodel (~> 6.0)
114
114
  banzai (~> 0.1.2)
115
115
  i18n (~> 1.7)
@@ -136,9 +136,9 @@ GEM
136
136
  parallel (1.19.2)
137
137
  parser (2.7.1.4)
138
138
  ast (~> 2.4.1)
139
- public_suffix (4.0.5)
139
+ public_suffix (4.0.6)
140
140
  rack (2.2.3)
141
- rack-protection (2.0.8.1)
141
+ rack-protection (2.1.0)
142
142
  rack
143
143
  rack-test (1.1.0)
144
144
  rack (>= 1.0, < 3)
@@ -210,10 +210,10 @@ GEM
210
210
  rb-inotify (~> 0.9, >= 0.9.7)
211
211
  shotgun (0.9.2)
212
212
  rack (>= 1.0)
213
- sinatra (2.0.8.1)
213
+ sinatra (2.1.0)
214
214
  mustermann (~> 1.0)
215
- rack (~> 2.0)
216
- rack-protection (= 2.0.8.1)
215
+ rack (~> 2.2)
216
+ rack-protection (= 2.1.0)
217
217
  tilt (~> 2.0)
218
218
  sprockets (4.0.2)
219
219
  concurrent-ruby (~> 1.0)
@@ -0,0 +1 @@
1
+ web: bundle exec ./exe/nexmo-oas-renderer
@@ -0,0 +1,15 @@
1
+ {
2
+ "buildpacks": [{ "url": "heroku/ruby" }],
3
+ "env": {
4
+ "RACK_ENV": "production",
5
+ "RAILS_ENV": "production",
6
+ "OAS_PATH": "samples"
7
+ },
8
+ "stack": "heroku-18",
9
+ "formation": {
10
+ "web": {
11
+ "quantity": 1,
12
+ "size": "free"
13
+ }
14
+ }
15
+ }
@@ -13,6 +13,7 @@ require_relative './presenters/open_api_specification'
13
13
  require_relative './presenters/navigation'
14
14
  require_relative './presenters/request_body_raw'
15
15
  require_relative './presenters/response_tabs'
16
+ require_relative './presenters/content_switcher'
16
17
  require_relative './helpers/render'
17
18
  require_relative './helpers/navigation'
18
19
  require_relative './helpers/summary'
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ module OAS
5
+ module Renderer
6
+ module Presenters
7
+ class ContentSwitcher
8
+ def initialize(format:, label:, theme_light:, force_type: nil)
9
+ @format = format
10
+ @panels = []
11
+ @label = label
12
+ @force_type = force_type
13
+ @theme_light = theme_light
14
+ end
15
+
16
+ def add_content(title:, content:, tab_id:, active:)
17
+ @panels.push({
18
+ 'title' => title,
19
+ 'content' => content,
20
+ 'x-tab-id' => tab_id,
21
+ 'active' => active,
22
+ })
23
+ end
24
+
25
+ def render
26
+ type = 'tabs'
27
+ type = 'dropdown' if @panels.length >= 8
28
+
29
+ type = @force_type if @force_type
30
+
31
+ [:"open_api/content_switcher/_#{type}", locals: {
32
+ panels: @panels,
33
+ format: @format,
34
+ label: @label,
35
+ switcher: self,
36
+ theme_light: @theme_light,
37
+ }]
38
+ end
39
+
40
+ def id
41
+ @id ||= "s-#{SecureRandom.hex}"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -8,7 +8,7 @@ module Nexmo
8
8
  module Renderer
9
9
  module Presenters
10
10
  class ResponseTabs
11
- attr_reader :format
11
+ attr_reader :format, :switcher
12
12
 
13
13
  def initialize(format, response, content, endpoint, theme_light: nil)
14
14
  @format = format
@@ -16,6 +16,7 @@ module Nexmo
16
16
  @content = content
17
17
  @endpoint = endpoint
18
18
  @theme_light = theme_light
19
+ @switcher ||= @response.schema(@format)['x-switcher']
19
20
  end
20
21
 
21
22
  def tab_links
@@ -1,4 +1,9 @@
1
- if(document.querySelector(".oas-wrapper")){
1
+ document.addEventListener("DOMContentLoaded", function() {
2
+ // Only run this JS on OAS pages
3
+ if(!document.querySelector(".oas-wrapper")){
4
+ return;
5
+ }
6
+
2
7
  if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
3
8
  var queryString = new URLSearchParams(window.location.search);
4
9
  if (!queryString.get('theme')) {
@@ -7,59 +12,64 @@ if(document.querySelector(".oas-wrapper")){
7
12
  }
8
13
  }
9
14
 
10
- document.addEventListener("DOMContentLoaded", function() {
11
- // Handle people clicking on oneOf tabs by changing every one on the page
12
- var oneOfTabs = document.querySelectorAll('[data-tab-link]');
13
- Array.from(oneOfTabs).forEach(function (element) {
14
- element.addEventListener('click', function (event) {
15
- var link = event.target.getAttribute('data-tab-link');
16
- var matchingTabs = document.querySelectorAll('[data-tab-link="' + link + '"]');
17
- Array.from(matchingTabs).forEach(function (element) {
18
- element.dispatchEvent(new Event('toggle'));
19
- });
15
+ // Handle people clicking on oneOf tabs by changing every one on the page
16
+ var oneOfTabs = document.querySelectorAll('[data-tab-link]');
17
+ Array.from(oneOfTabs).forEach(function (element) {
18
+ element.addEventListener('click', function (event) {
19
+ var link = event.target.getAttribute('data-tab-link');
20
+ var matchingTabs = document.querySelectorAll('[data-tab-link="' + link + '"]');
21
+ Array.from(matchingTabs).forEach(function (element) {
22
+ element.dispatchEvent(new Event('toggle'));
23
+
24
+ // Switch anything that's in a dropdown
25
+ if (element.parentNode.className.indexOf("Vlt-dropdown__panel__content") !== -1) {
26
+ // This is *very* structure dependent, but also the most compatible way to handle it
27
+ var panel = element.parentNode.parentNode;
28
+ var titleNodes = Array.from(panel.previousSibling.previousSibling.firstChild.childNodes);
29
+ titleNodes[1].textContent = element.textContent;
30
+ }
20
31
  });
21
32
  });
33
+ });
22
34
 
23
- var toggleTopNav = function(event, closeOnly) {
35
+ var toggleTopNav = function(event, closeOnly) {
24
36
 
25
- if (event) {
26
- if (!Array.from(event.target.classList).includes("oas-trigger")) {
27
- return;
28
- }
29
- }
30
-
31
- var c = document.querySelector('.oas-trigger-content');
32
- if (closeOnly === true) {
33
- c.style.display = "none";
37
+ if (event) {
38
+ if (!Array.from(event.target.classList).includes("oas-trigger")) {
34
39
  return;
35
40
  }
36
- c.style.display = c.style.display == 'block' ? 'none' : "block";
37
- };
41
+ }
38
42
 
39
- if (document.querySelector('.oas-trigger')) {
40
- document.querySelector('.oas-trigger').addEventListener("click", toggleTopNav);
43
+ var c = document.querySelector('.oas-trigger-content');
44
+ if (closeOnly === true) {
45
+ c.style.display = "none";
46
+ return;
41
47
  }
48
+ c.style.display = c.style.display == 'block' ? 'none' : "block";
49
+ };
50
+
51
+ if (document.querySelector('.oas-trigger')) {
52
+ document.querySelector('.oas-trigger').addEventListener("click", toggleTopNav);
53
+ }
42
54
 
43
- document.querySelectorAll('a').forEach((element) => {
44
- var href = element.getAttribute("href");
45
- if (!href){ return; }
46
- if (href.slice(0,1) !== "#"){ return; }
47
- element.addEventListener('click', function (event) {
48
- event.preventDefault();
55
+ document.querySelectorAll('a').forEach((element) => {
56
+ var href = element.getAttribute("href");
57
+ if (!href){ return; }
58
+ if (href.slice(0,1) !== "#"){ return; }
59
+ element.addEventListener('click', function (event) {
60
+ event.preventDefault();
49
61
 
50
- toggleTopNav(null, true);
62
+ toggleTopNav(null, true);
51
63
 
52
- var to = document.querySelector(event.target.hash)
53
- history.pushState({}, '', event.target.href);
54
- window.scrollTo({
55
- top: (window.scrollY + to.getBoundingClientRect().y) - 70,
56
- left: 0,
57
- })
64
+ var to = document.querySelector(event.target.hash)
65
+ history.pushState({}, '', event.target.href);
66
+ window.scrollTo({
67
+ top: (window.scrollY + to.getBoundingClientRect().y) - 70,
68
+ left: 0,
69
+ })
58
70
 
59
71
 
60
- });
61
72
  });
62
-
63
73
  });
64
- }
74
+ });
65
75
 
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Copyright (c) 2001-present, Vonage.
3
+ *
4
+ * Dropdowns (requires core)
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ Volta.dropdown = function () {
10
+ var _class = {
11
+ wrapper: 'Vlt-dropdown',
12
+ block: 'Vlt-dropdown__block',
13
+ btn: 'Vlt-dropdown__trigger',
14
+ btnLegacy: 'Vlt-dropdown__btn',
15
+ dismissed: 'Vlt-callout--dismissed',
16
+ expanded: 'Vlt-dropdown--expanded',
17
+ label: 'Vlt-dropdown__label',
18
+ link: 'Vlt-dropdown__link',
19
+ noCloseLink: 'Vlt-dropdown__link--noclose',
20
+ noCloseBlock: 'Vlt-dropdown__block--noclose',
21
+ panel: 'Vlt-dropdown__panel',
22
+ panelContent: 'Vlt-dropdown__panel__content',
23
+ selection: 'Vlt-dropdown__selection',
24
+ switch: 'Vlt-switch',
25
+ switchSlider: 'Vlt-switch__slider'
26
+ }
27
+
28
+ function Dropdown() {}
29
+
30
+ Dropdown.prototype = {
31
+ init: function(element, supressClickHandler) {
32
+ this.dropdown = element;
33
+ this.selection = this.dropdown.querySelector('.' + _class.selection);
34
+ this.isSelectionVisible = !!this.selection;
35
+ this.btn = this.dropdown.querySelector('.' + _class.btn) || this.dropdown.querySelector('.' + _class.btnLegacy);
36
+ this._suppress = supressClickHandler;
37
+
38
+ if(!this._suppress) {
39
+ this._addEventListener();
40
+ }
41
+ },
42
+ _addEventListener: function(){
43
+ var openHandler = this.open.bind(this);
44
+ this.dropdown.addEventListener('click', openHandler, { once: true })
45
+ },
46
+ close: function(text) {
47
+ if(text) {
48
+ this._setDropdownSelectionText(text);
49
+ }
50
+ this.dropdown.classList.remove(_class.expanded);
51
+
52
+ if(!this._suppress){
53
+ this._addEventListener();
54
+ }
55
+
56
+ },
57
+ _closeEventHandler: undefined,
58
+ _closeEvent: function(e) {
59
+ var targetIsPanel = Volta._hasClass(e.target, _class.panel);
60
+ var parentIsPanel = Volta._closest(e.target, '.' + _class.panelContent, _class.panel) !== null;
61
+ var parentLink = Volta._closest(e.target, '.' + _class.link, _class.wrapper);
62
+ var parentIsLink = parentLink && parentLink.length === 1;
63
+ var isSwitchSlider = Volta._hasClass(e.target, _class.switchSlider);
64
+ var isParentSwitch = Volta._closest(e.target,'.' + _class.switch, _class.link);
65
+ var isNoClose = Volta._hasClass(e.target, _class.noCloseLink) || Volta._hasClass(e.target, _class.noCloseBlock);
66
+ var isNoCloseParent = Volta._closest(e.target,'.' + _class.noCloseLink, _class.link) || Volta._closest(e.target,'.' + _class.noCloseBlock, _class.noCloseBlock);
67
+ var isInput = e.target instanceof HTMLInputElement;
68
+
69
+ if(!targetIsPanel && !parentIsPanel && !parentIsLink && !isNoClose && !isInput && !isNoCloseParent) {
70
+ e.preventDefault();
71
+ e.stopPropagation();
72
+ }
73
+
74
+ if(isSwitchSlider || isParentSwitch || isNoClose || isInput || isNoCloseParent) {
75
+ return null;
76
+ }
77
+
78
+ var text;
79
+ if(parentIsPanel && Volta._hasClass(e.target, _class.label)) {
80
+ text = e.target.innerHTML;
81
+ } else if (parentIsPanel) {
82
+ var label = e.target.querySelector('.' + _class.label);
83
+ if(label) {
84
+ text = label.innerHTML;
85
+ }
86
+ }
87
+
88
+ this.close(text);
89
+
90
+ document.querySelector('body').removeEventListener('click', this._closeEventHandler );
91
+ },
92
+ open: function(event) {
93
+ if(event) {
94
+ event.preventDefault();
95
+ event.stopPropagation();
96
+ }
97
+
98
+ this.dropdown.classList.add(_class.expanded);
99
+
100
+ if(!this._suppress){
101
+ this._closeEventHandler = this._closeEvent.bind(this);
102
+ document.querySelector('body').addEventListener('click', this._closeEventHandler );
103
+ }
104
+ },
105
+ _setDropdownSelectionText: function(text) {
106
+ if(this.isSelectionVisible) {
107
+ this.selection.innerText = text;
108
+ } else {
109
+ this.btn.innerText = text;
110
+ this.btn.value = text;
111
+ }
112
+ },
113
+ _suppress: false
114
+ }
115
+
116
+ return {
117
+ create: create,
118
+ init: attachDropdownHandlers
119
+ }
120
+
121
+ /**
122
+ * @public
123
+ *
124
+ * @description Attach a listeners to dropdowns
125
+ */
126
+ function attachDropdownHandlers() {
127
+ document.querySelectorAll('.' + _class.wrapper).forEach(attachHandler);
128
+
129
+ function attachHandler(dropdown) {
130
+ create(dropdown);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * @private
136
+ *
137
+ * @description Create a dropdown element
138
+ * @param {HTMLElement} element
139
+ */
140
+ function create(element){
141
+ var dropdown = Object.create(Dropdown.prototype, {})
142
+ dropdown.init(element);
143
+ return dropdown;
144
+ }
145
+ }();
@@ -3,7 +3,7 @@
3
3
  module Nexmo
4
4
  module OAS
5
5
  module Renderer
6
- VERSION = '2.1.0'
6
+ VERSION = '2.3.0'
7
7
  end
8
8
  end
9
9
  end
@@ -5,10 +5,11 @@
5
5
  <script src="/assets/javascripts/volta.accordion.js"></script>
6
6
  <script src="/assets/javascripts/volta.tabs.js"></script>
7
7
  <script src="/assets/javascripts/volta.modal.js"></script>
8
+ <script src="/assets/javascripts/volta.dropdown.js"></script>
8
9
  <script src="/assets/javascripts/volta.tooltip.js"></script>
9
10
  <script src="/assets/javascripts/nexmo-oas-renderer.js?a=1"></script>
10
11
  <script src="/assets/javascripts/components/format.js"></script>
11
12
  <script type="text/javascript">
12
- Volta.init(["accordion", "tab", "modal", "tooltip"]);
13
+ Volta.init(["accordion", "tab", "modal", "tooltip", "dropdown"]);
13
14
  new Format
14
15
  </script>
@@ -0,0 +1,34 @@
1
+ <% if definition.raw['x-errors'] %>
2
+ <div>
3
+ <div class="Vlt-grid">
4
+ <div class="Vlt-col oas-left-panel" style="padding-bottom: 36px;">
5
+ <h2 id="errors">Errors</h2>
6
+ <p>
7
+ The following is a non-exhaustive list of error codes that may occur while using this API. These codes are in addition to any of our <a href="/api-errors">generic error codes</a>.
8
+ </p>
9
+ </div>
10
+ <div class="Vlt-col oas-right-panel"></div>
11
+ </div>
12
+ <div class="Vlt-grid">
13
+ <div class="Vlt-col Vlt-table oas-left-panel">
14
+ <table>
15
+ <thead>
16
+ <tr>
17
+ <th>Code</th>
18
+ <th>Details</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% definition.raw['x-errors'].each do |name, body| %>
23
+ <tr>
24
+ <td><a href="/api-errors/<%= @specification.definition_name %>#<%= name %>"><b><%= name %></b></a></td>
25
+ <td><%= body['description'].render_markdown %> </td>
26
+ </tr>
27
+ <% end %>
28
+ </tbody>
29
+ </table>
30
+ </div>
31
+ <div class="Vlt-col oas-right-panel"></div>
32
+ </div>
33
+ </div>
34
+ <% end %>
@@ -39,6 +39,20 @@
39
39
  </div>
40
40
  </div>
41
41
 
42
+
43
+ <% if @specification.groups.size > 1 %>
44
+ <h4>Jump to:</h4>
45
+ <div style="margin-bottom: 30px; padding: 8px;">
46
+ <% @specification.groups.each do |name, endpoints| %>
47
+ <% if name %>
48
+ <% group = definition.raw['tags'].detect { |tag| tag['name'].capitalize == name.capitalize } %>
49
+ <p><a href="#<%= group['name'].parameterize %>"><%= group['name'] %> &raquo;</a></p>
50
+ <p class="Vlt-grey-darker"><%= group['description']&.render_markdown %></p>
51
+ <% end %>
52
+ <% end %>
53
+ </div>
54
+ <% end %>
55
+
42
56
  <%
43
57
  # If there's only one group, everything is untagged
44
58
  if @specification.groups.size === 1
@@ -13,6 +13,9 @@
13
13
  <a href="#webhooks" class="Vlt-btn Vlt-btn--tertiary group-link">Webhooks</a>
14
14
  <% end %>
15
15
 
16
+ <% if definition.raw['x-errors'] %>
17
+ <a href="#errors" class="Vlt-btn Vlt-btn--tertiary group-link">Errors</a>
18
+ <% end %>
16
19
 
17
20
  <% if @specification.formats.size > 1 %>
18
21
  <div class="Vlt-native-dropdown">
@@ -44,6 +47,10 @@
44
47
  <a href="#top" class="Vlt-btn Vlt-btn--tertiary group-link">Available Operations</a>
45
48
  <% end %>
46
49
 
50
+ <% if definition.raw['x-errors'] %>
51
+ <a href="#errors" class="Vlt-btn Vlt-btn--tertiary group-link">Errors</a>
52
+ <% end %>
53
+
47
54
  <br />
48
55
  <br />
49
56
 
@@ -29,14 +29,7 @@
29
29
  <% unless endpoint.request_body.exhibits_one_of_multiple_schemas?(format) %>
30
30
 
31
31
  <%
32
- # @mheap: This is hacky handling for allOf, but it works for now
33
- # We probably want real allOf support in OasParser, but that's more time than I have right now
34
- allOf = endpoint.request_body.content[format]['schema']['allOf']
35
- if allOf
36
- params = endpoint.request_body.handle_all_of(allOf)
37
- else
38
- params = endpoint.request_body.properties_for_format(format)
39
- end
32
+ params = endpoint.request_body.properties_for_format(format)
40
33
  if params
41
34
  %>
42
35
 
@@ -46,9 +39,10 @@
46
39
 
47
40
  <%
48
41
  # This can likely be better done as a presenter, but it works for now
49
- schema = endpoint.request_body.content[format]['schema']['oneOf']
42
+ request = endpoint.request_body.content[format]['schema']
43
+ schema = request['oneOf']
50
44
  %>
51
- <%= erb :'open_api/_tabbed_parameters', locals: { body: endpoint.request_body, schema: schema, format: format, callback: callback } %>
45
+ <%= erb :'open_api/_tabbed_parameters', locals: { body: endpoint.request_body, request: request, schema: schema, format: format, callback: callback } %>
52
46
  <%
53
47
  end
54
48
  end
@@ -1,18 +1,16 @@
1
- <% tabs = Nexmo::OAS::Renderer::Presenters::ResponseTabs.new(format, response, content, endpoint, theme_light: @theme_light) %>
1
+ <%
2
+ tabs = Nexmo::OAS::Renderer::Presenters::ResponseTabs.new(format, response, content, endpoint, theme_light: @theme_light)
2
3
 
3
- <div class='Vlt-tabs js-format' data-format='<%= tabs.format %>'>
4
- <div class='Vlt-tabs__header' role='tablist' aria-label='Responses'>
5
- <% tabs.tab_links.each do |link| %>
6
- <div role='tab' class='<%= link.css_classes %>' <% if link.data_tab_link %>data-tab-link="<%= link.data_tab_link %>"<% end %>>
7
- <%= link.content %>
8
- </div>
9
- <% end %>
10
- </div>
11
- <div class='Vlt-tabs__content'>
12
- <% tabs.tab_panels.each do |panel| %>
13
- <div class='<%= panel.css_classes %>'>
14
- <%= erb *panel.content %>
15
- </div>
16
- <% end %>
17
- </div>
18
- </div>
4
+ switcher = Nexmo::OAS::Renderer::Presenters::ContentSwitcher.new(label: "Response Example", format: format, force_type: tabs.switcher, theme_light: @theme_light)
5
+
6
+ tabs.tab_links.each_with_index do |v,k|
7
+ switcher.add_content(
8
+ title: v.content,
9
+ content: (erb *tabs.tab_panels[k].content),
10
+ tab_id: v.data_tab_link,
11
+ active: k == 0
12
+ )
13
+ end
14
+ %>
15
+
16
+ <%= erb *switcher.render %>
@@ -29,22 +29,23 @@
29
29
  </div>
30
30
  <% end %>
31
31
 
32
- <% missing.each do |format| %>
33
- <div class="js-format Nxd-api__response" data-format="<%= format %>">
34
- <div class="Vlt-callout Vlt-callout--warning">
35
- <i></i>
36
- <div class="Vlt-callout__content">
37
- <p>This endpoint does not support <code><%= format %></code></p>
38
- </div>
39
- </div>
40
- </div>
41
- <% end %>
42
-
43
32
  <% if response.code == '204' %>
44
33
  <% content = response.description ? response.description : 'No content' %>
45
34
  <pre class="language-json Vlt-prism--copy-disabled <%= @theme_light ? 'Vlt-prism--dark' : '' %>"><code><%= content %></code></pre>
35
+ <% else %>
36
+ <% missing.each do |format| %>
37
+ <div class="js-format Nxd-api__response" data-format="<%= format %>">
38
+ <div class="Vlt-callout Vlt-callout--warning">
39
+ <i></i>
40
+ <div class="Vlt-callout__content">
41
+ <p>This endpoint does not support <code><%= format %></code></p>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <% end %>
46
46
  <% end %>
47
- </div>
47
+
48
+ </div>
48
49
 
49
50
  <% end %>
50
51
  </div>
@@ -12,8 +12,7 @@
12
12
  s
13
13
  end
14
14
 
15
-
16
- panels = []
15
+ switcher = Nexmo::OAS::Renderer::Presenters::ContentSwitcher.new(label: "Request Details", format: format, force_type: request['x-switcher'], theme_light: @theme_light)
17
16
 
18
17
  schemas.each_with_index do |schema, index|
19
18
  if schema['properties']
@@ -25,40 +24,21 @@
25
24
  end
26
25
  end
27
26
 
28
- panels.push({
29
- 'description' => schema['title'] || schema['description'],
30
- 'parameters' => schema['properties'],
31
- 'oneOf' => schema['oneOf'],
32
- 'x-tab-id' => schema['x-tab-id'] || schema['title'].parameterize,
33
- 'active' => index == 0
34
- })
27
+
28
+ if schema['oneOf']
29
+ content = (erb :'open_api/_tabbed_parameters', locals: { body: body, request: schema, schema: schema['oneOf'], format: format, callback: callback })
30
+ else
31
+ content = (erb :'open_api/_parameters', locals: { parameters: schema['properties'], callback: callback })
32
+ end
33
+
34
+ switcher.add_content(
35
+ title: schema['title'] || schema['description'],
36
+ content: content,
37
+ tab_id: schema['x-tab-id'],
38
+ active: index == 0
39
+ )
35
40
  end
36
41
  %>
37
42
 
38
- <div class="Vlt-tabs js-format" data-format="<%= format %>">
39
- <div class="Vlt-tabs__header" role="tablist" aria-label="Responses">
40
- <% panels.each do |panel| %>
41
- <div role="tab" data-tab-link="<%= panel['x-tab-id'] %>" class="Vlt-tabs__link <%= panel['active'] ? 'Vlt-tabs__link_active' : '' %>">
42
- <%= panel['description'] %>
43
- </div>
44
- <% end %>
45
- </div>
46
- <div class="Vlt-tabs__content">
47
- <% panels.each do |panel| %>
48
- <div class="Vlt-tabs__panel <%= panel['active'] ? 'Vlt-tabs__panel_active' : '' %>">
49
- <%
50
- # Nested oneOf?
51
- if panel['oneOf']
52
- %>
53
- <%= erb :'open_api/_tabbed_parameters', locals: { body: body, schema: panel['oneOf'], format: format, callback: callback } %>
54
- <%
55
- else
56
- %>
57
-
58
- <%= erb :'open_api/_parameters', locals: { parameters: panel['parameters'], callback: callback } %>
59
- <% end %>
60
- </div>
61
- <% end %>
62
- </div>
63
- </div>
43
+ <%= erb *switcher.render %>
64
44
 
@@ -0,0 +1,22 @@
1
+ <div class="Vlt-dropdown Vlt-dropdown--full-width">
2
+ <div class="Vlt-dropdown__trigger Vlt-dropdown__trigger--btn"><button class="Vlt-btn Vlt-btn--<%= (theme_light ? "secondary" : "tertiary") %>"><%= label %>: <span class="Vlt-dropdown__selection"><%= panels[0]['title'] %></span></button></div>
3
+ <div class="Vlt-dropdown__panel">
4
+ <div data-tab-content="<%= switcher.id %>" class="Vlt-dropdown__panel__content">
5
+ <% panels.each do |panel| %>
6
+ <div role="tab" data-tab-link="<%= panel['x-tab-id'] || panel['title'].parameterize %>" class="Vlt-dropdown__link Vlt-dropdown__label Vlt-js-tabs__link"><%= panel['title'] %></div>
7
+ <% end %>
8
+ </div>
9
+ </div>
10
+ </div>
11
+
12
+
13
+ <div class="js-format" data-format="<%= format %>">
14
+ <div id="<%= switcher.id %>" class="Vlt-js-tabs__content">
15
+ <% panels.each do |panel| %>
16
+ <div class="Vlt-js-tabs__panel <%= panel['active'] ? 'Vlt-js-tabs__panel_active' : '' %>">
17
+ <%= panel['content'] %>
18
+ </div>
19
+ <% end %>
20
+ </div>
21
+ </div>
22
+
@@ -0,0 +1,18 @@
1
+ <div class="Vlt-tabs js-format" data-format="<%= format %>">
2
+ <div class="Vlt-tabs__header" role="tablist" aria-label="<%= label %>">
3
+ <% panels.each do |panel| %>
4
+ <div role="tab" data-tab-link="<%= panel['x-tab-id'] || panel['title'].parameterize %>" class="Vlt-tabs__link <%= panel['active'] ? 'Vlt-tabs__link_active' : '' %>">
5
+ <%= panel['title'] %>
6
+ </div>
7
+ <% end %>
8
+ </div>
9
+ <div class="Vlt-tabs__content">
10
+ <% panels.each do |panel| %>
11
+ <div class="Vlt-tabs__panel <%= panel['active'] ? 'Vlt-tabs__panel_active' : '' %>">
12
+ <%= panel['content'] %>
13
+ </div>
14
+ <% end %>
15
+ </div>
16
+ </div>
17
+
18
+
@@ -21,6 +21,6 @@
21
21
  <% end %>
22
22
 
23
23
  <%= erb :'open_api/_webhooks', locals: { definition: definition } %>
24
-
24
+ <%= erb :'open_api/_errors', locals: {definition: definition } %>
25
25
  </div>
26
26
  </div>
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  # Specify which files should be added to the gem when it is released.
26
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
27
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|samples)/}) }
29
29
  end
30
30
  spec.bindir = 'exe'
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexmo-oas-renderer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabian Rodriguez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-20 00:00:00.000000000 Z
11
+ date: 2020-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -243,6 +243,7 @@ extensions: []
243
243
  extra_rdoc_files: []
244
244
  files:
245
245
  - ".env.example"
246
+ - ".github/workflows/pull_request-review.yml"
246
247
  - ".github/workflows/push-docker-publish.yml"
247
248
  - ".gitignore"
248
249
  - ".rspec"
@@ -254,8 +255,10 @@ files:
254
255
  - Gemfile
255
256
  - Gemfile.lock
256
257
  - LICENSE.txt
258
+ - Procfile
257
259
  - README.md
258
260
  - Rakefile
261
+ - app.json
259
262
  - bin/console
260
263
  - bin/setup
261
264
  - exe/nexmo-oas-renderer
@@ -271,6 +274,7 @@ files:
271
274
  - lib/nexmo/oas/renderer/helpers/summary.rb
272
275
  - lib/nexmo/oas/renderer/helpers/url.rb
273
276
  - lib/nexmo/oas/renderer/presenters/api_specification.rb
277
+ - lib/nexmo/oas/renderer/presenters/content_switcher.rb
274
278
  - lib/nexmo/oas/renderer/presenters/endpoint.rb
275
279
  - lib/nexmo/oas/renderer/presenters/groups.rb
276
280
  - lib/nexmo/oas/renderer/presenters/navigation.rb
@@ -300,6 +304,7 @@ files:
300
304
  - lib/nexmo/oas/renderer/public/assets/javascripts/tooltip.min.js
301
305
  - lib/nexmo/oas/renderer/public/assets/javascripts/volta.accordion.js
302
306
  - lib/nexmo/oas/renderer/public/assets/javascripts/volta.core.js
307
+ - lib/nexmo/oas/renderer/public/assets/javascripts/volta.dropdown.js
303
308
  - lib/nexmo/oas/renderer/public/assets/javascripts/volta.modal.js
304
309
  - lib/nexmo/oas/renderer/public/assets/javascripts/volta.tabs.js
305
310
  - lib/nexmo/oas/renderer/public/assets/javascripts/volta.tooltip.js
@@ -348,6 +353,7 @@ files:
348
353
  - lib/nexmo/oas/renderer/views/open_api/_callbacks.erb
349
354
  - lib/nexmo/oas/renderer/views/open_api/_code_examples.erb
350
355
  - lib/nexmo/oas/renderer/views/open_api/_endpoint.erb
356
+ - lib/nexmo/oas/renderer/views/open_api/_errors.erb
351
357
  - lib/nexmo/oas/renderer/views/open_api/_header.erb
352
358
  - lib/nexmo/oas/renderer/views/open_api/_model.erb
353
359
  - lib/nexmo/oas/renderer/views/open_api/_navigation.erb
@@ -365,6 +371,8 @@ files:
365
371
  - lib/nexmo/oas/renderer/views/open_api/_tabbed_parameters.erb
366
372
  - lib/nexmo/oas/renderer/views/open_api/_tabbed_single_parameter.erb
367
373
  - lib/nexmo/oas/renderer/views/open_api/_webhooks.erb
374
+ - lib/nexmo/oas/renderer/views/open_api/content_switcher/_dropdown.erb
375
+ - lib/nexmo/oas/renderer/views/open_api/content_switcher/_tabs.erb
368
376
  - lib/nexmo/oas/renderer/views/open_api/show.erb
369
377
  - lib/nexmo/oas/renderer/views/static/404.erb
370
378
  - nexmo-oas-renderer.gemspec