Ensured short URLs list is updated after editing the long URL of a short URL

This commit is contained in:
Alejandro Celaya 2020-03-30 20:47:33 +02:00
parent 7949e224e0
commit 1219a16261
4 changed files with 10 additions and 16 deletions

View file

@ -2,7 +2,6 @@ import React, { useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button } from 'reactstrap'; import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button } from 'reactstrap';
import { ExternalLink } from 'react-external-link'; import { ExternalLink } from 'react-external-link';
import { pipe } from 'ramda';
import { shortUrlType } from '../reducers/shortUrlsList'; import { shortUrlType } from '../reducers/shortUrlsList';
import { ShortUrlEditionType } from '../reducers/shortUrlEdition'; import { ShortUrlEditionType } from '../reducers/shortUrlEdition';
import { hasValue } from '../../utils/utils'; import { hasValue } from '../../utils/utils';
@ -13,20 +12,18 @@ const propTypes = {
shortUrl: shortUrlType.isRequired, shortUrl: shortUrlType.isRequired,
shortUrlEdition: ShortUrlEditionType, shortUrlEdition: ShortUrlEditionType,
editShortUrl: PropTypes.func, editShortUrl: PropTypes.func,
resetShortUrlEdition: PropTypes.func,
}; };
const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShortUrl, resetShortUrlEdition }) => { const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShortUrl }) => {
const { saving, error } = shortUrlEdition; const { saving, error } = shortUrlEdition;
const url = shortUrl && (shortUrl.shortUrl || ''); const url = shortUrl && (shortUrl.shortUrl || '');
const [ longUrl, setLongUrl ] = useState(shortUrl.longUrl); const [ longUrl, setLongUrl ] = useState(shortUrl.longUrl);
const close = pipe(resetShortUrlEdition, toggle); const doEdit = () => editShortUrl(shortUrl.shortCode, shortUrl.domain, longUrl).then(toggle);
const doEdit = () => editShortUrl(shortUrl.shortCode, shortUrl.domain, longUrl).then(close);
return ( return (
<Modal isOpen={isOpen} toggle={close} centered> <Modal isOpen={isOpen} toggle={toggle} centered>
<ModalHeader toggle={close}> <ModalHeader toggle={toggle}>
Edit long URL for <ExternalLink href={url} /> Edit long URL for <ExternalLink href={url} />
</ModalHeader> </ModalHeader>
<form onSubmit={(e) => e.preventDefault() || doEdit()}> <form onSubmit={(e) => e.preventDefault() || doEdit()}>
@ -47,7 +44,7 @@ const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShor
)} )}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button color="link" onClick={close}>Cancel</Button> <Button color="link" onClick={toggle}>Cancel</Button>
<Button color="primary" disabled={saving || !hasValue(longUrl)}>{saving ? 'Saving...' : 'Save'}</Button> <Button color="primary" disabled={saving || !hasValue(longUrl)}>{saving ? 'Saving...' : 'Save'}</Button>
</ModalFooter> </ModalFooter>
</form> </form>

View file

@ -1,11 +1,10 @@
import { createAction, handleActions } from 'redux-actions'; import { handleActions } from 'redux-actions';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
/* eslint-disable padding-line-between-statements */ /* eslint-disable padding-line-between-statements */
export const EDIT_SHORT_URL_START = 'shlink/shortUrlEdition/EDIT_SHORT_URL_START'; export const EDIT_SHORT_URL_START = 'shlink/shortUrlEdition/EDIT_SHORT_URL_START';
export const EDIT_SHORT_URL_ERROR = 'shlink/shortUrlEdition/EDIT_SHORT_URL_ERROR'; export const EDIT_SHORT_URL_ERROR = 'shlink/shortUrlEdition/EDIT_SHORT_URL_ERROR';
export const SHORT_URL_EDITED = 'shlink/shortUrlEdition/SHORT_URL_EDITED'; export const SHORT_URL_EDITED = 'shlink/shortUrlEdition/SHORT_URL_EDITED';
export const RESET_EDIT_SHORT_URL = 'shlink/shortUrlEdition/RESET_EDIT_SHORT_URL';
/* eslint-enable padding-line-between-statements */ /* eslint-enable padding-line-between-statements */
export const ShortUrlEditionType = PropTypes.shape({ export const ShortUrlEditionType = PropTypes.shape({
@ -26,7 +25,6 @@ export default handleActions({
[EDIT_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }), [EDIT_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }),
[EDIT_SHORT_URL_ERROR]: (state) => ({ ...state, saving: false, error: true }), [EDIT_SHORT_URL_ERROR]: (state) => ({ ...state, saving: false, error: true }),
[SHORT_URL_EDITED]: (state, { shortCode, longUrl }) => ({ shortCode, longUrl, saving: false, error: false }), [SHORT_URL_EDITED]: (state, { shortCode, longUrl }) => ({ shortCode, longUrl, saving: false, error: false }),
[RESET_EDIT_SHORT_URL]: () => initialState,
}, initialState); }, initialState);
export const editShortUrl = (buildShlinkApiClient) => (shortCode, domain, longUrl) => async (dispatch, getState) => { export const editShortUrl = (buildShlinkApiClient) => (shortCode, domain, longUrl) => async (dispatch, getState) => {
@ -42,5 +40,3 @@ export const editShortUrl = (buildShlinkApiClient) => (shortCode, domain, longUr
throw e; throw e;
} }
}; };
export const resetShortUrlEdition = createAction(RESET_EDIT_SHORT_URL);

