From 8b17ff88ed79ed20f5f1da7df6afcad6ac2279cf Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 1 Sep 2018 11:26:35 +0200 Subject: [PATCH] Split short URL visits reducer into two individual reducers --- src/reducers/index.js | 6 ++- src/visits/ShortUrlVisits.js | 26 ++++++++---- src/visits/VisitsHeader.js | 8 ++-- src/visits/reducers/shortUrlDetail.js | 60 +++++++++++++++++++++++++++ src/visits/reducers/shortUrlVisits.js | 20 ++++----- 5 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 src/visits/reducers/shortUrlDetail.js diff --git a/src/reducers/index.js b/src/reducers/index.js index aa087212..54929232 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -4,8 +4,9 @@ import selectedServerReducer from '../servers/reducers/selectedServer'; import shortUrlsListReducer from '../short-urls/reducers/shortUrlsList'; import shortUrlsListParamsReducer from '../short-urls/reducers/shortUrlsListParams'; import shortUrlCreationResultReducer from '../short-urls/reducers/shortUrlCreationResult'; -import shortUrlVisitsReducer from '../visits/reducers/shortUrlVisits'; import shortUrlTagsReducer from '../short-urls/reducers/shortUrlTags'; +import shortUrlVisitsReducer from '../visits/reducers/shortUrlVisits'; +import shortUrlDetailReducer from '../visits/reducers/shortUrlDetail'; import tagsListReducer from '../tags/reducers/tagsList'; import tagDeleteReducer from '../tags/reducers/tagDelete'; import tagEditReducer from '../tags/reducers/tagEdit'; @@ -16,8 +17,9 @@ export default combineReducers({ shortUrlsList: shortUrlsListReducer, shortUrlsListParams: shortUrlsListParamsReducer, shortUrlCreationResult: shortUrlCreationResultReducer, - shortUrlVisits: shortUrlVisitsReducer, shortUrlTags: shortUrlTagsReducer, + shortUrlVisits: shortUrlVisitsReducer, + shortUrlDetail: shortUrlDetailReducer, tagsList: tagsListReducer, tagDelete: tagDeleteReducer, tagEdit: tagEditReducer, diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 7a5aaef7..42ec802f 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -15,9 +15,10 @@ import { processOsStats, processReferrersStats, } from './services/VisitsParser'; -import './ShortUrlVisits.scss'; import { VisitsHeader } from './VisitsHeader'; import { GraphCard } from './GraphCard'; +import { getShortUrlDetail, shortUrlDetailType } from './reducers/shortUrlDetail'; +import './ShortUrlVisits.scss'; export class ShortUrlsVisitsComponent extends React.Component { static propTypes = { @@ -26,9 +27,11 @@ export class ShortUrlsVisitsComponent extends React.Component { processCountriesStats: PropTypes.func, processReferrersStats: PropTypes.func, match: PropTypes.object, - getShortUrlVisits: PropTypes.func, selectedServer: serverType, + getShortUrlVisits: PropTypes.func, shortUrlVisits: shortUrlVisitsType, + getShortUrlDetail: PropTypes.func, + shortUrlDetail: shortUrlDetailType, }; static defaultProps = { processOsStats, @@ -48,7 +51,10 @@ export class ShortUrlsVisitsComponent extends React.Component { }; componentDidMount() { + const { match: { params }, getShortUrlDetail } = this.props; + this.loadVisits(); + getShortUrlDetail(params.shortCode); } render() { @@ -60,12 +66,14 @@ export class ShortUrlsVisitsComponent extends React.Component { processCountriesStats, processReferrersStats, shortUrlVisits, + shortUrlDetail, } = this.props; - const { visits, loading, error } = shortUrlVisits; const serverUrl = selectedServer ? selectedServer.url : ''; const shortLink = `${serverUrl}/${params.shortCode}`; - const renderContent = () => { + const renderVisitsContent = () => { + const { visits, loading, error } = shortUrlVisits; + if (loading) { return Loading...; } @@ -79,7 +87,7 @@ export class ShortUrlsVisitsComponent extends React.Component { } if (isEmpty(visits)) { - return There have been no visits matching current filter :(; + return There are no visits matching current filter :(; } return ( @@ -102,7 +110,7 @@ export class ShortUrlsVisitsComponent extends React.Component { return (
- +
@@ -127,7 +135,7 @@ export class ShortUrlsVisitsComponent extends React.Component {
- {renderContent()} + {renderVisitsContent()}
); @@ -135,8 +143,8 @@ export class ShortUrlsVisitsComponent extends React.Component { } const ShortUrlsVisits = connect( - pick([ 'selectedServer', 'shortUrlVisits' ]), - { getShortUrlVisits } + pick([ 'selectedServer', 'shortUrlVisits', 'shortUrlDetail' ]), + { getShortUrlVisits, getShortUrlDetail } )(ShortUrlsVisitsComponent); export default ShortUrlsVisits; diff --git a/src/visits/VisitsHeader.js b/src/visits/VisitsHeader.js index 30dbd412..cb932409 100644 --- a/src/visits/VisitsHeader.js +++ b/src/visits/VisitsHeader.js @@ -3,16 +3,16 @@ import Moment from 'react-moment'; import React from 'react'; import PropTypes from 'prop-types'; import ExternalLink from '../utils/ExternalLink'; -import { shortUrlVisitsType } from './reducers/shortUrlVisits'; import './VisitsHeader.scss'; +import { shortUrlDetailType } from './reducers/shortUrlDetail'; const propTypes = { - shortUrlVisits: shortUrlVisitsType, + shortUrlDetail: shortUrlDetailType, shortLink: PropTypes.string, }; -export function VisitsHeader({ shortUrlVisits, shortLink }) { - const { shortUrl, loading } = shortUrlVisits; +export function VisitsHeader({ shortUrlDetail, shortLink }) { + const { shortUrl, loading } = shortUrlDetail; const renderDate = () => ( {shortUrl.dateCreated} diff --git a/src/visits/reducers/shortUrlDetail.js b/src/visits/reducers/shortUrlDetail.js new file mode 100644 index 00000000..e1a44261 --- /dev/null +++ b/src/visits/reducers/shortUrlDetail.js @@ -0,0 +1,60 @@ +import { curry } from 'ramda'; +import PropTypes from 'prop-types'; +import shlinkApiClient from '../../api/ShlinkApiClient'; +import { shortUrlType } from '../../short-urls/reducers/shortUrlsList'; + +/* eslint-disable padding-line-between-statements, newline-after-var */ +const GET_SHORT_URL_DETAIL_START = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_START'; +const GET_SHORT_URL_DETAIL_ERROR = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_ERROR'; +const GET_SHORT_URL_DETAIL = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL'; +/* eslint-enable padding-line-between-statements, newline-after-var */ + +export const shortUrlDetailType = PropTypes.shape({ + shortUrl: shortUrlType, + loading: PropTypes.bool, + error: PropTypes.bool, +}); + +const initialState = { + shortUrl: {}, + loading: false, + error: false, +}; + +export default function reducer(state = initialState, action) { + switch (action.type) { + case GET_SHORT_URL_DETAIL_START: + return { + ...state, + loading: true, + }; + case GET_SHORT_URL_DETAIL_ERROR: + return { + ...state, + loading: false, + error: true, + }; + case GET_SHORT_URL_DETAIL: + return { + shortUrl: action.shortUrl, + loading: false, + error: false, + }; + default: + return state; + } +} + +export const _getShortUrlDetail = (shlinkApiClient, shortCode) => async (dispatch) => { + dispatch({ type: GET_SHORT_URL_DETAIL_START }); + + try { + const shortUrl = await shlinkApiClient.getShortUrl(shortCode); + + dispatch({ shortUrl, type: GET_SHORT_URL_DETAIL }); + } catch (e) { + dispatch({ type: GET_SHORT_URL_DETAIL_ERROR }); + } +}; + +export const getShortUrlDetail = curry(_getShortUrlDetail)(shlinkApiClient); diff --git a/src/visits/reducers/shortUrlVisits.js b/src/visits/reducers/shortUrlVisits.js index b3daf133..72d89a3e 100644 --- a/src/visits/reducers/shortUrlVisits.js +++ b/src/visits/reducers/shortUrlVisits.js @@ -1,7 +1,6 @@ import { curry } from 'ramda'; import PropTypes from 'prop-types'; import shlinkApiClient from '../../api/ShlinkApiClient'; -import { shortUrlType } from '../../short-urls/reducers/shortUrlsList'; /* eslint-disable padding-line-between-statements, newline-after-var */ const GET_SHORT_URL_VISITS_START = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS_START'; @@ -10,7 +9,6 @@ const GET_SHORT_URL_VISITS = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS'; /* eslint-enable padding-line-between-statements, newline-after-var */ export const shortUrlVisitsType = PropTypes.shape({ - shortUrl: shortUrlType, visits: PropTypes.array, loading: PropTypes.bool, error: PropTypes.bool, @@ -23,7 +21,7 @@ const initialState = { error: false, }; -export default function dispatch(state = initialState, action) { +export default function reducer(state = initialState, action) { switch (action.type) { case GET_SHORT_URL_VISITS_START: return { @@ -38,7 +36,6 @@ export default function dispatch(state = initialState, action) { }; case GET_SHORT_URL_VISITS: return { - shortUrl: action.shortUrl, visits: action.visits, loading: false, error: false, @@ -48,15 +45,16 @@ export default function dispatch(state = initialState, action) { } } -export const _getShortUrlVisits = (shlinkApiClient, shortCode, dates) => (dispatch) => { +export const _getShortUrlVisits = (shlinkApiClient, shortCode, dates) => async (dispatch) => { dispatch({ type: GET_SHORT_URL_VISITS_START }); - Promise.all([ - shlinkApiClient.getShortUrlVisits(shortCode, dates), - shlinkApiClient.getShortUrl(shortCode), - ]) - .then(([ visits, shortUrl ]) => dispatch({ visits, shortUrl, type: GET_SHORT_URL_VISITS })) - .catch(() => dispatch({ type: GET_SHORT_URL_VISITS_ERROR })); + try { + const visits = await shlinkApiClient.getShortUrlVisits(shortCode, dates); + + dispatch({ visits, type: GET_SHORT_URL_VISITS }); + } catch (e) { + dispatch({ type: GET_SHORT_URL_VISITS_ERROR }); + } }; export const getShortUrlVisits = curry(_getShortUrlVisits)(shlinkApiClient);