Implemented some of api keys

This commit is contained in:
Jori Lallo
2016-08-24 00:37:54 -07:00
parent 29665621b3
commit a2aea2abfc
12 changed files with 342 additions and 35 deletions

View File

@@ -2,25 +2,70 @@ import React from 'react';
import { observer } from 'mobx-react';
import Helmet from 'react-helmet';
const Application = observer((props) => {
return (
<div style={{ width: '100%', height: '100%', display: 'flex', flex: 1 }}>
<Helmet
title="Atlas"
meta={ [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0',
},
] }
/>
{ props.children }
</div>
);
});
@observer
class Application extends React.Component {
static childContextTypes = {
rebass: React.PropTypes.object,
}
Application.propTypes = {
children: React.PropTypes.node.isRequired,
};
propTypes = {
children: React.PropTypes.node.isRequired,
}
getChildContext() {
return {
rebass: {
colors: {
primary: '#171B35',
},
// color: '#eee',
// backgroundColor: '#fff',
borderRadius: 2,
borderColor: '#eee',
// fontSizes: [64, 48, 28, 20, 18, 16, 14],
bold: 500,
scale: [
0,
8,
18,
36,
72,
],
Input: {
// borderBottom: '1px solid #eee',
},
Button: {
// color: '#eee',
// backgroundColor: '#fff',
// border: '1px solid #ccc',
},
ButtonOutline: {
color: '#000',
},
InlineForm: {
},
},
};
}
render() {
return (
<div style={{ width: '100%', height: '100%', display: 'flex', flex: 1 }}>
<Helmet
title="Atlas"
meta={ [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0',
},
] }
/>
{ this.props.children }
</div>
);
}
}
export default Application;

View File

@@ -2,6 +2,7 @@ import React from 'react';
import { observer } from 'mobx-react';
import { Flex } from 'reflexbox';
import { Input, ButtonOutline, InlineForm } from 'rebass';
import Layout, { Title } from 'components/Layout';
import CenteredContent from 'components/CenteredContent';
import SlackAuthLink from 'components/SlackAuthLink';
@@ -19,6 +20,11 @@ class Settings extends React.Component {
this.store = new SettingsStore();
}
onKeyCreate = (e) => {
e.preventDefault();
this.store.createApiKey();
}
render() {
const title = (
<Title>
@@ -34,19 +40,57 @@ class Settings extends React.Component {
loading={ this.store.isFetching }
>
<CenteredContent>
<h2 className={ styles.sectionHeader }>Slack</h2>
<div className={ styles.section }>
<h2 className={ styles.sectionHeader }>Slack</h2>
<p>
Connect Atlas to your Slack to instantly search for your documents
using <code>/atlas</code> command.
</p>
<p>
Connect Atlas to your Slack to instantly search for your documents
using <code>/atlas</code> command.
</p>
<SlackAuthLink
scopes={ ['commands'] }
redirectUri={ `${URL}/auth/slack/commands` }
>
<img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcSet="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x" />
</SlackAuthLink>
<SlackAuthLink
scopes={ ['commands'] }
redirectUri={ `${URL}/auth/slack/commands` }
>
<img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcSet="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x" />
</SlackAuthLink>
</div>
<div className={ styles.section }>
<h2 className={ styles.sectionHeader }>API access</h2>
<p>
Create API tokens to hack on your Atlas.
Learn more in <a href>API documentation</a>.
</p>
{ this.store.apiKeys && (
<table className={ styles.apiKeyTable }>
{ this.store.apiKeys.map(key => (
<tr>
<td>{ key.name }</td>
<td><code>{ key.secret }</code></td>
{/* <td>
<span className={ styles.deleteAction }>Delete</span>
</td> */}
</tr>
)) }
</table>
) }
<div>
<InlineForm
placeholder="Token name"
buttonLabel="Create token"
label="InlineForm"
name="inline_form"
value={ this.store.keyName }
onChange={ this.store.setKeyName }
onClick={ this.onKeyCreate }
style={{ width: '100%' }}
disabled={ this.store.isFetching }
/>
</div>
</div>
</CenteredContent>
</Layout>
);

View File

@@ -1,4 +1,25 @@
@import '~styles/constants.scss';
.section {
margin-bottom: 40px;
}
.sectionHeader {
border-bottom: 1px solid #eee;
}
.apiKeyTable {
margin-bottom: 20px;
width: 100%;
td {
margin-right: 20px;
color: #969696;
}
}
.deleteAction {
font-size: 14px;
cursor: pointer;
color: $textColor;
}

View File

@@ -1,7 +1,52 @@
import { observable, action, runInAction } from 'mobx';
// import { client } from 'utils/ApiClient';
import { observable, action, runInAction, toJS } from 'mobx';
import { client } from 'utils/ApiClient';
class SearchStore {
};
@observable apiKeys = [];
@observable keyName;
@observable isFetching;
@action fetchApiKeys = async () => {
this.isFetching = true;
try {
const res = await client.post('/apiKeys.list');
const { data } = res;
runInAction('fetchApiKeys', () => {
this.apiKeys = data;
});
} catch (e) {
console.error("Something went wrong");
}
this.isFetching = false;
}
@action createApiKey = async () => {
this.isFetching = true;
try {
const res = await client.post('/apiKeys.create', {
name: `${this.keyName}` || 'Untitled key',
});
const { data } = res;
runInAction('createApiKey', () => {
this.apiKeys.push(data);
this.keyName = '';
});
} catch (e) {
console.error("Something went wrong");
}
this.isFetching = false;
}
@action setKeyName = (value) => {
this.keyName = value.target.value;
}
constructor() {
this.fetchApiKeys();
}
}
export default SearchStore;

View File

@@ -1,7 +1,7 @@
$lightGray: #eee;
$textColor: #171B35;
$actionColor: #2da9e1;
$actionColor: #3AA3E3;
$darkGray: #ccc;
$lightGray: #eee;