Nicer alerts when an API error occurs, see #6
This commit is contained in:
parent
9d1ef1b0bf
commit
bb02473b11
2
TODO
2
TODO
@ -1,5 +1,3 @@
|
|||||||
* PropTypes.object
|
|
||||||
|
|
||||||
5. Web player
|
5. Web player
|
||||||
6. Homepage
|
6. Homepage
|
||||||
7. Settings
|
7. Settings
|
||||||
|
@ -10,7 +10,7 @@ import commonMessages from "../locales/messagesDescriptors/common";
|
|||||||
|
|
||||||
import css from "../styles/Album.scss";
|
import css from "../styles/Album.scss";
|
||||||
|
|
||||||
const albumMessages = defineMessages(messagesMap(commonMessages));
|
const albumMessages = defineMessages(messagesMap(Array.concat([], commonMessages)));
|
||||||
|
|
||||||
class AlbumTrackRowCSS extends Component {
|
class AlbumTrackRowCSS extends Component {
|
||||||
render () {
|
render () {
|
||||||
|
@ -2,9 +2,15 @@ import React, { Component, PropTypes } from "react";
|
|||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import FilterablePaginatedGrid from "./elements/Grid";
|
import FilterablePaginatedGrid from "./elements/Grid";
|
||||||
|
import DismissibleAlert from "./elements/DismissibleAlert";
|
||||||
|
|
||||||
export default class Albums extends Component {
|
export default class Albums extends Component {
|
||||||
render () {
|
render () {
|
||||||
|
let error = null;
|
||||||
|
if (this.props.error) {
|
||||||
|
error = (<DismissibleAlert type="danger" text={this.props.error} />);
|
||||||
|
}
|
||||||
|
|
||||||
const grid = {
|
const grid = {
|
||||||
isFetching: this.props.isFetching,
|
isFetching: this.props.isFetching,
|
||||||
items: this.props.albums,
|
items: this.props.albums,
|
||||||
@ -14,13 +20,17 @@ export default class Albums extends Component {
|
|||||||
subItemsLabel: "app.common.track"
|
subItemsLabel: "app.common.track"
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
{ error }
|
||||||
<FilterablePaginatedGrid grid={grid} pagination={this.props.pagination} />
|
<FilterablePaginatedGrid grid={grid} pagination={this.props.pagination} />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Albums.propTypes = {
|
Albums.propTypes = {
|
||||||
isFetching: PropTypes.bool.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
|
error: PropTypes.string,
|
||||||
albums: PropTypes.instanceOf(Immutable.List).isRequired,
|
albums: PropTypes.instanceOf(Immutable.List).isRequired,
|
||||||
pagination: PropTypes.object.isRequired,
|
pagination: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -7,6 +7,7 @@ import Immutable from "immutable";
|
|||||||
import { messagesMap } from "../utils/";
|
import { messagesMap } from "../utils/";
|
||||||
|
|
||||||
import { AlbumRow } from "./Album";
|
import { AlbumRow } from "./Album";
|
||||||
|
import DismissibleAlert from "./elements/DismissibleAlert";
|
||||||
|
|
||||||
import commonMessages from "../locales/messagesDescriptors/common";
|
import commonMessages from "../locales/messagesDescriptors/common";
|
||||||
|
|
||||||
@ -25,11 +26,16 @@ class ArtistCSS extends Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this.props.artist) {
|
if (this.props.isFetching && !this.props.artist) {
|
||||||
// Loading
|
// Loading
|
||||||
return loading;
|
return loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let error = null;
|
||||||
|
if (this.props.error) {
|
||||||
|
error = (<DismissibleAlert type="danger" text={this.props.error} />);
|
||||||
|
}
|
||||||
|
|
||||||
let albumsRows = [];
|
let albumsRows = [];
|
||||||
const { albums, songs } = this.props;
|
const { albums, songs } = this.props;
|
||||||
const artistAlbums = this.props.artist.get("albums");
|
const artistAlbums = this.props.artist.get("albums");
|
||||||
@ -48,6 +54,7 @@ class ArtistCSS extends Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{ error }
|
||||||
<div className="row" styleName="name">
|
<div className="row" styleName="name">
|
||||||
<div className="col-sm-12">
|
<div className="col-sm-12">
|
||||||
<h1>{this.props.artist.get("name")}</h1>
|
<h1>{this.props.artist.get("name")}</h1>
|
||||||
@ -70,6 +77,7 @@ class ArtistCSS extends Component {
|
|||||||
|
|
||||||
ArtistCSS.propTypes = {
|
ArtistCSS.propTypes = {
|
||||||
isFetching: PropTypes.bool.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
|
error: PropTypes.string,
|
||||||
artist: PropTypes.instanceOf(Immutable.Map),
|
artist: PropTypes.instanceOf(Immutable.Map),
|
||||||
albums: PropTypes.instanceOf(Immutable.Map),
|
albums: PropTypes.instanceOf(Immutable.Map),
|
||||||
songs: PropTypes.instanceOf(Immutable.Map)
|
songs: PropTypes.instanceOf(Immutable.Map)
|
||||||
|
@ -2,9 +2,15 @@ import React, { Component, PropTypes } from "react";
|
|||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import FilterablePaginatedGrid from "./elements/Grid";
|
import FilterablePaginatedGrid from "./elements/Grid";
|
||||||
|
import DismissibleAlert from "./elements/DismissibleAlert";
|
||||||
|
|
||||||
class Artists extends Component {
|
class Artists extends Component {
|
||||||
render () {
|
render () {
|
||||||
|
let error = null;
|
||||||
|
if (this.props.error) {
|
||||||
|
error = (<DismissibleAlert type="danger" text={this.props.error} />);
|
||||||
|
}
|
||||||
|
|
||||||
const grid = {
|
const grid = {
|
||||||
isFetching: this.props.isFetching,
|
isFetching: this.props.isFetching,
|
||||||
items: this.props.artists,
|
items: this.props.artists,
|
||||||
@ -14,13 +20,17 @@ class Artists extends Component {
|
|||||||
subItemsLabel: "app.common.album"
|
subItemsLabel: "app.common.album"
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
{ error }
|
||||||
<FilterablePaginatedGrid grid={grid} pagination={this.props.pagination} />
|
<FilterablePaginatedGrid grid={grid} pagination={this.props.pagination} />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Artists.propTypes = {
|
Artists.propTypes = {
|
||||||
isFetching: PropTypes.bool.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
|
error: PropTypes.string,
|
||||||
artists: PropTypes.instanceOf(Immutable.List).isRequired,
|
artists: PropTypes.instanceOf(Immutable.List).isRequired,
|
||||||
pagination: PropTypes.object.isRequired,
|
pagination: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@ import FontAwesome from "react-fontawesome";
|
|||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
import Fuse from "fuse.js";
|
import Fuse from "fuse.js";
|
||||||
|
|
||||||
|
import DismissibleAlert from "./elements/DismissibleAlert";
|
||||||
import FilterBar from "./elements/FilterBar";
|
import FilterBar from "./elements/FilterBar";
|
||||||
import Pagination from "./elements/Pagination";
|
import Pagination from "./elements/Pagination";
|
||||||
import { formatLength, messagesMap } from "../utils";
|
import { formatLength, messagesMap } from "../utils";
|
||||||
@ -135,8 +136,14 @@ export default class FilterablePaginatedSongsTable extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
let error = null;
|
||||||
|
if (this.props.error) {
|
||||||
|
error = (<DismissibleAlert type="danger" text={this.props.error} />);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{ error }
|
||||||
<FilterBar filterText={this.state.filterText} onUserInput={this.handleUserInput} />
|
<FilterBar filterText={this.state.filterText} onUserInput={this.handleUserInput} />
|
||||||
<SongsTable isFetching={this.props.isFetching} songs={this.props.songs} filterText={this.state.filterText} />
|
<SongsTable isFetching={this.props.isFetching} songs={this.props.songs} filterText={this.state.filterText} />
|
||||||
<Pagination {...this.props.pagination} />
|
<Pagination {...this.props.pagination} />
|
||||||
@ -147,6 +154,7 @@ export default class FilterablePaginatedSongsTable extends Component {
|
|||||||
|
|
||||||
FilterablePaginatedSongsTable.propTypes = {
|
FilterablePaginatedSongsTable.propTypes = {
|
||||||
isFetching: PropTypes.bool.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
|
error: PropTypes.string,
|
||||||
songs: PropTypes.instanceOf(Immutable.List).isRequired,
|
songs: PropTypes.instanceOf(Immutable.List).isRequired,
|
||||||
pagination: PropTypes.object.isRequired
|
pagination: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
25
app/components/elements/DismissibleAlert.jsx
Normal file
25
app/components/elements/DismissibleAlert.jsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import React, { Component, PropTypes } from "react";
|
||||||
|
|
||||||
|
export default class DismissibleAlert extends Component {
|
||||||
|
render () {
|
||||||
|
let alertType = "alert-danger";
|
||||||
|
if (this.props.type) {
|
||||||
|
alertType = "alert-" + this.props.type;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={["alert", alertType].join(" ")} role="alert">
|
||||||
|
<p>
|
||||||
|
<button type="button" className="close" data-dismiss="alert" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
{this.props.text}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DismissibleAlert.propTypes = {
|
||||||
|
type: PropTypes.string,
|
||||||
|
text: PropTypes.string
|
||||||
|
};
|
@ -7,7 +7,7 @@ import messages from "../../locales/messagesDescriptors/elements/FilterBar";
|
|||||||
|
|
||||||
import css from "../../styles/elements/FilterBar.scss";
|
import css from "../../styles/elements/FilterBar.scss";
|
||||||
|
|
||||||
const filterMessages = defineMessages(messagesMap(messages));
|
const filterMessages = defineMessages(messagesMap(Array.concat([], messages)));
|
||||||
|
|
||||||
class FilterBarCSSIntl extends Component {
|
class FilterBarCSSIntl extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { i18nRecord } from "../models/i18n";
|
||||||
|
|
||||||
export function getBrowserLocales () {
|
export function getBrowserLocales () {
|
||||||
let langs;
|
let langs;
|
||||||
|
|
||||||
@ -31,3 +33,11 @@ export function messagesMap(messagesDescriptorsArray) {
|
|||||||
|
|
||||||
return messagesDescriptorsMap;
|
return messagesDescriptorsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function handleErrorI18nObject(errorMessage, formatMessage, messages) {
|
||||||
|
if (errorMessage instanceof i18nRecord) {
|
||||||
|
return formatMessage(messages[errorMessage.id], errorMessage.values);
|
||||||
|
}
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@ export class AlbumPage extends Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div></div>
|
<div></div>
|
||||||
); // TODO: Loading
|
); // TODO: Loading + error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component } from "react";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import * as actionCreators from "../actions";
|
import * as actionCreators from "../actions";
|
||||||
import { i18nRecord } from "../models/i18n";
|
import { buildPaginationObject, messagesMap, handleErrorI18nObject } from "../utils";
|
||||||
import { buildPaginationObject, messagesMap } from "../utils";
|
|
||||||
|
|
||||||
import Albums from "../components/Albums";
|
import Albums from "../components/Albums";
|
||||||
|
|
||||||
import APIMessages from "../locales/messagesDescriptors/api";
|
import APIMessages from "../locales/messagesDescriptors/api";
|
||||||
|
|
||||||
const albumsMessages = defineMessages(messagesMap(APIMessages));
|
const albumsMessages = defineMessages(messagesMap(Array.concat([], APIMessages)));
|
||||||
|
|
||||||
class AlbumsPageIntl extends Component {
|
class AlbumsPageIntl extends Component {
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
@ -31,27 +30,16 @@ class AlbumsPageIntl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {formatMessage} = this.props.intl;
|
|
||||||
if (this.props.error) {
|
|
||||||
let errorMessage = this.props.error;
|
|
||||||
if (this.props.error instanceof i18nRecord) {
|
|
||||||
errorMessage = formatMessage(albumsMessages[this.props.error.id], this.props.error.values);
|
|
||||||
}
|
|
||||||
alert(errorMessage);
|
|
||||||
this.context.router.replace("/");
|
|
||||||
return (<div></div>);
|
|
||||||
}
|
|
||||||
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
||||||
|
|
||||||
|
const {formatMessage} = this.props.intl;
|
||||||
|
const error = handleErrorI18nObject(this.props.error, formatMessage, albumsMessages);
|
||||||
return (
|
return (
|
||||||
<Albums isFetching={this.props.isFetching} albums={this.props.albumsList} pagination={pagination} />
|
<Albums isFetching={this.props.isFetching} error={error} albums={this.props.albumsList} pagination={pagination} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlbumsPageIntl.contextTypes = {
|
|
||||||
router: PropTypes.object.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
AlbumsPageIntl.propTypes = {
|
AlbumsPageIntl.propTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import * as actionCreators from "../actions";
|
import * as actionCreators from "../actions";
|
||||||
|
import { messagesMap, handleErrorI18nObject } from "../utils";
|
||||||
|
|
||||||
import Artist from "../components/Artist";
|
import Artist from "../components/Artist";
|
||||||
|
|
||||||
export class ArtistPage extends Component {
|
import APIMessages from "../locales/messagesDescriptors/api";
|
||||||
|
|
||||||
|
const artistMessages = defineMessages(messagesMap(Array.concat([], APIMessages)));
|
||||||
|
|
||||||
|
class ArtistPageIntl extends Component {
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
// Load the data
|
// Load the data
|
||||||
this.props.actions.loadArtists({
|
this.props.actions.loadArtists({
|
||||||
@ -18,8 +24,10 @@ export class ArtistPage extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const {formatMessage} = this.props.intl;
|
||||||
|
const error = handleErrorI18nObject(this.props.error, formatMessage, artistMessages);
|
||||||
return (
|
return (
|
||||||
<Artist isFetching={this.props.isFetching} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
|
<Artist isFetching={this.props.isFetching} error={error} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,14 +63,19 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
isFetching: state.api.isFetching,
|
isFetching: state.api.isFetching,
|
||||||
|
error: state.api.error,
|
||||||
artist: artist,
|
artist: artist,
|
||||||
albums: albums,
|
albums: albums,
|
||||||
songs: songs
|
songs: songs
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ArtistPageIntl.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
actions: bindActionCreators(actionCreators, dispatch)
|
actions: bindActionCreators(actionCreators, dispatch)
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(ArtistPage);
|
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(ArtistPageIntl));
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component } from "react";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import * as actionCreators from "../actions";
|
import * as actionCreators from "../actions";
|
||||||
import { i18nRecord } from "../models/i18n";
|
import { buildPaginationObject, messagesMap, handleErrorI18nObject } from "../utils";
|
||||||
import { buildPaginationObject, messagesMap } from "../utils";
|
|
||||||
|
|
||||||
import Artists from "../components/Artists";
|
import Artists from "../components/Artists";
|
||||||
|
|
||||||
import APIMessages from "../locales/messagesDescriptors/api";
|
import APIMessages from "../locales/messagesDescriptors/api";
|
||||||
|
|
||||||
const artistsMessages = defineMessages(messagesMap(APIMessages));
|
const artistsMessages = defineMessages(messagesMap(Array.concat([], APIMessages)));
|
||||||
|
|
||||||
class ArtistsPageIntl extends Component {
|
class ArtistsPageIntl extends Component {
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
@ -31,27 +30,16 @@ class ArtistsPageIntl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {formatMessage} = this.props.intl;
|
|
||||||
if (this.props.error) {
|
|
||||||
let errorMessage = this.props.error;
|
|
||||||
if (this.props.error instanceof i18nRecord) {
|
|
||||||
errorMessage = formatMessage(artistsMessages[this.props.error.id], this.props.error.values);
|
|
||||||
}
|
|
||||||
alert(errorMessage);
|
|
||||||
this.context.router.replace("/");
|
|
||||||
return (<div></div>);
|
|
||||||
}
|
|
||||||
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
||||||
|
|
||||||
|
const {formatMessage} = this.props.intl;
|
||||||
|
const error = handleErrorI18nObject(this.props.error, formatMessage, artistsMessages);
|
||||||
return (
|
return (
|
||||||
<Artists isFetching={this.props.isFetching} artists={this.props.artistsList} pagination={pagination} />
|
<Artists isFetching={this.props.isFetching} error={error} artists={this.props.artistsList} pagination={pagination} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtistsPageIntl.contextTypes = {
|
|
||||||
router: PropTypes.object.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
ArtistsPageIntl.propTypes = {
|
ArtistsPageIntl.propTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component } from "react";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import * as actionCreators from "../actions";
|
import * as actionCreators from "../actions";
|
||||||
import { i18nRecord } from "../models/i18n";
|
import { buildPaginationObject, messagesMap, handleErrorI18nObject } from "../utils";
|
||||||
import { buildPaginationObject, messagesMap } from "../utils";
|
|
||||||
|
|
||||||
import Songs from "../components/Songs";
|
import Songs from "../components/Songs";
|
||||||
|
|
||||||
import APIMessages from "../locales/messagesDescriptors/api";
|
import APIMessages from "../locales/messagesDescriptors/api";
|
||||||
|
|
||||||
const songsMessages = defineMessages(messagesMap(APIMessages));
|
const songsMessages = defineMessages(messagesMap(Array.concat([], APIMessages)));
|
||||||
|
|
||||||
class SongsPageIntl extends Component {
|
class SongsPageIntl extends Component {
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
@ -31,27 +30,16 @@ class SongsPageIntl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {formatMessage} = this.props.intl;
|
|
||||||
if (this.props.error) {
|
|
||||||
let errorMessage = this.props.error;
|
|
||||||
if (this.props.error instanceof i18nRecord) {
|
|
||||||
errorMessage = formatMessage(songsMessages[this.props.error.id], this.props.error.values);
|
|
||||||
}
|
|
||||||
alert(errorMessage);
|
|
||||||
this.context.router.replace("/");
|
|
||||||
return (<div></div>);
|
|
||||||
}
|
|
||||||
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
const pagination = buildPaginationObject(this.props.location, this.props.currentPage, this.props.nPages, this.props.actions.goToPageAction);
|
||||||
|
|
||||||
|
const {formatMessage} = this.props.intl;
|
||||||
|
const error = handleErrorI18nObject(this.props.error, formatMessage, songsMessages);
|
||||||
return (
|
return (
|
||||||
<Songs isFetching={this.props.isFetching} songs={this.props.songsList} pagination={pagination} />
|
<Songs isFetching={this.props.isFetching} error={error} songs={this.props.songsList} pagination={pagination} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SongsPageIntl.contextTypes = {
|
|
||||||
router: PropTypes.object.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
SongsPageIntl.propTypes = {
|
SongsPageIntl.propTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
|||||||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(625);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},625:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
|
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(626);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},626:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
|
||||||
//# sourceMappingURL=fix.ie9.js.map
|
//# sourceMappingURL=fix.ie9.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user