From b29bf38f1344ede45c9371400dc585dc10c90b77 Mon Sep 17 00:00:00 2001 From: diminator Date: Tue, 15 Sep 2015 13:15:29 +0200 Subject: [PATCH 1/7] ikono slides --- .../cyland/cyland_register_piece.js | 5 +- .../ascribe_buttons/ikonotv_submit_button.js | 58 ++--- .../ikonotv_additional_data_form.js | 134 +++++++++++ .../ikonotv/ikonotv_register_piece.js | 220 ++++++++++++++++++ .../whitelabel/wallet/wallet_routes.js | 3 +- 5 files changed, 378 insertions(+), 42 deletions(-) create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js diff --git a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js index 6e8a77c3..84713bd9 100644 --- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js +++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js @@ -10,9 +10,6 @@ import Row from 'react-bootstrap/lib/Row'; import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; -import Property from '../../../../ascribe_forms/property'; -import InputCheckbox from '../../../../ascribe_forms/input_checkbox'; - import WhitelabelActions from '../../../../../actions/whitelabel_actions'; import WhitelabelStore from '../../../../../stores/whitelabel_store'; @@ -136,7 +133,7 @@ let CylandRegisterPiece = React.createClass({ this.transitionTo('piece', {pieceId: this.state.piece.id}); }, - // We need to increase the step to lock the forms that are already filed out + // We need to increase the step to lock the forms that are already filled out incrementStep() { // also increase step let newStep = this.state.step + 1; diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js index 4b7f3dbc..be3bda77 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js @@ -1,17 +1,8 @@ 'use strict'; import React from 'react'; -import Moment from 'moment'; import classNames from 'classnames'; - -import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper'; - -import LoanForm from '../../../../../ascribe_forms/form_loan'; - -import Property from '../../../../../ascribe_forms/property'; -import InputCheckbox from '../../../../../ascribe_forms/input_checkbox'; - -import ApiUrls from '../../../../../../constants/api_urls'; +import ButtonLink from 'react-router-bootstrap/lib/ButtonLink'; import { getLangText } from '../../../../../../utils/lang_utils'; @@ -22,37 +13,30 @@ let IkonotvSubmitButton = React.createClass({ piece: React.PropTypes.object.isRequired }, - getSubmitButton() { - return ( - - ); - }, - render() { + let piece = this.props.piece; + let startFrom = 1; - let today = new Moment(); - let enddate = new Moment(); - enddate.add(1, 'years'); + // In the Ikonotv loan page a user has to complete two steps. + // Since every one of those steps is atomic a user should always be able to continue + // where he left of. + // This is why we start the process form slide 1/2 if the user has already finished + // it in another session. + if(piece && piece.extra_data && Object.keys(piece.extra_data).length > 0) { + startFrom = 1; + } return ( - - - - + + {getLangText('Loan to IkonoTV')} + ); } }); diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js new file mode 100644 index 00000000..6a2f8cc5 --- /dev/null +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js @@ -0,0 +1,134 @@ +'use strict'; + +import React from 'react'; + +import Form from '../../../../../ascribe_forms/form'; +import Property from '../../../../../ascribe_forms/property'; + +import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable'; + +import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader'; + +import ApiUrls from '../../../../../../constants/api_urls'; +import AppConstants from '../../../../../../constants/application_constants'; + +import requests from '../../../../../../utils/requests'; + +import { getLangText } from '../../../../../../utils/lang_utils'; +import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils'; + + +let IkonotvAdditionalDataForm = React.createClass({ + propTypes: { + handleSuccess: React.PropTypes.func.isRequired, + piece: React.PropTypes.object.isRequired, + + disabled: React.PropTypes.bool + }, + + getInitialState() { + return { + isUploadReady: true + }; + }, + + getFormData() { + let extradata = {}; + let formRefs = this.refs.form.refs; + + // Put additional fields in extra data object + Object + .keys(formRefs) + .forEach((fieldName) => { + extradata[fieldName] = formRefs[fieldName].state.value; + }); + + return { + extradata: extradata, + piece_id: this.props.piece.id + }; + + }, + + uploadStarted() { + this.setState({ + isUploadReady: false + }); + }, + + setIsUploadReady(isReady) { + this.setState({ + isUploadReady: isReady + }); + }, + + render() { + if(this.props.piece && this.props.piece.id) { + return ( +
+ {getLangText('Proceed to loan')} + + } + spinner={ +
+ +
+ }> +
+

+ {getLangText('Provide supporting materials')} +

