Skip to content

Commit

Permalink
Style swagger documentation (#766)
Browse files Browse the repository at this point in the history
* Include swagger in project and start styling

* Style endpoint heading text

Switch over to using jQuery since its in the project anyway and
increases readability

* Add demo API key to docs

Key is limited to 500 requests per day per IP address

* Use /api for docs and /api-proxy for passthrough

* Change expected API route for api util tests
  • Loading branch information
jeremiak authored and brendansudol committed May 23, 2017
1 parent e9509d9 commit e21faa7
Show file tree
Hide file tree
Showing 10 changed files with 3,720 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
build
coverage
node_modules
public/swagger/vendor

.DS_Store
.env
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
},
"scripts": {
"start": "node build/server.js",
"postinstall": "npm run swagger",
"build": "export NODE_ENV=production && npm run build:client && npm run build:server && unset NODE_ENV",
"build:client": "webpack -p --progress --config webpack.client.config.js",
"build:server": "webpack --config webpack.server.config.js",
Expand All @@ -20,7 +21,8 @@
"test:debug": "node --debug-brk jest -i --env=jsdom",
"test:watch": "jest --env=jsdom --watch",
"coverage": "npm test -- --coverage",
"prettier": "prettier --single-quote --trailing-comma all --semi false --write \"{src,test}/**/*.js\""
"prettier": "prettier --single-quote --trailing-comma all --semi false --write \"{src,test}/**/*.js\"",
"swagger": "rm -f node_modules/swagger-ui/dist/*.html && mkdir -p public/swagger/vendor && cp -r node_modules/swagger-ui/dist/* public/swagger/vendor"
},
"dependencies": {
"autotrack": "^2.3.2",
Expand Down Expand Up @@ -65,6 +67,7 @@
"redux-logger": "^2.8.1",
"redux-thunk": "^2.1.0",
"source-map-support": "^0.4.11",
"swagger-ui": "^2.2.6",
"topojson": "^2.2.0"
},
"devDependencies": {
Expand Down
56 changes: 56 additions & 0 deletions public/swagger/crime-data-style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
* { box-shadow: none !important; }
.models, .topbar { display: none; }
.site .swagger-ui-wrap .wrapper { width: auto; }
.site .swagger-ui-wrap .info_title { font-family: serif; }
.site .swagger-ui-wrap .info p { color: inherit; font-size: 1rem; }
.site .swagger-ui-wrap .resource {
background-color: white !important;
margin-top: 1.3rem !important;
padding-left: 1rem;
padding-right: 1rem;
}
.site .swagger-ui-wrap li.resource:last-child { border-bottom: 1px solid #dddddd !important; }
.site .swagger-ui-wrap .resource .heading h2 { margin-top: 0; }
.site .swagger-ui-wrap .opblock-tag {
display: block;
margin: 0;
padding-left: 0;
position: relative;
}
.site .opblock-tag span { display: block; }
.site .swagger-ui-wrap .opblock-tag small {
display: block;
padding-left: 0;
}
.site .expand-operation {
position: absolute;
right: 0;
top: 35%;
}
.site .heading .http_method,
.site .path a,
.site .footer h4 { font-family: monospace !important; }

.site .heading .http_method { font-size: 1.2rem; }
.site .sandbox_header [type=submit] {
color: #fff !important;
background-color: #284152;
border: 1px solid transparent;
border-radius: 3px;
font-family: inherit;
font-size: inherit;
font-weight: bold;
text-decoration: none;
cursor: pointer;
line-height: 1.375rem;
padding: .5rem 1.5rem !important;
margin: 0;
height: auto;
vertical-align: middle;
-webkit-appearance: none;
}


.flex-justify {
justify-content: space-between;
}
246 changes: 246 additions & 0 deletions public/swagger/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Crime Data API Documentation</title>
<link href="/swagger/vendor/css/reset.css" media="screen" rel="stylesheet"/>
<link href="/swagger/vendor/css/screen.css" media="screen" rel="stylesheet"/>
<link rel="stylesheet" href="/app.css">
<link rel="stylesheet" href="/swagger/crime-data-style.css">
</head>
<body>
<div class="site">
<div class="clearfix p1 fs-10 sm-fs-12 line-height-1 bg-white">
<img
class="mr-tiny align-bottom"
alt="US flag"
width="18"
height="12"
src="/img/usa-flag.png"
/>
An official website of the United States government
</div>
<header class="pt3 pb2 md-p0 flex items-center bg-blue white">
<div class="md-flex flex-auto items-baseline px2 md-px6">
<div class="flex-auto">
<div class="inline-block">
<span class="mb1 fs-10 md-fs-12 caps bold line-height-1 blue-light-508 block">
Federal Bureau of Investigation
</span>
<a href="/" class="fs-24 md-fs-32 serif line-height-1 white">
Crime Data Explorer
</a>
</div>
</div>
</div>
</header>

<main class="site-main swagger-section container mx-auto my3">
<form class="bg-white hide p3" id="api-key-container">
<div>
<label class="block bold mb1 serif" for="api-key">Add your API key</label>
<input class="border border-blue col-6 monospace" type="text" id="api-key">
<button class="btn btn-primary" id="api-key-btn">Update</button>
</div>
<p class="mb0 mt1">You can signup for one at <a class="underline" href="https://api.data.gov/signup/">https://api.data.gov/signup/</a>.</p>
<div class="hide" id="api-key-current">
<span class="bold">Current API key:</span>
<span class="monospace mr1" id="current"></span>
</div>
</form>

<div class="swagger-ui-wrap" id="swagger-ui">
<div class="mt3 mb8 fs-14 caps sans-serif center">
<img
class="align-middle mr1"
width="30"
height="30"
src="/img/loading.svg"
alt="loading..."
/>
Loading
</div>
</div>
</main>

<footer class="py6 bg-blue white">
<div class="px2 md-px6">
<div class="mt1 mb4">
<span class="mb1 fs-10 md-fs-12 caps bold line-height-1 blue-light-508 block">
Federal Bureau of Investigation
</span>
<a href="/" class="fs-24 md-fs-32 serif line-height-1 white">
Crime Data Explorer
</a>
</div>
<div class="clearfix mxn2">
<div class="md-col md-col-5 px2 mb3 md-m0">
<ul class="m0 p0 fs-14 list-style-none left-bars">
<li>
<a class="cursor-pointer white caps" href="/">Home</a>
</li>
<li>
<a class="cursor-pointer white caps" href="/explorer/violent-crime">Explorer</a>
</li>
<li>
<a class="cursor-pointer white caps" href="/about">About</a>
</li>
<li>
<a class="cursor-pointer white caps" href="/downloads-and-docs">Downloads and Documentation</a>
</li>
</ul>
</div>
<div class="md-col md-col-5 px2 mb3 md-m0 fs-14 white">
<div class="mb1 bold fs-18 serif blue-light-508">
Contact us
</div>
<div class="mb3">
<div class="bold">
Criminal Justice Information Services (CJIS) Division
</div>
<a
class="mr1 pr1 white border-white border-right"
href="mailto:cjis_comm@leo.gov"
>
cjis_comm@leo.gov
</a>
<a class="white" href="tel:3046254995">
(304) 625-4995
</a>
</div>
<div class="bold">FBI Uniform Crime Reporting Program</div>
<div>
<span class="mr1 pr1 border-right border-white">
1000 Custer Hollow Road
</span>
<span>Clarksburg, WV 26306</span>
</div>
</div>
<div class="md-col md-col-2 px2 fs-14">
<div class="mb1 bold fs-18 serif blue-light-508">Follow us</div>
<div class="mb2">
<img
class="mr1 align-middle"
width="20"
src="/img/twitter.svg"
alt="twitter"
/>
<a class="white" href="https://twitter.com/fbi">@FBI</a>
</div>
<div>
<img
class="mr1 align-middle"
width="20"
src="/img/github.svg"
alt="github"
/>
<a
class="white"
href="https://github.com/18F/crime-data-explorer"
>
GitHub
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<script src="/swagger/vendor/lib/object-assign-pollyfill.js"></script>
<script src="/swagger/vendor/lib/jquery-1.8.0.min.js"></script>
<script src="/swagger/vendor/lib/jquery.slideto.min.js"></script>
<script src="/swagger/vendor/lib/jquery.wiggle.min.js"></script>
<script src="/swagger/vendor/lib/jquery.ba-bbq.min.js"></script>
<script src="/swagger/vendor/lib/handlebars-4.0.5.js"></script>
<script src="/swagger/vendor/lib/lodash.min.js"></script>
<script src="/swagger/vendor/lib/backbone-min.js"></script>
<script src="/swagger/vendor/swagger-ui.js"></script>
<script src="/swagger/vendor/lib/highlight.9.1.0.pack.js"></script>
<script src="/swagger/vendor/lib/highlight.9.1.0.pack_extended.js"></script>
<script src="/swagger/vendor/lib/jsoneditor.min.js"></script>
<script src="/swagger/vendor/lib/marked.js"></script>
<script src="/swagger/vendor/lib/swagger-oauth.js"></script>
<script>
;(function() {
window.swaggerUi = new SwaggerUi({
url: '/swagger/swagger.json',
dom_id: 'swagger-ui',
operationsSorter: 'alpha',
docExpansion: 'list',
onComplete: function() {
showApiKeyForm()
$('#api-key-btn').on('click', handleApiKeyChange)
restructureEndpointHeadings()
},
})

function changeApiKey(apiKey) {
var auth = new SwaggerClient.ApiKeyAuthorization('api_key', apiKey, 'query')
window.swaggerUi.api.clientAuthorizations.add('auth_name', auth)
}

function handleApiKeyChange(e) {
e.preventDefault()
var $field = $('#api-key')
var $btn = $('#api-key-btn')

changeApiKey($field.val())
updateCurrentApiKeyUI($field.val())

$field.val('')
}

function restructureEndpointHeadings() {
$('.resource > .heading').each(function(i, heading) {
var $heading = $(heading)
var $h2 = $heading.children('h2')
var $options = $heading.children('.options')

var $flex = $('<div class="flex flex-justify"></div>')
var split = $h2.text().split(' : ')
var $p = $('<p class="mb0"></p>')

if (split.length === 1) return

$h2.text(split[0])
$p.text(split[1])

$flex.append($h2)
$flex.append($options)

$heading.append($flex)
$heading.append($p)
})
}

function sanitize(str) {
var div = document.createElement('div')
div.appendChild(document.createTextNode(str))
return div.innerHTML
}

function showApiKeyForm() {
var $container = $('#api-key-container')
var $target = $('#api_info')
$target.append($container)
$container.removeClass('hide')
}

function updateCurrentApiKeyUI(newKey) {
var cleaned = sanitize(newKey)
var $container = $('#api-key-current')
$container.removeClass('hide')
$container.children('#current').text(cleaned)
}

window.swaggerUi.load()

const docsKey = 'iiHnOKfno2Mgkt5AynpvPpUQTEyxE77jo1RU8PIv'
changeApiKey(docsKey)
updateCurrentApiKeyUI(docsKey)
$('#api-key').val(docsKey)
})()
</script>
</body>
</html>
Loading

0 comments on commit e21faa7

Please sign in to comment.