Edit collection (#173)
* Collection edit modal * Add icon * 💚 * Oh look, some specs * Delete collection * Remove from collection * Handle error responses Protect against deleting last collection * Fix key * 💚 * Keyboard navigate documents list * Add missing database constraints
This commit is contained in:
@@ -6,10 +6,10 @@ import { darken } from 'polished';
|
||||
|
||||
const RealButton = styled.button`
|
||||
display: inline-block;
|
||||
margin: 0 0 ${size.large};
|
||||
margin: 0 ${size.medium} ${size.large} 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: ${color.primary};
|
||||
background: ${props => (props.neutral ? color.slate : props.danger ? color.danger : color.primary)};
|
||||
color: ${color.white};
|
||||
border-radius: 4px;
|
||||
min-width: 32px;
|
||||
@@ -23,7 +23,7 @@ const RealButton = styled.button`
|
||||
border: 0;
|
||||
}
|
||||
&:hover {
|
||||
background: ${darken(0.05, color.primary)};
|
||||
background: ${props => darken(0.05, props.neutral ? color.slate : props.danger ? color.danger : color.primary)};
|
||||
}
|
||||
&:disabled {
|
||||
background: ${color.slateLight};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import React from 'react';
|
||||
import Document from 'models/Document';
|
||||
import DocumentPreview from 'components/DocumentPreview';
|
||||
import ArrowKeyNavigation from 'boundless-arrow-key-navigation';
|
||||
|
||||
class DocumentList extends React.Component {
|
||||
props: {
|
||||
@@ -10,12 +11,15 @@ class DocumentList extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<ArrowKeyNavigation
|
||||
mode={ArrowKeyNavigation.mode.VERTICAL}
|
||||
defaultActiveChildIndex={0}
|
||||
>
|
||||
{this.props.documents &&
|
||||
this.props.documents.map(document => (
|
||||
<DocumentPreview key={document.id} document={document} />
|
||||
))}
|
||||
</div>
|
||||
</ArrowKeyNavigation>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
21
frontend/components/Icon/MoreIcon.js
Normal file
21
frontend/components/Icon/MoreIcon.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import Icon from './Icon';
|
||||
import type { Props } from './Icon';
|
||||
|
||||
export default function MoreIcon(props: Props) {
|
||||
return (
|
||||
<Icon {...props}>
|
||||
<svg
|
||||
fill="#000000"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
|
||||
</svg>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
@@ -17,7 +17,9 @@ import Scrollable from 'components/Scrollable';
|
||||
import Avatar from 'components/Avatar';
|
||||
import Modal from 'components/Modal';
|
||||
import AddIcon from 'components/Icon/AddIcon';
|
||||
import MoreIcon from 'components/Icon/MoreIcon';
|
||||
import CollectionNew from 'scenes/CollectionNew';
|
||||
import CollectionEdit from 'scenes/CollectionEdit';
|
||||
import KeyboardShortcuts from 'scenes/KeyboardShortcuts';
|
||||
import Settings from 'scenes/Settings';
|
||||
|
||||
@@ -29,10 +31,12 @@ import UserStore from 'stores/UserStore';
|
||||
import AuthStore from 'stores/AuthStore';
|
||||
import UiStore from 'stores/UiStore';
|
||||
import CollectionsStore from 'stores/CollectionsStore';
|
||||
import DocumentsStore from 'stores/DocumentsStore';
|
||||
|
||||
type Props = {
|
||||
history: Object,
|
||||
collections: CollectionsStore,
|
||||
documents: DocumentsStore,
|
||||
children?: ?React.Element<any>,
|
||||
actions?: ?React.Element<any>,
|
||||
title?: ?React.Element<any>,
|
||||
@@ -66,8 +70,8 @@ type Props = {
|
||||
|
||||
@keydown('e')
|
||||
goToEdit() {
|
||||
if (!this.props.ui.activeDocument) return;
|
||||
this.props.history.push(documentEditUrl(this.props.ui.activeDocument));
|
||||
if (!this.props.documents.active) return;
|
||||
this.props.history.push(documentEditUrl(this.props.documents.active));
|
||||
}
|
||||
|
||||
handleLogout = () => {
|
||||
@@ -87,12 +91,16 @@ type Props = {
|
||||
this.modal = 'create-collection';
|
||||
};
|
||||
|
||||
handleEditCollection = () => {
|
||||
this.modal = 'edit-collection';
|
||||
};
|
||||
|
||||
handleCloseModal = () => {
|
||||
this.modal = null;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { user, auth, collections, history, ui } = this.props;
|
||||
const { user, auth, documents, collections, history, ui } = this.props;
|
||||
|
||||
return (
|
||||
<Container column auto>
|
||||
@@ -144,13 +152,17 @@ type Props = {
|
||||
<SidebarLink to="/starred">Starred</SidebarLink>
|
||||
</LinkSection>
|
||||
<LinkSection>
|
||||
<CreateCollection onClick={this.handleCreateCollection}>
|
||||
<AddIcon />
|
||||
</CreateCollection>
|
||||
{ui.activeCollection
|
||||
{collections.active
|
||||
? <CollectionAction onClick={this.handleEditCollection}>
|
||||
<MoreIcon />
|
||||
</CollectionAction>
|
||||
: <CollectionAction onClick={this.handleCreateCollection}>
|
||||
<AddIcon />
|
||||
</CollectionAction>}
|
||||
{collections.active
|
||||
? <SidebarCollection
|
||||
document={ui.activeDocument}
|
||||
collection={ui.activeCollection}
|
||||
document={documents.active}
|
||||
collection={collections.active}
|
||||
history={this.props.history}
|
||||
/>
|
||||
: <SidebarCollectionList history={this.props.history} />}
|
||||
@@ -171,9 +183,22 @@ type Props = {
|
||||
<CollectionNew
|
||||
collections={collections}
|
||||
history={history}
|
||||
onCollectionCreated={this.handleCloseModal}
|
||||
onSubmit={this.handleCloseModal}
|
||||
/>
|
||||
</Modal>
|
||||
<Modal
|
||||
isOpen={this.modal === 'edit-collection'}
|
||||
onRequestClose={this.handleCloseModal}
|
||||
title="Edit collection"
|
||||
>
|
||||
{collections.active &&
|
||||
<CollectionEdit
|
||||
collection={collections.active}
|
||||
collections={collections}
|
||||
history={history}
|
||||
onSubmit={this.handleCloseModal}
|
||||
/>}
|
||||
</Modal>
|
||||
<Modal
|
||||
isOpen={this.modal === 'keyboard-shortcuts'}
|
||||
onRequestClose={this.handleCloseModal}
|
||||
@@ -193,7 +218,7 @@ type Props = {
|
||||
}
|
||||
}
|
||||
|
||||
const CreateCollection = styled.a`
|
||||
const CollectionAction = styled.a`
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: ${layout.hpadding};
|
||||
@@ -260,4 +285,6 @@ const LinkSection = styled(Flex)`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
export default withRouter(inject('user', 'auth', 'ui', 'collections')(Layout));
|
||||
export default withRouter(
|
||||
inject('user', 'auth', 'ui', 'documents', 'collections')(Layout)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user