From 6dab66ec61663dd37f529ead16254f2417850238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 19 Aug 2015 13:56:43 +0200 Subject: [PATCH 1/6] restructure cyland submit button --- .../ascribe_buttons/cyland_submit_button.js | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js index 2bb35719..8b9a53ef 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js @@ -3,18 +3,12 @@ import React from 'react'; import classNames from 'classnames'; -import Moment from 'moment'; +import ButtonLink from 'react-router-bootstrap/lib/ButtonLink'; import WhitelabelActions from '../../../../../../actions/whitelabel_actions'; import WhitelabelStore from '../../../../../../stores/whitelabel_store'; -import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper'; -import LoanForm from '../../../../../ascribe_forms/form_loan'; - -import ApiUrls from '../../../../../../constants/api_urls'; - import { getLangText } from '../../../../../../utils/lang_utils'; -import { getAclFormMessage } from '../../../../../../utils/form_utils'; let CylandSubmitButton = React.createClass({ propTypes: { @@ -41,36 +35,14 @@ let CylandSubmitButton = React.createClass({ this.setState(state); }, - getSubmitButton() { + render() { return ( - - ); - }, - - render() { - let today = new Moment(); - let loanEndDate = new Moment(); - loanEndDate.add(1000, 'years'); - - return ( - - - + ); } }); From 406cee5bd3d1c56b86e202850eb9cbd8a1940ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 19 Aug 2015 14:11:03 +0200 Subject: [PATCH 2/6] refactor breadcrumbs to attributes --- .../slides_container.js | 32 ++++++++++++++----- .../cyland/cyland_register_piece.js | 7 ++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 9a3f2269..95c5859f 100644 --- a/js/components/ascribe_slides_container/slides_container.js +++ b/js/components/ascribe_slides_container/slides_container.js @@ -11,7 +11,6 @@ let Navigation = Router.Navigation; let SlidesContainer = React.createClass({ propTypes: { - breadcrumbs: React.PropTypes.arrayOf(React.PropTypes.string), children: React.PropTypes.arrayOf(React.PropTypes.element), forwardProcess: React.PropTypes.bool.isRequired }, @@ -135,15 +134,31 @@ let SlidesContainer = React.createClass({ } }, - renderBreadCrumbs() { - if (this.props.breadcrumbs) { - let numSlides = this.props.breadcrumbs.length; + extractBreadcrumbs() { + let breadcrumbs = []; + + ReactAddons.Children.map(this.props.children, (child) => { + breadcrumbs.push(child.props['data-slide-title']); + }); + + return breadcrumbs; + }, + + renderBreadcrumbs() { + let breadcrumbs = this.extractBreadcrumbs(); + let numOfChildren = React.Children.count(this.props.children); + + // check if every child/slide has a title, + // otherwise do not display the breadcrumbs at all + if(breadcrumbs.length === numOfChildren) { + let numSlides = breadcrumbs.length; let columnWidth = Math.floor(12 / numSlides); + return (
- {this.props.breadcrumbs.map((breadcrumb, i) => { + {breadcrumbs.map((breadcrumb, i) => { return (
- {this.props.breadcrumbs[i]} + {breadcrumb} @@ -163,8 +178,9 @@ let SlidesContainer = React.createClass({
); + } else { + return null; } - return null; }, // Since we need to give the slides a width, we need to call ReactAddons.addons.cloneWithProps @@ -186,7 +202,7 @@ let SlidesContainer = React.createClass({
- {this.renderBreadCrumbs()} + {this.renderBreadcrumbs()}
-
+
-
+
-
+
Date: Wed, 19 Aug 2015 15:30:48 +0200 Subject: [PATCH 3/6] add start_from parameter to slide container --- .../ascribe_accordion_list/accordion_list.js | 2 +- .../slides_container.js | 71 +++++++++++++++---- js/components/piece_list.js | 2 +- .../ascribe_buttons/cyland_submit_button.js | 6 +- .../ascribe_detail/cyland_piece_container.js | 8 +-- .../cyland_additional_data_form.js | 21 +++++- .../cyland/cyland_register_piece.js | 9 ++- sass/ascribe_accordion_list.scss | 7 +- sass/main.scss | 8 ++- 9 files changed, 102 insertions(+), 32 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list.js b/js/components/ascribe_accordion_list/accordion_list.js index 85084b5f..471ba9d5 100644 --- a/js/components/ascribe_accordion_list/accordion_list.js +++ b/js/components/ascribe_accordion_list/accordion_list.js @@ -28,7 +28,7 @@ let AccordionList = React.createClass({ ); } else { return ( -
+
{this.props.loadingElement}
); diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 95c5859f..56f1547f 100644 --- a/js/components/ascribe_slides_container/slides_container.js +++ b/js/components/ascribe_slides_container/slides_container.js @@ -21,15 +21,22 @@ let SlidesContainer = React.createClass({ // handle queryParameters let queryParams = this.getQuery(); let slideNum = -1; + let startFrom = -1; if(queryParams && 'slide_num' in queryParams) { slideNum = parseInt(queryParams.slide_num, 10); } // if slide_num is not set, this will be done in componentDidMount + // the query param 'start_from' removes all slide children before the respective number + if(queryParams && 'start_from' in queryParams) { + startFrom = parseInt(queryParams.start_from, 10); + } + return { + slideNum, + startFrom, containerWidth: 0, - slideNum: slideNum, historyLength: window.history.length }; }, @@ -54,9 +61,23 @@ let SlidesContainer = React.createClass({ window.addEventListener('resize', this.handleContainerResize); }, - componentDidUpdate() { - // check if slide_num was defined, and if not then default to 0 + componentWillReceiveProps() { let queryParams = this.getQuery(); + + // also check if start_from was updated + // This applies for example when the user tries to submit a already existing piece + // (starting from slide 1 for example) and then clicking on + NEW WORK + if(queryParams && !('start_from' in queryParams)) { + this.setState({ + startFrom: -1 + }); + } + }, + + componentDidUpdate() { + let queryParams = this.getQuery(); + + // check if slide_num was defined, and if not then default to 0 this.setSlideNum(queryParams.slide_num); }, @@ -137,20 +158,34 @@ let SlidesContainer = React.createClass({ extractBreadcrumbs() { let breadcrumbs = []; - ReactAddons.Children.map(this.props.children, (child) => { - breadcrumbs.push(child.props['data-slide-title']); + ReactAddons.Children.map(this.props.children, (child, i) => { + if(i >= this.state.startFrom) { + breadcrumbs.push(child.props['data-slide-title']); + } }); return breadcrumbs; }, + customChildrenCount() { + let count = 0; + React.Children.forEach(this.props.children, (child, i) => { + if(i >= this.state.startFrom) { + count++; + } + }); + + return count; + }, + renderBreadcrumbs() { let breadcrumbs = this.extractBreadcrumbs(); - let numOfChildren = React.Children.count(this.props.children); + let numOfChildren = this.customChildrenCount(); // check if every child/slide has a title, // otherwise do not display the breadcrumbs at all - if(breadcrumbs.length === numOfChildren) { + // Also, if there is only one child, do not display the breadcrumbs + if(breadcrumbs.length === numOfChildren && breadcrumbs.length > 1 && numOfChildren > 1) { let numSlides = breadcrumbs.length; let columnWidth = Math.floor(12 / numSlides); @@ -187,13 +222,21 @@ let SlidesContainer = React.createClass({ // Also, a key is nice to have! renderChildren() { return ReactAddons.Children.map(this.props.children, (child, i) => { - return ReactAddons.addons.cloneWithProps(child, { - className: 'ascribe-slide', - style: { - width: this.state.containerWidth - }, - key: i - }); + // 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) { + return ReactAddons.addons.cloneWithProps(child, { + className: 'ascribe-slide', + style: { + width: this.state.containerWidth + }, + key: i + }); + } else { + // Abortions are bad mkay + return null; + } }); }, diff --git a/js/components/piece_list.js b/js/components/piece_list.js index eac6ca15..14554ea0 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -138,7 +138,7 @@ let PieceList = React.createClass({ this.transitionTo(this.getPathname(), {page: 1}); }, - applyOrderBy(orderBy, orderAsc) { + applyOrderBy(orderBy) { PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, orderBy, this.state.orderAsc, this.state.filterBy); }, diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js index 8b9a53ef..a4c23e41 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js @@ -39,7 +39,11 @@ let CylandSubmitButton = React.createClass({ return ( {getLangText('Submit to Cyland')} 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 d22d8638..c8011fc7 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 @@ -20,11 +20,8 @@ import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_de import DetailProperty from '../../../../../ascribe_detail/detail_property'; import { mergeOptions } from '../../../../../../utils/general_utils'; -import { getLangText } from '../../../../../../utils/lang_utils'; -/** - * This is the component that implements resource/data specific functionality - */ + let CylandPieceContainer = React.createClass({ getInitialState() { return mergeOptions( @@ -106,10 +103,11 @@ let CylandPieceDetails = React.createClass({ show={true} defaultExpanded={true}>
- {Object.keys(this.props.piece.extra_data).map((data) => { + {Object.keys(this.props.piece.extra_data).map((data, i) => { let label = data.replace('_', ' '); return ( diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js index cddabb0c..95e55fca 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js @@ -24,7 +24,7 @@ let CylandAdditionalDataForm = React.createClass({ getInitialState() { return { - isUploadReady: false + isUploadReady: true }; }, @@ -64,6 +64,17 @@ let CylandAdditionalDataForm = React.createClass({ }, render() { + let artistBio = ''; + let conceptualOverview = ''; + + if (Object.keys(this.props.piece).length !== 0 && Object.keys(this.props.piece.extra_data).length !== 0) { + let extraData = this.props.piece.extra_data; + + artistBio = extraData.artist_bio; + conceptualOverview = extraData.conceptual_overview; + } + + if(this.props.piece && this.props.piece.id) { return ( ); } else { - return First register the piece.; + return ( +
+ +
+ ); } } }); 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 4e6fd333..ef1c154e 100644 --- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js +++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js @@ -40,9 +40,10 @@ import { getLangText } from '../../../../../utils/lang_utils'; import { mergeOptions } from '../../../../../utils/general_utils'; import { getAclFormMessage } from '../../../../../utils/form_utils'; + let CylandRegisterPiece = React.createClass({ - mixins: [Router.Navigation], + mixins: [Router.Navigation, Router.State], getInitialState(){ return mergeOptions( @@ -63,6 +64,12 @@ let CylandRegisterPiece = React.createClass({ WhitelabelStore.listen(this.onChange); UserActions.fetchCurrentUser(); WhitelabelActions.fetchWhitelabel(); + + let queryParams = this.getQuery(); + + if(queryParams && 'piece_id' in queryParams) { + PieceActions.fetchOne(queryParams.piece_id); + } }, componentWillUnmount() { diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss index f44be250..b040e877 100644 --- a/sass/ascribe_accordion_list.scss +++ b/sass/ascribe_accordion_list.scss @@ -65,7 +65,7 @@ $ascribe-accordion-list-font: 'Source Sans Pro'; overflow: hidden; text-overflow: ellipsis; } - a { + a:not(.btn) { color: #666; } } @@ -79,11 +79,6 @@ $ascribe-accordion-list-font: 'Source Sans Pro'; } } -.ascribe-accordion-list-loading { - padding-top: 30%; - padding-bottom: 30%; -} - .ascribe-accordion-list-loading img { display: block; margin: auto; diff --git a/sass/main.scss b/sass/main.scss index de166b0c..fed435f0 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -427,4 +427,10 @@ hr { &:hover { color: #000; } -} \ No newline at end of file +} + +.ascribe-loading-position { + padding-top: 30%; + padding-bottom: 30%; + text-align: center; +} From 0b4b3fa7273211760dcb58cbc01d5033a5837bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 19 Aug 2015 15:54:13 +0200 Subject: [PATCH 4/6] fix slideContainer broken functionality --- .../ascribe_slides_container/slides_container.js | 10 ++++++++-- .../wallet/components/cyland/cyland_register_piece.js | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 56f1547f..50b6eb82 100644 --- a/js/components/ascribe_slides_container/slides_container.js +++ b/js/components/ascribe_slides_container/slides_container.js @@ -92,6 +92,12 @@ let SlidesContainer = React.createClass({ }); }, + // When the start_from parameter is used, this.setSlideNum can not simply be used anymore. + nextSlide() { + let nextSlide = this.state.slideNum + 1; + this.setSlideNum(nextSlide); + }, + // We let every one from the outsite set the page number of the slider, // though only if the slideNum is actually in the range of our children-list. setSlideNum(slideNum) { @@ -122,7 +128,7 @@ let SlidesContainer = React.createClass({ // if slideNum is within the range of slides and none of the previous cases // where matched, we can actually do transitions - } else if(slideNum >= 0 || slideNum < React.Children.count(this.props.children)) { + } else if(slideNum >= 0 || slideNum < this.customChildrenCount()) { if(slideNum !== this.state.slideNum - 1) { // Bootstrapping the component, getInitialState is called once to save @@ -249,7 +255,7 @@ let SlidesContainer = React.createClass({
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 ef1c154e..5e96a1e6 100644 --- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js +++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js @@ -97,11 +97,11 @@ let CylandRegisterPiece = React.createClass({ PieceActions.updatePiece(response.piece); } - this.refs.slidesContainer.setSlideNum(1); + this.refs.slidesContainer.nextSlide(); }, handleAdditionalDataSuccess() { - this.refs.slidesContainer.setSlideNum(2); + this.refs.slidesContainer.nextSlide(); }, handleLoanSuccess(response) { From d5e8181855f5f8b2190f604344e472a5a0034904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 19 Aug 2015 16:02:10 +0200 Subject: [PATCH 5/6] make cyland submission stateful --- .../ascribe_buttons/cyland_submit_button.js | 9 ++++++++- .../ascribe_forms/cyland_additional_data_form.js | 13 ------------- .../components/cyland/cyland_register_piece.js | 15 ++++++++++----- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js index a4c23e41..ab7723ea 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js @@ -36,12 +36,19 @@ let CylandSubmitButton = React.createClass({ }, render() { + let piece = this.props.piece; + let startFrom = 1; + + if(piece && piece.extra_data && Object.keys(piece.extra_data).length > 0) { + startFrom = 2; + } + return ( diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js index 95e55fca..38eeee7f 100644 --- a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js +++ b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js @@ -64,17 +64,6 @@ let CylandAdditionalDataForm = React.createClass({ }, render() { - let artistBio = ''; - let conceptualOverview = ''; - - if (Object.keys(this.props.piece).length !== 0 && Object.keys(this.props.piece.extra_data).length !== 0) { - let extraData = this.props.piece.extra_data; - - artistBio = extraData.artist_bio; - conceptualOverview = extraData.conceptual_overview; - } - - if(this.props.piece && this.props.piece.id) { return ( Date: Wed, 19 Aug 2015 16:03:59 +0200 Subject: [PATCH 6/6] Revert "form validation first cut" Tim: I reverted this commit because I want to keep if for later. We decided to do so because we're of the opinion validation is not a pressing issue right now. This reverts commit 8a814c287cd6dc85fbd63cb29518ac0e21aabfb3. --- js/components/ascribe_forms/form.js | 41 ++----------- .../ascribe_forms/form_register_piece.js | 58 ++++++------------- js/components/ascribe_forms/input_checkbox.js | 27 ++++----- js/components/ascribe_forms/property.js | 43 +++----------- .../cyland/cyland_register_piece.js | 3 +- 5 files changed, 41 insertions(+), 131 deletions(-) diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js index a9e267d9..2b956a7e 100644 --- a/js/components/ascribe_forms/form.js +++ b/js/components/ascribe_forms/form.js @@ -23,8 +23,8 @@ let Form = React.createClass({ handleSuccess: React.PropTypes.func, getFormData: React.PropTypes.func, children: React.PropTypes.oneOfType([ - React.PropTypes.arrayOf(React.PropTypes.element), - React.PropTypes.element + React.PropTypes.object, + React.PropTypes.array ]), className: React.PropTypes.string, spinner: React.PropTypes.element, @@ -165,43 +165,14 @@ let Form = React.createClass({ this.setState({errors: []}); }, - checkFormValidity() { - let requiredProps = []; - - Object - .keys(this.refs) - .forEach((refName) => { - if(this.refs[refName].props.required) { - requiredProps.push(this.refs[refName]); - } - }); - - let validProps = requiredProps.filter((property) => property.state.isValid); - - if(requiredProps.length === validProps.length) { - return true; - } else { - return false; - } - - }, - getButtons() { - let buttons = null; - let isFormValid = this.checkFormValidity(); - - if(this.state.submitted) { + if (this.state.submitted){ return this.props.spinner; } - if(this.props.buttons) { - - buttons = React.cloneElement(this.props.buttons, { - disabled: !isFormValid - }); - - return buttons; + if (this.props.buttons){ + return this.props.buttons; } - + let buttons = null; if (this.state.edited){ buttons = ( diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js index ef25dd55..6545007c 100644 --- a/js/components/ascribe_forms/form_register_piece.js +++ b/js/components/ascribe_forms/form_register_piece.js @@ -27,10 +27,7 @@ let RegisterPieceForm = React.createClass({ isFineUploaderActive: React.PropTypes.bool, isFineUploaderEditable: React.PropTypes.bool, enableLocalHashing: React.PropTypes.bool, - children: React.PropTypes.oneOfType([ - React.PropTypes.arrayOf(React.PropTypes.element), - React.PropTypes.element - ]), + children: React.PropTypes.element, onLoggedOut: React.PropTypes.func }, @@ -77,11 +74,16 @@ let RegisterPieceForm = React.createClass({ }); }, + setIsUploadReady(isReady) { + this.setState({ + isUploadReady: isReady + }); + }, + render() { let currentUser = this.state.currentUser; let enableLocalHashing = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false; enableLocalHashing = enableLocalHashing && this.props.enableLocalHashing; - return ( {this.props.headerMessage}
+ ignoreFocus={true}> + label={getLangText('Artist Name')}> + label={getLangText('Title')}> + label={getLangText('Year Created')}> + style={{paddingBottom: 0}}> {' ' + getLangText('I agree to the Terms of Service of Cyland Archive') + ' '}