From e71c2f9fe092a05b96d9ea44e16e7c81ecde4f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Mon, 13 Jul 2015 17:09:44 +0200 Subject: [PATCH] separate create edition form logic --- .../accordion_list_item.js | 17 ++- .../accordion_list_item_create_editions.js | 51 --------- js/components/ascribe_buttons/acl_button.js | 26 +++-- .../ascribe_buttons/acl_button_list.js | 15 ++- .../ascribe_buttons/create_editions_button.js | 88 +++++++++++---- js/components/ascribe_detail/edition.js | 10 +- js/components/ascribe_detail/header.js | 26 ----- js/components/ascribe_detail/piece.js | 105 +++++++++--------- .../ascribe_forms/create_editions_form.js | 50 +++++++++ js/constants/languages.js | 3 + 10 files changed, 216 insertions(+), 175 deletions(-) delete mode 100644 js/components/ascribe_accordion_list/accordion_list_item_create_editions.js delete mode 100644 js/components/ascribe_detail/header.js create mode 100644 js/components/ascribe_forms/create_editions_form.js diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index 4d057c44..a5e5679d 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -8,7 +8,7 @@ import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; import Tooltip from 'react-bootstrap/lib/Tooltip'; import AccordionListItemEditionWidget from './accordion_list_item_edition_widget'; -import AccordionListItemCreateEditions from './accordion_list_item_create_editions'; +import CreateEditionsForm from '../ascribe_forms/create_editions_form'; import PieceListActions from '../../actions/piece_list_actions'; import EditionListActions from '../../actions/edition_list_actions'; @@ -101,6 +101,18 @@ let AccordionListItem = React.createClass({ }); }, + getCreateEditionsDialog() { + if(this.props.content.num_editions < 1 && this.state.showCreateEditionsDialog) { + return ( +
+ +
+ ); + } + }, + render() { let linkData; @@ -150,8 +162,9 @@ let AccordionListItem = React.createClass({ - {this.props.content.num_editions < 1 && this.state.showCreateEditionsDialog ? : null} + {this.getCreateEditionsDialog()} + {/* this.props.children is AccordionListItemTableEditions */} {this.props.children} diff --git a/js/components/ascribe_accordion_list/accordion_list_item_create_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_create_editions.js deleted file mode 100644 index 30a6efbc..00000000 --- a/js/components/ascribe_accordion_list/accordion_list_item_create_editions.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -import React from 'react'; - -import Form from '../ascribe_forms/form'; -import Property from '../ascribe_forms/property'; - -import apiUrls from '../../constants/api_urls'; -import { getLangText } from '../../utils/lang_utils'; - -let AccordionListItemCreateEditions = React.createClass({ - - propTypes: { - pieceId: React.PropTypes.number, - handleSuccess: React.PropTypes.func - }, - - getFormData(){ - return { - piece_id: parseInt(this.props.pieceId, 10) - }; - }, - - render() { - return ( -
-
- - - }> - - - -
-
- ); - } -}); - -export default AccordionListItemCreateEditions; \ No newline at end of file diff --git a/js/components/ascribe_buttons/acl_button.js b/js/components/ascribe_buttons/acl_button.js index 1e20d0d8..e9d2aa2a 100644 --- a/js/components/ascribe_buttons/acl_button.js +++ b/js/components/ascribe_buttons/acl_button.js @@ -105,6 +105,20 @@ let AclButton = React.createClass({ } }, + getShareMessage(){ + return ( + ` +${getLangText('Hi')}, + +${getLangText('I am sharing')}: +${this.getTitlesString()} ${getLangText('with you')}. + +${getLangText('Truly yours')}, +${this.props.currentUser.username} + ` + ); + }, + render() { let shouldDisplay = this.props.availableAcls.indexOf(this.props.action) > -1; let aclProps = this.actionProperties(); @@ -121,18 +135,6 @@ let AclButton = React.createClass({ { aclProps.form } ); - }, - - getShareMessage(){ - return ( -`${getLangText('Hi')}, - -${getLangText('I am sharing')} : -${this.getTitlesString()}${getLangText('with you')}. - -${getLangText('Truly yours')}, -${this.props.currentUser.username}` - ); } }); diff --git a/js/components/ascribe_buttons/acl_button_list.js b/js/components/ascribe_buttons/acl_button_list.js index eb3dc720..5fb3b224 100644 --- a/js/components/ascribe_buttons/acl_button_list.js +++ b/js/components/ascribe_buttons/acl_button_list.js @@ -7,14 +7,20 @@ import UserStore from '../../stores/user_store'; import AclButton from '../ascribe_buttons/acl_button'; import DeleteButton from '../ascribe_buttons/delete_button'; -import CreateEditionButton from '../ascribe_buttons/create_editions_button'; let AclButtonList = React.createClass({ propTypes: { className: React.PropTypes.string, - editions: React.PropTypes.object, + editions: React.PropTypes.oneOfType([ + React.PropTypes.object, + React.PropTypes.array + ]), availableAcls: React.PropTypes.array, - handleSuccess: React.PropTypes.func + handleSuccess: React.PropTypes.func, + children: React.PropTypes.oneOfType([ + React.PropTypes.arrayOf(React.PropTypes.element), + React.PropTypes.element + ]) }, getInitialState() { @@ -69,8 +75,7 @@ let AclButtonList = React.createClass({ handleSuccess={this.props.handleSuccess} /> - + {this.props.children} ); } diff --git a/js/components/ascribe_buttons/create_editions_button.js b/js/components/ascribe_buttons/create_editions_button.js index 4b189db2..9ccb52cf 100644 --- a/js/components/ascribe_buttons/create_editions_button.js +++ b/js/components/ascribe_buttons/create_editions_button.js @@ -1,42 +1,82 @@ 'use strict'; import React from 'react'; -import Router from 'react-router'; - -import Button from 'react-bootstrap/lib/Button'; - -import EditionDeleteForm from '../ascribe_forms/form_delete_edition'; -import EditionRemoveFromCollectionForm from '../ascribe_forms/form_remove_editions_from_collection'; -import ModalWrapper from '../ascribe_modal/modal_wrapper'; -import AccordionListItemCreateEditions from './../ascribe_accordion_list/accordion_list_item_create_editions'; -import GlobalNotificationModel from '../../models/global_notification_model'; -import GlobalNotificationActions from '../../actions/global_notification_actions'; - -import { getAvailableAcls } from '../../utils/acl_utils'; -import { getLangText } from '../../utils/lang_utils.js' import EditionListActions from '../../actions/edition_list_actions'; +import PieceListActions from '../../actions/piece_list_actions'; + +import { getAvailableAcls } from '../../utils/acl_utils'; let CreateEditionsButton = React.createClass({ propTypes: { - piece: React.PropTypes.object.isRequired + piece: React.PropTypes.object.isRequired, + toggleCreateEditionsDialog: React.PropTypes.func.isRequired }, - mixins: [Router.Navigation], + getInitialState() { + return {}; + }, + + componentDidUpdate() { + if(this.props.piece.num_editions === 0 && typeof this.state.pollingIntervalIndex === 'undefined') { + this.startPolling(); + } + }, + + componentWillUnmount() { + clearInterval(this.state.pollingIntervalIndex); + }, + + startPolling() { + // start polling until editions are defined + let pollingIntervalIndex = setInterval(() => { + EditionListActions.fetchEditionList(this.props.piece.id) + .then((res) => { + + clearInterval(this.state.pollingIntervalIndex); + + PieceListActions.updatePropertyForPiece({ + pieceId: this.props.piece.id, + key: 'num_editions', + value: res.editions[0].num_editions + }); + + EditionListActions.toggleEditionList(this.props.piece.id); + + }) + .catch(() => { + /* Ignore and keep going */ + }); + }, 5000); + + this.setState({ + pollingIntervalIndex + }); + }, render: function () { - if (this.props.piece.constructor === Array){ + let piece = this.props.piece; + + let availableAcls = getAvailableAcls(piece); + if (availableAcls.indexOf('editions') < -1 || piece.num_editions > 0){ return null; } - let availableAcls = getAvailableAcls([this.props.piece]); - if (availableAcls.indexOf('editions') === -1){ - return null; + + if(piece.num_editions === 0) { + return ( + + ); + } else { + return ( + + ); } - return ( - - ); } }); diff --git a/js/components/ascribe_detail/edition.js b/js/components/ascribe_detail/edition.js index ea9b44c3..a47f2148 100644 --- a/js/components/ascribe_detail/edition.js +++ b/js/components/ascribe_detail/edition.js @@ -5,7 +5,6 @@ import Router from 'react-router'; import Row from 'react-bootstrap/lib/Row'; import Col from 'react-bootstrap/lib/Col'; -import Button from 'react-bootstrap/lib/Button'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; import UserActions from '../../actions/user_actions'; @@ -22,7 +21,6 @@ import Property from './../ascribe_forms/property'; import EditionDetailProperty from './detail_property'; import InputTextAreaToggable from './../ascribe_forms/input_textarea_toggable'; -import EditionHeader from './header'; import EditionFurtherDetails from './further_details'; //import PieceExtraDataForm from './../ascribe_forms/form_piece_extradata'; @@ -38,7 +36,6 @@ import GlobalNotificationActions from '../../actions/global_notification_actions import apiUrls from '../../constants/api_urls'; import AppConstants from '../../constants/application_constants'; -import { getCookie } from '../../utils/fetch_api_utils'; import { getLangText } from '../../utils/lang_utils'; let Link = Router.Link; @@ -76,7 +73,12 @@ let Edition = React.createClass({ content={this.props.edition}/> - +
+ {this.props.edition.title}
} /> + + +
+ diff --git a/js/components/ascribe_detail/header.js b/js/components/ascribe_detail/header.js deleted file mode 100644 index e9226a85..00000000 --- a/js/components/ascribe_detail/header.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -import React from 'react'; - -import EditionDetailProperty from './detail_property'; - - -let Header = React.createClass({ - propTypes: { - content: React.PropTypes.object - }, - - render() { - var titleHtml =
{this.props.content.title}
; - return ( -
- - - -
-
- ); - } -}); - -export default Header; \ No newline at end of file diff --git a/js/components/ascribe_detail/piece.js b/js/components/ascribe_detail/piece.js index d37addea..ec2bcb5a 100644 --- a/js/components/ascribe_detail/piece.js +++ b/js/components/ascribe_detail/piece.js @@ -15,21 +15,14 @@ import UserStore from '../../stores/user_store'; import MediaContainer from './media_container'; -import Header from './header'; +import EditionDetailProperty from './detail_property'; -import Form from './../ascribe_forms/form'; -import Property from './../ascribe_forms/property'; - -import RequestActionForm from './../ascribe_forms/form_request_action'; -import EditionActions from '../../actions/edition_actions'; import AclButtonList from './../ascribe_buttons/acl_button_list'; +import CreateEditionsForm from '../ascribe_forms/create_editions_form'; +import CreateEditionsButton from '../ascribe_buttons/create_editions_button'; - -import GlobalNotificationModel from '../../models/global_notification_model'; -import GlobalNotificationActions from '../../actions/global_notification_actions'; - -import apiUrls from '../../constants/api_urls'; import { getLangText } from '../../utils/lang_utils'; +import { mergeOptions } from '../../utils/general_utils'; /** * This is the component that implements display-specific functionality @@ -41,7 +34,12 @@ let Piece = React.createClass({ }, getInitialState() { - return UserStore.getState(); + return mergeOptions( + UserStore.getState(), + { + showCreateEditionsDialog: false + } + ); }, componentDidMount() { @@ -57,8 +55,28 @@ let Piece = React.createClass({ this.setState(state); }, - render() { + toggleCreateEditionsDialog() { + this.setState({ + showCreateEditionsDialog: !this.state.showCreateEditionsDialog + }); + }, + getCreateEditionsDialog() { + if(this.props.piece.num_editions < 1 && this.state.showCreateEditionsDialog) { + return ( +
+ +
+
+ ); + } else { + return (
); + } + }, + + render() { return ( @@ -66,12 +84,29 @@ let Piece = React.createClass({ content={this.props.piece}/> -
- +
+ {this.props.piece.title}
} /> + + + {this.props.piece.num_editions > 0 ? : null} +
+ +
+ +
+ + + + + + {this.getCreateEditionsDialog()} + -1 @@ -85,42 +120,10 @@ let Piece = React.createClass({ otherData={this.props.piece.other_data} handleSuccess={this.props.loadPiece}/> - ); } }); -let PieceSummary = React.createClass({ - propTypes: { - piece: React.PropTypes.object - }, - getActions(){ - let actions = ( - - - - - ); - return actions; - //return null; - }, - render() { - return ( -
- - {this.getActions()} -
-
- ); - - } -}); - - export default Piece; diff --git a/js/components/ascribe_forms/create_editions_form.js b/js/components/ascribe_forms/create_editions_form.js new file mode 100644 index 00000000..335851f9 --- /dev/null +++ b/js/components/ascribe_forms/create_editions_form.js @@ -0,0 +1,50 @@ +'use strict'; + +import React from 'react'; + +import Form from '../ascribe_forms/form'; +import Property from '../ascribe_forms/property'; + +import apiUrls from '../../constants/api_urls'; + +import { getLangText } from '../../utils/lang_utils'; + +let CreateEditionsForm = React.createClass({ + + propTypes: { + handleSuccess: React.PropTypes.func, + pieceId: React.PropTypes.number + }, + + getFormData(){ + return { + piece_id: parseInt(this.props.pieceId, 10) + }; + }, + + render() { + return ( +
+ + + }> + + + +
+ ); + } +}); + +export default CreateEditionsForm; \ No newline at end of file diff --git a/js/constants/languages.js b/js/constants/languages.js index c21bd0ad..d718fa69 100644 --- a/js/constants/languages.js +++ b/js/constants/languages.js @@ -210,6 +210,7 @@ const languages = { 'I agree to the Terms of Service': 'I agree to the Terms of Service', 'read': 'read', 'If your email address exists in our database, you will receive a password recovery link in a few minutes.': 'If your email address exists in our database, you will receive a password recovery link in a few minutes.', + 'REGISTREE': 'REGISTREE', }, 'de': { 'ID': 'ID', @@ -420,6 +421,7 @@ const languages = { 'I agree to the Terms of Service': 'I agree to the Terms of Service', 'read': 'read', 'If your email address exists in our database, you will receive a password recovery link in a few minutes.': 'If your email address exists in our database, you will receive a password recovery link in a few minutes.', + 'REGISTREE': 'REGISTREE', }, 'fr': { 'ID': 'ID', @@ -630,6 +632,7 @@ const languages = { 'I agree to the Terms of Service': 'I agree to the Terms of Service', 'read': 'read', 'If your email address exists in our database, you will receive a password recovery link in a few minutes.': 'Si votre adresse électronique existe dans notre base de données, vous recevrez un lien de récupération de mot de passe dans quelques minutes.', + 'REGISTREE': 'REGISTREE', } };