1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

Fix default filter on piece list

This commit is contained in:
Brett Sun 2015-11-24 19:26:45 +01:00
parent e228a4bf15
commit c270977eb9
6 changed files with 114 additions and 55 deletions

View File

@ -28,7 +28,7 @@ let PieceListToolbarFilterWidget = React.createClass({
}, },
generateFilterByStatement(param) { generateFilterByStatement(param) {
const { filterBy } = this.props; const filterBy = Object.assign({}, this.props.filterBy);
if(filterBy) { if(filterBy) {
// we need hasOwnProperty since the values are all booleans // we need hasOwnProperty since the values are all booleans

View File

@ -26,7 +26,7 @@ import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
import AscribeSpinner from './ascribe_spinner'; import AscribeSpinner from './ascribe_spinner';
import { getAvailableAcls } from '../utils/acl_utils'; import { getAvailableAcls } from '../utils/acl_utils';
import { mergeOptions } from '../utils/general_utils'; import { mergeOptions, isShallowEqual } from '../utils/general_utils';
import { getLangText } from '../utils/lang_utils'; import { getLangText } from '../utils/lang_utils';
import { setDocumentTitle } from '../utils/dom_utils'; import { setDocumentTitle } from '../utils/dom_utils';
@ -35,6 +35,7 @@ let PieceList = React.createClass({
propTypes: { propTypes: {
accordionListItemType: React.PropTypes.func, accordionListItemType: React.PropTypes.func,
bulkModalButtonListType: React.PropTypes.func, bulkModalButtonListType: React.PropTypes.func,
canLoadPieceList: React.PropTypes.bool,
redirectTo: React.PropTypes.string, redirectTo: React.PropTypes.string,
customSubmitButton: React.PropTypes.element, customSubmitButton: React.PropTypes.element,
filterParams: React.PropTypes.array, filterParams: React.PropTypes.array,
@ -49,6 +50,7 @@ let PieceList = React.createClass({
return { return {
accordionListItemType: AccordionListItemWallet, accordionListItemType: AccordionListItemWallet,
bulkModalButtonListType: AclButtonList, bulkModalButtonListType: AclButtonList,
canLoadPieceList: true,
orderParams: ['artist_name', 'title'], orderParams: ['artist_name', 'title'],
filterParams: [{ filterParams: [{
label: getLangText('Show works I can'), label: getLangText('Show works I can'),
@ -62,27 +64,51 @@ let PieceList = React.createClass({
}, },
getInitialState() { getInitialState() {
const pieceListStore = PieceListStore.getState();
const stores = mergeOptions( const stores = mergeOptions(
PieceListStore.getState(), pieceListStore,
EditionListStore.getState() EditionListStore.getState(),
{
isFilterDirty: false
}
); );
// Use the default filters but use the stores' settings if they're available // Use the default filters but use the pieceListStore's settings if they're available
stores.filterBy = Object.assign(this.getDefaultFilterBy(), stores.filterBy); stores.filterBy = Object.assign(this.getDefaultFilterBy(), pieceListStore.filterBy);
return stores; return stores;
}, },
componentDidMount() { componentDidMount() {
let page = this.props.location.query.page || 1;
PieceListStore.listen(this.onChange); PieceListStore.listen(this.onChange);
EditionListStore.listen(this.onChange); EditionListStore.listen(this.onChange);
let orderBy = this.props.orderBy ? this.props.orderBy : this.state.orderBy; let page = this.props.location.query.page || 1;
if (this.state.pieceList.length === 0 || this.state.page !== page){ if (this.props.canLoadPieceList && (this.state.pieceList.length === 0 || this.state.page !== page)) {
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.loadPieceList({ page });
orderBy, this.state.orderAsc, this.state.filterBy); }
},
componentWillReceiveProps(nextProps) {
let filterBy;
let page = this.props.location.query.page || 1;
// If the user hasn't changed the filter and the new default filter is different
// than the current filter, apply the new default filter
if (!this.state.isFilterDirty) {
const newDefaultFilterBy = this.getDefaultFilterBy(nextProps);
// Only need to check shallowly since the filterBy shouldn't be nested
if (!isShallowEqual(this.state.filterBy, newDefaultFilterBy)) {
filterBy = newDefaultFilterBy;
page = 1;
}
}
// Only load if we are applying a new filter or if it's the first time we can
// load the piece list
if (nextProps.canLoadPieceList && (filterBy || !this.props.canLoadPieceList)) {
this.loadPieceList({ page, filterBy });
} }
}, },
@ -102,17 +128,19 @@ let PieceList = React.createClass({
this.setState(state); this.setState(state);
}, },
getDefaultFilterBy() { getDefaultFilterBy(props = this.props) {
const { filterParams } = this.props; const { filterParams } = props;
const defaultFilterBy = {}; const defaultFilterBy = {};
filterParams.forEach(({ label, items }) => { if (filterParams && typeof filterParams.forEach === 'function') {
items.forEach((item) => { filterParams.forEach(({ label, items }) => {
if (typeof item === 'object' && item.defaultValue) { items.forEach((item) => {
defaultFilterBy[item.key] = true; if (typeof item === 'object' && item.defaultValue) {
} defaultFilterBy[item.key] = true;
}
});
}); });
}); }
return defaultFilterBy; return defaultFilterBy;
}, },
@ -122,9 +150,7 @@ let PieceList = React.createClass({
// if the users clicks a pager of the pagination, // if the users clicks a pager of the pagination,
// 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;
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.loadPieceList({ page });
this.state.orderBy, this.state.orderAsc,
this.state.filterBy);
}; };
}, },
@ -143,29 +169,35 @@ let PieceList = React.createClass({
}, },
searchFor(searchTerm) { searchFor(searchTerm) {
PieceListActions.fetchPieceList(1, this.state.pageSize, searchTerm, this.state.orderBy, this.loadPieceList({
this.state.orderAsc, this.state.filterBy); page: 1,
this.history.pushState(null, this.props.location.pathname, {page: 1}); search: searchTerm
});
this.history.pushState(null, this.props.location.pathname, {page: 1});
}, },
applyFilterBy(filterBy){ applyFilterBy(filterBy){
// first we need to apply the filter on the piece list this.setState({
PieceListActions.fetchPieceList(1, this.state.pageSize, this.state.search, isFilterDirty: true
this.state.orderBy, this.state.orderAsc, filterBy) });
.then(() => {
// but also, we need to filter all the open edition lists
this.state.pieceList
.forEach((piece) => {
// but only if they're actually open
if(this.state.isEditionListOpenForPieceId[piece.id].show) {
EditionListActions.refreshEditionList({
pieceId: piece.id,
filterBy
});
}
}); // first we need to apply the filter on the piece list
}); this
.loadPieceList({ page: 1, filterBy })
.then(() => {
// but also, we need to filter all the open edition lists
this.state.pieceList
.forEach((piece) => {
// but only if they're actually open
if(this.state.isEditionListOpenForPieceId[piece.id].show) {
EditionListActions.refreshEditionList({
pieceId: piece.id,
filterBy
});
}
});
});
// we have to redirect the user always to page one as it could be that there is no page two // we have to redirect the user always to page one as it could be that there is no page two
// for filtered pieces // for filtered pieces
@ -177,6 +209,13 @@ let PieceList = React.createClass({
orderBy, this.state.orderAsc, this.state.filterBy); orderBy, this.state.orderAsc, this.state.filterBy);
}, },
loadPieceList({ page, filterBy = this.state.filterBy, search = this.state.search }) {
let orderBy = this.state.orderBy ? this.state.orderBy : this.props.orderBy;
return PieceListActions.fetchPieceList(page, this.state.pageSize, search,
orderBy, this.state.orderAsc, filterBy);
},
fetchSelectedPieceEditionList() { fetchSelectedPieceEditionList() {
let filteredPieceIdList = Object.keys(this.state.editionList) let filteredPieceIdList = Object.keys(this.state.editionList)
.filter((pieceId) => { .filter((pieceId) => {

View File

@ -21,6 +21,10 @@ let LumenusLanding = React.createClass({
); );
}, },
componentWillMount() {
setDocumentTitle('Lumenus Marketplace');
},
componentDidMount() { componentDidMount() {
WhitelabelStore.listen(this.onChange); WhitelabelStore.listen(this.onChange);
WhitelabelActions.fetchWhitelabel(); WhitelabelActions.fetchWhitelabel();
@ -35,8 +39,6 @@ let LumenusLanding = React.createClass({
}, },
render() { render() {
setDocumentTitle('Lumenus Marketplace');
return ( return (
<div className="container ascribe-form-wrapper"> <div className="container ascribe-form-wrapper">
<div className="row"> <div className="row">

View File

@ -27,6 +27,10 @@ let MarketPieceList = React.createClass({
); );
}, },
componentWillMount() {
setDocumentTitle(getLangText('Collection'));
},
componentDidMount() { componentDidMount() {
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange); WhitelabelStore.listen(this.onChange);
@ -46,23 +50,30 @@ let MarketPieceList = React.createClass({
render() { render() {
const { currentUser, whitelabel } = this.state; const { currentUser, whitelabel } = this.state;
const isUserAdmin = currentUser.email === whitelabel.user; let filterParams = undefined;
let canLoadPieceList = false;
setDocumentTitle(getLangText('Collection')); if (currentUser.email && whitelabel.user) {
canLoadPieceList = true;
const isUserAdmin = currentUser.email === whitelabel.user;
filterParams = [{
label: getLangText('Show works I can'),
items: [{
key: isUserAdmin ? 'acl_transfer' : 'acl_consign',
label: getLangText(isUserAdmin ? 'transfer' : 'consign to %s', whitelabel.name),
defaultValue: true
}]
}];
}
return ( return (
<PieceList <PieceList
canLoadPieceList={canLoadPieceList}
redirectTo="/register_piece?slide_num=0" redirectTo="/register_piece?slide_num=0"
bulkModalButtonListType={MarketAclButtonList} bulkModalButtonListType={MarketAclButtonList}
filterParams={[{ filterParams={filterParams}
label: getLangText('Show works I can'), location={this.props.location} />
items: [{
key: isUserAdmin ? 'acl_transfer' : 'acl_consign',
label: getLangText(isUserAdmin ? 'transfer' : 'consign to Market'),
defaultValue: true
}]
}]}
location={this.props.location}/>
); );
} }
}); });

View File

@ -1,5 +1,11 @@
'use strict'; 'use strict';
/**
* Checks shallow equality
* Re-export of shallow from shallow-equals
*/
export { default as isShallowEqual } from 'shallow-equals';
/** /**
* Takes an object and returns a shallow copy without any keys * Takes an object and returns a shallow copy without any keys
* that fail the passed in filter function. * that fail the passed in filter function.

View File

@ -85,6 +85,7 @@
"react-star-rating": "~1.3.2", "react-star-rating": "~1.3.2",
"react-textarea-autosize": "^2.5.2", "react-textarea-autosize": "^2.5.2",
"reactify": "^1.1.0", "reactify": "^1.1.0",
"shallow-equals": "0.0.0",
"shmui": "^0.1.0", "shmui": "^0.1.0",
"spark-md5": "~1.0.0", "spark-md5": "~1.0.0",
"uglifyjs": "^2.4.10", "uglifyjs": "^2.4.10",