Added sorting to referrers bar graph

This commit is contained in:
Alejandro Celaya 2018-10-28 23:04:52 +01:00
parent 368de2b4c7
commit 05936c52b3
4 changed files with 30 additions and 19 deletions

View file

@ -54,7 +54,7 @@ const SortingDropdown = ({ items, orderField, orderDir, onChange, isButton, righ
</DropdownItem> </DropdownItem>
))} ))}
<DropdownItem divider /> <DropdownItem divider />
<DropdownItem onClick={() => onChange()}> <DropdownItem disabled={!orderField} onClick={() => onChange()}>
<i>Clear selection</i> <i>Clear selection</i>
</DropdownItem> </DropdownItem>
</DropdownMenu> </DropdownMenu>

View file

@ -7,7 +7,7 @@ import { Card } from 'reactstrap';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import DateInput from '../common/DateInput'; import DateInput from '../common/DateInput';
import MutedMessage from '../utils/MuttedMessage'; import MutedMessage from '../utils/MuttedMessage';
import CountriesGraph from './CountriesGraph'; import SortableBarGraph from './SortableBarGraph';
import { getShortUrlVisits, shortUrlVisitsType } from './reducers/shortUrlVisits'; import { getShortUrlVisits, shortUrlVisitsType } from './reducers/shortUrlVisits';
import { import {
processBrowserStats, processBrowserStats,
@ -96,10 +96,24 @@ export class ShortUrlsVisitsComponent extends React.Component {
<GraphCard title="Browsers" stats={processBrowserStats(visits)} /> <GraphCard title="Browsers" stats={processBrowserStats(visits)} />
</div> </div>
<div className="col-md-6"> <div className="col-md-6">
<CountriesGraph stats={processCountriesStats(visits)} /> <SortableBarGraph
stats={processCountriesStats(visits)}
title="Countries"
sortingItems={{
name: 'Country name',
amount: 'Visits amount',
}}
/>
</div> </div>
<div className="col-md-6"> <div className="col-md-6">
<GraphCard title="Referrers" stats={processReferrersStats(visits)} isBarChart /> <SortableBarGraph
stats={processReferrersStats(visits)}
title="Referrers"
sortingItems={{
name: 'Referrer name',
amount: 'Visits amount',
}}
/>
</div> </div>
</div> </div>
); );

View file

@ -4,9 +4,11 @@ import { fromPairs, head, keys, prop, reverse, sortBy, toPairs } from 'ramda';
import SortingDropdown from '../utils/SortingDropdown'; import SortingDropdown from '../utils/SortingDropdown';
import GraphCard from './GraphCard'; import GraphCard from './GraphCard';
export default class CountriesGraph extends React.Component { export default class SortableBarGraph extends React.Component {
static propTypes = { static propTypes = {
stats: PropTypes.any, stats: PropTypes.object.isRequired,
title: PropTypes.string.isRequired,
sortingItems: PropTypes.object.isRequired,
}; };
state = { state = {
@ -15,31 +17,27 @@ export default class CountriesGraph extends React.Component {
}; };
render() { render() {
const items = { const { stats, sortingItems, title } = this.props;
name: 'Country name',
amount: 'Visits amount',
};
const { stats } = this.props;
const sortStats = () => { const sortStats = () => {
if (!this.state.orderField) { if (!this.state.orderField) {
return stats; return stats;
} }
const sortedPairs = sortBy(prop(this.state.orderField === head(keys(items)) ? 0 : 1), toPairs(stats)); const sortedPairs = sortBy(prop(this.state.orderField === head(keys(sortingItems)) ? 0 : 1), toPairs(stats));
return fromPairs(this.state.orderDir === 'ASC' ? sortedPairs : reverse(sortedPairs)); return fromPairs(this.state.orderDir === 'ASC' ? sortedPairs : reverse(sortedPairs));
}; };
return ( return (
<GraphCard stats={sortStats()} isBarChart> <GraphCard stats={sortStats()} isBarChart>
Countries {title}
<div className="float-right"> <div className="float-right">
<SortingDropdown <SortingDropdown
isButton={false} isButton={false}
right right
orderField={this.state.orderField} orderField={this.state.orderField}
orderDir={this.state.orderDir} orderDir={this.state.orderDir}
items={items} items={sortingItems}
onChange={(orderField, orderDir) => this.setState({ orderField, orderDir })} onChange={(orderField, orderDir) => this.setState({ orderField, orderDir })}
/> />
</div> </div>

View file

@ -7,7 +7,7 @@ import { ShortUrlsVisitsComponent as ShortUrlsVisits } from '../../src/visits/Sh
import MutedMessage from '../../src/utils/MuttedMessage'; import MutedMessage from '../../src/utils/MuttedMessage';
import GraphCard from '../../src/visits/GraphCard'; import GraphCard from '../../src/visits/GraphCard';
import DateInput from '../../src/common/DateInput'; import DateInput from '../../src/common/DateInput';
import CountriesGraph from '../../src/visits/CountriesGraph'; import SortableBarGraph from '../../src/visits/SortableBarGraph';
describe('<ShortUrlVisits />', () => { describe('<ShortUrlVisits />', () => {
let wrapper; let wrapper;
@ -70,11 +70,10 @@ describe('<ShortUrlVisits />', () => {
it('renders all graphics when visits are properly loaded', () => { it('renders all graphics when visits are properly loaded', () => {
const wrapper = createComponent({ loading: false, error: false, visits: [{}, {}, {}] }); const wrapper = createComponent({ loading: false, error: false, visits: [{}, {}, {}] });
const graphs = wrapper.find(GraphCard); const graphs = wrapper.find(GraphCard);
const countriesGraphs = wrapper.find(CountriesGraph); const sortableBarGraphs = wrapper.find(SortableBarGraph);
const expectedGraphsCount = 3; const expectedGraphsCount = 4;
expect(graphs).toHaveLength(expectedGraphsCount); expect(graphs.length + sortableBarGraphs.length).toEqual(expectedGraphsCount);
expect(countriesGraphs).toHaveLength(1);
}); });
it('reloads visits when selected dates change', () => { it('reloads visits when selected dates change', () => {