diff --git a/CHANGELOG.md b/CHANGELOG.md index 69b25f6f..6cc73f47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), #### Changed -* *Nothing* +* [#218](https://github.com/shlinkio/shlink-web-client/issues/218) Added back button to sections not displayed in left menu #### Deprecated diff --git a/src/servers/EditServer.js b/src/servers/EditServer.js index 6a6b89b6..33560631 100644 --- a/src/servers/EditServer.js +++ b/src/servers/EditServer.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { Button } from 'reactstrap'; import NoMenuLayout from '../common/NoMenuLayout'; import { ServerForm } from './helpers/ServerForm'; import { withSelectedServer } from './helpers/withSelectedServer'; @@ -10,11 +11,12 @@ const propTypes = { selectedServer: serverType, history: PropTypes.shape({ push: PropTypes.func, + goBack: PropTypes.func, }), }; export const EditServer = (ServerError) => { - const EditServerComp = ({ editServer, selectedServer, history: { push } }) => { + const EditServerComp = ({ editServer, selectedServer, history: { push, goBack } }) => { const handleSubmit = (serverData) => { editServer(selectedServer.id, serverData); push(`/server/${selectedServer.id}/list-short-urls/1`); @@ -23,7 +25,8 @@ export const EditServer = (ServerError) => { return ( - + + ); diff --git a/src/tags/TagsList.js b/src/tags/TagsList.js index 914a1ba8..2c482b68 100644 --- a/src/tags/TagsList.js +++ b/src/tags/TagsList.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { splitEvery } from 'ramda'; import PropTypes from 'prop-types'; import Message from '../utils/Message'; @@ -7,78 +7,74 @@ import SearchField from '../utils/SearchField'; const { ceil } = Math; const TAGS_GROUPS_AMOUNT = 4; -const TagsList = (TagCard) => class TagsList extends React.Component { - static propTypes = { - filterTags: PropTypes.func, - forceListTags: PropTypes.func, - tagsList: PropTypes.shape({ - loading: PropTypes.bool, - error: PropTypes.bool, - filteredTags: PropTypes.arrayOf(PropTypes.string), - }), - match: PropTypes.object, +const propTypes = { + filterTags: PropTypes.func, + forceListTags: PropTypes.func, + tagsList: PropTypes.shape({ + loading: PropTypes.bool, + error: PropTypes.bool, + filteredTags: PropTypes.arrayOf(PropTypes.string), + }), + match: PropTypes.object, +}; + +const TagsList = (TagCard) => { + const TagListComp = ({ filterTags, forceListTags, tagsList, match }) => { + useEffect(() => { + forceListTags(); + }, []); + + const renderContent = () => { + if (tagsList.loading) { + return ; + } + + if (tagsList.error) { + return ( +
+
Error loading tags :(
+
+ ); + } + + const tagsCount = tagsList.filteredTags.length; + + if (tagsCount < 1) { + return No tags found; + } + + const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags); + + return ( + + {tagsGroups.map((group, index) => ( +
+ {group.map((tag) => ( + + ))} +
+ ))} +
+ ); + }; + + return ( + + {!tagsList.loading && } +
+ {renderContent()} +
+
+ ); }; - componentDidMount() { - const { forceListTags } = this.props; + TagListComp.propTypes = propTypes; - forceListTags(); - } - - renderContent() { - const { tagsList, match } = this.props; - - if (tagsList.loading) { - return ; - } - - if (tagsList.error) { - return ( -
-
Error loading tags :(
-
- ); - } - - const tagsCount = tagsList.filteredTags.length; - - if (tagsCount < 1) { - return No tags found; - } - - const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags); - - return ( - - {tagsGroups.map((group, index) => ( -
- {group.map((tag) => ( - - ))} -
- ))} -
- ); - } - - render() { - const { filterTags } = this.props; - - return ( - - {!this.props.tagsList.loading && - - } -
- {this.renderContent()} -
-
- ); - } + return TagListComp; }; export default TagsList; diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 410d390b..6882e478 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -21,6 +21,9 @@ import { shortUrlDetailType } from './reducers/shortUrlDetail'; import VisitsTable from './VisitsTable'; const propTypes = { + history: PropTypes.shape({ + goBack: PropTypes.func, + }), match: PropTypes.shape({ params: PropTypes.object, }), @@ -53,6 +56,7 @@ let selectedBar; const ShortUrlVisits = ({ processStatsFromVisits, normalizeVisits }, OpenMapModalBtn) => { const ShortUrlVisitsComp = ({ + history, match, location, shortUrlVisits, @@ -204,7 +208,7 @@ const ShortUrlVisits = ({ processStatsFromVisits, normalizeVisits }, OpenMapModa return ( - +
diff --git a/src/visits/VisitsHeader.js b/src/visits/VisitsHeader.js index e13398dc..84752c1c 100644 --- a/src/visits/VisitsHeader.js +++ b/src/visits/VisitsHeader.js @@ -1,7 +1,10 @@ -import { Card, UncontrolledTooltip } from 'reactstrap'; +import { Button, Card, UncontrolledTooltip } from 'reactstrap'; import Moment from 'react-moment'; import React from 'react'; +import PropTypes from 'prop-types'; import { ExternalLink } from 'react-external-link'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faArrowLeft } from '@fortawesome/free-solid-svg-icons'; import ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount'; import { shortUrlDetailType } from './reducers/shortUrlDetail'; import { shortUrlVisitsType } from './reducers/shortUrlVisits'; @@ -10,9 +13,10 @@ import './VisitsHeader.scss'; const propTypes = { shortUrlDetail: shortUrlDetailType.isRequired, shortUrlVisits: shortUrlVisitsType.isRequired, + goBack: PropTypes.func.isRequired, }; -export default function VisitsHeader({ shortUrlDetail, shortUrlVisits }) { +export default function VisitsHeader({ shortUrlDetail, shortUrlVisits, goBack }) { const { shortUrl, loading } = shortUrlDetail; const { visits } = shortUrlVisits; const shortLink = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; @@ -26,17 +30,28 @@ export default function VisitsHeader({ shortUrlDetail, shortUrlVisits }) { ); + const visitsStatsTitle = ( + + Visit stats for + + ); return (
-

- +

+ + + {visitsStatsTitle} + + Visits:{' '} - Visit stats for

+

{visitsStatsTitle}


Created: {renderDate()}
diff --git a/test/visits/ShortUrlVisits.test.js b/test/visits/ShortUrlVisits.test.js index ad8743a1..0f221308 100644 --- a/test/visits/ShortUrlVisits.test.js +++ b/test/visits/ShortUrlVisits.test.js @@ -18,6 +18,9 @@ describe('', () => { params: { shortCode: 'abc123' }, }; const location = { search: '' }; + const history = { + goBack: jest.fn(), + }; const createComponent = (shortUrlVisits) => { const ShortUrlVisits = createShortUrlVisits({ processStatsFromVisits, normalizeVisits: identity }, () => ''); @@ -28,6 +31,7 @@ describe('', () => { getShortUrlVisits={getShortUrlVisitsMock} match={match} location={location} + history={history} shortUrlVisits={shortUrlVisits} shortUrlDetail={{}} cancelGetShortUrlVisits={identity} diff --git a/test/visits/VisitsHeader.test.js b/test/visits/VisitsHeader.test.js index 3d4b48dd..8c151c4b 100644 --- a/test/visits/VisitsHeader.test.js +++ b/test/visits/VisitsHeader.test.js @@ -17,9 +17,10 @@ describe('', () => { const shortUrlVisits = { visits: [{}, {}, {}], }; + const goBack = jest.fn(); beforeEach(() => { - wrapper = shallow(); + wrapper = shallow(); }); afterEach(() => wrapper.unmount());