diff --git a/src/client/actions/ParticipantActions.js b/src/client/actions/ParticipantActions.js index e9c2dc86..8a1c6042 100644 --- a/src/client/actions/ParticipantActions.js +++ b/src/client/actions/ParticipantActions.js @@ -49,7 +49,7 @@ export function getParticipantActions(alt, participantResource, errorActions) { } else { this.participantListUpdated(participantList); } - }, err => errorActions.error(err, 'Osallitujia ei voitu ladata')); + }, err => errorActions.error(err, 'Osallistujia ei voitu ladata')); }; } @@ -61,9 +61,12 @@ export function getParticipantActions(alt, participantResource, errorActions) { } 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), - err => errorActions.error(err, 'Osallistujien tilan päivitys epäonnistui')); + return dispatch => { + dispatch(); + participantResource.raw('post', 'massAssign', { body: { ids: ids, newValue: newValue, fieldName: 'presence' } }) + .then(response => this.loadParticipantList(offset, limit, order, filter), + err => errorActions.error(err, 'Osallistujien tilan päivitys epäonnistui')); + }; } updateProperty(participantId, property, value) { diff --git a/src/client/components/ParticipantListPage/ParticipantListPage.jsx b/src/client/components/ParticipantListPage/ParticipantListPage.jsx index f74ee138..c5cf6501 100644 --- a/src/client/components/ParticipantListPage/ParticipantListPage.jsx +++ b/src/client/components/ParticipantListPage/ParticipantListPage.jsx @@ -1,6 +1,6 @@ import React from 'react'; import _ from 'lodash'; -import { Table, Grid, Row, Col, Input, Button } from 'react-bootstrap'; +import { Table, Grid, Row, Col, Input } from 'react-bootstrap'; import { getParticipantListUpdater } from './containers/ParticipantListUpdater'; import { getSortableHeaderCellContainer } from './containers/SortableHeaderCellContainer'; import { getListOffsetSelectorContainer } from './containers/ListOffsetSelectorContainer'; @@ -8,6 +8,7 @@ import { getParticipantRowsContainer } from './containers/ParticipantRowsContain import { getQuickFilterContainer } from './containers/QuickFilterContainer'; import { getParticipantCount } from './containers/ParticipantCount'; import { getPresenceLabel } from '../../components'; +import { LoadingButton } from '../../components'; function getOrder(query) { try { @@ -35,22 +36,36 @@ function getLimit(query) { return query.limit && Number(query.limit) || 200; } -export function getMassEdit() { +export function getMassEdit(participantStore) { class MassEdit extends React.Component { constructor(props){ super(props); - this.state = {}; + this.state = { loading: false }; this.onSubmit = this.onSubmit.bind(this); this.onChange = this.onChange.bind(this); + this.onStoreChanged = this.onStoreChanged.bind(this); } onSubmit(event) { event.preventDefault(); if (this.state.value !== null && this.state.value !== 'null') { + this.setState({ value: this.state.value, loading: true }); this.props.onSubmit(this.state.value); } } + componentDidMount() { + participantStore.listen(this.onStoreChanged); + } + + componentWillUnmount() { + participantStore.unlisten(this.onStoreChanged); + } + + onStoreChanged() { + this.setState({ loading: false }); + } + onChange(event){ event.persist(); this.setState({ value: event.target.value }); @@ -69,7 +84,7 @@ export function getMassEdit() { - + ); } @@ -118,7 +133,7 @@ export function getParticipantListPage(participantStore, participantActions, sea const ParticipantRowsContainer = getParticipantRowsContainer(participantStore); const QuickFilterContainer = getQuickFilterContainer(participantStore, participantActions, searchFilterActions, searchFilterStore); const ParticipantCount = getParticipantCount(participantStore); - const MassEdit = getMassEdit(); + const MassEdit = getMassEdit(participantStore); const SelectAll = getSelectAll(); class ParticipantListPage extends React.Component { diff --git a/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx b/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx index 2e00590a..9420a8a8 100644 --- a/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx +++ b/src/client/components/ParticipantListPage/containers/ParticipantRowsContainer.jsx @@ -52,7 +52,7 @@ export function getParticipantRowsContainer(participantStore) { const rowCreator = element => ; - return this.state.participants === undefined + return this.state.loading ? ( diff --git a/src/client/components/Util/LoadingButton.jsx b/src/client/components/Util/LoadingButton.jsx new file mode 100644 index 00000000..36ac7f98 --- /dev/null +++ b/src/client/components/Util/LoadingButton.jsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Button } from 'react-bootstrap'; + +export class LoadingButton extends React.Component { + render() { + return ( + + ); + } +} + +LoadingButton.propTypes = { + loading: React.PropTypes.bool.isRequired, + label: React.PropTypes.string.isRequired, + labelWhileLoading: React.PropTypes.string.isRequired, + bsStyle: React.PropTypes.string, +}; diff --git a/src/client/components/index.js b/src/client/components/index.js index d312836c..36332240 100644 --- a/src/client/components/index.js +++ b/src/client/components/index.js @@ -26,3 +26,4 @@ export { PresenceHistory } from './ParticipantDetailsPage/PresenceHistory'; export { ParticipantDates } from './ParticipantDetailsPage/ParticipantDates'; export { getLogin } from './OfflineLogin'; export { PropertyTextArea } from './PropertyTextArea'; +export { LoadingButton } from './Util/LoadingButton'; diff --git a/src/client/stores/ParticipantStore.js b/src/client/stores/ParticipantStore.js index 22465f12..31277e5f 100644 --- a/src/client/stores/ParticipantStore.js +++ b/src/client/stores/ParticipantStore.js @@ -22,13 +22,14 @@ export function getParticipantStore(alt, ParticipantActions, RegistryUserActions } handleLoadParticipantList(countParticipants) { - this.participants = undefined; + this.loading = true; if (countParticipants) { this.participantCount = undefined; } } handleParticipantListUpdated({ participants, newCount }) { + this.loading = false; this.participants = participants; if (newCount !== undefined) { this.participantCount = newCount; diff --git a/src/client/styles.scss b/src/client/styles.scss index d6adcf63..ed724b54 100644 --- a/src/client/styles.scss +++ b/src/client/styles.scss @@ -65,6 +65,15 @@ $screen-sm: 768px; @import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss"; @import "~react-spinner/react-spinner.css"; +table .react-spinner, .h2 .react-spinner { + top: 15px; + left: 15px; +} + +.react-spinner_bar { + background: $mid-grey; +} + /** * Tables */