View file

@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { SHORT_URL_TAGS_EDITED } from './shortUrlTags'; import { SHORT_URL_TAGS_EDITED } from './shortUrlTags';
import { SHORT_URL_DELETED } from './shortUrlDeletion'; import { SHORT_URL_DELETED } from './shortUrlDeletion';
import { SHORT_URL_META_EDITED, shortUrlMetaType } from './shortUrlMeta'; import { SHORT_URL_META_EDITED, shortUrlMetaType } from './shortUrlMeta';
import { SHORT_URL_EDITED } from './shortUrlEdition';
/* eslint-disable padding-line-between-statements */ /* eslint-disable padding-line-between-statements */
export const LIST_SHORT_URLS_START = 'shlink/shortUrlsList/LIST_SHORT_URLS_START'; export const LIST_SHORT_URLS_START = 'shlink/shortUrlsList/LIST_SHORT_URLS_START';
@ -54,6 +55,7 @@ export default handleActions({
), ),
[SHORT_URL_TAGS_EDITED]: setPropFromActionOnMatchingShortUrl('tags'), [SHORT_URL_TAGS_EDITED]: setPropFromActionOnMatchingShortUrl('tags'),
[SHORT_URL_META_EDITED]: setPropFromActionOnMatchingShortUrl('meta'), [SHORT_URL_META_EDITED]: setPropFromActionOnMatchingShortUrl('meta'),
[SHORT_URL_EDITED]: setPropFromActionOnMatchingShortUrl('longUrl'),
}, initialState); }, initialState);
export const listShortUrls = (buildShlinkApiClient) => (params = {}) => async (dispatch, getState) => { export const listShortUrls = (buildShlinkApiClient) => (params = {}) => async (dispatch, getState) => {

View file

@ -17,7 +17,7 @@ import { deleteShortUrl, resetDeleteShortUrl } from '../reducers/shortUrlDeletio
import { editShortUrlTags, resetShortUrlsTags } from '../reducers/shortUrlTags'; import { editShortUrlTags, resetShortUrlsTags } from '../reducers/shortUrlTags';
import { editShortUrlMeta, resetShortUrlMeta } from '../reducers/shortUrlMeta'; import { editShortUrlMeta, resetShortUrlMeta } from '../reducers/shortUrlMeta';
import { resetShortUrlParams } from '../reducers/shortUrlsListParams'; import { resetShortUrlParams } from '../reducers/shortUrlsListParams';
import { editShortUrl, resetShortUrlEdition } from '../reducers/shortUrlEdition'; import { editShortUrl } from '../reducers/shortUrlEdition';
const provideServices = (bottle, connect) => { const provideServices = (bottle, connect) => {
// Components // Components
@ -64,7 +64,7 @@ const provideServices = (bottle, connect) => {
bottle.decorator('EditMetaModal', connect([ 'shortUrlMeta' ], [ 'editShortUrlMeta', 'resetShortUrlMeta' ])); bottle.decorator('EditMetaModal', connect([ 'shortUrlMeta' ], [ 'editShortUrlMeta', 'resetShortUrlMeta' ]));
bottle.serviceFactory('EditShortUrlModal', () => EditShortUrlModal); bottle.serviceFactory('EditShortUrlModal', () => EditShortUrlModal);
bottle.decorator('EditShortUrlModal', connect([ 'shortUrlEdition' ], [ 'editShortUrl', 'resetShortUrlEdition' ])); bottle.decorator('EditShortUrlModal', connect([ 'shortUrlEdition' ], [ 'editShortUrl' ]));
// Actions // Actions
bottle.serviceFactory('editShortUrlTags', editShortUrlTags, 'buildShlinkApiClient'); bottle.serviceFactory('editShortUrlTags', editShortUrlTags, 'buildShlinkApiClient');
@ -83,7 +83,6 @@ const provideServices = (bottle, connect) => {
bottle.serviceFactory('resetShortUrlMeta', () => resetShortUrlMeta); bottle.serviceFactory('resetShortUrlMeta', () => resetShortUrlMeta);
bottle.serviceFactory('editShortUrl', editShortUrl, 'buildShlinkApiClient'); bottle.serviceFactory('editShortUrl', editShortUrl, 'buildShlinkApiClient');
bottle.serviceFactory('resetShortUrlEdition', () => resetShortUrlEdition);
}; };
export default provideServices; export default provideServices;