1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-23 01:39:36 +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:
diminator 2015-08-05 14:52:18 +02:00
commit 36356dd5c5
22 changed files with 263 additions and 207 deletions

View File

@ -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
}); });

View File

@ -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
}); });

View File

@ -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);

View File

@ -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);
} }
}, },

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;
}
}, },

View File

@ -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) => {

View File

@ -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: {

View File

@ -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>

View File

@ -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;
label = param.split('_')[1];
}
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> </div>
</MenuItem> </MenuItem>
);
})}
</DropdownButton> </DropdownButton>
); );
} }

View File

@ -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;

View File

@ -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;

View File

@ -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() {

View File

@ -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});

View File

@ -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, page,
pageSize, pageSize,
ordering ordering,
}); piece_id: pieceId
},
filterBy
);
return requests.get('editions_list', queryParams);
} }
}; };

View File

@ -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() {

View File

@ -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;

View File

@ -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:

View File

@ -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;
}
}
} }