Modals architecture
This commit is contained in:
@ -17,6 +17,7 @@ import Avatar from 'components/Avatar';
|
||||
import SidebarCollection from './components/SidebarCollection';
|
||||
import SidebarCollectionList from './components/SidebarCollectionList';
|
||||
import SidebarLink from './components/SidebarLink';
|
||||
import Modals from './components/Modals';
|
||||
|
||||
import UserStore from 'stores/UserStore';
|
||||
import AuthStore from 'stores/AuthStore';
|
||||
@ -59,6 +60,10 @@ type Props = {
|
||||
this.props.auth.logout(() => this.props.history.push('/'));
|
||||
};
|
||||
|
||||
createNewCollection = () => {
|
||||
this.props.ui.openModal('NewCollection');
|
||||
};
|
||||
|
||||
render() {
|
||||
const { user, auth, ui } = this.props;
|
||||
|
||||
@ -73,6 +78,12 @@ type Props = {
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Modals
|
||||
name={this.props.ui.modalName}
|
||||
component={this.props.ui.modalComponent}
|
||||
onRequestClose={this.props.ui.closeModal}
|
||||
{...this.props.ui.modalProps}
|
||||
/>
|
||||
|
||||
{this.props.ui.progressBarVisible && <LoadingIndicatorBar />}
|
||||
|
||||
@ -111,6 +122,9 @@ type Props = {
|
||||
<SidebarLink to="/dashboard">Home</SidebarLink>
|
||||
<SidebarLink to="/starred">Starred</SidebarLink>
|
||||
</LinkSection>
|
||||
<a onClick={this.createNewCollection}>
|
||||
Create new collection
|
||||
</a>
|
||||
<LinkSection>
|
||||
{ui.activeCollection
|
||||
? <SidebarCollection
|
||||
|
24
frontend/components/Layout/components/Modals.js
Normal file
24
frontend/components/Layout/components/Modals.js
Normal file
@ -0,0 +1,24 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import Modal from 'react-modal';
|
||||
|
||||
class Modals extends Component {
|
||||
render() {
|
||||
const { name, component, onRequestClose, ...rest } = this.props;
|
||||
const isOpen = !!component;
|
||||
const ModalComponent = component;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
contentLabel={name}
|
||||
onRequestClose={onRequestClose}
|
||||
>
|
||||
<button onClick={onRequestClose}>Close</button>
|
||||
{isOpen && <ModalComponent {...rest} />}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Modals;
|
6
frontend/components/NewCollection/NewCollection.js
Normal file
6
frontend/components/NewCollection/NewCollection.js
Normal file
@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
const NewCollection = () => <span>NEW COLLECTION</span>;
|
||||
|
||||
export default NewCollection;
|
3
frontend/components/NewCollection/index.js
Normal file
3
frontend/components/NewCollection/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
// @flow
|
||||
import NewCollection from './NewCollection';
|
||||
export default NewCollection;
|
5
frontend/components/modals.js
Normal file
5
frontend/components/modals.js
Normal file
@ -0,0 +1,5 @@
|
||||
// @flow
|
||||
// All components wishing to be used as modals must be defined below
|
||||
import NewCollection from './NewCollection';
|
||||
|
||||
export default { NewCollection };
|
@ -2,11 +2,14 @@
|
||||
import { observable, action, computed } from 'mobx';
|
||||
import Document from 'models/Document';
|
||||
import Collection from 'models/Collection';
|
||||
import modals from 'components/modals';
|
||||
|
||||
class UiStore {
|
||||
@observable activeDocument: ?Document;
|
||||
@observable progressBarVisible: boolean = false;
|
||||
@observable editMode: boolean = false;
|
||||
@observable modalName: ?string;
|
||||
@observable modalProps: ?Object;
|
||||
|
||||
/* Computed */
|
||||
|
||||
@ -14,6 +17,10 @@ class UiStore {
|
||||
return this.activeDocument ? this.activeDocument.collection : undefined;
|
||||
}
|
||||
|
||||
@computed get modalComponent(): ?ReactClass<any> {
|
||||
if (this.modalName) return modals[this.modalName];
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
|
||||
@action setActiveDocument = (document: Document): void => {
|
||||
@ -24,6 +31,16 @@ class UiStore {
|
||||
this.activeDocument = undefined;
|
||||
};
|
||||
|
||||
@action openModal = (name: string, props?: Object) => {
|
||||
this.modalName = name;
|
||||
this.modalProps = props;
|
||||
};
|
||||
|
||||
@action closeModal = () => {
|
||||
this.modalName = undefined;
|
||||
this.modalProps = undefined;
|
||||
};
|
||||
|
||||
@action enableEditMode() {
|
||||
this.editMode = true;
|
||||
}
|
||||
|
@ -142,6 +142,7 @@
|
||||
"react-dropzone": "3.6.0",
|
||||
"react-helmet": "3.1.0",
|
||||
"react-keydown": "^1.7.3",
|
||||
"react-modal": "^2.2.1",
|
||||
"react-portal": "^3.1.0",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"redis": "^2.6.2",
|
||||
|
51
yarn.lock
51
yarn.lock
@ -2433,6 +2433,10 @@ elegant-spinner@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
|
||||
|
||||
element-class@^0.2.0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/element-class/-/element-class-0.2.2.tgz#9d3bbd0767f9013ef8e1c8ebe722c1402a60050e"
|
||||
|
||||
elliptic@^6.0.0:
|
||||
version "6.3.2"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.2.tgz#e4c81e0829cf0a65ab70e998b8232723b5c1bc48"
|
||||
@ -2908,6 +2912,10 @@ execa@^0.6.0:
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
exenv@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89"
|
||||
|
||||
exit-hook@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
|
||||
@ -6973,6 +6981,13 @@ promise@7.x, promise@^7.0.3, promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10:
|
||||
version "15.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.3.1"
|
||||
|
||||
prop-types@^15.5.4, prop-types@^15.5.8:
|
||||
version "15.5.8"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394"
|
||||
@ -7121,6 +7136,10 @@ react-deep-force-update@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.0.1.tgz#f911b5be1d2a6fe387507dd6e9a767aa2924b4c7"
|
||||
|
||||
react-dom-factories@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.0.tgz#f43c05e5051b304f33251618d5bc859b29e46b6d"
|
||||
|
||||
react-dom@15.3.2, "react-dom@^0.14.0 || ^15.0.0":
|
||||
version "15.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.3.2.tgz#c46b0aa5380d7b838e7a59c4a7beff2ed315531f"
|
||||
@ -7145,6 +7164,15 @@ react-keydown@^1.7.3:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/react-keydown/-/react-keydown-1.7.3.tgz#51262d5e6e5ce5909e0279783e607bd5a6cc480c"
|
||||
|
||||
react-modal@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-2.2.1.tgz#22563782688bbb43441ac436156d6cb5dcb60c8b"
|
||||
dependencies:
|
||||
element-class "^0.2.0"
|
||||
exenv "1.2.0"
|
||||
prop-types "^15.5.10"
|
||||
react-dom-factories "^1.0.0"
|
||||
|
||||
react-portal@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-3.1.0.tgz#865c44fb72a1da106c649206936559ce891ee899"
|
||||
@ -7369,13 +7397,6 @@ referrer-policy@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79"
|
||||
|
||||
reflexbox@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/reflexbox/-/reflexbox-2.2.3.tgz#9b9ce983dbe677cebf3a94cf2c50b8157f50c0d1"
|
||||
dependencies:
|
||||
robox "^1.0.0-beta.8"
|
||||
ruled "^1.0.1"
|
||||
|
||||
regenerate@^1.2.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.1.tgz#0300203a5d2fdcf89116dce84275d011f5903f33"
|
||||
@ -7629,16 +7650,6 @@ rndm@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c"
|
||||
|
||||
robox@^1.0.0-beta.8:
|
||||
version "1.0.0-beta.8"
|
||||
resolved "https://registry.yarnpkg.com/robox/-/robox-1.0.0-beta.8.tgz#9aaee1dacf38a8c4ca4584a80012aebab5711c73"
|
||||
dependencies:
|
||||
understyle "^1.2.0"
|
||||
|
||||
ruled@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ruled/-/ruled-1.0.1.tgz#8301a1accc9d2e14b6502fca7033582335c2c0f4"
|
||||
|
||||
run-async@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
|
||||
@ -8613,12 +8624,6 @@ underscore@^1.7.0:
|
||||
version "1.8.3"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
|
||||
|
||||
understyle@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/understyle/-/understyle-1.3.0.tgz#df3f9a9be96779d718c3da9598fad1c2f90f24ee"
|
||||
dependencies:
|
||||
object-assign "^4.1.0"
|
||||
|
||||
"unicode@>= 0.3.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/unicode/-/unicode-0.6.1.tgz#ec69e3c4537e2b9650b826133bcb068f0445d0bc"
|
||||
|
Reference in New Issue
Block a user