mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Improved server form
This commit is contained in:
parent
d62edb2249
commit
4d969b994e
8 changed files with 55 additions and 44 deletions
|
@ -44,7 +44,7 @@ const CreateServer = (ImportServersBtn: FC<ImportServersBtnProps>, useStateFlagT
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NoMenuLayout>
|
<NoMenuLayout>
|
||||||
<ServerForm onSubmit={handleSubmit}>
|
<ServerForm title={<h5 className="mb-0">Add new server</h5>} onSubmit={handleSubmit}>
|
||||||
<ImportServersBtn onImport={setServersImported} onImportError={setErrorImporting} />
|
<ImportServersBtn onImport={setServersImported} onImportError={setErrorImporting} />
|
||||||
<button className="btn btn-outline-primary">Create server</button>
|
<button className="btn btn-outline-primary">Create server</button>
|
||||||
</ServerForm>
|
</ServerForm>
|
||||||
|
|
|
@ -23,7 +23,11 @@ export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProp
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NoMenuLayout>
|
<NoMenuLayout>
|
||||||
<ServerForm initialValues={selectedServer} onSubmit={handleSubmit}>
|
<ServerForm
|
||||||
|
title={<h5 className="mb-0">Edit "{selectedServer.name}"</h5>}
|
||||||
|
initialValues={selectedServer}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
<Button outline className="mr-2" onClick={goBack}>Cancel</Button>
|
<Button outline className="mr-2" onClick={goBack}>Cancel</Button>
|
||||||
<Button outline color="primary">Save</Button>
|
<Button outline color="primary">Save</Button>
|
||||||
</ServerForm>
|
</ServerForm>
|
||||||
|
|
3
src/servers/helpers/ServerForm.scss
Normal file
3
src/servers/helpers/ServerForm.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.server-form .form-group:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, ReactNode, useEffect, useState } from 'react';
|
||||||
import { HorizontalFormGroup } from '../../utils/HorizontalFormGroup';
|
import { FormGroupContainer } from '../../utils/FormGroupContainer';
|
||||||
import { handleEventPreventingDefault } from '../../utils/utils';
|
import { handleEventPreventingDefault } from '../../utils/utils';
|
||||||
import { ServerData } from '../data';
|
import { ServerData } from '../data';
|
||||||
|
import { SimpleCard } from '../../utils/SimpleCard';
|
||||||
|
import './ServerForm.scss';
|
||||||
|
|
||||||
interface ServerFormProps {
|
interface ServerFormProps {
|
||||||
onSubmit: (server: ServerData) => void;
|
onSubmit: (server: ServerData) => void;
|
||||||
initialValues?: ServerData;
|
initialValues?: ServerData;
|
||||||
|
title?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, children }) => {
|
export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, children, title }) => {
|
||||||
const [ name, setName ] = useState('');
|
const [ name, setName ] = useState('');
|
||||||
const [ url, setUrl ] = useState('');
|
const [ url, setUrl ] = useState('');
|
||||||
const [ apiKey, setApiKey ] = useState('');
|
const [ apiKey, setApiKey ] = useState('');
|
||||||
|
@ -21,10 +24,12 @@ export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, child
|
||||||
}, [ initialValues ]);
|
}, [ initialValues ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit}>
|
<form className="server-form" onSubmit={handleSubmit}>
|
||||||
<HorizontalFormGroup value={name} onChange={setName}>Name</HorizontalFormGroup>
|
<SimpleCard className="mb-4" title={title}>
|
||||||
<HorizontalFormGroup type="url" value={url} onChange={setUrl}>URL</HorizontalFormGroup>
|
<FormGroupContainer value={name} onChange={setName}>Name</FormGroupContainer>
|
||||||
<HorizontalFormGroup value={apiKey} onChange={setApiKey}>API key</HorizontalFormGroup>
|
<FormGroupContainer type="url" value={url} onChange={setUrl}>URL</FormGroupContainer>
|
||||||
|
<FormGroupContainer value={apiKey} onChange={setApiKey}>API key</FormGroupContainer>
|
||||||
|
</SimpleCard>
|
||||||
|
|
||||||
<div className="text-right">{children}</div>
|
<div className="text-right">{children}</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
29
src/utils/FormGroupContainer.tsx
Normal file
29
src/utils/FormGroupContainer.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import { InputType } from 'reactstrap/lib/Input';
|
||||||
|
|
||||||
|
interface FormGroupContainer {
|
||||||
|
value: string;
|
||||||
|
onChange: (newValue: string) => void;
|
||||||
|
id?: string;
|
||||||
|
type?: InputType;
|
||||||
|
required?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FormGroupContainer: FC<FormGroupContainer> = (
|
||||||
|
{ children, value, onChange, id = uuid(), type = 'text', required = true },
|
||||||
|
) => (
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor={id} className="create-server__label">
|
||||||
|
{children}:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="form-control"
|
||||||
|
type={type}
|
||||||
|
id={id}
|
||||||
|
value={value}
|
||||||
|
required={required}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
|
@ -1,31 +0,0 @@
|
||||||
import { FC } from 'react';
|
|
||||||
import { v4 as uuid } from 'uuid';
|
|
||||||
import { InputType } from 'reactstrap/lib/Input';
|
|
||||||
|
|
||||||
interface HorizontalFormGroupProps {
|
|
||||||
value: string;
|
|
||||||
onChange: (newValue: string) => void;
|
|
||||||
id?: string;
|
|
||||||
type?: InputType;
|
|
||||||
required?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const HorizontalFormGroup: FC<HorizontalFormGroupProps> = (
|
|
||||||
{ children, value, onChange, id = uuid(), type = 'text', required = true },
|
|
||||||
) => (
|
|
||||||
<div className="form-group row">
|
|
||||||
<label htmlFor={id} className="col-lg-1 col-md-2 col-form-label create-server__label">
|
|
||||||
{children}:
|
|
||||||
</label>
|
|
||||||
<div className="col-lg-11 col-md-10">
|
|
||||||
<input
|
|
||||||
className="form-control"
|
|
||||||
type={type}
|
|
||||||
id={id}
|
|
||||||
value={value}
|
|
||||||
required={required}
|
|
||||||
onChange={(e) => onChange(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { CardProps } from 'reactstrap/lib/Card';
|
import { CardProps } from 'reactstrap/lib/Card';
|
||||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
interface SimpleCardProps extends CardProps {
|
interface SimpleCardProps extends Omit<CardProps, 'title'> {
|
||||||
title?: string;
|
title?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SimpleCard = ({ title, children, ...rest }: SimpleCardProps) => (
|
export const SimpleCard = ({ title, children, ...rest }: SimpleCardProps) => (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { ServerForm } from '../../../src/servers/helpers/ServerForm';
|
import { ServerForm } from '../../../src/servers/helpers/ServerForm';
|
||||||
import { HorizontalFormGroup } from '../../../src/utils/HorizontalFormGroup';
|
import { FormGroupContainer } from '../../../src/utils/FormGroupContainer';
|
||||||
|
|
||||||
describe('<ServerForm />', () => {
|
describe('<ServerForm />', () => {
|
||||||
let wrapper: ShallowWrapper;
|
let wrapper: ShallowWrapper;
|
||||||
|
@ -14,7 +14,7 @@ describe('<ServerForm />', () => {
|
||||||
afterEach(jest.resetAllMocks);
|
afterEach(jest.resetAllMocks);
|
||||||
|
|
||||||
it('renders components', () => {
|
it('renders components', () => {
|
||||||
expect(wrapper.find(HorizontalFormGroup)).toHaveLength(3);
|
expect(wrapper.find(FormGroupContainer)).toHaveLength(3);
|
||||||
expect(wrapper.find('span')).toHaveLength(1);
|
expect(wrapper.find('span')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue