Added api, keyboard shortcut flatpages
This commit is contained in:
@ -21,7 +21,7 @@
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
min-width: 150px;
|
min-width: 160px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ class Layout extends React.Component {
|
|||||||
/> }
|
/> }
|
||||||
>
|
>
|
||||||
<MenuItem to="/settings">Settings</MenuItem>
|
<MenuItem to="/settings">Settings</MenuItem>
|
||||||
|
<MenuItem to="/keyboard-shortcuts">Keyboard shortcuts</MenuItem>
|
||||||
|
<MenuItem to="/developers">API</MenuItem>
|
||||||
<MenuItem onClick={ user.logout }>Logout</MenuItem>
|
<MenuItem onClick={ user.logout }>Logout</MenuItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -26,9 +26,12 @@ import DocumentEdit from 'scenes/DocumentEdit';
|
|||||||
import Search from 'scenes/Search';
|
import Search from 'scenes/Search';
|
||||||
import Settings from 'scenes/Settings';
|
import Settings from 'scenes/Settings';
|
||||||
import SlackAuth from 'scenes/SlackAuth';
|
import SlackAuth from 'scenes/SlackAuth';
|
||||||
|
import Flatpage from 'scenes/Flatpage';
|
||||||
import Error404 from 'scenes/Error404';
|
import Error404 from 'scenes/Error404';
|
||||||
import ErrorAuth from 'scenes/ErrorAuth';
|
import ErrorAuth from 'scenes/ErrorAuth';
|
||||||
|
|
||||||
|
import flatpages from 'static/flatpages';
|
||||||
|
|
||||||
let DevTools;
|
let DevTools;
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
DevTools = require('mobx-react-devtools').default; // eslint-disable-line global-require
|
DevTools = require('mobx-react-devtools').default; // eslint-disable-line global-require
|
||||||
@ -79,6 +82,21 @@ render((
|
|||||||
/>
|
/>
|
||||||
<Route path="/auth/error" component={ ErrorAuth } />
|
<Route path="/auth/error" component={ ErrorAuth } />
|
||||||
|
|
||||||
|
<Flatpage
|
||||||
|
path="/keyboard-shortcuts"
|
||||||
|
component={ Flatpage }
|
||||||
|
title="Keyboard shortcuts"
|
||||||
|
content={ flatpages.keyboard }
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Flatpage
|
||||||
|
path="/developers"
|
||||||
|
component={ Flatpage }
|
||||||
|
title="API"
|
||||||
|
content={ flatpages.api }
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<Route path="/404" component={ Error404 } />
|
<Route path="/404" component={ Error404 } />
|
||||||
<Redirect from="*" to="/404" />
|
<Redirect from="*" to="/404" />
|
||||||
</Route>
|
</Route>
|
||||||
|
33
frontend/scenes/Flatpage/Flatpage.js
Normal file
33
frontend/scenes/Flatpage/Flatpage.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React, { PropTypes } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import Layout, { Title } from 'components/Layout';
|
||||||
|
import CenteredContent from 'components/CenteredContent';
|
||||||
|
import { DocumentHtml } from 'components/Document';
|
||||||
|
|
||||||
|
import { convertToMarkdown } from 'utils/markdown';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
class Flatpage extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
route: PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { title, content } = this.props.route;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout
|
||||||
|
title={ <Title>{ title }</Title> }
|
||||||
|
titleText={ title }
|
||||||
|
search={ false }
|
||||||
|
>
|
||||||
|
<CenteredContent>
|
||||||
|
<DocumentHtml html={ convertToMarkdown(content) } />
|
||||||
|
</CenteredContent>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Flatpage;
|
0
frontend/scenes/Flatpage/Flatpage.scss
Normal file
0
frontend/scenes/Flatpage/Flatpage.scss
Normal file
2
frontend/scenes/Flatpage/index.js
Normal file
2
frontend/scenes/Flatpage/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import Flatpage from './Flatpage';
|
||||||
|
export default Flatpage;
|
117
frontend/static/flatpages/api.markdown
Normal file
117
frontend/static/flatpages/api.markdown
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# Atlas API
|
||||||
|
|
||||||
|
## Making requests
|
||||||
|
|
||||||
|
Atlas' API follows JSON RPC style convention where each API endpoint is a method on `https://www.beautifulatlas.com/api/<METHOD>`. Each request needs to be made using HTTPS.
|
||||||
|
|
||||||
|
Each method can be called with either `GET` or `POST` (recommended). For `GET` requests query string parameters are expected (e.g. `/api/document.info?id=...&token=...`). When making `POST` requests, request parameters are parsed depending on `Content-Type` header. To make a call using JSON payload, one must pass `Content-Type: application/json` header:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl 'https://www.beautifulatlas.com/api/documents.info?id=atlas-api-NTpezNwhUP'\
|
||||||
|
-H 'authorization: Bearer <API KEY>'\
|
||||||
|
-H 'content-type: application/json'\
|
||||||
|
-H 'accept: application/json'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
To access private API endpoints, you must provide a valid API key. You can create new API keys in your [account settings](https://www.beautifulatlas.com/settings). Be careful when handling your keys as they give access to all of your documents.
|
||||||
|
|
||||||
|
To authenticate with Atlas API, you can supply the API key as a header (`Authorization: Bearer <API KEY>`) or as part of the payload using `token` parameter.
|
||||||
|
|
||||||
|
Some API endpoints allow unauhenticated requests for public resources and they can be called without an API key.
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
All successful API requests will be returned with `200` status code and `ok: true` in the response payload. If there's an error while making the request, appropriate status code is returned with the `error` message:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ok": false,
|
||||||
|
"error: "Not Found"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### `documents.info` - Get a document
|
||||||
|
|
||||||
|
This method returns information for a document with a specific ID. Following identifiers are allowed:
|
||||||
|
|
||||||
|
- UUID - `id` field of the document
|
||||||
|
- URI identifier - Human readable identifier used in Atlas URLs (e.g. `atlas-api-i48ZEZc5zjXndcP`)
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
`https://www.beautifulatlas.com/api/documents.info`
|
||||||
|
|
||||||
|
Parameter | Description
|
||||||
|
------------ | -------------
|
||||||
|
`token` | Authentication token
|
||||||
|
`id` | Document id or URI identifier
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `documents.search` - Search documents
|
||||||
|
|
||||||
|
This methods allows you to search all of your documents with keywords.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
`https://www.beautifulatlas.com/api/documents.search`
|
||||||
|
|
||||||
|
Parameter | Description
|
||||||
|
------------ | -------------
|
||||||
|
`token` | Authentication token
|
||||||
|
`query` | Search query
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `documents.create` - Create a new document
|
||||||
|
|
||||||
|
This method allows you to publish a new document under an existing collection. If your collection is structured `type: atlas` collection, you can also create sub-documents for other documents with optional `parentDocument` parameter.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
`https://www.beautifulatlas.com/api/documents.create`
|
||||||
|
|
||||||
|
Parameter | Description
|
||||||
|
------------ | -------------
|
||||||
|
`token` | Authentication token
|
||||||
|
`collection` | `id` of the collection to which the document is created
|
||||||
|
`parentDocument` | `id` of the parent document within the collection
|
||||||
|
`title` | Title for the document
|
||||||
|
`text` | Content of the document in Markdown
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `user.info` - Get current user
|
||||||
|
|
||||||
|
This method returns the information for currently logged in user.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
`https://www.beautifulatlas.com/api/user.info`
|
||||||
|
|
||||||
|
Parameter | Description
|
||||||
|
------------ | -------------
|
||||||
|
`token` | Authentication token
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `user.s3Upload` - Gets S3 upload credentials
|
||||||
|
|
||||||
|
You can upload small files and images as part of your documents. All files are stored using Amazon S3. Instead of uploading files to Atlas, you need to upload them directly to S3 with special credentials which can be obtained through this endpoint.
|
||||||
|
|
||||||
|
_TODO: Add more about restrictions and flow_
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
`https://www.beautifulatlas.com/api/user.s3Upload`
|
||||||
|
|
||||||
|
Parameter | Description
|
||||||
|
------------ | -------------
|
||||||
|
`token` | Authentication token
|
||||||
|
`filename` | Filename of the uploaded file
|
||||||
|
`kind` | Mimetype of the document
|
||||||
|
`size` | Filesize of the document
|
7
frontend/static/flatpages/index.js
Normal file
7
frontend/static/flatpages/index.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import api from './api.markdown';
|
||||||
|
import keyboard from './keyboard.markdown';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
api,
|
||||||
|
keyboard,
|
||||||
|
};
|
10
frontend/static/flatpages/keyboard.markdown
Normal file
10
frontend/static/flatpages/keyboard.markdown
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Keyboard shortcuts
|
||||||
|
|
||||||
|
- `Cmd+/` - Toggle navigation tree
|
||||||
|
- `Cmd+Enter` - Save document
|
||||||
|
- `Cmd+Esc` - Cancel edit
|
||||||
|
- `Cmd+Shift+p` - Toggle document preview
|
||||||
|
- `/` or `t` - Jump to search
|
||||||
|
- `d` - Jump to dashboard
|
||||||
|
- `c` - Compose within a collection
|
||||||
|
- `e` - Edit document
|
@ -122,6 +122,7 @@
|
|||||||
"query-string": "^4.2.2",
|
"query-string": "^4.2.2",
|
||||||
"querystring": "0.2.0",
|
"querystring": "0.2.0",
|
||||||
"randomstring": "1.1.5",
|
"randomstring": "1.1.5",
|
||||||
|
"raw-loader": "^0.5.1",
|
||||||
"react": "15.3.1",
|
"react": "15.3.1",
|
||||||
"react-codemirror": "0.2.6",
|
"react-codemirror": "0.2.6",
|
||||||
"react-dom": "15.1.0",
|
"react-dom": "15.1.0",
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
<title>Atlas</title>
|
<title>Atlas</title>
|
||||||
<link href="/static/styles.css" rel="stylesheet"></head>
|
<link href="/static/styles.css" rel="stylesheet"></head>
|
||||||
<style>
|
<style>
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Atlas</title>
|
<title>Atlas</title>
|
||||||
<style>
|
<style>
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
var path = require('path');
|
const path = require('path');
|
||||||
var webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
|
|
||||||
// Load .env
|
// Load .env
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
var definePlugin = new webpack.DefinePlugin({
|
const definePlugin = new webpack.DefinePlugin({
|
||||||
__DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV !== 'production')),
|
__DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV !== 'production')),
|
||||||
__PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false')),
|
__PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false')),
|
||||||
SLACK_REDIRECT_URI: JSON.stringify(process.env.SLACK_REDIRECT_URI),
|
SLACK_REDIRECT_URI: JSON.stringify(process.env.SLACK_REDIRECT_URI),
|
||||||
@ -16,41 +16,43 @@ module.exports = {
|
|||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'dist'),
|
path: path.join(__dirname, 'dist'),
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
publicPath: '/static/'
|
publicPath: '/static/',
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
loaders: [
|
loaders: [
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
loader: 'babel',
|
loader: 'babel',
|
||||||
include: path.join(__dirname, 'frontend')
|
include: path.join(__dirname, 'frontend'),
|
||||||
},
|
},
|
||||||
{ test: /\.json$/, loader: 'json-loader' },
|
{ test: /\.json$/, loader: 'json-loader' },
|
||||||
{ test: /\.(png|jpg|svg)$/, loader: 'url-loader' }, // inline base64 URLs for <=8k images, direct URLs for the rest
|
// inline base64 URLs for <=8k images, direct URLs for the rest
|
||||||
|
{ test: /\.(png|jpg|svg)$/, loader: 'url-loader' },
|
||||||
{
|
{
|
||||||
test: /\.woff$/,
|
test: /\.woff$/,
|
||||||
loader: 'url-loader?limit=1&mimetype=application/font-woff&name=public/fonts/[name].[ext]'
|
loader: 'url-loader?limit=1&mimetype=application/font-woff&name=public/fonts/[name].[ext]',
|
||||||
},
|
},
|
||||||
|
{ test: /\.markdown/, loader: 'raw-loader' },
|
||||||
|
|
||||||
// Excludes
|
// Excludes
|
||||||
{
|
{
|
||||||
// slug
|
// slug
|
||||||
test: /unicode/,
|
test: /unicode/,
|
||||||
loader: 'ignore-loader',
|
loader: 'ignore-loader',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
root: path.join(__dirname, 'frontend'),
|
root: path.join(__dirname, 'frontend'),
|
||||||
// you can now require('file') instead of require('file.json')
|
// you can now require('file') instead of require('file.json')
|
||||||
extensions: ['', '.js', '.json']
|
extensions: ['', '.js', '.json'],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
definePlugin,
|
definePlugin,
|
||||||
new webpack.ProvidePlugin({
|
new webpack.ProvidePlugin({
|
||||||
'fetch': 'imports?this=>global!exports?global.fetch!isomorphic-fetch'
|
fetch: 'imports?this=>global!exports?global.fetch!isomorphic-fetch',
|
||||||
}),
|
}),
|
||||||
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en)$/)
|
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en)$/),
|
||||||
],
|
],
|
||||||
stats: {
|
stats: {
|
||||||
assets: false,
|
assets: false,
|
||||||
|
Reference in New Issue
Block a user