mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Added a view for the API docs
This commit is contained in:
parent
bed2498667
commit
45b5e631e2
@ -106,7 +106,7 @@ class ApiDocsGenerator
|
||||
return strpos($route->uri, 'api/') === 0;
|
||||
})->map(function ($route) {
|
||||
[$controller, $controllerMethod] = explode('@', $route->action['uses']);
|
||||
$baseModelName = explode('/', $route->uri)[1];
|
||||
$baseModelName = explode('.', explode('/', $route->uri)[1])[0];
|
||||
$shortName = $baseModelName . '-' . $controllerMethod;
|
||||
return [
|
||||
'name' => $shortName,
|
||||
|
@ -13,9 +13,9 @@ class ApiDocsController extends ApiController
|
||||
public function display()
|
||||
{
|
||||
$docs = $this->getDocs();
|
||||
dd($docs);
|
||||
// TODO - Build view for API docs
|
||||
return view('');
|
||||
return view('api-docs.index', [
|
||||
'docs' => $docs,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
use BookStack\Entities\Book;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Exceptions\NotifyException;
|
||||
use BookStack\Facades\Activity;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class BooksApiController extends ApiController
|
||||
{
|
||||
@ -41,8 +44,8 @@ class BooksApiController extends ApiController
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new book.
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* Create a new book in the system.
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
@ -66,7 +69,7 @@ class BooksApiController extends ApiController
|
||||
|
||||
/**
|
||||
* Update the details of a single book.
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
@ -81,9 +84,9 @@ class BooksApiController extends ApiController
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a book from the system.
|
||||
* @throws \BookStack\Exceptions\NotifyException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* Delete a single book from the system.
|
||||
* @throws NotifyException
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
public function delete(string $id)
|
||||
{
|
||||
|
18
resources/js/components/details-highlighter.js
Normal file
18
resources/js/components/details-highlighter.js
Normal file
@ -0,0 +1,18 @@
|
||||
import Code from "../services/code"
|
||||
class DetailsHighlighter {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.dealtWith = false;
|
||||
elem.addEventListener('toggle', this.onToggle.bind(this));
|
||||
}
|
||||
|
||||
onToggle() {
|
||||
if (this.dealtWith) return;
|
||||
|
||||
Code.highlightWithin(this.elem);
|
||||
this.dealtWith = true;
|
||||
}
|
||||
}
|
||||
|
||||
export default DetailsHighlighter;
|
@ -30,6 +30,7 @@ import settingColorPicker from "./setting-color-picker";
|
||||
import entityPermissionsEditor from "./entity-permissions-editor";
|
||||
import templateManager from "./template-manager";
|
||||
import newUserPassword from "./new-user-password";
|
||||
import detailsHighlighter from "./details-highlighter";
|
||||
|
||||
const componentMapping = {
|
||||
'dropdown': dropdown,
|
||||
@ -64,6 +65,7 @@ const componentMapping = {
|
||||
'entity-permissions-editor': entityPermissionsEditor,
|
||||
'template-manager': templateManager,
|
||||
'new-user-password': newUserPassword,
|
||||
'details-highlighter': detailsHighlighter,
|
||||
};
|
||||
|
||||
window.components = {};
|
||||
|
@ -87,9 +87,20 @@ const modeMap = {
|
||||
* Highlight pre elements on a page
|
||||
*/
|
||||
function highlight() {
|
||||
let codeBlocks = document.querySelectorAll('.page-content pre, .comment-box .content pre');
|
||||
for (let i = 0; i < codeBlocks.length; i++) {
|
||||
highlightElem(codeBlocks[i]);
|
||||
const codeBlocks = document.querySelectorAll('.page-content pre, .comment-box .content pre');
|
||||
for (const codeBlock of codeBlocks) {
|
||||
highlightElem(codeBlock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight all code blocks within the given parent element
|
||||
* @param {HTMLElement} parent
|
||||
*/
|
||||
function highlightWithin(parent) {
|
||||
const codeBlocks = parent.querySelectorAll('pre');
|
||||
for (const codeBlock of codeBlocks) {
|
||||
highlightElem(codeBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,6 +319,7 @@ function getMetaKey() {
|
||||
|
||||
export default {
|
||||
highlight: highlight,
|
||||
highlightWithin: highlightWithin,
|
||||
wysiwygView: wysiwygView,
|
||||
popupEditor: popupEditor,
|
||||
setMode: setMode,
|
||||
|
@ -236,4 +236,26 @@
|
||||
|
||||
.tag-list div:last-child .tag-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* API Docs
|
||||
*/
|
||||
.api-method {
|
||||
font-size: 0.75rem;
|
||||
background-color: #888;
|
||||
padding: $-xs;
|
||||
line-height: 1.3;
|
||||
opacity: 0.7;
|
||||
vertical-align: top;
|
||||
border-radius: 3px;
|
||||
color: #FFF;
|
||||
display: inline-block;
|
||||
min-width: 60px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
&[data-method="GET"] { background-color: #077b70 }
|
||||
&[data-method="POST"] { background-color: #cf4d03 }
|
||||
&[data-method="PUT"] { background-color: #0288D1 }
|
||||
&[data-method="DELETE"] { background-color: #ab0f0e }
|
||||
}
|
@ -213,6 +213,18 @@ blockquote {
|
||||
}
|
||||
}
|
||||
|
||||
.text-mono {
|
||||
font-family: $mono;
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.text-capitals {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.code-base {
|
||||
background-color: #F8F8F8;
|
||||
font-size: 0.80em;
|
||||
|
51
resources/views/api-docs/index.blade.php
Normal file
51
resources/views/api-docs/index.blade.php
Normal file
@ -0,0 +1,51 @@
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container pt-xl">
|
||||
|
||||
<div class="grid right-focus reverse-collapse">
|
||||
|
||||
<div>
|
||||
@foreach($docs as $model => $endpoints)
|
||||
<p class="text-uppercase text-muted mb-xm mt-l"><strong>{{ $model }}</strong></p>
|
||||
|
||||
@foreach($endpoints as $endpoint)
|
||||
<div class="mb-xs">
|
||||
<a href="#{{ $endpoint['name'] }}" class="text-mono">
|
||||
<span class="api-method" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
|
||||
/{{ $endpoint['uri'] }}
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@foreach($docs as $model => $endpoints)
|
||||
<section class="card content-wrap auto-height">
|
||||
<h1 class="list-heading text-capitals">{{ $model }}</h1>
|
||||
|
||||
@foreach($endpoints as $endpoint)
|
||||
<h5 id="{{ $endpoint['name'] }}" class="text-mono mb-m">
|
||||
<span class="api-method" data-method="{{ $endpoint['method'] }}">{{ $endpoint['method'] }}</span>
|
||||
{{ url($endpoint['uri']) }}
|
||||
</h5>
|
||||
<p class="mb-m">{{ $endpoint['description'] ?? '' }}</p>
|
||||
@if($endpoint['example_response'] ?? false)
|
||||
<details details-highlighter>
|
||||
<summary class="text-muted">Example Response</summary>
|
||||
<pre><code class="language-json">{{ $endpoint['example_response'] }}</code></pre>
|
||||
</details>
|
||||
<hr class="mt-m">
|
||||
@endif
|
||||
@endforeach
|
||||
</section>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@stop
|
Loading…
Reference in New Issue
Block a user