+
+ + + + + + + + + ); + } else { + return ( +
+ +
+ ); + } + } +}); + +export default IkonotvAdditionalDataForm; \ No newline at end of file diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js new file mode 100644 index 00000000..6a2acbb8 --- /dev/null +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js @@ -0,0 +1,220 @@ +'use strict'; + +import React from 'react'; +import Moment from 'moment'; +import Router from 'react-router'; + +import Col from 'react-bootstrap/lib/Col'; +import Row from 'react-bootstrap/lib/Row'; + +import PieceListStore from '../../../../../stores/piece_list_store'; +import PieceListActions from '../../../../../actions/piece_list_actions'; + +import UserStore from '../../../../../stores/user_store'; +import UserActions from '../../../../../actions/user_actions'; + +import PieceStore from '../../../../../stores/piece_store'; +import PieceActions from '../../../../../actions/piece_actions'; + +import GlobalNotificationModel from '../../../../../models/global_notification_model'; +import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; + +import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; +import LoanForm from '../../../../ascribe_forms/form_loan'; +import IkonotvAdditionalDataForm from './ascribe_forms/ikonotv_additional_data_form'; + +import SlidesContainer from '../../../../ascribe_slides_container/slides_container'; + +import ApiUrls from '../../../../../constants/api_urls'; + +import { mergeOptions } from '../../../../../utils/general_utils'; +import { getLangText } from '../../../../../utils/lang_utils'; + +let IkonotvRegisterPiece = React.createClass({ + + propTypes: { + handleSuccess: React.PropTypes.func, + piece: React.PropTypes.object.isRequired + }, + + mixins: [Router.Navigation, Router.State], + + getInitialState(){ + return mergeOptions( + UserStore.getState(), + PieceListStore.getState(), + PieceStore.getState(), + { + step: 0 + }); + }, + + componentDidMount() { + PieceListStore.listen(this.onChange); + UserStore.listen(this.onChange); + PieceStore.listen(this.onChange); + UserActions.fetchCurrentUser(); + + let queryParams = this.getQuery(); + + // Since every step of this register process is atomic, + // 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. + // It is encoded in the URL as a queryParam and we're checking for it here. + // + // 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. + if (queryParams && 'piece_id' in queryParams) { + PieceActions.fetchOne(queryParams.piece_id); + } + }, + + componentWillUnmount() { + PieceListStore.unlisten(this.onChange); + UserStore.unlisten(this.onChange); + PieceStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + + if(this.state.currentUser && this.state.currentUser.email) { + // we should also make the fineuploader component editable again + this.setState({ + isFineUploaderActive: true + }); + } + }, + + + handleRegisterSuccess(response){ + + this.refreshPieceList(); + + // also start loading the piece for the next step + if(response && response.piece) { + PieceActions.updatePiece(response.piece); + } + + this.incrementStep(); + + this.refs.slidesContainer.nextSlide(); + }, + + handleAdditionalDataSuccess() { + + // We need to refetch the piece again after submitting the additional data + // since we want it's otherData to be displayed when the user choses to click + // on the browsers back button. + PieceActions.fetchOne(this.state.piece.id); + + this.refreshPieceList(); + + this.incrementStep(); + + this.refs.slidesContainer.nextSlide(); + }, + + handleLoanSuccess(response) { + let notification = new GlobalNotificationModel(response.notification, 'success', 10000); + GlobalNotificationActions.appendGlobalNotification(notification); + + this.refreshPieceList(); + + PieceActions.fetchOne(this.state.piece.id); + this.transitionTo('piece', {pieceId: this.state.piece.id}); + }, + + // We need to increase the step to lock the forms that are already filled out + incrementStep() { + // also increase step + let newStep = this.state.step + 1; + this.setState({ + step: newStep + }); + }, + + refreshPieceList() { + PieceListActions.fetchPieceList( + this.state.page, + this.state.pageSize, + this.state.searchTerm, + this.state.orderBy, + this.state.orderAsc, + this.state.filterBy + ); + }, + + changeSlide() { + // only transition to the login store, if user is not logged in + // ergo the currentUser object is not properly defined + if(this.state.currentUser && !this.state.currentUser.email) { + this.onLoggedOut(); + } + }, + + // basically redirects to the second slide (index: 1), when the user is not logged in + onLoggedOut() { + this.transitionTo('login'); + }, + + render() { + + let today = new Moment(); + let enddate = new Moment(); + enddate.add(1, 'years'); + + return ( + +
+ + + 0} + enableLocalHashing={false} + headerMessage={getLangText('Submit to Cyland Archive')} + submitMessage={getLangText('Submit')} + isFineUploaderActive={this.state.isFineUploaderActive} + handleSuccess={this.handleRegisterSuccess} + onLoggedOut={this.onLoggedOut} /> + + +
+
+ + + 1} + handleSuccess={this.handleAdditionalDataSuccess} + piece={this.state.piece}/> + + +
+
+ + + + + +
+
+ ); + } +}); + +export default IkonotvRegisterPiece; diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js index 25fc1d80..6dd1ed24 100644 --- a/js/components/whitelabel/wallet/wallet_routes.js +++ b/js/components/whitelabel/wallet/wallet_routes.js @@ -21,6 +21,7 @@ import CylandPieceList from './components/cyland/cyland_piece_list'; import IkonotvPieceList from './components/ikonotv/ikonotv_piece_list'; import IkonotvRequestLoan from './components/ikonotv/ikonotv_request_loan'; +import IkonotvRegisterPiece from './components/ikonotv/ikonotv_register_piece'; import IkonotvPieceContainer from './components/ikonotv/ascribe_detail/ikonotv_piece_container'; import IkonotvContractNotifications from './components/ikonotv/ikonotv_contract_notifications'; @@ -73,7 +74,7 @@ let ROUTES = { - + From d6bd4b4ac1914ced446795695f9efd85acd9f20d Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 16 Sep 2015 14:07:13 +0200 Subject: [PATCH 2/7] bug fix acl button form copyright association + account settings bug fix dispatch in form loan ikonotv slides --- js/actions/contract_agreement_list_actions.js | 11 +++ js/components/ascribe_buttons/acl_button.js | 33 +++---- .../ascribe_forms/form_contract_agreement.js | 89 +++++++++++-------- .../form_copyright_association.js | 75 ++++++++++++++++ js/components/ascribe_forms/form_loan.js | 23 ++--- .../ascribe_settings/account_settings.js | 3 + .../ikonotv_additional_data_form.js | 13 +-- .../ikonotv/ikonotv_contract_notifications.js | 83 +++++++++-------- js/constants/application_constants.js | 6 +- 9 files changed, 221 insertions(+), 115 deletions(-) create mode 100644 js/components/ascribe_forms/form_copyright_association.js diff --git a/js/actions/contract_agreement_list_actions.js b/js/actions/contract_agreement_list_actions.js index 86988f47..f2959901 100644 --- a/js/actions/contract_agreement_list_actions.js +++ b/js/actions/contract_agreement_list_actions.js @@ -89,6 +89,17 @@ class ContractAgreementListActions { }); } + flushContractAgreementList(){ + return Q.Promise((resolve, reject) => { + this.actions.updateContractAgreementList(null).then( + resolve() + ).catch((err) => { + console.logGlobal(err); + reject(err); + }); + }); + } + } export default alt.createActions(ContractAgreementListActions); diff --git a/js/components/ascribe_buttons/acl_button.js b/js/components/ascribe_buttons/acl_button.js index 084de194..e3c7fa1c 100644 --- a/js/components/ascribe_buttons/acl_button.js +++ b/js/components/ascribe_buttons/acl_button.js @@ -162,21 +162,24 @@ let AclButton = React.createClass({ }, render() { - let shouldDisplay = this.props.availableAcls[this.props.action]; - let aclProps = this.actionProperties(); - let buttonClassName = this.props.buttonAcceptClassName ? this.props.buttonAcceptClassName : ''; - return ( - - {this.sanitizeAction()} - - } - handleSuccess={aclProps.handleSuccess} - title={aclProps.title}> - {aclProps.form} - - ); + if (this.props.availableAcls){ + let shouldDisplay = this.props.availableAcls[this.props.action]; + let aclProps = this.actionProperties(); + let buttonClassName = this.props.buttonAcceptClassName ? this.props.buttonAcceptClassName : ''; + return ( + + {this.sanitizeAction()} + + } + handleSuccess={aclProps.handleSuccess} + title={aclProps.title}> + {aclProps.form} + + ); + } + return null; } }); diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js index fb6793e6..94ab26d0 100644 --- a/js/components/ascribe_forms/form_contract_agreement.js +++ b/js/components/ascribe_forms/form_contract_agreement.js @@ -35,7 +35,7 @@ let ContractAgreementForm = React.createClass({ componentDidMount() { ContractListStore.listen(this.onChange); - ContractListActions.fetchContractList(true); + ContractListActions.fetchContractList(true, false); }, componentWillUnmount() { @@ -95,45 +95,56 @@ let ContractAgreementForm = React.createClass({ }, render() { + if (this.state.contractList && this.state.contractList.length > 0) { + return ( +
+ {getLangText('Send loan request')} + } + spinner={ + + + + }> +
+

{getLangText('Contract form')}

+
+ + + + {this.getContracts()} + + {getLangText('Appendix')} + + +
+ ); + } return ( -
- {getLangText('Send loan request')} - } - spinner={ - - - - }> -
-

{getLangText('Contract form')}

-
- - - - {this.getContracts()} - - {getLangText('Appendix')} - - -
+
+

+ {getLangText('No private contracts found, please go to the ')} + {getLangText('settings page')} + {getLangText(' and create them.')} +

+
); } }); diff --git a/js/components/ascribe_forms/form_copyright_association.js b/js/components/ascribe_forms/form_copyright_association.js new file mode 100644 index 00000000..451afb97 --- /dev/null +++ b/js/components/ascribe_forms/form_copyright_association.js @@ -0,0 +1,75 @@ +'use strict'; + +import React from 'react'; + +import GlobalNotificationModel from '../../models/global_notification_model'; +import GlobalNotificationActions from '../../actions/global_notification_actions'; + +import Form from './form'; +import Property from './property'; + +import apiUrls from '../../constants/api_urls'; +import appConstants from '../../constants/application_constants'; + +import { getLangText } from '../../utils/lang_utils'; + +let CopyrightAssociationForm = React.createClass({ + propTypes: { + currentUser: React.PropTypes.object + }, + + handleSubmitSuccess(){ + let notification = getLangText('Copyright association updated'); + notification = new GlobalNotificationModel(notification, 'success', 10000); + GlobalNotificationActions.appendGlobalNotification(notification); + }, + + getProfileFormData(){ + if (this.props.currentUser && this.props.currentUser.email){ + return {email: this.props.currentUser.email}; + } + return null; + }, + + render() { + let selectedState = -1; + if (this.props.currentUser + && this.props.currentUser.profile + && this.props.currentUser.profile.copyright_association) { + selectedState = appConstants.copyrightAssociations.indexOf(this.props.currentUser.profile.copyright_association); + } + return ( +
+ + + +
+
+ ); + } +}); + +export default CopyrightAssociationForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index dacbae77..a1c31330 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -61,7 +61,7 @@ let LoanForm = React.createClass({ // 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) { + if(nextProps && nextProps.email && this.props.email !== nextProps.email) { this.getContractAgreementsOrCreatePublic(nextProps.email); } }, @@ -75,16 +75,19 @@ let LoanForm = React.createClass({ }, getContractAgreementsOrCreatePublic(email){ - ContractAgreementListActions.flushContractAgreementList(); - if (email) { - ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( - (contractAgreementList) => { - if (!contractAgreementList) { - ContractAgreementListActions.createContractAgreementFromPublicContract(email); + /* a more complex defer (with promises) otherwise we dispatch while an action is being dispatched) */ + window.setTimeout(() => { + ContractAgreementListActions.flushContractAgreementList(); + + if (email) { + ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( + (contractAgreementList) => { + if (!contractAgreementList) { + ContractAgreementListActions.createContractAgreementFromPublicContract(email); + } } - } - ); - } + ); + }}, 0); }, getFormData(){ diff --git a/js/components/ascribe_settings/account_settings.js b/js/components/ascribe_settings/account_settings.js index b4d46b2d..93a419c2 100644 --- a/js/components/ascribe_settings/account_settings.js +++ b/js/components/ascribe_settings/account_settings.js @@ -13,6 +13,8 @@ import Property from '../ascribe_forms/property'; import InputCheckbox from '../ascribe_forms/input_checkbox'; import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph'; +import CopyrightAssociationForm from '../ascribe_forms/form_copyright_association'; + import ApiUrls from '../../constants/api_urls'; import AppConstants from '../../constants/application_constants'; @@ -117,6 +119,7 @@ let AccountSettings = React.createClass({ show={true} defaultExpanded={true}> {content} + {profile} {/*
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js index 6a2f8cc5..6f249c7b 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js @@ -7,7 +7,7 @@ import Property from '../../../../../ascribe_forms/property'; import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable'; -import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader'; +//import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader'; import ApiUrls from '../../../../../../constants/api_urls'; import AppConstants from '../../../../../../constants/application_constants'; @@ -15,7 +15,7 @@ import AppConstants from '../../../../../../constants/application_constants'; import requests from '../../../../../../utils/requests'; import { getLangText } from '../../../../../../utils/lang_utils'; -import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils'; +//import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils'; let IkonotvAdditionalDataForm = React.createClass({ @@ -110,15 +110,6 @@ let IkonotvAdditionalDataForm = React.createClass({ placeholder={getLangText('Enter a conceptual overview...')} required="required"/> - ); } else { diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js index 6a63657c..beffe23a 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js @@ -6,17 +6,18 @@ import Router from 'react-router'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; import Button from 'react-bootstrap/lib/Button'; -import Form from '../../../../ascribe_forms/form'; -import Property from '../../../../ascribe_forms/property'; -import InputCheckbox from '../../../../ascribe_forms/input_checkbox'; - import NotificationActions from '../../../../../actions/notification_actions'; import NotificationStore from '../../../../../stores/notification_store'; + +import UserStore from '../../../../../stores/user_store'; + import WhitelabelStore from '../../../../../stores/whitelabel_store'; import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; +import CopyrightAssociationForm from '../../../../ascribe_forms/form_copyright_association'; + import apiUrls from '../../../../../constants/api_urls'; import requests from '../../../../../utils/requests'; @@ -32,12 +33,14 @@ let IkonotvContractNotifications = React.createClass({ getInitialState() { return mergeOptions( NotificationStore.getState(), + UserStore.getState(), WhitelabelStore.getState() ); }, componentDidMount() { NotificationStore.listen(this.onChange); + UserStore.listen(this.onChange); WhitelabelStore.listen(this.onChange); if (this.state.contractAgreementListNotifications === null){ NotificationActions.fetchContractAgreementListNotifications(); @@ -88,7 +91,8 @@ let IkonotvContractNotifications = React.createClass({ let notifications = this.state.contractAgreementListNotifications[0]; let appendix = notifications.contract_agreement.appendix; if (appendix) { - return (
+ return ( +

{getLangText('Appendix')}

                         {appendix.default}
@@ -99,6 +103,13 @@ let IkonotvContractNotifications = React.createClass({
         return null;
     },
 
+    handleConfirm() {
+        let contractAgreement = this.state.contractAgreementListNotifications[0].contract_agreement;
+        requests.put(apiUrls.ownership_contract_agreements_confirm, {contract_agreement_id: contractAgreement.id}).then(
+            () => this.handleConfirmSuccess()
+        );
+    },
+
     handleConfirmSuccess() {
         let notification = new GlobalNotificationModel(getLangText('You have accepted the conditions'), 'success', 10000);
         GlobalNotificationActions.appendGlobalNotification(notification);
@@ -118,11 +129,29 @@ let IkonotvContractNotifications = React.createClass({
         this.transitionTo('pieces');
     },
 
+    getCopyrightAssociationForm(){
+        if (this.state.currentUser && this.state.currentUser.profile
+            && this.state.currentUser.profile.copyright_association){
+            return null;
+        }
+        return (
+            
+

{getLangText('Are you a member of any copyright societies?')}

+

+ ARS, DACS, Bildkunst, Pictoright, SODRAC, Copyright Agency/Viscopy, SAVA, Bildrecht GmbH, + SABAM, AUTVIS, CREAIMAGEN, SONECA, Copydan, EAU, Kuvasto, GCA, HUNGART, IVARO, SIAE, JASPAR-SPDA, + AKKA/LAA, LATGA-A, SOMAAP, ARTEGESTION, CARIER, BONO, APSAV, SPA, GESTOR, VISaRTA, RAO, LITA, + DALRO, VeGaP, BUS, ProLitteris, AGADU, AUTORARTE, BUBEDRA, BBDA, BCDA, BURIDA, ADAVIS, BSDA +

+ +
+ ); + }, + render() { if (this.state.contractAgreementListNotifications && this.state.contractAgreementListNotifications.length > 0) { - let contractAgreement = this.state.contractAgreementListNotifications[0].contract_agreement; return (
@@ -133,41 +162,17 @@ let IkonotvContractNotifications = React.createClass({
{this.getContract()} -
- {this.getAppendix} -

{getLangText('Are you a member of any copyright societies?')}

-

- ARS, DACS, Bildkunst, Pictoright, SODRAC, Copyright Agency/Viscopy, SAVA, Bildrecht GmbH, - SABAM, AUTVIS, CREAIMAGEN, SONECA, Copydan, EAU, Kuvasto, GCA, HUNGART, IVARO, SIAE, JASPAR-SPDA, - AKKA/LAA, LATGA-A, SOMAAP, ARTEGESTION, CARIER, BONO, APSAV, SPA, GESTOR, VISaRTA, RAO, LITA, - DALRO, VeGaP, BUS, ProLitteris, AGADU, AUTORARTE, BUBEDRA, BBDA, BCDA, BURIDA, ADAVIS, BSDA + {this.getAppendix()} + {this.getCopyrightAssociationForm()} +

+ +

-
- - -

- }> - - - - {' ' + getLangText('Yes') } - - - - -
diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index f1455029..3b3c4a9f 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -61,7 +61,11 @@ let constants = { 'whitelabel': {}, 'raven': { 'url': 'https://0955da3388c64ab29bd32c2a429f9ef4@app.getsentry.com/48351' - } + }, + 'copyrightAssociations': ['ARS', 'DACS', 'Bildkunst', 'Pictoright', 'SODRAC', 'Copyright Agency/Viscopy', 'SAVA', + 'Bildrecht GmbH', 'SABAM', 'AUTVIS', 'CREAIMAGEN', 'SONECA', 'Copydan', 'EAU', 'Kuvasto', 'GCA', 'HUNGART', + 'IVARO', 'SIAE', 'JASPAR-SPDA', 'AKKA/LAA', 'LATGA-A', 'SOMAAP', 'ARTEGESTION', 'CARIER', 'BONO', 'APSAV', + 'SPA', 'GESTOR', 'VISaRTA', 'RAO', 'LITA', 'DALRO', 'VeGaP', 'BUS', 'ProLitteris', 'AGADU', 'AUTORARTE', 'BUBEDRA', 'BBDA', 'BCDA', 'BURIDA', 'ADAVIS', 'BSDA'] }; export default constants; From a85447e94c3df3ac14e7aa044369c4b14302ffb0 Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 16 Sep 2015 19:00:59 +0200 Subject: [PATCH 3/7] bug fix user token on signup/login --- js/components/ascribe_forms/form_login.js | 6 ++++-- js/components/ascribe_forms/form_signup.js | 10 +++++++++- .../components/ikonotv/ikonotv_register_piece.js | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/js/components/ascribe_forms/form_login.js b/js/components/ascribe_forms/form_login.js index 86a20119..1c6fd0ad 100644 --- a/js/components/ascribe_forms/form_login.js +++ b/js/components/ascribe_forms/form_login.js @@ -27,7 +27,7 @@ let LoginForm = React.createClass({ onLogin: React.PropTypes.func }, - mixins: [Router.Navigation], + mixins: [Router.Navigation, Router.State], getDefaultProps() { return { @@ -95,6 +95,7 @@ let LoginForm = React.createClass({ }, render() { + let email = this.getQuery().email ? this.getQuery().email : null; return (
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js index 6a2acbb8..6be9f9f6 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js @@ -178,7 +178,7 @@ let IkonotvRegisterPiece = React.createClass({ 0} enableLocalHashing={false} - headerMessage={getLangText('Submit to Cyland Archive')} + headerMessage={getLangText('Submit to IkonoTV')} submitMessage={getLangText('Submit')} isFineUploaderActive={this.state.isFineUploaderActive} handleSuccess={this.handleRegisterSuccess} From 5c2ec3ffb0f2b558ca8f6a9d55303908e6d7e116 Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 16 Sep 2015 23:27:38 +0200 Subject: [PATCH 4/7] bug fix signup query landing page redirect ikono: user acl proxy on submit button ikono: further details + slides --- js/components/ascribe_forms/form_loan.js | 6 +- js/components/ascribe_forms/form_signup.js | 1 - .../slides_container.js | 4 +- js/components/signup_container.js | 9 + .../ikonotv_accordion_list_item.js | 14 +- .../ascribe_detail/ikonotv_piece_container.js | 137 +++++++-------- ...form.js => ikonotv_artist_details_form.js} | 44 +++-- .../ikonotv_artwork_details_form.js | 164 ++++++++++++++++++ .../ikonotv/ikonotv_contract_notifications.js | 4 +- .../components/ikonotv/ikonotv_landing.js | 31 ++-- .../ikonotv/ikonotv_register_piece.js | 128 ++++++++++---- js/components/whitelabel/wallet/wallet_app.js | 2 +- 12 files changed, 395 insertions(+), 149 deletions(-) rename js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/{ikonotv_additional_data_form.js => ikonotv_artist_details_form.js} (64%) create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index a1c31330..0c60fd7b 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -35,6 +35,7 @@ let LoanForm = React.createClass({ url: React.PropTypes.string, id: React.PropTypes.object, message: React.PropTypes.string, + createPublicContractAgreement: React.PropTypes.bool, handleSuccess: React.PropTypes.func }, @@ -44,7 +45,8 @@ let LoanForm = React.createClass({ showPersonalMessage: true, showEndDate: true, showStartDate: true, - showPassword: true + showPassword: true, + createPublicContractAgreement: true }; }, @@ -82,7 +84,7 @@ let LoanForm = React.createClass({ if (email) { ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( (contractAgreementList) => { - if (!contractAgreementList) { + if (!contractAgreementList && this.props.createPublicContractAgreement) { ContractAgreementListActions.createContractAgreementFromPublicContract(email); } } diff --git a/js/components/ascribe_forms/form_signup.js b/js/components/ascribe_forms/form_signup.js index 8b4e4cf7..928afe38 100644 --- a/js/components/ascribe_forms/form_signup.js +++ b/js/components/ascribe_forms/form_signup.js @@ -67,7 +67,6 @@ let SignupForm = React.createClass({ }, getFormData() { - console.log(this.getQuery()); if (this.getQuery().token){ return {token: this.getQuery().token}; } diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 84dff61c..53092a38 100644 --- a/js/components/ascribe_slides_container/slides_container.js +++ b/js/components/ascribe_slides_container/slides_container.js @@ -178,7 +178,7 @@ let SlidesContainer = React.createClass({ let breadcrumbs = []; ReactAddons.Children.map(this.props.children, (child, i) => { - if(i >= this.state.startFrom && child.props['data-slide-title']) { + if(child && i >= this.state.startFrom && child.props['data-slide-title']) { breadcrumbs.push(child.props['data-slide-title']); } }); @@ -229,7 +229,7 @@ let SlidesContainer = React.createClass({ // 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(i >= this.state.startFrom) { + if(child && i >= this.state.startFrom) { return ReactAddons.addons.cloneWithProps(child, { className: 'ascribe-slide', style: { diff --git a/js/components/signup_container.js b/js/components/signup_container.js index 46813b59..856e4af2 100644 --- a/js/components/signup_container.js +++ b/js/components/signup_container.js @@ -1,8 +1,12 @@ 'use strict'; import React from 'react'; +import Router from 'react-router'; import SignupForm from './ascribe_forms/form_signup'; +import { getLangText } from '../utils/lang_utils'; + +let Link = Router.Link; let SignupContainer = React.createClass({ getInitialState() { @@ -33,7 +37,12 @@ let SignupContainer = React.createClass({ return (
+
+ {getLangText('Already an ascribe user')}? {getLangText('Log in')}...
+ {getLangText('Forgot my password')}? {getLangText('Rescue me')}... +
+ ); } }); diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js index b716914a..2dd3cc2f 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js @@ -63,12 +63,16 @@ let IkonotvAccordionListItem = React.createClass({ return (
- + + + 0) { - return ( - ); - } - else { - - //We need to disable the normal acl_loan because we're inserting a custom acl_loan button - let availableAcls; - - if(this.state.piece && this.state.piece.acl && typeof this.state.piece.acl.acl_loan !== 'undefined') { - // make a copy to not have side effects - availableAcls = mergeOptions({}, this.state.piece.acl); - availableAcls.acl_loan = false; - } - - return ( - - - - - - - ); - } - }, - render() { if(this.state.piece && this.state.piece.title) { return ( @@ -152,14 +87,29 @@ let IkonotvPieceContainer = React.createClass({
- } - buttons={this.getActions()}> + }> + 0}> + + {return {'id': this.state.piece.id}; }} + label={getLangText('Personal note (private)')} + defaultValue={this.state.piece.private_note ? this.state.piece.private_note : null} + placeholder={getLangText('Enter your comments ...')} + editable={true} + successMessage={getLangText('Private note saved')} + url={ApiUrls.note_private_piece} + currentUser={this.state.currentUser}/> + + ); } else { @@ -172,4 +122,43 @@ let IkonotvPieceContainer = React.createClass({ } }); + +let IkonotvPieceDetails = React.createClass({ + propTypes: { + piece: React.PropTypes.object + }, + + render() { + if (this.props.piece && Object.keys(this.props.piece.extra_data).length !== 0){ + return ( + + + {Object.keys(this.props.piece.extra_data).map((data, i) => { + let label = data.replace('_', ' '); + return ( + ); + } + )} +
+ +
+ ); + } + return null; + } +}); + export default IkonotvPieceContainer; diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js similarity index 64% rename from js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js rename to js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js index 6f249c7b..cd98a94c 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js @@ -15,10 +15,9 @@ import AppConstants from '../../../../../../constants/application_constants'; import requests from '../../../../../../utils/requests'; import { getLangText } from '../../../../../../utils/lang_utils'; -//import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils'; -let IkonotvAdditionalDataForm = React.createClass({ +let IkonotvArtistDetailsForm = React.createClass({ propTypes: { handleSuccess: React.PropTypes.func.isRequired, piece: React.PropTypes.object.isRequired, @@ -77,7 +76,7 @@ let IkonotvAdditionalDataForm = React.createClass({ type="submit" className="btn ascribe-btn ascribe-btn-login" disabled={!this.state.isUploadReady || this.props.disabled}> - {getLangText('Proceed to loan')} + {getLangText('Proceed to artwork details')} } spinner={ @@ -87,28 +86,49 @@ let IkonotvAdditionalDataForm = React.createClass({ }>

- {getLangText('Provide supporting materials')} + {getLangText('Artist Details')}

+ defaultValue={this.props.piece.extra_data.artist_website} + placeholder={getLangText('The artist\'s website if present...')}/> + + + + + + + defaultValue={this.props.piece.extra_data.conceptual_overview} + placeholder={getLangText('Enter a short bio about the Artist')} + /> ); @@ -122,4 +142,4 @@ let IkonotvAdditionalDataForm = React.createClass({ } }); -export default IkonotvAdditionalDataForm; \ No newline at end of file +export default IkonotvArtistDetailsForm; \ No newline at end of file diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js new file mode 100644 index 00000000..ffaa8fa5 --- /dev/null +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js @@ -0,0 +1,164 @@ +'use strict'; + +import React from 'react'; + +import Form from '../../../../../ascribe_forms/form'; +import Property from '../../../../../ascribe_forms/property'; + +import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable'; + +//import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader'; + +import ApiUrls from '../../../../../../constants/api_urls'; +import AppConstants from '../../../../../../constants/application_constants'; + +import requests from '../../../../../../utils/requests'; + +import { getLangText } from '../../../../../../utils/lang_utils'; + + +let IkonotvArtworkDetailsForm = React.createClass({ + propTypes: { + handleSuccess: React.PropTypes.func.isRequired, + piece: React.PropTypes.object.isRequired, + + disabled: React.PropTypes.bool + }, + + getInitialState() { + return { + isUploadReady: true + }; + }, + + getFormData() { + let extradata = {}; + let formRefs = this.refs.form.refs; + + // Put additional fields in extra data object + Object + .keys(formRefs) + .forEach((fieldName) => { + extradata[fieldName] = formRefs[fieldName].state.value; + }); + + return { + extradata: extradata, + piece_id: this.props.piece.id + }; + + }, + + uploadStarted() { + this.setState({ + isUploadReady: false + }); + }, + + setIsUploadReady(isReady) { + this.setState({ + isUploadReady: isReady + }); + }, + + render() { + if(this.props.piece && this.props.piece.id) { + return ( +
+ {getLangText('Proceed to loan')} + + } + spinner={ +
+ +
+ }> +
+

+ {getLangText('Artwork Details')} +

+
+ + + + + + + + + + + + + + + + + + +
+ ); + } else { + return ( +
+ +
+ ); + } + } +}); + +export default IkonotvArtworkDetailsForm; \ No newline at end of file diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js index beffe23a..60ec2208 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js @@ -12,6 +12,7 @@ import NotificationStore from '../../../../../stores/notification_store'; import UserStore from '../../../../../stores/user_store'; import WhitelabelStore from '../../../../../stores/whitelabel_store'; +import WhitelabelActions from '../../../../../actions/whitelabel_actions'; import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; @@ -42,6 +43,7 @@ let IkonotvContractNotifications = React.createClass({ NotificationStore.listen(this.onChange); UserStore.listen(this.onChange); WhitelabelStore.listen(this.onChange); + WhitelabelActions.fetchWhitelabel(); if (this.state.contractAgreementListNotifications === null){ NotificationActions.fetchContractAgreementListNotifications(); } @@ -90,7 +92,7 @@ let IkonotvContractNotifications = React.createClass({ getAppendix() { let notifications = this.state.contractAgreementListNotifications[0]; let appendix = notifications.contract_agreement.appendix; - if (appendix) { + if (appendix && appendix.default) { return (

{getLangText('Appendix')}

diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js index 1e2d3803..7abfd62c 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js @@ -1,10 +1,10 @@ 'use strict'; import React from 'react'; +import Router from 'react-router'; import ButtonLink from 'react-router-bootstrap/lib/ButtonLink'; -import UserActions from '../../../../../actions/user_actions'; import UserStore from '../../../../../stores/user_store'; import { getLangText } from '../../../../../utils/lang_utils'; @@ -12,6 +12,8 @@ import { getLangText } from '../../../../../utils/lang_utils'; let IkonotvLanding = React.createClass({ + mixins: [Router.Navigation, Router.State], + getInitialState() { return UserStore.getState(); }, @@ -29,19 +31,20 @@ let IkonotvLanding = React.createClass({ }, getEnterButton() { + let redirect = 'signup'; + if(this.state.currentUser && this.state.currentUser.email) { - return ( - - {getLangText('ENTER')} - - ); - } else { - return ( - - {getLangText('ENTER')} - - ); + redirect = 'pieces'; } + else if (this.getQuery() && this.getQuery().redirect) { + redirect = this.getQuery().redirect; + } + console.log(redirect); + return ( + + {getLangText('ENTER')} + + ); }, render() { @@ -52,7 +55,7 @@ let IkonotvLanding = React.createClass({

PROTECT

-

& SHARE

+

& SHARE

Welcome to the ikonoTV

Registration Page

@@ -93,7 +96,7 @@ let IkonotvLanding = React.createClass({

Elizabeth Markevitch

-

Founder & CEO Markevitch Media GmbH

+

Founder & CEO Markevitch Media GmbH

{this.getEnterButton()}
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js index 6be9f9f6..ecb594c5 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js @@ -21,7 +21,9 @@ import GlobalNotificationActions from '../../../../../actions/global_notificatio import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; import LoanForm from '../../../../ascribe_forms/form_loan'; -import IkonotvAdditionalDataForm from './ascribe_forms/ikonotv_additional_data_form'; + +import IkonotvArtistDetailsForm from './ascribe_forms/ikonotv_artist_details_form'; +import IkonotvArtworkDetailsForm from './ascribe_forms/ikonotv_artwork_details_form'; import SlidesContainer from '../../../../ascribe_slides_container/slides_container'; @@ -95,10 +97,14 @@ let IkonotvRegisterPiece = React.createClass({ if(response && response.piece) { PieceActions.updatePiece(response.piece); } + if (!this.canSubmit()) { + this.transitionTo('pieces'); + } + else { + this.incrementStep(); + this.refs.slidesContainer.nextSlide(); + } - this.incrementStep(); - - this.refs.slidesContainer.nextSlide(); }, handleAdditionalDataSuccess() { @@ -158,12 +164,83 @@ let IkonotvRegisterPiece = React.createClass({ this.transitionTo('login'); }, + canSubmit() { + if (this.state.currentUser && this.state.currentUser.acl) { + return ( + this.state.currentUser + && this.state.currentUser.acl + && !!this.state.currentUser.acl.acl_submit + ); + } + return false; + }, + + getSlideArtistDetails() { + if (this.canSubmit()) { + return ( +
+ + + 1} + handleSuccess={this.handleAdditionalDataSuccess} + piece={this.state.piece}/> + + +
+ ); + } + return null; + }, + + getSlideArtworkDetails() { + if (this.canSubmit()) { + return ( +
+ + + 1} + handleSuccess={this.handleAdditionalDataSuccess} + piece={this.state.piece}/> + + +
+ ); + } + return null; + }, + + getSlideLoan() { + if (this.canSubmit()) { + + let today = new Moment(); + let enddate = new Moment(); + enddate.add(1, 'years'); + return ( +
+ + + + + +
+ ); + } + return null; + }, + render() { - - let today = new Moment(); - let enddate = new Moment(); - enddate.add(1, 'years'); - return ( 0} enableLocalHashing={false} - headerMessage={getLangText('Submit to IkonoTV')} - submitMessage={getLangText('Submit')} + headerMessage={getLangText('Register work')} + submitMessage={getLangText('Register')} isFineUploaderActive={this.state.isFineUploaderActive} handleSuccess={this.handleRegisterSuccess} onLoggedOut={this.onLoggedOut} />
-
- - - 1} - handleSuccess={this.handleAdditionalDataSuccess} - piece={this.state.piece}/> - - -
-
- - - - - -
+ {this.getSlideArtistDetails()} + {this.getSlideArtworkDetails()} + {this.getSlideLoan()} ); } diff --git a/js/components/whitelabel/wallet/wallet_app.js b/js/components/whitelabel/wallet/wallet_app.js index 06bac15f..9a742f8b 100644 --- a/js/components/whitelabel/wallet/wallet_app.js +++ b/js/components/whitelabel/wallet/wallet_app.js @@ -19,7 +19,7 @@ let WalletApp = React.createClass({ let ROUTES = getRoutes(null, subdomain); let header = null; - if ((this.isActive('landing') || this.isActive('login') || this.isActive('signup')) + if ((this.isActive('landing') || this.isActive('login') || this.isActive('signup') || this.isActive('contract_notifications')) && (['ikonotv', 'cyland']).indexOf(subdomain) > -1) { header = (
); From 63fffc213260ba940e97266e59502f2e64cced33 Mon Sep 17 00:00:00 2001 From: diminator Date: Thu, 17 Sep 2015 11:39:55 +0200 Subject: [PATCH 5/7] PR comments fix --- js/actions/contract_agreement_list_actions.js | 7 +- js/components/ascribe_detail/edition.js | 2 +- .../ascribe_detail/piece_container.js | 2 +- .../form_copyright_association.js | 76 +++++++++---------- js/components/ascribe_forms/form_loan.js | 7 +- .../ascribe_detail/cyland_piece_container.js | 2 +- .../ascribe_detail/ikonotv_piece_container.js | 2 +- .../ikonotv_artist_details_form.js | 2 +- .../ikonotv_artwork_details_form.js | 4 +- .../ikonotv/ikonotv_contract_notifications.js | 38 +++++----- 10 files changed, 72 insertions(+), 70 deletions(-) diff --git a/js/actions/contract_agreement_list_actions.js b/js/actions/contract_agreement_list_actions.js index f2959901..52c055a6 100644 --- a/js/actions/contract_agreement_list_actions.js +++ b/js/actions/contract_agreement_list_actions.js @@ -91,12 +91,7 @@ class ContractAgreementListActions { flushContractAgreementList(){ return Q.Promise((resolve, reject) => { - this.actions.updateContractAgreementList(null).then( - resolve() - ).catch((err) => { - console.logGlobal(err); - reject(err); - }); + return this.actions.updateContractAgreementList(null); }); } diff --git a/js/components/ascribe_detail/edition.js b/js/components/ascribe_detail/edition.js index aa3d81ba..1e69a7ab 100644 --- a/js/components/ascribe_detail/edition.js +++ b/js/components/ascribe_detail/edition.js @@ -152,7 +152,7 @@ let Edition = React.createClass({ {return {'bitcoin_id': this.props.edition.bitcoin_id}; }} diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js index 8642ee05..4f8d8d8d 100644 --- a/js/components/ascribe_detail/piece_container.js +++ b/js/components/ascribe_detail/piece_container.js @@ -237,7 +237,7 @@ let PieceContainer = React.createClass({ - - - -
- - ); + if (this.props.currentUser && this.props.currentUser.email){ + return ( +
+ + + +
+
+ ); + } + return null; } }); diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index 0c60fd7b..1b37a116 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -79,12 +79,17 @@ let LoanForm = React.createClass({ getContractAgreementsOrCreatePublic(email){ /* a more complex defer (with promises) otherwise we dispatch while an action is being dispatched) */ window.setTimeout(() => { - ContractAgreementListActions.flushContractAgreementList(); + ContractAgreementListActions.flushContractAgreementList() + .catch((err) => { + console.logGlobal(err); + }); if (email) { + // fetch the available contractagreements (pending/accepted) ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( (contractAgreementList) => { if (!contractAgreementList && this.props.createPublicContractAgreement) { + // for public contracts: fetch the public contract and create a contractagreement if available ContractAgreementListActions.createContractAgreementFromPublicContract(email); } } diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js index 395cd86e..5b605007 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js @@ -98,7 +98,7 @@ let CylandPieceContainer = React.createClass({
{return {'id': this.state.piece.id}; }} diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js index 8368bd89..9ee94245 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js @@ -97,7 +97,7 @@ let IkonotvPieceContainer = React.createClass({ {return {'id': this.state.piece.id}; }} diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js index cd98a94c..e840173a 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js @@ -62,7 +62,7 @@ let IkonotvArtistDetailsForm = React.createClass({ }, render() { - if(this.props.piece && this.props.piece.id) { + if(this.props.piece && this.props.piece.id && this.props.piece.extra_data) { return (
this.handleConfirmSuccess() ); }, handleConfirmSuccess() { - let notification = new GlobalNotificationModel(getLangText('You have accepted the conditions'), 'success', 10000); + let notification = new GlobalNotificationModel(getLangText('You have accepted the conditions'), 'success', 5000); GlobalNotificationActions.appendGlobalNotification(notification); this.transitionTo('pieces'); }, handleDeny() { let contractAgreement = this.state.contractAgreementListNotifications[0].contract_agreement; - requests.put(apiUrls.ownership_contract_agreements_deny, {contract_agreement_id: contractAgreement.id}).then( + requests.put(ApiUrls.ownership_contract_agreements_deny, {contract_agreement_id: contractAgreement.id}).then( () => this.handleDenySuccess() ); }, handleDenySuccess() { - let notification = new GlobalNotificationModel(getLangText('You have denied the conditions'), 'success', 10000); + let notification = new GlobalNotificationModel(getLangText('You have denied the conditions'), 'success', 5000); GlobalNotificationActions.appendGlobalNotification(notification); this.transitionTo('pieces'); }, @@ -136,18 +139,19 @@ let IkonotvContractNotifications = React.createClass({ && this.state.currentUser.profile.copyright_association){ return null; } - return ( -
-

{getLangText('Are you a member of any copyright societies?')}

-

- ARS, DACS, Bildkunst, Pictoright, SODRAC, Copyright Agency/Viscopy, SAVA, Bildrecht GmbH, - SABAM, AUTVIS, CREAIMAGEN, SONECA, Copydan, EAU, Kuvasto, GCA, HUNGART, IVARO, SIAE, JASPAR-SPDA, - AKKA/LAA, LATGA-A, SOMAAP, ARTEGESTION, CARIER, BONO, APSAV, SPA, GESTOR, VISaRTA, RAO, LITA, - DALRO, VeGaP, BUS, ProLitteris, AGADU, AUTORARTE, BUBEDRA, BBDA, BCDA, BURIDA, ADAVIS, BSDA -

- -
- ); + if (this.state.currentUser && this.state.currentUser.profile) { + return ( +
+

{getLangText('Are you a member of any copyright societies?')}

+ +

+ {AppConstants.copyrightAssociations.join(', ')} +

+ +
+ ); + } + return null; }, render() { From 780ab9f7f1d2e5a3eab5342296dbcee5315decd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Thu, 17 Sep 2015 13:28:59 +0200 Subject: [PATCH 6/7] Cleanup window.setTimeout --- js/actions/contract_agreement_list_actions.js | 4 +-- js/components/ascribe_forms/form_loan.js | 28 ++++++++----------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/js/actions/contract_agreement_list_actions.js b/js/actions/contract_agreement_list_actions.js index 52c055a6..a5059ff0 100644 --- a/js/actions/contract_agreement_list_actions.js +++ b/js/actions/contract_agreement_list_actions.js @@ -90,9 +90,7 @@ class ContractAgreementListActions { } flushContractAgreementList(){ - return Q.Promise((resolve, reject) => { - return this.actions.updateContractAgreementList(null); - }); + this.actions.updateContractAgreementList(null); } } diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index 1b37a116..f8946486 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -77,24 +77,18 @@ let LoanForm = React.createClass({ }, getContractAgreementsOrCreatePublic(email){ - /* a more complex defer (with promises) otherwise we dispatch while an action is being dispatched) */ - window.setTimeout(() => { - ContractAgreementListActions.flushContractAgreementList() - .catch((err) => { - console.logGlobal(err); - }); - - if (email) { - // fetch the available contractagreements (pending/accepted) - ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( - (contractAgreementList) => { - if (!contractAgreementList && this.props.createPublicContractAgreement) { - // for public contracts: fetch the public contract and create a contractagreement if available - ContractAgreementListActions.createContractAgreementFromPublicContract(email); - } + ContractAgreementListActions.flushContractAgreementList(); + if (email) { + // fetch the available contractagreements (pending/accepted) + ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( + (contractAgreementList) => { + if (!contractAgreementList && this.props.createPublicContractAgreement) { + // for public contracts: fetch the public contract and create a contractagreement if available + ContractAgreementListActions.createContractAgreementFromPublicContract(email); } - ); - }}, 0); + } + ); + } }, getFormData(){ From ff163df61ebe8d8e92643fc2f72d1a800c6e48f5 Mon Sep 17 00:00:00 2001 From: diminator Date: Thu, 17 Sep 2015 14:20:46 +0200 Subject: [PATCH 7/7] PR update --- js/components/ascribe_detail/edition.js | 5 +++-- js/components/ascribe_detail/piece_container.js | 5 ++--- .../ascribe_forms/form_copyright_association.js | 2 +- js/components/ascribe_forms/form_login.js | 2 +- js/components/ascribe_forms/form_signup.js | 2 +- .../ascribe_detail/cyland_piece_container.js | 5 ++--- .../ascribe_detail/ikonotv_piece_container.js | 5 ++--- .../ikonotv/ikonotv_contract_notifications.js | 16 +++++++--------- .../wallet/components/ikonotv/ikonotv_landing.js | 3 +-- .../components/ikonotv/ikonotv_register_piece.js | 10 ++-------- js/fetchers/ownership_fetcher.js | 8 ++++++++ 11 files changed, 30 insertions(+), 33 deletions(-) diff --git a/js/components/ascribe_detail/edition.js b/js/components/ascribe_detail/edition.js index 1e69a7ab..f2dbf682 100644 --- a/js/components/ascribe_detail/edition.js +++ b/js/components/ascribe_detail/edition.js @@ -152,8 +152,9 @@ let Edition = React.createClass({ + show={!!(this.state.currentUser.username + || this.props.edition.acl.acl_edit + || this.props.edition.public_note)}> {return {'bitcoin_id': this.props.edition.bitcoin_id}; }} label={getLangText('Personal note (private)')} diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js index 4f8d8d8d..f14cf743 100644 --- a/js/components/ascribe_detail/piece_container.js +++ b/js/components/ascribe_detail/piece_container.js @@ -237,12 +237,11 @@ let PieceContainer = React.createClass({ + show={!!(this.state.currentUser.username || this.state.piece.public_note)}>