mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
Merge branch 'AD-456-ikonotv-branded-page-for-registra' into AD-957-custom-upload-button-for-contract
This commit is contained in:
commit
497a330e1a
@ -1,47 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import OwnershipFetcher from '../fetchers/ownership_fetcher';
|
||||
|
||||
|
||||
class ContractActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updateContract',
|
||||
'flushContract'
|
||||
);
|
||||
}
|
||||
|
||||
fetchContract(email) {
|
||||
if(email.match(/.+\@.+\..+/)) {
|
||||
OwnershipFetcher.fetchContract(email)
|
||||
.then((contracts) => {
|
||||
if (contracts && contracts.length > 0) {
|
||||
this.actions.updateContract({
|
||||
contractKey: contracts[0].s3Key,
|
||||
contractUrl: contracts[0].s3Url,
|
||||
contractEmail: email
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.actions.updateContract({
|
||||
contractKey: null,
|
||||
contractUrl: null,
|
||||
contractEmail: null
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
this.actions.updateContract({
|
||||
contractKey: null,
|
||||
contractUrl: null,
|
||||
contractEmail: null
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default alt.createActions(ContractActions);
|
94
js/actions/contract_agreement_list_actions.js
Normal file
94
js/actions/contract_agreement_list_actions.js
Normal file
@ -0,0 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import Q from 'q';
|
||||
|
||||
import OwnershipFetcher from '../fetchers/ownership_fetcher';
|
||||
import ContractListActions from './contract_list_actions';
|
||||
|
||||
class ContractAgreementListActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updateContractAgreementList',
|
||||
'flushContractAgreementList'
|
||||
);
|
||||
}
|
||||
|
||||
fetchContractAgreementList(issuer, accepted, pending) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
this.actions.updateContractAgreementList(null);
|
||||
OwnershipFetcher.fetchContractAgreementList(issuer, accepted, pending)
|
||||
.then((contractAgreementList) => {
|
||||
if (contractAgreementList.count > 0) {
|
||||
this.actions.updateContractAgreementList(contractAgreementList.results);
|
||||
resolve(contractAgreementList.results);
|
||||
}
|
||||
else{
|
||||
resolve(null);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
fetchAvailableContractAgreementList(issuer){
|
||||
return Q.Promise((resolve, reject) => {
|
||||
this.actions.fetchContractAgreementList(issuer, true, null)
|
||||
.then((contractAgreementListAccepted) => {
|
||||
if (!contractAgreementListAccepted) {
|
||||
// fetch pending agreements if no accepted ones
|
||||
return this.actions.fetchContractAgreementList(issuer, null, true);
|
||||
}
|
||||
else {
|
||||
resolve(contractAgreementListAccepted);
|
||||
}
|
||||
}).then((contractAgreementListPending) => {
|
||||
resolve(contractAgreementListPending);
|
||||
}).catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createContractAgreementFromPublicContract(issuer){
|
||||
ContractListActions.fetchContractList(null, null, issuer)
|
||||
.then((publicContract) => {
|
||||
// create an agreement with the public contract if there is one
|
||||
if (publicContract && publicContract.length > 0) {
|
||||
return this.actions.createContractAgreement(null, publicContract[0]);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
contractAgreementList in the store is already set to null;
|
||||
*/
|
||||
}
|
||||
}).then((publicContracAgreement) => {
|
||||
if (publicContracAgreement) {
|
||||
this.actions.updateContractAgreementList([publicContracAgreement]);
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
|
||||
createContractAgreement(issuer, contract){
|
||||
return Q.Promise((resolve, reject) => {
|
||||
OwnershipFetcher.createContractAgreement(issuer, contract).then(
|
||||
(contractAgreement) => {
|
||||
resolve(contractAgreement);
|
||||
}
|
||||
).catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default alt.createActions(ContractAgreementListActions);
|
@ -12,14 +12,18 @@ class ContractListActions {
|
||||
);
|
||||
}
|
||||
|
||||
fetchContractList(isActive) {
|
||||
OwnershipFetcher.fetchContractList(isActive)
|
||||
fetchContractList(isActive, isPublic, issuer) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
OwnershipFetcher.fetchContractList(isActive, isPublic, issuer)
|
||||
.then((contracts) => {
|
||||
this.actions.updateContractList(contracts.results);
|
||||
resolve(contracts.results);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
this.actions.updateContractList([]);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -20,21 +20,28 @@ let AclProxy = React.createClass({
|
||||
show: React.PropTypes.bool
|
||||
},
|
||||
|
||||
render() {
|
||||
if(this.props.show) {
|
||||
getChildren() {
|
||||
if (React.Children.count(this.props.children) > 1){
|
||||
/*
|
||||
This might ruin styles for header items in the navbar etc
|
||||
*/
|
||||
return (
|
||||
<span>
|
||||
{this.props.children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
/* can only do this when there is only 1 child, but will preserve styles */
|
||||
return this.props.children;
|
||||
},
|
||||
|
||||
render() {
|
||||
if(this.props.show) {
|
||||
return this.getChildren();
|
||||
} else {
|
||||
if(this.props.aclObject) {
|
||||
if(this.props.aclObject[this.props.aclName]) {
|
||||
return (
|
||||
<span>
|
||||
{this.props.children}
|
||||
</span>
|
||||
);
|
||||
return this.getChildren();
|
||||
} else {
|
||||
/* if(typeof this.props.aclObject[this.props.aclName] === 'undefined') {
|
||||
console.warn('The aclName you\'re filtering for was not present (or undefined) in the aclObject.');
|
||||
|
@ -14,7 +14,7 @@ import CoaActions from '../../actions/coa_actions';
|
||||
import CoaStore from '../../stores/coa_store';
|
||||
import PieceListActions from '../../actions/piece_list_actions';
|
||||
import PieceListStore from '../../stores/piece_list_store';
|
||||
import EditionListActions from '../../actions/edition_list_actions';;
|
||||
import EditionListActions from '../../actions/edition_list_actions';
|
||||
|
||||
import HistoryIterator from './history_iterator';
|
||||
|
||||
|
@ -35,7 +35,7 @@ let ContractAgreementForm = React.createClass({
|
||||
|
||||
componentDidMount() {
|
||||
ContractListStore.listen(this.onChange);
|
||||
ContractListActions.fetchContractList({is_active: 'True'});
|
||||
ContractListActions.fetchContractList({is_active: true});
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -45,7 +45,7 @@ let CreateContractForm = React.createClass({
|
||||
},
|
||||
|
||||
handleCreateSuccess(response) {
|
||||
ContractListActions.fetchContractList({is_active: 'True'});
|
||||
ContractListActions.fetchContractList({is_active: true});
|
||||
let notification = new GlobalNotificationModel(getLangText('Contract %s successfully created', response.name), 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
this.refs.form.reset();
|
||||
|
@ -12,11 +12,12 @@ import InputTextAreaToggable from './input_textarea_toggable';
|
||||
import InputDate from './input_date';
|
||||
import InputCheckbox from './input_checkbox';
|
||||
|
||||
import ContractStore from '../../stores/contract_store';
|
||||
import ContractActions from '../../actions/contract_actions';
|
||||
import ContractAgreementListStore from '../../stores/contract_agreement_list_store';
|
||||
import ContractAgreementListActions from '../../actions/contract_agreement_list_actions';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
|
||||
@ -48,40 +49,74 @@ let LoanForm = React.createClass({
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return ContractStore.getState();
|
||||
return ContractAgreementListStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
ContractStore.listen(this.onChange);
|
||||
ContractActions.flushContract.defer();
|
||||
ContractAgreementListStore.listen(this.onChange);
|
||||
this.getContractAgreementsOrCreatePublic(this.props.email);
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// however, it can also be that at the time the component is mounting,
|
||||
// the email is not defined (because it's asynchronously fetched from the server).
|
||||
// Then we need to update it as soon as it is included into LoanForm's props.
|
||||
if(nextProps && nextProps.email) {
|
||||
this.getContractAgreementsOrCreatePublic(nextProps.email);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
ContractStore.unlisten(this.onChange);
|
||||
ContractAgreementListStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getContractAgreementsOrCreatePublic(email){
|
||||
ContractAgreementListActions.flushContractAgreementList();
|
||||
if (email) {
|
||||
ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
|
||||
(contractAgreementList) => {
|
||||
if (!contractAgreementList) {
|
||||
ContractAgreementListActions.createContractAgreementFromPublicContract(email);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getFormData(){
|
||||
return this.props.id;
|
||||
return mergeOptions(
|
||||
this.props.id,
|
||||
this.getContractAgreementId()
|
||||
);
|
||||
},
|
||||
|
||||
handleOnChange(event) {
|
||||
// event.target.value is the submitted email of the loanee
|
||||
if(event && event.target && event.target.value && event.target.value.match(/.*@.*/)) {
|
||||
ContractActions.fetchContract(event.target.value);
|
||||
if(event && event.target && event.target.value && event.target.value.match(/.*@.*\..*/)) {
|
||||
this.getContractAgreementsOrCreatePublic(event.target.value);
|
||||
} else {
|
||||
ContractActions.flushContract();
|
||||
ContractAgreementListActions.flushContractAgreementList();
|
||||
}
|
||||
},
|
||||
|
||||
getContractAgreementId() {
|
||||
if (this.state.contractAgreementList && this.state.contractAgreementList.length > 0) {
|
||||
return {'contract_agreement_id': this.state.contractAgreementList[0].id};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getContractCheckbox() {
|
||||
if(this.state.contractKey && this.state.contractUrl) {
|
||||
if(this.state.contractAgreementList && this.state.contractAgreementList.length > 0) {
|
||||
// we need to define a key on the InputCheckboxes as otherwise
|
||||
// react is not rerendering them on a store switch and is keeping
|
||||
// the default value of the component (which is in that case true)
|
||||
let contract = this.state.contractAgreementList[0].contract;
|
||||
|
||||
return (
|
||||
<Property
|
||||
name="terms"
|
||||
@ -92,8 +127,8 @@ let LoanForm = React.createClass({
|
||||
defaultChecked={false}>
|
||||
<span>
|
||||
{getLangText('I agree to the')}
|
||||
<a href={this.state.contractUrl} target="_blank">
|
||||
{getLangText('terms of')} {this.state.contractEmail}
|
||||
<a href={contract.blob.url_safe} target="_blank">
|
||||
{getLangText('terms of ')} {contract.issuer}
|
||||
</a>
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
@ -157,8 +192,8 @@ let LoanForm = React.createClass({
|
||||
<Property
|
||||
name='loanee'
|
||||
label={getLangText('Loanee Email')}
|
||||
onChange={this.handleOnChange}
|
||||
editable={!this.props.email}
|
||||
onBlur={this.handleOnChange}
|
||||
overrideForm={!!this.props.email}>
|
||||
<input
|
||||
value={this.props.email}
|
||||
|
@ -28,7 +28,7 @@ let ContractSettings = React.createClass({
|
||||
|
||||
componentDidMount() {
|
||||
ContractListStore.listen(this.onChange);
|
||||
ContractListActions.fetchContractList({is_active: 'True'});
|
||||
ContractListActions.fetchContractList({is_active: true});
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -44,7 +44,7 @@ let ContractSettings = React.createClass({
|
||||
contract.is_public = true;
|
||||
ContractListActions.changeContract(contract)
|
||||
.then(() => {
|
||||
ContractListActions.fetchContractList({is_active: 'True'});
|
||||
ContractListActions.fetchContractList({is_active: true});
|
||||
let notification = getLangText('Contract %s is now public', contract.name);
|
||||
notification = new GlobalNotificationModel(notification, 'success', 4000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
@ -60,7 +60,7 @@ let ContractSettings = React.createClass({
|
||||
return () => {
|
||||
ContractListActions.removeContract(contract.id)
|
||||
.then((response) => {
|
||||
ContractListActions.fetchContractList({is_active: 'True'});
|
||||
ContractListActions.fetchContractList({is_active: true});
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success', 4000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
})
|
||||
|
@ -141,7 +141,7 @@ let Header = React.createClass({
|
||||
<MenuItemLink eventKey="3" to="logout">{getLangText('Log out')}</MenuItemLink>
|
||||
</DropdownButton>
|
||||
);
|
||||
navRoutesLinks = <NavRoutesLinks routes={this.props.routes} navbar right/>;
|
||||
navRoutesLinks = <NavRoutesLinks routes={this.props.routes} userAcl={this.state.currentUser.acl} navbar right/>;
|
||||
}
|
||||
else {
|
||||
account = <NavItemLink to="login">{getLangText('LOGIN')}</NavItemLink>;
|
||||
|
@ -3,53 +3,80 @@
|
||||
import React from 'react';
|
||||
|
||||
import Nav from 'react-bootstrap/lib/Nav';
|
||||
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||
import MenuItemLink from 'react-router-bootstrap/lib/MenuItemLink';
|
||||
import NavItemLink from 'react-router-bootstrap/lib/NavItemLink';
|
||||
|
||||
import NavRoutesLinksLink from './nav_routes_links_link';
|
||||
|
||||
import AclProxy from './acl_proxy';
|
||||
|
||||
import { sanitizeList } from '../utils/general_utils';
|
||||
|
||||
|
||||
let NavRoutesLinks = React.createClass({
|
||||
propTypes: {
|
||||
routes: React.PropTypes.element
|
||||
routes: React.PropTypes.element,
|
||||
userAcl: React.PropTypes.object
|
||||
},
|
||||
|
||||
extractLinksFromRoutes(node, i) {
|
||||
/**
|
||||
* This method generales a bunch of react-bootstrap specific links
|
||||
* from the routes we defined in one of the specific routes.js file
|
||||
*
|
||||
* We can define a headerTitle as well as a aclName and according to that the
|
||||
* link will be created for a specific user
|
||||
* @param {ReactElement} node Starts at the very top of a routes files root
|
||||
* @param {object} userAcl ACL object we use throughout the whole app
|
||||
* @param {number} i Depth of the route in comparison to the root
|
||||
* @return {Array} Array of ReactElements that can be displayed to the user
|
||||
*/
|
||||
extractLinksFromRoutes(node, userAcl, i) {
|
||||
if(!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
node = node.props;
|
||||
let links = node.props.children.map((child, j) => {
|
||||
let childrenFn = null;
|
||||
let { aclName, headerTitle, name, children } = child.props;
|
||||
|
||||
let links = node.children.map((child, j) => {
|
||||
|
||||
// check if this a candidate for a link generation
|
||||
if(child.props.headerTitle && typeof child.props.headerTitle === 'string') {
|
||||
|
||||
// also check if it is a candidate for generating a dropdown menu
|
||||
// If the node has children that could be rendered, then we want
|
||||
// to execute this function again with the child as the root
|
||||
//
|
||||
// Otherwise we'll just pass childrenFn as false
|
||||
if(child.props.children && child.props.children.length > 0) {
|
||||
childrenFn = this.extractLinksFromRoutes(child, userAcl, i++);
|
||||
}
|
||||
|
||||
// We validate if the user has set the title correctly,
|
||||
// otherwise we're not going to render his route
|
||||
if(headerTitle && typeof headerTitle === 'string') {
|
||||
// if there is an aclName present on the route definition,
|
||||
// we evaluate it against the user's acl
|
||||
if(aclName && typeof aclName !== 'undefined') {
|
||||
return (
|
||||
<DropdownButton title={child.props.headerTitle} key={j}>
|
||||
{this.extractLinksFromRoutes(child, i++)}
|
||||
</DropdownButton>
|
||||
);
|
||||
} else if(i === 1) {
|
||||
// if the node's child is actually a node of level one (a child of a node), we're
|
||||
// returning a DropdownButton matching MenuItemLink
|
||||
return (
|
||||
<MenuItemLink to={child.props.name} key={j}>{child.props.headerTitle}</MenuItemLink>
|
||||
);
|
||||
} else if(i === 0) {
|
||||
return (
|
||||
<NavItemLink to={child.props.name} key={j}>{child.props.headerTitle}</NavItemLink>
|
||||
<AclProxy
|
||||
key={j}
|
||||
aclName={aclName}
|
||||
aclObject={this.props.userAcl}>
|
||||
<NavRoutesLinksLink
|
||||
headerTitle={headerTitle}
|
||||
routeName={name}
|
||||
depth={i}
|
||||
children={childrenFn}/>
|
||||
</AclProxy>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
return (
|
||||
<NavRoutesLinksLink
|
||||
key={j}
|
||||
headerTitle={headerTitle}
|
||||
routeName={name}
|
||||
depth={i}
|
||||
children={childrenFn}/>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// remove all nulls from the list of generated links
|
||||
@ -57,9 +84,11 @@ let NavRoutesLinks = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
let {routes, userAcl} = this.props;
|
||||
|
||||
return (
|
||||
<Nav {...this.props}>
|
||||
{this.extractLinksFromRoutes(this.props.routes, 0)}
|
||||
{this.extractLinksFromRoutes(routes, userAcl, 0)}
|
||||
</Nav>
|
||||
);
|
||||
}
|
||||
|
51
js/components/nav_routes_links_link.js
Normal file
51
js/components/nav_routes_links_link.js
Normal file
@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||
import MenuItemLink from 'react-router-bootstrap/lib/MenuItemLink';
|
||||
import NavItemLink from 'react-router-bootstrap/lib/NavItemLink';
|
||||
|
||||
let NavRoutesLinksLink = React.createClass({
|
||||
propTypes: {
|
||||
headerTitle: React.PropTypes.string,
|
||||
routeName: React.PropTypes.string,
|
||||
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||
React.PropTypes.element
|
||||
]),
|
||||
|
||||
depth: React.PropTypes.number
|
||||
},
|
||||
|
||||
render() {
|
||||
let { children, headerTitle, depth, routeName } = this.props;
|
||||
|
||||
// if the route has children, we're returning a DropdownButton that will get filled
|
||||
// with MenuItemLinks
|
||||
if(children) {
|
||||
return (
|
||||
<DropdownButton title={headerTitle}>
|
||||
{children}
|
||||
</DropdownButton>
|
||||
);
|
||||
} else {
|
||||
if(depth === 1) {
|
||||
// if the node's child is actually a node of level one (a child of a node), we're
|
||||
// returning a DropdownButton matching MenuItemLink
|
||||
return (
|
||||
<MenuItemLink to={routeName}>{headerTitle}</MenuItemLink>
|
||||
);
|
||||
} else if(depth === 0) {
|
||||
return (
|
||||
<NavItemLink to={routeName}>{headerTitle}</NavItemLink>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default NavRoutesLinksLink;
|
@ -222,21 +222,7 @@ let CylandRegisterPiece = React.createClass({
|
||||
showStartDate={false}
|
||||
showEndDate={false}
|
||||
showPersonalMessage={false}
|
||||
handleSuccess={this.handleLoanSuccess}>
|
||||
<Property
|
||||
name="terms"
|
||||
className="ascribe-settings-property-collapsible-toggle"
|
||||
style={{paddingBottom: 0}}>
|
||||
<InputCheckbox>
|
||||
<span>
|
||||
{' ' + getLangText('I agree to the Terms of Service of Cyland Archive') + ' '}
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/cyland/terms_and_contract.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
{getLangText('read')}
|
||||
</a>)
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
</Property>
|
||||
</LoanForm>
|
||||
handleSuccess={this.handleLoanSuccess} />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
@ -50,21 +50,7 @@ let IkonotvSubmitButton = React.createClass({
|
||||
enddate={enddate}
|
||||
gallery="IkonoTV archive"
|
||||
showPersonalMessage={false}
|
||||
handleSuccess={this.props.handleSuccess}>
|
||||
<Property
|
||||
name="terms"
|
||||
className="ascribe-settings-property-collapsible-toggle"
|
||||
style={{paddingBottom: 0}}>
|
||||
<InputCheckbox>
|
||||
<span>
|
||||
{' ' + getLangText('I agree to the Terms of Service of IkonoTV Archive') + ' '}
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/ikonotv/ikono-tos.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
{getLangText('read')}
|
||||
</a>)
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
</Property>
|
||||
</LoanForm>
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
</ModalWrapper>
|
||||
|
||||
);
|
||||
|
@ -8,7 +8,6 @@ import UserStore from '../../../../../stores/user_store';
|
||||
|
||||
import IkonotvAccordionListItem from './ascribe_accordion_list/ikonotv_accordion_list_item';
|
||||
|
||||
|
||||
let IkonotvPieceList = React.createClass({
|
||||
getInitialState() {
|
||||
return UserStore.getState();
|
||||
|
@ -14,7 +14,8 @@ function getWalletApiUrls(subdomain) {
|
||||
else if (subdomain === 'ikonotv'){
|
||||
return {
|
||||
'pieces_list': walletConstants.walletApiEndpoint + subdomain + '/pieces/',
|
||||
'piece': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/'
|
||||
'piece': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/',
|
||||
'user': walletConstants.walletApiEndpoint + subdomain + '/users/'
|
||||
};
|
||||
}
|
||||
return {};
|
||||
|
@ -72,7 +72,7 @@ let ROUTES = {
|
||||
<Route name="logout" path="logout" handler={LogoutContainer} />
|
||||
<Route name="signup" path="signup" handler={SignupContainer} />
|
||||
<Route name="password_reset" path="password_reset" handler={PasswordResetContainer} />
|
||||
<Route name="request_loan" path="request_loan" handler={IkonotvRequestLoan} headerTitle="SEND NEW CONTRACT" />
|
||||
<Route name="request_loan" path="request_loan" handler={IkonotvRequestLoan} headerTitle="SEND NEW CONTRACT" aclName="acl_send_contract" />
|
||||
<Route name="register_piece" path="register_piece" handler={RegisterPiece} headerTitle="+ NEW WORK"/>
|
||||
<Route name="pieces" path="collection" handler={IkonotvPieceList} headerTitle="COLLECTION"/>
|
||||
<Route name="piece" path="pieces/:pieceId" handler={IkonotvPieceContainer} />
|
||||
|
@ -15,8 +15,33 @@ let OwnershipFetcher = {
|
||||
/**
|
||||
* Fetch the contracts of the logged-in user from the API.
|
||||
*/
|
||||
fetchContractList(isActive){
|
||||
return requests.get(ApiUrls.ownership_contract_list, isActive);
|
||||
fetchContractList(isActive, isPublic, issuer){
|
||||
let queryParams = {
|
||||
isActive,
|
||||
isPublic,
|
||||
issuer
|
||||
};
|
||||
return requests.get(ApiUrls.ownership_contract_list, queryParams);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Create a contractagreement between the logged-in user and the email from the API with contract.
|
||||
*/
|
||||
createContractAgreement(signee, contractObj){
|
||||
return requests.post(ApiUrls.ownership_contract_agreements, { body: {signee: signee, contract: contractObj.id }});
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the contractagreement between the logged-in user and the email from the API.
|
||||
*/
|
||||
fetchContractAgreementList(issuer, accepted, pending) {
|
||||
let queryParams = {
|
||||
issuer,
|
||||
accepted,
|
||||
pending
|
||||
};
|
||||
return requests.get(ApiUrls.ownership_contract_agreements, queryParams);
|
||||
},
|
||||
|
||||
fetchLoanPieceRequestList(){
|
||||
|
22
js/stores/contract_agreement_list_store.js
Normal file
22
js/stores/contract_agreement_list_store.js
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import ContractAgreementListActions from '../actions/contract_agreement_list_actions';
|
||||
|
||||
|
||||
class ContractAgreementListStore {
|
||||
constructor() {
|
||||
this.contractAgreementList = null;
|
||||
this.bindActions(ContractAgreementListActions);
|
||||
}
|
||||
|
||||
onUpdateContractAgreementList(contractAgreementList) {
|
||||
this.contractAgreementList = contractAgreementList;
|
||||
}
|
||||
|
||||
onFlushContractAgreementList() {
|
||||
this.contractAgreementList = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createStore(ContractAgreementListStore, 'ContractAgreementListStore');
|
@ -1,28 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import ContractActions from '../actions/contract_actions';
|
||||
|
||||
|
||||
class ContractStore {
|
||||
constructor() {
|
||||
this.contractKey = null;
|
||||
this.contractUrl = null;
|
||||
this.contractEmail = null;
|
||||
this.bindActions(ContractActions);
|
||||
}
|
||||
|
||||
onUpdateContract({contractKey, contractUrl, contractEmail}) {
|
||||
this.contractKey = contractKey;
|
||||
this.contractUrl = contractUrl;
|
||||
this.contractEmail = contractEmail;
|
||||
}
|
||||
|
||||
onFlushContract() {
|
||||
this.contractKey = null;
|
||||
this.contractUrl = null;
|
||||
this.contractEmail = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createStore(ContractStore, 'ContractStore');
|
@ -122,6 +122,34 @@ hr {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/questions/22228239/bootstrap-navbar-static-top-menu-breaks-on-two-lines
|
||||
@media (max-width: 990px) {
|
||||
.navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.navbar-toggle {
|
||||
display: block;
|
||||
}
|
||||
.navbar-collapse {
|
||||
border-top: 1px solid transparent;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
|
||||
}
|
||||
.navbar-collapse.collapse {
|
||||
display: none!important;
|
||||
}
|
||||
.navbar-nav {
|
||||
float: none!important;
|
||||
margin: 7.5px -15px;
|
||||
}
|
||||
.navbar-nav>li {
|
||||
float: none;
|
||||
}
|
||||
.navbar-nav>li>a {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
Loading…
Reference in New Issue
Block a user