diff --git a/src/actions/DocumentActions.js b/src/actions/DocumentActions.js
index 54a93a940..63aea582a 100644
--- a/src/actions/DocumentActions.js
+++ b/src/actions/DocumentActions.js
@@ -5,6 +5,8 @@ import { createAction } from 'redux-actions';
export const resetDocument = createAction('RESET_DOCUMENT');
+// GET
+
export const FETCH_DOCUMENT_PENDING = 'FETCH_DOCUMENT_PENDING';
export const FETCH_DOCUMENT_SUCCESS = 'FETCH_DOCUMENT_SUCCESS';
export const FETCH_DOCUMENT_FAILURE = 'FETCH_DOCUMENT_FAILURE';
@@ -29,6 +31,8 @@ export function fetchDocumentAsync(documentId) {
};
};
+// POST/UPDATE
+
export const SAVE_DOCUMENT_PENDING = 'SAVE_DOCUMENT_PENDING';
export const SAVE_DOCUMENT_SUCCESS = 'SAVE_DOCUMENT_SUCCESS';
export const SAVE_DOCUMENT_FAILURE = 'SAVE_DOCUMENT_FAILURE';
@@ -65,3 +69,23 @@ export function saveDocumentAsync(atlasId, documentId, title, text) {
};
};
+// documents.delete
+
+export const deleteDocumentPending = createAction('DELETE_DOCUMENT_PENDING');
+export const deleteDocumentSuccess = createAction('DELETE_DOCUMENT_SUCCESS');
+export const deleteDocumentFailure = createAction('DELETE_DOCUMENT_FAILURE');
+
+export const deleteDocument = (documentId, returnPath) => {
+ return (dispatch) => {
+ dispatch(deleteDocumentPending());
+
+ client.post('/documents.delete', { id: documentId })
+ .then(data => {
+ dispatch(deleteDocumentSuccess(documentId));
+ dispatch(replace(returnPath));
+ })
+ .catch((err) => {
+ dispatch(deleteDocumentFailure(err));
+ })
+ };
+};
diff --git a/src/components/DropdownMenu/DropdownMenu.js b/src/components/DropdownMenu/DropdownMenu.js
new file mode 100644
index 000000000..1f2c1f125
--- /dev/null
+++ b/src/components/DropdownMenu/DropdownMenu.js
@@ -0,0 +1,66 @@
+import React from 'react';
+import styles from './DropdownMenu.scss';
+
+const MenuItem = (props) => {
+ return (
+
{ props.children }
+ );
+};
+
+MenuItem.propTypes = {
+ onClick: React.PropTypes.func,
+ children: React.PropTypes.node.isRequired,
+};
+
+//
+
+class DropdownMenu extends React.Component {
+ static propTypes = {
+ label: React.PropTypes.string.isRequired,
+ children: React.PropTypes.node.isRequired,
+ }
+
+ state = {
+ menuVisible: false,
+ }
+
+ onMouseEnter = () => {
+ this.setState({ menuVisible: true });
+ }
+
+ onMouseLeave = () => {
+ this.setState({ menuVisible: false });
+ }
+
+ onClick = () => {
+ this.setState({ menuVisible: !this.state.menuVisible });
+ }
+
+ render() {
+ return (
+
+
+ { this.props.label }
+
+
+ { this.state.menuVisible ? (
+
+ { this.props.children }
+
+ ) : null }
+
+ );
+ }
+};
+
+export default DropdownMenu;
+export {
+ MenuItem,
+}
\ No newline at end of file
diff --git a/src/components/DropdownMenu/DropdownMenu.scss b/src/components/DropdownMenu/DropdownMenu.scss
new file mode 100644
index 000000000..beda6dc53
--- /dev/null
+++ b/src/components/DropdownMenu/DropdownMenu.scss
@@ -0,0 +1,40 @@
+@import '../../utils/constants.scss';
+
+.label {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+
+ min-height: 43px;
+ padding: 0 0.5rem;
+ color: $linkColor;
+}
+
+.menuContainer {
+ position: relative;
+
+ .menu {
+ position: absolute;
+ top: 42px;
+ right: 0;
+ z-index: 1000;
+ border: 1px solid #eee;
+ min-width: 150px;
+ padding: 5px 0;
+ }
+}
+
+.menuItem {
+ margin: 0;
+ padding: 5px 10px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ cursor: pointer;
+
+ a {
+ color: $textColor;
+ text-decoration: none;
+ }
+}
\ No newline at end of file
diff --git a/src/components/DropdownMenu/index.js b/src/components/DropdownMenu/index.js
new file mode 100644
index 000000000..934329f8d
--- /dev/null
+++ b/src/components/DropdownMenu/index.js
@@ -0,0 +1,5 @@
+import DropdownMenu, { MenuItem } from './DropdownMenu';
+export default DropdownMenu;
+export {
+ MenuItem,
+};
diff --git a/src/components/Layout/Layout.js b/src/components/Layout/Layout.js
index 532e8b80c..5a5ed621b 100644
--- a/src/components/Layout/Layout.js
+++ b/src/components/Layout/Layout.js
@@ -1,10 +1,13 @@
import React from 'react';
import { connect } from 'react-redux';
import Link from 'react-router/lib/Link';
+import { bindActionCreators } from 'redux';
+import { logoutUser } from 'actions/UserActions';
-import HeaderMenu from './components/HeaderMenu';
+import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
import Flex from 'components/Flex';
import LoadingIndicator from 'components/LoadingIndicator';
+import { Avatar } from 'rebass';
import styles from './Layout.scss';
import classNames from 'classnames/bind';
@@ -18,6 +21,10 @@ class Layout extends React.Component {
loading: React.PropTypes.bool,
}
+ onLogout = () => {
+ this.props.logoutUser();
+ }
+
render() {
return (
@@ -35,11 +42,19 @@ class Layout extends React.Component {
{ this.props.actions }
-
-
-
+
+
+ }>
+
+
+
{ this.props.children }
@@ -55,6 +70,13 @@ const mapStateToProps = (state) => {
}
};
+const mapDispatchToProps = (dispatch) => {
+ return bindActionCreators({
+ logoutUser,
+ }, dispatch)
+}
+
export default connect(
mapStateToProps,
+ mapDispatchToProps,
)(Layout);
\ No newline at end of file
diff --git a/src/components/Layout/Layout.scss b/src/components/Layout/Layout.scss
index 1ed76ccb4..40c57c913 100644
--- a/src/components/Layout/Layout.scss
+++ b/src/components/Layout/Layout.scss
@@ -43,7 +43,3 @@
justify-content: center;
}
-.actions a {
- text-decoration: none;
- margin-right: 15px;
-}
diff --git a/src/components/Layout/components/HeaderMenu/HeaderMenu.js b/src/components/Layout/components/HeaderMenu/HeaderMenu.js
deleted file mode 100644
index 167170b18..000000000
--- a/src/components/Layout/components/HeaderMenu/HeaderMenu.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { logoutUser } from 'actions/UserActions';
-
-import styles from './HeaderMenu.scss';
-
-class HeaderMenu extends React.Component {
- static propTypes = {
- children: React.PropTypes.node.isRequired,
- }
-
- state = {
- menuVisible: false,
- }
-
- onMouseEnter = () => {
- this.setState({ menuVisible: true });
- }
-
- onMouseLeave = () => {
- this.setState({ menuVisible: false });
- }
-
- onClick = () => {
- this.setState({ menuVisible: !this.state.menuVisible });
- }
-
- logout = (event) => {
- event.preventDefault();
- this.props.logout();
- }
-
- render() {
- return (
-
-
- { this.props.children }
-
-
- { this.state.menuVisible ? (
-
- ) : null }
-
- );
- }
-};
-
-const mapDispatchToProps = (dispatch) => {
- return {
- logout: () => {
- dispatch(logoutUser())
- },
- }
-};
-
-
-export default connect(null, mapDispatchToProps)(HeaderMenu);
\ No newline at end of file
diff --git a/src/components/Layout/components/HeaderMenu/HeaderMenu.scss b/src/components/Layout/components/HeaderMenu/HeaderMenu.scss
deleted file mode 100644
index f910f428c..000000000
--- a/src/components/Layout/components/HeaderMenu/HeaderMenu.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-@import '../../../../utils/constants.scss';
-
-.content {
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
-
- min-height: 43px;
- min-width: 43px;
-}
-
-.menu {
- position: relative;
-
- img {
- height: 24px;
- width: 24px;
- border-radius: 12px;
- }
-
- .menu {
- position: absolute;
- top: 42px;
- right: 0;
- z-index: 1000;
- border: 1px solid #eee;
-
- ul {
- margin: 0;
- padding: 5px 0;
- font-size: 0.9em;
- }
-
- li {
- margin: 0;
- padding: 0;
- list-style-type: none;
-
- a {
- display: flex;
- margin: 0;
- padding: 5px 10px;
- min-width: 150px;
-
- color: $textColor;
- text-decoration: none;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/components/Layout/components/HeaderMenu/index.js b/src/components/Layout/components/HeaderMenu/index.js
deleted file mode 100644
index cc2de652b..000000000
--- a/src/components/Layout/components/HeaderMenu/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import HeaderMenu from './HeaderMenu';
-export default HeaderMenu;
\ No newline at end of file
diff --git a/src/components/Layout/index.js b/src/components/Layout/index.js
index 82ecfc082..203673809 100644
--- a/src/components/Layout/index.js
+++ b/src/components/Layout/index.js
@@ -1,8 +1,10 @@
import Layout from './Layout';
import Title from './components/Title';
+import HeaderLink from './components/HeaderLink';
export default Layout;
export {
Title,
+ HeaderLink,
};
diff --git a/src/scenes/DocumentScene/DocumentScene.js b/src/scenes/DocumentScene/DocumentScene.js
index fad80e16a..48360f665 100644
--- a/src/scenes/DocumentScene/DocumentScene.js
+++ b/src/scenes/DocumentScene/DocumentScene.js
@@ -2,12 +2,16 @@ import React from 'react';
import { connect } from 'react-redux';
import Link from 'react-router/lib/Link';
import { bindActionCreators } from 'redux';
-import { fetchDocumentAsync } from 'actions/DocumentActions';
+import {
+ fetchDocumentAsync,
+ deleteDocument,
+} from 'actions/DocumentActions';
-import Layout from 'components/Layout';
+import Layout, { HeaderLink } from 'components/Layout';
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
import CenteredContent from 'components/CenteredContent';
import Document from 'components/Document';
+import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
import styles from './DocumentScene.scss';
@@ -35,12 +39,30 @@ class DocumentScene extends React.Component {
}
}
+ onDelete = () => {
+ if (confirm("Are you sure you want to delete this document?")) {
+ this.props.deleteDocument(
+ this.props.document.id,
+ `/atlas/${ this.props.document.atlas.id }`,
+ );
+ };
+ }
+
render() {
const document = this.props.document;
let title;
let actions;
if (document) {
- actions = Edit;
+ actions = (
+
+
+ Edit
+
+
+
+
+
+ );
title = `${document.atlas.name} - ${document.title}`;
}
@@ -72,6 +94,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
fetchDocumentAsync,
+ deleteDocument,
}, dispatch)
}
diff --git a/src/scenes/DocumentScene/DocumentScene.scss b/src/scenes/DocumentScene/DocumentScene.scss
index e69de29bb..c7d614611 100644
--- a/src/scenes/DocumentScene/DocumentScene.scss
+++ b/src/scenes/DocumentScene/DocumentScene.scss
@@ -0,0 +1,4 @@
+.actions {
+ display: flex;
+ flex-direction: row;
+}
\ No newline at end of file