From ed84fc548bfaeb1de7d396b85c790fcce584f9e5 Mon Sep 17 00:00:00 2001 From: Pompo Stenberg Date: Mon, 18 Jul 2016 02:32:00 +0300 Subject: [PATCH] Revert "Bugfix/participantlist count out of sync" --- src/client/actions/ParticipantActions.js | 42 +++++++----- .../ParticipantListPage.jsx | 5 +- .../ListOffsetSelectorContainer.jsx | 2 +- .../containers/ParticipantCount.jsx | 61 +++++------------ .../containers/ParticipantCountUpdater.jsx | 22 +++++++ .../containers/ParticipantListUpdater.jsx | 23 ++----- .../containers/ParticipantRowsContainer.jsx | 66 +++++-------------- src/client/stores/ParticipantStore.js | 18 ++--- src/client/styles.scss | 15 ++--- src/common/models/participant.js | 31 --------- 10 files changed, 100 insertions(+), 185 deletions(-) create mode 100644 src/client/components/ParticipantListPage/containers/ParticipantCountUpdater.jsx diff --git a/src/client/actions/ParticipantActions.js b/src/client/actions/ParticipantActions.js index 15a35fac..2935ce15 100644 --- a/src/client/actions/ParticipantActions.js +++ b/src/client/actions/ParticipantActions.js @@ -17,7 +17,7 @@ export function getParticipantActions(alt, participantResource) { return err; } - loadParticipantList(offset, limit, order, filter, countParticipants) { + loadParticipantList(offset, limit, order, filter) { function getLoopbackOrderParameter() { if (!order) { return undefined; @@ -38,35 +38,41 @@ export function getParticipantActions(alt, participantResource) { skip: offset, limit: limit, order: getLoopbackOrderParameter(), - count: countParticipants, }; - const filterString = `filter=${encodeURIComponent(JSON.stringify(filters))}`; - return dispatch => { - dispatch(countParticipants); - participantResource.findAll(filterString) - .then(participantList => { - if (countParticipants) { - this.participantListUpdated(participantList.result, participantList.count); - } else { - this.participantListUpdated(participantList); - } - }, err => this.participantListUpdateFailed(err)); + dispatch(); + participantResource.findAll(`filter=${encodeURIComponent(JSON.stringify(filters))}`) + .then(participantList => this.participantListUpdated(participantList), + err => this.participantListUpdateFailed(err)); }; } - participantListUpdated(participants, newCount) { - return { - participants: participants, - newCount: newCount, - }; + participantListUpdated(participants) { + return participants; } participantListUpdateFailed(error) { return error; } + loadParticipantCount(filter) { + return dispatch => { + dispatch(); + participantResource.raw('get', 'count', { filters: `where=${encodeURIComponent(JSON.stringify(filter))}` }) + .then(response => this.participantCountUpdated(response.count), + err => this.participantCountUpdateFailed(err)); + }; + } + + participantCountUpdated(newCount) { + return newCount; + } + + participantCountUpdateFailed(err) { + return err; + } + updateParticipantPresences(ids, newValue, offset, limit, order, filter) { participantResource.raw('post', 'massAssign', { body: { ids: ids, newValue: newValue, fieldName: 'presence' } }) .then(response => this.loadParticipantList(offset, limit, order, filter), diff --git a/src/client/components/ParticipantListPage/ParticipantListPage.jsx b/src/client/components/ParticipantListPage/ParticipantListPage.jsx index 2bf4f6a7..acd36671 100644 --- a/src/client/components/ParticipantListPage/ParticipantListPage.jsx +++ b/src/client/components/ParticipantListPage/ParticipantListPage.jsx @@ -2,6 +2,7 @@ import React from 'react'; import _ from 'lodash'; import { Table, Grid, Row, Col, Input, Button } from 'react-bootstrap'; import { getParticipantListUpdater } from './containers/ParticipantListUpdater'; +import { getParticipantCountUpdater } from './containers/ParticipantCountUpdater'; import { getSortableHeaderCellContainer } from './containers/SortableHeaderCellContainer'; import { getListOffsetSelectorContainer } from './containers/ListOffsetSelectorContainer'; import { getParticipantRowsContainer } from './containers/ParticipantRowsContainer'; @@ -113,6 +114,7 @@ export function getSelectAll() { export function getParticipantListPage(participantStore, participantActions, searchFilterActions, searchFilterStore) { const ParticipantListUpdater = getParticipantListUpdater(participantActions); + const ParticipantCountUpdater = getParticipantCountUpdater(participantActions); const SortableHeaderCellContainer = getSortableHeaderCellContainer(); const ListOffsetSelectorContainer = getListOffsetSelectorContainer(participantStore); const ParticipantRowsContainer = getParticipantRowsContainer(participantStore); @@ -223,6 +225,7 @@ export function getParticipantListPage(participantStore, participantActions, sea return ( +

Leiriläiset

@@ -260,7 +263,7 @@ export function getParticipantListPage(participantStore, participantActions, sea } - + diff --git a/src/client/components/ParticipantListPage/containers/ListOffsetSelectorContainer.jsx b/src/client/components/ParticipantListPage/containers/ListOffsetSelectorContainer.jsx index c8acfd8d..e2ce9e11 100644 --- a/src/client/components/ParticipantListPage/containers/ListOffsetSelectorContainer.jsx +++ b/src/client/components/ParticipantListPage/containers/ListOffsetSelectorContainer.jsx @@ -10,7 +10,7 @@ export function getListOffsetSelectorContainer(participantStore) { stores={ { count: function() { - return { store: participantStore, value: participantStore.getState().participantCount || 0 }; + return { store: participantStore, value: participantStore.getState().participantCount }; }, } } diff --git a/src/client/components/ParticipantListPage/containers/ParticipantCount.jsx b/src/client/components/ParticipantListPage/containers/ParticipantCount.jsx index 506c5635..701225e8 100644 --- a/src/client/components/ParticipantListPage/containers/ParticipantCount.jsx +++ b/src/client/components/ParticipantListPage/containers/ParticipantCount.jsx @@ -1,5 +1,6 @@ import React from 'react'; -import Spinner from 'react-spinner'; +import AltContainer from 'alt-container'; +import { pureShouldComponentUpdate } from '../../../utils'; function Count(props) { return ( @@ -13,52 +14,20 @@ Count.propTypes = { count: React.PropTypes.number, }; -function CountSpinner() { - return ( -
- Hakutulokset -
-
- ); -} - export function getParticipantCount(participantStore) { - class ParticipantCount extends React.Component { - constructor(props) { - super(props); - - this.state = this.extractState(); - - this.onStoreChanged = this.onStoreChanged.bind(this); - } - - componentDidMount() { - participantStore.listen(this.onStoreChanged); - } - - componentWillUnmount() { - participantStore.unlisten(this.onStoreChanged); - } - - onStoreChanged() { - this.setState(this.extractState()); - } - - extractState() { - return { count: participantStore.getState().participantCount }; - } - - render() { - if (this.state.count === undefined) { - return ( - - ); - } else { - return ( - - ); - } - } + function ParticipantCount() { + return ( + ({ store: participantStore, value: participantStore.getState().participantCount }), + } + } + shouldComponentUpdate={ pureShouldComponentUpdate } + > + + + ); } return ParticipantCount; diff --git a/src/client/components/ParticipantListPage/containers/ParticipantCountUpdater.jsx b/src/client/components/ParticipantListPage/containers/ParticipantCountUpdater.jsx new file mode 100644 index 00000000..2a5d30e6 --- /dev/null +++ b/src/client/components/ParticipantListPage/containers/ParticipantCountUpdater.jsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { pureShouldComponentUpdate } from '../../../utils'; + +export function getParticipantCountUpdater(participantActions) { + class ParticipantCountUpdater extends React.Component { + shouldComponentUpdate(nextProps, nextState) { + return pureShouldComponentUpdate.call(this, nextProps, nextState); + } + + render() { + participantActions.loadParticipantCount.defer(this.props.filter); + return null; + } + } + + ParticipantCountUpdater.propTypes = { + filter: React.PropTypes.object, + }; + + return ParticipantCountUpdater; +} + diff --git a/src/client/components/ParticipantListPage/containers/ParticipantListUpdater.jsx b/src/client/components/ParticipantListPage/containers/ParticipantListUpdater.jsx index 54ab681e..b93b2c6c 100644 --- a/src/client/components/ParticipantListPage/containers/ParticipantListUpdater.jsx +++ b/src/client/components/ParticipantListPage/containers/ParticipantListUpdater.jsx @@ -1,36 +1,25 @@ import React from 'react'; -import _ from 'lodash'; +import { pureShouldComponentUpdate } from '../../../utils'; export function getParticipantListUpdater(participantActions) { class ParticipantListUpdater extends React.Component { - reloadList(nextProps, recount) { + reloadList() { const { offset, limit, order, filter, - } = nextProps; + } = this.props; - participantActions.loadParticipantList(offset, limit, order, filter, recount); - } - - componentWillMount() { - this.reloadList(this.props, true); - } - - componentWillReceiveProps(nextProps) { - if (!_.isEqual(this.props, nextProps)) { - const recount = !_.isEqual(this.props.filter, nextProps.filter); - - this.reloadList(nextProps, recount); - } + participantActions.loadParticipantList.defer(offset, limit, order, filter); } shouldComponentUpdate(nextProps, nextState) { - return false; + return pureShouldComponentUpdate.call(this, nextProps, nextState); } render() { + this.reloadList(); return null; } } diff --git a/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx b/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx index cf8674de..59d5a9be 100644 --- a/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx +++ b/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx @@ -1,6 +1,7 @@ import React from 'react'; -import Spinner from 'react-spinner'; +import AltContainer from 'alt-container'; import { ParticipantRow } from '../../../components'; +import { pureShouldComponentUpdate } from '../../../utils'; function Tbody(props) { const elements = props.elements || []; @@ -17,59 +18,26 @@ Tbody.propTypes = { }; export function getParticipantRowsContainer(participantStore) { - class ParticipantRowsContainer extends React.Component { - constructor(props) { - super(props); - - this.onStoreChange = this.onStoreChange.bind(this); - - this.state = this.extractState(); - } - - componentDidMount() { - participantStore.listen(this.onStoreChange); - } - - componentWillUnmount() { - participantStore.unlisten(this.onStoreChange); - } - - onStoreChange() { - this.setState(this.extractState()); - } - - extractState() { - return { participants: participantStore.getState().participants }; - } - - render() { - const { - isChecked, - checkboxCallback, - columnCount, - } = this.props; - - const rowCreator = element => ; - - return this.state.participants === undefined - ? ( - - - - - - - - ) : ( - - ); - } + function ParticipantRowsContainer({ isChecked, checkboxCallback }) { + const rowCreator = element => ; + + return ( + ({ store: participantStore, value: participantStore.getState().participants }), + } + } + shouldComponentUpdate={ pureShouldComponentUpdate } + > + + + ); } ParticipantRowsContainer.propTypes = { isChecked: React.PropTypes.func, checkboxCallback: React.PropTypes.func, - columnCount: React.PropTypes.number, }; return ParticipantRowsContainer; diff --git a/src/client/stores/ParticipantStore.js b/src/client/stores/ParticipantStore.js index 8611ff27..1cc8ebf3 100644 --- a/src/client/stores/ParticipantStore.js +++ b/src/client/stores/ParticipantStore.js @@ -5,8 +5,8 @@ export function getParticipantStore(alt, ParticipantActions, RegistryUserActions this.bindListeners({ handleUpdateParticipantById: ParticipantActions.UPDATE_PARTICIPANT_BY_ID, - handleLoadParticipantList: ParticipantActions.LOAD_PARTICIPANT_LIST, handleParticipantListUpdated: ParticipantActions.PARTICIPANT_LIST_UPDATED, + handleParticipantCountUpdated: ParticipantActions.PARTICIPANT_COUNT_UPDATED, handleParticipantPropertyUpdated: ParticipantActions.PARTICIPANT_PROPERTY_UPDATED, resetAllData: RegistryUserActions.RESET_ALL_DATA, }); @@ -16,18 +16,8 @@ export function getParticipantStore(alt, ParticipantActions, RegistryUserActions this.participantDetails = participant; } - handleLoadParticipantList(countParticipants) { - this.participants = undefined; - if (countParticipants) { - this.participantCount = undefined; - } - } - - handleParticipantListUpdated({ participants, newCount }) { + handleParticipantListUpdated(participants) { this.participants = participants; - if (newCount !== undefined) { - this.participantCount = newCount; - } } handleParticipantCountUpdated(newCount) { @@ -39,9 +29,9 @@ export function getParticipantStore(alt, ParticipantActions, RegistryUserActions } resetAllData() { - this.participants = undefined; + this.participants = [ ]; this.participantDetails = {}; - this.participantCount = undefined; + this.participantCount = 0; this.localGroups = ['']; this.campGroups = ['']; diff --git a/src/client/styles.scss b/src/client/styles.scss index cccd69d9..9e7e4cf7 100644 --- a/src/client/styles.scss +++ b/src/client/styles.scss @@ -63,7 +63,6 @@ $screen-xs: 480px; $screen-sm: 768px; @import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss"; -@import "~react-spinner/react-spinner.css"; /** * Tables @@ -71,10 +70,10 @@ $screen-sm: 768px; table { border: 1px solid $table-border-color; - + &.noborder { border: none; - + & td:first-child, & th:first-child { padding-left: 0; } & td:last-child, & th:last-child { padding-right: 0; } } @@ -115,7 +114,7 @@ table { td { padding-top: 1em !important; padding-bottom: 1em !important; - + input[type="checkbox"] { position: absolute !important; top: -28px; @@ -261,7 +260,7 @@ table { table .presence { margin-bottom: 0; - + .ball { margin-left: 0.5em; } @@ -325,10 +324,10 @@ dl { margin: -1em 0 0; dt { - font-weight: 400; - margin-top: 1em; + font-weight: 400; + margin-top: 1em; } - + dd { @extend .text-muted; } diff --git a/src/common/models/participant.js b/src/common/models/participant.js index afe50f1e..821e5231 100644 --- a/src/common/models/participant.js +++ b/src/common/models/participant.js @@ -91,36 +91,6 @@ export default function (Participant) { } } - function checkFullParticipantCount(ctx, participantInstance, next) { - Promise.try(() => getFilterIfShouldCount()) - .then(filterForCount => { - if (filterForCount) { - const countParticipants = Promise.promisify(Participant.count, { context: Participant }); - return countParticipants(filterForCount) - .then(count => { - const findResult = ctx.result; - ctx.result = { - result: findResult, - count: count, - }; - console.log(filterForCount); - console.log(ctx.result); - }); - } - }).asCallback(next); - - function getFilterIfShouldCount() { - const args = ctx && ctx.args || null; - - if (args && args.filter && _.isString(args.filter)) { - // This if clause is technically not needed since the textsearch hook does the same but I left it here for robustness, in case the text search is changed - args.filter = JSON.parse(args.filter); - } - - return args && args.filter && args.filter.count && args.filter.where || false; - } - } - Participant.afterRemote('create', (ctx, participantInstance, next) => { const userId = ctx.req.accessToken ? ctx.req.accessToken.userId : 0; app.models.AuditEvent.createEvent.Participant(userId, participantInstance.participantId, 'add') @@ -140,7 +110,6 @@ export default function (Participant) { }); Participant.beforeRemote('find', handleTextSearch); - Participant.afterRemote('find', checkFullParticipantCount); Participant.beforeRemote('count', handleTextSearch);