mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Ensured tags list is not updated until the edit modal is closed
This commit is contained in:
parent
2183b09ffe
commit
5ecc791b38
4 changed files with 19 additions and 21 deletions
|
@ -1,3 +1,4 @@
|
|||
import { pipe } from 'ramda';
|
||||
import { useState } from 'react';
|
||||
import { Button, Input, Modal, ModalBody, ModalFooter, ModalHeader, Popover, InputGroup } from 'reactstrap';
|
||||
import { HexColorPicker } from 'react-colorful';
|
||||
|
@ -24,16 +25,16 @@ export const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
|
|||
const [newTagName, setNewTagName] = useState(tag);
|
||||
const [color, setColor] = useState(getColorForKey(tag));
|
||||
const [showColorPicker, toggleColorPicker, , hideColorPicker] = useToggle();
|
||||
const { editing, error, errorData } = tagEdit;
|
||||
const { editing, error, edited, errorData } = tagEdit;
|
||||
const saveTag = handleEventPreventingDefault(
|
||||
async () => editTag(tag, newTagName, color)
|
||||
.then(() => tagEdited(tag, newTagName, color))
|
||||
.then(toggle)
|
||||
.catch(() => {}),
|
||||
);
|
||||
const onClosed = pipe(hideColorPicker, () => edited && tagEdited(tag, newTagName, color));
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={hideColorPicker}>
|
||||
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={onClosed}>
|
||||
<form name="editTag" onSubmit={saveTag}>
|
||||
<ModalHeader toggle={toggle}>Edit tag</ModalHeader>
|
||||
<ModalBody>
|
||||
|
|
|
@ -11,13 +11,13 @@ import { ProblemDetailsError } from '../../api/types/errors';
|
|||
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';
|
||||
|
||||
export const TAG_EDITED = 'shlink/editTag/TAG_EDITED';
|
||||
|
||||
export interface TagEdition {
|
||||
oldName: string;
|
||||
newName: string;
|
||||
oldName?: string;
|
||||
newName?: string;
|
||||
editing: boolean;
|
||||
edited: boolean;
|
||||
error: boolean;
|
||||
errorData?: ProblemDetailsError;
|
||||
}
|
||||
|
@ -29,18 +29,18 @@ export interface EditTagAction extends Action<string> {
|
|||
}
|
||||
|
||||
const initialState: TagEdition = {
|
||||
oldName: '',
|
||||
newName: '',
|
||||
editing: false,
|
||||
edited: false,
|
||||
error: false,
|
||||
};
|
||||
|
||||
export default buildReducer<TagEdition, EditTagAction & ApiErrorAction>({
|
||||
[EDIT_TAG_START]: (state) => ({ ...state, editing: true, error: false }),
|
||||
[EDIT_TAG_ERROR]: (state, { errorData }) => ({ ...state, editing: false, error: true, errorData }),
|
||||
[EDIT_TAG_START]: () => ({ editing: true, edited: false, error: false }),
|
||||
[EDIT_TAG_ERROR]: (_, { errorData }) => ({ editing: false, edited: false, error: true, errorData }),
|
||||
[EDIT_TAG]: (_, action) => ({
|
||||
...pick(['oldName', 'newName'], action),
|
||||
editing: false,
|
||||
edited: true,
|
||||
error: false,
|
||||
}),
|
||||
}, initialState);
|
||||
|
@ -56,7 +56,7 @@ export const editTag = (buildShlinkApiClient: ShlinkApiClientBuilder, colorGener
|
|||
try {
|
||||
await shlinkEditTag(oldName, newName);
|
||||
colorGenerator.setColorForKey(newName, color);
|
||||
dispatch({ type: EDIT_TAG, oldName, newName });
|
||||
dispatch({ type: EDIT_TAG, oldName, newName, color });
|
||||
} catch (e: any) {
|
||||
dispatch<ApiErrorAction>({ type: EDIT_TAG_ERROR, errorData: parseApiError(e) });
|
||||
|
||||
|
|
|
@ -9,12 +9,11 @@ import { ProblemDetailsError } from '../../../src/api/types/errors';
|
|||
describe('<EditTagModal />', () => {
|
||||
const EditTagModal = createEditTagModal(Mock.of<ColorGenerator>({ getColorForKey: jest.fn(() => 'green') }));
|
||||
const editTag = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const tagEdited = jest.fn().mockReturnValue(Promise.resolve());
|
||||
const toggle = jest.fn();
|
||||
const setUp = (tagEdit: Partial<TagEdition> = {}) => {
|
||||
const edition = Mock.of<TagEdition>(tagEdit);
|
||||
return renderWithEvents(
|
||||
<EditTagModal isOpen tag="foo" tagEdit={edition} editTag={editTag} tagEdited={tagEdited} toggle={toggle} />,
|
||||
<EditTagModal isOpen tag="foo" tagEdit={edition} editTag={editTag} tagEdited={jest.fn()} toggle={toggle} />,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -30,7 +29,6 @@ describe('<EditTagModal />', () => {
|
|||
|
||||
expect(toggle).toHaveBeenCalledTimes(2);
|
||||
expect(editTag).not.toHaveBeenCalled();
|
||||
expect(tagEdited).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
|
@ -63,12 +61,12 @@ describe('<EditTagModal />', () => {
|
|||
const { user } = setUp();
|
||||
|
||||
expect(editTag).not.toHaveBeenCalled();
|
||||
expect(tagEdited).not.toHaveBeenCalled();
|
||||
expect(toggle).not.toHaveBeenCalled();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'Save' }));
|
||||
|
||||
expect(editTag).toHaveBeenCalled();
|
||||
expect(tagEdited).toHaveBeenCalled();
|
||||
expect(toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('changes color when changing on color picker', async () => {
|
||||
|
|
|
@ -21,24 +21,23 @@ describe('tagEditReducer', () => {
|
|||
it('returns loading on EDIT_TAG_START', () => {
|
||||
expect(reducer(undefined, Mock.of<EditTagAction>({ type: EDIT_TAG_START }))).toEqual({
|
||||
editing: true,
|
||||
edited: false,
|
||||
error: false,
|
||||
oldName: '',
|
||||
newName: '',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error on EDIT_TAG_ERROR', () => {
|
||||
expect(reducer(undefined, Mock.of<EditTagAction>({ type: EDIT_TAG_ERROR }))).toEqual({
|
||||
editing: false,
|
||||
edited: false,
|
||||
error: true,
|
||||
oldName: '',
|
||||
newName: '',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns tag names on EDIT_TAG', () => {
|
||||
expect(reducer(undefined, { type: EDIT_TAG, oldName, newName, color })).toEqual({
|
||||
editing: false,
|
||||
edited: true,
|
||||
error: false,
|
||||
oldName: 'foo',
|
||||
newName: 'bar',
|
||||
|
@ -82,7 +81,7 @@ describe('tagEditReducer', () => {
|
|||
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_TAG_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_TAG, oldName, newName });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_TAG, oldName, newName, color });
|
||||
});
|
||||
|
||||
it('throws on error', async () => {
|
||||
|
|
Loading…
Reference in a new issue