mirror of
https://github.com/ascribe/onion.git
synced 2024-06-30 21:52:08 +02:00
Merge remote-tracking branch 'origin/AD-419-decouple-piece-registration-from-' into AD-419-decouple-piece-registration-from-
Conflicts: js/components/ascribe_detail/edition.js
This commit is contained in:
commit
982b701a5c
|
@ -8,6 +8,7 @@ class EditionListActions {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.generateActions(
|
this.generateActions(
|
||||||
'updateEditionList',
|
'updateEditionList',
|
||||||
|
'refreshEditionList',
|
||||||
'selectEdition',
|
'selectEdition',
|
||||||
'clearAllEditionSelections',
|
'clearAllEditionSelections',
|
||||||
'closeAllEditionLists',
|
'closeAllEditionLists',
|
||||||
|
@ -16,7 +17,7 @@ class EditionListActions {
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc) {
|
fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc) {
|
||||||
if(!orderBy && typeof orderAsc == 'undefined') {
|
if(!orderBy && typeof orderAsc === 'undefined') {
|
||||||
orderBy = 'edition_number';
|
orderBy = 'edition_number';
|
||||||
orderAsc = true;
|
orderAsc = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||||
import PieceListActions from '../../actions/piece_list_actions';
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
import EditionListActions from '../../actions/edition_list_actions';
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
let Link = Router.Link;
|
||||||
|
@ -63,6 +66,9 @@ let AccordionListItem = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
|
|
||||||
|
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
getCreateEditionsDialog() {
|
getCreateEditionsDialog() {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import UserActions from '../../actions/user_actions';
|
||||||
import UserStore from '../../stores/user_store';
|
import UserStore from '../../stores/user_store';
|
||||||
|
|
||||||
import AclButton from '../ascribe_buttons/acl_button';
|
import AclButton from '../ascribe_buttons/acl_button';
|
||||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
|
||||||
|
|
||||||
let AclButtonList = React.createClass({
|
let AclButtonList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -73,9 +72,6 @@ let AclButtonList = React.createClass({
|
||||||
pieceOrEditions={this.props.editions}
|
pieceOrEditions={this.props.editions}
|
||||||
currentUser={this.state.currentUser}
|
currentUser={this.state.currentUser}
|
||||||
handleSuccess={this.props.handleSuccess} />
|
handleSuccess={this.props.handleSuccess} />
|
||||||
<DeleteButton
|
|
||||||
handleSuccess={this.props.handleSuccess}
|
|
||||||
editions={this.props.editions}/>
|
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,66 +6,71 @@ import Router from 'react-router';
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
|
|
||||||
import EditionDeleteForm from '../ascribe_forms/form_delete_edition';
|
import EditionDeleteForm from '../ascribe_forms/form_delete_edition';
|
||||||
import EditionRemoveFromCollectionForm from '../ascribe_forms/form_remove_editions_from_collection';
|
import PieceDeleteForm from '../ascribe_forms/form_delete_piece';
|
||||||
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import EditionRemoveFromCollectionForm from '../ascribe_forms/form_remove_editions_from_collection';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import PieceRemoveFromCollectionForm from '../ascribe_forms/form_remove_piece_from_collection';
|
||||||
|
|
||||||
|
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
||||||
|
|
||||||
import { getAvailableAcls } from '../../utils/acl_utils';
|
import { getAvailableAcls } from '../../utils/acl_utils';
|
||||||
import { getLangText } from '../../utils/lang_utils.js';
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
|
||||||
import EditionListActions from '../../actions/edition_list_actions';
|
|
||||||
|
|
||||||
let DeleteButton = React.createClass({
|
let DeleteButton = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
editions: React.PropTypes.array.isRequired,
|
editions: React.PropTypes.array,
|
||||||
|
piece: React.PropTypes.object,
|
||||||
handleSuccess: React.PropTypes.func
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [Router.Navigation],
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
showNotification(response) {
|
|
||||||
if (this.props.editions.constructor === Array){
|
|
||||||
this.props.editions
|
|
||||||
.forEach((edition) => {
|
|
||||||
EditionListActions.fetchEditionList(edition.parent);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
EditionListActions.fetchEditionList(this.props.editions.id);
|
|
||||||
}
|
|
||||||
EditionListActions.clearAllEditionSelections();
|
|
||||||
EditionListActions.closeAllEditionLists();
|
|
||||||
this.props.handleSuccess();
|
|
||||||
this.transitionTo('pieces');
|
|
||||||
let notification = new GlobalNotificationModel(response.notification, 'success');
|
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
let availableAcls = getAvailableAcls(this.props.editions);
|
let availableAcls;
|
||||||
let btnDelete = null;
|
let btnDelete;
|
||||||
let content = null;
|
let content;
|
||||||
|
let title;
|
||||||
|
|
||||||
if (availableAcls.acl_delete) {
|
if(this.props.piece && !this.props.editions) {
|
||||||
content = <EditionDeleteForm editions={ this.props.editions }/>;
|
availableAcls = getAvailableAcls([this.props.piece]);
|
||||||
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('DELETE')}</Button>;
|
} else {
|
||||||
|
availableAcls = getAvailableAcls(this.props.editions);
|
||||||
}
|
}
|
||||||
else if (availableAcls.acl_unshare || (this.props.editions.constructor !== Array && this.props.editions.acl.acl_unshare)){
|
|
||||||
content = <EditionRemoveFromCollectionForm editions={ this.props.editions }/>;
|
if(availableAcls.acl_delete) {
|
||||||
|
|
||||||
|
if(this.props.piece && !this.props.editions) {
|
||||||
|
content = <PieceDeleteForm pieceId={this.props.piece.id}/>;
|
||||||
|
title = getLangText('Remove Piece');
|
||||||
|
} else {
|
||||||
|
content = <EditionDeleteForm editions={this.props.editions}/>;
|
||||||
|
title = getLangText('Remove Edition');
|
||||||
|
}
|
||||||
|
|
||||||
|
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('DELETE')}</Button>;
|
||||||
|
|
||||||
|
} else if(availableAcls.acl_unshare){
|
||||||
|
|
||||||
|
if(this.props.editions && this.props.editions.constructor !== Array && this.props.editions.acl.acl_unshare) {
|
||||||
|
content = <EditionRemoveFromCollectionForm editions={this.props.editions}/>;
|
||||||
|
title = getLangText('Remove Edition from Collection');
|
||||||
|
} else {
|
||||||
|
content = <PieceRemoveFromCollectionForm pieceId={this.props.piece.id}/>;
|
||||||
|
title = getLangText('Remove Piece from Collection');
|
||||||
|
}
|
||||||
|
|
||||||
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('REMOVE FROM COLLECTION')}</Button>;
|
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('REMOVE FROM COLLECTION')}</Button>;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ModalWrapper
|
<ModalWrapper
|
||||||
button={ btnDelete }
|
button={btnDelete}
|
||||||
handleSuccess={ this.showNotification }
|
handleSuccess={this.props.handleSuccess}
|
||||||
title={getLangText('Remove Edition')}
|
title={title}>
|
||||||
tooltip={getLangText('Click to remove edition')}>
|
{content}
|
||||||
{ content }
|
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@ import UserActions from '../../actions/user_actions';
|
||||||
import UserStore from '../../stores/user_store';
|
import UserStore from '../../stores/user_store';
|
||||||
import CoaActions from '../../actions/coa_actions';
|
import CoaActions from '../../actions/coa_actions';
|
||||||
import CoaStore from '../../stores/coa_store';
|
import CoaStore from '../../stores/coa_store';
|
||||||
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
|
import PieceListStore from '../../stores/piece_list_store';
|
||||||
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
|
|
||||||
|
|
||||||
import MediaContainer from './media_container';
|
import MediaContainer from './media_container';
|
||||||
|
|
||||||
|
@ -24,13 +28,11 @@ import InputTextAreaToggable from './../ascribe_forms/input_textarea_toggable';
|
||||||
|
|
||||||
import EditionFurtherDetails from './further_details';
|
import EditionFurtherDetails from './further_details';
|
||||||
|
|
||||||
//import PieceExtraDataForm from './../ascribe_forms/form_piece_extradata';
|
|
||||||
import RequestActionForm from './../ascribe_forms/form_request_action';
|
import RequestActionForm from './../ascribe_forms/form_request_action';
|
||||||
import EditionActions from '../../actions/edition_actions';
|
import EditionActions from '../../actions/edition_actions';
|
||||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
||||||
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
|
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
|
||||||
|
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||||
//import ReactS3FineUploader from './../ascribe_uploader/react_s3_fine_uploader';
|
|
||||||
|
|
||||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
@ -39,6 +41,7 @@ import apiUrls from '../../constants/api_urls';
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
let Link = Router.Link;
|
||||||
/**
|
/**
|
||||||
|
@ -50,23 +53,44 @@ let Edition = React.createClass({
|
||||||
loadEdition: React.PropTypes.func
|
loadEdition: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return UserStore.getState();
|
return mergeOptions(
|
||||||
|
UserStore.getState(),
|
||||||
|
PieceListStore.getState()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
UserStore.listen(this.onChange);
|
UserStore.listen(this.onChange);
|
||||||
|
PieceListStore.listen(this.onChange);
|
||||||
UserActions.fetchCurrentUser();
|
UserActions.fetchCurrentUser();
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
UserStore.unlisten(this.onChange);
|
UserStore.unlisten(this.onChange);
|
||||||
|
PieceListStore.unlisten(this.onChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleDeleteSuccess(response) {
|
||||||
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
||||||
|
|
||||||
|
// we don't need to refresh the edition list for a piece here, since its reloaded from
|
||||||
|
// scatch once you click on show-editions anyway
|
||||||
|
EditionListActions.closeAllEditionLists();
|
||||||
|
EditionListActions.clearAllEditionSelections();
|
||||||
|
|
||||||
|
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
|
this.transitionTo('pieces');
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -84,7 +108,8 @@ let Edition = React.createClass({
|
||||||
<EditionSummary
|
<EditionSummary
|
||||||
handleSuccess={this.props.loadEdition}
|
handleSuccess={this.props.loadEdition}
|
||||||
currentUser={this.state.currentUser}
|
currentUser={this.state.currentUser}
|
||||||
edition={this.props.edition} />
|
edition={this.props.edition}
|
||||||
|
handleDeleteSuccess={this.handleDeleteSuccess}/>
|
||||||
|
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={getLangText('Certificate of Authenticity')}
|
title={getLangText('Certificate of Authenticity')}
|
||||||
|
@ -157,6 +182,7 @@ let EditionSummary = React.createClass({
|
||||||
edition: React.PropTypes.object,
|
edition: React.PropTypes.object,
|
||||||
handleSuccess: React.PropTypes.func,
|
handleSuccess: React.PropTypes.func,
|
||||||
currentUser: React.PropTypes.object
|
currentUser: React.PropTypes.object
|
||||||
|
handleDeleteSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
getTransferWithdrawData(){
|
getTransferWithdrawData(){
|
||||||
|
@ -176,14 +202,13 @@ let EditionSummary = React.createClass({
|
||||||
status = <EditionDetailProperty label="STATUS" value={ statusStr }/>;
|
status = <EditionDetailProperty label="STATUS" value={ statusStr }/>;
|
||||||
if (this.props.edition.pending_new_owner && this.props.edition.acl.acl_withdraw_transfer){
|
if (this.props.edition.pending_new_owner && this.props.edition.acl.acl_withdraw_transfer){
|
||||||
status = (
|
status = (
|
||||||
|
<EditionDetailProperty label="STATUS" value={ statusStr } />
|
||||||
<EditionDetailProperty label="STATUS" value={ statusStr } />
|
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
|
|
||||||
getActions(){
|
getActions(){
|
||||||
let actions = null;
|
let actions = null;
|
||||||
if (this.props.edition.request_action && this.props.edition.request_action.length > 0){
|
if (this.props.edition.request_action && this.props.edition.request_action.length > 0){
|
||||||
|
@ -227,6 +252,9 @@ let EditionSummary = React.createClass({
|
||||||
editions={[this.props.edition]}
|
editions={[this.props.edition]}
|
||||||
handleSuccess={this.props.handleSuccess}>
|
handleSuccess={this.props.handleSuccess}>
|
||||||
{withdrawButton}
|
{withdrawButton}
|
||||||
|
<DeleteButton
|
||||||
|
handleSuccess={this.props.handleDeleteSuccess}
|
||||||
|
editions={[this.props.edition]}/>
|
||||||
{unconsignRequestButton}
|
{unconsignRequestButton}
|
||||||
</AclButtonList>
|
</AclButtonList>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
import Row from 'react-bootstrap/lib/Row';
|
import Row from 'react-bootstrap/lib/Row';
|
||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
|
@ -14,6 +15,11 @@ import FurtherDetails from './further_details';
|
||||||
import UserActions from '../../actions/user_actions';
|
import UserActions from '../../actions/user_actions';
|
||||||
import UserStore from '../../stores/user_store';
|
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 PieceActions from '../../actions/piece_actions';
|
||||||
|
|
||||||
import MediaContainer from './media_container';
|
import MediaContainer from './media_container';
|
||||||
|
@ -23,6 +29,10 @@ import EditionDetailProperty from './detail_property';
|
||||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
||||||
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
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 { getLangText } from '../../utils/lang_utils';
|
||||||
import { mergeOptions } from '../../utils/general_utils';
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
|
@ -36,9 +46,12 @@ let Piece = React.createClass({
|
||||||
loadPiece: React.PropTypes.func
|
loadPiece: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(
|
return mergeOptions(
|
||||||
UserStore.getState(),
|
UserStore.getState(),
|
||||||
|
PieceListStore.getState(),
|
||||||
{
|
{
|
||||||
showCreateEditionsDialog: false
|
showCreateEditionsDialog: false
|
||||||
}
|
}
|
||||||
|
@ -47,11 +60,13 @@ let Piece = React.createClass({
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
UserStore.listen(this.onChange);
|
UserStore.listen(this.onChange);
|
||||||
|
PieceListStore.listen(this.onChange);
|
||||||
UserActions.fetchCurrentUser();
|
UserActions.fetchCurrentUser();
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
UserStore.unlisten(this.onChange);
|
UserStore.unlisten(this.onChange);
|
||||||
|
PieceListStore.unlisten(this.onChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
|
@ -69,6 +84,20 @@ let Piece = React.createClass({
|
||||||
this.toggleCreateEditionsDialog();
|
this.toggleCreateEditionsDialog();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleDeleteSuccess(response) {
|
||||||
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
||||||
|
|
||||||
|
// 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() {
|
getCreateEditionsDialog() {
|
||||||
if(this.props.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
|
if(this.props.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
|
||||||
return (
|
return (
|
||||||
|
@ -89,6 +118,9 @@ let Piece = React.createClass({
|
||||||
key: 'num_editions',
|
key: 'num_editions',
|
||||||
value: numEditions
|
value: numEditions
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -121,6 +153,9 @@ let Piece = React.createClass({
|
||||||
piece={this.props.piece}
|
piece={this.props.piece}
|
||||||
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
|
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
|
||||||
onPollingSuccess={this.handlePollingSuccess}/>
|
onPollingSuccess={this.handlePollingSuccess}/>
|
||||||
|
<DeleteButton
|
||||||
|
handleSuccess={this.handleDeleteSuccess}
|
||||||
|
piece={this.props.piece}/>
|
||||||
</AclButtonList>
|
</AclButtonList>
|
||||||
|
|
||||||
{this.getCreateEditionsDialog()}
|
{this.getCreateEditionsDialog()}
|
||||||
|
|
|
@ -59,7 +59,6 @@ let Form = React.createClass({
|
||||||
for (let ref in this.refs){
|
for (let ref in this.refs){
|
||||||
data[this.refs[ref].props.name] = this.refs[ref].state.value;
|
data[this.refs[ref].props.name] = this.refs[ref].state.value;
|
||||||
}
|
}
|
||||||
console.log(data);
|
|
||||||
if ('getFormData' in this.props){
|
if ('getFormData' in this.props){
|
||||||
data = mergeOptionsWithDuplicates(data, this.props.getFormData());
|
data = mergeOptionsWithDuplicates(data, this.props.getFormData());
|
||||||
}
|
}
|
||||||
|
|
41
js/components/ascribe_forms/form_delete_piece.js
Normal file
41
js/components/ascribe_forms/form_delete_piece.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import requests from '../../utils/requests';
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
|
let PieceDeleteForm = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
pieceId: React.PropTypes.number
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return requests.prepareUrl(ApiUrls.piece, {piece_id: this.props.pieceId});
|
||||||
|
},
|
||||||
|
|
||||||
|
httpVerb() {
|
||||||
|
return 'delete';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm () {
|
||||||
|
return (
|
||||||
|
<div className="modal-body">
|
||||||
|
<p>{getLangText('Are you sure you would like to permanently delete this piece')}?</p>
|
||||||
|
<p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="submit" className="btn btn-danger btn-delete btn-sm ascribe-margin-1px" onClick={this.submit}>{getLangText('YES, DELETE')}</button>
|
||||||
|
<button className="btn btn-default btn-sm ascribe-margin-1px" style={{marginLeft: '0'}}
|
||||||
|
onClick={this.props.onRequestHide}>{getLangText('CLOSE')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default PieceDeleteForm;
|
|
@ -12,13 +12,9 @@ let EditionRemoveFromCollectionForm = React.createClass({
|
||||||
mixins: [FormMixin],
|
mixins: [FormMixin],
|
||||||
|
|
||||||
url() {
|
url() {
|
||||||
if (this.props.editions.constructor === Array) {
|
return requests.prepareUrl(apiUrls.edition_remove_from_collection, {edition_id: this.getBitcoinIds().join()});
|
||||||
return requests.prepareUrl(apiUrls.edition_remove_from_collection, {edition_id: this.getBitcoinIds().join()});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return requests.prepareUrl(apiUrls.piece_remove_from_collection, {piece_id: this.props.editions.id});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
httpVerb(){
|
httpVerb(){
|
||||||
return 'delete';
|
return 'delete';
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
import requests from '../../utils/requests';
|
||||||
|
import apiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
let PieceRemoveFromCollectionForm = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
pieceId: React.PropTypes.number
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return requests.prepareUrl(apiUrls.piece_remove_from_collection, {piece_id: this.props.pieceId});
|
||||||
|
},
|
||||||
|
|
||||||
|
httpVerb(){
|
||||||
|
return 'delete';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm () {
|
||||||
|
return (
|
||||||
|
<div className="modal-body">
|
||||||
|
<p>{getLangText('Are you sure you would like to remove this piece from your collection')}?</p>
|
||||||
|
<p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="submit" className="btn btn-danger btn-delete btn-sm ascribe-margin-1px" onClick={this.submit}>{getLangText('YES, REMOVE')}</button>
|
||||||
|
<button className="btn btn-default btn-sm ascribe-margin-1px" style={{marginLeft: '0'}}
|
||||||
|
onClick={this.props.onRequestHide}>{getLangText('CLOSE')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default PieceRemoveFromCollectionForm;
|
|
@ -17,24 +17,41 @@ let ModalWrapper = React.createClass({
|
||||||
handleSuccess: React.PropTypes.func.isRequired,
|
handleSuccess: React.PropTypes.func.isRequired,
|
||||||
button: React.PropTypes.object.isRequired,
|
button: React.PropTypes.object.isRequired,
|
||||||
children: React.PropTypes.object,
|
children: React.PropTypes.object,
|
||||||
tooltip: React.PropTypes.string.isRequired
|
tooltip: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
|
getModalTrigger() {
|
||||||
|
return (
|
||||||
|
<ModalTrigger modal={
|
||||||
|
<ModalBody
|
||||||
|
title={this.props.title}
|
||||||
|
handleSuccess={this.props.handleSuccess}>
|
||||||
|
{this.props.children}
|
||||||
|
</ModalBody>
|
||||||
|
}>
|
||||||
|
{this.props.button}
|
||||||
|
</ModalTrigger>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
if(this.props.tooltip) {
|
||||||
<OverlayTrigger delay={500} placement="left"
|
return (
|
||||||
overlay={<Tooltip>{this.props.tooltip}</Tooltip>}>
|
<OverlayTrigger
|
||||||
<ModalTrigger modal={
|
delay={500}
|
||||||
<ModalBody
|
placement="left"
|
||||||
title={this.props.title}
|
overlay={<Tooltip>{this.props.tooltip}</Tooltip>}>
|
||||||
handleSuccess={this.props.handleSuccess}>
|
{this.getModalTrigger()}
|
||||||
{this.props.children}
|
</OverlayTrigger>
|
||||||
</ModalBody>
|
);
|
||||||
}>
|
} else {
|
||||||
{this.props.button}
|
return (
|
||||||
</ModalTrigger>
|
<span>
|
||||||
</OverlayTrigger>
|
{/* This needs to be some kind of inline-block */}
|
||||||
);
|
{this.getModalTrigger()}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,12 @@ import EditionListActions from '../../actions/edition_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 PieceListStore from '../../stores/piece_list_store';
|
||||||
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
|
|
||||||
import PieceListBulkModalSelectedEditionsWidget from './piece_list_bulk_modal_selected_editions_widget';
|
import PieceListBulkModalSelectedEditionsWidget from './piece_list_bulk_modal_selected_editions_widget';
|
||||||
import AclButtonList from '../ascribe_buttons/acl_button_list';
|
import AclButtonList from '../ascribe_buttons/acl_button_list';
|
||||||
|
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||||
|
|
||||||
import { getAvailableAcls } from '../../utils/acl_utils';
|
import { getAvailableAcls } from '../../utils/acl_utils';
|
||||||
import { getLangText } from '../../utils/lang_utils.js';
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
@ -23,7 +26,11 @@ let PieceListBulkModal = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(EditionListStore.getState(), UserStore.getState());
|
return mergeOptions(
|
||||||
|
EditionListStore.getState(),
|
||||||
|
UserStore.getState(),
|
||||||
|
PieceListStore.getState()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
|
@ -69,13 +76,11 @@ let PieceListBulkModal = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess() {
|
handleSuccess() {
|
||||||
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
||||||
|
|
||||||
this.fetchSelectedPieceEditionList()
|
this.fetchSelectedPieceEditionList()
|
||||||
.forEach((pieceId) => {
|
.forEach((pieceId) => {
|
||||||
let editionsForPiece = this.state.editionList[pieceId];
|
EditionListActions.refreshEditionList(pieceId);
|
||||||
for(let i = 1; i <= editionsForPiece.page; i++) {
|
|
||||||
EditionListActions.fetchEditionList(pieceId, i, editionsForPiece.pageSize, editionsForPiece.orderBy, editionsForPiece.orderAsc);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
EditionListActions.clearAllEditionSelections();
|
EditionListActions.clearAllEditionSelections();
|
||||||
},
|
},
|
||||||
|
@ -106,7 +111,11 @@ let PieceListBulkModal = React.createClass({
|
||||||
availableAcls={availableAcls}
|
availableAcls={availableAcls}
|
||||||
editions={selectedEditions}
|
editions={selectedEditions}
|
||||||
handleSuccess={this.handleSuccess}
|
handleSuccess={this.handleSuccess}
|
||||||
className="text-center ascribe-button-list collapse-group"/>
|
className="text-center ascribe-button-list collapse-group">
|
||||||
|
<DeleteButton
|
||||||
|
handleSuccess={this.handleSuccess}
|
||||||
|
editions={selectedEditions}/>
|
||||||
|
</AclButtonList>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,6 +10,7 @@ let TableItemAclFiltered = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
var availableAcls = ['acl_consign', 'acl_loan', 'acl_transfer', 'acl_view', 'acl_share', 'acl_unshare', 'acl_delete'];
|
||||||
if (this.props.requestAction){
|
if (this.props.requestAction){
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
|
@ -17,7 +18,6 @@ let TableItemAclFiltered = React.createClass({
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var availableAcls = ['acl_consign', 'acl_loan', 'acl_transfer', 'acl_view', 'acl_share', 'acl_unshare'];
|
|
||||||
|
|
||||||
let filteredAcls = Object.keys(this.props.content).filter((key) => {
|
let filteredAcls = Object.keys(this.props.content).filter((key) => {
|
||||||
return availableAcls.indexOf(key) > -1 && this.props.content[key];
|
return availableAcls.indexOf(key) > -1 && this.props.content[key];
|
||||||
|
|
|
@ -56,6 +56,31 @@ class EditionListStore {
|
||||||
this.editionList[pieceId].count = count;
|
this.editionList[pieceId].count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We often just have to refresh the edition list for a certain pieceId,
|
||||||
|
* this method provides exactly that functionality without any side effects
|
||||||
|
*/
|
||||||
|
onRefreshEditionList(pieceId) {
|
||||||
|
const prevEditionListLength = this.editionList[pieceId].length;
|
||||||
|
const prevEditionListPage = this.editionList[pieceId].page;
|
||||||
|
const prevEditionListPageSize = this.editionList[pieceId].pageSize;
|
||||||
|
|
||||||
|
// to clear an array, david walsh recommends to just set it's length to zero
|
||||||
|
// http://davidwalsh.name/empty-array
|
||||||
|
this.editionList[pieceId].length = 0;
|
||||||
|
|
||||||
|
// refetch editions with adjusted page size
|
||||||
|
EditionsListActions.fetchEditionList(pieceId, 1, prevEditionListLength, this.editionList[pieceId].orderBy, this.editionList[pieceId].orderAsc)
|
||||||
|
.then(() => {
|
||||||
|
// reset back to the normal pageSize and page
|
||||||
|
this.editionList[pieceId].page = prevEditionListPage;
|
||||||
|
this.editionList[pieceId].pageSize = prevEditionListPageSize;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSelectEdition({pieceId, editionId, toValue}) {
|
onSelectEdition({pieceId, editionId, toValue}) {
|
||||||
this.editionList[pieceId].forEach((edition) => {
|
this.editionList[pieceId].forEach((edition) => {
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ function intersectAcls(a, b) {
|
||||||
|
|
||||||
export function getAvailableAcls(editions, filterFn) {
|
export function getAvailableAcls(editions, filterFn) {
|
||||||
let availableAcls = [];
|
let availableAcls = [];
|
||||||
if (editions.constructor !== Array){
|
if (!editions || editions.constructor !== Array){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// if you copy a javascript array of objects using slice, then
|
// if you copy a javascript array of objects using slice, then
|
||||||
|
|
|
@ -54,6 +54,11 @@ class Requests {
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl(url) {
|
getUrl(url) {
|
||||||
|
// Handle case, that the url string is not defined at all
|
||||||
|
if (!url) {
|
||||||
|
throw new Error('Url was not defined and could therefore not be mapped.');
|
||||||
|
}
|
||||||
|
|
||||||
let name = url;
|
let name = url;
|
||||||
if (!url.match(/^http/)) {
|
if (!url.match(/^http/)) {
|
||||||
url = this.urlMap[url];
|
url = this.urlMap[url];
|
||||||
|
@ -66,9 +71,16 @@ class Requests {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareUrl(url, params, attachParamsToQuery) {
|
prepareUrl(url, params, attachParamsToQuery) {
|
||||||
let newUrl = this.getUrl(url);
|
let newUrl;
|
||||||
let re = /\${(\w+)}/g;
|
let re = /\${(\w+)}/g;
|
||||||
|
|
||||||
|
// catch errors and throw them to react
|
||||||
|
try {
|
||||||
|
newUrl = this.getUrl(url);
|
||||||
|
} catch(err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
newUrl = newUrl.replace(re, (match, key) => {
|
newUrl = newUrl.replace(re, (match, key) => {
|
||||||
let val = params[key];
|
let val = params[key];
|
||||||
if (!val) {
|
if (!val) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user