mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-11 02:37:22 +03:00
Created common component that can be used both for create and edit servers
This commit is contained in:
parent
fb0ebddf28
commit
6d44ac1e0c
4 changed files with 93 additions and 33 deletions
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { HorizontalFormGroup } from '../utils/HorizontalFormGroup';
|
|
||||||
import './CreateServer.scss';
|
import './CreateServer.scss';
|
||||||
|
import { ServerForm } from './helpers/ServerForm';
|
||||||
|
|
||||||
const SHOW_IMPORT_MSG_TIME = 4000;
|
const SHOW_IMPORT_MSG_TIME = 4000;
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
@ -15,15 +15,10 @@ const propTypes = {
|
||||||
|
|
||||||
const CreateServer = (ImportServersBtn, useStateFlagTimeout) => {
|
const CreateServer = (ImportServersBtn, useStateFlagTimeout) => {
|
||||||
const CreateServerComp = ({ createServer, history: { push }, resetSelectedServer }) => {
|
const CreateServerComp = ({ createServer, history: { push }, resetSelectedServer }) => {
|
||||||
const [ name, setName ] = useState('');
|
|
||||||
const [ url, setUrl ] = useState('');
|
|
||||||
const [ apiKey, setApiKey ] = useState('');
|
|
||||||
const [ serversImported, setServersImported ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
const [ serversImported, setServersImported ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (serverData) => {
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const id = uuid();
|
const id = uuid();
|
||||||
const server = { id, name, url, apiKey };
|
const server = { id, ...serverData };
|
||||||
|
|
||||||
createServer(server);
|
createServer(server);
|
||||||
push(`/server/${id}/list-short-urls/1`);
|
push(`/server/${id}/list-short-urls/1`);
|
||||||
|
@ -35,26 +30,20 @@ const CreateServer = (ImportServersBtn, useStateFlagTimeout) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="create-server">
|
<div className="create-server">
|
||||||
<form onSubmit={handleSubmit}>
|
<ServerForm onSubmit={handleSubmit}>
|
||||||
<HorizontalFormGroup value={name} onChange={setName}>Name</HorizontalFormGroup>
|
<ImportServersBtn onImport={setServersImported} />
|
||||||
<HorizontalFormGroup type="url" value={url} onChange={setUrl}>URL</HorizontalFormGroup>
|
<button className="btn btn-outline-primary">Create server</button>
|
||||||
<HorizontalFormGroup value={apiKey} onChange={setApiKey}>API key</HorizontalFormGroup>
|
</ServerForm>
|
||||||
|
|
||||||
<div className="text-right">
|
{serversImported && (
|
||||||
<ImportServersBtn onImport={setServersImported} />
|
<div className="row create-server__import-success-msg">
|
||||||
<button className="btn btn-outline-primary">Create server</button>
|
<div className="col-md-10 offset-md-1">
|
||||||
</div>
|
<div className="p-2 mt-3 bg-main text-white text-center">
|
||||||
|
Servers properly imported. You can now select one from the list :)
|
||||||
{serversImported && (
|
|
||||||
<div className="row create-server__import-success-msg">
|
|
||||||
<div className="col-md-10 offset-md-1">
|
|
||||||
<div className="p-2 mt-3 bg-main text-white text-center">
|
|
||||||
Servers properly imported. You can now select one from the list :)
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</form>
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
41
src/servers/helpers/ServerForm.js
Normal file
41
src/servers/helpers/ServerForm.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { HorizontalFormGroup } from '../../utils/HorizontalFormGroup';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
onSubmit: PropTypes.func.isRequired,
|
||||||
|
initialValues: PropTypes.shape({
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
|
apiKey: PropTypes.string.isRequired,
|
||||||
|
}),
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ServerForm = ({ onSubmit, initialValues, children }) => {
|
||||||
|
const [ name, setName ] = useState('');
|
||||||
|
const [ url, setUrl ] = useState('');
|
||||||
|
const [ apiKey, setApiKey ] = useState('');
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
onSubmit({ name, url, apiKey });
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initialValues && setName(initialValues.name);
|
||||||
|
initialValues && setUrl(initialValues.url);
|
||||||
|
initialValues && setApiKey(initialValues.apiKey);
|
||||||
|
}, [ initialValues ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<HorizontalFormGroup value={name} onChange={setName}>Name</HorizontalFormGroup>
|
||||||
|
<HorizontalFormGroup type="url" value={url} onChange={setUrl}>URL</HorizontalFormGroup>
|
||||||
|
<HorizontalFormGroup value={apiKey} onChange={setApiKey}>API key</HorizontalFormGroup>
|
||||||
|
|
||||||
|
<div className="text-right">{children}</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerForm.propTypes = propTypes;
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import createServerConstruct from '../../src/servers/CreateServer';
|
import createServerConstruct from '../../src/servers/CreateServer';
|
||||||
import { HorizontalFormGroup } from '../../src/utils/HorizontalFormGroup';
|
import { ServerForm } from '../../src/servers/helpers/ServerForm';
|
||||||
|
|
||||||
describe('<CreateServer />', () => {
|
describe('<CreateServer />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
@ -29,8 +29,7 @@ describe('<CreateServer />', () => {
|
||||||
it('renders components', () => {
|
it('renders components', () => {
|
||||||
const wrapper = createWrapper();
|
const wrapper = createWrapper();
|
||||||
|
|
||||||
expect(wrapper.find(HorizontalFormGroup)).toHaveLength(3);
|
expect(wrapper.find(ServerForm)).toHaveLength(1);
|
||||||
expect(wrapper.find(ImportServersBtn)).toHaveLength(1);
|
|
||||||
expect(wrapper.find('.create-server__import-success-msg')).toHaveLength(0);
|
expect(wrapper.find('.create-server__import-success-msg')).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,11 +41,9 @@ describe('<CreateServer />', () => {
|
||||||
|
|
||||||
it('creates server and redirects to it when form is submitted', () => {
|
it('creates server and redirects to it when form is submitted', () => {
|
||||||
const wrapper = createWrapper();
|
const wrapper = createWrapper();
|
||||||
const form = wrapper.find('form');
|
const form = wrapper.find(ServerForm);
|
||||||
|
|
||||||
form.simulate('submit', { preventDefault() {
|
form.simulate('submit', {});
|
||||||
return '';
|
|
||||||
} });
|
|
||||||
|
|
||||||
expect(createServerMock).toHaveBeenCalledTimes(1);
|
expect(createServerMock).toHaveBeenCalledTimes(1);
|
||||||
expect(historyMock.push).toHaveBeenCalledTimes(1);
|
expect(historyMock.push).toHaveBeenCalledTimes(1);
|
||||||
|
|
33
test/servers/helpers/ServerForm.test.js
Normal file
33
test/servers/helpers/ServerForm.test.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { ServerForm } from '../../../src/servers/helpers/ServerForm';
|
||||||
|
import { HorizontalFormGroup } from '../../../src/utils/HorizontalFormGroup';
|
||||||
|
|
||||||
|
describe('<ServerForm />', () => {
|
||||||
|
let wrapper;
|
||||||
|
const onSubmit = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(<ServerForm onSubmit={onSubmit}><span>Something</span></ServerForm>);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
wrapper && wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders components', () => {
|
||||||
|
expect(wrapper.find(HorizontalFormGroup)).toHaveLength(3);
|
||||||
|
expect(wrapper.find('span')).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('invokes submit callback when submit event is triggered', () => {
|
||||||
|
const form = wrapper.find('form');
|
||||||
|
const preventDefault = jest.fn();
|
||||||
|
|
||||||
|
form.simulate('submit', { preventDefault });
|
||||||
|
|
||||||
|
expect(preventDefault).toHaveBeenCalled();
|
||||||
|
expect(onSubmit).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue