mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
Merge remote-tracking branches 'remotes/origin/AD-391-add-filter-functions-to-pieces-an', 'remotes/origin/AD-589-Form-Cancel-doesnt-reset' and 'remotes/origin/AD-619-due-1208-create-jury-dashboard' into AD-686-in-sluice-art-prize-i-can-submit-
This commit is contained in:
commit
36356dd5c5
@ -17,21 +17,21 @@ class EditionListActions {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc) {
|
fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc, filterBy) {
|
||||||
if(!orderBy && typeof orderAsc === 'undefined') {
|
if((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) {
|
||||||
orderBy = 'edition_number';
|
orderBy = 'edition_number';
|
||||||
orderAsc = true;
|
orderAsc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken from: http://stackoverflow.com/a/519157/1263876
|
// Taken from: http://stackoverflow.com/a/519157/1263876
|
||||||
if(typeof page === 'undefined' && typeof pageSize === 'undefined') {
|
if((typeof page === 'undefined' || !page) && (typeof pageSize === 'undefined' || !pageSize)) {
|
||||||
page = 1;
|
page = 1;
|
||||||
pageSize = 10;
|
pageSize = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Q.Promise((resolve, reject) => {
|
return Q.Promise((resolve, reject) => {
|
||||||
EditionListFetcher
|
EditionListFetcher
|
||||||
.fetch(pieceId, page, pageSize, orderBy, orderAsc)
|
.fetch(pieceId, page, pageSize, orderBy, orderAsc, filterBy)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.actions.updateEditionList({
|
this.actions.updateEditionList({
|
||||||
pieceId,
|
pieceId,
|
||||||
@ -39,6 +39,7 @@ class EditionListActions {
|
|||||||
pageSize,
|
pageSize,
|
||||||
orderBy,
|
orderBy,
|
||||||
orderAsc,
|
orderAsc,
|
||||||
|
filterBy,
|
||||||
'editionListOfPiece': res.editions,
|
'editionListOfPiece': res.editions,
|
||||||
'count': res.count
|
'count': res.count
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ class PieceListActions {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchPieceList(page, pageSize, search, orderBy, orderAsc) {
|
fetchPieceList(page, pageSize, search, orderBy, orderAsc, filterBy) {
|
||||||
// To prevent flickering on a pagination request,
|
// To prevent flickering on a pagination request,
|
||||||
// we overwrite the piecelist with an empty list before
|
// we overwrite the piecelist with an empty list before
|
||||||
// pieceListCount === -1 defines the loading state
|
// pieceListCount === -1 defines the loading state
|
||||||
@ -24,6 +24,7 @@ class PieceListActions {
|
|||||||
search,
|
search,
|
||||||
orderBy,
|
orderBy,
|
||||||
orderAsc,
|
orderAsc,
|
||||||
|
filterBy,
|
||||||
'pieceList': [],
|
'pieceList': [],
|
||||||
'pieceListCount': -1
|
'pieceListCount': -1
|
||||||
});
|
});
|
||||||
@ -32,7 +33,7 @@ class PieceListActions {
|
|||||||
|
|
||||||
return Q.Promise((resolve, reject) => {
|
return Q.Promise((resolve, reject) => {
|
||||||
PieceListFetcher
|
PieceListFetcher
|
||||||
.fetch(page, pageSize, search, orderBy, orderAsc)
|
.fetch(page, pageSize, search, orderBy, orderAsc, filterBy)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.actions.updatePieceList({
|
this.actions.updatePieceList({
|
||||||
page,
|
page,
|
||||||
@ -40,6 +41,7 @@ class PieceListActions {
|
|||||||
search,
|
search,
|
||||||
orderBy,
|
orderBy,
|
||||||
orderAsc,
|
orderAsc,
|
||||||
|
filterBy,
|
||||||
'pieceList': res.pieces,
|
'pieceList': res.pieces,
|
||||||
'pieceListCount': res.count
|
'pieceListCount': res.count
|
||||||
});
|
});
|
||||||
|
@ -87,14 +87,16 @@ let AccordionListItem = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSubmitPrizeSuccess(response) {
|
handleSubmitPrizeSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
onPollingSuccess(pieceId) {
|
onPollingSuccess(pieceId) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||||
|
@ -6,10 +6,14 @@ import classNames from 'classnames';
|
|||||||
import EditionListActions from '../../actions/edition_list_actions';
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
import EditionListStore from '../../stores/edition_list_store';
|
import EditionListStore from '../../stores/edition_list_store';
|
||||||
|
|
||||||
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
|
import PieceListStore from '../../stores/piece_list_store';
|
||||||
|
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
|
|
||||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
||||||
|
|
||||||
|
import { mergeOptions } from '../../utils/general_utils';
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let AccordionListItemEditionWidget = React.createClass({
|
let AccordionListItemEditionWidget = React.createClass({
|
||||||
@ -21,15 +25,20 @@ let AccordionListItemEditionWidget = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return EditionListStore.getState();
|
return mergeOptions(
|
||||||
|
EditionListStore.getState(),
|
||||||
|
PieceListStore.getState()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
EditionListStore.listen(this.onChange);
|
EditionListStore.listen(this.onChange);
|
||||||
|
PieceListStore.listen(this.onChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
EditionListStore.unlisten(this.onChange);
|
EditionListStore.unlisten(this.onChange);
|
||||||
|
PieceListStore.unlisten(this.onChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
@ -47,7 +56,7 @@ let AccordionListItemEditionWidget = React.createClass({
|
|||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
} else {
|
} else {
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
EditionListActions.fetchEditionList(pieceId);
|
EditionListActions.fetchEditionList(pieceId, null, null, null, null, this.state.filterBy);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,13 +76,9 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let editionList = this.state.editionList[this.props.parentId];
|
let editionList = this.state.editionList[this.props.parentId];
|
||||||
EditionListActions.fetchEditionList(this.props.parentId, editionList.page + 1, editionList.pageSize);
|
EditionListActions.fetchEditionList(this.props.parentId, editionList.page + 1, editionList.pageSize,
|
||||||
|
editionList.orderBy, editionList.orderAsc, editionList.filterBy);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeEditionListOrder(orderBy, orderAsc) {
|
|
||||||
EditionListActions.fetchEditionList(this.props.parentId, orderBy, orderAsc);
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let selectedEditionsCount = 0;
|
let selectedEditionsCount = 0;
|
||||||
let allEditionsCount = 0;
|
let allEditionsCount = 0;
|
||||||
|
@ -44,7 +44,9 @@ let CreateEditionsButton = React.createClass({
|
|||||||
startPolling() {
|
startPolling() {
|
||||||
// start polling until editions are defined
|
// start polling until editions are defined
|
||||||
let pollingIntervalIndex = setInterval(() => {
|
let pollingIntervalIndex = setInterval(() => {
|
||||||
EditionListActions.fetchEditionList(this.props.piece.id)
|
let editionsForPiece = this.state.editionList[this.props.piece.id];
|
||||||
|
|
||||||
|
EditionListActions.fetchEditionList(this.props.piece.id, null, null, null, null, editionsForPiece.filterBy)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
|
||||||
clearInterval(this.state.pollingIntervalIndex);
|
clearInterval(this.state.pollingIntervalIndex);
|
||||||
|
@ -86,7 +86,8 @@ let Edition = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSuccess(response) {
|
handleDeleteSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||||
|
|
||||||
EditionListActions.refreshEditionList(this.props.edition.parent);
|
EditionListActions.refreshEditionList(this.props.edition.parent);
|
||||||
EditionListActions.closeAllEditionLists();
|
EditionListActions.closeAllEditionLists();
|
||||||
|
@ -79,12 +79,14 @@ let Piece = React.createClass({
|
|||||||
|
|
||||||
handleEditionCreationSuccess() {
|
handleEditionCreationSuccess() {
|
||||||
PieceActions.updateProperty({key: 'num_editions', value: 0});
|
PieceActions.updateProperty({key: 'num_editions', value: 0});
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||||
this.toggleCreateEditionsDialog();
|
this.toggleCreateEditionsDialog();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSuccess(response) {
|
handleDeleteSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
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
|
// since we're deleting a piece, we just need to close
|
||||||
// all editions dialogs and not reload them
|
// all editions dialogs and not reload them
|
||||||
@ -124,7 +126,8 @@ let Piece = React.createClass({
|
|||||||
// btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion
|
// 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.
|
// 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
|
// 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);
|
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);
|
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
@ -70,23 +70,22 @@ let Property = React.createClass({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.state.initialValue) {
|
if(!this.state.initialValue && childInput.props.defaultValue) {
|
||||||
this.setState({
|
this.setState({
|
||||||
initialValue: childInput.defaultValue
|
initialValue: childInput.props.defaultValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
reset(){
|
reset() {
|
||||||
// maybe do reset by reload instead of front end state?
|
// maybe do reset by reload instead of front end state?
|
||||||
this.setState({value: this.state.initialValue});
|
this.setState({value: this.state.initialValue});
|
||||||
if (this.refs.input.state){
|
|
||||||
// This is probably not the right way but easy fix
|
// resets the value of a custom react component input
|
||||||
this.refs.input.state.value = this.state.initialValue;
|
this.refs.input.state.value = this.state.initialValue;
|
||||||
}
|
|
||||||
else{
|
// resets the value of a plain HTML5 input
|
||||||
this.refs.input.getDOMNode().value = this.state.initialValue;
|
this.refs.input.getDOMNode().value = this.state.initialValue;
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,7 +76,8 @@ let PieceListBulkModal = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess() {
|
handleSuccess() {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||||
|
|
||||||
this.fetchSelectedPieceEditionList()
|
this.fetchSelectedPieceEditionList()
|
||||||
.forEach((pieceId) => {
|
.forEach((pieceId) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { getLangText } from '../../utils/lang_utils.js'
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
|
||||||
let PieceListBulkModalSelectedEditionsWidget = React.createClass({
|
let PieceListBulkModalSelectedEditionsWidget = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import PieceListToolbarFilterWidget from './piece_list_toolbar_filter_widget';
|
||||||
|
|
||||||
import Input from 'react-bootstrap/lib/Input';
|
import Input from 'react-bootstrap/lib/Input';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
@ -41,6 +43,13 @@ let PieceListToolbar = React.createClass({
|
|||||||
onChange={this.searchFor}
|
onChange={this.searchFor}
|
||||||
addonAfter={searchIcon} />
|
addonAfter={searchIcon} />
|
||||||
</span>
|
</span>
|
||||||
|
<span className="pull-right">
|
||||||
|
<PieceListToolbarFilterWidget
|
||||||
|
filterParams={['acl_transfer', 'acl_consign', {
|
||||||
|
key: 'acl_editions',
|
||||||
|
label: 'create editions'
|
||||||
|
}]} />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,30 +2,132 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import PieceListStore from '../../stores/piece_list_store';
|
||||||
|
import PieceListActions from '../../actions/piece_list_actions';
|
||||||
|
|
||||||
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
|
||||||
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
import MenuItem from 'react-bootstrap/lib/MenuItem';
|
||||||
import { getLangText } from '../../utils/lang_utils.js'
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
|
||||||
let PieceListToolbarFilterWidgetFilter = React.createClass({
|
let PieceListToolbarFilterWidgetFilter = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
// An array of either strings (which represent acl enums) or objects of the form
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// key: <acl enum>,
|
||||||
|
// label: <a human readable string>
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
filterParams: React.PropTypes.arrayOf(React.PropTypes.any).isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return PieceListStore.getState();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
PieceListStore.listen(this.onChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
PieceListStore.unlisten(this.onChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange(state) {
|
||||||
|
this.setState(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
generateFilterByStatement(param) {
|
||||||
|
let filterBy = this.state.filterBy;
|
||||||
|
|
||||||
|
if(filterBy) {
|
||||||
|
// we need hasOwnProperty since the values are all booleans
|
||||||
|
if(filterBy.hasOwnProperty(param)) {
|
||||||
|
filterBy[param] = !filterBy[param];
|
||||||
|
|
||||||
|
// if the parameter is false, then we want to remove it again
|
||||||
|
// from the list of queryParameters as this component is only about
|
||||||
|
// which actions *CAN* be done and not what *CANNOT*
|
||||||
|
if(!filterBy[param]) {
|
||||||
|
delete filterBy[param];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
filterBy[param] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterBy;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need overloading here to find the correct parameter of the label
|
||||||
|
* the user is clicking on.
|
||||||
|
*/
|
||||||
|
filterBy(param) {
|
||||||
|
return () => {
|
||||||
|
let filterBy = this.generateFilterByStatement(param);
|
||||||
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, filterBy);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
isFilterActive() {
|
||||||
|
let trueValuesOnly = Object.keys(this.state.filterBy).filter((acl) => acl);
|
||||||
|
|
||||||
|
// We're hiding the star in that complicated matter so that,
|
||||||
|
// the surrounding button is not resized up on appearance
|
||||||
|
if(trueValuesOnly.length > 0) {
|
||||||
|
return { visibility: 'visible'};
|
||||||
|
} else {
|
||||||
|
return { visibility: 'hidden' };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let filterIcon = <Glyphicon glyph='filter' className="filter-glyph"/>;
|
let filterIcon = (
|
||||||
|
<span>
|
||||||
|
<span className="glyphicon glyphicon-filter" aria-hidden="true"></span>
|
||||||
|
<span style={this.isFilterActive()}>*</span>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownButton title={filterIcon}>
|
<DropdownButton
|
||||||
|
title={filterIcon}
|
||||||
|
className="ascribe-piece-list-toolbar-filter-widget">
|
||||||
<li style={{'textAlign': 'center'}}>
|
<li style={{'textAlign': 'center'}}>
|
||||||
<em>{getLangText('Show Pieces that')}:</em>
|
<em>{getLangText('Show works that')}:</em>
|
||||||
</li>
|
</li>
|
||||||
<MenuItem eventKey='1'>
|
{this.props.filterParams.map((param, i) => {
|
||||||
<div className="checkbox">
|
let label;
|
||||||
{getLangText('I can transfer')} <input type="checkbox" />
|
|
||||||
</div>
|
if(typeof param !== 'string') {
|
||||||
</MenuItem>
|
label = param.label;
|
||||||
<MenuItem eventKey='2'>
|
param = param.key;
|
||||||
<div className="checkbox">
|
} else {
|
||||||
{getLangText('I can consign')} <input type="checkbox" />
|
param = param;
|
||||||
</div>
|
label = param.split('_')[1];
|
||||||
</MenuItem>
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={i}
|
||||||
|
onClick={this.filterBy(param)}
|
||||||
|
className="filter-widget-item">
|
||||||
|
<div className="checkbox-line">
|
||||||
|
<span>
|
||||||
|
{getLangText('I can') + ' ' + getLangText(label)}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
readOnly
|
||||||
|
type="checkbox"
|
||||||
|
checked={this.state.filterBy[param]} />
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</DropdownButton>
|
</DropdownButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { ColumnModel } from './models/table_models';
|
|
||||||
|
|
||||||
import EditionListStore from '../../stores/edition_list_store';
|
|
||||||
import EditionListActions from '../../actions/edition_list_actions';
|
|
||||||
|
|
||||||
|
|
||||||
import Table from './table';
|
|
||||||
import TableItemWrapper from './table_item_wrapper';
|
|
||||||
import TableItemText from './table_item_text';
|
|
||||||
import TableItemAcl from './table_item_acl';
|
|
||||||
import TableItemSelectable from './table_item_selectable';
|
|
||||||
import TableItemSubtableButton from './table_item_subtable_button';
|
|
||||||
|
|
||||||
|
|
||||||
let TableItemSubtable = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)),
|
|
||||||
columnContent: React.PropTypes.object
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState() {
|
|
||||||
return {
|
|
||||||
'open': false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
EditionListStore.listen(this.onChange);
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
EditionListStore.unlisten(this.onChange);
|
|
||||||
},
|
|
||||||
|
|
||||||
onChange(state) {
|
|
||||||
this.setState(state);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadEditionList() {
|
|
||||||
if(this.state.open) {
|
|
||||||
this.setState({
|
|
||||||
'open': false
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
|
|
||||||
EditionListActions.fetchEditionList(this.props.columnContent.id);
|
|
||||||
this.setState({
|
|
||||||
'open': true,
|
|
||||||
'editionList': EditionListStore.getState()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selectItem(parentId, itemId) {
|
|
||||||
EditionListActions.selectEdition({
|
|
||||||
'pieceId': parentId,
|
|
||||||
'editionId': itemId
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
let renderEditionListTable = () => {
|
|
||||||
|
|
||||||
let columnList = [
|
|
||||||
new ColumnModel('edition_number', 'Number', TableItemText, 2, false),
|
|
||||||
new ColumnModel('user_registered', 'User', TableItemText, 4, true),
|
|
||||||
new ColumnModel('acl', 'Actions', TableItemAcl, 4, true)
|
|
||||||
];
|
|
||||||
|
|
||||||
if(this.state.open && this.state.editionList[this.props.columnContent.id] && this.state.editionList[this.props.columnContent.id].length) {
|
|
||||||
return (
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
|
||||||
<Table itemList={this.state.editionList[this.props.columnContent.id]} columnList={columnList}>
|
|
||||||
{this.state.editionList[this.props.columnContent.id].map((edition, i) => {
|
|
||||||
return (
|
|
||||||
<TableItemSelectable
|
|
||||||
className="ascribe-table-item-selectable"
|
|
||||||
selectItem={this.selectItem}
|
|
||||||
parentId={this.props.columnContent.id}
|
|
||||||
key={i} />
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 ascribe-table-item">
|
|
||||||
<div className="row">
|
|
||||||
<TableItemWrapper
|
|
||||||
columnList={this.props.columnList}
|
|
||||||
columnContent={this.props.columnContent}
|
|
||||||
columnWidth={12} />
|
|
||||||
<div className="col-xs-1 col-sm-1 col-md-1 col-lg-1 ascribe-table-item-column">
|
|
||||||
<TableItemSubtableButton content="+" onClick={this.loadEditionList} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{renderEditionListTable()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default TableItemSubtable;
|
|
@ -1,23 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
let TableItemSubtableButton = React.createClass({
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
content: React.PropTypes.string.isRequired,
|
|
||||||
onClick: React.PropTypes.func.isRequired
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
<button type="button" className="btn btn-default btn-sm ascribe-table-expand-button" onClick={this.props.onClick}>
|
|
||||||
{this.props.content}
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default TableItemSubtableButton;
|
|
@ -34,7 +34,8 @@ let PieceList = React.createClass({
|
|||||||
let page = this.getQuery().page || 1;
|
let page = this.getQuery().page || 1;
|
||||||
PieceListStore.listen(this.onChange);
|
PieceListStore.listen(this.onChange);
|
||||||
if (this.state.pieceList.length === 0){
|
if (this.state.pieceList.length === 0){
|
||||||
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc)
|
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search,
|
||||||
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy)
|
||||||
.then(PieceListActions.fetchPieceRequestActions());
|
.then(PieceListActions.fetchPieceRequestActions());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -59,9 +60,9 @@ let PieceList = React.createClass({
|
|||||||
// the site should go to the top
|
// the site should go to the top
|
||||||
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||||
|
|
||||||
return () => PieceListActions.fetchPieceList(page, this.state.pageSize,
|
return () => PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search,
|
||||||
this.state.search, this.state.orderBy,
|
this.state.orderBy, this.state.orderAsc,
|
||||||
this.state.orderAsc);
|
this.state.filterBy);
|
||||||
},
|
},
|
||||||
|
|
||||||
getPagination() {
|
getPagination() {
|
||||||
@ -79,13 +80,14 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
searchFor(searchTerm) {
|
searchFor(searchTerm) {
|
||||||
PieceListActions.fetchPieceList(1, this.state.pageSize, searchTerm, this.state.orderBy, this.state.orderAsc);
|
PieceListActions.fetchPieceList(1, this.state.pageSize, searchTerm, this.state.orderBy,
|
||||||
|
this.state.orderAsc, this.state.filterBy);
|
||||||
this.transitionTo(this.getPathname(), {page: 1});
|
this.transitionTo(this.getPathname(), {page: 1});
|
||||||
},
|
},
|
||||||
|
|
||||||
accordionChangeOrder(orderBy, orderAsc) {
|
accordionChangeOrder(orderBy, orderAsc) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize,
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||||
this.state.search, orderBy, orderAsc);
|
orderBy, orderAsc, this.state.filterBy);
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -101,7 +101,8 @@ let RegisterPiece = React.createClass( {
|
|||||||
this.state.pageSize,
|
this.state.pageSize,
|
||||||
this.state.searchTerm,
|
this.state.searchTerm,
|
||||||
this.state.orderBy,
|
this.state.orderBy,
|
||||||
this.state.orderAsc
|
this.state.orderAsc,
|
||||||
|
this.state.filterBy
|
||||||
);
|
);
|
||||||
|
|
||||||
this.transitionTo('piece', {pieceId: response.piece.id});
|
this.transitionTo('piece', {pieceId: response.piece.id});
|
||||||
|
@ -3,20 +3,26 @@
|
|||||||
import requests from '../utils/requests';
|
import requests from '../utils/requests';
|
||||||
|
|
||||||
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
||||||
|
import { mergeOptions } from '../utils/general_utils';
|
||||||
|
|
||||||
let EditionListFetcher = {
|
let EditionListFetcher = {
|
||||||
/**
|
/**
|
||||||
* Fetches a list of editions from the API.
|
* Fetches a list of editions from the API.
|
||||||
*/
|
*/
|
||||||
fetch(pieceId, page, pageSize, orderBy, orderAsc) {
|
fetch(pieceId, page, pageSize, orderBy, orderAsc, filterBy) {
|
||||||
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
return requests.get('editions_list', {
|
|
||||||
'piece_id': pieceId,
|
let queryParams = mergeOptions(
|
||||||
page,
|
{
|
||||||
pageSize,
|
page,
|
||||||
ordering
|
pageSize,
|
||||||
});
|
ordering,
|
||||||
|
piece_id: pieceId
|
||||||
|
},
|
||||||
|
filterBy
|
||||||
|
);
|
||||||
|
|
||||||
|
return requests.get('editions_list', queryParams);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,17 +1,31 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
|
||||||
import requests from '../utils/requests';
|
import requests from '../utils/requests';
|
||||||
|
|
||||||
|
import { mergeOptions } from '../utils/general_utils';
|
||||||
|
import { generateOrderingQueryParams } from '../utils/fetch_api_utils';
|
||||||
|
|
||||||
let PieceListFetcher = {
|
let PieceListFetcher = {
|
||||||
/**
|
/**
|
||||||
* Fetches a list of pieces from the API.
|
* Fetches a list of pieces from the API.
|
||||||
* Can be called with all supplied queryparams the API.
|
* Can be called with all supplied queryparams the API.
|
||||||
*/
|
*/
|
||||||
fetch(page, pageSize, search, orderBy, orderAsc) {
|
fetch(page, pageSize, search, orderBy, orderAsc, filterBy) {
|
||||||
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
return requests.get('pieces_list', { page, pageSize, search, ordering });
|
|
||||||
|
// filterBy is an object of acl key-value pairs.
|
||||||
|
// The values are booleans
|
||||||
|
let queryParams = mergeOptions(
|
||||||
|
{
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
search,
|
||||||
|
ordering
|
||||||
|
},
|
||||||
|
filterBy
|
||||||
|
);
|
||||||
|
|
||||||
|
return requests.get('pieces_list', queryParams);
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchRequestActions() {
|
fetchRequestActions() {
|
||||||
|
@ -12,7 +12,7 @@ class EditionListStore {
|
|||||||
this.bindActions(EditionsListActions);
|
this.bindActions(EditionsListActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateEditionList({pieceId, editionListOfPiece, page, pageSize, orderBy, orderAsc, count}) {
|
onUpdateEditionList({pieceId, editionListOfPiece, page, pageSize, orderBy, orderAsc, count, filterBy}) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Basically there are two modes an edition list can be updated.
|
Basically there are two modes an edition list can be updated.
|
||||||
@ -54,6 +54,7 @@ class EditionListStore {
|
|||||||
this.editionList[pieceId].orderBy = orderBy;
|
this.editionList[pieceId].orderBy = orderBy;
|
||||||
this.editionList[pieceId].orderAsc = orderAsc;
|
this.editionList[pieceId].orderAsc = orderAsc;
|
||||||
this.editionList[pieceId].count = count;
|
this.editionList[pieceId].count = count;
|
||||||
|
this.editionList[pieceId].filterBy = filterBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +81,10 @@ class EditionListStore {
|
|||||||
this.editionList[pieceId].length = 0;
|
this.editionList[pieceId].length = 0;
|
||||||
|
|
||||||
// refetch editions with adjusted page size
|
// refetch editions with adjusted page size
|
||||||
EditionsListActions.fetchEditionList(pieceId, 1, prevEditionListLength, this.editionList[pieceId].orderBy, this.editionList[pieceId].orderAsc)
|
EditionsListActions.fetchEditionList(pieceId, 1, prevEditionListLength,
|
||||||
|
this.editionList[pieceId].orderBy,
|
||||||
|
this.editionList[pieceId].orderAsc,
|
||||||
|
this.editionList[pieceId].filterBy)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// reset back to the normal pageSize and page
|
// reset back to the normal pageSize and page
|
||||||
this.editionList[pieceId].page = prevEditionListPage;
|
this.editionList[pieceId].page = prevEditionListPage;
|
||||||
|
@ -26,16 +26,18 @@ class PieceListStore {
|
|||||||
this.search = '';
|
this.search = '';
|
||||||
this.orderBy = 'artist_name';
|
this.orderBy = 'artist_name';
|
||||||
this.orderAsc = true;
|
this.orderAsc = true;
|
||||||
|
this.filterBy = {};
|
||||||
this.bindActions(PieceListActions);
|
this.bindActions(PieceListActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) {
|
onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount, filterBy }) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
this.search = search;
|
this.search = search;
|
||||||
this.orderAsc = orderAsc;
|
this.orderAsc = orderAsc;
|
||||||
this.orderBy = orderBy;
|
this.orderBy = orderBy;
|
||||||
this.pieceListCount = pieceListCount;
|
this.pieceListCount = pieceListCount;
|
||||||
|
this.filterBy = filterBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagination - Known Issue:
|
* Pagination - Known Issue:
|
||||||
|
@ -5,5 +5,41 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
max-width: 160px;
|
max-width: 200px;
|
||||||
|
input {
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-piece-list-toolbar-filter-widget {
|
||||||
|
margin-right: 1em;
|
||||||
|
|
||||||
|
.filter-widget-item {
|
||||||
|
|
||||||
|
> a {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-line {
|
||||||
|
position: relative;
|
||||||
|
height: 25px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: absolute;
|
||||||
|
left: 9px;
|
||||||
|
top: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
right: 9px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user