From 724c80497111c817d45febfac03a16431d38186f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 08:49:24 +0100 Subject: [PATCH 01/15] Installed redux-actions dependency and used it for selectedServer reducer --- package.json | 1 + src/servers/reducers/selectedServer.js | 25 ++++++------- yarn.lock | 50 ++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 457521b4..29cb437b 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react-tagsinput": "^3.19.0", "reactstrap": "^6.0.1", "redux": "^4.0.0", + "redux-actions": "^2.6.5", "redux-thunk": "^2.3.0", "uuid": "^3.3.2" }, diff --git a/src/servers/reducers/selectedServer.js b/src/servers/reducers/selectedServer.js index 51b53e86..b05443f6 100644 --- a/src/servers/reducers/selectedServer.js +++ b/src/servers/reducers/selectedServer.js @@ -1,24 +1,14 @@ +import { createAction, handleActions } from 'redux-actions'; import { resetShortUrlParams } from '../../short-urls/reducers/shortUrlsListParams'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const SELECT_SERVER = 'shlink/selectedServer/SELECT_SERVER'; export const RESET_SELECTED_SERVER = 'shlink/selectedServer/RESET_SELECTED_SERVER'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ const defaultState = null; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case SELECT_SERVER: - return action.selectedServer; - case RESET_SELECTED_SERVER: - return defaultState; - default: - return state; - } -} - -export const resetSelectedServer = () => ({ type: RESET_SELECTED_SERVER }); +export const resetSelectedServer = createAction(RESET_SELECTED_SERVER); export const selectServer = (serversService) => (serverId) => (dispatch) => { dispatch(resetShortUrlParams()); @@ -30,3 +20,10 @@ export const selectServer = (serversService) => (serverId) => (dispatch) => { selectedServer, }); }; + +const reducer = handleActions({ + [RESET_SELECTED_SERVER]: () => defaultState, + [SELECT_SERVER]: (state, { selectedServer }) => selectedServer, +}, defaultState); + +export default reducer; diff --git a/yarn.lock b/yarn.lock index 44d72b70..639969e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5663,6 +5663,11 @@ jsx-ast-utils@^2.0.1: dependencies: array-includes "^3.0.3" +just-curry-it@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/just-curry-it/-/just-curry-it-3.1.0.tgz#ab59daed308a58b847ada166edd0a2d40766fbc5" + integrity sha512-mjzgSOFzlrurlURaHVjnQodyPNvrHrf1TbQP2XU9NSqBtHQPuHZ+Eb6TAJP7ASeJN9h9K0KXoRTs8u6ouHBKvg== + just-extend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" @@ -7612,6 +7617,11 @@ postcss-reduce-initial@^4.0.2: postcss-reduce-transforms@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.1.tgz#8600d5553bdd3ad640f43bff81eb52f8760d4561" + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" postcss-replace-overflow-wrap@^3.0.0: version "3.0.0" @@ -8325,6 +8335,22 @@ redent@^2.0.0: indent-string "^3.0.0" strip-indent "^2.0.0" +reduce-reducers@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.4.3.tgz#8e052618801cd8fc2714b4915adaa8937eb6d66c" + integrity sha512-+CNMnI8QhgVMtAt54uQs3kUxC3Sybpa7Y63HR14uGLgI9/QR5ggHvpxwhGGe3wmx5V91YwqQIblN9k5lspAmGw== + +redux-actions@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.6.5.tgz#bdca548768ee99832a63910c276def85e821a27e" + integrity sha512-pFhEcWFTYNk7DhQgxMGnbsB1H2glqhQJRQrtPb96kD3hWiZRzXHwwmFPswg6V2MjraXRXWNmuP9P84tvdLAJmw== + dependencies: + invariant "^2.2.4" + just-curry-it "^3.1.0" + loose-envify "^1.4.0" + reduce-reducers "^0.4.3" + to-camel-case "^1.0.0" + redux-thunk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" @@ -8936,6 +8962,11 @@ shebang-regex@^1.0.0: shell-quote@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" shellwords@^0.1.1: version "0.1.1" @@ -9676,6 +9707,13 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" +to-camel-case@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46" + integrity sha1-GlYFSy+daWKYzmamCJcyK29CPkY= + dependencies: + to-space-case "^1.0.0" + to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -9684,6 +9722,11 @@ to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" +to-no-case@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a" + integrity sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo= + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -9706,6 +9749,13 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +to-space-case@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17" + integrity sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc= + dependencies: + to-no-case "^1.0.0" + toggle-selection@^1.0.3: version "1.0.6" resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" From 51b5f6264d594ac5bb1ed4ef6d907b3068f4f57d Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:06:10 +0100 Subject: [PATCH 02/15] Refactored server reducer, removing duplicated code and taking advantage of redux-actions --- src/servers/reducers/selectedServer.js | 4 +-- src/servers/reducers/server.js | 37 +++++++------------------- test/servers/reducers/server.test.js | 10 +++---- 3 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/servers/reducers/selectedServer.js b/src/servers/reducers/selectedServer.js index b05443f6..c2ff3ca0 100644 --- a/src/servers/reducers/selectedServer.js +++ b/src/servers/reducers/selectedServer.js @@ -21,9 +21,7 @@ export const selectServer = (serversService) => (serverId) => (dispatch) => { }); }; -const reducer = handleActions({ +export default handleActions({ [RESET_SELECTED_SERVER]: () => defaultState, [SELECT_SERVER]: (state, { selectedServer }) => selectedServer, }, defaultState); - -export default reducer; diff --git a/src/servers/reducers/server.js b/src/servers/reducers/server.js index 44837d15..1a3955f6 100644 --- a/src/servers/reducers/server.js +++ b/src/servers/reducers/server.js @@ -1,33 +1,16 @@ +import { createAction, handleActions } from 'redux-actions'; +import { pipe } from 'ramda'; + export const FETCH_SERVERS = 'shlink/servers/FETCH_SERVERS'; -export default function reducer(state = {}, action) { - switch (action.type) { - case FETCH_SERVERS: - return action.servers; - default: - return state; - } -} +export const listServers = ({ listServers }) => createAction(FETCH_SERVERS, () => listServers()); -export const listServers = (serversService) => () => ({ - type: FETCH_SERVERS, - servers: serversService.listServers(), -}); +export const createServer = ({ createServer }, listServers) => pipe(createServer, listServers); -export const createServer = (serversService, listServers) => (server) => { - serversService.createServer(server); +export const deleteServer = ({ deleteServer }, listServers) => pipe(deleteServer, listServers); - return listServers(); -}; +export const createServers = ({ createServers }, listServers) => pipe(createServers, listServers); -export const deleteServer = (serversService, listServers) => (server) => { - serversService.deleteServer(server); - - return listServers(); -}; - -export const createServers = (serversService, listServers) => (servers) => { - serversService.createServers(servers); - - return listServers(); -}; +export default handleActions({ + [FETCH_SERVERS]: (state, { payload }) => payload, +}, {}); diff --git a/test/servers/reducers/server.test.js b/test/servers/reducers/server.test.js index 99cf30b7..55844f0a 100644 --- a/test/servers/reducers/server.test.js +++ b/test/servers/reducers/server.test.js @@ -9,13 +9,13 @@ import reducer, { } from '../../../src/servers/reducers/server'; describe('serverReducer', () => { - const servers = { + const payload = { abc123: { id: 'abc123' }, def456: { id: 'def456' }, }; - const expectedFetchServersResult = { type: FETCH_SERVERS, servers }; + const expectedFetchServersResult = { type: FETCH_SERVERS, payload }; const ServersServiceMock = { - listServers: sinon.fake.returns(servers), + listServers: sinon.fake.returns(payload), createServer: sinon.fake(), deleteServer: sinon.fake(), createServers: sinon.fake(), @@ -23,7 +23,7 @@ describe('serverReducer', () => { describe('reducer', () => { it('returns servers when action is FETCH_SERVERS', () => - expect(reducer({}, { type: FETCH_SERVERS, servers })).toEqual(servers)); + expect(reducer({}, { type: FETCH_SERVERS, payload })).toEqual(payload)); it('returns default when action is unknown', () => expect(reducer({}, { type: 'unknown' })).toEqual({})); @@ -79,7 +79,7 @@ describe('serverReducer', () => { describe('createServer', () => { it('creates multiple servers and then fetches servers again', () => { - const serversToCreate = values(servers); + const serversToCreate = values(payload); const result = createServers(ServersServiceMock, () => expectedFetchServersResult)(serversToCreate); expect(result).toEqual(expectedFetchServersResult); From 4a09d99322a34720175e8581988fcd3f5659a55e Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:11:37 +0100 Subject: [PATCH 03/15] Refactored shortUrlsList to take advantage of redux-actions --- src/short-urls/reducers/shortUrlsList.js | 54 +++++++++--------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/short-urls/reducers/shortUrlsList.js b/src/short-urls/reducers/shortUrlsList.js index fa4d4fe5..e48c0492 100644 --- a/src/short-urls/reducers/shortUrlsList.js +++ b/src/short-urls/reducers/shortUrlsList.js @@ -1,13 +1,14 @@ +import { handleActions } from 'redux-actions'; import { assoc, assocPath, propEq, reject } from 'ramda'; import PropTypes from 'prop-types'; import { SHORT_URL_TAGS_EDITED } from './shortUrlTags'; import { SHORT_URL_DELETED } from './shortUrlDeletion'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const LIST_SHORT_URLS_START = 'shlink/shortUrlsList/LIST_SHORT_URLS_START'; export const LIST_SHORT_URLS_ERROR = 'shlink/shortUrlsList/LIST_SHORT_URLS_ERROR'; export const LIST_SHORT_URLS = 'shlink/shortUrlsList/LIST_SHORT_URLS'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const shortUrlType = PropTypes.shape({ shortCode: PropTypes.string, @@ -22,39 +23,24 @@ const initialState = { error: false, }; -export default function reducer(state = initialState, action) { - switch (action.type) { - case LIST_SHORT_URLS_START: - return { ...state, loading: true, error: false }; - case LIST_SHORT_URLS: - return { - loading: false, - error: false, - shortUrls: action.shortUrls, - }; - case LIST_SHORT_URLS_ERROR: - return { - loading: false, - error: true, - shortUrls: {}, - }; - case SHORT_URL_TAGS_EDITED: - const { data } = state.shortUrls; +export default handleActions({ + [LIST_SHORT_URLS_START]: (state) => ({ ...state, loading: true, error: false }), + [LIST_SHORT_URLS]: (state, { shortUrls }) => ({ loading: false, error: false, shortUrls }), + [LIST_SHORT_URLS_ERROR]: () => ({ loading: false, error: true, shortUrls: {} }), + [SHORT_URL_TAGS_EDITED]: (state, action) => { // eslint-disable-line object-shorthand + const { data } = state.shortUrls; - return assocPath([ 'shortUrls', 'data' ], data.map((shortUrl) => - shortUrl.shortCode === action.shortCode - ? assoc('tags', action.tags, shortUrl) - : shortUrl), state); - case SHORT_URL_DELETED: - return assocPath( - [ 'shortUrls', 'data' ], - reject(propEq('shortCode', action.shortCode), state.shortUrls.data), - state, - ); - default: - return state; - } -} + return assocPath([ 'shortUrls', 'data' ], data.map((shortUrl) => + shortUrl.shortCode === action.shortCode + ? assoc('tags', action.tags, shortUrl) + : shortUrl), state); + }, + [SHORT_URL_DELETED]: (state, action) => assocPath( + [ 'shortUrls', 'data' ], + reject(propEq('shortCode', action.shortCode), state.shortUrls.data), + state, + ), +}, initialState); export const listShortUrls = (buildShlinkApiClient) => (params = {}) => async (dispatch, getState) => { dispatch({ type: LIST_SHORT_URLS_START }); From 4894ab9035c04966fe342f8a98551715915c9cc7 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:15:58 +0100 Subject: [PATCH 04/15] Refactored shortUrlsListParams reducer to takle advantage of redux-actions --- src/short-urls/reducers/shortUrlsListParams.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/short-urls/reducers/shortUrlsListParams.js b/src/short-urls/reducers/shortUrlsListParams.js index ef8de0b6..80f8e42e 100644 --- a/src/short-urls/reducers/shortUrlsListParams.js +++ b/src/short-urls/reducers/shortUrlsListParams.js @@ -1,3 +1,4 @@ +import { createAction, handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; import { LIST_SHORT_URLS } from './shortUrlsList'; @@ -11,15 +12,9 @@ export const shortUrlsListParamsType = PropTypes.shape({ const defaultState = { page: '1' }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case LIST_SHORT_URLS: - return { ...state, ...action.params }; - case RESET_SHORT_URL_PARAMS: - return defaultState; - default: - return state; - } -} +export default handleActions({ + [LIST_SHORT_URLS]: (state, { params }) => ({ ...state, ...params }), + [RESET_SHORT_URL_PARAMS]: () => defaultState, +}, defaultState); -export const resetShortUrlParams = () => ({ type: RESET_SHORT_URL_PARAMS }); +export const resetShortUrlParams = createAction(RESET_SHORT_URL_PARAMS); From 3075ccb4b9b897bb666d3acb0ddc34c8117786f5 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:20:02 +0100 Subject: [PATCH 05/15] Refactored shortUrlCreation reducer to takle advantage of redux-actions --- src/short-urls/reducers/shortUrlCreation.js | 35 +++++---------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/short-urls/reducers/shortUrlCreation.js b/src/short-urls/reducers/shortUrlCreation.js index 8a6d772f..6188feff 100644 --- a/src/short-urls/reducers/shortUrlCreation.js +++ b/src/short-urls/reducers/shortUrlCreation.js @@ -1,4 +1,5 @@ import PropTypes from 'prop-types'; +import { createAction, handleActions } from 'redux-actions'; /* eslint-disable padding-line-between-statements, newline-after-var */ export const CREATE_SHORT_URL_START = 'shlink/createShortUrl/CREATE_SHORT_URL_START'; @@ -21,32 +22,12 @@ const defaultState = { error: false, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case CREATE_SHORT_URL_START: - return { - ...state, - saving: true, - error: false, - }; - case CREATE_SHORT_URL_ERROR: - return { - ...state, - saving: false, - error: true, - }; - case CREATE_SHORT_URL: - return { - result: action.result, - saving: false, - error: false, - }; - case RESET_CREATE_SHORT_URL: - return defaultState; - default: - return state; - } -} +export default handleActions({ + [CREATE_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }), + [CREATE_SHORT_URL_ERROR]: (state) => ({ ...state, saving: false, error: true }), + [CREATE_SHORT_URL]: (state, { result }) => ({ result, saving: false, error: false }), + [RESET_CREATE_SHORT_URL]: () => defaultState, +}, defaultState); export const createShortUrl = (buildShlinkApiClient) => (data) => async (dispatch, getState) => { dispatch({ type: CREATE_SHORT_URL_START }); @@ -63,4 +44,4 @@ export const createShortUrl = (buildShlinkApiClient) => (data) => async (dispatc } }; -export const resetCreateShortUrl = () => ({ type: RESET_CREATE_SHORT_URL }); +export const resetCreateShortUrl = createAction(RESET_CREATE_SHORT_URL); From 4654bff73707a0d378cc0701a824c321de09a882 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:27:01 +0100 Subject: [PATCH 06/15] Refactored shortUrlDeletion reducer to takle advantage of redux-actions --- src/short-urls/reducers/shortUrlDeletion.js | 37 +++++---------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/short-urls/reducers/shortUrlDeletion.js b/src/short-urls/reducers/shortUrlDeletion.js index 6d2f2f52..74980bc7 100644 --- a/src/short-urls/reducers/shortUrlDeletion.js +++ b/src/short-urls/reducers/shortUrlDeletion.js @@ -1,3 +1,4 @@ +import { createAction, handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; /* eslint-disable padding-line-between-statements, newline-after-var */ @@ -25,34 +26,12 @@ const defaultState = { errorData: {}, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case DELETE_SHORT_URL_START: - return { - ...state, - loading: true, - error: false, - }; - case DELETE_SHORT_URL_ERROR: - return { - ...state, - loading: false, - error: true, - errorData: action.errorData, - }; - case DELETE_SHORT_URL: - return { - ...state, - shortCode: action.shortCode, - loading: false, - error: false, - }; - case RESET_DELETE_SHORT_URL: - return defaultState; - default: - return state; - } -} +export default handleActions({ + [DELETE_SHORT_URL_START]: (state) => ({ ...state, loading: true, error: false }), + [DELETE_SHORT_URL_ERROR]: (state, { errorData }) => ({ ...state, errorData, loading: false, error: true }), + [DELETE_SHORT_URL]: (state, { shortCode }) => ({ ...state, shortCode, loading: false, error: false }), + [RESET_DELETE_SHORT_URL]: () => defaultState, +}, defaultState); export const deleteShortUrl = (buildShlinkApiClient) => (shortCode) => async (dispatch, getState) => { dispatch({ type: DELETE_SHORT_URL_START }); @@ -70,6 +49,6 @@ export const deleteShortUrl = (buildShlinkApiClient) => (shortCode) => async (di } }; -export const resetDeleteShortUrl = () => ({ type: RESET_DELETE_SHORT_URL }); +export const resetDeleteShortUrl = createAction(RESET_DELETE_SHORT_URL); export const shortUrlDeleted = (shortCode) => ({ type: SHORT_URL_DELETED, shortCode }); From 7ff731808908636d4ca59f9428b3903f2df2341f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:32:53 +0100 Subject: [PATCH 07/15] Refactored shortUrlTags reducer to take advantage of redux-actions --- src/short-urls/reducers/shortUrlTags.js | 39 +++++++------------------ 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/src/short-urls/reducers/shortUrlTags.js b/src/short-urls/reducers/shortUrlTags.js index a0390a60..35d783cc 100644 --- a/src/short-urls/reducers/shortUrlTags.js +++ b/src/short-urls/reducers/shortUrlTags.js @@ -1,13 +1,14 @@ +import { createAction, handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; import { pick } from 'ramda'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const EDIT_SHORT_URL_TAGS_START = 'shlink/shortUrlTags/EDIT_SHORT_URL_TAGS_START'; 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'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const shortUrlTagsType = PropTypes.shape({ shortCode: PropTypes.string, @@ -23,32 +24,12 @@ const defaultState = { error: false, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case EDIT_SHORT_URL_TAGS_START: - return { - ...state, - saving: true, - error: false, - }; - case EDIT_SHORT_URL_TAGS_ERROR: - return { - ...state, - saving: false, - error: true, - }; - case EDIT_SHORT_URL_TAGS: - return { - ...pick([ 'shortCode', 'tags' ], action), - saving: false, - error: false, - }; - case RESET_EDIT_SHORT_URL_TAGS: - return defaultState; - default: - return state; - } -} +export default handleActions({ + [EDIT_SHORT_URL_TAGS_START]: (state) => ({ ...state, saving: true, error: false }), + [EDIT_SHORT_URL_TAGS_ERROR]: (state) => ({ ...state, saving: false, error: true }), + [EDIT_SHORT_URL_TAGS]: (state, action) => ({ ...pick([ 'shortCode', 'tags' ], action), saving: false, error: false }), + [RESET_EDIT_SHORT_URL_TAGS]: () => defaultState, +}, defaultState); export const editShortUrlTags = (buildShlinkApiClient) => (shortCode, tags) => async (dispatch, getState) => { dispatch({ type: EDIT_SHORT_URL_TAGS_START }); @@ -66,7 +47,7 @@ export const editShortUrlTags = (buildShlinkApiClient) => (shortCode, tags) => a } }; -export const resetShortUrlsTags = () => ({ type: RESET_EDIT_SHORT_URL_TAGS }); +export const resetShortUrlsTags = createAction(RESET_EDIT_SHORT_URL_TAGS); export const shortUrlTagsEdited = (shortCode, tags) => ({ tags, From 468e34aa3d654bbb0bfbab8213c71fb0707f7e59 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:36:07 +0100 Subject: [PATCH 08/15] Refactored shortUrlVisits reducer to take advantage of redux-actions --- src/visits/reducers/shortUrlVisits.js | 70 +++++++++++---------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/src/visits/reducers/shortUrlVisits.js b/src/visits/reducers/shortUrlVisits.js index 5aedef99..16c1f14f 100644 --- a/src/visits/reducers/shortUrlVisits.js +++ b/src/visits/reducers/shortUrlVisits.js @@ -1,13 +1,14 @@ +import { createAction, handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; import { flatten, prop, range, splitEvery } from 'ramda'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const GET_SHORT_URL_VISITS_START = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS_START'; export const GET_SHORT_URL_VISITS_ERROR = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS_ERROR'; export const GET_SHORT_URL_VISITS = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS'; export const GET_SHORT_URL_VISITS_LARGE = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS_LARGE'; export const GET_SHORT_URL_VISITS_CANCEL = 'shlink/shortUrlVisits/GET_SHORT_URL_VISITS_CANCEL'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const shortUrlVisitsType = PropTypes.shape({ visits: PropTypes.array, @@ -23,45 +24,30 @@ const initialState = { cancelLoad: false, }; -export default function reducer(state = initialState, action) { - switch (action.type) { - case GET_SHORT_URL_VISITS_START: - return { - ...state, - loading: true, - loadingLarge: false, - cancelLoad: false, - }; - case GET_SHORT_URL_VISITS_ERROR: - return { - ...state, - loading: false, - loadingLarge: false, - error: true, - cancelLoad: false, - }; - case GET_SHORT_URL_VISITS: - return { - visits: action.visits, - loading: false, - loadingLarge: false, - error: false, - cancelLoad: false, - }; - case GET_SHORT_URL_VISITS_LARGE: - return { - ...state, - loadingLarge: true, - }; - case GET_SHORT_URL_VISITS_CANCEL: - return { - ...state, - cancelLoad: true, - }; - default: - return state; - } -} +export default handleActions({ + [GET_SHORT_URL_VISITS_START]: (state) => ({ + ...state, + loading: true, + loadingLarge: false, + cancelLoad: false, + }), + [GET_SHORT_URL_VISITS_ERROR]: (state) => ({ + ...state, + loading: false, + loadingLarge: false, + error: true, + cancelLoad: false, + }), + [GET_SHORT_URL_VISITS]: (state, { visits }) => ({ + visits, + loading: false, + loadingLarge: false, + error: false, + cancelLoad: false, + }), + [GET_SHORT_URL_VISITS_LARGE]: (state) => ({ ...state, loadingLarge: true }), + [GET_SHORT_URL_VISITS_CANCEL]: (state) => ({ ...state, cancelLoad: true }), +}, initialState); export const getShortUrlVisits = (buildShlinkApiClient) => (shortCode, dates) => async (dispatch, getState) => { dispatch({ type: GET_SHORT_URL_VISITS_START }); @@ -124,4 +110,4 @@ export const getShortUrlVisits = (buildShlinkApiClient) => (shortCode, dates) => } }; -export const cancelGetShortUrlVisits = () => ({ type: GET_SHORT_URL_VISITS_CANCEL }); +export const cancelGetShortUrlVisits = createAction(GET_SHORT_URL_VISITS_CANCEL); From fcfab79bed90cc2b2b5ed8235a30e2afb697a12e Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:38:37 +0100 Subject: [PATCH 09/15] Refactored shortUrlDetail reducer to take advantage of redux-actions --- src/visits/reducers/shortUrlDetail.js | 33 +++++++-------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/visits/reducers/shortUrlDetail.js b/src/visits/reducers/shortUrlDetail.js index 385c8071..cd06db65 100644 --- a/src/visits/reducers/shortUrlDetail.js +++ b/src/visits/reducers/shortUrlDetail.js @@ -1,11 +1,12 @@ +import { handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; import { shortUrlType } from '../../short-urls/reducers/shortUrlsList'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const GET_SHORT_URL_DETAIL_START = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_START'; export const GET_SHORT_URL_DETAIL_ERROR = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_ERROR'; export const GET_SHORT_URL_DETAIL = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const shortUrlDetailType = PropTypes.shape({ shortUrl: shortUrlType, @@ -19,29 +20,11 @@ const initialState = { 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 default handleActions({ + [GET_SHORT_URL_DETAIL_START]: (state) => ({ ...state, loading: true }), + [GET_SHORT_URL_DETAIL_ERROR]: (state) => ({ ...state, loading: false, error: true }), + [GET_SHORT_URL_DETAIL]: (state, { shortUrl }) => ({ shortUrl, loading: false, error: false }), +}, initialState); export const getShortUrlDetail = (buildShlinkApiClient) => (shortCode) => async (dispatch, getState) => { dispatch({ type: GET_SHORT_URL_DETAIL_START }); From 740aacbbf1768f5aefee3fa96619f5ad09aa9d30 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 09:59:26 +0100 Subject: [PATCH 10/15] Refactored tagsList reducer to take advantage of redux-actions --- src/tags/reducers/tagsList.js | 73 ++++++++++++----------------------- 1 file changed, 24 insertions(+), 49 deletions(-) diff --git a/src/tags/reducers/tagsList.js b/src/tags/reducers/tagsList.js index 9b4fe65e..e7d21df7 100644 --- a/src/tags/reducers/tagsList.js +++ b/src/tags/reducers/tagsList.js @@ -1,14 +1,15 @@ +import { handleActions } from 'redux-actions'; import { isEmpty, reject } from 'ramda'; import { buildShlinkApiClientWithAxios as buildShlinkApiClient } from '../../utils/services/ShlinkApiClientBuilder'; import { TAG_DELETED } from './tagDelete'; import { TAG_EDITED } from './tagEdit'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ const LIST_TAGS_START = 'shlink/tagsList/LIST_TAGS_START'; const LIST_TAGS_ERROR = 'shlink/tagsList/LIST_TAGS_ERROR'; const LIST_TAGS = 'shlink/tagsList/LIST_TAGS'; const FILTER_TAGS = 'shlink/tagsList/FILTER_TAGS'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ const defaultState = { tags: [], @@ -17,54 +18,28 @@ const defaultState = { error: false, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case LIST_TAGS_START: - return { - ...state, - loading: true, - error: false, - }; - case LIST_TAGS_ERROR: - return { - ...state, - loading: false, - error: true, - }; - case LIST_TAGS: - return { - tags: action.tags, - filteredTags: action.tags, - loading: false, - error: false, - }; - case TAG_DELETED: - return { - ...state, +const renameTag = (oldName, newName) => (tag) => tag === oldName ? newName : tag; +const rejectTag = (tags, tagToReject) => reject((tag) => tag === tagToReject, tags); - // FIXME This should be optimized somehow... - tags: reject((tag) => tag === action.tag, state.tags), - filteredTags: reject((tag) => tag === action.tag, state.filteredTags), - }; - case TAG_EDITED: - const renameTag = (tag) => tag === action.oldName ? action.newName : tag; - - return { - ...state, - - // FIXME This should be optimized somehow... - tags: state.tags.map(renameTag).sort(), - filteredTags: state.filteredTags.map(renameTag).sort(), - }; - case FILTER_TAGS: - return { - ...state, - filteredTags: state.tags.filter((tag) => tag.toLowerCase().match(action.searchTerm)), - }; - default: - return state; - } -} +export default handleActions({ + [LIST_TAGS_START]: (state) => ({ ...state, loading: true, error: false }), + [LIST_TAGS_ERROR]: (state) => ({ ...state, loading: false, error: true }), + [LIST_TAGS]: (state, { tags }) => ({ tags, filteredTags: tags, loading: false, error: false }), + [TAG_DELETED]: (state, { tag }) => ({ + ...state, + tags: rejectTag(state.tags, tag), + filteredTags: rejectTag(state.filteredTags, tag), + }), + [TAG_EDITED]: (state, { oldName, newName }) => ({ + ...state, + tags: state.tags.map(renameTag(oldName, newName)).sort(), + filteredTags: state.filteredTags.map(renameTag(oldName, newName)).sort(), + }), + [FILTER_TAGS]: (state, { searchTerm }) => ({ + ...state, + filteredTags: state.tags.filter((tag) => tag.toLowerCase().match(searchTerm)), + }), +}, defaultState); export const _listTags = (buildShlinkApiClient, force = false) => async (dispatch, getState) => { const { tagsList, selectedServer } = getState(); From 879034c9c64ec9bf1aedecdbbaab415e57a0af91 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 10:02:44 +0100 Subject: [PATCH 11/15] Refactored tagDelete reducer to take advantage of redux-actions --- src/tags/reducers/tagDelete.js | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/tags/reducers/tagDelete.js b/src/tags/reducers/tagDelete.js index 03c42947..1940fafe 100644 --- a/src/tags/reducers/tagDelete.js +++ b/src/tags/reducers/tagDelete.js @@ -1,11 +1,12 @@ +import { handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const DELETE_TAG_START = 'shlink/deleteTag/DELETE_TAG_START'; export const DELETE_TAG_ERROR = 'shlink/deleteTag/DELETE_TAG_ERROR'; export const DELETE_TAG = 'shlink/deleteTag/DELETE_TAG'; export const TAG_DELETED = 'shlink/deleteTag/TAG_DELETED'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const tagDeleteType = PropTypes.shape({ deleting: PropTypes.bool, @@ -17,27 +18,11 @@ const defaultState = { error: false, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case DELETE_TAG_START: - return { - deleting: true, - error: false, - }; - case DELETE_TAG_ERROR: - return { - deleting: false, - error: true, - }; - case DELETE_TAG: - return { - deleting: false, - error: false, - }; - default: - return state; - } -} +export default handleActions({ + [DELETE_TAG_START]: () => ({ deleting: true, error: false }), + [DELETE_TAG_ERROR]: () => ({ deleting: false, error: true }), + [DELETE_TAG]: () => ({ deleting: false, error: false }), +}, defaultState); export const deleteTag = (buildShlinkApiClient) => (tag) => async (dispatch, getState) => { dispatch({ type: DELETE_TAG_START }); From 5bb9d15e2745fe3eded4e6b4ee32653c97ea6979 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 10:07:28 +0100 Subject: [PATCH 12/15] Refactored tagEdit reducer to take advantage of redux-actions --- src/short-urls/reducers/shortUrlCreation.js | 4 +-- src/short-urls/reducers/shortUrlDeletion.js | 4 +-- src/tags/reducers/tagEdit.js | 38 +++++++-------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/short-urls/reducers/shortUrlCreation.js b/src/short-urls/reducers/shortUrlCreation.js index 6188feff..b98cc1d6 100644 --- a/src/short-urls/reducers/shortUrlCreation.js +++ b/src/short-urls/reducers/shortUrlCreation.js @@ -1,12 +1,12 @@ import PropTypes from 'prop-types'; import { createAction, handleActions } from 'redux-actions'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const CREATE_SHORT_URL_START = 'shlink/createShortUrl/CREATE_SHORT_URL_START'; export const CREATE_SHORT_URL_ERROR = 'shlink/createShortUrl/CREATE_SHORT_URL_ERROR'; export const CREATE_SHORT_URL = 'shlink/createShortUrl/CREATE_SHORT_URL'; export const RESET_CREATE_SHORT_URL = 'shlink/createShortUrl/RESET_CREATE_SHORT_URL'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const createShortUrlResultType = PropTypes.shape({ result: PropTypes.shape({ diff --git a/src/short-urls/reducers/shortUrlDeletion.js b/src/short-urls/reducers/shortUrlDeletion.js index 74980bc7..3b13241f 100644 --- a/src/short-urls/reducers/shortUrlDeletion.js +++ b/src/short-urls/reducers/shortUrlDeletion.js @@ -1,13 +1,13 @@ import { createAction, handleActions } from 'redux-actions'; import PropTypes from 'prop-types'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const DELETE_SHORT_URL_START = 'shlink/deleteShortUrl/DELETE_SHORT_URL_START'; export const DELETE_SHORT_URL_ERROR = 'shlink/deleteShortUrl/DELETE_SHORT_URL_ERROR'; export const DELETE_SHORT_URL = 'shlink/deleteShortUrl/DELETE_SHORT_URL'; export const RESET_DELETE_SHORT_URL = 'shlink/deleteShortUrl/RESET_DELETE_SHORT_URL'; export const SHORT_URL_DELETED = 'shlink/deleteShortUrl/SHORT_URL_DELETED'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const shortUrlDeletionType = PropTypes.shape({ shortCode: PropTypes.string.isRequired, diff --git a/src/tags/reducers/tagEdit.js b/src/tags/reducers/tagEdit.js index 950e95db..393d7660 100644 --- a/src/tags/reducers/tagEdit.js +++ b/src/tags/reducers/tagEdit.js @@ -1,10 +1,11 @@ import { pick } from 'ramda'; +import { handleActions } from 'redux-actions'; -/* eslint-disable padding-line-between-statements, newline-after-var */ +/* eslint-disable padding-line-between-statements */ export const EDIT_TAG_START = 'shlink/editTag/EDIT_TAG_START'; export const EDIT_TAG_ERROR = 'shlink/editTag/EDIT_TAG_ERROR'; export const EDIT_TAG = 'shlink/editTag/EDIT_TAG'; -/* eslint-enable padding-line-between-statements, newline-after-var */ +/* eslint-enable padding-line-between-statements */ export const TAG_EDITED = 'shlink/editTag/TAG_EDITED'; @@ -15,30 +16,15 @@ const defaultState = { error: false, }; -export default function reducer(state = defaultState, action) { - switch (action.type) { - case EDIT_TAG_START: - return { - ...state, - editing: true, - error: false, - }; - case EDIT_TAG_ERROR: - return { - ...state, - editing: false, - error: true, - }; - case EDIT_TAG: - return { - ...pick([ 'oldName', 'newName' ], action), - editing: false, - error: false, - }; - default: - return state; - } -} +export default handleActions({ + [EDIT_TAG_START]: (state) => ({ ...state, editing: true, error: false }), + [EDIT_TAG_ERROR]: (state) => ({ ...state, editing: false, error: true }), + [EDIT_TAG]: (state, action) => ({ + ...pick([ 'oldName', 'newName' ], action), + editing: false, + error: false, + }), +}, defaultState); export const editTag = (buildShlinkApiClient, colorGenerator) => (oldName, newName, color) => async ( dispatch, From 232c059e4f0e8fd18a93988196b8f17b0f4cb4cd Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 10:11:20 +0100 Subject: [PATCH 13/15] Replaced usages of defaultState by initialState --- src/servers/reducers/selectedServer.js | 6 +++--- src/short-urls/reducers/shortUrlCreation.js | 6 +++--- src/short-urls/reducers/shortUrlDeletion.js | 6 +++--- src/short-urls/reducers/shortUrlTags.js | 6 +++--- src/short-urls/reducers/shortUrlsListParams.js | 6 +++--- src/tags/reducers/tagDelete.js | 4 ++-- src/tags/reducers/tagEdit.js | 4 ++-- src/tags/reducers/tagsList.js | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/servers/reducers/selectedServer.js b/src/servers/reducers/selectedServer.js index c2ff3ca0..2d35987f 100644 --- a/src/servers/reducers/selectedServer.js +++ b/src/servers/reducers/selectedServer.js @@ -6,7 +6,7 @@ export const SELECT_SERVER = 'shlink/selectedServer/SELECT_SERVER'; export const RESET_SELECTED_SERVER = 'shlink/selectedServer/RESET_SELECTED_SERVER'; /* eslint-enable padding-line-between-statements */ -const defaultState = null; +const initialState = null; export const resetSelectedServer = createAction(RESET_SELECTED_SERVER); @@ -22,6 +22,6 @@ export const selectServer = (serversService) => (serverId) => (dispatch) => { }; export default handleActions({ - [RESET_SELECTED_SERVER]: () => defaultState, + [RESET_SELECTED_SERVER]: () => initialState, [SELECT_SERVER]: (state, { selectedServer }) => selectedServer, -}, defaultState); +}, initialState); diff --git a/src/short-urls/reducers/shortUrlCreation.js b/src/short-urls/reducers/shortUrlCreation.js index b98cc1d6..2cd4e9e3 100644 --- a/src/short-urls/reducers/shortUrlCreation.js +++ b/src/short-urls/reducers/shortUrlCreation.js @@ -16,7 +16,7 @@ export const createShortUrlResultType = PropTypes.shape({ error: PropTypes.bool, }); -const defaultState = { +const initialState = { result: null, saving: false, error: false, @@ -26,8 +26,8 @@ export default handleActions({ [CREATE_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }), [CREATE_SHORT_URL_ERROR]: (state) => ({ ...state, saving: false, error: true }), [CREATE_SHORT_URL]: (state, { result }) => ({ result, saving: false, error: false }), - [RESET_CREATE_SHORT_URL]: () => defaultState, -}, defaultState); + [RESET_CREATE_SHORT_URL]: () => initialState, +}, initialState); export const createShortUrl = (buildShlinkApiClient) => (data) => async (dispatch, getState) => { dispatch({ type: CREATE_SHORT_URL_START }); diff --git a/src/short-urls/reducers/shortUrlDeletion.js b/src/short-urls/reducers/shortUrlDeletion.js index 3b13241f..2c2a568b 100644 --- a/src/short-urls/reducers/shortUrlDeletion.js +++ b/src/short-urls/reducers/shortUrlDeletion.js @@ -19,7 +19,7 @@ export const shortUrlDeletionType = PropTypes.shape({ }).isRequired, }); -const defaultState = { +const initialState = { shortCode: '', loading: false, error: false, @@ -30,8 +30,8 @@ export default handleActions({ [DELETE_SHORT_URL_START]: (state) => ({ ...state, loading: true, error: false }), [DELETE_SHORT_URL_ERROR]: (state, { errorData }) => ({ ...state, errorData, loading: false, error: true }), [DELETE_SHORT_URL]: (state, { shortCode }) => ({ ...state, shortCode, loading: false, error: false }), - [RESET_DELETE_SHORT_URL]: () => defaultState, -}, defaultState); + [RESET_DELETE_SHORT_URL]: () => initialState, +}, initialState); export const deleteShortUrl = (buildShlinkApiClient) => (shortCode) => async (dispatch, getState) => { dispatch({ type: DELETE_SHORT_URL_START }); diff --git a/src/short-urls/reducers/shortUrlTags.js b/src/short-urls/reducers/shortUrlTags.js index 35d783cc..9c9f8149 100644 --- a/src/short-urls/reducers/shortUrlTags.js +++ b/src/short-urls/reducers/shortUrlTags.js @@ -17,7 +17,7 @@ export const shortUrlTagsType = PropTypes.shape({ error: PropTypes.bool.isRequired, }); -const defaultState = { +const initialState = { shortCode: null, tags: [], saving: false, @@ -28,8 +28,8 @@ export default handleActions({ [EDIT_SHORT_URL_TAGS_START]: (state) => ({ ...state, saving: true, error: false }), [EDIT_SHORT_URL_TAGS_ERROR]: (state) => ({ ...state, saving: false, error: true }), [EDIT_SHORT_URL_TAGS]: (state, action) => ({ ...pick([ 'shortCode', 'tags' ], action), saving: false, error: false }), - [RESET_EDIT_SHORT_URL_TAGS]: () => defaultState, -}, defaultState); + [RESET_EDIT_SHORT_URL_TAGS]: () => initialState, +}, initialState); export const editShortUrlTags = (buildShlinkApiClient) => (shortCode, tags) => async (dispatch, getState) => { dispatch({ type: EDIT_SHORT_URL_TAGS_START }); diff --git a/src/short-urls/reducers/shortUrlsListParams.js b/src/short-urls/reducers/shortUrlsListParams.js index 80f8e42e..14962362 100644 --- a/src/short-urls/reducers/shortUrlsListParams.js +++ b/src/short-urls/reducers/shortUrlsListParams.js @@ -10,11 +10,11 @@ export const shortUrlsListParamsType = PropTypes.shape({ searchTerm: PropTypes.string, }); -const defaultState = { page: '1' }; +const initialState = { page: '1' }; export default handleActions({ [LIST_SHORT_URLS]: (state, { params }) => ({ ...state, ...params }), - [RESET_SHORT_URL_PARAMS]: () => defaultState, -}, defaultState); + [RESET_SHORT_URL_PARAMS]: () => initialState, +}, initialState); export const resetShortUrlParams = createAction(RESET_SHORT_URL_PARAMS); diff --git a/src/tags/reducers/tagDelete.js b/src/tags/reducers/tagDelete.js index 1940fafe..d8fd747a 100644 --- a/src/tags/reducers/tagDelete.js +++ b/src/tags/reducers/tagDelete.js @@ -13,7 +13,7 @@ export const tagDeleteType = PropTypes.shape({ error: PropTypes.bool, }); -const defaultState = { +const initialState = { deleting: false, error: false, }; @@ -22,7 +22,7 @@ export default handleActions({ [DELETE_TAG_START]: () => ({ deleting: true, error: false }), [DELETE_TAG_ERROR]: () => ({ deleting: false, error: true }), [DELETE_TAG]: () => ({ deleting: false, error: false }), -}, defaultState); +}, initialState); export const deleteTag = (buildShlinkApiClient) => (tag) => async (dispatch, getState) => { dispatch({ type: DELETE_TAG_START }); diff --git a/src/tags/reducers/tagEdit.js b/src/tags/reducers/tagEdit.js index 393d7660..2613169e 100644 --- a/src/tags/reducers/tagEdit.js +++ b/src/tags/reducers/tagEdit.js @@ -9,7 +9,7 @@ export const EDIT_TAG = 'shlink/editTag/EDIT_TAG'; export const TAG_EDITED = 'shlink/editTag/TAG_EDITED'; -const defaultState = { +const initialState = { oldName: '', newName: '', editing: false, @@ -24,7 +24,7 @@ export default handleActions({ editing: false, error: false, }), -}, defaultState); +}, initialState); export const editTag = (buildShlinkApiClient, colorGenerator) => (oldName, newName, color) => async ( dispatch, diff --git a/src/tags/reducers/tagsList.js b/src/tags/reducers/tagsList.js index e7d21df7..899be3e6 100644 --- a/src/tags/reducers/tagsList.js +++ b/src/tags/reducers/tagsList.js @@ -11,7 +11,7 @@ const LIST_TAGS = 'shlink/tagsList/LIST_TAGS'; const FILTER_TAGS = 'shlink/tagsList/FILTER_TAGS'; /* eslint-enable padding-line-between-statements */ -const defaultState = { +const initialState = { tags: [], filteredTags: [], loading: false, @@ -39,7 +39,7 @@ export default handleActions({ ...state, filteredTags: state.tags.filter((tag) => tag.toLowerCase().match(searchTerm)), }), -}, defaultState); +}, initialState); export const _listTags = (buildShlinkApiClient, force = false) => async (dispatch, getState) => { const { tagsList, selectedServer } = getState(); From d1c10e4895f66d587dc67bd1a3bece9d388a6e14 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 10:17:44 +0100 Subject: [PATCH 14/15] Removed test cases for the old default on reducers switch statements --- test/servers/reducers/selectedServer.test.js | 3 --- test/servers/reducers/server.test.js | 3 --- test/short-urls/reducers/shortUrlCreation.test.js | 3 --- ...tUrlDeleteion.test.js => shortUrlDeletion.test.js} | 6 ------ test/short-urls/reducers/shortUrlsList.test.js | 6 ------ test/short-urls/reducers/shortUrlsListParams.test.js | 3 --- test/tags/reducers/tagDelete.test.js | 3 --- test/tags/reducers/tagEdit.test.js | 3 --- test/visits/reducers/shortUrlDetail.test.js | 11 ----------- test/visits/reducers/shortUrlVisits.test.js | 11 ----------- 10 files changed, 52 deletions(-) rename test/short-urls/reducers/{shortUrlDeleteion.test.js => shortUrlDeletion.test.js} (95%) diff --git a/test/servers/reducers/selectedServer.test.js b/test/servers/reducers/selectedServer.test.js index 2316e583..423637d6 100644 --- a/test/servers/reducers/selectedServer.test.js +++ b/test/servers/reducers/selectedServer.test.js @@ -9,9 +9,6 @@ import { RESET_SHORT_URL_PARAMS } from '../../../src/short-urls/reducers/shortUr describe('selectedServerReducer', () => { describe('reducer', () => { - it('returns default when action is not handled', () => - expect(reducer(null, { type: 'unknown' })).toEqual(null)); - it('returns default when action is RESET_SELECTED_SERVER', () => expect(reducer(null, { type: RESET_SELECTED_SERVER })).toEqual(null)); diff --git a/test/servers/reducers/server.test.js b/test/servers/reducers/server.test.js index 55844f0a..cbf81d00 100644 --- a/test/servers/reducers/server.test.js +++ b/test/servers/reducers/server.test.js @@ -24,9 +24,6 @@ describe('serverReducer', () => { describe('reducer', () => { it('returns servers when action is FETCH_SERVERS', () => expect(reducer({}, { type: FETCH_SERVERS, payload })).toEqual(payload)); - - it('returns default when action is unknown', () => - expect(reducer({}, { type: 'unknown' })).toEqual({})); }); describe('action creators', () => { diff --git a/test/short-urls/reducers/shortUrlCreation.test.js b/test/short-urls/reducers/shortUrlCreation.test.js index 371d257f..c9a4e0e3 100644 --- a/test/short-urls/reducers/shortUrlCreation.test.js +++ b/test/short-urls/reducers/shortUrlCreation.test.js @@ -39,9 +39,6 @@ describe('shortUrlCreationReducer', () => { error: false, }); }); - - it('returns provided state on unknown action', () => - expect(reducer({}, { type: 'unknown' })).toEqual({})); }); describe('resetCreateShortUrl', () => { diff --git a/test/short-urls/reducers/shortUrlDeleteion.test.js b/test/short-urls/reducers/shortUrlDeletion.test.js similarity index 95% rename from test/short-urls/reducers/shortUrlDeleteion.test.js rename to test/short-urls/reducers/shortUrlDeletion.test.js index 60aca8e7..b0289614 100644 --- a/test/short-urls/reducers/shortUrlDeleteion.test.js +++ b/test/short-urls/reducers/shortUrlDeletion.test.js @@ -45,12 +45,6 @@ describe('shortUrlDeletionReducer', () => { errorData, }); }); - - it('returns provided state as is on unknown action', () => { - const state = { foo: 'bar' }; - - expect(reducer(state, { type: 'unknown' })).toEqual(state); - }); }); describe('resetDeleteShortUrl', () => { diff --git a/test/short-urls/reducers/shortUrlsList.test.js b/test/short-urls/reducers/shortUrlsList.test.js index 08274afb..a3055a04 100644 --- a/test/short-urls/reducers/shortUrlsList.test.js +++ b/test/short-urls/reducers/shortUrlsList.test.js @@ -70,12 +70,6 @@ describe('shortUrlsListReducer', () => { }, }); }); - - it('returns provided state as is on unknown action', () => { - const state = { foo: 'bar' }; - - expect(reducer(state, { type: 'unknown' })).toEqual(state); - }); }); describe('listShortUrls', () => { diff --git a/test/short-urls/reducers/shortUrlsListParams.test.js b/test/short-urls/reducers/shortUrlsListParams.test.js index 334fdb71..5c032e95 100644 --- a/test/short-urls/reducers/shortUrlsListParams.test.js +++ b/test/short-urls/reducers/shortUrlsListParams.test.js @@ -8,9 +8,6 @@ describe('shortUrlsListParamsReducer', () => { describe('reducer', () => { const defaultState = { page: '1' }; - it('returns default value when action is unknown', () => - expect(reducer(defaultState, { type: 'unknown' })).toEqual(defaultState)); - it('returns params when action is LIST_SHORT_URLS', () => expect(reducer(defaultState, { type: LIST_SHORT_URLS, params: { searchTerm: 'foo' } })).toEqual({ ...defaultState, diff --git a/test/tags/reducers/tagDelete.test.js b/test/tags/reducers/tagDelete.test.js index b3cc8c8e..8915b14f 100644 --- a/test/tags/reducers/tagDelete.test.js +++ b/test/tags/reducers/tagDelete.test.js @@ -30,9 +30,6 @@ describe('tagDeleteReducer', () => { error: false, }); }); - - it('returns provided state on unknown action', () => - expect(reducer({}, { type: 'unknown' })).toEqual({})); }); describe('tagDeleted', () => { diff --git a/test/tags/reducers/tagEdit.test.js b/test/tags/reducers/tagEdit.test.js index 91642c06..14a63353 100644 --- a/test/tags/reducers/tagEdit.test.js +++ b/test/tags/reducers/tagEdit.test.js @@ -32,9 +32,6 @@ describe('tagEditReducer', () => { newName: 'bar', }); }); - - it('returns provided state on unknown action', () => - expect(reducer({}, { type: 'unknown' })).toEqual({})); }); describe('tagEdited', () => { diff --git a/test/visits/reducers/shortUrlDetail.test.js b/test/visits/reducers/shortUrlDetail.test.js index 2a5de1e1..218ca1c3 100644 --- a/test/visits/reducers/shortUrlDetail.test.js +++ b/test/visits/reducers/shortUrlDetail.test.js @@ -32,17 +32,6 @@ describe('shortUrlDetailReducer', () => { expect(error).toEqual(false); expect(shortUrl).toEqual(actionShortUrl); }); - - it('returns default state on unknown action', () => { - const defaultState = { - shortUrl: {}, - loading: false, - error: false, - }; - const state = reducer(defaultState, { type: 'unknown' }); - - expect(state).toEqual(defaultState); - }); }); describe('getShortUrlDetail', () => { diff --git a/test/visits/reducers/shortUrlVisits.test.js b/test/visits/reducers/shortUrlVisits.test.js index 97978609..0f714675 100644 --- a/test/visits/reducers/shortUrlVisits.test.js +++ b/test/visits/reducers/shortUrlVisits.test.js @@ -49,17 +49,6 @@ describe('shortUrlVisitsReducer', () => { expect(error).toEqual(false); expect(visits).toEqual(actionVisits); }); - - it('returns default state on unknown action', () => { - const defaultState = { - visits: [], - loading: false, - error: false, - }; - const state = reducer(defaultState, { type: 'unknown' }); - - expect(state).toEqual(defaultState); - }); }); describe('getShortUrlVisits', () => { From 8d9e8565f0c649befc9aef4df3c2ec740a204bdb Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 17 Mar 2019 10:23:17 +0100 Subject: [PATCH 15/15] Updated changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd7161c6..f3a19b08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org). +## [Unreleased] + +#### Added + +* *Nothing* + +#### Changed + +* [#125](https://github.com/shlinkio/shlink-web-client/issues/125) Refactored reducers to replace `switch` statements by `handleActions` from [redux-actions](https://github.com/redux-utilities/redux-actions). + +#### Deprecated + +* *Nothing* + +#### Removed + +* *Nothing* + +#### Fixed + +* *Nothing* + + ## 2.0.3 - 2019-03-16 #### Added