1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-30 13:41:57 +02:00

Add Lumenus specific data forms to edition and piece details

This commit is contained in:
Brett Sun 2015-10-28 11:26:54 +01:00
parent 82b49fc653
commit c72a5aa308
11 changed files with 170 additions and 50 deletions

View File

@ -40,6 +40,8 @@ import { getLangText } from '../../utils/lang_utils';
*/ */
let Edition = React.createClass({ let Edition = React.createClass({
propTypes: { propTypes: {
actionPanelButtonListType: React.PropTypes.func,
furtherDetailsType: React.PropTypes.func,
edition: React.PropTypes.object, edition: React.PropTypes.object,
loadEdition: React.PropTypes.func, loadEdition: React.PropTypes.func,
location: React.PropTypes.object location: React.PropTypes.object
@ -47,6 +49,12 @@ let Edition = React.createClass({
mixins: [History], mixins: [History],
getDefaultProps() {
return {
furtherDetailsType: FurtherDetails
};
},
getInitialState() { getInitialState() {
return UserStore.getState(); return UserStore.getState();
}, },
@ -74,6 +82,8 @@ let Edition = React.createClass({
}, },
render() { render() {
let FurtherDetailsType = this.props.furtherDetailsType;
return ( return (
<Row> <Row>
<Col md={6}> <Col md={6}>
@ -89,6 +99,7 @@ let Edition = React.createClass({
<hr/> <hr/>
</div> </div>
<EditionSummary <EditionSummary
actionPanelButtonListType={this.props.actionPanelButtonListType}
edition={this.props.edition} edition={this.props.edition}
currentUser={this.state.currentUser} currentUser={this.state.currentUser}
handleSuccess={this.props.loadEdition}/> handleSuccess={this.props.loadEdition}/>
@ -151,13 +162,13 @@ let Edition = React.createClass({
show={this.props.edition.acl.acl_edit show={this.props.edition.acl.acl_edit
|| Object.keys(this.props.edition.extra_data).length > 0 || Object.keys(this.props.edition.extra_data).length > 0
|| this.props.edition.other_data.length > 0}> || this.props.edition.other_data.length > 0}>
<FurtherDetails <FurtherDetailsType
editable={this.props.edition.acl.acl_edit} editable={this.props.edition.acl.acl_edit}
pieceId={this.props.edition.parent} pieceId={this.props.edition.parent}
extraData={this.props.edition.extra_data} extraData={this.props.edition.extra_data}
otherData={this.props.edition.other_data} otherData={this.props.edition.other_data}
handleSuccess={this.props.loadEdition} handleSuccess={this.props.loadEdition}
location={this.props.location}/> location={this.props.location} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
@ -174,6 +185,7 @@ let Edition = React.createClass({
let EditionSummary = React.createClass({ let EditionSummary = React.createClass({
propTypes: { propTypes: {
actionPanelButtonListType: React.PropTypes.func,
edition: React.PropTypes.object, edition: React.PropTypes.object,
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,
handleSuccess: React.PropTypes.func handleSuccess: React.PropTypes.func
@ -198,7 +210,7 @@ let EditionSummary = React.createClass({
}, },
render() { render() {
let { edition, currentUser } = this.props; let { actionPanelButtonListType, edition, currentUser } = this.props;
return ( return (
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<EditionDetailProperty <EditionDetailProperty
@ -214,6 +226,7 @@ let EditionSummary = React.createClass({
<LicenseDetail license={edition.license_type}/> <LicenseDetail license={edition.license_type}/>
{this.getStatus()} {this.getStatus()}
<EditionActionPanel <EditionActionPanel
actionPanelButtonListType={actionPanelButtonListType}
edition={edition} edition={edition}
currentUser={currentUser} currentUser={currentUser}
handleSuccess={this.handleSuccess} /> handleSuccess={this.handleSuccess} />

View File

@ -34,6 +34,7 @@ import { getLangText } from '../../utils/lang_utils';
*/ */
let EditionActionPanel = React.createClass({ let EditionActionPanel = React.createClass({
propTypes: { propTypes: {
actionPanelButtonListType: React.PropTypes.func,
edition: React.PropTypes.object, edition: React.PropTypes.object,
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,
handleSuccess: React.PropTypes.func handleSuccess: React.PropTypes.func
@ -41,6 +42,12 @@ let EditionActionPanel = React.createClass({
mixins: [History], mixins: [History],
getDefaultProps() {
return {
actionPanelButtonListType: AclButtonList
};
},
getInitialState() { getInitialState() {
return PieceListStore.getState(); return PieceListStore.getState();
}, },
@ -85,7 +92,8 @@ let EditionActionPanel = React.createClass({
}, },
render(){ render(){
let {edition, currentUser} = this.props; let { edition, currentUser } = this.props;
let ActionPanelButtonListType = this.props.actionPanelButtonListType;
if (edition && if (edition &&
edition.notifications && edition.notifications &&
@ -102,7 +110,7 @@ let EditionActionPanel = React.createClass({
return ( return (
<Row> <Row>
<Col md={12}> <Col md={12}>
<AclButtonList <ActionPanelButtonListType
className="text-center ascribe-button-list" className="text-center ascribe-button-list"
availableAcls={edition.acl} availableAcls={edition.acl}
editions={[edition]} editions={[edition]}
@ -119,8 +127,9 @@ let EditionActionPanel = React.createClass({
name="bitcoin_id" name="bitcoin_id"
hidden={true}> hidden={true}>
<input <input
type="text" type="text"
value={edition.bitcoin_id} /> value={edition.bitcoin_id}
readOnly />
</Property> </Property>
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit"> <Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
{getLangText('WITHDRAW TRANSFER')} {getLangText('WITHDRAW TRANSFER')}
@ -139,8 +148,9 @@ let EditionActionPanel = React.createClass({
name="bitcoin_id" name="bitcoin_id"
hidden={true}> hidden={true}>
<input <input
type="text" type="text"
value={edition.bitcoin_id} /> value={edition.bitcoin_id}
readOnly />
</Property> </Property>
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit"> <Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
{getLangText('WITHDRAW CONSIGN')} {getLangText('WITHDRAW CONSIGN')}
@ -158,7 +168,7 @@ let EditionActionPanel = React.createClass({
<DeleteButton <DeleteButton
handleSuccess={this.handleDeleteSuccess} handleSuccess={this.handleDeleteSuccess}
editions={[edition]}/> editions={[edition]}/>
</AclButtonList> </ActionPanelButtonListType>
</Col> </Col>
</Row> </Row>
); );
@ -166,4 +176,4 @@ let EditionActionPanel = React.createClass({
} }
}); });
export default EditionActionPanel; export default EditionActionPanel;

View File

@ -17,6 +17,8 @@ import { setDocumentTitle } from '../../utils/dom_utils';
*/ */
let EditionContainer = React.createClass({ let EditionContainer = React.createClass({
propTypes: { propTypes: {
actionPanelButtonListType: React.PropTypes.func,
furtherDetailsType: React.PropTypes.func,
location: React.PropTypes.object location: React.PropTypes.object
}, },
@ -71,6 +73,8 @@ let EditionContainer = React.createClass({
return ( return (
<Edition <Edition
actionPanelButtonListType={this.props.actionPanelButtonListType}
furtherDetailsType={this.props.furtherDetailsType}
edition={this.state.edition} edition={this.state.edition}
loadEdition={this.loadEdition} loadEdition={this.loadEdition}
location={this.props.location}/> location={this.props.location}/>

View File

@ -46,11 +46,18 @@ import { setDocumentTitle } from '../../utils/dom_utils';
*/ */
let PieceContainer = React.createClass({ let PieceContainer = React.createClass({
propTypes: { propTypes: {
furtherDetailsType: React.PropTypes.func,
location: React.PropTypes.object location: React.PropTypes.object
}, },
mixins: [History], mixins: [History],
getDefaultProps() {
return {
furtherDetailsType: FurtherDetails
};
},
getInitialState() { getInitialState() {
return mergeOptions( return mergeOptions(
UserStore.getState(), UserStore.getState(),
@ -83,7 +90,7 @@ let PieceContainer = React.createClass({
onChange(state) { onChange(state) {
/* /*
ATTENTION: ATTENTION:
THIS IS JUST A TEMPORARY USABILITY FIX THAT ESSENTIALLY REMOVES THE LOAN BUTTON THIS IS JUST A TEMPORARY USABILITY FIX THAT ESSENTIALLY REMOVES THE LOAN BUTTON
FROM THE PIECE DETAIL PAGE SO THAT USERS DO NOT CONFUSE A PIECE WITH AN EDITION. FROM THE PIECE DETAIL PAGE SO THAT USERS DO NOT CONFUSE A PIECE WITH AN EDITION.
@ -212,6 +219,7 @@ let PieceContainer = React.createClass({
render() { render() {
if(this.state.piece && this.state.piece.title) { if(this.state.piece && this.state.piece.title) {
let FurtherDetailsType = this.props.furtherDetailsType;
setDocumentTitle([this.state.piece.artist_name, this.state.piece.title].join(', ')); setDocumentTitle([this.state.piece.artist_name, this.state.piece.title].join(', '));
return ( return (
@ -263,7 +271,7 @@ let PieceContainer = React.createClass({
|| Object.keys(this.state.piece.extra_data).length > 0 || Object.keys(this.state.piece.extra_data).length > 0
|| this.state.piece.other_data.length > 0} || this.state.piece.other_data.length > 0}
defaultExpanded={true}> defaultExpanded={true}>
<FurtherDetails <FurtherDetailsType
editable={this.state.piece.acl.acl_edit} editable={this.state.piece.acl.acl_edit}
pieceId={this.state.piece.id} pieceId={this.state.piece.id}
extraData={this.state.piece.extra_data} extraData={this.state.piece.extra_data}

View File

@ -0,0 +1,30 @@
'use strict';
import React from 'react';
import LumenusFurtherDetails from './lumenus_further_details';
import LumenusAclButtonList from '../lumenus_buttons/lumenus_acl_button_list';
import EditionContainer from '../../../../../ascribe_detail/edition_container';
let LumenusEditionContainer = React.createClass({
propTypes: {
params: React.PropTypes.object,
location: React.PropTypes.object
},
render() {
return (
<div>
<EditionContainer
params={this.props.params}
actionPanelButtonListType={LumenusAclButtonList}
furtherDetailsType={LumenusFurtherDetails}
location={this.props.location} />
</div>
);
}
});
export default LumenusEditionContainer;

View File

@ -0,0 +1,46 @@
'use strict';
import React from 'react';
import LumenusAdditionalDataForm from '../lumenus_forms/lumenus_additional_data_form'
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
let FurtherDetails = React.createClass({
propTypes: {
pieceId: React.PropTypes.number,
extraData: React.PropTypes.object,
otherData: React.PropTypes.arrayOf(React.PropTypes.object),
handleSuccess: React.PropTypes.func,
location: React.PropTypes.object
},
showNotification() {
this.props.handleSuccess();
let notification = new GlobalNotificationModel('Further details updated', 'success');
GlobalNotificationActions.appendGlobalNotification(notification);
},
render() {
const { pieceId, extraData, otherData, handleSuccess, location } = this.props;
// Instead of grabbing the entire piece from the PieceStore and making this component
// stateful, we can put together a piece for the additional form solely based on the props
const piece = {
id: pieceId,
extra_data: extraData,
other_data: otherData
};
return (
<LumenusAdditionalDataForm
piece={piece}
handleSuccess={this.showNotification}
isInline
location={location} />
);
}
});
export default FurtherDetails;

View File

@ -0,0 +1,27 @@
'use strict';
import React from 'react';
import LumenusFurtherDetails from './lumenus_further_details';
import PieceContainer from '../../../../../ascribe_detail/piece_container';
let LumenusPieceContainer = React.createClass({
propTypes: {
params: React.PropTypes.object,
location: React.PropTypes.object
},
render() {
return (
<div>
<PieceContainer
params={this.props.params}
furtherDetailsType={LumenusFurtherDetails}
location={this.props.location} />
</div>
);
}
});
export default LumenusPieceContainer;

View File

@ -23,7 +23,11 @@ import { getLangText } from '../../../../../../utils/lang_utils';
let LumenusAdditionalDataForm = React.createClass({ let LumenusAdditionalDataForm = React.createClass({
propTypes: { propTypes: {
handleSuccess: React.PropTypes.func, handleSuccess: React.PropTypes.func,
piece: React.PropTypes.object.isRequired, piece: React.PropTypes.shape({
id: React.PropTypes.number,
extra_data: React.PropTypes.object,
other_data: React.PropTypes.arrayOf(React.PropTypes.object)
}).isRequired,
isInline: React.PropTypes.bool, isInline: React.PropTypes.bool,
location: React.PropTypes.object location: React.PropTypes.object
}, },
@ -78,7 +82,7 @@ let LumenusAdditionalDataForm = React.createClass({
let { piece, isInline, handleSuccess } = this.props; let { piece, isInline, handleSuccess } = this.props;
let buttons, spinner, heading; let buttons, spinner, heading;
if(!isInline) { if (!isInline) {
buttons = ( buttons = (
<button <button
type="submit" type="submit"
@ -103,7 +107,7 @@ let LumenusAdditionalDataForm = React.createClass({
); );
} }
if(piece && piece.id) { if (piece && piece.id) {
return ( return (
<Form <Form
className="ascribe-form-bordered" className="ascribe-form-bordered"
@ -130,7 +134,7 @@ let LumenusAdditionalDataForm = React.createClass({
rows={1} rows={1}
defaultValue={piece.extra_data.artist_bio} defaultValue={piece.extra_data.artist_bio}
placeholder={getLangText('Enter a biography of the artist...')} placeholder={getLangText('Enter a biography of the artist...')}
required/> required="required"/>
</Property> </Property>
<Property <Property
name='work_description' name='work_description'
@ -139,7 +143,7 @@ let LumenusAdditionalDataForm = React.createClass({
rows={1} rows={1}
defaultValue={piece.extra_data.work_description} defaultValue={piece.extra_data.work_description}
placeholder={getLangText('Enter a description of the work...')} placeholder={getLangText('Enter a description of the work...')}
required/> required="required"/>
</Property> </Property>
<Property <Property
name='tech_details' name='tech_details'
@ -148,7 +152,7 @@ let LumenusAdditionalDataForm = React.createClass({
rows={1} rows={1}
defaultValue={piece.extra_data.tech_details} defaultValue={piece.extra_data.tech_details}
placeholder={getLangText('Enter technological details about the work was produced...')} placeholder={getLangText('Enter technological details about the work was produced...')}
required/> required="required"/>
</Property> </Property>
<Property <Property
name='display_instructions' name='display_instructions'
@ -157,7 +161,7 @@ let LumenusAdditionalDataForm = React.createClass({
rows={1} rows={1}
defaultValue={piece.extra_data.display_instructions} defaultValue={piece.extra_data.display_instructions}
placeholder={getLangText('Enter instructions on how to best display the work...')} placeholder={getLangText('Enter instructions on how to best display the work...')}
required/> required="required"/>
</Property> </Property>
</Form> </Form>
); );

View File

@ -6,35 +6,14 @@ import LumenusAclButtonList from './lumenus_buttons/lumenus_acl_button_list';
import PieceList from '../../../../piece_list'; import PieceList from '../../../../piece_list';
import UserActions from '../../../../../actions/user_actions';
import UserStore from '../../../../../stores/user_store';
import { getLangText } from '../../../../../utils/lang_utils'; import { getLangText } from '../../../../../utils/lang_utils';
import { setDocumentTitle } from '../../../../../utils/dom_utils'; import { setDocumentTitle } from '../../../../../utils/dom_utils';
let LumenusPieceList = React.createClass({ let LumenusPieceList = React.createClass({
propTypes: { propTypes: {
location: React.PropTypes.object location: React.PropTypes.object
}, },
getInitialState() {
return UserStore.getState();
},
componentDidMount() {
UserStore.listen(this.onChange);
UserActions.fetchCurrentUser();
},
componentWillUnmount() {
UserStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
render() { render() {
setDocumentTitle(getLangText('Collection')); setDocumentTitle(getLangText('Collection'));

View File

@ -6,19 +6,17 @@ import { History } from 'react-router';
import Col from 'react-bootstrap/lib/Col'; import Col from 'react-bootstrap/lib/Col';
import Row from 'react-bootstrap/lib/Row'; import Row from 'react-bootstrap/lib/Row';
import LumenusAdditionalDataForm from './lumenus_forms/lumenus_additional_data_form';
import Property from '../../../../ascribe_forms/property'; import Property from '../../../../ascribe_forms/property';
import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
import PieceListStore from '../../../../../stores/piece_list_store';
import PieceListActions from '../../../../../actions/piece_list_actions';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import UserActions from '../../../../../actions/user_actions'; import UserActions from '../../../../../actions/user_actions';
import PieceStore from '../../../../../stores/piece_store'; import PieceStore from '../../../../../stores/piece_store';
import PieceActions from '../../../../../actions/piece_actions'; import PieceActions from '../../../../../actions/piece_actions';
import PieceListStore from '../../../../../stores/piece_list_store';
import LumenusAdditionalDataForm from './lumenus_forms/lumenus_additional_data_form'; import PieceListActions from '../../../../../actions/piece_list_actions';
import SlidesContainer from '../../../../ascribe_slides_container/slides_container'; import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
@ -26,7 +24,6 @@ import { getLangText } from '../../../../../utils/lang_utils';
import { setDocumentTitle } from '../../../../../utils/dom_utils'; import { setDocumentTitle } from '../../../../../utils/dom_utils';
import { mergeOptions } from '../../../../../utils/general_utils'; import { mergeOptions } from '../../../../../utils/general_utils';
let LumenusRegisterPiece = React.createClass({ let LumenusRegisterPiece = React.createClass({
propTypes: { propTypes: {
location: React.PropTypes.object location: React.PropTypes.object

View File

@ -31,6 +31,8 @@ import IkonotvContractNotifications from './components/ikonotv/ikonotv_contract_
import LumenusPieceList from './components/lumenus/lumenus_piece_list'; import LumenusPieceList from './components/lumenus/lumenus_piece_list';
import LumenusRegisterPiece from './components/lumenus/lumenus_register_piece'; import LumenusRegisterPiece from './components/lumenus/lumenus_register_piece';
import LumenusPieceContainer from './components/lumenus/lumenus_detail/lumenus_piece_container';
import LumenusEditionContainer from './components/lumenus/lumenus_detail/lumenus_edition_container';
import CCRegisterPiece from './components/cc/cc_register_piece'; import CCRegisterPiece from './components/cc/cc_register_piece';
@ -181,8 +183,8 @@ let ROUTES = {
path='collection' path='collection'
component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(LumenusPieceList)} component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(LumenusPieceList)}
headerTitle='COLLECTION'/> headerTitle='COLLECTION'/>
<Route path='pieces/:pieceId' component={PieceContainer} /> <Route path='pieces/:pieceId' component={LumenusPieceContainer} />
<Route path='editions/:editionId' component={EditionContainer} /> <Route path='editions/:editionId' component={LumenusEditionContainer} />
<Route path='verify' component={CoaVerifyContainer} /> <Route path='verify' component={CoaVerifyContainer} />
<Route path='*' component={ErrorNotFoundPage} /> <Route path='*' component={ErrorNotFoundPage} />
</Route> </Route>