Migrated tag actions to have a single DTO param

This commit is contained in:
Alejandro Celaya 2022-11-07 21:57:01 +01:00
parent f8fc1245ca
commit 648744f440
4 changed files with 14 additions and 23 deletions

View file

@ -8,15 +8,15 @@ import { useToggle } from '../../utils/helpers/hooks';
import { handleEventPreventingDefault } from '../../utils/utils'; import { handleEventPreventingDefault } from '../../utils/utils';
import { ColorGenerator } from '../../utils/services/ColorGenerator'; import { ColorGenerator } from '../../utils/services/ColorGenerator';
import { TagModalProps } from '../data'; import { TagModalProps } from '../data';
import { TagEdition } from '../reducers/tagEdit'; import { EditTag, TagEdition } from '../reducers/tagEdit';
import { Result } from '../../utils/Result'; import { Result } from '../../utils/Result';
import { ShlinkApiError } from '../../api/ShlinkApiError'; import { ShlinkApiError } from '../../api/ShlinkApiError';
import './EditTagModal.scss'; import './EditTagModal.scss';
interface EditTagModalProps extends TagModalProps { interface EditTagModalProps extends TagModalProps {
tagEdit: TagEdition; tagEdit: TagEdition;
editTag: (oldName: string, newName: string, color: string) => Promise<void>; editTag: (editTag: EditTag) => Promise<void>;
tagEdited: (oldName: string, newName: string, color: string) => void; tagEdited: (tagEdited: EditTag) => void;
} }
export const EditTagModal = ({ getColorForKey }: ColorGenerator) => ( export const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
@ -27,11 +27,11 @@ export const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
const [showColorPicker, toggleColorPicker, , hideColorPicker] = useToggle(); const [showColorPicker, toggleColorPicker, , hideColorPicker] = useToggle();
const { editing, error, edited, errorData } = tagEdit; const { editing, error, edited, errorData } = tagEdit;
const saveTag = handleEventPreventingDefault( const saveTag = handleEventPreventingDefault(
async () => editTag(tag, newTagName, color) async () => editTag({ oldName: tag, newName: newTagName, color })
.then(toggle) .then(toggle)
.catch(() => {}), .catch(() => {}),
); );
const onClosed = pipe(hideColorPicker, () => edited && tagEdited(tag, newTagName, color)); const onClosed = pipe(hideColorPicker, () => edited && tagEdited({ oldName: tag, newName: newTagName, color }));
return ( return (
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={onClosed}> <Modal isOpen={isOpen} toggle={toggle} centered onClosed={onClosed}>

View file

@ -1,5 +1,5 @@
import { pick } from 'ramda'; import { pick } from 'ramda';
import { PayloadAction } from '@reduxjs/toolkit'; import { createAction, PayloadAction } from '@reduxjs/toolkit';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { buildReducer } from '../../utils/helpers/redux'; import { buildReducer } from '../../utils/helpers/redux';
import { GetState } from '../../container/types'; import { GetState } from '../../container/types';
@ -23,7 +23,7 @@ export interface TagEdition {
errorData?: ProblemDetailsError; errorData?: ProblemDetailsError;
} }
interface EditTag { export interface EditTag {
oldName: string; oldName: string;
newName: string; newName: string;
color: string; color: string;
@ -49,9 +49,7 @@ export default buildReducer<TagEdition, EditTagAction & ApiErrorAction>({
}, initialState); }, initialState);
export const editTag = (buildShlinkApiClient: ShlinkApiClientBuilder, colorGenerator: ColorGenerator) => ( export const editTag = (buildShlinkApiClient: ShlinkApiClientBuilder, colorGenerator: ColorGenerator) => (
oldName: string, { oldName, newName, color }: EditTag,
newName: string,
color: string,
) => async (dispatch: Dispatch, getState: GetState) => { ) => async (dispatch: Dispatch, getState: GetState) => {
dispatch({ type: EDIT_TAG_START }); dispatch({ type: EDIT_TAG_START });
const { editTag: shlinkEditTag } = buildShlinkApiClient(getState); const { editTag: shlinkEditTag } = buildShlinkApiClient(getState);
@ -70,11 +68,4 @@ export const editTag = (buildShlinkApiClient: ShlinkApiClientBuilder, colorGener
} }
}; };
export const tagEdited = (oldName: string, newName: string, color: string): EditTagAction => ({ export const tagEdited = createAction<EditTag>(TAG_EDITED);
type: TAG_EDITED,
payload: {
oldName,
newName,
color,
},
});

View file

@ -11,7 +11,7 @@ import { TagStats } from '../data';
import { ApiErrorAction } from '../../api/types/actions'; import { ApiErrorAction } from '../../api/types/actions';
import { CREATE_SHORT_URL, CreateShortUrlAction } from '../../short-urls/reducers/shortUrlCreation'; import { CREATE_SHORT_URL, CreateShortUrlAction } from '../../short-urls/reducers/shortUrlCreation';
import { DeleteTagAction, TAG_DELETED } from './tagDelete'; import { DeleteTagAction, TAG_DELETED } from './tagDelete';
import { EditTagAction, TAG_EDITED } from './tagEdit'; import { EditTagAction, tagEdited } from './tagEdit';
import { ProblemDetailsError } from '../../api/types/errors'; import { ProblemDetailsError } from '../../api/types/errors';
export const LIST_TAGS_START = 'shlink/tagsList/LIST_TAGS_START'; export const LIST_TAGS_START = 'shlink/tagsList/LIST_TAGS_START';
@ -90,7 +90,7 @@ export default buildReducer<TagsList, TagsCombinedAction>({
tags: rejectTag(state.tags, tag), tags: rejectTag(state.tags, tag),
filteredTags: rejectTag(state.filteredTags, tag), filteredTags: rejectTag(state.filteredTags, tag),
}), }),
[TAG_EDITED]: (state, { payload }) => ({ [tagEdited.toString()]: (state, { payload }) => ({
...state, ...state,
tags: state.tags.map(renameTag(payload.oldName, payload.newName)).sort(), tags: state.tags.map(renameTag(payload.oldName, payload.newName)).sort(),
filteredTags: state.filteredTags.map(renameTag(payload.oldName, payload.newName)).sort(), filteredTags: state.filteredTags.map(renameTag(payload.oldName, payload.newName)).sort(),

View file

@ -50,7 +50,7 @@ describe('tagEditReducer', () => {
describe('tagEdited', () => { describe('tagEdited', () => {
it('returns action based on provided params', () => it('returns action based on provided params', () =>
expect(tagEdited('foo', 'bar', '#ff0000')).toEqual({ expect(tagEdited({ oldName: 'foo', newName: 'bar', color: '#ff0000' })).toEqual({
type: TAG_EDITED, type: TAG_EDITED,
payload: { payload: {
oldName: 'foo', oldName: 'foo',
@ -74,7 +74,7 @@ describe('tagEditReducer', () => {
it('calls API on success', async () => { it('calls API on success', async () => {
const apiClientMock = createApiClientMock(Promise.resolve()); const apiClientMock = createApiClientMock(Promise.resolve());
const dispatchable = editTag(() => apiClientMock, colorGenerator)(oldName, newName, color); const dispatchable = editTag(() => apiClientMock, colorGenerator)({ oldName, newName, color });
await dispatchable(dispatch, getState); await dispatchable(dispatch, getState);
@ -95,7 +95,7 @@ describe('tagEditReducer', () => {
it('throws on error', async () => { it('throws on error', async () => {
const error = 'Error'; const error = 'Error';
const apiClientMock = createApiClientMock(Promise.reject(error)); const apiClientMock = createApiClientMock(Promise.reject(error));
const dispatchable = editTag(() => apiClientMock, colorGenerator)(oldName, newName, color); const dispatchable = editTag(() => apiClientMock, colorGenerator)({ oldName, newName, color });
try { try {
await dispatchable(dispatch, getState); await dispatchable(dispatch, getState);