diff --git a/js/components/ascribe_detail/media_container.js b/js/components/ascribe_detail/media_container.js
index 529817c3..6ac2f745 100644
--- a/js/components/ascribe_detail/media_container.js
+++ b/js/components/ascribe_detail/media_container.js
@@ -19,7 +19,33 @@ const EMBED_IFRAME_HEIGHT = {
let MediaContainer = React.createClass({
propTypes: {
- content: React.PropTypes.object
+ content: React.PropTypes.object,
+ refreshObject: React.PropTypes.func
+ },
+
+ getInitialState() {
+ return {timerId: null};
+ },
+
+ componentDidMount() {
+ if (!this.props.content.digital_work) {
+ return;
+ }
+ let isEncoding = this.props.content.digital_work.isEncoding;
+ if (this.props.content.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
+ let timerId = window.setInterval(this.props.refreshObject, 10000);
+ this.setState({timerId: timerId});
+ }
+ },
+
+ componentWillUpdate() {
+ if (this.props.content.digital_work.isEncoding === 100) {
+ window.clearInterval(this.state.timerId);
+ }
+ },
+
+ componentWillUnmount() {
+ window.clearInterval(this.state.timerId);
},
render() {
diff --git a/js/components/ascribe_detail/piece.js b/js/components/ascribe_detail/piece.js
index 3fabb055..ed312f5f 100644
--- a/js/components/ascribe_detail/piece.js
+++ b/js/components/ascribe_detail/piece.js
@@ -1,38 +1,14 @@
'use strict';
import React from 'react';
-import Router from 'react-router';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
-import DetailProperty from './detail_property';
-
-import UserActions from '../../actions/user_actions';
-import UserStore from '../../stores/user_store';
-
-import PieceListActions from '../../actions/piece_list_actions';
-import PieceListStore from '../../stores/piece_list_store';
-
-import EditionListActions from '../../actions/edition_list_actions';
-
import PieceActions from '../../actions/piece_actions';
import MediaContainer from './media_container';
-import EditionDetailProperty from './detail_property';
-
-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 GlobalNotificationModel from '../../models/global_notification_model';
-import GlobalNotificationActions from '../../actions/global_notification_actions';
-
-import { getLangText } from '../../utils/lang_utils';
-import { mergeOptions } from '../../utils/general_utils';
-
/**
* This is the component that implements display-specific functionality
@@ -40,97 +16,16 @@ import { mergeOptions } from '../../utils/general_utils';
let Piece = React.createClass({
propTypes: {
piece: React.PropTypes.object,
+ header: React.PropTypes.object,
+ subheader: React.PropTypes.object,
+ buttons: React.PropTypes.object,
loadPiece: React.PropTypes.func,
children: React.PropTypes.object
},
- mixins: [Router.Navigation],
- getInitialState() {
- return mergeOptions(
- UserStore.getState(),
- PieceListStore.getState(),
- {
- showCreateEditionsDialog: false
- }
- );
- },
-
- componentDidMount() {
- UserStore.listen(this.onChange);
- PieceListStore.listen(this.onChange);
- UserActions.fetchCurrentUser();
- },
-
- componentWillUnmount() {
- UserStore.unlisten(this.onChange);
- PieceListStore.unlisten(this.onChange);
- },
-
- onChange(state) {
- this.setState(state);
- },
-
- 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.transitionTo('pieces');
- },
-
- getCreateEditionsDialog() {
- if(this.props.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);
+ updateObject() {
+ return PieceActions.fetchOne(this.props.piece.id);
},
render() {
@@ -138,38 +33,14 @@ let Piece = React.createClass({
+ {this.props.header}
+ {this.props.subheader}
+ {this.props.buttons}
-
-
-
-
-
- {this.getCreateEditionsDialog()}
{this.props.children}
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 8e3a5750..2b607516 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -1,37 +1,59 @@
'use strict';
import React from 'react';
+import Router from 'react-router';
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 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 GlobalNotificationModel from '../../models/global_notification_model';
+import GlobalNotificationActions from '../../actions/global_notification_actions';
+
import AppConstants from '../../constants/application_constants';
+import { mergeOptions } from '../../utils/general_utils';
+import { getLangText } from '../../utils/lang_utils';
/**
* This is the component that implements resource/data specific functionality
*/
let PieceContainer = React.createClass({
- getInitialState() {
- return PieceStore.getState();
- },
- onChange(state) {
- this.setState(state);
- if (!state.piece.digital_work) {
- return;
- }
- let isEncoding = state.piece.digital_work.isEncoding;
- if (state.piece.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
- let timerId = window.setInterval(() => PieceActions.fetchOne(this.props.params.pieceId), 10000);
- this.setState({timerId: timerId});
- }
+ mixins: [Router.Navigation],
+
+ getInitialState() {
+ return mergeOptions(
+ UserStore.getState(),
+ PieceListStore.getState(),
+ PieceStore.getState(),
+ {
+ showCreateEditionsDialog: false
+ }
+ );
},
componentDidMount() {
+ UserStore.listen(this.onChange);
+ PieceListStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
PieceStore.listen(this.onChange);
PieceActions.fetchOne(this.props.params.pieceId);
},
@@ -42,21 +64,121 @@ let PieceContainer = React.createClass({
// as it will otherwise display wrong/old data once the user loads
// the piece detail a second time
PieceActions.updatePiece({});
- window.clearInterval(this.state.timerId);
PieceStore.unlisten(this.onChange);
+ UserStore.unlisten(this.onChange);
+ PieceListStore.unlisten(this.onChange);
},
+ onChange(state) {
+ 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.transitionTo('pieces');
+ },
+
+ 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);
+ },
+
render() {
if('title' in this.state.piece) {
return (
+ loadPiece={this.loadPiece}
+ header={
+