mirror of
https://github.com/ascribe/onion.git
synced 2025-02-14 21:10:27 +01:00
Merge pull request #202 from ascribe/upgrade-react
Upgrade react and react-router
This commit is contained in:
commit
6eeac85012
24
js/app.js
24
js/app.js
@ -4,16 +4,20 @@ import 'classlist-polyfill';
|
|||||||
import 'isomorphic-fetch';
|
import 'isomorphic-fetch';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Router } from 'react-router';
|
import ReactDOM from 'react-dom';
|
||||||
|
import Router from 'react-router/es6/Router';
|
||||||
|
|
||||||
import AppResolver from './app_resolver';
|
import AppResolver from './app_resolver';
|
||||||
import history from './history';
|
import history from './history';
|
||||||
|
|
||||||
|
import AppConstants from './constants/application_constants';
|
||||||
|
|
||||||
import { getDefaultSubdomainSettings, getSubdomainSettings } from './utils/constants_utils';
|
import { getDefaultSubdomainSettings, getSubdomainSettings } from './utils/constants_utils';
|
||||||
import { initLogging } from './utils/error_utils';
|
import { initLogging } from './utils/error_utils';
|
||||||
import { getSubdomain } from './utils/general_utils';
|
import { getSubdomain } from './utils/general_utils';
|
||||||
import requests from './utils/requests';
|
import requests from './utils/requests';
|
||||||
|
|
||||||
|
|
||||||
// FIXME: rename these event actions
|
// FIXME: rename these event actions
|
||||||
import EventActions from './actions/event_actions';
|
import EventActions from './actions/event_actions';
|
||||||
|
|
||||||
@ -50,10 +54,22 @@ const AppGateway = {
|
|||||||
|
|
||||||
// `history.listen` is called on every route change, which is perfect for routeDidChange
|
// `history.listen` is called on every route change, which is perfect for routeDidChange
|
||||||
// events.
|
// events.
|
||||||
history.listen(EventActions.routeDidChange);
|
// For history <= 3.0, history.listen will synchronously invoke the callback once
|
||||||
|
// immediately after registration.
|
||||||
|
history.listen((location) => {
|
||||||
|
const { locationQueue } = history;
|
||||||
|
locationQueue.unshift(location);
|
||||||
|
|
||||||
|
// Limit the number of locations to keep in memory to avoid too much memory usage
|
||||||
|
if (locationQueue.length > AppConstants.locationThreshold) {
|
||||||
|
locationQueue.length = AppConstants.locationThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventActions.routeDidChange(location);
|
||||||
|
});
|
||||||
|
|
||||||
// Adds a client specific class to the body for whitelabel styling
|
// Adds a client specific class to the body for whitelabel styling
|
||||||
window.document.body.classList.add(`client--${settings.subdomain}`);
|
window.document.body.classList.add(`client--${settings.subdomain || 'ascribe'}`);
|
||||||
|
|
||||||
AppResolver
|
AppResolver
|
||||||
.resolve(settings)
|
.resolve(settings)
|
||||||
@ -70,7 +86,7 @@ const AppGateway = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
React.render((
|
ReactDOM.render((
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
{redirectRoute}
|
{redirectRoute}
|
||||||
{routes}
|
{routes}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Redirect } from 'react-router';
|
import Redirect from 'react-router/es6/Redirect';
|
||||||
|
|
||||||
import Routes from './routes';
|
import Routes from './routes';
|
||||||
|
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import UserActions from '../actions/user_actions';
|
import UserActions from '../actions/user_actions';
|
||||||
import UserStore from '../stores/user_store';
|
import UserStore from '../stores/user_store';
|
||||||
@ -11,8 +7,7 @@ import WhitelabelActions from '../actions/whitelabel_actions';
|
|||||||
import WhitelabelStore from '../stores/whitelabel_store';
|
import WhitelabelStore from '../stores/whitelabel_store';
|
||||||
|
|
||||||
import GlobalNotification from './global_notification';
|
import GlobalNotification from './global_notification';
|
||||||
|
import { currentUserShape, locationShape, whitelabelShape } from './prop_types';
|
||||||
import AppConstants from '../constants/application_constants';
|
|
||||||
|
|
||||||
import { mergeOptions } from '../utils/general_utils';
|
import { mergeOptions } from '../utils/general_utils';
|
||||||
|
|
||||||
@ -23,11 +18,16 @@ export default function AppBase(App) {
|
|||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
children: React.PropTypes.element.isRequired,
|
children: React.PropTypes.element.isRequired,
|
||||||
history: React.PropTypes.object.isRequired,
|
location: locationShape.isRequired,
|
||||||
location: React.PropTypes.object.isRequired,
|
|
||||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
|
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
|
childContextTypes: {
|
||||||
|
currentUser: currentUserShape,
|
||||||
|
location: locationShape,
|
||||||
|
whitelabel: whitelabelShape
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
UserStore.getState(),
|
UserStore.getState(),
|
||||||
@ -35,7 +35,15 @@ export default function AppBase(App) {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
getChildContext() {
|
||||||
|
const { currentUser, whitelabel } = this.state;
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentUser,
|
||||||
|
whitelabel,
|
||||||
|
location: this.props.location
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
UserStore.listen(this.onChange);
|
UserStore.listen(this.onChange);
|
||||||
@ -43,18 +51,6 @@ export default function AppBase(App) {
|
|||||||
|
|
||||||
UserActions.fetchCurrentUser();
|
UserActions.fetchCurrentUser();
|
||||||
WhitelabelActions.fetchWhitelabel();
|
WhitelabelActions.fetchWhitelabel();
|
||||||
|
|
||||||
this.history.locationQueue.push(this.props.location);
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
const { locationQueue } = this.history;
|
|
||||||
locationQueue.unshift(nextProps.location);
|
|
||||||
|
|
||||||
// Limit the number of locations to keep in memory to avoid too much memory usage
|
|
||||||
if (locationQueue.length > AppConstants.locationThreshold) {
|
|
||||||
locationQueue.length = AppConstants.locationThreshold;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@ -68,7 +64,6 @@ export default function AppBase(App) {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { routes } = this.props;
|
const { routes } = this.props;
|
||||||
const { currentUser, whitelabel } = this.state;
|
|
||||||
|
|
||||||
// The second element of the routes prop given to us by react-router is always the
|
// The second element of the routes prop given to us by react-router is always the
|
||||||
// active second-level component object (ie. after App).
|
// active second-level component object (ie. after App).
|
||||||
@ -78,13 +73,11 @@ export default function AppBase(App) {
|
|||||||
<div>
|
<div>
|
||||||
<App
|
<App
|
||||||
{...this.props}
|
{...this.props}
|
||||||
activeRoute={activeRoute}
|
activeRoute={activeRoute} />
|
||||||
currentUser={currentUser}
|
|
||||||
whitelabel={whitelabel} />
|
|
||||||
<GlobalNotification />
|
<GlobalNotification />
|
||||||
<div id="modal" className="container" />
|
<div id="modal" className="container" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { omitFromObject } from '../utils/general_utils';
|
|
||||||
|
|
||||||
const AppRouteWrapper = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
children: React.PropTypes.oneOfType([
|
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
|
||||||
React.PropTypes.element
|
|
||||||
]).isRequired
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const propsToPropagate = omitFromObject(this.props, ['children']);
|
|
||||||
|
|
||||||
let childrenWithProps = this.props.children;
|
|
||||||
// If there are more props given, propagate them into the child routes by cloning the routes
|
|
||||||
if (Object.keys(propsToPropagate).length) {
|
|
||||||
childrenWithProps = React.Children.map(this.props.children, (child) => {
|
|
||||||
return React.cloneElement(child, propsToPropagate);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container ascribe-body">
|
|
||||||
{childrenWithProps}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default AppRouteWrapper;
|
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
|
|
||||||
let AccordionListItem = React.createClass({
|
let AccordionListItem = React.createClass({
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
|
||||||
|
|
||||||
import AccordionListItem from './accordion_list_item';
|
import AccordionListItem from './accordion_list_item';
|
||||||
import AccordionListItemThumbnailPlacholder from './accordion_list_item_thumbnail_placeholder';
|
import AccordionListItemThumbnailPlacholder from './accordion_list_item_thumbnail_placeholder';
|
||||||
|
@ -19,24 +19,27 @@ import AccordionListItemPiece from './accordion_list_item_piece';
|
|||||||
import AccordionListItemEditionWidget from './accordion_list_item_edition_widget';
|
import AccordionListItemEditionWidget from './accordion_list_item_edition_widget';
|
||||||
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||||
|
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let AccordionListItemWallet = React.createClass({
|
let AccordionListItemWallet = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
content: React.PropTypes.object.isRequired,
|
content: React.PropTypes.object.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
React.PropTypes.element
|
React.PropTypes.element
|
||||||
]),
|
]),
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
thumbnailPlaceholder: React.PropTypes.func
|
thumbnailPlaceholder: React.PropTypes.func,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -162,4 +165,4 @@ let AccordionListItemWallet = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AccordionListItemWallet;
|
export default withContext(AccordionListItemWallet, 'whitelabel');
|
||||||
|
@ -1,41 +1,28 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import AppBase from './app_base';
|
import AppBase from './app_base';
|
||||||
import AppRouteWrapper from './app_route_wrapper';
|
|
||||||
import Footer from './footer';
|
|
||||||
import Header from './header';
|
import Header from './header';
|
||||||
|
|
||||||
|
|
||||||
let AscribeApp = React.createClass({
|
const AscribeApp = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
activeRoute: React.PropTypes.object.isRequired,
|
activeRoute: React.PropTypes.object.isRequired,
|
||||||
children: React.PropTypes.element.isRequired,
|
children: React.PropTypes.element.isRequired,
|
||||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
|
||||||
|
|
||||||
// Provided from AppBase
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { activeRoute, children, currentUser, routes, whitelabel } = this.props;
|
const { activeRoute, children, routes } = this.props;
|
||||||
const Footer = activeRoute && activeRoute.footer;
|
const RouteFooterType = activeRoute && activeRoute.footer;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ascribe-app ascribe-default-app">
|
<div className="ascribe-app ascribe-default-app">
|
||||||
<Header
|
<Header routes={routes} />
|
||||||
currentUser={currentUser}
|
<div className="container ascribe-body">
|
||||||
routes={routes}
|
|
||||||
whitelabel={whitelabel} />
|
|
||||||
<AppRouteWrapper
|
|
||||||
currentUser={currentUser}
|
|
||||||
whitelabel={whitelabel}>
|
|
||||||
{/* Routes are injected here */}
|
{/* Routes are injected here */}
|
||||||
{children}
|
{children}
|
||||||
</AppRouteWrapper>
|
</div>
|
||||||
{Footer ? <Footer /> : null}
|
{RouteFooterType ? <RouteFooterType /> : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react/addons';
|
import React from 'react';
|
||||||
|
|
||||||
import ConsignButton from './acls/consign_button';
|
import ConsignButton from './acls/consign_button';
|
||||||
import EmailButton from './acls/email_button';
|
import EmailButton from './acls/email_button';
|
||||||
@ -14,7 +14,6 @@ import { selectFromObject } from '../../utils/general_utils';
|
|||||||
let AclButtonList = React.createClass({
|
let AclButtonList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
availableAcls: React.PropTypes.object.isRequired,
|
availableAcls: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
handleSuccess: React.PropTypes.func.isRequired,
|
handleSuccess: React.PropTypes.func.isRequired,
|
||||||
pieceOrEditions: React.PropTypes.oneOfType([
|
pieceOrEditions: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.object,
|
React.PropTypes.object,
|
||||||
@ -52,7 +51,7 @@ let AclButtonList = React.createClass({
|
|||||||
|
|
||||||
handleResize() {
|
handleResize() {
|
||||||
this.setState({
|
this.setState({
|
||||||
buttonListSize: this.refs.buttonList.getDOMNode().offsetWidth
|
buttonListSize: this.refs.buttonList.offsetWidth
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ let AclButtonList = React.createClass({
|
|||||||
const { buttonListSize } = this.state;
|
const { buttonListSize } = this.state;
|
||||||
|
|
||||||
return React.Children.map(children, (child) => {
|
return React.Children.map(children, (child) => {
|
||||||
return React.addons.cloneWithProps(child, { buttonListSize });
|
return React.cloneElement(child, { buttonListSize });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -69,13 +68,11 @@ let AclButtonList = React.createClass({
|
|||||||
const { availableAcls,
|
const { availableAcls,
|
||||||
buttonsStyle,
|
buttonsStyle,
|
||||||
className,
|
className,
|
||||||
currentUser,
|
|
||||||
handleSuccess,
|
handleSuccess,
|
||||||
pieceOrEditions } = this.props;
|
pieceOrEditions } = this.props;
|
||||||
|
|
||||||
const buttonProps = selectFromObject(this.props, [
|
const buttonProps = selectFromObject(this.props, [
|
||||||
'availableAcls',
|
'availableAcls',
|
||||||
'currentUser',
|
|
||||||
'handleSuccess',
|
'handleSuccess',
|
||||||
'pieceOrEditions'
|
'pieceOrEditions'
|
||||||
]);
|
]);
|
||||||
|
@ -37,13 +37,13 @@ let AclInformation = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getInfoText(title, info, example){
|
getInfoText(title, info, example) {
|
||||||
const aim = this.props.aim;
|
const aim = this.props.aim;
|
||||||
|
|
||||||
if(aim) {
|
if(aim) {
|
||||||
if(aim === 'form') {
|
if(aim === 'form') {
|
||||||
return (
|
return (
|
||||||
<p>
|
<p key={title}>
|
||||||
<span className="info">
|
<span className="info">
|
||||||
{replaceSubstringAtIndex(info.slice(2), 's ', ' ')}
|
{replaceSubstringAtIndex(info.slice(2), 's ', ' ')}
|
||||||
</span>
|
</span>
|
||||||
@ -55,7 +55,7 @@ let AclInformation = React.createClass({
|
|||||||
}
|
}
|
||||||
else if(aim === 'button') {
|
else if(aim === 'button') {
|
||||||
return (
|
return (
|
||||||
<p>
|
<p key={title}>
|
||||||
<span className="title">
|
<span className="title">
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
|
@ -31,7 +31,6 @@ export default function AclButton({ action, displayName, title, tooltip }) {
|
|||||||
|
|
||||||
buttonAcceptName: React.PropTypes.string,
|
buttonAcceptName: React.PropTypes.string,
|
||||||
buttonAcceptClassName: React.PropTypes.string,
|
buttonAcceptClassName: React.PropTypes.string,
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
@ -43,7 +42,6 @@ export default function AclButton({ action, displayName, title, tooltip }) {
|
|||||||
render() {
|
render() {
|
||||||
const { availableAcls,
|
const { availableAcls,
|
||||||
buttonAcceptClassName,
|
buttonAcceptClassName,
|
||||||
currentUser,
|
|
||||||
email,
|
email,
|
||||||
pieceOrEditions,
|
pieceOrEditions,
|
||||||
handleSuccess } = this.props;
|
handleSuccess } = this.props;
|
||||||
@ -63,7 +61,6 @@ export default function AclButton({ action, displayName, title, tooltip }) {
|
|||||||
title={title}>
|
title={title}>
|
||||||
<AclFormFactory
|
<AclFormFactory
|
||||||
action={action}
|
action={action}
|
||||||
currentUser={currentUser}
|
|
||||||
email={email}
|
email={email}
|
||||||
pieceOrEditions={pieceOrEditions}
|
pieceOrEditions={pieceOrEditions}
|
||||||
showNotification />
|
showNotification />
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react/addons';
|
import React from 'react';
|
||||||
|
import update from 'react-addons-update';
|
||||||
|
|
||||||
const { string, object } = React.PropTypes;
|
const { string, object } = React.PropTypes;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ const FormSubmitButton = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setReadyStateForKey(key, state) {
|
setReadyStateForKey(key, state) {
|
||||||
const readyStates = React.addons.update(this.state.readyStates, { [key]: { $set: state } });
|
const readyStates = update(this.state.readyStates, { [key]: { $set: state } });
|
||||||
this.setState({ readyStates });
|
this.setState({ readyStates });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -5,21 +5,26 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
|
|
||||||
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
||||||
import UnConsignRequestForm from './../ascribe_forms/form_unconsign_request';
|
import UnConsignRequestForm from '../ascribe_forms/form_unconsign_request';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils.js';
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape } from '../prop_types';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
|
|
||||||
let UnConsignRequestButton = React.createClass({
|
const UnConsignRequestButton = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
edition: React.PropTypes.object.isRequired,
|
edition: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
render() {
|
||||||
const { currentUser, edition, handleSuccess } = this.props;
|
const { currentUser, edition, handleSuccess } = this.props;
|
||||||
return (
|
return (
|
||||||
<ModalWrapper
|
<ModalWrapper
|
||||||
@ -45,5 +50,4 @@ ${currentUser.username}`
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default UnConsignRequestButton;
|
export default withContext(UnConsignRequestButton, 'currentUser');
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
|
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
|
|
||||||
import EditionActions from '../../actions/edition_actions';
|
|
||||||
|
|
||||||
import DetailProperty from './detail_property';
|
import DetailProperty from './detail_property';
|
||||||
import EditionActionPanel from './edition_action_panel';
|
import EditionActionPanel from './edition_action_panel';
|
||||||
import FurtherDetails from './further_details';
|
import FurtherDetails from './further_details';
|
||||||
@ -24,6 +22,7 @@ import Form from '../ascribe_forms/form';
|
|||||||
import Property from '../ascribe_forms/property';
|
import Property from '../ascribe_forms/property';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
@ -34,16 +33,17 @@ import { getLangText } from '../../utils/lang_utils';
|
|||||||
/**
|
/**
|
||||||
* This is the component that implements display-specific functionality
|
* This is the component that implements display-specific functionality
|
||||||
*/
|
*/
|
||||||
let Edition = React.createClass({
|
const Edition = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
edition: React.PropTypes.object.isRequired,
|
edition: React.PropTypes.object.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
actionPanelButtonListType: React.PropTypes.func,
|
actionPanelButtonListType: React.PropTypes.func,
|
||||||
coaError: React.PropTypes.object,
|
coaError: React.PropTypes.object,
|
||||||
furtherDetailsType: React.PropTypes.func,
|
furtherDetailsType: React.PropTypes.func,
|
||||||
loadEdition: React.PropTypes.func
|
loadEdition: React.PropTypes.func,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
@ -53,20 +53,20 @@ let Edition = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { actionPanelButtonListType,
|
const {
|
||||||
coaError,
|
actionPanelButtonListType,
|
||||||
currentUser,
|
coaError,
|
||||||
edition,
|
edition,
|
||||||
furtherDetailsType: FurtherDetailsType,
|
isLoggedIn,
|
||||||
loadEdition,
|
loadEdition,
|
||||||
whitelabel } = this.props;
|
furtherDetailsType: FurtherDetailsType
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={6} className="ascribe-print-col-left">
|
<Col md={6} className="ascribe-print-col-left">
|
||||||
<MediaContainer
|
<MediaContainer
|
||||||
content={edition}
|
content={edition}
|
||||||
currentUser={currentUser}
|
|
||||||
refreshObject={loadEdition} />
|
refreshObject={loadEdition} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} className="ascribe-edition-details ascribe-print-col-right">
|
<Col md={6} className="ascribe-edition-details ascribe-print-col-right">
|
||||||
@ -82,9 +82,7 @@ let Edition = React.createClass({
|
|||||||
<EditionSummary
|
<EditionSummary
|
||||||
actionPanelButtonListType={actionPanelButtonListType}
|
actionPanelButtonListType={actionPanelButtonListType}
|
||||||
edition={edition}
|
edition={edition}
|
||||||
currentUser={currentUser}
|
handleSuccess={loadEdition} />
|
||||||
handleSuccess={loadEdition}
|
|
||||||
whitelabel={whitelabel} />
|
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Certificate of Authenticity')}
|
title={getLangText('Certificate of Authenticity')}
|
||||||
show={edition.acl.acl_coa === true}>
|
show={edition.acl.acl_coa === true}>
|
||||||
@ -114,7 +112,7 @@ let Edition = React.createClass({
|
|||||||
|
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Notes')}
|
title={getLangText('Notes')}
|
||||||
show={!!(currentUser.username || edition.acl.acl_edit || edition.public_note)}>
|
show={!!(isLoggedIn || edition.acl.acl_edit || edition.public_note)}>
|
||||||
<Note
|
<Note
|
||||||
id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
|
id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
|
||||||
label={getLangText('Personal note (private)')}
|
label={getLangText('Personal note (private)')}
|
||||||
@ -122,8 +120,7 @@ let Edition = React.createClass({
|
|||||||
placeholder={getLangText('Enter your comments ...')}
|
placeholder={getLangText('Enter your comments ...')}
|
||||||
editable={true}
|
editable={true}
|
||||||
successMessage={getLangText('Private note saved')}
|
successMessage={getLangText('Private note saved')}
|
||||||
url={ApiUrls.note_private_edition}
|
url={ApiUrls.note_private_edition} />
|
||||||
currentUser={currentUser} />
|
|
||||||
<Note
|
<Note
|
||||||
id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
|
id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
|
||||||
label={getLangText('Personal note (public)')}
|
label={getLangText('Personal note (public)')}
|
||||||
@ -132,8 +129,7 @@ let Edition = React.createClass({
|
|||||||
editable={!!edition.acl.acl_edit}
|
editable={!!edition.acl.acl_edit}
|
||||||
show={!!(edition.public_note || edition.acl.acl_edit)}
|
show={!!(edition.public_note || edition.acl.acl_edit)}
|
||||||
successMessage={getLangText('Public edition note saved')}
|
successMessage={getLangText('Public edition note saved')}
|
||||||
url={ApiUrls.note_public_edition}
|
url={ApiUrls.note_public_edition} />
|
||||||
currentUser={currentUser} />
|
|
||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Further Details')}
|
title={getLangText('Further Details')}
|
||||||
@ -155,14 +151,15 @@ let Edition = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let EditionSummary = React.createClass({
|
let EditionSummary = withContext(React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
edition: React.PropTypes.object.isRequired,
|
edition: React.PropTypes.object.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
actionPanelButtonListType: React.PropTypes.func,
|
actionPanelButtonListType: React.PropTypes.func,
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getStatus() {
|
getStatus() {
|
||||||
@ -176,7 +173,12 @@ let EditionSummary = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { actionPanelButtonListType, currentUser, edition, handleSuccess, whitelabel } = this.props;
|
const {
|
||||||
|
actionPanelButtonListType,
|
||||||
|
edition,
|
||||||
|
handleSuccess,
|
||||||
|
isLoggedIn,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ascribe-detail-header">
|
<div className="ascribe-detail-header">
|
||||||
@ -200,23 +202,21 @@ let EditionSummary = React.createClass({
|
|||||||
no more than 1 key, we're hiding the `DetailProperty` actions as otherwise
|
no more than 1 key, we're hiding the `DetailProperty` actions as otherwise
|
||||||
`AclInformation` would show up
|
`AclInformation` would show up
|
||||||
*/}
|
*/}
|
||||||
<AclProxy show={currentUser.email && Object.keys(edition.acl).length > 1}>
|
<AclProxy show={isLoggedIn && Object.keys(edition.acl).length > 1}>
|
||||||
<DetailProperty
|
<DetailProperty
|
||||||
label={getLangText('ACTIONS')}
|
label={getLangText('ACTIONS')}
|
||||||
className="hidden-print">
|
className="hidden-print">
|
||||||
<EditionActionPanel
|
<EditionActionPanel
|
||||||
actionPanelButtonListType={actionPanelButtonListType}
|
actionPanelButtonListType={actionPanelButtonListType}
|
||||||
currentUser={currentUser}
|
|
||||||
edition={edition}
|
edition={edition}
|
||||||
handleSuccess={handleSuccess}
|
handleSuccess={handleSuccess} />
|
||||||
whitelabel={whitelabel} />
|
|
||||||
</DetailProperty>
|
</DetailProperty>
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}), 'isLoggedIn');
|
||||||
|
|
||||||
|
|
||||||
let CoaDetails = React.createClass({
|
let CoaDetails = React.createClass({
|
||||||
@ -277,7 +277,7 @@ let CoaDetails = React.createClass({
|
|||||||
coaDetailElement = coa;
|
coaDetailElement = coa;
|
||||||
} else {
|
} else {
|
||||||
coaDetailElement = [
|
coaDetailElement = [
|
||||||
<AscribeSpinner color='dark-blue' size='md'/>,
|
<AscribeSpinner color='dark-blue' size='md' />,
|
||||||
<p>{getLangText("Just a sec, we're generating your COA")}</p>,
|
<p>{getLangText("Just a sec, we're generating your COA")}</p>,
|
||||||
<p>{getLangText('(you may leave the page)')}</p>
|
<p>{getLangText('(you may leave the page)')}</p>
|
||||||
];
|
];
|
||||||
@ -354,9 +354,9 @@ let SpoolDetails = React.createClass({
|
|||||||
<pre className="ascribe-pre">{ownerAddress}</pre>
|
<pre className="ascribe-pre">{ownerAddress}</pre>
|
||||||
</Property>
|
</Property>
|
||||||
<hr />
|
<hr />
|
||||||
</Form>);
|
</Form>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Edition;
|
export default withContext(Edition, 'isLoggedIn');
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
@ -11,20 +10,21 @@ import EditionListActions from '../../actions/edition_list_actions';
|
|||||||
import PieceListActions from '../../actions/piece_list_actions';
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
import PieceListStore from '../../stores/piece_list_store';
|
import PieceListStore from '../../stores/piece_list_store';
|
||||||
|
|
||||||
import Form from './../ascribe_forms/form';
|
|
||||||
import Property from './../ascribe_forms/property';
|
|
||||||
|
|
||||||
import ListRequestActions from './../ascribe_forms/list_form_request_actions';
|
|
||||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
|
||||||
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
|
|
||||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
|
import Form from './../ascribe_forms/form';
|
||||||
|
import ListRequestActions from './../ascribe_forms/list_form_request_actions';
|
||||||
|
import Property from './../ascribe_forms/property';
|
||||||
|
|
||||||
|
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
||||||
import AclInformation from '../ascribe_buttons/acl_information';
|
import AclInformation from '../ascribe_buttons/acl_information';
|
||||||
|
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||||
|
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { routerShape } from '../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
@ -34,17 +34,16 @@ import { getLangText } from '../../utils/lang_utils';
|
|||||||
A component that handles all the actions inside of the edition detail
|
A component that handles all the actions inside of the edition detail
|
||||||
handleSuccess requires a loadEdition action (could be refactored)
|
handleSuccess requires a loadEdition action (could be refactored)
|
||||||
*/
|
*/
|
||||||
let EditionActionPanel = React.createClass({
|
const EditionActionPanel = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
edition: React.PropTypes.object.isRequired,
|
edition: React.PropTypes.object.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
actionPanelButtonListType: React.PropTypes.func,
|
actionPanelButtonListType: React.PropTypes.func,
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func,
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
// Injected through HOCs
|
||||||
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
@ -77,7 +76,7 @@ let EditionActionPanel = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(response.notification, 'success');
|
const notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
refreshCollection() {
|
refreshCollection() {
|
||||||
@ -101,15 +100,11 @@ let EditionActionPanel = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { actionPanelButtonListType: ActionPanelButtonListType,
|
const { edition, actionPanelButtonListType: ActionPanelButtonListType } = this.props;
|
||||||
currentUser,
|
|
||||||
edition,
|
|
||||||
whitelabel } = this.props;
|
|
||||||
|
|
||||||
if (edition.notifications && edition.notifications.length) {
|
if (edition.notifications && edition.notifications.length) {
|
||||||
return (
|
return (
|
||||||
<ListRequestActions
|
<ListRequestActions
|
||||||
currentUser={currentUser}
|
|
||||||
notifications={edition.notifications}
|
notifications={edition.notifications}
|
||||||
pieceOrEditions={[edition]}
|
pieceOrEditions={[edition]}
|
||||||
handleSuccess={this.handleSuccess} />);
|
handleSuccess={this.handleSuccess} />);
|
||||||
@ -120,10 +115,8 @@ let EditionActionPanel = React.createClass({
|
|||||||
<ActionPanelButtonListType
|
<ActionPanelButtonListType
|
||||||
availableAcls={edition.acl}
|
availableAcls={edition.acl}
|
||||||
className="ascribe-button-list"
|
className="ascribe-button-list"
|
||||||
currentUser={currentUser}
|
|
||||||
handleSuccess={this.handleSuccess}
|
handleSuccess={this.handleSuccess}
|
||||||
pieceOrEditions={[edition]}
|
pieceOrEditions={[edition]} >
|
||||||
whitelabel={whitelabel}>
|
|
||||||
<AclProxy
|
<AclProxy
|
||||||
aclObject={edition.acl}
|
aclObject={edition.acl}
|
||||||
aclName="acl_withdraw_transfer">
|
aclName="acl_withdraw_transfer">
|
||||||
@ -170,7 +163,6 @@ let EditionActionPanel = React.createClass({
|
|||||||
aclObject={edition.acl}
|
aclObject={edition.acl}
|
||||||
aclName="acl_request_unconsign">
|
aclName="acl_request_unconsign">
|
||||||
<UnConsignRequestButton
|
<UnConsignRequestButton
|
||||||
currentUser={currentUser}
|
|
||||||
edition={edition}
|
edition={edition}
|
||||||
handleSuccess={this.handleSuccess} />
|
handleSuccess={this.handleSuccess} />
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
@ -189,4 +181,4 @@ let EditionActionPanel = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default EditionActionPanel;
|
export default withContext(EditionActionPanel, 'router');
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import ReactError from '../../mixins/react_error';
|
import ReactError from '../../mixins/react_error';
|
||||||
import { ResourceNotFoundError } from '../../models/errors';
|
import { ResourceNotFoundError } from '../../models/errors';
|
||||||
@ -25,16 +24,11 @@ let EditionContainer = React.createClass({
|
|||||||
actionPanelButtonListType: React.PropTypes.func,
|
actionPanelButtonListType: React.PropTypes.func,
|
||||||
furtherDetailsType: React.PropTypes.func,
|
furtherDetailsType: React.PropTypes.func,
|
||||||
|
|
||||||
// Provided from AscribeApp
|
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
// Provided from router
|
// Provided from router
|
||||||
location: React.PropTypes.object,
|
|
||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History, ReactError],
|
mixins: [ReactError],
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return EditionStore.getInitialState();
|
return EditionStore.getInitialState();
|
||||||
@ -77,7 +71,7 @@ let EditionContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { actionPanelButtonListType, currentUser, furtherDetailsType, whitelabel } = this.props;
|
const { actionPanelButtonListType, furtherDetailsType } = this.props;
|
||||||
const { edition, coaMeta } = this.state;
|
const { edition, coaMeta } = this.state;
|
||||||
|
|
||||||
if (edition.id) {
|
if (edition.id) {
|
||||||
@ -87,11 +81,9 @@ let EditionContainer = React.createClass({
|
|||||||
<Edition
|
<Edition
|
||||||
actionPanelButtonListType={actionPanelButtonListType}
|
actionPanelButtonListType={actionPanelButtonListType}
|
||||||
coaError={coaMeta.err}
|
coaError={coaMeta.err}
|
||||||
currentUser={currentUser}
|
|
||||||
edition={edition}
|
edition={edition}
|
||||||
furtherDetailsType={furtherDetailsType}
|
furtherDetailsType={furtherDetailsType}
|
||||||
loadEdition={this.loadEdition}
|
loadEdition={this.loadEdition} />
|
||||||
whitelabel={whitelabel} />
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
|
@ -17,12 +17,13 @@ import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
|
|||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape } from '../prop_types';
|
||||||
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
|
||||||
|
|
||||||
import { extractFileExtensionFromUrl } from '../../utils/file_utils';
|
import { extractFileExtensionFromUrl } from '../../utils/file_utils';
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
const EMBED_IFRAME_HEIGHT = {
|
const EMBED_IFRAME_HEIGHT = {
|
||||||
@ -36,7 +37,8 @@ let MediaContainer = React.createClass({
|
|||||||
content: React.PropTypes.object.isRequired,
|
content: React.PropTypes.object.isRequired,
|
||||||
refreshObject: React.PropTypes.func.isRequired,
|
refreshObject: React.PropTypes.func.isRequired,
|
||||||
|
|
||||||
currentUser: React.PropTypes.object
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -118,7 +120,7 @@ let MediaContainer = React.createClass({
|
|||||||
// the information in content will be updated if a user updates their username.
|
// the information in content will be updated if a user updates their username.
|
||||||
// We also force uniqueness of usernames, so this check is safe to dtermine if the
|
// We also force uniqueness of usernames, so this check is safe to dtermine if the
|
||||||
// content was registered by the current user.
|
// content was registered by the current user.
|
||||||
const didUserRegisterContent = currentUser && (currentUser.username === content.user_registered);
|
const didUserRegisterContent = currentUser.username === content.user_registered;
|
||||||
const thumbnail = content.thumbnail.thumbnail_sizes && content.thumbnail.thumbnail_sizes['600x600'] ? content.thumbnail.thumbnail_sizes['600x600']
|
const thumbnail = content.thumbnail.thumbnail_sizes && content.thumbnail.thumbnail_sizes['600x600'] ? content.thumbnail.thumbnail_sizes['600x600']
|
||||||
: content.thumbnail.url_safe;
|
: content.thumbnail.url_safe;
|
||||||
|
|
||||||
@ -181,4 +183,4 @@ let MediaContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MediaContainer;
|
export default withContext(MediaContainer, 'currentUser');
|
||||||
|
@ -5,15 +5,16 @@ import React from 'react';
|
|||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
import Form from './../ascribe_forms/form';
|
import Form from '../ascribe_forms/form';
|
||||||
import Property from './../ascribe_forms/property';
|
import Property from '../ascribe_forms/property';
|
||||||
import InputTextAreaToggable from './../ascribe_forms/input_textarea_toggable';
|
import InputTextAreaToggable from '../ascribe_forms/input_textarea_toggable';
|
||||||
|
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let Note = React.createClass({
|
let Note = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
id: React.PropTypes.func.isRequired,
|
id: React.PropTypes.func.isRequired,
|
||||||
url: React.PropTypes.string.isRequired,
|
url: React.PropTypes.string.isRequired,
|
||||||
|
|
||||||
@ -22,7 +23,10 @@ let Note = React.createClass({
|
|||||||
label: React.PropTypes.string,
|
label: React.PropTypes.string,
|
||||||
placeholder: React.PropTypes.string,
|
placeholder: React.PropTypes.string,
|
||||||
show: React.PropTypes.bool,
|
show: React.PropTypes.bool,
|
||||||
successMessage: React.PropTypes.string
|
successMessage: React.PropTypes.string,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
@ -40,9 +44,18 @@ let Note = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser, defaultValue, editable, id, label, placeholder, show, url } = this.props;
|
const {
|
||||||
|
defaultValue,
|
||||||
|
editable,
|
||||||
|
id,
|
||||||
|
isLoggedIn,
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
show,
|
||||||
|
url
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if ((currentUser.username && editable || !editable) && show) {
|
if ((isLoggedIn && editable || !editable) && show) {
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
url={url}
|
url={url}
|
||||||
@ -66,4 +79,4 @@ let Note = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Note;
|
export default withContext(Note, 'isLoggedIn');
|
||||||
|
@ -18,7 +18,6 @@ let Piece = React.createClass({
|
|||||||
piece: React.PropTypes.object.isRequired,
|
piece: React.PropTypes.object.isRequired,
|
||||||
|
|
||||||
buttons: React.PropTypes.object,
|
buttons: React.PropTypes.object,
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
header: React.PropTypes.object,
|
header: React.PropTypes.object,
|
||||||
subheader: React.PropTypes.object,
|
subheader: React.PropTypes.object,
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
@ -32,14 +31,13 @@ let Piece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { buttons, children, currentUser, header, piece, subheader } = this.props;
|
const { buttons, children, header, piece, subheader } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={6} className="ascribe-print-col-left">
|
<Col md={6} className="ascribe-print-col-left">
|
||||||
<MediaContainer
|
<MediaContainer
|
||||||
content={piece}
|
content={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
refreshObject={this.updatePiece} />
|
refreshObject={this.updatePiece} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={6} className="ascribe-edition-details ascribe-print-col-right">
|
<Col md={6} className="ascribe-edition-details ascribe-print-col-right">
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
|
|
||||||
import ReactError from '../../mixins/react_error';
|
import ReactError from '../../mixins/react_error';
|
||||||
@ -25,7 +24,7 @@ import LicenseDetail from './license_detail';
|
|||||||
import Note from './note';
|
import Note from './note';
|
||||||
import Piece from './piece';
|
import Piece from './piece';
|
||||||
|
|
||||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
import AclButtonList from '../ascribe_buttons/acl_button_list';
|
||||||
import AclInformation from '../ascribe_buttons/acl_information';
|
import AclInformation from '../ascribe_buttons/acl_information';
|
||||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
||||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||||
@ -36,31 +35,32 @@ import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
|||||||
import ListRequestActions from '../ascribe_forms/list_form_request_actions';
|
import ListRequestActions from '../ascribe_forms/list_form_request_actions';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { routerShape } from '../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
|
||||||
|
|
||||||
|
import { setDocumentTitle } from '../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
import { setDocumentTitle } from '../../utils/dom_utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the component that implements resource/data specific functionality
|
* This is the component that implements resource/data specific functionality
|
||||||
*/
|
*/
|
||||||
let PieceContainer = React.createClass({
|
const PieceContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
furtherDetailsType: React.PropTypes.func,
|
furtherDetailsType: React.PropTypes.func,
|
||||||
|
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
isLoggedIn: React.PropTypes.bool.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object,
|
router: routerShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
// Provided from router
|
||||||
location: React.PropTypes.object,
|
|
||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History, ReactError],
|
mixins: [ReactError],
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
@ -164,7 +164,7 @@ let PieceContainer = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(response.notification, 'success');
|
const notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
getCreateEditionsDialog() {
|
getCreateEditionsDialog() {
|
||||||
@ -207,12 +207,11 @@ let PieceContainer = React.createClass({
|
|||||||
|
|
||||||
getActions() {
|
getActions() {
|
||||||
const { piece } = this.state;
|
const { piece } = this.state;
|
||||||
const { currentUser } = this.props;
|
const { isLoggedIn } = this.props;
|
||||||
|
|
||||||
if (piece.notifications && piece.notifications.length > 0) {
|
if (piece.notifications && piece.notifications.length > 0) {
|
||||||
return (
|
return (
|
||||||
<ListRequestActions
|
<ListRequestActions
|
||||||
currentUser={currentUser}
|
|
||||||
handleSuccess={this.loadPiece}
|
handleSuccess={this.loadPiece}
|
||||||
notifications={piece.notifications}
|
notifications={piece.notifications}
|
||||||
pieceOrEditions={piece} />
|
pieceOrEditions={piece} />
|
||||||
@ -220,7 +219,7 @@ let PieceContainer = React.createClass({
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<AclProxy
|
<AclProxy
|
||||||
show={currentUser && currentUser.email && Object.keys(piece.acl).length > 1}>
|
show={isLoggedIn && Object.keys(piece.acl).length > 1}>
|
||||||
{/*
|
{/*
|
||||||
`acl_view` is always available in `edition.acl`, therefore if it has
|
`acl_view` is always available in `edition.acl`, therefore if it has
|
||||||
no more than 1 key, we're hiding the `DetailProperty` actions as otherwise
|
no more than 1 key, we're hiding the `DetailProperty` actions as otherwise
|
||||||
@ -232,7 +231,6 @@ let PieceContainer = React.createClass({
|
|||||||
<AclButtonList
|
<AclButtonList
|
||||||
availableAcls={piece.acl}
|
availableAcls={piece.acl}
|
||||||
className="ascribe-button-list"
|
className="ascribe-button-list"
|
||||||
currentUser={currentUser}
|
|
||||||
pieceOrEditions={piece}
|
pieceOrEditions={piece}
|
||||||
handleSuccess={this.loadPiece}>
|
handleSuccess={this.loadPiece}>
|
||||||
<CreateEditionsButton
|
<CreateEditionsButton
|
||||||
@ -257,7 +255,7 @@ let PieceContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser, furtherDetailsType: FurtherDetailsType } = this.props;
|
const { isLoggedIn, furtherDetailsType: FurtherDetailsType } = this.props;
|
||||||
const { piece } = this.state;
|
const { piece } = this.state;
|
||||||
|
|
||||||
if (piece.id) {
|
if (piece.id) {
|
||||||
@ -266,7 +264,6 @@ let PieceContainer = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<Piece
|
<Piece
|
||||||
piece={piece}
|
piece={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
header={
|
header={
|
||||||
<div className="ascribe-detail-header">
|
<div className="ascribe-detail-header">
|
||||||
<hr className="hidden-print" style={{marginTop: 0}} />
|
<hr className="hidden-print" style={{marginTop: 0}} />
|
||||||
@ -297,7 +294,7 @@ let PieceContainer = React.createClass({
|
|||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Notes')}
|
title={getLangText('Notes')}
|
||||||
show={!!(currentUser.username || piece.acl.acl_edit || piece.public_note)}>
|
show={!!(isLoggedIn || piece.acl.acl_edit || piece.public_note)}>
|
||||||
<Note
|
<Note
|
||||||
id={this.getId}
|
id={this.getId}
|
||||||
label={getLangText('Personal note (private)')}
|
label={getLangText('Personal note (private)')}
|
||||||
@ -305,8 +302,7 @@ let PieceContainer = React.createClass({
|
|||||||
placeholder={getLangText('Enter your comments ...')}
|
placeholder={getLangText('Enter your comments ...')}
|
||||||
editable={true}
|
editable={true}
|
||||||
successMessage={getLangText('Private note saved')}
|
successMessage={getLangText('Private note saved')}
|
||||||
url={ApiUrls.note_private_piece}
|
url={ApiUrls.note_private_piece} />
|
||||||
currentUser={currentUser} />
|
|
||||||
<Note
|
<Note
|
||||||
id={this.getId}
|
id={this.getId}
|
||||||
label={getLangText('Personal note (public)')}
|
label={getLangText('Personal note (public)')}
|
||||||
@ -315,8 +311,7 @@ let PieceContainer = React.createClass({
|
|||||||
editable={!!piece.acl.acl_edit}
|
editable={!!piece.acl.acl_edit}
|
||||||
show={!!(piece.public_note || piece.acl.acl_edit)}
|
show={!!(piece.public_note || piece.acl.acl_edit)}
|
||||||
successMessage={getLangText('Public note saved')}
|
successMessage={getLangText('Public note saved')}
|
||||||
url={ApiUrls.note_public_piece}
|
url={ApiUrls.note_public_piece} />
|
||||||
currentUser={currentUser} />
|
|
||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Further Details')}
|
title={getLangText('Further Details')}
|
||||||
@ -344,4 +339,4 @@ let PieceContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default PieceContainer;
|
export default withContext(PieceContainer, 'isLoggedIn', 'router');
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
import ConsignForm from '../ascribe_forms/form_consign';
|
import ConsignForm from '../ascribe_forms/form_consign';
|
||||||
import UnConsignForm from '../ascribe_forms/form_unconsign';
|
import UnConsignForm from '../ascribe_forms/form_unconsign';
|
||||||
import TransferForm from '../ascribe_forms/form_transfer';
|
import TransferForm from '../ascribe_forms/form_transfer';
|
||||||
@ -9,12 +12,12 @@ import LoanForm from '../ascribe_forms/form_loan';
|
|||||||
import LoanRequestAnswerForm from '../ascribe_forms/form_loan_request_answer';
|
import LoanRequestAnswerForm from '../ascribe_forms/form_loan_request_answer';
|
||||||
import ShareForm from '../ascribe_forms/form_share_email';
|
import ShareForm from '../ascribe_forms/form_share_email';
|
||||||
|
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape } from '../prop_types';
|
||||||
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
|
||||||
|
|
||||||
import { getAclFormMessage, getAclFormDataId } from '../../utils/form_utils';
|
import { getAclFormMessage, getAclFormDataId } from '../../utils/form_utils';
|
||||||
|
|
||||||
let AclFormFactory = React.createClass({
|
let AclFormFactory = React.createClass({
|
||||||
@ -26,12 +29,14 @@ let AclFormFactory = React.createClass({
|
|||||||
]).isRequired,
|
]).isRequired,
|
||||||
|
|
||||||
autoFocusProperty: React.PropTypes.string,
|
autoFocusProperty: React.PropTypes.string,
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
handleSuccess: React.PropTypes.func,
|
handleSuccess: React.PropTypes.func,
|
||||||
message: React.PropTypes.string,
|
|
||||||
labels: React.PropTypes.object,
|
labels: React.PropTypes.object,
|
||||||
showNotification: React.PropTypes.bool
|
message: React.PropTypes.string,
|
||||||
|
showNotification: React.PropTypes.bool,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
isPiece() {
|
isPiece() {
|
||||||
@ -54,21 +59,23 @@ let AclFormFactory = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { action,
|
const {
|
||||||
autoFocusProperty,
|
action,
|
||||||
pieceOrEditions,
|
autoFocusProperty,
|
||||||
currentUser,
|
pieceOrEditions,
|
||||||
email,
|
email,
|
||||||
message,
|
message,
|
||||||
labels,
|
labels,
|
||||||
handleSuccess,
|
handleSuccess,
|
||||||
showNotification } = this.props;
|
showNotification,
|
||||||
|
currentUser: { username: senderName }
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const formMessage = message || getAclFormMessage({
|
const formMessage = message || getAclFormMessage({
|
||||||
|
senderName,
|
||||||
aclName: action,
|
aclName: action,
|
||||||
entities: pieceOrEditions,
|
entities: pieceOrEditions,
|
||||||
isPiece: this.isPiece(),
|
isPiece: this.isPiece()
|
||||||
senderName: currentUser && currentUser.username
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (action === 'acl_consign') {
|
if (action === 'acl_consign') {
|
||||||
@ -131,4 +138,4 @@ let AclFormFactory = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AclFormFactory;
|
export default withContext(AclFormFactory, 'currentUser');
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactAddons from 'react/addons';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ let Form = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
return ReactAddons.Children.map(this.props.children, (child, i) => {
|
return React.Children.map(this.props.children, (child, i) => {
|
||||||
if (child) {
|
if (child) {
|
||||||
// Since refs will be overwritten by this functions return statement,
|
// Since refs will be overwritten by this functions return statement,
|
||||||
// we still want to be able to define refs for nested `Form` or `Property`
|
// we still want to be able to define refs for nested `Form` or `Property`
|
||||||
@ -355,7 +355,7 @@ let Form = React.createClass({
|
|||||||
let refToValidate = {};
|
let refToValidate = {};
|
||||||
const property = this.refs[refName];
|
const property = this.refs[refName];
|
||||||
const input = property.refs.input;
|
const input = property.refs.input;
|
||||||
const value = input.getDOMNode().value || input.state.value;
|
const value = ReactDOM.findDOMNode(input).value || input.state.value;
|
||||||
const { max,
|
const { max,
|
||||||
min,
|
min,
|
||||||
pattern,
|
pattern,
|
||||||
|
@ -8,14 +8,22 @@ import GlobalNotificationActions from '../../actions/global_notification_actions
|
|||||||
import Form from './form';
|
import Form from './form';
|
||||||
import Property from './property';
|
import Property from './property';
|
||||||
|
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape } from '../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let CopyrightAssociationForm = React.createClass({
|
|
||||||
|
const { bool } = React.PropTypes;
|
||||||
|
|
||||||
|
const CopyrightAssociationForm = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired,
|
||||||
|
isLoggedIn: bool.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSubmitSuccess() {
|
handleSubmitSuccess() {
|
||||||
@ -28,7 +36,7 @@ let CopyrightAssociationForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser } = this.props;
|
const { currentUser, isLoggedIn } = this.props;
|
||||||
const selectDefaultValue = ' -- ' + getLangText('select an association') + ' -- ';
|
const selectDefaultValue = ' -- ' + getLangText('select an association') + ' -- ';
|
||||||
|
|
||||||
let selectedState = selectDefaultValue;
|
let selectedState = selectDefaultValue;
|
||||||
@ -38,7 +46,7 @@ let CopyrightAssociationForm = React.createClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUser.email) {
|
if (isLoggedIn) {
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
ref='form'
|
ref='form'
|
||||||
@ -77,4 +85,4 @@ let CopyrightAssociationForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CopyrightAssociationForm;
|
export default withContext(CopyrightAssociationForm, 'currentUser', 'isLoggedIn');
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
@ -11,9 +10,11 @@ import UserActions from '../../actions/user_actions';
|
|||||||
import Form from './form';
|
import Form from './form';
|
||||||
import Property from './property';
|
import Property from './property';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { locationShape } from '../prop_types';
|
||||||
|
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
@ -22,11 +23,11 @@ let LoginForm = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
headerMessage: React.PropTypes.string,
|
headerMessage: React.PropTypes.string,
|
||||||
submitMessage: React.PropTypes.string,
|
submitMessage: React.PropTypes.string,
|
||||||
location: React.PropTypes.object,
|
whitelabelName: React.PropTypes.string,
|
||||||
whitelabelName: React.PropTypes.string
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
// Injected through HOCs
|
||||||
|
location: locationShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
@ -93,4 +94,4 @@ let LoginForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default LoginForm;
|
export default withContext(LoginForm, 'location');
|
||||||
|
@ -8,23 +8,22 @@ import InputFineUploader from './input_fineuploader';
|
|||||||
|
|
||||||
import FormSubmitButton from '../ascribe_buttons/form_submit_button';
|
import FormSubmitButton from '../ascribe_buttons/form_submit_button';
|
||||||
|
|
||||||
import { FileStatus } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
|
||||||
import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button';
|
import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button';
|
||||||
|
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape, locationShape } from '../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
import { validationParts, validationTypes } from '../../constants/uploader_constants';
|
import { validationParts, validationTypes } from '../../constants/uploader_constants';
|
||||||
|
|
||||||
|
import { FileStatus, formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
|
||||||
|
|
||||||
|
|
||||||
let RegisterPieceForm = React.createClass({
|
let RegisterPieceForm = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
headerMessage: React.PropTypes.string,
|
headerMessage: React.PropTypes.string,
|
||||||
submitMessage: React.PropTypes.string,
|
submitMessage: React.PropTypes.string,
|
||||||
enableLocalHashing: React.PropTypes.bool,
|
enableLocalHashing: React.PropTypes.bool,
|
||||||
@ -36,11 +35,14 @@ let RegisterPieceForm = React.createClass({
|
|||||||
// For this form to work with SlideContainer, we sometimes have to disable it
|
// For this form to work with SlideContainer, we sometimes have to disable it
|
||||||
disabled: React.PropTypes.bool,
|
disabled: React.PropTypes.bool,
|
||||||
|
|
||||||
location: React.PropTypes.object,
|
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
React.PropTypes.element
|
React.PropTypes.element
|
||||||
])
|
]),
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
location: locationShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
@ -128,7 +130,7 @@ let RegisterPieceForm = React.createClass({
|
|||||||
location,
|
location,
|
||||||
submitMessage } = this.props;
|
submitMessage } = this.props;
|
||||||
|
|
||||||
const profileHashLocally = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false;
|
const profileHashLocally = currentUser.profile ? currentUser.profile.hash_locally : false;
|
||||||
const hashLocally = profileHashLocally && enableLocalHashing;
|
const hashLocally = profileHashLocally && enableLocalHashing;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -238,4 +240,4 @@ let RegisterPieceForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default RegisterPieceForm;
|
export default withContext(RegisterPieceForm, 'currentUser', 'location');
|
||||||
|
@ -27,7 +27,6 @@ let RequestActionForm = React.createClass({
|
|||||||
React.PropTypes.array
|
React.PropTypes.array
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -99,7 +98,6 @@ let RequestActionForm = React.createClass({
|
|||||||
availableAcls={{'acl_unconsign': true}}
|
availableAcls={{'acl_unconsign': true}}
|
||||||
buttonAcceptClassName='inline pull-right btn-sm ascribe-margin-1px'
|
buttonAcceptClassName='inline pull-right btn-sm ascribe-margin-1px'
|
||||||
pieceOrEditions={this.props.pieceOrEditions}
|
pieceOrEditions={this.props.pieceOrEditions}
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
handleSuccess={this.handleSuccess} />
|
handleSuccess={this.handleSuccess} />
|
||||||
);
|
);
|
||||||
} else if (this.props.notifications.action === 'loan_request') {
|
} else if (this.props.notifications.action === 'loan_request') {
|
||||||
@ -109,7 +107,6 @@ let RequestActionForm = React.createClass({
|
|||||||
buttonAcceptName="LOAN"
|
buttonAcceptName="LOAN"
|
||||||
buttonAcceptClassName='inline pull-right btn-sm ascribe-margin-1px'
|
buttonAcceptClassName='inline pull-right btn-sm ascribe-margin-1px'
|
||||||
pieceOrEditions={this.props.pieceOrEditions}
|
pieceOrEditions={this.props.pieceOrEditions}
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
handleSuccess={this.handleSuccess} />
|
handleSuccess={this.handleSuccess} />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import ContractListActions from '../../actions/contract_list_actions';
|
import ContractListActions from '../../actions/contract_list_actions';
|
||||||
import ContractListStore from '../../stores/contract_list_store';
|
import ContractListStore from '../../stores/contract_list_store';
|
||||||
@ -13,19 +12,23 @@ import Form from './form';
|
|||||||
import Property from './property';
|
import Property from './property';
|
||||||
import InputTextAreaToggable from './input_textarea_toggable';
|
import InputTextAreaToggable from './input_textarea_toggable';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { routerShape } from '../prop_types';
|
||||||
|
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
|
|
||||||
|
|
||||||
let SendContractAgreementForm = React.createClass({
|
const SendContractAgreementForm = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func,
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
// Injected through HOCs
|
||||||
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
@ -57,7 +60,7 @@ let SendContractAgreementForm = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(getLangText('Contract agreement sent'), 'success', 10000);
|
const notification = new GlobalNotificationModel(getLangText('Contract agreement sent'), 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
getFormData() {
|
getFormData() {
|
||||||
@ -151,4 +154,4 @@ let SendContractAgreementForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default SendContractAgreementForm;
|
export default withContext(SendContractAgreementForm, 'router');
|
||||||
|
@ -21,7 +21,6 @@ let ShareForm = React.createClass({
|
|||||||
id: React.PropTypes.object,
|
id: React.PropTypes.object,
|
||||||
message: React.PropTypes.string,
|
message: React.PropTypes.string,
|
||||||
editions: React.PropTypes.array,
|
editions: React.PropTypes.array,
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
@ -12,8 +11,11 @@ import Form from './form';
|
|||||||
import Property from './property';
|
import Property from './property';
|
||||||
import InputCheckbox from './input_checkbox';
|
import InputCheckbox from './input_checkbox';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { locationShape } from '../prop_types';
|
||||||
|
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
@ -23,16 +25,16 @@ let SignupForm = React.createClass({
|
|||||||
headerMessage: React.PropTypes.string,
|
headerMessage: React.PropTypes.string,
|
||||||
submitMessage: React.PropTypes.string,
|
submitMessage: React.PropTypes.string,
|
||||||
handleSuccess: React.PropTypes.func,
|
handleSuccess: React.PropTypes.func,
|
||||||
location: React.PropTypes.object,
|
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
React.PropTypes.element,
|
React.PropTypes.element,
|
||||||
React.PropTypes.string
|
React.PropTypes.string
|
||||||
]),
|
]),
|
||||||
whitelabelName: React.PropTypes.string
|
whitelabelName: React.PropTypes.string,
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
// Injected through HOCs
|
||||||
|
isLoggedIn: locationShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
@ -132,4 +134,4 @@ let SignupForm = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default SignupForm;
|
export default withContext(SignupForm, 'location');
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component can be used as a custom input element for form properties.
|
* This component can be used as a custom input element for form properties.
|
||||||
@ -71,7 +72,7 @@ let InputCheckbox = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On every change, we're inversing the input's value
|
// On every change, we're inversing the input's value
|
||||||
let inverseValue = !this.refs.checkbox.getDOMNode().checked;
|
let inverseValue = !ReactDOM.findDOMNode(this.refs.checkbox).checked;
|
||||||
|
|
||||||
// pass it to the state
|
// pass it to the state
|
||||||
this.setState({value: inverseValue});
|
this.setState({value: inverseValue});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react/addons';
|
import React from 'react';
|
||||||
|
import update from 'react-addons-update';
|
||||||
|
|
||||||
import InputCheckbox from './input_checkbox';
|
import InputCheckbox from './input_checkbox';
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ const InputContractAgreementCheckbox = React.createClass({
|
|||||||
// so the parent `Property` is able to get the correct value of this component
|
// so the parent `Property` is able to get the correct value of this component
|
||||||
// when the `Form` queries it.
|
// when the `Form` queries it.
|
||||||
this.setState({
|
this.setState({
|
||||||
value: React.addons.update(this.state.value, {
|
value: update(this.state.value, {
|
||||||
terms: { $set: event.target.value }
|
terms: { $set: event.target.value }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -11,19 +11,17 @@ let ListRequestActions = React.createClass({
|
|||||||
React.PropTypes.array
|
React.PropTypes.array
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { currentUser, handleSuccess, notifications, pieceOrEditions } = this.props;
|
const { handleSuccess, notifications, pieceOrEditions } = this.props;
|
||||||
|
|
||||||
if (notifications.length) {
|
if (notifications.length) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{notifications.map((notification) =>
|
{notifications.map((notification) =>
|
||||||
<RequestActionForm
|
<RequestActionForm
|
||||||
currentUser={currentUser}
|
|
||||||
handleSuccess={handleSuccess}
|
handleSuccess={handleSuccess}
|
||||||
notifications={notification}
|
notifications={notification}
|
||||||
pieceOrEditions={pieceOrEditions} />
|
pieceOrEditions={pieceOrEditions} />
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactAddons from 'react/addons';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import Panel from 'react-bootstrap/lib/Panel';
|
import Panel from 'react-bootstrap/lib/Panel';
|
||||||
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
|
||||||
|
|
||||||
|
|
||||||
const { bool, element, string, oneOfType, func, object, arrayOf } = React.PropTypes;
|
const { bool, element, string, oneOfType, func, object, arrayOf } = React.PropTypes;
|
||||||
|
|
||||||
@ -101,9 +99,9 @@ const Property = React.createClass({
|
|||||||
// In order to set this.state.value from another component
|
// In order to set this.state.value from another component
|
||||||
// the state of value should only be set if its not undefined and
|
// the state of value should only be set if its not undefined and
|
||||||
// actually references something
|
// actually references something
|
||||||
if(childInput && typeof childInput.getDOMNode().value !== 'undefined') {
|
if(childInput && typeof ReactDOM.findDOMNode(childInput).value !== 'undefined') {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: childInput.getDOMNode().value
|
value: ReactDOM.findDOMNode(childInput).value
|
||||||
});
|
});
|
||||||
|
|
||||||
// When implementing custom input components, their value isn't exposed like the one
|
// When implementing custom input components, their value isn't exposed like the one
|
||||||
@ -116,9 +114,9 @@ const Property = React.createClass({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.state.initialValue && childInput && childInput.props.defaultValue) {
|
if(!this.state.initialValue && childInput && childInput.defaultValue) {
|
||||||
this.setState({
|
this.setState({
|
||||||
initialValue: childInput.props.defaultValue
|
initialValue: childInput.defaultValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -140,7 +138,7 @@ const Property = React.createClass({
|
|||||||
// Therefore we have to make sure only to reset the initial value
|
// Therefore we have to make sure only to reset the initial value
|
||||||
// of HTML inputs (which we determine by checking if there 'type' attribute matches
|
// of HTML inputs (which we determine by checking if there 'type' attribute matches
|
||||||
// the ones included in AppConstants.possibleInputTypes).
|
// the ones included in AppConstants.possibleInputTypes).
|
||||||
let inputDOMNode = input.getDOMNode();
|
let inputDOMNode = ReactDOM.findDOMNode(input);
|
||||||
if(inputDOMNode.type && typeof inputDOMNode.type === 'string' &&
|
if(inputDOMNode.type && typeof inputDOMNode.type === 'string' &&
|
||||||
AppConstants.possibleInputTypes.indexOf(inputDOMNode.type.toLowerCase()) > -1) {
|
AppConstants.possibleInputTypes.indexOf(inputDOMNode.type.toLowerCase()) > -1) {
|
||||||
inputDOMNode.value = this.state.initialValue;
|
inputDOMNode.value = this.state.initialValue;
|
||||||
@ -180,10 +178,10 @@ const Property = React.createClass({
|
|||||||
// skip the focus of non-input elements
|
// skip the focus of non-input elements
|
||||||
let nonInputHTMLElements = ['pre', 'div'];
|
let nonInputHTMLElements = ['pre', 'div'];
|
||||||
if (this.refs.input &&
|
if (this.refs.input &&
|
||||||
nonInputHTMLElements.indexOf(this.refs.input.getDOMNode().nodeName.toLowerCase()) > -1 ) {
|
nonInputHTMLElements.indexOf(ReactDOM.findDOMNode(this.refs.input).nodeName.toLowerCase()) > -1 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.refs.input.getDOMNode().focus();
|
ReactDOM.findDOMNode(this.refs.input).focus();
|
||||||
this.setState({
|
this.setState({
|
||||||
isFocused: true
|
isFocused: true
|
||||||
});
|
});
|
||||||
@ -205,7 +203,7 @@ const Property = React.createClass({
|
|||||||
errors: null,
|
errors: null,
|
||||||
|
|
||||||
// also update initialValue in case of the user updating and canceling its actions again
|
// also update initialValue in case of the user updating and canceling its actions again
|
||||||
initialValue: this.refs.input.getDOMNode().value
|
initialValue: ReactDOM.findDOMNode(this.refs.input).value
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -261,7 +259,7 @@ const Property = React.createClass({
|
|||||||
// Input's props should only be cloned and propagated down the tree,
|
// Input's props should only be cloned and propagated down the tree,
|
||||||
// if the component is actually being shown (!== 'expanded === false')
|
// if the component is actually being shown (!== 'expanded === false')
|
||||||
if((this.state.expanded && this.props.checkboxLabel) || !this.props.checkboxLabel) {
|
if((this.state.expanded && this.props.checkboxLabel) || !this.props.checkboxLabel) {
|
||||||
return ReactAddons.Children.map(this.props.children, (child) => {
|
return React.Children.map(this.props.children, (child) => {
|
||||||
// Since refs will be overriden by this functions return statement,
|
// Since refs will be overriden by this functions return statement,
|
||||||
// we still want to be able to define refs for nested `Form` or `Property`
|
// we still want to be able to define refs for nested `Form` or `Property`
|
||||||
// children, which is why we're upfront simply invoking the callback-ref-
|
// children, which is why we're upfront simply invoking the callback-ref-
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
@ -1,66 +1,39 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
let ActionPanel = React.createClass({
|
let ActionPanel = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
title: React.PropTypes.string,
|
buttons: React.PropTypes.element,
|
||||||
content: React.PropTypes.oneOfType([
|
content: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.string,
|
React.PropTypes.string,
|
||||||
React.PropTypes.element
|
React.PropTypes.element
|
||||||
]),
|
]),
|
||||||
buttons: React.PropTypes.element,
|
|
||||||
onClick: React.PropTypes.func,
|
|
||||||
ignoreFocus: React.PropTypes.bool,
|
|
||||||
|
|
||||||
leftColumnWidth: React.PropTypes.string,
|
leftColumnWidth: React.PropTypes.string,
|
||||||
|
onClick: React.PropTypes.func,
|
||||||
rightColumnWidth: React.PropTypes.string
|
rightColumnWidth: React.PropTypes.string
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
|
||||||
return {
|
|
||||||
isFocused: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
handleFocus() {
|
|
||||||
// if ignoreFocus (bool) is defined, then just ignore focusing on
|
|
||||||
// the property and input
|
|
||||||
if(this.props.ignoreFocus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if onClick is defined from the outside,
|
|
||||||
// just call it
|
|
||||||
if(this.props.onClick) {
|
|
||||||
this.props.onClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.refs.input.getDOMNode().focus();
|
|
||||||
this.setState({
|
|
||||||
isFocused: true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { buttons, content, leftColumnWidth, onClick, rightColumnWidth } = this.props;
|
||||||
let { leftColumnWidth, rightColumnWidth } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('ascribe-panel-wrapper', {'is-focused': this.state.isFocused})}>
|
<div
|
||||||
|
className={'ascribe-panel-wrapper'}
|
||||||
|
onClick={onClick}>
|
||||||
<div
|
<div
|
||||||
className="ascribe-panel-table"
|
className="ascribe-panel-table"
|
||||||
style={{width: leftColumnWidth}}>
|
style={{width: leftColumnWidth}}>
|
||||||
<div className="ascribe-panel-content">
|
<div className="ascribe-panel-content">
|
||||||
{this.props.content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="ascribe-panel-table"
|
className="ascribe-panel-table"
|
||||||
style={{width: rightColumnWidth}}>
|
style={{width: rightColumnWidth}}>
|
||||||
<div className="ascribe-panel-content">
|
<div className="ascribe-panel-content">
|
||||||
{this.props.buttons}
|
{buttons}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -68,4 +41,4 @@ let ActionPanel = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ActionPanel;
|
export default ActionPanel;
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RouteContext } from 'react-router';
|
|
||||||
import history from '../../history';
|
|
||||||
|
|
||||||
import UserStore from '../../stores/user_store';
|
import UserStore from '../../stores/user_store';
|
||||||
|
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
|
|
||||||
const { object } = React.PropTypes;
|
const { bool, object } = React.PropTypes;
|
||||||
const WHEN_ENUM = ['loggedIn', 'loggedOut'];
|
const WHEN_ENUM = ['loggedIn', 'loggedOut'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +26,7 @@ export function AuthRedirect({ to, when }) {
|
|||||||
throw new Error(`"when" must be one of: [${whenValues}] got "${when}" instead`);
|
throw new Error(`"when" must be one of: [${whenValues}] got "${when}" instead`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(currentUser, query) {
|
return function redirectRoute(router, { query }, { isLoggedIn }) {
|
||||||
const { redirectAuthenticated, redirect } = query;
|
const { redirectAuthenticated, redirect } = query;
|
||||||
|
|
||||||
// The user of this handler specifies with `when`, what kind of status
|
// The user of this handler specifies with `when`, what kind of status
|
||||||
@ -34,19 +35,18 @@ export function AuthRedirect({ to, when }) {
|
|||||||
//
|
//
|
||||||
// So if when === 'loggedIn', we're checking if the user is logged in (and
|
// So if when === 'loggedIn', we're checking if the user is logged in (and
|
||||||
// vice versa)
|
// vice versa)
|
||||||
const isLoggedIn = Object.keys(currentUser).length && currentUser.email;
|
|
||||||
const exprToValidate = when === 'loggedIn' ? isLoggedIn : !isLoggedIn;
|
const exprToValidate = when === 'loggedIn' ? isLoggedIn : !isLoggedIn;
|
||||||
|
|
||||||
// and redirect if `true`.
|
// and redirect if `true`.
|
||||||
if (exprToValidate) {
|
if (exprToValidate) {
|
||||||
window.setTimeout(() => history.replace({ query, pathname: to }));
|
window.setTimeout(() => router.replace({ query, pathname: to }));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise there can also be the case that the backend
|
// Otherwise there can also be the case that the backend
|
||||||
// wants to redirect the user to a specific route when the user is logged out already
|
// wants to redirect the user to a specific route when the user is logged out already
|
||||||
} else if (!exprToValidate && when === 'loggedIn' && redirect) {
|
} else if (!exprToValidate && when === 'loggedIn' && redirect) {
|
||||||
delete query.redirect;
|
delete query.redirect;
|
||||||
window.setTimeout(() => history.replace({ query, pathname: '/' + redirect }));
|
window.setTimeout(() => router.replace({ query, pathname: `/${redirect}` }));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (!exprToValidate && when === 'loggedOut' && redirectAuthenticated) {
|
} else if (!exprToValidate && when === 'loggedOut' && redirectAuthenticated) {
|
||||||
@ -77,22 +77,19 @@ export function AuthRedirect({ to, when }) {
|
|||||||
*/
|
*/
|
||||||
export function ProxyHandler(...redirectFunctions) {
|
export function ProxyHandler(...redirectFunctions) {
|
||||||
return (Component) => {
|
return (Component) => {
|
||||||
return React.createClass({
|
// Don't worry about shadowing the HOC here; using a declaration like this allows
|
||||||
displayName: 'ProxyHandler',
|
// babel-plugin-react-display-name to automatically generate the displayName.
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
const ProxyHandler = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp, after the routes have been initialized
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object,
|
isLoggedIn: bool.isRequired,
|
||||||
|
location: locationShape.isRequired,
|
||||||
// Provided from router
|
router: routerShape.isRequired,
|
||||||
location: object
|
whitelabel: whitelabelShape.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
// We need insert `RouteContext` here in order to be able
|
|
||||||
// to use the `Lifecycle` widget in further down nested components
|
|
||||||
mixins: [RouteContext],
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.evaluateRedirectFunctions();
|
this.evaluateRedirectFunctions();
|
||||||
},
|
},
|
||||||
@ -102,15 +99,15 @@ export function ProxyHandler(...redirectFunctions) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
evaluateRedirectFunctions(props = this.props) {
|
evaluateRedirectFunctions(props = this.props) {
|
||||||
const { currentUser, location: { query } } = props;
|
const { currentUser, isLoggedIn, location, router, whitelabel } = props;
|
||||||
|
|
||||||
if (UserStore.hasLoaded() && !UserStore.isLoading()) {
|
if (UserStore.hasLoaded() && !UserStore.isLoading()) {
|
||||||
|
const context = { currentUser, isLoggedIn, whitelabel };
|
||||||
|
|
||||||
for (let i = 0; i < redirectFunctions.length; i++) {
|
for (let i = 0; i < redirectFunctions.length; i++) {
|
||||||
// if a redirectFunction redirects the user,
|
// if a redirectFunction redirects the user, it should return `true` and
|
||||||
// it should return `true` and therefore
|
// therefore stop/avoid the execution of all functions that follow
|
||||||
// stop/avoid the execution of all functions
|
if (redirectFunctions[i](router, location, context)) {
|
||||||
// that follow
|
|
||||||
if (redirectFunctions[i](currentUser, query)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,5 +120,12 @@ export function ProxyHandler(...redirectFunctions) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return withContext(ProxyHandler,
|
||||||
|
'currentUser',
|
||||||
|
'isLoggedIn',
|
||||||
|
'location',
|
||||||
|
'router',
|
||||||
|
'whitelabel');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,25 +5,29 @@ import React from 'react';
|
|||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
|
import CopyrightAssociationForm from '../ascribe_forms/form_copyright_association';
|
||||||
import Form from '../ascribe_forms/form';
|
import Form from '../ascribe_forms/form';
|
||||||
import Property from '../ascribe_forms/property';
|
|
||||||
import InputCheckbox from '../ascribe_forms/input_checkbox';
|
import InputCheckbox from '../ascribe_forms/input_checkbox';
|
||||||
|
import Property from '../ascribe_forms/property';
|
||||||
|
|
||||||
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
|
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
import CopyrightAssociationForm from '../ascribe_forms/form_copyright_association';
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape, whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../constants/api_urls';
|
import ApiUrls from '../../constants/api_urls';
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let AccountSettings = React.createClass({
|
let AccountSettings = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
loadUser: React.PropTypes.func.isRequired,
|
loadUser: React.PropTypes.func.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess() {
|
handleSuccess() {
|
||||||
@ -100,7 +104,7 @@ let AccountSettings = React.createClass({
|
|||||||
<AclProxy
|
<AclProxy
|
||||||
aclObject={whitelabel}
|
aclObject={whitelabel}
|
||||||
aclName="acl_view_settings_copyright_association">
|
aclName="acl_view_settings_copyright_association">
|
||||||
<CopyrightAssociationForm currentUser={currentUser} />
|
<CopyrightAssociationForm />
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
{profile}
|
{profile}
|
||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
@ -108,4 +112,4 @@ let AccountSettings = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AccountSettings;
|
export default withContext(AccountSettings, 'currentUser', 'whitelabel');
|
||||||
|
@ -2,33 +2,33 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
|
|
||||||
import CreateContractForm from '../ascribe_forms/form_create_contract';
|
|
||||||
|
|
||||||
import ContractListStore from '../../stores/contract_list_store';
|
import ContractListStore from '../../stores/contract_list_store';
|
||||||
import ContractListActions from '../../actions/contract_list_actions';
|
import ContractListActions from '../../actions/contract_list_actions';
|
||||||
|
|
||||||
import ActionPanel from '../ascribe_panel/action_panel';
|
|
||||||
import ContractSettingsUpdateButton from './contract_settings_update_button';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import ContractSettingsUpdateButton from './contract_settings_update_button';
|
||||||
|
|
||||||
|
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
|
||||||
|
import CreateContractForm from '../ascribe_forms/form_create_contract';
|
||||||
|
|
||||||
|
import ActionPanel from '../ascribe_panel/action_panel';
|
||||||
|
|
||||||
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { currentUserShape, whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../utils/dom_utils';
|
import { setDocumentTitle } from '../../utils/dom_utils';
|
||||||
import { truncateTextAtCharIndex } from '../../utils/general_utils';
|
import { truncateTextAtCharIndex } from '../../utils/general_utils';
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let ContractSettings = React.createClass({
|
let ContractSettings = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -72,7 +72,7 @@ let ContractSettings = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser, location, whitelabel } = this.props;
|
const { currentUser, whitelabel } = this.props;
|
||||||
const publicContracts = this.getPublicContracts();
|
const publicContracts = this.getPublicContracts();
|
||||||
const privateContracts = this.getPrivateContracts();
|
const privateContracts = this.getPrivateContracts();
|
||||||
let createPublicContractForm = null;
|
let createPublicContractForm = null;
|
||||||
@ -180,4 +180,4 @@ let ContractSettings = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ContractSettings;
|
export default withContext(ContractSettings, 'currentUser', 'whitelabel');
|
||||||
|
@ -5,15 +5,16 @@ import React from 'react';
|
|||||||
import UserActions from '../../actions/user_actions';
|
import UserActions from '../../actions/user_actions';
|
||||||
|
|
||||||
import AccountSettings from './account_settings';
|
import AccountSettings from './account_settings';
|
||||||
|
import ApiSettings from './api_settings';
|
||||||
import BitcoinWalletSettings from './bitcoin_wallet_settings';
|
import BitcoinWalletSettings from './bitcoin_wallet_settings';
|
||||||
import APISettings from './api_settings';
|
|
||||||
import WebhookSettings from './webhook_settings';
|
import WebhookSettings from './webhook_settings';
|
||||||
|
|
||||||
import AclProxy from '../acl_proxy';
|
import AclProxy from '../acl_proxy';
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../utils/dom_utils';
|
import { setDocumentTitle } from '../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let SettingsContainer = React.createClass({
|
let SettingsContainer = React.createClass({
|
||||||
@ -23,12 +24,9 @@ let SettingsContainer = React.createClass({
|
|||||||
React.PropTypes.element
|
React.PropTypes.element
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
isLoggedIn: React.PropTypes.bool.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadUser(invalidateCache) {
|
loadUser(invalidateCache) {
|
||||||
@ -36,22 +34,19 @@ let SettingsContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children, currentUser, whitelabel } = this.props;
|
const { children, isLoggedIn, whitelabel } = this.props;
|
||||||
|
|
||||||
setDocumentTitle(getLangText('Account settings'));
|
setDocumentTitle(getLangText('Account settings'));
|
||||||
|
|
||||||
if (currentUser.username) {
|
if (isLoggedIn) {
|
||||||
return (
|
return (
|
||||||
<div className="settings-container">
|
<div className="settings-container">
|
||||||
<AccountSettings
|
<AccountSettings loadUser={this.loadUser} />
|
||||||
currentUser={currentUser}
|
|
||||||
loadUser={this.loadUser}
|
|
||||||
whitelabel={whitelabel} />
|
|
||||||
{children}
|
{children}
|
||||||
<AclProxy
|
<AclProxy
|
||||||
aclObject={whitelabel}
|
aclObject={whitelabel}
|
||||||
aclName="acl_view_settings_api">
|
aclName="acl_view_settings_api">
|
||||||
<APISettings />
|
<ApiSettings />
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
<WebhookSettings />
|
<WebhookSettings />
|
||||||
<AclProxy
|
<AclProxy
|
||||||
@ -66,4 +61,4 @@ let SettingsContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default SettingsContainer;
|
export default withContext(SettingsContainer, 'isLoggedIn', 'whitelabel');
|
||||||
|
@ -1,32 +1,33 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react/addons';
|
import React from 'react';
|
||||||
import { History, Lifecycle } from 'react-router';
|
|
||||||
|
|
||||||
import SlidesContainerBreadcrumbs from './slides_container_breadcrumbs';
|
import SlidesContainerBreadcrumbs from './slides_container_breadcrumbs';
|
||||||
|
|
||||||
|
import withContext from '../context/with_context';
|
||||||
|
import { locationShape, routerShape } from '../prop_types';
|
||||||
|
|
||||||
|
|
||||||
const { arrayOf, element, bool, shape, string, object } = React.PropTypes;
|
const { arrayOf, element, bool, shape, string, object } = React.PropTypes;
|
||||||
|
|
||||||
const SlidesContainer = React.createClass({
|
const SlidesContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
children: arrayOf(element),
|
|
||||||
forwardProcess: bool.isRequired,
|
forwardProcess: bool.isRequired,
|
||||||
|
|
||||||
|
children: arrayOf(element),
|
||||||
glyphiconClassNames: shape({
|
glyphiconClassNames: shape({
|
||||||
pending: string,
|
pending: string,
|
||||||
complete: string
|
complete: string
|
||||||
}),
|
}),
|
||||||
location: object,
|
|
||||||
pageExitWarning: string
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History, Lifecycle],
|
// Injected through HOCs
|
||||||
|
location: locationShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
containerWidth: 0,
|
containerWidth: 0
|
||||||
pageExitWarning: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -37,20 +38,17 @@ const SlidesContainer = React.createClass({
|
|||||||
|
|
||||||
// Initially, we need to dispatch 'resize' once to render correctly
|
// Initially, we need to dispatch 'resize' once to render correctly
|
||||||
window.dispatchEvent(new Event('resize'));
|
window.dispatchEvent(new Event('resize'));
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('resize', this.handleContainerResize);
|
window.removeEventListener('resize', this.handleContainerResize);
|
||||||
},
|
},
|
||||||
|
|
||||||
routerWillLeave() {
|
|
||||||
return this.props.pageExitWarning;
|
|
||||||
},
|
|
||||||
|
|
||||||
handleContainerResize() {
|
handleContainerResize() {
|
||||||
this.setState({
|
this.setState({
|
||||||
// +30 to get rid of the padding of the container which is 15px + 15px left and right
|
// +30 to get rid of the padding of the container which is 15px + 15px left and right
|
||||||
containerWidth: this.refs.containerWrapper.getDOMNode().offsetWidth + 30
|
containerWidth: this.refs.containerWrapper.offsetWidth + 30
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -61,10 +59,10 @@ const SlidesContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setSlideNum(nextSlideNum, additionalQueryParams = {}) {
|
setSlideNum(nextSlideNum, additionalQueryParams = {}) {
|
||||||
const { location: { pathname } } = this.props;
|
const { location: { pathname, query }, router } = this.props;
|
||||||
const query = Object.assign({}, this.props.location.query, additionalQueryParams, { slide_num: nextSlideNum });
|
const slideQuery = Object.assign({}, query, additionalQueryParams, { slide_num: nextSlideNum });
|
||||||
|
|
||||||
this.history.push({ pathname, query });
|
router.push({ pathname, query: slideQuery });
|
||||||
},
|
},
|
||||||
|
|
||||||
// breadcrumbs are defined as attributes of the slides.
|
// breadcrumbs are defined as attributes of the slides.
|
||||||
@ -120,7 +118,7 @@ const SlidesContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Since we need to give the slides a width, we need to call ReactAddons.addons.cloneWithProps
|
// Since we need to give the slides a width, we need to call React.cloneElement
|
||||||
// Also, a key is nice to have!
|
// Also, a key is nice to have!
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
const startFrom = parseInt(this.props.location.query.start_from, 10) || -1;
|
const startFrom = parseInt(this.props.location.query.start_from, 10) || -1;
|
||||||
@ -129,7 +127,7 @@ const SlidesContainer = React.createClass({
|
|||||||
// since the default parameter of startFrom is -1, we do not need to check
|
// since the default parameter of startFrom is -1, we do not need to check
|
||||||
// if its actually present in the url bar, as it will just not match
|
// if its actually present in the url bar, as it will just not match
|
||||||
if(child && i >= startFrom) {
|
if(child && i >= startFrom) {
|
||||||
return React.addons.cloneWithProps(child, {
|
return React.cloneElement(child, {
|
||||||
className: 'ascribe-slide',
|
className: 'ascribe-slide',
|
||||||
style: {
|
style: {
|
||||||
width: this.state.containerWidth
|
width: this.state.containerWidth
|
||||||
@ -179,4 +177,4 @@ const SlidesContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default SlidesContainer;
|
export default withContext(SlidesContainer, 'location', 'router');
|
||||||
|
@ -50,7 +50,7 @@ let FacebookShareButton = React.createClass({
|
|||||||
.inject(AppConstants.facebook.sdkUrl)
|
.inject(AppConstants.facebook.sdkUrl)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (this.state.loaded) {
|
if (this.state.loaded) {
|
||||||
FB.XFBML.parse(this.refs.fbShareButton.getDOMNode().parent)
|
window.FB.XFBML.parse(this.refs.fbShareButton.parent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -31,7 +31,7 @@ let TwitterShareButton = React.createClass({
|
|||||||
loadTwitterButton() {
|
loadTwitterButton() {
|
||||||
const { count, counturl, hashtags, size, text, url, via } = this.props;
|
const { count, counturl, hashtags, size, text, url, via } = this.props;
|
||||||
|
|
||||||
twttr.widgets.createShareButton(url, this.refs.twitterShareButton.getDOMNode(), {
|
window.twttr.widgets.createShareButton(url, this.refs.twitterShareButton, {
|
||||||
count,
|
count,
|
||||||
counturl,
|
counturl,
|
||||||
hashtags,
|
hashtags,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactAddons from 'react/addons';
|
|
||||||
|
|
||||||
import TableHeader from './table_header';
|
import TableHeader from './table_header';
|
||||||
import { ColumnModel } from './models/table_models';
|
import { ColumnModel } from './models/table_models';
|
||||||
@ -20,8 +19,8 @@ let Table = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
return ReactAddons.Children.map(this.props.children, (child, i) => {
|
return React.Children.map(this.props.children, (child, i) => {
|
||||||
return ReactAddons.addons.cloneWithProps(child, {
|
return React.cloneElement(child, {
|
||||||
columnList: this.props.columnList,
|
columnList: this.props.columnList,
|
||||||
columnContent: this.props.itemList[i],
|
columnContent: this.props.itemList[i],
|
||||||
key: i
|
key: i
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
import { ColumnModel } from './models/table_models';
|
import { ColumnModel } from './models/table_models';
|
||||||
|
|
||||||
@ -50,4 +50,4 @@ let TableItemWrapper = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default TableItemWrapper;
|
export default TableItemWrapper;
|
||||||
|
@ -55,7 +55,7 @@ let FileDragAndDrop = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
clearSelection() {
|
clearSelection() {
|
||||||
this.refs.fileSelector.getDOMNode().value = '';
|
this.refs.fileSelector.value = '';
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDragOver(event) {
|
handleDragOver(event) {
|
||||||
@ -132,7 +132,7 @@ let FileDragAndDrop = React.createClass({
|
|||||||
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
|
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refs.fileSelector.getDOMNode().dispatchEvent(evt);
|
this.refs.fileSelector.dispatchEvent(evt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -34,11 +34,13 @@ let FileDragAndDropDialog = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { enableLocalHashing,
|
const {
|
||||||
fileClassToUpload,
|
enableLocalHashing,
|
||||||
multipleFiles,
|
fileClassToUpload,
|
||||||
onClick,
|
multipleFiles,
|
||||||
uploadMethod } = this.props;
|
onClick,
|
||||||
|
uploadMethod
|
||||||
|
} = this.props;
|
||||||
let dialogElement;
|
let dialogElement;
|
||||||
|
|
||||||
if (enableLocalHashing && !uploadMethod) {
|
if (enableLocalHashing && !uploadMethod) {
|
||||||
@ -66,10 +68,8 @@ let FileDragAndDropDialog = React.createClass({
|
|||||||
{getLangText('Hash your work')}
|
{getLangText('Hash your work')}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<span> {getLangText('or')} </span>
|
<span> {getLangText('or')} </span>
|
||||||
|
<Link
|
||||||
<Link
|
|
||||||
to={`/${window.location.pathname.split('/').pop()}`}
|
to={`/${window.location.pathname.split('/').pop()}`}
|
||||||
query={queryParamsUpload}>
|
query={queryParamsUpload}>
|
||||||
<span className="btn btn-default btn-sm">
|
<span className="btn btn-default btn-sm">
|
||||||
|
@ -66,7 +66,7 @@ export default function UploadButton({ className = 'btn btn-default btn-sm', sho
|
|||||||
},
|
},
|
||||||
|
|
||||||
clearSelection() {
|
clearSelection() {
|
||||||
this.refs.fileSelector.getDOMNode().value = '';
|
this.refs.fileSelector.value = '';
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOnClick() {
|
handleOnClick() {
|
||||||
@ -88,7 +88,7 @@ export default function UploadButton({ className = 'btn btn-default btn-sm', sho
|
|||||||
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
|
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
|
||||||
}
|
}
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
this.refs.fileSelector.getDOMNode().dispatchEvent(evt);
|
this.refs.fileSelector.dispatchEvent(evt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react/addons';
|
import React from 'react';
|
||||||
|
import update from 'react-addons-update';
|
||||||
// FIXME: remove once using react-components
|
// FIXME: remove once using react-components
|
||||||
import fineUploader from 'exports?qq!./vendor/s3.fine-uploader';
|
import fineUploader from 'exports?qq!./vendor/s3.fine-uploader';
|
||||||
import Q from 'q';
|
import Q from 'q';
|
||||||
@ -536,7 +537,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
|
|
||||||
changeSet.status = { $set: status };
|
changeSet.status = { $set: status };
|
||||||
|
|
||||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { [fileId]: changeSet });
|
let filesToUpload = update(this.state.filesToUpload, { [fileId]: changeSet });
|
||||||
|
|
||||||
this.setState({ filesToUpload }, resolve);
|
this.setState({ filesToUpload }, resolve);
|
||||||
});
|
});
|
||||||
@ -547,7 +548,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
|
|
||||||
if(fileId < filesToUpload.length) {
|
if(fileId < filesToUpload.length) {
|
||||||
const changeSet = { $set: url };
|
const changeSet = { $set: url };
|
||||||
const newFilesToUpload = React.addons.update(filesToUpload, {
|
const newFilesToUpload = update(filesToUpload, {
|
||||||
[fileId]: { thumbnailUrl: changeSet }
|
[fileId]: { thumbnailUrl: changeSet }
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -574,7 +575,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
completed: false
|
completed: false
|
||||||
};
|
};
|
||||||
|
|
||||||
let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks });
|
let startedChunks = update(this.state.startedChunks, { $set: chunks });
|
||||||
|
|
||||||
this.setState({ startedChunks });
|
this.setState({ startedChunks });
|
||||||
},
|
},
|
||||||
@ -588,7 +589,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
chunks[chunkKey].responseJson = responseJson;
|
chunks[chunkKey].responseJson = responseJson;
|
||||||
chunks[chunkKey].xhr = xhr;
|
chunks[chunkKey].xhr = xhr;
|
||||||
|
|
||||||
let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks });
|
let startedChunks = update(this.state.startedChunks, { $set: chunks });
|
||||||
|
|
||||||
this.setState({ startedChunks });
|
this.setState({ startedChunks });
|
||||||
}
|
}
|
||||||
@ -619,7 +620,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
files[id].status = FileStatus.UPLOAD_SUCCESSFUL;
|
files[id].status = FileStatus.UPLOAD_SUCCESSFUL;
|
||||||
files[id].key = this.state.uploader.getKey(id);
|
files[id].key = this.state.uploader.getKey(id);
|
||||||
|
|
||||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: files });
|
let filesToUpload = update(this.state.filesToUpload, { $set: files });
|
||||||
this.setState({ filesToUpload });
|
this.setState({ filesToUpload });
|
||||||
|
|
||||||
// Only after the blob has been created server-side, we can make the form submittable.
|
// Only after the blob has been created server-side, we can make the form submittable.
|
||||||
@ -667,7 +668,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
if (!this.state.errorState.errorClass) {
|
if (!this.state.errorState.errorClass) {
|
||||||
notificationMessage = errorNotificationMessage;
|
notificationMessage = errorNotificationMessage;
|
||||||
|
|
||||||
const errorState = React.addons.update(this.state.errorState, {
|
const errorState = update(this.state.errorState, {
|
||||||
errorClass: {
|
errorClass: {
|
||||||
$set: this.getUploadErrorClass({
|
$set: this.getUploadErrorClass({
|
||||||
reason: errorReason,
|
reason: errorReason,
|
||||||
@ -720,7 +721,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onProgress(id, name, uploadedBytes, totalBytes) {
|
onProgress(id, name, uploadedBytes, totalBytes) {
|
||||||
let filesToUpload = React.addons.update(this.state.filesToUpload, {
|
let filesToUpload = update(this.state.filesToUpload, {
|
||||||
[id]: {
|
[id]: {
|
||||||
progress: { $set: (uploadedBytes / totalBytes) * 100}
|
progress: { $set: (uploadedBytes / totalBytes) * 100}
|
||||||
}
|
}
|
||||||
@ -747,7 +748,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
|
|
||||||
let filesToUpload = React.addons.update(this.state.filesToUpload, {$set: updatedFilesToUpload});
|
let filesToUpload = update(this.state.filesToUpload, {$set: updatedFilesToUpload});
|
||||||
|
|
||||||
this.setState({filesToUpload });
|
this.setState({filesToUpload });
|
||||||
} else {
|
} else {
|
||||||
@ -846,7 +847,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
|
|
||||||
fileIds.forEach((fileId) => {
|
fileIds.forEach((fileId) => {
|
||||||
this.state.uploader.retry(fileId);
|
this.state.uploader.retry(fileId);
|
||||||
filesToUpload = React.addons.update(filesToUpload, { [fileId]: { status: { $set: FileStatus.UPLOADING } } });
|
filesToUpload = update(filesToUpload, { [fileId]: { status: { $set: FileStatus.UPLOADING } } });
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -1041,7 +1042,7 @@ const ReactS3FineUploader = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the new file array
|
// set the new file array
|
||||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: oldAndNewFiles });
|
let filesToUpload = update(this.state.filesToUpload, { $set: oldAndNewFiles });
|
||||||
|
|
||||||
this.setState({ filesToUpload }, () => {
|
this.setState({ filesToUpload }, () => {
|
||||||
// when files have been dropped or selected by a user, we want to propagate that
|
// when files have been dropped or selected by a user, we want to propagate that
|
||||||
|
@ -6,24 +6,23 @@ import GlobalNotificationModel from '../models/global_notification_model';
|
|||||||
import GlobalNotificationActions from '../actions/global_notification_actions';
|
import GlobalNotificationActions from '../actions/global_notification_actions';
|
||||||
|
|
||||||
import Form from './ascribe_forms/form';
|
import Form from './ascribe_forms/form';
|
||||||
import Property from './ascribe_forms/property';
|
|
||||||
import InputTextAreaToggable from './ascribe_forms/input_textarea_toggable';
|
import InputTextAreaToggable from './ascribe_forms/input_textarea_toggable';
|
||||||
|
import Property from './ascribe_forms/property';
|
||||||
|
|
||||||
import AscribeSpinner from './ascribe_spinner';
|
import AscribeSpinner from './ascribe_spinner';
|
||||||
|
import withContext from './context/with_context';
|
||||||
|
import { locationShape } from './prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../constants/api_urls';
|
import ApiUrls from '../constants/api_urls';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import { getLangText } from '../utils/lang_utils';
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
|
|
||||||
|
|
||||||
let CoaVerifyContainer = React.createClass({
|
let CoaVerifyContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
location: locationShape.isRequired
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -117,5 +116,4 @@ let CoaVerifyForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withContext(CoaVerifyContainer, 'location');
|
||||||
export default CoaVerifyContainer;
|
|
||||||
|
138
js/components/context/with_context.js
Normal file
138
js/components/context/with_context.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../prop_types';
|
||||||
|
|
||||||
|
import { selectFromObject } from '../../utils/general_utils';
|
||||||
|
import { getDisplayName } from '../../utils/react_utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ContextPropDefinitions
|
||||||
|
* ======================
|
||||||
|
* contextType definitions for `contextProp`s.
|
||||||
|
*
|
||||||
|
* Each definition is of the form:
|
||||||
|
*
|
||||||
|
* contextProp = {
|
||||||
|
* 'contextTypes': {
|
||||||
|
* 'contextType': contextType used by the contextProp,
|
||||||
|
* ...
|
||||||
|
* },
|
||||||
|
* transformToProps: (optional) function that will receive the contextTypes from the component's
|
||||||
|
* context and should return an object containing the props to inject.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* In the common case where your `contextProp` maps directly to the `contextType` used
|
||||||
|
* (eg. using `currentUser` as a `contextProp` to get the `currentUser` from context), you can omit
|
||||||
|
* the object definition and simply assign the `contextType` to the `contextProp`:
|
||||||
|
*
|
||||||
|
* contextProp = contextType
|
||||||
|
*
|
||||||
|
* as opposed to:
|
||||||
|
*
|
||||||
|
* contextProp = {
|
||||||
|
* 'contextTypes': {
|
||||||
|
* contextProp: contextType
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const ContextPropDefinitions = {
|
||||||
|
currentUser: currentUserShape.isRequired,
|
||||||
|
isLoggedIn: {
|
||||||
|
contextTypes: {
|
||||||
|
currentUser: currentUserShape.isRequired
|
||||||
|
},
|
||||||
|
transformToProps: ({ currentUser }) => ({ isLoggedIn: !!currentUser.email })
|
||||||
|
},
|
||||||
|
location: locationShape.isRequired,
|
||||||
|
router: routerShape.isRequired,
|
||||||
|
whitelabel: whitelabelShape.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expand any shortform definitions in ContextPropDefinitions into a normalized form that's
|
||||||
|
// easier for withContext to work with
|
||||||
|
Object.entries(ContextPropDefinitions).forEach(([prop, def]) => {
|
||||||
|
if (!def.hasOwnProperty('contextTypes')) {
|
||||||
|
ContextPropDefinitions[prop] = {
|
||||||
|
contextTypes: {
|
||||||
|
[prop]: def
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generalized version of react-router's `withRouter`.
|
||||||
|
* This injects the given `contextProp`s from the WrappedComponent's context into the component as
|
||||||
|
* a prop.
|
||||||
|
*
|
||||||
|
* Given `contextProp`s must have a matching definition in `ContextPropDefinitions`.
|
||||||
|
*
|
||||||
|
* @param {Component} WrappedComponent Component to inject context into
|
||||||
|
* @param {...string} contextProps Argument list of `contextProp`s (that must be registered in
|
||||||
|
* `ContextPropDefinitions`) to be injected into component as
|
||||||
|
* props
|
||||||
|
* @return {Component} Wrapped component
|
||||||
|
*/
|
||||||
|
export default function withContext(WrappedComponent, ...contextProps) {
|
||||||
|
const wrappedComponentName = getDisplayName(WrappedComponent);
|
||||||
|
|
||||||
|
if (!contextProps.length) {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(`Used withContext on ${wrappedComponentName} without supplying any ` +
|
||||||
|
"items to inject from the component's context. Ignoring...");
|
||||||
|
}
|
||||||
|
|
||||||
|
return WrappedComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const contextTypes = contextProps.reduce((types, contextProp) => {
|
||||||
|
const contextDef = ContextPropDefinitions[contextProp];
|
||||||
|
|
||||||
|
if (contextDef) {
|
||||||
|
Object.assign(types, contextDef.contextTypes);
|
||||||
|
} else if (process.env.NODE_ENV !== 'production') {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(`No context types were found for '${contextProp}' when adding context ` +
|
||||||
|
`to ${wrappedComponentName}. Make sure to add the context information ` +
|
||||||
|
'with_context.js.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const WithContext = (props, context) => {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
// Check if the expected context was available
|
||||||
|
Object.keys(contextTypes).forEach((contextType) => {
|
||||||
|
if (!context[contextType]) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(`Expected '${contextType}' did not exist in ` +
|
||||||
|
`${wrappedComponentName}'s context during mounting`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const injectedProps = Object.assign({}, ...contextProps.map((contextProp) => {
|
||||||
|
const contextDef = ContextPropDefinitions[contextProp];
|
||||||
|
|
||||||
|
if (contextDef) {
|
||||||
|
const contextForProp = selectFromObject(context, Object.keys(contextDef.contextTypes));
|
||||||
|
return typeof contextDef.transformToProps === 'function'
|
||||||
|
? contextDef.transformToProps(contextForProp)
|
||||||
|
: contextForProp;
|
||||||
|
} else {
|
||||||
|
// Will be ignored by Object.assign()
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WrappedComponent {...props} {...injectedProps} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WithContext.displayName = `WithContext(${wrappedComponentName}): [${contextProps.join(', ')}]`;
|
||||||
|
WithContext.contextTypes = contextTypes;
|
||||||
|
|
||||||
|
return WithContext;
|
||||||
|
}
|
@ -1,25 +1,15 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
import history from '../history';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let ErrorNotFoundPage = React.createClass({
|
const ErrorNotFoundPage = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
message: React.PropTypes.string,
|
message: React.PropTypes.string,
|
||||||
|
|
||||||
// Provided from AscribeApp
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
message: getLangText("Oops, the page you are looking for doesn't exist.")
|
message: getLangText("Oops, the page you are looking for doesn't exist.")
|
||||||
@ -28,7 +18,7 @@ let ErrorNotFoundPage = React.createClass({
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// The previous page, if any, is the second item in the locationQueue
|
// The previous page, if any, is the second item in the locationQueue
|
||||||
const { locationQueue: [ , previousPage ] } = this.history;
|
const { locationQueue: [, previousPage] } = history;
|
||||||
|
|
||||||
if (previousPage) {
|
if (previousPage) {
|
||||||
console.logGlobal('Page not found', {
|
console.logGlobal('Page not found', {
|
||||||
|
@ -48,7 +48,7 @@ let GlobalNotification = React.createClass({
|
|||||||
|
|
||||||
handleContainerResize() {
|
handleContainerResize() {
|
||||||
this.setState({
|
this.setState({
|
||||||
containerWidth: this.refs.notificationWrapper.getDOMNode().offsetWidth
|
containerWidth: this.refs.notificationWrapper.offsetWidth
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -3,35 +3,35 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import history from '../history';
|
|
||||||
|
|
||||||
import Nav from 'react-bootstrap/lib/Nav';
|
import Nav from 'react-bootstrap/lib/Nav';
|
||||||
import Navbar from 'react-bootstrap/lib/Navbar';
|
import Navbar from 'react-bootstrap/lib/Navbar';
|
||||||
import CollapsibleNav from 'react-bootstrap/lib/CollapsibleNav';
|
|
||||||
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||||
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
||||||
import NavItem from 'react-bootstrap/lib/NavItem';
|
import NavItem from 'react-bootstrap/lib/NavItem';
|
||||||
|
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import EventActions from '../actions/event_actions';
|
|
||||||
|
|
||||||
import PieceListStore from '../stores/piece_list_store';
|
import PieceListStore from '../stores/piece_list_store';
|
||||||
|
|
||||||
import AclProxy from './acl_proxy';
|
import AclProxy from './acl_proxy';
|
||||||
|
import withContext from './context/with_context';
|
||||||
import HeaderNotifications from './header_notifications';
|
import HeaderNotifications from './header_notifications';
|
||||||
import HeaderNotificationDebug from './header_notification_debug';
|
import HeaderNotificationDebug from './header_notification_debug';
|
||||||
import NavRoutesLinks from './nav_routes_links';
|
import NavRoutesLinks from './nav_routes_links';
|
||||||
|
import { currentUserShape, whitelabelShape } from './prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
|
||||||
import { constructHead } from '../utils/dom_utils';
|
import { constructHead } from '../utils/dom_utils';
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let Header = React.createClass({
|
let Header = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -42,16 +42,10 @@ let Header = React.createClass({
|
|||||||
// Listen to the piece list store, but don't fetch immediately to avoid
|
// Listen to the piece list store, but don't fetch immediately to avoid
|
||||||
// conflicts with routes that may need to wait to load the piece list
|
// conflicts with routes that may need to wait to load the piece list
|
||||||
PieceListStore.listen(this.onChange);
|
PieceListStore.listen(this.onChange);
|
||||||
|
|
||||||
// react-bootstrap 0.25.1 has a bug in which it doesn't
|
|
||||||
// close the mobile expanded navigation after a click by itself.
|
|
||||||
// To get rid of this, we set the state of the component ourselves.
|
|
||||||
history.listen(this.onRouteChange);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
PieceListStore.unlisten(this.onChange);
|
PieceListStore.unlisten(this.onChange);
|
||||||
//history.unlisten(this.onRouteChange);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
@ -116,24 +110,15 @@ let Header = React.createClass({
|
|||||||
this.refs.dropdownbutton.setDropdownState(false);
|
this.refs.dropdownbutton.setDropdownState(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
// On route change, close expanded navbar again since react-bootstrap doesn't close
|
|
||||||
// the collapsibleNav by itself on click. setState() isn't available on a ref so
|
|
||||||
// doing this explicitly is the only way for now.
|
|
||||||
onRouteChange() {
|
|
||||||
if (this.refs.navbar) {
|
|
||||||
this.refs.navbar.state.navExpanded = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser, routes, whitelabel } = this.props;
|
const { currentUser, isLoggedIn, routes, whitelabel } = this.props;
|
||||||
const { unfilteredPieceListCount } = this.state;
|
const { unfilteredPieceListCount } = this.state;
|
||||||
|
|
||||||
let account;
|
let account;
|
||||||
let signup;
|
let signup;
|
||||||
let navRoutesLinks;
|
let navRoutesLinks;
|
||||||
|
|
||||||
if (currentUser.username) {
|
if (isLoggedIn) {
|
||||||
account = (
|
account = (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
ref='dropdownbutton'
|
ref='dropdownbutton'
|
||||||
@ -175,7 +160,7 @@ let Header = React.createClass({
|
|||||||
navRoutesLinks = (
|
navRoutesLinks = (
|
||||||
<NavRoutesLinks
|
<NavRoutesLinks
|
||||||
navbar
|
navbar
|
||||||
right
|
pullRight
|
||||||
hasPieces={!!unfilteredPieceListCount}
|
hasPieces={!!unfilteredPieceListCount}
|
||||||
routes={routes}
|
routes={routes}
|
||||||
userAcl={currentUser.acl} />
|
userAcl={currentUser.acl} />
|
||||||
@ -201,26 +186,30 @@ let Header = React.createClass({
|
|||||||
<div>
|
<div>
|
||||||
<Navbar
|
<Navbar
|
||||||
ref="navbar"
|
ref="navbar"
|
||||||
brand={this.getLogo()}
|
|
||||||
toggleNavKey={0}
|
|
||||||
fixedTop={true}
|
fixedTop={true}
|
||||||
className="hidden-print">
|
className="hidden-print">
|
||||||
<CollapsibleNav eventKey={0}>
|
<Navbar.Header>
|
||||||
<Nav navbar left>
|
<Navbar.Brand>
|
||||||
|
{this.getLogo()}
|
||||||
|
</Navbar.Brand>
|
||||||
|
</Navbar.Header>
|
||||||
|
<Navbar.Collapse
|
||||||
|
eventKey={0}>
|
||||||
|
<Nav navbar pullLeft>
|
||||||
<AclProxy
|
<AclProxy
|
||||||
aclObject={whitelabel}
|
aclObject={whitelabel}
|
||||||
aclName="acl_view_powered_by">
|
aclName="acl_view_powered_by">
|
||||||
{this.getPoweredBy()}
|
{this.getPoweredBy()}
|
||||||
</AclProxy>
|
</AclProxy>
|
||||||
</Nav>
|
</Nav>
|
||||||
<Nav navbar right>
|
<Nav navbar pullRight>
|
||||||
<HeaderNotificationDebug show={false} />
|
<HeaderNotificationDebug show={false}/>
|
||||||
{account}
|
{account}
|
||||||
{signup}
|
{signup}
|
||||||
</Nav>
|
</Nav>
|
||||||
<HeaderNotifications currentUser={currentUser} />
|
<HeaderNotifications />
|
||||||
{navRoutesLinks}
|
{navRoutesLinks}
|
||||||
</CollapsibleNav>
|
</Navbar.Collapse>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
<p className="ascribe-print-header visible-print">
|
<p className="ascribe-print-header visible-print">
|
||||||
<span className="icon-ascribe-logo" />
|
<span className="icon-ascribe-logo" />
|
||||||
@ -230,4 +219,4 @@ let Header = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Header;
|
export default withContext(Header, 'currentUser', 'isLoggedIn', 'whitelabel');
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
|
||||||
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
||||||
@ -11,12 +10,17 @@ import Nav from 'react-bootstrap/lib/Nav';
|
|||||||
import NotificationActions from '../actions/notification_actions';
|
import NotificationActions from '../actions/notification_actions';
|
||||||
import NotificationStore from '../stores/notification_store';
|
import NotificationStore from '../stores/notification_store';
|
||||||
|
|
||||||
|
import withContext from './context/with_context';
|
||||||
|
import { currentUserShape } from './prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let HeaderNotifications = React.createClass({
|
let HeaderNotifications = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
currentUser: React.PropTypes.object.isRequired
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -26,7 +30,7 @@ let HeaderNotifications = React.createClass({
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
NotificationStore.listen(this.onChange);
|
NotificationStore.listen(this.onChange);
|
||||||
|
|
||||||
if (this.props.currentUser.email) {
|
if (this.props.isLoggedIn) {
|
||||||
this.refreshNotifications();
|
this.refreshNotifications();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -45,31 +49,6 @@ let HeaderNotifications = React.createClass({
|
|||||||
this.setState(state);
|
this.setState(state);
|
||||||
},
|
},
|
||||||
|
|
||||||
onMenuItemClick() {
|
|
||||||
/*
|
|
||||||
This is a hack to make the dropdown close after clicking on an item
|
|
||||||
The function just need to be defined
|
|
||||||
|
|
||||||
from https://github.com/react-bootstrap/react-bootstrap/issues/368:
|
|
||||||
|
|
||||||
@jvillasante - Have you tried to use onSelect with the DropdownButton?
|
|
||||||
I don't have a working example that is exactly like yours,
|
|
||||||
but I just noticed that the Dropdown closes when I've attached an event handler to OnSelect:
|
|
||||||
|
|
||||||
<DropdownButton eventKey={3} title="Admin" onSelect={ this.OnSelected } >
|
|
||||||
|
|
||||||
onSelected: function(e) {
|
|
||||||
// doesn't need to have functionality (necessarily) ... just wired up
|
|
||||||
}
|
|
||||||
Internally, a call to DropdownButton.setDropDownState(false) is made which will hide the dropdown menu.
|
|
||||||
So, you should be able to call that directly on the DropdownButton instance as well if needed.
|
|
||||||
|
|
||||||
NOW, THAT DIDN'T WORK - the onSelect routine isnt triggered in all cases
|
|
||||||
Hence, we do this manually
|
|
||||||
*/
|
|
||||||
this.refs.dropdownbutton.setDropdownState(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
refreshNotifications() {
|
refreshNotifications() {
|
||||||
NotificationActions.fetchPieceListNotifications();
|
NotificationActions.fetchPieceListNotifications();
|
||||||
NotificationActions.fetchEditionListNotifications();
|
NotificationActions.fetchEditionListNotifications();
|
||||||
@ -83,12 +62,18 @@ let HeaderNotifications = React.createClass({
|
|||||||
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
|
{`${(isPiece ? 'Artworks' : 'Editions')} (${notifications.length})`}
|
||||||
</div>
|
</div>
|
||||||
{notifications.map((notification, i) => {
|
{notifications.map((notification, i) => {
|
||||||
|
const pieceOrEdition = isPiece ? notification.piece : notification.edition;
|
||||||
|
const href = isPiece ? `/pieces/${pieceOrEdition.id}`
|
||||||
|
: `/editions/${pieceOrEdition.bitcoin_id}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem eventKey={i + 2}>
|
<MenuItem
|
||||||
|
key={href}
|
||||||
|
eventKey={i + 2}
|
||||||
|
href={href}>
|
||||||
<NotificationListItem
|
<NotificationListItem
|
||||||
notification={notification.notification}
|
notification={notification.notification}
|
||||||
pieceOrEdition={isPiece ? notification.piece : notification.edition}
|
pieceOrEdition={pieceOrEdition} />
|
||||||
onClick={this.onMenuItemClick}/>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -112,7 +97,7 @@ let HeaderNotifications = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Nav navbar right>
|
<Nav navbar pullRight>
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
ref='dropdownButton'
|
ref='dropdownButton'
|
||||||
id="header-notification-dropdown"
|
id="header-notification-dropdown"
|
||||||
@ -138,25 +123,6 @@ let NotificationListItem = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
notification: React.PropTypes.array,
|
notification: React.PropTypes.array,
|
||||||
pieceOrEdition: React.PropTypes.object,
|
pieceOrEdition: React.PropTypes.object,
|
||||||
onClick: React.PropTypes.func
|
|
||||||
},
|
|
||||||
|
|
||||||
isPiece() {
|
|
||||||
return !(this.props.pieceOrEdition && this.props.pieceOrEdition.parent);
|
|
||||||
},
|
|
||||||
|
|
||||||
getLinkData() {
|
|
||||||
let { pieceOrEdition } = this.props;
|
|
||||||
|
|
||||||
if (this.isPiece()) {
|
|
||||||
return `/pieces/${pieceOrEdition.id}`;
|
|
||||||
} else {
|
|
||||||
return `/editions/${pieceOrEdition.bitcoin_id}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onClick(event){
|
|
||||||
this.props.onClick(event);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getNotificationText(){
|
getNotificationText(){
|
||||||
@ -174,23 +140,22 @@ let NotificationListItem = React.createClass({
|
|||||||
render() {
|
render() {
|
||||||
if (this.props.pieceOrEdition) {
|
if (this.props.pieceOrEdition) {
|
||||||
return (
|
return (
|
||||||
<Link to={this.getLinkData()} onClick={this.onClick}>
|
<div className="row notification-wrapper">
|
||||||
<div className="row notification-wrapper">
|
<div className="col-xs-4 clear-paddings">
|
||||||
<div className="col-xs-4 clear-paddings">
|
<div className="thumbnail-wrapper">
|
||||||
<div className="thumbnail-wrapper">
|
<img src={this.props.pieceOrEdition.thumbnail.url_safe}/>
|
||||||
<img src={this.props.pieceOrEdition.thumbnail.url_safe}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-xs-8 notification-list-item-header">
|
|
||||||
<h1>{this.props.pieceOrEdition.title}</h1>
|
|
||||||
<div className="sub-header">by {this.props.pieceOrEdition.artist_name}</div>
|
|
||||||
{this.getNotificationText()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>);
|
<div className="col-xs-8 notification-list-item-header">
|
||||||
|
<h1>{this.props.pieceOrEdition.title}</h1>
|
||||||
|
<div className="sub-header">by {this.props.pieceOrEdition.artist_name}</div>
|
||||||
|
{this.getNotificationText()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default HeaderNotifications;
|
export default withContext(HeaderNotifications, 'currentUser', 'isLoggedIn');
|
||||||
|
@ -1,35 +1,31 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
import LoginForm from './ascribe_forms/form_login';
|
import LoginForm from './ascribe_forms/form_login';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import withContext from './context/with_context';
|
||||||
|
import { whitelabelShape } from './prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let LoginContainer = React.createClass({
|
let LoginContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { whitelabel: { name: whitelabelName },
|
const { whitelabel: { name: whitelabelName } } = this.props;
|
||||||
location } = this.props;
|
|
||||||
|
|
||||||
setDocumentTitle(getLangText('Log in'));
|
setDocumentTitle(getLangText('Log in'));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ascribe-login-wrapper">
|
<div className="ascribe-login-wrapper">
|
||||||
<LoginForm
|
<LoginForm whitelabelName={whitelabelName} />
|
||||||
location={location}
|
|
||||||
whitelabelName={whitelabelName} />
|
|
||||||
<div className="ascribe-login-text">
|
<div className="ascribe-login-text">
|
||||||
{getLangText(`Not a ${whitelabelName || 'ascribe'} user`)}? <Link to="/signup">{getLangText('Sign up')}...</Link><br/>
|
{getLangText(`Not a ${whitelabelName || 'ascribe'} user`)}? <Link to="/signup">{getLangText('Sign up')}...</Link><br/>
|
||||||
{getLangText('Forgot my password')}? <Link to="/password_reset">{getLangText('Rescue me')}...</Link>
|
{getLangText('Forgot my password')}? <Link to="/password_reset">{getLangText('Rescue me')}...</Link>
|
||||||
@ -39,6 +35,4 @@ let LoginContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withContext(LoginContainer, 'whitelabel');
|
||||||
|
|
||||||
export default LoginContainer;
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import AscribeSpinner from './ascribe_spinner';
|
import AscribeSpinner from './ascribe_spinner';
|
||||||
|
|
||||||
@ -12,17 +11,6 @@ import { setDocumentTitle } from '../utils/dom_utils';
|
|||||||
|
|
||||||
|
|
||||||
let LogoutContainer = React.createClass({
|
let LogoutContainer = React.createClass({
|
||||||
propTypes: {
|
|
||||||
// Provided from AscribeApp
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
UserActions.logoutCurrentUser();
|
UserActions.logoutCurrentUser();
|
||||||
},
|
},
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Form from './ascribe_forms/form';
|
|
||||||
import Property from './ascribe_forms/property';
|
|
||||||
import ApiUrls from '../constants/api_urls';
|
|
||||||
import AscribeSpinner from './ascribe_spinner';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../models/global_notification_model';
|
import GlobalNotificationModel from '../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../actions/global_notification_actions';
|
import GlobalNotificationActions from '../actions/global_notification_actions';
|
||||||
import { getLangText } from '../utils/lang_utils';
|
|
||||||
|
import Form from './ascribe_forms/form';
|
||||||
|
import Property from './ascribe_forms/property';
|
||||||
|
|
||||||
|
import AscribeSpinner from './ascribe_spinner';
|
||||||
|
import withContext from './context/with_context';
|
||||||
|
import { locationShape, routerShape } from './prop_types';
|
||||||
|
|
||||||
|
import ApiUrls from '../constants/api_urls';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let PasswordResetContainer = React.createClass({
|
let PasswordResetContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
location: locationShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -108,13 +108,14 @@ let PasswordRequestResetForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let PasswordResetForm = React.createClass({
|
let PasswordResetForm = withContext(React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
token: React.PropTypes.string
|
token: React.PropTypes.string,
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [History],
|
// Injected through HOCs
|
||||||
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
},
|
||||||
|
|
||||||
getFormData() {
|
getFormData() {
|
||||||
return {
|
return {
|
||||||
@ -124,7 +125,7 @@ let PasswordResetForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess() {
|
handleSuccess() {
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
|
|
||||||
const notification = new GlobalNotificationModel(getLangText('Password successfully updated'), 'success', 10000);
|
const notification = new GlobalNotificationModel(getLangText('Password successfully updated'), 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
@ -175,6 +176,6 @@ let PasswordResetForm = React.createClass({
|
|||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}), 'router');
|
||||||
|
|
||||||
export default PasswordResetContainer;
|
export default withContext(PasswordResetContainer, 'location');
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import PieceListStore from '../stores/piece_list_store';
|
import PieceListStore from '../stores/piece_list_store';
|
||||||
import PieceListActions from '../actions/piece_list_actions';
|
import PieceListActions from '../actions/piece_list_actions';
|
||||||
@ -24,14 +21,16 @@ import PieceListBulkModal from './ascribe_piece_list_bulk_modal/piece_list_bulk_
|
|||||||
import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
|
import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
|
||||||
|
|
||||||
import AscribeSpinner from './ascribe_spinner';
|
import AscribeSpinner from './ascribe_spinner';
|
||||||
|
import withContext from './context/with_context';
|
||||||
|
import { locationShape, routerShape } from './prop_types';
|
||||||
|
|
||||||
import { getAvailableAcls } from '../utils/acl_utils';
|
import { getAvailableAcls } from '../utils/acl_utils';
|
||||||
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
import { mergeOptions, isShallowEqual } from '../utils/general_utils';
|
import { mergeOptions, isShallowEqual } from '../utils/general_utils';
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import { getLangText } from '../utils/lang_utils';
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
|
||||||
|
|
||||||
|
|
||||||
let PieceList = React.createClass({
|
const PieceList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
accordionListItemType: React.PropTypes.func,
|
accordionListItemType: React.PropTypes.func,
|
||||||
bulkModalButtonListType: React.PropTypes.func,
|
bulkModalButtonListType: React.PropTypes.func,
|
||||||
@ -47,16 +46,11 @@ let PieceList = React.createClass({
|
|||||||
orderParams: React.PropTypes.array,
|
orderParams: React.PropTypes.array,
|
||||||
orderBy: React.PropTypes.string,
|
orderBy: React.PropTypes.string,
|
||||||
|
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
location: locationShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
accordionListItemType: AccordionListItemWallet,
|
accordionListItemType: AccordionListItemWallet,
|
||||||
@ -129,18 +123,18 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const { location: { query }, redirectTo, shouldRedirect } = this.props;
|
const { location: { query }, redirectTo, router, shouldRedirect } = this.props;
|
||||||
const { unfilteredPieceListCount } = this.state;
|
const { unfilteredPieceListCount } = this.state;
|
||||||
|
|
||||||
if (redirectTo && redirectTo.pathname &&
|
if (redirectTo && redirectTo.pathname &&
|
||||||
(typeof shouldRedirect === 'function' && shouldRedirect(unfilteredPieceListCount))) {
|
(typeof shouldRedirect === 'function' && shouldRedirect(unfilteredPieceListCount))) {
|
||||||
// FIXME: hack to redirect out of the dispatch cycle
|
// FIXME: hack to redirect out of the dispatch cycle
|
||||||
window.setTimeout(() => this.history.push({
|
window.setTimeout(() => router.push({
|
||||||
// Occasionally, the back end also sets query parameters for Onion.
|
// Occasionally, the back end also sets query parameters for Onion.
|
||||||
// We need to consider this by merging all passed query parameters, as we'll
|
// We need to consider this by merging all passed query parameters, as we'll
|
||||||
// otherwise end up in a 404 screen
|
// otherwise end up in a 404 screen
|
||||||
query: Object.assign({}, query, redirectTo.query),
|
pathname: redirectTo.pathname,
|
||||||
pathname: redirectTo.pathname
|
query: Object.assign({}, query, redirectTo.query)
|
||||||
}), 0);
|
}), 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -195,14 +189,14 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
searchFor(search) {
|
searchFor(search) {
|
||||||
const { location: { pathname } } = this.props;
|
const { location: { pathname }, router } = this.props;
|
||||||
|
|
||||||
this.loadPieceList({ search, page: 1 });
|
this.loadPieceList({ search, page: 1 });
|
||||||
this.history.push({ pathname, query: { page: 1 } });
|
router.push({ pathname, query: { page: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
applyFilterBy(filterBy) {
|
applyFilterBy(filterBy) {
|
||||||
const { location: { pathname } } = this.props;
|
const { location: { pathname }, router } = this.props;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isFilterDirty: true
|
isFilterDirty: true
|
||||||
@ -228,7 +222,7 @@ let PieceList = React.createClass({
|
|||||||
|
|
||||||
// we have to redirect the user always to page one as it could be that there is no page two
|
// we have to redirect the user always to page one as it could be that there is no page two
|
||||||
// for filtered pieces
|
// for filtered pieces
|
||||||
this.history.push({ pathname, query: { page: 1 } });
|
router.push({ pathname, query: { page: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
applyOrderBy(orderBy) {
|
applyOrderBy(orderBy) {
|
||||||
@ -277,14 +271,14 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { accordionListItemType: AccordionListItemType,
|
const {
|
||||||
bulkModalButtonListType: BulkModalButtonListType,
|
customSubmitButton,
|
||||||
currentUser,
|
customThumbnailPlaceholder,
|
||||||
customSubmitButton,
|
filterParams,
|
||||||
customThumbnailPlaceholder,
|
orderParams,
|
||||||
filterParams,
|
accordionListItemType: AccordionListItemType,
|
||||||
orderParams,
|
bulkModalButtonListType: BulkModalButtonListType
|
||||||
whitelabel } = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const loadingElement = <AscribeSpinner color='dark-blue' size='lg'/>;
|
const loadingElement = <AscribeSpinner color='dark-blue' size='lg'/>;
|
||||||
|
|
||||||
@ -313,10 +307,8 @@ let PieceList = React.createClass({
|
|||||||
className="ascribe-piece-list-bulk-modal">
|
className="ascribe-piece-list-bulk-modal">
|
||||||
<BulkModalButtonListType
|
<BulkModalButtonListType
|
||||||
availableAcls={availableAcls}
|
availableAcls={availableAcls}
|
||||||
currentUser={currentUser}
|
|
||||||
handleSuccess={this.handleAclSuccess}
|
handleSuccess={this.handleAclSuccess}
|
||||||
pieceOrEditions={selectedEditions}
|
pieceOrEditions={selectedEditions}
|
||||||
whitelabel={whitelabel}
|
|
||||||
className="text-center ascribe-button-list collapse-group">
|
className="text-center ascribe-button-list collapse-group">
|
||||||
<DeleteButton
|
<DeleteButton
|
||||||
handleSuccess={this.handleAclSuccess}
|
handleSuccess={this.handleAclSuccess}
|
||||||
@ -344,9 +336,7 @@ let PieceList = React.createClass({
|
|||||||
key={piece.id}
|
key={piece.id}
|
||||||
className="col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2 ascribe-accordion-list-item"
|
className="col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2 ascribe-accordion-list-item"
|
||||||
content={piece}
|
content={piece}
|
||||||
currentUser={currentUser}
|
thumbnailPlaceholder={customThumbnailPlaceholder}>
|
||||||
thumbnailPlaceholder={customThumbnailPlaceholder}
|
|
||||||
whitelabel={whitelabel}>
|
|
||||||
<AccordionListItemTableEditions
|
<AccordionListItemTableEditions
|
||||||
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2"
|
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2"
|
||||||
parentId={piece.id} />
|
parentId={piece.id} />
|
||||||
@ -360,4 +350,4 @@ let PieceList = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default PieceList;
|
export default withContext(PieceList, 'location', 'router');
|
||||||
|
12
js/components/prop_types/current_user_shape.js
Normal file
12
js/components/prop_types/current_user_shape.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
const { number, object, shape, string } = React.PropTypes;
|
||||||
|
|
||||||
|
export default shape({
|
||||||
|
acl: object,
|
||||||
|
email: string,
|
||||||
|
id: number,
|
||||||
|
profile: object,
|
||||||
|
username: string
|
||||||
|
});
|
5
js/components/prop_types/index.js
Normal file
5
js/components/prop_types/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export { default as currentUserShape } from './current_user_shape';
|
||||||
|
export { default as whitelabelShape } from './whitelabel_shape';
|
||||||
|
|
||||||
|
// Re-export PropTypes from react-router
|
||||||
|
export { locationShape, routerShape } from 'react-router/es6/PropTypes';
|
11
js/components/prop_types/whitelabel_shape.js
Normal file
11
js/components/prop_types/whitelabel_shape.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
const { shape, string } = React.PropTypes;
|
||||||
|
|
||||||
|
export default shape({
|
||||||
|
name: string,
|
||||||
|
subdomain: string,
|
||||||
|
title: string,
|
||||||
|
user: string
|
||||||
|
});
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
@ -15,11 +12,14 @@ import GlobalNotificationActions from '../actions/global_notification_actions';
|
|||||||
import Property from './ascribe_forms/property';
|
import Property from './ascribe_forms/property';
|
||||||
import RegisterPieceForm from './ascribe_forms/form_register_piece';
|
import RegisterPieceForm from './ascribe_forms/form_register_piece';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import withContext from './context/with_context';
|
||||||
|
import { routerShape, whitelabelShape } from './prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let RegisterPiece = React.createClass( {
|
const RegisterPiece = React.createClass( {
|
||||||
propTypes: {
|
propTypes: {
|
||||||
headerMessage: React.PropTypes.string,
|
headerMessage: React.PropTypes.string,
|
||||||
submitMessage: React.PropTypes.string,
|
submitMessage: React.PropTypes.string,
|
||||||
@ -29,16 +29,11 @@ let RegisterPiece = React.createClass( {
|
|||||||
React.PropTypes.string
|
React.PropTypes.string
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
router: routerShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState(){
|
getInitialState(){
|
||||||
return PieceListStore.getState();
|
return PieceListStore.getState();
|
||||||
},
|
},
|
||||||
@ -65,7 +60,7 @@ let RegisterPiece = React.createClass( {
|
|||||||
// the piece list up to date
|
// the piece list up to date
|
||||||
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
this.history.push(`/pieces/${response.piece.id}`);
|
this.props.router.push(`/pieces/${response.piece.id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSpecifyEditions() {
|
getSpecifyEditions() {
|
||||||
@ -107,5 +102,4 @@ let RegisterPiece = React.createClass( {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withContext(RegisterPiece, 'router', 'whitelabel');
|
||||||
export default RegisterPiece;
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
// FIXME: Input is deprecated
|
||||||
import Input from 'react-bootstrap/lib/Input';
|
import Input from 'react-bootstrap/lib/Input';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
|
|
||||||
@ -140,4 +141,4 @@ const SearchBar = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default SearchBar;
|
export default SearchBar;
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import Link from 'react-router/es6/Link';
|
||||||
|
|
||||||
import SignupForm from './ascribe_forms/form_signup';
|
import SignupForm from './ascribe_forms/form_signup';
|
||||||
|
|
||||||
import { getLangText } from '../utils/lang_utils';
|
import withContext from './context/with_context';
|
||||||
|
import { whitelabelShape } from './prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../utils/dom_utils';
|
import { setDocumentTitle } from '../utils/dom_utils';
|
||||||
|
import { getLangText } from '../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let SignupContainer = React.createClass({
|
let SignupContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from AscribeApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -34,8 +31,7 @@ let SignupContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { location,
|
const { whitelabel: { name: whitelabelName } } = this.props;
|
||||||
whitelabel: { name: whitelabelName } } = this.props;
|
|
||||||
const { message, submitted } = this.state;
|
const { message, submitted } = this.state;
|
||||||
|
|
||||||
setDocumentTitle(getLangText('Sign up'));
|
setDocumentTitle(getLangText('Sign up'));
|
||||||
@ -54,8 +50,7 @@ let SignupContainer = React.createClass({
|
|||||||
<div className="ascribe-login-wrapper">
|
<div className="ascribe-login-wrapper">
|
||||||
<SignupForm
|
<SignupForm
|
||||||
handleSuccess={this.handleSuccess}
|
handleSuccess={this.handleSuccess}
|
||||||
whitelabelName={whitelabelName}
|
whitelabelName={whitelabelName} />
|
||||||
location={location}/>
|
|
||||||
<div className="ascribe-login-text">
|
<div className="ascribe-login-text">
|
||||||
{getLangText(`Already a ${whitelabelName || 'ascribe'} user`)}? <Link to="/login">{getLangText('Log in')}...</Link><br/>
|
{getLangText(`Already a ${whitelabelName || 'ascribe'} user`)}? <Link to="/login">{getLangText('Log in')}...</Link><br/>
|
||||||
</div>
|
</div>
|
||||||
@ -65,5 +60,4 @@ let SignupContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withContext(SignupContainer, 'whitelabel');
|
||||||
export default SignupContainer;
|
|
||||||
|
@ -5,20 +5,17 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let Vivi23Landing = React.createClass({
|
let Vivi23Landing = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
customThumbnailPlaceholder: React.PropTypes.func,
|
// Injected through HOCs
|
||||||
|
whitelabel: whitelabelShape.isRequired
|
||||||
// Provided from WalletApp
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -69,4 +66,4 @@ let Vivi23Landing = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Vivi23Landing;
|
export default withContext(Vivi23Landing, 'whitelabel');
|
||||||
|
@ -7,15 +7,6 @@ import Vivi23AccordionListItemThumbnailPlaceholder from './23vivi_accordion_list
|
|||||||
import MarketPieceList from '../market/market_piece_list';
|
import MarketPieceList from '../market/market_piece_list';
|
||||||
|
|
||||||
let Vivi23PieceList = React.createClass({
|
let Vivi23PieceList = React.createClass({
|
||||||
propTypes: {
|
|
||||||
// Provided from WalletApp
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<MarketPieceList
|
<MarketPieceList
|
||||||
|
@ -5,15 +5,17 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
|
||||||
|
|
||||||
let ArtcityLanding = React.createClass({
|
let ArtcityLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -61,4 +63,4 @@ let ArtcityLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ArtcityLanding;
|
export default withContext(ArtcityLanding, 'whitelabel');
|
||||||
|
@ -7,17 +7,21 @@ import AclButtonList from '../../../../ascribe_buttons/acl_button_list';
|
|||||||
import DeleteButton from '../../../../ascribe_buttons/delete_button';
|
import DeleteButton from '../../../../ascribe_buttons/delete_button';
|
||||||
|
|
||||||
import AclProxy from '../../../../acl_proxy';
|
import AclProxy from '../../../../acl_proxy';
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||||
|
|
||||||
|
|
||||||
let WalletActionPanel = React.createClass({
|
let WalletActionPanel = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
piece: React.PropTypes.object.isRequired,
|
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
handleDeleteSuccess: React.PropTypes.func.isRequired,
|
handleDeleteSuccess: React.PropTypes.func.isRequired,
|
||||||
loadPiece: React.PropTypes.func.isRequired,
|
loadPiece: React.PropTypes.func.isRequired,
|
||||||
submitButtonType: React.PropTypes.func.isRequired
|
piece: React.PropTypes.object.isRequired,
|
||||||
|
submitButtonType: React.PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -27,7 +31,6 @@ let WalletActionPanel = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<ListRequestActions
|
<ListRequestActions
|
||||||
pieceOrEditions={piece}
|
pieceOrEditions={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
handleSuccess={loadPiece}
|
handleSuccess={loadPiece}
|
||||||
notifications={piece.notifications}/>);
|
notifications={piece.notifications}/>);
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +49,6 @@ let WalletActionPanel = React.createClass({
|
|||||||
<AclButtonList
|
<AclButtonList
|
||||||
availableAcls={availableAcls}
|
availableAcls={availableAcls}
|
||||||
className="text-center ascribe-button-list"
|
className="text-center ascribe-button-list"
|
||||||
currentUser={currentUser}
|
|
||||||
pieceOrEditions={piece}
|
pieceOrEditions={piece}
|
||||||
handleSuccess={loadPiece}>
|
handleSuccess={loadPiece}>
|
||||||
<AclProxy
|
<AclProxy
|
||||||
@ -69,4 +71,4 @@ let WalletActionPanel = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default WalletActionPanel;
|
export default withContext(WalletActionPanel, 'currentUser');
|
||||||
|
@ -13,6 +13,7 @@ import Note from '../../../../ascribe_detail/note';
|
|||||||
import Piece from '../../../../../components/ascribe_detail/piece';
|
import Piece from '../../../../../components/ascribe_detail/piece';
|
||||||
|
|
||||||
import AscribeSpinner from '../../../../ascribe_spinner';
|
import AscribeSpinner from '../../../../ascribe_spinner';
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
|
||||||
import ApiUrls from '../../../../../constants/api_urls';
|
import ApiUrls from '../../../../../constants/api_urls';
|
||||||
|
|
||||||
@ -22,7 +23,6 @@ import { getLangText } from '../../../../../utils/lang_utils';
|
|||||||
let WalletPieceContainer = React.createClass({
|
let WalletPieceContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
piece: React.PropTypes.object.isRequired,
|
piece: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
handleDeleteSuccess: React.PropTypes.func.isRequired,
|
handleDeleteSuccess: React.PropTypes.func.isRequired,
|
||||||
loadPiece: React.PropTypes.func.isRequired,
|
loadPiece: React.PropTypes.func.isRequired,
|
||||||
submitButtonType: React.PropTypes.func.isRequired,
|
submitButtonType: React.PropTypes.func.isRequired,
|
||||||
@ -30,13 +30,16 @@ let WalletPieceContainer = React.createClass({
|
|||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.object,
|
React.PropTypes.object,
|
||||||
React.PropTypes.array
|
React.PropTypes.array
|
||||||
])
|
]),
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
isLoggedIn: React.PropTypes.bool.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children,
|
const { children,
|
||||||
currentUser,
|
|
||||||
handleDeleteSuccess,
|
handleDeleteSuccess,
|
||||||
|
isLoggedIn,
|
||||||
loadPiece,
|
loadPiece,
|
||||||
piece,
|
piece,
|
||||||
submitButtonType } = this.props;
|
submitButtonType } = this.props;
|
||||||
@ -45,7 +48,6 @@ let WalletPieceContainer = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<Piece
|
<Piece
|
||||||
piece={piece}
|
piece={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
header={
|
header={
|
||||||
<div className="ascribe-detail-header">
|
<div className="ascribe-detail-header">
|
||||||
<hr style={{marginTop: 0}}/>
|
<hr style={{marginTop: 0}}/>
|
||||||
@ -64,7 +66,6 @@ let WalletPieceContainer = React.createClass({
|
|||||||
}>
|
}>
|
||||||
<WalletActionPanel
|
<WalletActionPanel
|
||||||
piece={piece}
|
piece={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
loadPiece={loadPiece}
|
loadPiece={loadPiece}
|
||||||
handleDeleteSuccess={handleDeleteSuccess}
|
handleDeleteSuccess={handleDeleteSuccess}
|
||||||
submitButtonType={submitButtonType}/>
|
submitButtonType={submitButtonType}/>
|
||||||
@ -76,7 +77,7 @@ let WalletPieceContainer = React.createClass({
|
|||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Notes')}
|
title={getLangText('Notes')}
|
||||||
show={!!(currentUser.username || piece.public_note)}>
|
show={!!(isLoggedIn || piece.public_note)}>
|
||||||
<Note
|
<Note
|
||||||
id={() => {return {'id': piece.id}; }}
|
id={() => {return {'id': piece.id}; }}
|
||||||
label={getLangText('Personal note (private)')}
|
label={getLangText('Personal note (private)')}
|
||||||
@ -84,8 +85,7 @@ let WalletPieceContainer = React.createClass({
|
|||||||
placeholder={getLangText('Enter your comments ...')}
|
placeholder={getLangText('Enter your comments ...')}
|
||||||
editable={true}
|
editable={true}
|
||||||
successMessage={getLangText('Private note saved')}
|
successMessage={getLangText('Private note saved')}
|
||||||
url={ApiUrls.note_private_piece}
|
url={ApiUrls.note_private_piece} />
|
||||||
currentUser={currentUser}/>
|
|
||||||
</CollapsibleParagraph>
|
</CollapsibleParagraph>
|
||||||
{children}
|
{children}
|
||||||
</Piece>
|
</Piece>
|
||||||
@ -101,4 +101,4 @@ let WalletPieceContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default WalletPieceContainer;
|
export default withContext(WalletPieceContainer, 'isLoggedIn');
|
||||||
|
@ -12,15 +12,6 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
|||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||||
|
|
||||||
let CCRegisterPiece = React.createClass({
|
let CCRegisterPiece = React.createClass({
|
||||||
propTypes: {
|
|
||||||
// Provided from AscribeApp
|
|
||||||
currentUser: React.PropTypes.object,
|
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
LicenseStore.getState(),
|
LicenseStore.getState(),
|
||||||
@ -93,8 +84,7 @@ let CCRegisterPiece = React.createClass({
|
|||||||
{...this.props}
|
{...this.props}
|
||||||
enableLocalHashing={false}
|
enableLocalHashing={false}
|
||||||
headerMessage={getLangText('Register under a Creative Commons license')}
|
headerMessage={getLangText('Register under a Creative Commons license')}
|
||||||
submitMessage={getLangText('Submit')}
|
submitMessage={getLangText('Submit')}>
|
||||||
location={this.props.location}>
|
|
||||||
{this.getLicenses()}
|
{this.getLicenses()}
|
||||||
</RegisterPiece>
|
</RegisterPiece>
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import EditionListActions from '../../../../../../actions/edition_list_actions';
|
import EditionListActions from '../../../../../../actions/edition_list_actions';
|
||||||
|
|
||||||
@ -23,25 +20,23 @@ import WalletPieceContainer from '../../ascribe_detail/wallet_piece_container';
|
|||||||
import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
||||||
|
|
||||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||||
|
import withContext from '../../../../../context/with_context';
|
||||||
|
import { routerShape } from '../../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||||
|
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let CylandPieceContainer = React.createClass({
|
const CylandPieceContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
router: routerShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
// Provided from router
|
||||||
location: React.PropTypes.object,
|
|
||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
PieceStore.getInitialState(),
|
PieceStore.getInitialState(),
|
||||||
@ -90,22 +85,19 @@ let CylandPieceContainer = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(response.notification, 'success');
|
const notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { piece } = this.state;
|
const { piece } = this.state;
|
||||||
|
|
||||||
if (piece.id) {
|
if (piece.id) {
|
||||||
const { currentUser } = this.props;
|
|
||||||
|
|
||||||
setDocumentTitle(`${piece.artist_name}, ${piece.title}`);
|
setDocumentTitle(`${piece.artist_name}, ${piece.title}`);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WalletPieceContainer
|
<WalletPieceContainer
|
||||||
{...this.props}
|
{...this.props}
|
||||||
piece={this.state.piece}
|
piece={this.state.piece}
|
||||||
currentUser={currentUser}
|
|
||||||
loadPiece={this.loadPiece}
|
loadPiece={this.loadPiece}
|
||||||
handleDeleteSuccess={this.handleDeleteSuccess}
|
handleDeleteSuccess={this.handleDeleteSuccess}
|
||||||
submitButtonType={CylandSubmitButton}>
|
submitButtonType={CylandSubmitButton}>
|
||||||
@ -129,4 +121,4 @@ let CylandPieceContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CylandPieceContainer;
|
export default withContext(CylandPieceContainer, 'router');
|
||||||
|
@ -6,20 +6,17 @@ import Button from 'react-bootstrap/lib/Button';
|
|||||||
|
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import AscribeSpinner from '../../../../ascribe_spinner';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let CylandLanding = React.createClass({
|
let CylandLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -67,4 +64,4 @@ let CylandLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CylandLanding;
|
export default withContext(CylandLanding, 'whitelabel');
|
||||||
|
@ -5,26 +5,28 @@ import PieceList from '../../../../piece_list';
|
|||||||
|
|
||||||
import CylandAccordionListItem from './cyland_accordion_list/cyland_accordion_list_item';
|
import CylandAccordionListItem from './cyland_accordion_list/cyland_accordion_list_item';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
let CylandPieceList = React.createClass({
|
let CylandPieceList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldRedirect(pieceCount) {
|
shouldRedirect(pieceCount) {
|
||||||
const { currentUser: { email: userEmail },
|
const {
|
||||||
whitelabel: {
|
currentUser: { email: userEmail },
|
||||||
user: whitelabelAdminEmail
|
whitelabel: {
|
||||||
} } = this.props;
|
user: whitelabelAdminEmail
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return userEmail !== whitelabelAdminEmail && !pieceCount;
|
return userEmail !== whitelabelAdminEmail && !pieceCount;
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -52,4 +54,4 @@ let CylandPieceList = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CylandPieceList;
|
export default withContext(CylandPieceList, 'currentUser', 'whitelabel');
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
|
|
||||||
@ -26,26 +23,26 @@ import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
|
|||||||
|
|
||||||
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../../../../constants/api_urls';
|
import ApiUrls from '../../../../../constants/api_urls';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
|
||||||
import { getAclFormMessage } from '../../../../../utils/form_utils';
|
import { getAclFormMessage } from '../../../../../utils/form_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||||
|
|
||||||
|
|
||||||
let CylandRegisterPiece = React.createClass({
|
const CylandRegisterPiece = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
location: locationShape.isRequired,
|
||||||
|
router: routerShape.isRequired,
|
||||||
// Provided from router
|
whitelabel: whitelabelShape.isRequired,
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState(){
|
getInitialState(){
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
PieceListStore.getState(),
|
PieceListStore.getState(),
|
||||||
@ -110,7 +107,7 @@ let CylandRegisterPiece = React.createClass({
|
|||||||
|
|
||||||
this.refreshPieceList();
|
this.refreshPieceList();
|
||||||
|
|
||||||
this.history.push(`/pieces/${this.state.piece.id}`);
|
this.props.router.push(`/pieces/${this.state.piece.id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
nextSlide(queryParams) {
|
nextSlide(queryParams) {
|
||||||
@ -129,7 +126,7 @@ let CylandRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser, location, whitelabel } = this.props;
|
const { currentUser, whitelabel } = this.props;
|
||||||
const { piece, step } = this.state;
|
const { piece, step } = this.state;
|
||||||
|
|
||||||
const today = new Moment();
|
const today = new Moment();
|
||||||
@ -164,8 +161,7 @@ let CylandRegisterPiece = React.createClass({
|
|||||||
glyphiconClassNames={{
|
glyphiconClassNames={{
|
||||||
pending: 'glyphicon glyphicon-chevron-right',
|
pending: 'glyphicon glyphicon-chevron-right',
|
||||||
completed: 'glyphicon glyphicon-lock'
|
completed: 'glyphicon glyphicon-lock'
|
||||||
}}
|
}}>
|
||||||
location={location}>
|
|
||||||
<div data-slide-title={getLangText('Register work')}>
|
<div data-slide-title={getLangText('Register work')}>
|
||||||
<Row className="no-margin">
|
<Row className="no-margin">
|
||||||
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
||||||
@ -220,4 +216,4 @@ let CylandRegisterPiece = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default CylandRegisterPiece;
|
export default withContext(CylandRegisterPiece, 'currentUser', 'location', 'router', 'whitelabel');
|
||||||
|
@ -5,18 +5,17 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
|
import withContext from '../../../../context/with_context';
|
||||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let DemoLanding = React.createClass({
|
let DemoLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Provided from WalletApp
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -64,4 +63,4 @@ let DemoLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DemoLanding;
|
export default withContext(DemoLanding, 'whitelabel');
|
||||||
|
@ -14,21 +14,24 @@ import IkonotvSubmitButton from '../ikonotv_buttons/ikonotv_submit_button';
|
|||||||
import AccordionListItemPiece from '../../../../../ascribe_accordion_list/accordion_list_item_piece';
|
import AccordionListItemPiece from '../../../../../ascribe_accordion_list/accordion_list_item_piece';
|
||||||
|
|
||||||
import AclProxy from '../../../../../acl_proxy';
|
import AclProxy from '../../../../../acl_proxy';
|
||||||
|
import withContext from '../../../../../context/with_context';
|
||||||
|
import { currentUserShape } from '../../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
|
||||||
|
|
||||||
|
|
||||||
let IkonotvAccordionListItem = React.createClass({
|
let IkonotvAccordionListItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
content: React.PropTypes.object.isRequired,
|
content: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
React.PropTypes.element
|
React.PropTypes.element
|
||||||
]),
|
]),
|
||||||
className: React.PropTypes.string
|
className: React.PropTypes.string,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -116,4 +119,4 @@ let IkonotvAccordionListItem = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvAccordionListItem;
|
export default withContext(IkonotvAccordionListItem, 'currentUser');
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
@ -17,24 +14,23 @@ import OwnershipFetcher from '../../../../../fetchers/ownership_fetcher';
|
|||||||
import CopyrightAssociationForm from '../../../../ascribe_forms/form_copyright_association';
|
import CopyrightAssociationForm from '../../../../ascribe_forms/form_copyright_association';
|
||||||
import Property from '../../../../ascribe_forms/property';
|
import Property from '../../../../ascribe_forms/property';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape, routerShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import AppConstants from '../../../../../constants/application_constants';
|
import AppConstants from '../../../../../constants/application_constants';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let IkonotvContractNotifications = React.createClass({
|
const IkonotvContractNotifications = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
router: routerShape.isRequired,
|
||||||
|
whitelabel: whitelabelShape.isRequired
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return NotificationStore.getState();
|
return NotificationStore.getState();
|
||||||
},
|
},
|
||||||
@ -115,7 +111,7 @@ let IkonotvContractNotifications = React.createClass({
|
|||||||
NotificationActions.flushContractAgreementListNotifications();
|
NotificationActions.flushContractAgreementListNotifications();
|
||||||
NotificationActions.fetchContractAgreementListNotifications();
|
NotificationActions.fetchContractAgreementListNotifications();
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeny() {
|
handleDeny() {
|
||||||
@ -129,13 +125,13 @@ let IkonotvContractNotifications = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(getLangText('You have denied the conditions'), 'success', 5000);
|
const notification = new GlobalNotificationModel(getLangText('You have denied the conditions'), 'success', 5000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
getCopyrightAssociationForm(){
|
getCopyrightAssociationForm() {
|
||||||
const { currentUser } = this.props;
|
const { profile } = this.props.currentUser;
|
||||||
|
|
||||||
if (currentUser.profile && !currentUser.profile.copyright_association) {
|
if (profile && !profile.copyright_association) {
|
||||||
return (
|
return (
|
||||||
<div className='notification-contract-footer'>
|
<div className='notification-contract-footer'>
|
||||||
<h1>{getLangText('Are you a member of any copyright societies?')}</h1>
|
<h1>{getLangText('Are you a member of any copyright societies?')}</h1>
|
||||||
@ -143,7 +139,7 @@ let IkonotvContractNotifications = React.createClass({
|
|||||||
<p>
|
<p>
|
||||||
{AppConstants.copyrightAssociations.join(', ')}
|
{AppConstants.copyrightAssociations.join(', ')}
|
||||||
</p>
|
</p>
|
||||||
<CopyrightAssociationForm currentUser={currentUser}/>
|
<CopyrightAssociationForm />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -200,4 +196,4 @@ let IkonotvContractNotifications = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvContractNotifications;
|
export default withContext(IkonotvContractNotifications, 'currentUser', 'router', 'whitelabel');
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import EditionListActions from '../../../../../../actions/edition_list_actions';
|
import EditionListActions from '../../../../../../actions/edition_list_actions';
|
||||||
|
|
||||||
@ -24,25 +21,23 @@ import WalletPieceContainer from '../../ascribe_detail/wallet_piece_container';
|
|||||||
import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
||||||
|
|
||||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||||
|
import withContext from '../../../../../context/with_context';
|
||||||
|
import { routerShape } from '../../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||||
|
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let IkonotvPieceContainer = React.createClass({
|
const IkonotvPieceContainer = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
router: routerShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object,
|
|
||||||
|
|
||||||
// Provided from router
|
// Provided from router
|
||||||
location: React.PropTypes.object,
|
|
||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
PieceListStore.getState(),
|
PieceListStore.getState(),
|
||||||
@ -91,11 +86,10 @@ let IkonotvPieceContainer = React.createClass({
|
|||||||
const notification = new GlobalNotificationModel(response.notification, 'success');
|
const notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser } = this.props;
|
|
||||||
const { piece } = this.state;
|
const { piece } = this.state;
|
||||||
|
|
||||||
let furtherDetails = (
|
let furtherDetails = (
|
||||||
@ -129,7 +123,6 @@ let IkonotvPieceContainer = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<WalletPieceContainer
|
<WalletPieceContainer
|
||||||
piece={piece}
|
piece={piece}
|
||||||
currentUser={currentUser}
|
|
||||||
loadPiece={this.loadPiece}
|
loadPiece={this.loadPiece}
|
||||||
handleDeleteSuccess={this.handleDeleteSuccess}
|
handleDeleteSuccess={this.handleDeleteSuccess}
|
||||||
submitButtonType={IkonotvSubmitButton}>
|
submitButtonType={IkonotvSubmitButton}>
|
||||||
@ -146,4 +139,4 @@ let IkonotvPieceContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvPieceContainer;
|
export default withContext(IkonotvPieceContainer, 'router');
|
||||||
|
@ -6,32 +6,32 @@ import Button from 'react-bootstrap/lib/Button';
|
|||||||
|
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { locationShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let IkonotvLanding = React.createClass({
|
let IkonotvLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
isLoggedIn: React.PropTypes.bool.isRequired,
|
||||||
whitelabel: React.PropTypes.object,
|
location: locationShape.isRequired
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getEnterButton() {
|
getEnterButton() {
|
||||||
const { currentUser, location } = this.props;
|
const { isLoggedIn, location: { query } } = this.props;
|
||||||
let redirect = '/login';
|
let redirect = '/login';
|
||||||
|
|
||||||
if (currentUser.email) {
|
if (isLoggedIn) {
|
||||||
redirect = '/collection';
|
redirect = '/collection';
|
||||||
} else if (location.query.redirect) {
|
} else if (query.redirect) {
|
||||||
redirect = '/' + location.query.redirect;
|
redirect = `/${query.redirect}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LinkContainer to={redirect} query={location.query}>
|
<LinkContainer to={redirect} query={query}>
|
||||||
<Button>
|
<Button>
|
||||||
{getLangText('ENTER TO START')}
|
{getLangText('ENTER TO START')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -101,4 +101,4 @@ let IkonotvLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvLanding;
|
export default withContext(IkonotvLanding, 'isLoggedIn', 'location');
|
||||||
|
@ -8,18 +8,18 @@ import NotificationStore from '../../../../../stores/notification_store';
|
|||||||
|
|
||||||
import IkonotvAccordionListItem from './ikonotv_accordion_list/ikonotv_accordion_list_item';
|
import IkonotvAccordionListItem from './ikonotv_accordion_list/ikonotv_accordion_list_item';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let IkonotvPieceList = React.createClass({
|
let IkonotvPieceList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -39,10 +39,12 @@ let IkonotvPieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
shouldRedirect(pieceCount) {
|
shouldRedirect(pieceCount) {
|
||||||
const { currentUser: { email: userEmail },
|
const {
|
||||||
whitelabel: {
|
currentUser: { email: userEmail },
|
||||||
user: whitelabelAdminEmail
|
whitelabel: {
|
||||||
} } = this.props;
|
user: whitelabelAdminEmail
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
const { contractAgreementListNotifications } = this.state;
|
const { contractAgreementListNotifications } = this.state;
|
||||||
|
|
||||||
return contractAgreementListNotifications &&
|
return contractAgreementListNotifications &&
|
||||||
@ -84,4 +86,4 @@ let IkonotvPieceList = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvPieceList;
|
export default withContext(IkonotvPieceList, 'currentUser', 'whitelabel');
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
@ -24,43 +21,46 @@ import LoanForm from '../../../../ascribe_forms/form_loan';
|
|||||||
|
|
||||||
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import ApiUrls from '../../../../../constants/api_urls';
|
import ApiUrls from '../../../../../constants/api_urls';
|
||||||
|
|
||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let IkonotvRegisterPiece = React.createClass({
|
const IkonotvRegisterPiece = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
handleSuccess: React.PropTypes.func,
|
handleSuccess: React.PropTypes.func,
|
||||||
|
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
location: locationShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
router: routerShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
whitelabel: whitelabelShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
// Provided from router
|
||||||
location: React.PropTypes.object
|
route: React.PropTypes.object.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
PieceListStore.getState(),
|
PieceListStore.getState(),
|
||||||
PieceStore.getInitialState(),
|
PieceStore.getInitialState(),
|
||||||
{
|
{
|
||||||
step: 0,
|
step: 0,
|
||||||
pageExitWarning: getLangText("If you leave this form now, your work will not be loaned to Ikono TV.")
|
pageExitWarning: getLangText('If you leave this form now, your work will not be loaned to Ikono TV.')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
const { location: { query }, route, router } = this.props;
|
||||||
|
|
||||||
PieceListStore.listen(this.onChange);
|
PieceListStore.listen(this.onChange);
|
||||||
PieceStore.listen(this.onChange);
|
PieceStore.listen(this.onChange);
|
||||||
|
|
||||||
const queryParams = this.props.location.query;
|
|
||||||
|
|
||||||
// Since every step of this register process is atomic,
|
// Since every step of this register process is atomic,
|
||||||
// we may need to enter the process at step 1 or 2.
|
// we may need to enter the process at step 1 or 2.
|
||||||
// If this is the case, we'll need the piece number to complete submission.
|
// If this is the case, we'll need the piece number to complete submission.
|
||||||
@ -68,9 +68,12 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
//
|
//
|
||||||
// We're using 'in' here as we want to know if 'piece_id' is present in the url,
|
// We're using 'in' here as we want to know if 'piece_id' is present in the url,
|
||||||
// we don't care about the value.
|
// we don't care about the value.
|
||||||
if ('piece_id' in queryParams) {
|
if ('piece_id' in query) {
|
||||||
PieceActions.fetchPiece(queryParams.piece_id);
|
PieceActions.fetchPiece(query.piece_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warn the user if they try to leave before completing registration
|
||||||
|
router.setRouteLeaveHook(route, () => this.state.pageExitWarning);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@ -92,7 +95,7 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.canSubmit()) {
|
if (!this.canSubmit()) {
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
} else {
|
} else {
|
||||||
this.nextSlide({ piece_id: response.piece.id });
|
this.nextSlide({ piece_id: response.piece.id });
|
||||||
}
|
}
|
||||||
@ -117,7 +120,7 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
|
|
||||||
this.refreshPieceList();
|
this.refreshPieceList();
|
||||||
|
|
||||||
this.history.push(`/pieces/${this.state.piece.id}`);
|
this.props.router.push(`/pieces/${this.state.piece.id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
nextSlide(queryParams) {
|
nextSlide(queryParams) {
|
||||||
@ -210,7 +213,6 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { location } = this.props;
|
|
||||||
const { pageExitWarning, step } = this.state;
|
const { pageExitWarning, step } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -221,7 +223,6 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
pending: 'glyphicon glyphicon-chevron-right',
|
pending: 'glyphicon glyphicon-chevron-right',
|
||||||
completed: 'glyphicon glyphicon-lock'
|
completed: 'glyphicon glyphicon-lock'
|
||||||
}}
|
}}
|
||||||
location={location}
|
|
||||||
pageExitWarning={pageExitWarning}>
|
pageExitWarning={pageExitWarning}>
|
||||||
<div data-slide-title={getLangText('Register work')}>
|
<div data-slide-title={getLangText('Register work')}>
|
||||||
<Row className="no-margin">
|
<Row className="no-margin">
|
||||||
@ -245,4 +246,4 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IkonotvRegisterPiece;
|
export default withContext(IkonotvRegisterPiece, 'currentUser', 'location', 'router', 'whitelabel');
|
||||||
|
@ -5,18 +5,17 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let LumenusLanding = React.createClass({
|
let LumenusLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -66,4 +65,4 @@ let LumenusLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default LumenusLanding;
|
export default withContext(LumenusLanding, 'whitelabel');
|
||||||
|
@ -14,10 +14,8 @@ import { selectFromObject } from '../../../../../../utils/general_utils';
|
|||||||
let MarketAclButtonList = React.createClass({
|
let MarketAclButtonList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
availableAcls: React.PropTypes.object.isRequired,
|
availableAcls: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
handleSuccess: React.PropTypes.func.isRequired,
|
handleSuccess: React.PropTypes.func.isRequired,
|
||||||
pieceOrEditions: React.PropTypes.array.isRequired,
|
pieceOrEditions: React.PropTypes.array.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
@ -27,17 +25,16 @@ let MarketAclButtonList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { availableAcls,
|
const {
|
||||||
children,
|
availableAcls,
|
||||||
className,
|
children,
|
||||||
currentUser,
|
className,
|
||||||
handleSuccess,
|
handleSuccess,
|
||||||
pieceOrEditions,
|
pieceOrEditions
|
||||||
whitelabel } = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const buttonProps = selectFromObject(this.props, [
|
const buttonProps = selectFromObject(this.props, [
|
||||||
'availableAcls',
|
'availableAcls',
|
||||||
'currentUser',
|
|
||||||
'handleSuccess',
|
'handleSuccess',
|
||||||
'pieceOrEditions'
|
'pieceOrEditions'
|
||||||
]);
|
]);
|
||||||
@ -46,10 +43,8 @@ let MarketAclButtonList = React.createClass({
|
|||||||
<div className={className}>
|
<div className={className}>
|
||||||
<MarketSubmitButton
|
<MarketSubmitButton
|
||||||
availableAcls={availableAcls}
|
availableAcls={availableAcls}
|
||||||
currentUser={currentUser}
|
|
||||||
editions={pieceOrEditions}
|
editions={pieceOrEditions}
|
||||||
handleSuccess={handleSuccess}
|
handleSuccess={handleSuccess} />
|
||||||
whitelabel={whitelabel} />
|
|
||||||
<EmailButton {...buttonProps} />
|
<EmailButton {...buttonProps} />
|
||||||
<TransferButton {...buttonProps} />
|
<TransferButton {...buttonProps} />
|
||||||
<UnconsignButton {...buttonProps} />
|
<UnconsignButton {...buttonProps} />
|
||||||
|
@ -10,13 +10,12 @@ import MarketAdditionalDataForm from '../market_forms/market_additional_data_for
|
|||||||
import MarketErrorConsignUnavailable from '../market_error_consign_unavailable';
|
import MarketErrorConsignUnavailable from '../market_error_consign_unavailable';
|
||||||
|
|
||||||
import AclFormFactory from '../../../../../ascribe_forms/acl_form_factory';
|
import AclFormFactory from '../../../../../ascribe_forms/acl_form_factory';
|
||||||
import ConsignForm from '../../../../../ascribe_forms/form_consign';
|
|
||||||
|
|
||||||
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
||||||
|
|
||||||
import AclProxy from '../../../../../acl_proxy';
|
import AclProxy from '../../../../../acl_proxy';
|
||||||
|
import withContext from '../../../../../context/with_context';
|
||||||
import ApiUrls from '../../../../../../constants/api_urls';
|
import { currentUserShape, whitelabelShape } from '../../../../../prop_types';
|
||||||
|
|
||||||
import { getAclFormMessage, getAclFormDataId } from '../../../../../../utils/form_utils';
|
import { getAclFormMessage, getAclFormDataId } from '../../../../../../utils/form_utils';
|
||||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||||
@ -24,12 +23,14 @@ import { getLangText } from '../../../../../../utils/lang_utils';
|
|||||||
let MarketSubmitButton = React.createClass({
|
let MarketSubmitButton = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
availableAcls: React.PropTypes.object.isRequired,
|
availableAcls: React.PropTypes.object.isRequired,
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
|
||||||
editions: React.PropTypes.array.isRequired,
|
editions: React.PropTypes.array.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func,
|
||||||
|
|
||||||
|
// Injected through HOCs
|
||||||
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
},
|
},
|
||||||
|
|
||||||
canEditionBeSubmitted(edition) {
|
canEditionBeSubmitted(edition) {
|
||||||
@ -81,12 +82,14 @@ let MarketSubmitButton = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { availableAcls,
|
const {
|
||||||
currentUser,
|
availableAcls,
|
||||||
className,
|
currentUser,
|
||||||
editions,
|
className,
|
||||||
handleSuccess,
|
editions,
|
||||||
whitelabel: { name: whitelabelName = 'Market', user: whitelabelAdminEmail } } = this.props;
|
handleSuccess,
|
||||||
|
whitelabel: { name: whitelabelName = 'Market', user: whitelabelAdminEmail }
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const { solePieceId, canEdit, canSubmit } = this.getAggregateEditionDetails();
|
const { solePieceId, canEdit, canSubmit } = this.getAggregateEditionDetails();
|
||||||
const message = getAclFormMessage({
|
const message = getAclFormMessage({
|
||||||
@ -184,4 +187,4 @@ let MarketSubmitButton = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MarketSubmitButton;
|
export default withContext(MarketSubmitButton, 'currentUser', 'whitelabel');
|
||||||
|
@ -5,23 +5,22 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
|
import withContext from '../../../../context/with_context';
|
||||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let MarketLanding = React.createClass({
|
let MarketLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const { name } = this.props.whitelabel;
|
const { name } = this.props.whitelabel;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
setDocumentTitle(`${name} Marketplace`);
|
setDocumentTitle(`${name} Marketplace`);
|
||||||
}
|
}
|
||||||
@ -70,4 +69,4 @@ let MarketLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MarketLanding;
|
export default withContext(MarketLanding, 'whitelabel');
|
||||||
|
@ -4,22 +4,20 @@ import React from 'react';
|
|||||||
|
|
||||||
import MarketAclButtonList from './market_buttons/market_acl_button_list';
|
import MarketAclButtonList from './market_buttons/market_acl_button_list';
|
||||||
|
|
||||||
|
import withContext from '../../../../context/with_context';
|
||||||
import PieceList from '../../../../piece_list';
|
import PieceList from '../../../../piece_list';
|
||||||
|
import { currentUserShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
let MarketPieceList = React.createClass({
|
let MarketPieceList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
customThumbnailPlaceholder: React.PropTypes.func,
|
customThumbnailPlaceholder: React.PropTypes.func,
|
||||||
|
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: currentUserShape.isRequired, // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
whitelabel: whitelabelShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
|
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -27,11 +25,13 @@ let MarketPieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentUser: { email: userEmail },
|
const {
|
||||||
whitelabel: {
|
currentUser: { email: userEmail },
|
||||||
name: whitelabelName = 'Market',
|
whitelabel: {
|
||||||
user: whitelabelAdminEmail
|
name: whitelabelName = 'Market',
|
||||||
} } = this.props;
|
user: whitelabelAdminEmail
|
||||||
|
}
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
let filterParams = null;
|
let filterParams = null;
|
||||||
let isUserAdmin = null;
|
let isUserAdmin = null;
|
||||||
@ -68,4 +68,4 @@ let MarketPieceList = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MarketPieceList;
|
export default withContext(MarketPieceList, 'currentUser', 'whitelabel');
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { History } from 'react-router';
|
|
||||||
|
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
@ -19,22 +16,21 @@ import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
|
|||||||
|
|
||||||
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
import withContext from '../../../../context/with_context';
|
||||||
|
import { locationShape, routerShape, whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
let MarketRegisterPiece = React.createClass({
|
let MarketRegisterPiece = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
router: routerShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired,
|
location: locationShape.isRequired,
|
||||||
|
whitelabel: whitelabelShape.isRequired
|
||||||
// Provided from router
|
|
||||||
location: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
|
||||||
|
|
||||||
getInitialState(){
|
getInitialState(){
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
PieceListStore.getState(),
|
PieceListStore.getState(),
|
||||||
@ -82,7 +78,7 @@ let MarketRegisterPiece = React.createClass({
|
|||||||
handleAdditionalDataSuccess() {
|
handleAdditionalDataSuccess() {
|
||||||
this.refreshPieceList();
|
this.refreshPieceList();
|
||||||
|
|
||||||
this.history.push('/collection');
|
this.props.router.push('/collection');
|
||||||
},
|
},
|
||||||
|
|
||||||
nextSlide(queryParams) {
|
nextSlide(queryParams) {
|
||||||
@ -101,10 +97,7 @@ let MarketRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { location,
|
const { whitelabel: { name: whitelabelName = 'Market' } } = this.props;
|
||||||
whitelabel: {
|
|
||||||
name: whitelabelName = 'Market'
|
|
||||||
} } = this.props
|
|
||||||
const { piece, step } = this.state;
|
const { piece, step } = this.state;
|
||||||
|
|
||||||
setDocumentTitle(getLangText('Register a new piece'));
|
setDocumentTitle(getLangText('Register a new piece'));
|
||||||
@ -116,8 +109,7 @@ let MarketRegisterPiece = React.createClass({
|
|||||||
glyphiconClassNames={{
|
glyphiconClassNames={{
|
||||||
pending: 'glyphicon glyphicon-chevron-right',
|
pending: 'glyphicon glyphicon-chevron-right',
|
||||||
completed: 'glyphicon glyphicon-lock'
|
completed: 'glyphicon glyphicon-lock'
|
||||||
}}
|
}}>
|
||||||
location={location}>
|
|
||||||
<div data-slide-title={getLangText('Register work')}>
|
<div data-slide-title={getLangText('Register work')}>
|
||||||
<Row className="no-margin">
|
<Row className="no-margin">
|
||||||
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
||||||
@ -160,4 +152,4 @@ let MarketRegisterPiece = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MarketRegisterPiece;
|
export default withContext(MarketRegisterPiece, 'location', 'router', 'whitelabel');
|
||||||
|
@ -5,18 +5,17 @@ import React from 'react';
|
|||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||||
|
|
||||||
import WhitelabelActions from '../../../../../actions/whitelabel_actions';
|
import withContext from '../../../../context/with_context';
|
||||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
import { whitelabelShape } from '../../../../prop_types';
|
||||||
|
|
||||||
import { getLangText } from '../../../../../utils/lang_utils';
|
|
||||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||||
|
import { getLangText } from '../../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
let PollineLanding = React.createClass({
|
let PollineLanding = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
// Provided from WalletApp
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
whitelabel: whitelabelShape.isRequired,
|
||||||
whitelabel: React.PropTypes.object.isRequired
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@ -64,4 +63,4 @@ let PollineLanding = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default PollineLanding;
|
export default withContext(PollineLanding, 'whitelabel');
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import AppBase from '../../app_base';
|
import AppBase from '../../app_base';
|
||||||
import AppRouteWrapper from '../../app_route_wrapper';
|
import withContext from '../../context/with_context';
|
||||||
import Header from '../../header';
|
import Header from '../../header';
|
||||||
|
import { routerShape } from '../../prop_types';
|
||||||
|
|
||||||
import { getSubdomain } from '../../../utils/general_utils';
|
import { getSubdomain } from '../../../utils/general_utils';
|
||||||
|
|
||||||
@ -14,31 +13,26 @@ let WalletApp = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
activeRoute: React.PropTypes.object.isRequired,
|
activeRoute: React.PropTypes.object.isRequired,
|
||||||
children: React.PropTypes.element.isRequired,
|
children: React.PropTypes.element.isRequired,
|
||||||
history: React.PropTypes.object.isRequired,
|
|
||||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||||
|
|
||||||
// Provided from AppBase
|
// Injected through HOCs
|
||||||
currentUser: React.PropTypes.object,
|
router: routerShape.isRequired // eslint-disable-line react/sort-prop-types
|
||||||
whitelabel: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { activeRoute, children, currentUser, history, routes, whitelabel } = this.props;
|
const { activeRoute, children, router, routes } = this.props;
|
||||||
const subdomain = getSubdomain();
|
const subdomain = getSubdomain();
|
||||||
const path = activeRoute && activeRoute.path;
|
const path = activeRoute && activeRoute.path;
|
||||||
const Footer = activeRoute && activeRoute.footer;
|
const RouteFooterType = activeRoute && activeRoute.footer;
|
||||||
|
|
||||||
let header = null;
|
let header = null;
|
||||||
// if the path of the current activeRoute is not defined, then this is the IndexRoute
|
// if the path of the current activeRoute is not defined, then this is the IndexRoute
|
||||||
if ((!path || history.isActive('/login') || history.isActive('/signup') || history.isActive('/contract_notifications'))
|
if ((!path || router.isActive('/login') || router.isActive('/signup') || router.isActive('/contract_notifications'))
|
||||||
&& (['cyland', 'ikonotv', 'lumenus', '23vivi', 'polline', 'artcity', 'demo', 'liquidgallery']).includes(subdomain)) {
|
&& (['cyland', 'ikonotv', 'lumenus', '23vivi', 'polline', 'artcity', 'demo', 'liquidgallery']).includes(subdomain)) {
|
||||||
header = (<div className="hero"/>);
|
header = (<div className="hero"/>);
|
||||||
} else {
|
} else {
|
||||||
header = (
|
header = (
|
||||||
<Header
|
<Header routes={routes} />
|
||||||
currentUser={currentUser}
|
|
||||||
routes={routes}
|
|
||||||
whitelabel={whitelabel} />
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,16 +41,14 @@ let WalletApp = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<div className={classNames('ascribe-app', 'ascribe-wallet-app', `route--${(path ? path.split('/')[0] : 'landing')}`)}>
|
<div className={classNames('ascribe-app', 'ascribe-wallet-app', `route--${(path ? path.split('/')[0] : 'landing')}`)}>
|
||||||
{header}
|
{header}
|
||||||
<AppRouteWrapper
|
<div className="container ascribe-body">
|
||||||
currentUser={currentUser}
|
|
||||||
whitelabel={whitelabel}>
|
|
||||||
{/* Routes are injected here */}
|
{/* Routes are injected here */}
|
||||||
{children}
|
{children}
|
||||||
</AppRouteWrapper>
|
</div>
|
||||||
{Footer ? <Footer /> : null}
|
{RouteFooterType ? <RouteFooterType /> : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AppBase(WalletApp);
|
export default AppBase(withContext(WalletApp, 'router'));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Redirect } from 'react-router';
|
import Redirect from 'react-router/es6/Redirect';
|
||||||
|
|
||||||
import getWalletApiUrls from './constants/wallet_api_urls';
|
import getWalletApiUrls from './constants/wallet_api_urls';
|
||||||
import getWalletRoutes from './wallet_routes';
|
import getWalletRoutes from './wallet_routes';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Route, IndexRoute } from 'react-router';
|
import IndexRoute from 'react-router/es6/IndexRoute';
|
||||||
|
import Route from 'react-router/es6/Route';
|
||||||
|
|
||||||
import { ProxyHandler, AuthRedirect } from '../../../components/ascribe_routes/proxy_handler';
|
import { ProxyHandler, AuthRedirect } from '../../../components/ascribe_routes/proxy_handler';
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
'use strict';
|
import useRouterHistory from 'react-router/es6/useRouterHistory';
|
||||||
|
|
||||||
import useBasename from 'history/lib/useBasename';
|
|
||||||
import useQueries from 'history/lib/useQueries';
|
|
||||||
import createBrowserHistory from 'history/lib/createBrowserHistory';
|
import createBrowserHistory from 'history/lib/createBrowserHistory';
|
||||||
|
|
||||||
import AppConstants from './constants/application_constants';
|
import AppConstants from './constants/application_constants';
|
||||||
|
|
||||||
|
|
||||||
const history = useBasename(useQueries(createBrowserHistory))({
|
const history = useRouterHistory(createBrowserHistory)({
|
||||||
basename: AppConstants.baseUrl
|
basename: AppConstants.baseUrl
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Route } from 'react-router';
|
import Route from 'react-router/es6/Route';
|
||||||
|
|
||||||
import AscribeApp from './components/ascribe_app';
|
import AscribeApp from './components/ascribe_app';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import update from 'react-addons-update';
|
||||||
|
|
||||||
import { alt } from '../alt';
|
import { alt } from '../alt';
|
||||||
import EditionsListActions from '../actions/edition_list_actions';
|
import EditionsListActions from '../actions/edition_list_actions';
|
||||||
@ -30,7 +30,7 @@ class EditionListStore {
|
|||||||
|
|
||||||
// if edition already exists, just merge
|
// if edition already exists, just merge
|
||||||
if (pieceEditionList[storeEditionIndex]) {
|
if (pieceEditionList[storeEditionIndex]) {
|
||||||
pieceEditionList[storeEditionIndex] = React.addons.update(pieceEditionList[storeEditionIndex], { $merge: updatedEdition });
|
pieceEditionList[storeEditionIndex] = update(pieceEditionList[storeEditionIndex], { $merge: updatedEdition });
|
||||||
} else {
|
} else {
|
||||||
// if does not exist, assign
|
// if does not exist, assign
|
||||||
pieceEditionList[storeEditionIndex] = updatedEdition;
|
pieceEditionList[storeEditionIndex] = updatedEdition;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import update from 'react-addons-update';
|
||||||
import { alt } from '../alt';
|
import { alt } from '../alt';
|
||||||
|
|
||||||
import PieceListActions from '../actions/piece_list_actions';
|
import PieceListActions from '../actions/piece_list_actions';
|
||||||
@ -62,7 +62,7 @@ class PieceListStore {
|
|||||||
pieceList.forEach((piece, i) => {
|
pieceList.forEach((piece, i) => {
|
||||||
const oldPiece = this.pieceList[i];
|
const oldPiece = this.pieceList[i];
|
||||||
if (oldPiece) {
|
if (oldPiece) {
|
||||||
piece = React.addons.update(piece, {
|
piece = update(piece, {
|
||||||
show: { $set: oldPiece.show }
|
show: { $set: oldPiece.show }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class WhitelabelStore {
|
|||||||
this.whitelabel = whitelabel;
|
this.whitelabel = whitelabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
onErrorCurrentUser(err) {
|
onErrorWhitelabel(err) {
|
||||||
console.logGlobal(err);
|
console.logGlobal(err);
|
||||||
this.whitelabelMeta.err = err;
|
this.whitelabelMeta.err = err;
|
||||||
}
|
}
|
||||||
|
7
js/utils/react_utils.js
Normal file
7
js/utils/react_utils.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Taken from react-router (https://github.com/reactjs/react-router/blob/master/modules/withRouter.js)
|
||||||
|
* FIXME: should be put into react-component's utils
|
||||||
|
*/
|
||||||
|
export function getDisplayName(WrappedComponent) {
|
||||||
|
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
|
||||||
|
}
|
19
package.json
19
package.json
@ -88,9 +88,8 @@
|
|||||||
"express": "^4.13.4",
|
"express": "^4.13.4",
|
||||||
"extract-text-webpack-plugin": "^1.0.1",
|
"extract-text-webpack-plugin": "^1.0.1",
|
||||||
"file-loader": "^0.8.5",
|
"file-loader": "^0.8.5",
|
||||||
"history": "1.17.0",
|
|
||||||
"html-webpack-plugin": "^2.19.0",
|
"html-webpack-plugin": "^2.19.0",
|
||||||
"invariant": "^2.1.1",
|
"invariant": "^2.2.1",
|
||||||
"isomorphic-fetch": "^2.0.2",
|
"isomorphic-fetch": "^2.0.2",
|
||||||
"moment": "^2.10.6",
|
"moment": "^2.10.6",
|
||||||
"node-sass": "^3.7.0",
|
"node-sass": "^3.7.0",
|
||||||
@ -98,13 +97,15 @@
|
|||||||
"q": "^1.4.1",
|
"q": "^1.4.1",
|
||||||
"query-string": "^3.0.0",
|
"query-string": "^3.0.0",
|
||||||
"raven-js": "^1.1.19",
|
"raven-js": "^1.1.19",
|
||||||
"react": "0.13.2",
|
"react": "^15.1.0",
|
||||||
"react-bootstrap": "0.25.1",
|
"react-addons-update": "^15.1.0",
|
||||||
"react-datepicker": "^0.12.0",
|
"react-bootstrap": "^0.29.4",
|
||||||
"react-router": "1.0.3",
|
"react-datepicker": "^0.27.0",
|
||||||
"react-router-bootstrap": "^0.19.0",
|
"react-dom": "^15.1.0",
|
||||||
"react-star-rating": "~1.3.2",
|
"react-router": "^2.4.1",
|
||||||
"react-textarea-autosize": "^2.5.2",
|
"react-router-bootstrap": "^0.23.0",
|
||||||
|
"react-star-rating": "^1.4.2",
|
||||||
|
"react-textarea-autosize": "^4.0.2",
|
||||||
"react-transform-hmr": "^1.0.4",
|
"react-transform-hmr": "^1.0.4",
|
||||||
"remove-trailing-slash": "^0.1.0",
|
"remove-trailing-slash": "^0.1.0",
|
||||||
"resolve-url-loader": "^1.4.3",
|
"resolve-url-loader": "^1.4.3",
|
||||||
|
@ -20,6 +20,10 @@ config.entry.unshift(`webpack-dev-server/client?http://${HOST}:${PORT}/`,
|
|||||||
'webpack/hot/dev-server');
|
'webpack/hot/dev-server');
|
||||||
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
||||||
|
|
||||||
|
// Set absolute url for public path to avoid OTS parsing errors in Chrome
|
||||||
|
// See http://stackoverflow.com/questions/34133808/webpack-ots-parsing-error-loading-fonts
|
||||||
|
config.output.publicPath = `http://${HOST}:${PORT}${config.output.publicPath}`;
|
||||||
|
|
||||||
// Configure server
|
// Configure server
|
||||||
const compiler = webpack(config);
|
const compiler = webpack(config);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user