From 680d80d7536f93c85a62d2b8889a141d73e3ed70 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 18 Aug 2018 17:14:33 +0200 Subject: [PATCH] Prevented short URLs list to be reloaded when tags are edited --- src/short-urls/helpers/EditTagsModal.js | 19 ++++++++++++++----- src/short-urls/reducers/shortUrlTags.js | 7 +++++++ src/short-urls/reducers/shortUrlsList.js | 15 +++++++++------ test/common/AsideMenu.test.js | 7 ++++--- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/short-urls/helpers/EditTagsModal.js b/src/short-urls/helpers/EditTagsModal.js index ea4a0c15..8bef6daf 100644 --- a/src/short-urls/helpers/EditTagsModal.js +++ b/src/short-urls/helpers/EditTagsModal.js @@ -3,9 +3,13 @@ import { connect } from 'react-redux'; import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; import TagsSelector from '../../utils/TagsSelector'; import PropTypes from 'prop-types'; -import { editShortUrlTags, resetShortUrlsTags, shortUrlTagsType } from '../reducers/shortUrlTags'; +import { + editShortUrlTags, + resetShortUrlsTags, + shortUrlTagsType, + shortUrlTagsEdited +} from '../reducers/shortUrlTags'; import { pick } from 'ramda'; -import { refreshShortUrls } from '../reducers/shortUrlsList'; const propTypes = { isOpen: PropTypes.bool.isRequired, @@ -13,6 +17,7 @@ const propTypes = { url: PropTypes.string.isRequired, shortUrl: PropTypes.shape({ tags: PropTypes.arrayOf(PropTypes.string), + shortCode: PropTypes.string, }).isRequired, shortUrlTags: shortUrlTagsType, }; @@ -32,7 +37,9 @@ export class EditTagsModal extends React.Component { return; } - this.props.refreshShortUrls(); + const { shortUrlTagsEdited, shortUrl } = this.props; + const { tags } = this.state; + shortUrlTagsEdited(shortUrl.shortCode, tags); }; componentDidMount() { @@ -51,7 +58,9 @@ export class EditTagsModal extends React.Component { return ( - Edit tags for {url} + + Edit tags for {url} + this.setState({ tags })} /> {shortUrlTags.error && ( @@ -80,5 +89,5 @@ EditTagsModal.propTypes = propTypes; export default connect( pick(['shortUrlTags']), - { editShortUrlTags, resetShortUrlsTags, refreshShortUrls } + { editShortUrlTags, resetShortUrlsTags, shortUrlTagsEdited } )(EditTagsModal); diff --git a/src/short-urls/reducers/shortUrlTags.js b/src/short-urls/reducers/shortUrlTags.js index d01eda25..e2244a92 100644 --- a/src/short-urls/reducers/shortUrlTags.js +++ b/src/short-urls/reducers/shortUrlTags.js @@ -6,6 +6,7 @@ export const EDIT_SHORT_URL_TAGS_START = 'shlink/shortUrlTags/EDIT_SHORT_URL_TAG export const EDIT_SHORT_URL_TAGS_ERROR = 'shlink/shortUrlTags/EDIT_SHORT_URL_TAGS_ERROR'; export const EDIT_SHORT_URL_TAGS = 'shlink/shortUrlTags/EDIT_SHORT_URL_TAGS'; export const RESET_EDIT_SHORT_URL_TAGS = 'shlink/shortUrlTags/RESET_EDIT_SHORT_URL_TAGS'; +export const SHORT_URL_TAGS_EDITED = 'shlink/shortUrlTags/SHORT_URL_TAGS_EDITED'; export const shortUrlTagsType = PropTypes.shape({ shortCode: PropTypes.string, @@ -64,3 +65,9 @@ export const _editShortUrlTags = (ShlinkApiClient, shortCode, tags) => async (di export const editShortUrlTags = curry(_editShortUrlTags)(ShlinkApiClient); export const resetShortUrlsTags = () => ({ type: RESET_EDIT_SHORT_URL_TAGS }); + +export const shortUrlTagsEdited = (shortCode, tags) => ({ + tags, + shortCode, + type: SHORT_URL_TAGS_EDITED, +}); diff --git a/src/short-urls/reducers/shortUrlsList.js b/src/short-urls/reducers/shortUrlsList.js index 29eb99da..93c1f453 100644 --- a/src/short-urls/reducers/shortUrlsList.js +++ b/src/short-urls/reducers/shortUrlsList.js @@ -1,4 +1,6 @@ import ShlinkApiClient from '../../api/ShlinkApiClient'; +import { SHORT_URL_TAGS_EDITED } from './shortUrlTags'; +import { assoc, assocPath } from 'ramda'; const LIST_SHORT_URLS_START = 'shlink/shortUrlsList/LIST_SHORT_URLS_START'; const LIST_SHORT_URLS_ERROR = 'shlink/shortUrlsList/LIST_SHORT_URLS_ERROR'; @@ -25,6 +27,13 @@ export default function reducer(state = initialState, action) { error: true, shortUrls: [] }; + case SHORT_URL_TAGS_EDITED: + const { data } = state.shortUrls; + return assocPath(['shortUrls', 'data'], data.map(shortUrl => + shortUrl.shortCode === action.shortCode + ? assoc('tags', action.tags, shortUrl) + : shortUrl + ), state); default: return state; } @@ -41,9 +50,3 @@ export const _listShortUrls = (ShlinkApiClient, params = {}) => async dispatch = } }; export const listShortUrls = (params = {}) => _listShortUrls(ShlinkApiClient, params); - -export const _refreshShortUrls = ShlinkApiClient => async (dispatch, getState) => { - const { shortUrlsListParams } = getState(); - await _listShortUrls(ShlinkApiClient, shortUrlsListParams)(dispatch); -}; -export const refreshShortUrls = () => _refreshShortUrls(ShlinkApiClient); diff --git a/test/common/AsideMenu.test.js b/test/common/AsideMenu.test.js index db5e8f71..141f20a9 100644 --- a/test/common/AsideMenu.test.js +++ b/test/common/AsideMenu.test.js @@ -1,6 +1,7 @@ import { shallow } from 'enzyme' import React from 'react' import AsideMenu from '../../src/common/AsideMenu' +import { NavLink } from 'react-router-dom'; describe('', () => { let wrapped; @@ -12,10 +13,10 @@ describe('', () => { wrapped.unmount(); }); - it('contains links to selected server', () => { - const links = wrapped.find('NavLink'); + it('contains links to different sections', () => { + const links = wrapped.find(NavLink); - expect(links).toHaveLength(2); + expect(links).toHaveLength(3); links.forEach(link => expect(link.prop('to')).toContain('abc123')); });