Combined documents and collections in the sidepanel
This commit is contained in:
@ -1,80 +1,98 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import invariant from 'invariant';
|
||||||
import { observable } from 'mobx';
|
import { observable } from 'mobx';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import keydown from 'react-keydown';
|
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import Portal from 'react-portal';
|
||||||
import Flex from 'components/Flex';
|
import Flex from 'components/Flex';
|
||||||
import { color } from 'styles/constants';
|
import { color } from 'styles/constants';
|
||||||
import { fadeAndScaleIn } from 'styles/animations';
|
import { fadeAndScaleIn } from 'styles/animations';
|
||||||
|
|
||||||
type DropdownMenuProps = {
|
type DropdownMenuProps = {
|
||||||
label: React.Element<any>,
|
label: React.Element<any>,
|
||||||
|
onShow?: Function,
|
||||||
|
onClose?: Function,
|
||||||
children?: React.Element<any>,
|
children?: React.Element<any>,
|
||||||
style?: Object,
|
style?: Object,
|
||||||
};
|
};
|
||||||
|
|
||||||
@observer class DropdownMenu extends React.Component {
|
@observer class DropdownMenu extends React.Component {
|
||||||
props: DropdownMenuProps;
|
props: DropdownMenuProps;
|
||||||
|
actionRef: Object;
|
||||||
@observable open: boolean = false;
|
@observable open: boolean = false;
|
||||||
|
@observable top: number;
|
||||||
|
@observable left: number;
|
||||||
|
@observable right: number;
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = (ev: SyntheticEvent) => {
|
||||||
this.open = !this.open;
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
invariant(document.body, 'why you not here');
|
||||||
|
const bodyRect = document.body.getBoundingClientRect();
|
||||||
|
// $FlowIssue it's there
|
||||||
|
const targetRect = ev.currentTarget.getBoundingClientRect();
|
||||||
|
this.open = true;
|
||||||
|
this.top = targetRect.bottom - bodyRect.top;
|
||||||
|
this.right = bodyRect.width - targetRect.left - targetRect.width;
|
||||||
|
if (this.props.onShow) this.props.onShow();
|
||||||
};
|
};
|
||||||
|
|
||||||
@keydown('esc')
|
handleClose = (ev: SyntheticEvent) => {
|
||||||
handleEscape() {
|
|
||||||
this.open = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClickOutside = (ev: SyntheticEvent) => {
|
|
||||||
ev.stopPropagation();
|
|
||||||
this.open = false;
|
this.open = false;
|
||||||
|
if (this.props.onClose) this.props.onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
const openAction = (
|
||||||
<MenuContainer onClick={this.handleClick}>
|
<Label
|
||||||
{this.open && <Backdrop onClick={this.handleClickOutside} />}
|
onClick={this.handleClick}
|
||||||
<Label>
|
innerRef={ref => (this.actionRef = ref)}
|
||||||
|
>
|
||||||
{this.props.label}
|
{this.props.label}
|
||||||
</Label>
|
</Label>
|
||||||
{this.open &&
|
);
|
||||||
<Menu style={this.props.style}>
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{openAction}
|
||||||
|
<Portal
|
||||||
|
closeOnEsc
|
||||||
|
closeOnOutsideClick
|
||||||
|
isOpened={this.open}
|
||||||
|
onClose={this.handleClose}
|
||||||
|
>
|
||||||
|
<Menu
|
||||||
|
style={this.props.style}
|
||||||
|
left={this.left}
|
||||||
|
top={this.top}
|
||||||
|
right={this.right}
|
||||||
|
>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</Menu>}
|
</Menu>
|
||||||
</MenuContainer>
|
</Portal>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Backdrop = styled.div`
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 999;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Label = styled(Flex).attrs({
|
const Label = styled(Flex).attrs({
|
||||||
justify: 'center',
|
justify: 'center',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
})`
|
})`
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MenuContainer = styled.div`
|
|
||||||
position: relative;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Menu = styled.div`
|
const Menu = styled.div`
|
||||||
animation: ${fadeAndScaleIn} 250ms ease;
|
animation: ${fadeAndScaleIn} 250ms ease;
|
||||||
transform-origin: 75% 0;
|
transform-origin: 75% 0;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: ${({ right }) => right}px;
|
||||||
|
top: ${({ top }) => top}px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
border: ${color.slateLight};
|
border: ${color.slateLight};
|
||||||
background: ${color.white};
|
background: ${color.white};
|
||||||
|
@ -14,11 +14,9 @@ import { LoadingIndicatorBar } from 'components/LoadingIndicator';
|
|||||||
import Scrollable from 'components/Scrollable';
|
import Scrollable from 'components/Scrollable';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
import Toasts from 'components/Toasts';
|
import Toasts from 'components/Toasts';
|
||||||
import CollectionMenu from 'menus/CollectionMenu';
|
|
||||||
import AccountMenu from 'menus/AccountMenu';
|
import AccountMenu from 'menus/AccountMenu';
|
||||||
|
|
||||||
import SidebarCollection from './components/SidebarCollection';
|
import SidebarCollections from './components/SidebarCollections';
|
||||||
import SidebarCollectionList from './components/SidebarCollectionList';
|
|
||||||
import SidebarLink from './components/SidebarLink';
|
import SidebarLink from './components/SidebarLink';
|
||||||
import HeaderBlock from './components/HeaderBlock';
|
import HeaderBlock from './components/HeaderBlock';
|
||||||
import Modals from './components/Modals';
|
import Modals from './components/Modals';
|
||||||
@ -84,7 +82,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { auth, documents, collections, ui } = this.props;
|
const { auth, documents, ui } = this.props;
|
||||||
const { user, team } = auth;
|
const { user, team } = auth;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -130,20 +128,11 @@ type Props = {
|
|||||||
</SidebarLink>
|
</SidebarLink>
|
||||||
</LinkSection>
|
</LinkSection>
|
||||||
<LinkSection>
|
<LinkSection>
|
||||||
{collections.active
|
<SidebarCollections
|
||||||
? <CollectionAction>
|
|
||||||
<CollectionMenu collection={collections.active} />
|
|
||||||
</CollectionAction>
|
|
||||||
: <CollectionAction onClick={this.handleCreateCollection}>
|
|
||||||
<Icon type="PlusCircle" />
|
|
||||||
</CollectionAction>}
|
|
||||||
{collections.active
|
|
||||||
? <SidebarCollection
|
|
||||||
document={documents.active}
|
|
||||||
collection={collections.active}
|
|
||||||
history={this.props.history}
|
history={this.props.history}
|
||||||
|
activeDocument={documents.active}
|
||||||
|
onCreateCollection={this.handleCreateCollection}
|
||||||
/>
|
/>
|
||||||
: <SidebarCollectionList history={this.props.history} />}
|
|
||||||
</LinkSection>
|
</LinkSection>
|
||||||
</Scrollable>
|
</Scrollable>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -160,18 +149,6 @@ type Props = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionAction = styled.a`
|
|
||||||
position: absolute;
|
|
||||||
top: -4px;
|
|
||||||
right: ${layout.hpadding};
|
|
||||||
color: ${color.slate};
|
|
||||||
svg { opacity: .75; }
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
svg { opacity: 1; }
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Container = styled(Flex)`
|
const Container = styled(Flex)`
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import React from 'react';
|
|
||||||
import { observer } from 'mobx-react';
|
|
||||||
import Flex from 'components/Flex';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { color, layout } from 'styles/constants';
|
|
||||||
import SidebarLink from '../SidebarLink';
|
|
||||||
import DropToImport from 'components/DropToImport';
|
|
||||||
|
|
||||||
import Collection from 'models/Collection';
|
|
||||||
import Document from 'models/Document';
|
|
||||||
import type { NavigationNode } from 'types';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
collection: ?Collection,
|
|
||||||
document: ?Document,
|
|
||||||
history: Object,
|
|
||||||
};
|
|
||||||
|
|
||||||
const activeStyle = {
|
|
||||||
color: color.black,
|
|
||||||
background: color.slateDark,
|
|
||||||
};
|
|
||||||
|
|
||||||
@observer class SidebarCollection extends React.Component {
|
|
||||||
props: Props;
|
|
||||||
|
|
||||||
renderDocuments(documentList: Array<NavigationNode>, depth: number = 0) {
|
|
||||||
const { document, history } = this.props;
|
|
||||||
const canDropToImport = depth === 0;
|
|
||||||
|
|
||||||
if (document) {
|
|
||||||
return documentList.map(doc => (
|
|
||||||
<Flex column key={doc.id}>
|
|
||||||
{canDropToImport &&
|
|
||||||
<DropToImport
|
|
||||||
history={history}
|
|
||||||
documentId={doc.id}
|
|
||||||
activeStyle={activeStyle}
|
|
||||||
>
|
|
||||||
<SidebarLink to={doc.url}>{doc.title}</SidebarLink>
|
|
||||||
</DropToImport>}
|
|
||||||
{!canDropToImport &&
|
|
||||||
<SidebarLink to={doc.url}>{doc.title}</SidebarLink>}
|
|
||||||
|
|
||||||
{(document.pathToDocument.map(entry => entry.id).includes(doc.id) ||
|
|
||||||
document.id === doc.id) &&
|
|
||||||
<Children column>
|
|
||||||
{doc.children && this.renderDocuments(doc.children, depth + 1)}
|
|
||||||
</Children>}
|
|
||||||
</Flex>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { collection } = this.props;
|
|
||||||
|
|
||||||
if (collection) {
|
|
||||||
return (
|
|
||||||
<Flex column>
|
|
||||||
<Header>{collection.name}</Header>
|
|
||||||
{this.renderDocuments(collection.documents)}
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Header = styled(Flex)`
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 500;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: ${color.slate};
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
padding: 0 ${layout.hpadding};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Children = styled(Flex)`
|
|
||||||
margin-left: 20px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default SidebarCollection;
|
|
@ -1,3 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import SidebarCollection from './SidebarCollection';
|
|
||||||
export default SidebarCollection;
|
|
@ -1,52 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import React from 'react';
|
|
||||||
import { observer, inject } from 'mobx-react';
|
|
||||||
import Flex from 'components/Flex';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { color, layout, fontWeight } from 'styles/constants';
|
|
||||||
|
|
||||||
import SidebarLink from '../SidebarLink';
|
|
||||||
import DropToImport from 'components/DropToImport';
|
|
||||||
|
|
||||||
import CollectionsStore from 'stores/CollectionsStore';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
history: Object,
|
|
||||||
collections: CollectionsStore,
|
|
||||||
};
|
|
||||||
|
|
||||||
const activeStyle = {
|
|
||||||
color: color.black,
|
|
||||||
background: color.slateDark,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SidebarCollectionList = observer(({ history, collections }: Props) => {
|
|
||||||
return (
|
|
||||||
<Flex column>
|
|
||||||
<Header>Collections</Header>
|
|
||||||
{collections.data.map(collection => (
|
|
||||||
<DropToImport
|
|
||||||
key={collection.id}
|
|
||||||
history={history}
|
|
||||||
collectionId={collection.id}
|
|
||||||
activeStyle={activeStyle}
|
|
||||||
>
|
|
||||||
<SidebarLink key={collection.id} to={collection.entryUrl}>
|
|
||||||
{collection.name}
|
|
||||||
</SidebarLink>
|
|
||||||
</DropToImport>
|
|
||||||
))}
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const Header = styled(Flex)`
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: ${fontWeight.semiBold};
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: ${color.slate};
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
padding: 0 ${layout.hpadding};
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default inject('collections')(SidebarCollectionList);
|
|
@ -1,3 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import SidebarCollectionList from './SidebarCollectionList';
|
|
||||||
export default SidebarCollectionList;
|
|
171
frontend/components/Layout/components/SidebarCollections.js
Normal file
171
frontend/components/Layout/components/SidebarCollections.js
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import { observable } from 'mobx';
|
||||||
|
import { observer, inject } from 'mobx-react';
|
||||||
|
import Flex from 'components/Flex';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { color, layout, fontWeight } from 'styles/constants';
|
||||||
|
|
||||||
|
import SidebarLink from './SidebarLink';
|
||||||
|
import DropToImport from 'components/DropToImport';
|
||||||
|
import Icon from 'components/Icon';
|
||||||
|
import CollectionMenu from 'menus/CollectionMenu';
|
||||||
|
|
||||||
|
import CollectionsStore from 'stores/CollectionsStore';
|
||||||
|
import UiStore from 'stores/UiStore';
|
||||||
|
import Document from 'models/Document';
|
||||||
|
import { type NavigationNode } from 'types';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
history: Object,
|
||||||
|
collections: CollectionsStore,
|
||||||
|
activeDocument: ?Document,
|
||||||
|
onCreateCollection: Function,
|
||||||
|
ui: UiStore,
|
||||||
|
};
|
||||||
|
|
||||||
|
const activeStyle = {
|
||||||
|
color: color.black,
|
||||||
|
background: color.slateDark,
|
||||||
|
};
|
||||||
|
|
||||||
|
@observer class SidebarCollections extends React.PureComponent {
|
||||||
|
props: Props;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { collections, activeDocument, ui } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex column>
|
||||||
|
<Header>Collections</Header>
|
||||||
|
{collections.data.map(collection => (
|
||||||
|
<CollectionLink
|
||||||
|
key={collection.id}
|
||||||
|
collection={collection}
|
||||||
|
activeDocument={activeDocument}
|
||||||
|
ui={ui}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{collections.isLoaded &&
|
||||||
|
<SidebarLink onClick={this.props.onCreateCollection}>
|
||||||
|
<Icon type="Plus" /> Add new collection
|
||||||
|
</SidebarLink>}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer class CollectionLink extends React.Component {
|
||||||
|
@observable isHovering = false;
|
||||||
|
@observable menuOpen = false;
|
||||||
|
|
||||||
|
handleHover = () => (this.isHovering = true);
|
||||||
|
handleBlur = () => {
|
||||||
|
if (!this.menuOpen) this.isHovering = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { collection, activeDocument, ui } = this.props;
|
||||||
|
return (
|
||||||
|
<DropToImport
|
||||||
|
key={collection.id}
|
||||||
|
history={history}
|
||||||
|
collectionId={collection.id}
|
||||||
|
activeStyle={activeStyle}
|
||||||
|
onMouseEnter={this.handleHover}
|
||||||
|
onMouseLeave={this.handleBlur}
|
||||||
|
>
|
||||||
|
<SidebarLink key={collection.id} to={collection.url}>
|
||||||
|
<Flex justify="space-between">
|
||||||
|
{collection.name}
|
||||||
|
|
||||||
|
{(this.isHovering || this.menuOpen) &&
|
||||||
|
<CollectionAction>
|
||||||
|
<CollectionMenu
|
||||||
|
collection={collection}
|
||||||
|
onShow={() => (this.menuOpen = true)}
|
||||||
|
onClose={() => (this.menuOpen = false)}
|
||||||
|
/>
|
||||||
|
</CollectionAction>}
|
||||||
|
</Flex>
|
||||||
|
{collection.id === ui.activeCollectionId &&
|
||||||
|
collection.documents.map(document => (
|
||||||
|
<DocumentLink
|
||||||
|
key={document.id}
|
||||||
|
document={document}
|
||||||
|
activeDocument={activeDocument}
|
||||||
|
depth={0}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</SidebarLink>
|
||||||
|
</DropToImport>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DocumentLinkProps = {
|
||||||
|
document: NavigationNode,
|
||||||
|
activeDocument: ?Document,
|
||||||
|
depth: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
const DocumentLink = observer((props: DocumentLinkProps) => {
|
||||||
|
const { document, activeDocument, depth } = props;
|
||||||
|
const canDropToImport = depth === 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex column key={document.id}>
|
||||||
|
{canDropToImport &&
|
||||||
|
<DropToImport
|
||||||
|
history={history}
|
||||||
|
documentId={document.id}
|
||||||
|
activeStyle={activeStyle}
|
||||||
|
>
|
||||||
|
<SidebarLink to={document.url}>{document.title}</SidebarLink>
|
||||||
|
</DropToImport>}
|
||||||
|
{!canDropToImport &&
|
||||||
|
<SidebarLink to={document.url}>{document.title}</SidebarLink>}
|
||||||
|
|
||||||
|
{activeDocument &&
|
||||||
|
(activeDocument.pathToDocument
|
||||||
|
.map(entry => entry.id)
|
||||||
|
.includes(document.id) ||
|
||||||
|
activeDocument.id === document.id) &&
|
||||||
|
<Children column>
|
||||||
|
{document.children &&
|
||||||
|
document.children.map(childDocument => (
|
||||||
|
<DocumentLink
|
||||||
|
key={childDocument.id}
|
||||||
|
document={childDocument}
|
||||||
|
depth={depth + 1}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Children>}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const Header = styled(Flex)`
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: ${fontWeight.semiBold};
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: ${color.slate};
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
padding: 0 ${layout.hpadding};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CollectionAction = styled.a`
|
||||||
|
color: ${color.slate};
|
||||||
|
svg { opacity: .75; }
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
svg { opacity: 1; }
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Children = styled(Flex)`
|
||||||
|
margin-left: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default inject('collections', 'ui')(SidebarCollections);
|
@ -9,21 +9,24 @@ const activeStyle = {
|
|||||||
fontWeight: fontWeight.semiBold,
|
fontWeight: fontWeight.semiBold,
|
||||||
};
|
};
|
||||||
|
|
||||||
function SidebarLink(props: Object) {
|
// $FlowFixMe :/
|
||||||
return <StyledNavLink exact activeStyle={activeStyle} {...props} />;
|
const styleComponent = component => styled(component)`
|
||||||
}
|
|
||||||
|
|
||||||
const StyledNavLink = styled(NavLink)`
|
|
||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
margin: 5px ${layout.hpadding};
|
margin: 5px ${layout.hpadding};
|
||||||
color: ${color.slateDark};
|
color: ${color.slateDark};
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: ${color.text};
|
color: ${color.text};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function SidebarLink(props: Object) {
|
||||||
|
const Component = styleComponent(props.to ? NavLink : 'div');
|
||||||
|
return <Component exact activeStyle={activeStyle} {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
export default SidebarLink;
|
export default SidebarLink;
|
@ -1,3 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import SidebarLink from './SidebarLink';
|
|
||||||
export default SidebarLink;
|
|
@ -1,3 +0,0 @@
|
|||||||
// @flow
|
|
||||||
import Title from './Title';
|
|
||||||
export default Title;
|
|
@ -1,6 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import Collection from 'models/Collection';
|
import Collection from 'models/Collection';
|
||||||
import UiStore from 'stores/UiStore';
|
import UiStore from 'stores/UiStore';
|
||||||
@ -10,6 +9,8 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
|
|||||||
@observer class CollectionMenu extends Component {
|
@observer class CollectionMenu extends Component {
|
||||||
props: {
|
props: {
|
||||||
label?: React$Element<any>,
|
label?: React$Element<any>,
|
||||||
|
onShow?: Function,
|
||||||
|
onClose?: Function,
|
||||||
history: Object,
|
history: Object,
|
||||||
ui: UiStore,
|
ui: UiStore,
|
||||||
collection: Collection,
|
collection: Collection,
|
||||||
@ -26,11 +27,15 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { collection, label } = this.props;
|
const { collection, label, onShow, onClose } = this.props;
|
||||||
const { allowDelete } = collection;
|
const { allowDelete } = collection;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu label={label || <Icon type="MoreHorizontal" />}>
|
<DropdownMenu
|
||||||
|
label={label || <Icon type="MoreHorizontal" />}
|
||||||
|
onShow={onShow}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
{collection &&
|
{collection &&
|
||||||
<DropdownMenuItem onClick={this.onEdit}>Edit</DropdownMenuItem>}
|
<DropdownMenuItem onClick={this.onEdit}>Edit</DropdownMenuItem>}
|
||||||
{allowDelete &&
|
{allowDelete &&
|
||||||
@ -40,4 +45,4 @@ import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(inject('ui')(CollectionMenu));
|
export default inject('ui')(CollectionMenu);
|
||||||
|
@ -29,12 +29,17 @@ type Props = {
|
|||||||
@observable redirectUrl;
|
@observable redirectUrl;
|
||||||
|
|
||||||
componentDidMount = () => {
|
componentDidMount = () => {
|
||||||
this.fetchDocument();
|
this.fetchDocument(this.props.match.params.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchDocument = async () => {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (nextProps.match.params.id !== this.props.match.params.id) {
|
||||||
|
this.fetchDocument(nextProps.match.params.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchDocument = async (id: string) => {
|
||||||
const { collections } = this.props;
|
const { collections } = this.props;
|
||||||
const { id } = this.props.match.params;
|
|
||||||
|
|
||||||
this.collection = await collections.getById(id);
|
this.collection = await collections.getById(id);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user