Displayed preloader when a server is being loaded

This commit is contained in:
Alejandro Celaya
2020-03-05 08:41:55 +01:00
parent 3b0e282a52
commit 853032ac7f
7 changed files with 51 additions and 41 deletions

View File

@@ -3,9 +3,10 @@ import { Route, Switch } from 'react-router-dom';
import { Swipeable } from 'react-swipeable'; import { Swipeable } from 'react-swipeable';
import { faBars as burgerIcon } from '@fortawesome/free-solid-svg-icons'; import { faBars as burgerIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classnames from 'classnames'; import classNames from 'classnames';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import { serverType } from '../servers/prop-types'; import { serverType } from '../servers/prop-types';
import MutedMessage from '../utils/MutedMessage';
import NotFound from './NotFound'; import NotFound from './NotFound';
import './MenuLayout.scss'; import './MenuLayout.scss';
@@ -38,8 +39,13 @@ const MenuLayout = (TagsList, ShortUrls, AsideMenu, CreateShortUrl, ShortUrlVisi
render() { render() {
const { selectedServer, match } = this.props; const { selectedServer, match } = this.props;
if (!selectedServer) {
return <MutedMessage loading />;
}
const { params: { serverId } } = match; const { params: { serverId } } = match;
const burgerClasses = classnames('menu-layout__burger-icon', { const burgerClasses = classNames('menu-layout__burger-icon', {
'menu-layout__burger-icon--active': this.state.showSideBar, 'menu-layout__burger-icon--active': this.state.showSideBar,
}); });
const swipeMenuIfNoModalExists = (showSideBar) => () => { const swipeMenuIfNoModalExists = (showSideBar) => () => {

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { splitEvery } from 'ramda'; import { splitEvery } from 'ramda';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import MuttedMessage from '../utils/MuttedMessage'; import MutedMessage from '../utils/MutedMessage';
import SearchField from '../utils/SearchField'; import SearchField from '../utils/SearchField';
const { ceil } = Math; const { ceil } = Math;
@@ -29,7 +29,7 @@ const TagsList = (TagCard) => class TagsList extends React.Component {
const { tagsList, match } = this.props; const { tagsList, match } = this.props;
if (tagsList.loading) { if (tagsList.loading) {
return <MuttedMessage marginSize={0}>Loading...</MuttedMessage>; return <MutedMessage noMargin loading />;
} }
if (tagsList.error) { if (tagsList.error) {
@@ -43,7 +43,7 @@ const TagsList = (TagCard) => class TagsList extends React.Component {
const tagsCount = tagsList.filteredTags.length; const tagsCount = tagsList.filteredTags.length;
if (tagsCount < 1) { if (tagsCount < 1) {
return <MuttedMessage>No tags found</MuttedMessage>; return <MutedMessage>No tags found</MutedMessage>;
} }
const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags); const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags);

34
src/utils/MutedMessage.js Normal file
View File

@@ -0,0 +1,34 @@
import React from 'react';
import { Card } from 'reactstrap';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const propTypes = {
noMargin: PropTypes.bool,
loading: PropTypes.bool,
children: PropTypes.node,
};
const MutedMessage = ({ children, loading = false, noMargin = false }) => {
const cardClasses = classNames('bg-light', {
'mt-4': !noMargin,
});
return (
<div className="col-md-10 offset-md-1">
<Card className={cardClasses} body>
<h3 className="text-center text-muted mb-0">
{loading && <FontAwesomeIcon icon={preloader} spin />}
{loading && !children && <span className="ml-2">Loading...</span>}
{children}
</h3>
</Card>
</div>
);
};
MutedMessage.propTypes = propTypes;
export default MutedMessage;

View File

@@ -1,28 +0,0 @@
import React from 'react';
import { Card } from 'reactstrap';
import classnames from 'classnames';
import PropTypes from 'prop-types';
const DEFAULT_MARGIN_SIZE = 4;
const propTypes = {
marginSize: PropTypes.number,
children: PropTypes.node,
};
export default function MutedMessage({ children, marginSize = DEFAULT_MARGIN_SIZE }) {
const cardClasses = classnames('bg-light', {
[`mt-${marginSize}`]: marginSize > 0,
});
return (
<div className="col-md-10 offset-md-1">
<Card className={cardClasses} body>
<h3 className="text-center text-muted mb-0">
{children}
</h3>
</Card>
</div>
);
}
MutedMessage.propTypes = propTypes;

View File

@@ -1,12 +1,10 @@
import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { isEmpty, mapObjIndexed, values } from 'ramda'; import { isEmpty, mapObjIndexed, values } from 'ramda';
import React from 'react'; import React from 'react';
import { Card } from 'reactstrap'; import { Card } from 'reactstrap';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import qs from 'qs'; import qs from 'qs';
import DateRangeRow from '../utils/DateRangeRow'; import DateRangeRow from '../utils/DateRangeRow';
import MutedMessage from '../utils/MuttedMessage'; import MutedMessage from '../utils/MutedMessage';
import { formatDate } from '../utils/utils'; import { formatDate } from '../utils/utils';
import SortableBarGraph from './SortableBarGraph'; import SortableBarGraph from './SortableBarGraph';
import { shortUrlVisitsType } from './reducers/shortUrlVisits'; import { shortUrlVisitsType } from './reducers/shortUrlVisits';
@@ -66,7 +64,7 @@ const ShortUrlVisits = (
if (loading) { if (loading) {
const message = loadingLarge ? 'This is going to take a while... :S' : 'Loading...'; const message = loadingLarge ? 'This is going to take a while... :S' : 'Loading...';
return <MutedMessage><FontAwesomeIcon icon={preloader} spin /> {message}</MutedMessage>; return <MutedMessage loading>{message}</MutedMessage>;
} }
if (error) { if (error) {

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { identity } from 'ramda'; import { identity } from 'ramda';
import createTagsList from '../../src/tags/TagsList'; import createTagsList from '../../src/tags/TagsList';
import MuttedMessage from '../../src/utils/MuttedMessage'; import MutedMessage from '../../src/utils/MutedMessage';
import SearchField from '../../src/utils/SearchField'; import SearchField from '../../src/utils/SearchField';
import { rangeOf } from '../../src/utils/utils'; import { rangeOf } from '../../src/utils/utils';
@@ -28,7 +28,7 @@ describe('<TagsList />', () => {
it('shows a loading message when tags are being loaded', () => { it('shows a loading message when tags are being loaded', () => {
const wrapper = createWrapper({ loading: true }); const wrapper = createWrapper({ loading: true });
const loadingMsg = wrapper.find(MuttedMessage); const loadingMsg = wrapper.find(MutedMessage);
expect(loadingMsg).toHaveLength(1); expect(loadingMsg).toHaveLength(1);
expect(loadingMsg.html()).toContain('Loading...'); expect(loadingMsg.html()).toContain('Loading...');
@@ -44,7 +44,7 @@ describe('<TagsList />', () => {
it('shows a message when the list of tags is empty', () => { it('shows a message when the list of tags is empty', () => {
const wrapper = createWrapper({ filteredTags: [] }); const wrapper = createWrapper({ filteredTags: [] });
const msg = wrapper.find(MuttedMessage); const msg = wrapper.find(MutedMessage);
expect(msg).toHaveLength(1); expect(msg).toHaveLength(1);
expect(msg.html()).toContain('No tags found'); expect(msg.html()).toContain('No tags found');

View File

@@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
import { identity } from 'ramda'; import { identity } from 'ramda';
import { Card } from 'reactstrap'; import { Card } from 'reactstrap';
import createShortUrlVisits from '../../src/visits/ShortUrlVisits'; import createShortUrlVisits from '../../src/visits/ShortUrlVisits';
import MutedMessage from '../../src/utils/MuttedMessage'; import MutedMessage from '../../src/utils/MutedMessage';
import GraphCard from '../../src/visits/GraphCard'; import GraphCard from '../../src/visits/GraphCard';
import SortableBarGraph from '../../src/visits/SortableBarGraph'; import SortableBarGraph from '../../src/visits/SortableBarGraph';
import DateRangeRow from '../../src/utils/DateRangeRow'; import DateRangeRow from '../../src/utils/DateRangeRow';