]
end
n.br
n.p 'API LIBRARIES'
n.div do |n|
n.push %[Ruby]
n.push %[Javascript]
n.push %[Python]
n.push %[C#]
end
n.br
n.p 'RESOURCES'
n.div do |n|
n.push %[Why we only prefer POST?]
end
end
end
n._col_9 do |n|
n.push index
n.push list_errors
end
end
end
end
end
end
# anchor link
def name_link name, top=nil
%[]
end
# render single icon
def icon data, size: 24, color: nil, style: nil
%[]
end
# top side navigation icons
def top_icons
tag.div({ style: 'float: right; margin-top: 18px;' }) do |n|
for icon in ICONS.values
next unless icon[:url]
n.push %[#{icon icon[:image]}]
end
end
end
# left side navigation
def left_nav
tag.div do |n|
Joshua.documented.each do |name|
n.a({ class:'btn btn-outline-info btn-sm', style: '-font-size: 14px; margin-bottom: 10px;', href: '#%s' % name}) do |n|
icon = name.opts.dig(:opts, :icon)
n.push self.icon icon, size: 20 if icon
n.push name.to_s.sub(/Api$/, '')
end
n.br
end
end
end
# render doc for all documented classes
def index
tag.div do |n|
for @klass in Joshua.documented
@opts = @klass.opts
icon = @opts.dig(:opts, :icon)
n._sticky(style: 'background: #f7f7f7; padding-bottom: 5px; padding-top: 30px; margin-top: 2px;') do |n|
n.push name_link @klass, 40
n.push self.icon icon, style: 'position: absolute; margin-left: -40px; margin-top: 1px; fill: #777; background: #f7f7f7;' if icon
n.h4 { @klass.to_s.sub(/Api$/, '') }
end
if desc = @opts.dig(:opts, :desc)
n.p { desc }
end
if detail = @opts.dig(:opts, :detail)
n.p { detail }
end
n.push render_type :member
n.push render_type :collection
n.br
n.hr
n.br
end
end
end
# render members or collection
def render_type name
base = @opts[name] || return
tag.div do |n|
n.br
n.h5 '%s methods' % name
for m_name, member in base
n.div do |n|
n.push render_method name: name, m_name: m_name, opts: member
end
end
end
end
# render api method
def render_method name:, m_name:, opts:
tag._box do |n|
# n.push %[]
anchor = [@klass, m_name].join('-')
n.push name_link anchor
n.h5 do |n|
n.push "#{m_name}"
n.push ' — %s' % opts[:desc] if opts[:desc]
end
n.p({style: 'margin: 20px 0 25px 0;'}) do |n|
path = @klass.api_path
path += '/:id' if name == :member
path += "/#{m_name}"
n.push %[]
end
if opts[:detail]
n.h6 'Details'
n.pre opts[:detail]
end
if mopts = opts[:params]
n.h6 'Params'
n.ul do |n|
for name, opt in mopts
n.li do |n|
n.push '%s: ' % name
n.push opt[:type]
data = []
data.push 'required' if opt[:required]
data.push 'default: %s' % opt[:default].to_s unless opt[:default].nil?
n.push ' — (%s)' % data.join(', ') if data.length > 0
end
end
end
end
end
end
def list_errors
tag.div do |n|
n.push name_link :api_errors
n.push icon ICONS[:error][:image], style: 'position: absolute; margin-left: -40px; margin-top: 1px; fill: #777;'
n.h4 { 'Named errors' }
n._box do |n|
if RESCUE_FROM.keys.length == 0
n.p 'No named errors defiend via'
n.code "rescue from :name, 'Error description'"
end
n._row({ style: 'margin-bottom: 30px;' }) do |n|
for key, desc in RESCUE_FROM
next if key == :all
next unless key.is_a?(Symbol) && desc.is_a?(String)
n._col_4 { "#{key}" }
n._col_8 { desc }
end
end
end
end
end
def modal_dialog
%[