'use strict'; import React from 'react'; import { History } from 'react-router'; import Moment from 'moment'; import ReactError from '../../mixins/react_error'; import { ResourceNotFoundError } from '../../models/errors'; import PieceActions from '../../actions/piece_actions'; import PieceStore from '../../stores/piece_store'; import PieceListActions from '../../actions/piece_list_actions'; import PieceListStore from '../../stores/piece_list_store'; import UserActions from '../../actions/user_actions'; import UserStore from '../../stores/user_store'; import EditionListActions from '../../actions/edition_list_actions'; import Piece from './piece'; import CollapsibleParagraph from './../ascribe_collapsible/collapsible_paragraph'; import FurtherDetails from './further_details'; import DetailProperty from './detail_property'; import LicenseDetail from './license_detail'; import HistoryIterator from './history_iterator'; 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 DeleteButton from '../ascribe_buttons/delete_button'; import AclInformation from '../ascribe_buttons/acl_information'; import AclProxy from '../acl_proxy'; import ListRequestActions from '../ascribe_forms/list_form_request_actions'; import GlobalNotificationModel from '../../models/global_notification_model'; import GlobalNotificationActions from '../../actions/global_notification_actions'; import Note from './note'; import ApiUrls from '../../constants/api_urls'; import AscribeSpinner from '../ascribe_spinner'; import { mergeOptions } from '../../utils/general_utils'; import { getLangText } from '../../utils/lang_utils'; import { setDocumentTitle } from '../../utils/dom_utils'; /** * This is the component that implements resource/data specific functionality */ let PieceContainer = React.createClass({ propTypes: { params: React.PropTypes.object }, mixins: [History, ReactError], getInitialState() { return mergeOptions( UserStore.getState(), PieceListStore.getState(), PieceStore.getState(), { showCreateEditionsDialog: false } ); }, componentDidMount() { UserStore.listen(this.onChange); PieceListStore.listen(this.onChange); PieceStore.listen(this.onChange); // Every time we enter the piece detail page, just reset the piece // store as it will otherwise display wrong/old data once the user loads // the piece detail a second time PieceActions.updatePiece({}); this.loadPiece(); UserActions.fetchCurrentUser(); }, componentDidUpdate() { const { pieceError } = this.state; if(pieceError && pieceError.status === 404) { this.throws(new ResourceNotFoundError(getLangText('Oops, the piece you\'re looking for doesn\'t exist.'))); } }, componentWillUnmount() { PieceStore.unlisten(this.onChange); UserStore.unlisten(this.onChange); PieceListStore.unlisten(this.onChange); }, onChange(state) { /* ATTENTION: 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. IT SHOULD BE REMOVED AND REPLACED WITH A BETTER SOLUTION ASAP! ALSO, WE ENABLED THE LOAN BUTTON FOR IKONOTV TO LET THEM LOAN ON A PIECE LEVEL */ if(state && state.piece && state.piece.acl && typeof state.piece.acl.acl_loan !== 'undefined') { let pieceState = mergeOptions({}, state.piece); pieceState.acl.acl_loan = false; this.setState({ piece: pieceState }); } else { this.setState(state); } }, loadPiece() { PieceActions.fetchOne(this.props.params.pieceId); }, toggleCreateEditionsDialog() { this.setState({ showCreateEditionsDialog: !this.state.showCreateEditionsDialog }); }, handleEditionCreationSuccess() { PieceActions.updateProperty({key: 'num_editions', value: 0}); PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc, this.state.filterBy); this.toggleCreateEditionsDialog(); }, handleDeleteSuccess(response) { PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc, this.state.filterBy); // since we're deleting a piece, we just need to close // all editions dialogs and not reload them EditionListActions.closeAllEditionLists(); EditionListActions.clearAllEditionSelections(); let notification = new GlobalNotificationModel(response.notification, 'success'); GlobalNotificationActions.appendGlobalNotification(notification); this.history.pushState(null, '/collection'); }, getCreateEditionsDialog() { if(this.state.piece.num_editions < 1 && this.state.showCreateEditionsDialog) { return (

); } else { return (
); } }, handlePollingSuccess(pieceId, numEditions) { // we need to refresh the num_editions property of the actual piece we're looking at PieceActions.updateProperty({ key: 'num_editions', value: numEditions }); // as well as its representation in the collection // btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion // list item also uses the firstEdition property which we can only get from the server in that case. // Therefore we need to at least refetch the changed piece from the server or on our case simply all PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc, this.state.filterBy); let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000); GlobalNotificationActions.appendGlobalNotification(notification); }, getId() { return {'id': this.state.piece.id}; }, getActions() { const { piece, currentUser } = this.state; if (piece && piece.notifications && piece.notifications.length > 0) { return ( ); } else { return ( ); } }, render() { if(this.state.piece && this.state.piece.id) { setDocumentTitle([this.state.piece.artist_name, this.state.piece.title].join(', ')); return (

{this.state.piece.title}

{this.state.piece.num_editions > 0 ? : null}
} subheader={
} buttons={this.getActions()}> {this.getCreateEditionsDialog()} 0}> 0 || this.state.piece.other_data.length > 0} defaultExpanded={true}>
); } else { return (
); } } }); export default PieceContainer;