Merge pull request #451 from liyasthomas/doc

API documentation page
This commit is contained in:
Liyas Thomas
2019-12-23 08:24:53 +05:30
committed by GitHub
7 changed files with 409 additions and 56 deletions

View File

@@ -52,15 +52,6 @@
"code"
]
},
{
"login": "terranblake",
"name": "Terran Blake",
"avatar_url": "https://avatars3.githubusercontent.com/u/8795767?v=4",
"profile": "https://www.lumahealth.io/",
"contributions": [
"code"
]
},
{
"login": "AndrewBastin",
"name": "Andrew Bastin",

View File

@@ -10,7 +10,7 @@
</p>
<p>
[![Travis Build Status](https://img.shields.io/travis/com/liyasthomas/postwoman?logo=Travis)](https://travis-ci.com/liyasthomas/postwoman) [![GitHub release](https://img.shields.io/github/release/liyasthomas/postwoman/all?logo=GitHub)](https://github.com/liyasthomas/postwoman/releases/latest) [![Website](https://img.shields.io/website?url=https%3A%2F%2Fpostwoman.io&logo=Postwoman)](https://postwoman.io) [![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen?style=flat)](CONTRIBUTING.md) [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors) [![Financial Contributors on Open Collective](https://img.shields.io/opencollective/all/postwoman?logo=Open-Collective&label=financial+contributors)](https://opencollective.com/postwoman) [![Donate on PayPal](https://img.shields.io/badge/support-PayPal-blue?logo=PayPal)](https://www.paypal.me/liyascthomas) [![Chat on Telegram](https://img.shields.io/badge/chat-Telegram-blueviolet?logo=Telegram)](https://t.me/postwoman_app) [![Chat on Discord](https://img.shields.io/badge/chat-Discord-violet?logo=discord)](https://discord.gg/GAMWxmR) [![Tweet](https://img.shields.io/twitter/url?url=https%3A%2F%2Fpostwoman.io%2F)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fpostwoman.io&text=%F0%9F%91%BD%20Postwoman%20%E2%80%A2%20API%20request%20builder%20-%20Helps%20you%20create%20your%20requests%20faster%2C%20saving%20you%20precious%20time%20on%20your%20development&original_referer=https%3A%2F%2Ftwitter.com%2Fshare%3Ftext%3D%25F0%259F%2591%25BD%2520Postwoman%2520%25E2%2580%25A2%2520API%2520request%2520builder%2520-%2520Helps%2520you%2520create%2520your%2520requests%2520faster%2C%2520saving%2520you%2520precious%2520time%2520on%2520your%2520development%26url%3Dhttps%3A%2F%2Fpostwoman.io%26hashtags%3Dpostwoman%26via%3Dliyasthomas&via=liyasthomas&hashtags=postwoman)
[![Travis Build Status](https://img.shields.io/travis/com/liyasthomas/postwoman?logo=Travis)](https://travis-ci.com/liyasthomas/postwoman) [![GitHub release](https://img.shields.io/github/release/liyasthomas/postwoman/all?logo=GitHub)](https://github.com/liyasthomas/postwoman/releases/latest) [![Website](https://img.shields.io/website?url=https%3A%2F%2Fpostwoman.io&logo=Postwoman)](https://postwoman.io) [![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen)](CONTRIBUTING.md) [![Financial Contributors on Open Collective](https://img.shields.io/opencollective/all/postwoman?logo=Open-Collective&label=financial+contributors)](https://opencollective.com/postwoman) [![Donate on PayPal](https://img.shields.io/badge/support-PayPal-blue?logo=PayPal)](https://www.paypal.me/liyascthomas) [![Chat on Telegram](https://img.shields.io/badge/chat-Telegram-blueviolet?logo=Telegram)](https://t.me/postwoman_app) [![Chat on Discord](https://img.shields.io/badge/chat-Discord-violet?logo=discord)](https://discord.gg/GAMWxmR) [![Tweet](https://img.shields.io/twitter/url?url=https%3A%2F%2Fpostwoman.io%2F)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fpostwoman.io&text=%F0%9F%91%BD%20Postwoman%20%E2%80%A2%20API%20request%20builder%20-%20Helps%20you%20create%20your%20requests%20faster%2C%20saving%20you%20precious%20time%20on%20your%20development&original_referer=https%3A%2F%2Ftwitter.com%2Fshare%3Ftext%3D%25F0%259F%2591%25BD%2520Postwoman%2520%25E2%2580%25A2%2520API%2520request%2520builder%2520-%2520Helps%2520you%2520create%2520your%2520requests%2520faster%2C%2520saving%2520you%2520precious%2520time%2520on%2520your%2520development%26url%3Dhttps%3A%2F%2Fpostwoman.io%26hashtags%3Dpostwoman%26via%3Dliyasthomas&via=liyasthomas&hashtags=postwoman)
</p>
<p>
@@ -171,6 +171,13 @@ _Official Postwoman Proxy is hosted by ApolloTV - **[Privacy policy](https://apo
_Requests with Pre-Request Scripts are indicated in History entries_
📄 **API Documentation**: Create and share dynamic API documentation easily, quickly.
**Use-cases:**
1. Add your requests to Collections and Folders
2. Export Collections and easily share your APIs with the rest of your team
3. Import Collections and Generate Documentation on-the-go
⌨️ **Keyboard Shortcuts**: Optimized for efficiency.
**Shortcuts:**
@@ -315,11 +322,10 @@ See the [CHANGELOG](CHANGELOG.md) file for details.
<td align="center"><a href="https://nicholaslaroux.com"><img src="https://avatars0.githubusercontent.com/u/1557529?v=4" width="100px;" alt="Nicholas La Roux"/><br /><sub><b>Nicholas La Roux</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=larouxn" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/yubathom"><img src="https://avatars3.githubusercontent.com/u/4117768?v=4" width="100px;" alt="Thomas Yuba"/><br /><sub><b>Thomas Yuba</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=yubathom" title="Code">💻</a></td>
<td align="center"><a href="http://www.linkedin.com/in/nickpalenchar"><img src="https://avatars1.githubusercontent.com/u/7539781?v=4" width="100px;" alt="Nick Palenchar"/><br /><sub><b>Nick Palenchar</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=nickpalenchar" title="Code">💻</a></td>
<td align="center"><a href="https://www.lumahealth.io/"><img src="https://avatars3.githubusercontent.com/u/8795767?v=4" width="100px;" alt="Terran Blake"/><br /><sub><b>Terran Blake</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=terranblake" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/AndrewBastin"><img src="https://avatars2.githubusercontent.com/u/9131943?v=4" width="100px;" alt="Andrew Bastin"/><br /><sub><b>Andrew Bastin</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=AndrewBastin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/vlad0337187"><img src="https://avatars1.githubusercontent.com/u/12682937?v=4" width="100px;" alt="Vladislav"/><br /><sub><b>Vladislav</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=vlad0337187" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/vlad0337187"><img src="https://avatars1.githubusercontent.com/u/12682937?v=4" width="100px;" alt="Vladislav"/><br /><sub><b>Vladislav</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=vlad0337187" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/izerozlu"><img src="https://avatars3.githubusercontent.com/u/17386157?v=4" width="100px;" alt="izerozlu"/><br /><sub><b>izerozlu</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=izerozlu" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/JacobAnavisca"><img src="https://avatars2.githubusercontent.com/u/21232366?v=4" width="100px;" alt="Jacob Anavisca"/><br /><sub><b>Jacob Anavisca</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=JacobAnavisca" title="Code">💻</a></td>
<td align="center"><a href="http://nityanandagohain.github.io"><img src="https://avatars3.githubusercontent.com/u/26831659?v=4" width="100px;" alt="Nityananda Gohain"/><br /><sub><b>Nityananda Gohain</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=nityanandagohain" title="Code">💻</a></td>

View File

@@ -251,7 +251,10 @@ nav.secondary-nav {
h1,
h2,
h3 {
h3,
h4 {
display: flex;
align-items: center;
margin: 0;
font-weight: 700;
}
@@ -379,6 +382,11 @@ h3.title {
margin: 4px;
}
.info {
margin-left: 4px;
color: var(--fg-light-color);
}
button {
display: inline-flex;
align-items: center;
@@ -526,7 +534,9 @@ kbd,
select,
input,
textarea,
pre {
pre,
code {
display: inline-flex;
margin: 4px;
padding: 8px;
border-radius: 8px;
@@ -560,9 +570,10 @@ pre.ace_editor {
z-index: 0;
}
code {
height: 336px;
border-radius: 8px;
kbd,
code,
pre {
width: auto;
}
.select-wrapper {
@@ -663,6 +674,7 @@ ol li {
display: inline-flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
}
.flex-wrap {

View File

@@ -138,6 +138,14 @@
</g>
</svg>
</nuxt-link>
<nuxt-link
:to="localePath('doc')"
:class="linkActive('/doc')"
v-tooltip.right="'Documentation'"
aria-label="Documentation"
>
<i class="material-icons">books</i>
</nuxt-link>
<nuxt-link
:to="localePath('settings')"
:class="linkActive('/settings')"
@@ -210,6 +218,22 @@
</ul>
</nav>
</div>
<div v-else-if="$route.path === '/doc'">
<nav class="secondary-nav">
<ul>
<li>
<a href="#collections" v-tooltip.right="$t('collections')">
<i class="material-icons">folder</i>
</a>
</li>
<li>
<a href="#documentation" v-tooltip.right="'Documentation'">
<i class="material-icons">insert_drive_file</i>
</a>
</li>
</ul>
</nav>
</div>
<div v-else-if="$route.path === '/settings'">
<nav class="secondary-nav">
<ul>
@@ -582,6 +606,9 @@ export default {
}
});
});
console.log("%cWe ❤︎ open source!", "background-color:white;padding:8px 16px;border-radius:8px;font-size:32px;color:red;")
console.log("%cContribute: https://github.com/liyasthomas/postwoman", "background-color:black;padding:4px 8px;border-radius:8px;font-size:16px;color:white;")
},
watch: {

355
pages/doc.vue Normal file
View File

@@ -0,0 +1,355 @@
<template>
<div class="page">
<pw-section class="blue" label="Collections" ref="collections">
<ul class="info">
<li>
<p>
Import any Postwoman Collection to Generate Documentation on-the-go.
</p>
</li>
</ul>
<ul>
<li>
<label for="collectionUpload">
<button
class="icon"
@click="$refs.collectionUpload.click()"
v-tooltip="'JSON'"
>
<i class="material-icons">folder</i>
<span>Import Collections</span>
</button>
</label>
<input
ref="collectionUpload"
name="collectionUpload"
type="file"
@change="uploadCollection"
/>
</li>
</ul>
<ul>
<li>
<Editor
v-model="collectionJSON"
:lang="'json'"
:options="{
maxLines: '16',
minLines: '8',
fontSize: '16px',
autoScrollEditorIntoView: true,
showPrintMargin: false,
useWorker: false
}"
/>
</li>
</ul>
<ul>
<li>
<button class="icon" @click="getDoc">
<i class="material-icons">book</i>
<span>Generate Documentation</span>
</button>
</li>
</ul>
</pw-section>
<pw-section class="green" label="Documentation" ref="documentation">
<div>
<span
class="collection"
v-for="(collection, index) in this.items"
:key="index"
>
<h2>
<i class="material-icons">folder</i>
{{ collection.name || "None" }}
</h2>
<span
class="folder"
v-for="(folder, index) in collection.folders"
:key="index"
>
<h3>
<i class="material-icons">folder_open</i>
{{ folder.name || "None" }}
</h3>
<span
class="request"
v-for="(request, index) in folder.requests"
:key="index"
>
<h4>
<i class="material-icons">insert_drive_file</i>
{{ request.name || "None" }}
</h4>
<p class="doc-desc">
<span>
URL: <code>{{ request.url || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Path: <code>{{ request.path || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Method: <code>{{ request.method || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Authentication:
<code>{{ request.auth || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Username: <code>{{ request.httpUser || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Password: <code>{{ request.httpPassword || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Token: <code>{{ request.bearerToken || "None" }}</code>
</span>
</p>
<h4>Headers</h4>
<span v-for="header in request.headers" :key="header.key">
<p class="doc-desc">
<span>
{{ header.key || "None" }}:
<code>{{ header.value || "None" }}</code>
</span>
</p>
</span>
<h4>Parameters</h4>
<span v-for="parameter in request.params" :key="parameter.key">
<p class="doc-desc">
<span>
{{ parameter.key || "None" }}:
<code>{{ parameter.value || "None" }}</code>
</span>
</p>
</span>
<h4>Payload</h4>
<span v-for="payload in request.bodyParam" :key="payload.key">
<p class="doc-desc">
<span>
{{ payload.key || "None" }}:
<code>{{ payload.value || "None" }}</code>
</span>
</p>
</span>
<p class="doc-desc">
<span>
Parameters: <code>{{ request.rawParams || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Content Type: <code>{{ request.contentType || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Request Type: <code>{{ request.requestType || "None" }}</code>
</span>
</p>
</span>
</span>
<span
class="request"
v-for="(request, index) in collection.folders"
:key="`request-${index}`"
>
<h4>
<i class="material-icons">insert_drive_file</i>
{{ request.name || "None" }}
</h4>
<p class="doc-desc">
<span>
URL: <code>{{ request.url || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Path: <code>{{ request.path || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Method: <code>{{ request.method || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Authentication:
<code>{{ request.auth || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Username: <code>{{ request.httpUser || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Password: <code>{{ request.httpPassword || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Token: <code>{{ request.bearerToken || "None" }}</code>
</span>
</p>
<h4>Headers</h4>
<span v-for="header in request.headers" :key="header.key">
<p class="doc-desc">
<span>
{{ header.key || "None" }}:
<code>{{ header.value || "None" }}</code>
</span>
</p>
</span>
<h4>Parameters</h4>
<span v-for="parameter in request.params" :key="parameter.key">
<p class="doc-desc">
<span>
{{ parameter.key || "None" }}:
<code>{{ parameter.value || "None" }}</code>
</span>
</p>
</span>
<h4>Payload</h4>
<span v-for="payload in request.bodyParam" :key="payload.key">
<p class="doc-desc">
<span>
{{ payload.key || "None" }}:
<code>{{ payload.value || "None" }}</code>
</span>
</p>
</span>
<p class="doc-desc">
<span>
Parameters: <code>{{ request.rawParams || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Content Type: <code>{{ request.contentType || "None" }}</code>
</span>
</p>
<p class="doc-desc">
<span>
Request Type: <code>{{ request.requestType || "None" }}</code>
</span>
</p>
</span>
</span>
</div>
</pw-section>
</div>
</template>
<style scoped lang="scss">
.collection,
.folder,
.request,
.doc-desc {
display: flex;
flex-flow: column;
justify-content: center;
flex: 1;
padding: 16px;
.material-icons {
margin-right: 16px;
}
}
.collection {
}
.folder {
border-left: 1px solid var(--brd-color);
margin: 16px 0 0;
}
.request {
border: 1px solid var(--brd-color);
border-radius: 8px;
margin: 16px 0 0;
h4 {
margin: 8px 0;
}
}
.doc-desc {
color: var(--fg-light-color);
border-bottom: 1px dashed var(--brd-color);
margin: 0;
&:last-child {
border-bottom: none;
}
}
</style>
<script>
import AceEditor from "../components/ace-editor";
export default {
components: {
"pw-section": () => import("../components/section"),
Editor: AceEditor
},
data() {
return {
collectionJSON: "[]",
items: []
};
},
methods: {
uploadCollection() {
this.rawInput = true;
let file = this.$refs.collectionUpload.files[0];
if (file !== undefined && file !== null) {
let reader = new FileReader();
reader.onload = e => {
this.collectionJSON = e.target.result;
};
reader.readAsText(file);
this.$toast.info("File imported", {
icon: "attach_file"
});
} else {
this.$toast.error("Choose a file", {
icon: "attach_file"
});
}
},
getDoc() {
try {
this.items = JSON.parse(this.collectionJSON);
this.$toast.info("Documentation generated", {
icon: "book"
});
} catch (e) {
this.$toast.error(e, {
icon: "code"
});
}
}
}
};
</script>

View File

@@ -227,7 +227,6 @@
<Editor
v-model="rawParams"
:lang="'json'"
@keydown="formatRawParams"
:options="{
maxLines: '16',
minLines: '8',
@@ -1816,38 +1815,6 @@ export default {
}
});
},
formatRawParams(event) {
if (event.which !== 13 && event.which !== 9) {
return;
}
const textBody = event.target.value;
const textBeforeCursor = textBody.substring(
0,
event.target.selectionStart
);
const textAfterCursor = textBody.substring(event.target.selectionEnd);
if (event.which === 13) {
event.preventDefault();
const oldSelectionStart = event.target.selectionStart;
const lastLine = textBeforeCursor.split("\n").slice(-1)[0];
const rightPadding = lastLine.match(/([\s\t]*).*/)[1] || "";
event.target.value =
textBeforeCursor + "\n" + rightPadding + textAfterCursor;
setTimeout(
() =>
(event.target.selectionStart = event.target.selectionEnd =
oldSelectionStart + rightPadding.length + 1),
1
);
} else if (event.which === 9) {
event.preventDefault();
const oldSelectionStart = event.target.selectionStart;
event.target.value = textBeforeCursor + "\xa0\xa0" + textAfterCursor;
event.target.selectionStart = event.target.selectionEnd =
oldSelectionStart + 2;
return false;
}
},
copyRequest() {
if (navigator.share) {
let time = new Date().toLocaleTimeString();

View File

@@ -134,12 +134,7 @@
</div>
</template>
<style scoped lang="scss">
.info {
margin-left: 4px;
color: var(--fg-light-color);
}
</style>
<style scoped lang="scss"></style>
<script>
export default {