mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-03 23:07:26 +03:00
Created SimpleCard component to reduce duplicated code when rendering cards
This commit is contained in:
parent
e60d241fcf
commit
2017ee7456
4 changed files with 126 additions and 93 deletions
|
@ -1,6 +1,7 @@
|
|||
import { Card, CardBody, CardHeader, FormGroup, Input } from 'reactstrap';
|
||||
import { FormGroup, Input } from 'reactstrap';
|
||||
import classNames from 'classnames';
|
||||
import ToggleSwitch from '../utils/ToggleSwitch';
|
||||
import { SimpleCard } from '../utils/SimpleCard';
|
||||
import { Settings } from './reducers/settings';
|
||||
|
||||
interface RealTimeUpdatesProps {
|
||||
|
@ -14,9 +15,7 @@ const intervalValue = (interval?: number) => !interval ? '' : `${interval}`;
|
|||
const RealTimeUpdates = (
|
||||
{ settings: { realTimeUpdates }, toggleRealTimeUpdates, setRealTimeUpdatesInterval }: RealTimeUpdatesProps,
|
||||
) => (
|
||||
<Card>
|
||||
<CardHeader>Real-time updates</CardHeader>
|
||||
<CardBody>
|
||||
<SimpleCard title="Real-time updates">
|
||||
<FormGroup>
|
||||
<ToggleSwitch checked={realTimeUpdates.enabled} onChange={toggleRealTimeUpdates}>
|
||||
Enable or disable real-time updates, when using Shlink v2.2.0 or newer.
|
||||
|
@ -45,8 +44,7 @@ const RealTimeUpdates = (
|
|||
</small>
|
||||
)}
|
||||
</FormGroup>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SimpleCard>
|
||||
);
|
||||
|
||||
export default RealTimeUpdates;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { isEmpty, pipe, replace, trim } from 'ramda';
|
||||
import { FC, useState } from 'react';
|
||||
import { Button, Card, CardBody, CardHeader, FormGroup, Input } from 'reactstrap';
|
||||
import { Button, FormGroup, Input } from 'reactstrap';
|
||||
import { InputType } from 'reactstrap/lib/Input';
|
||||
import * as m from 'moment';
|
||||
import DateInput, { DateInputProps } from '../utils/DateInput';
|
||||
|
@ -11,6 +11,7 @@ import { isReachableServer, SelectedServer } from '../servers/data';
|
|||
import { formatIsoDate } from '../utils/helpers/date';
|
||||
import { TagsSelectorProps } from '../tags/helpers/TagsSelector';
|
||||
import { DomainSelectorProps } from '../domains/DomainSelector';
|
||||
import { SimpleCard } from '../utils/SimpleCard';
|
||||
import { ShortUrlData } from './data';
|
||||
import { ShortUrlCreation } from './reducers/shortUrlCreation';
|
||||
import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
|
||||
|
@ -121,9 +122,7 @@ const CreateShortUrl = (
|
|||
<>
|
||||
<div className="row">
|
||||
<div className="col-sm-6 mb-3">
|
||||
<Card>
|
||||
<CardHeader>Customize the short URL</CardHeader>
|
||||
<CardBody>
|
||||
<SimpleCard title="Customize the short URL">
|
||||
<p>
|
||||
Use a custom slug for your marketing campaigns, change the domain or set a specific length for
|
||||
the auto-generated short code.
|
||||
|
@ -150,26 +149,21 @@ const CreateShortUrl = (
|
|||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SimpleCard>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-6 mb-3">
|
||||
<Card>
|
||||
<CardHeader>Limit access to the short URL</CardHeader>
|
||||
<CardBody>
|
||||
<SimpleCard title="Limit access to the short URL">
|
||||
<p>Determine when and how many times your short URL can be accessed.</p>
|
||||
{renderOptionalInput('maxVisits', 'Maximum number of visits allowed', 'number', { min: 1 })}
|
||||
{renderDateInput('validSince', 'Enabled since...', { maxDate: shortUrlCreation.validUntil as m.Moment | undefined })}
|
||||
{renderDateInput('validUntil', 'Enabled until...', { minDate: shortUrlCreation.validSince as m.Moment | undefined })}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SimpleCard>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="mb-3">
|
||||
<CardHeader>Extra validations</CardHeader>
|
||||
<CardBody>
|
||||
<ForServerVersion minVersion="1.16.0">
|
||||
<SimpleCard title="Extra validations" className="mb-3">
|
||||
<p>
|
||||
Make sure the long URL is valid, or ensure an existing short URL is returned if it matches all
|
||||
provided data.
|
||||
|
@ -185,7 +179,6 @@ const CreateShortUrl = (
|
|||
</Checkbox>
|
||||
</p>
|
||||
</ForServerVersion>
|
||||
<ForServerVersion minVersion="1.16.0">
|
||||
<p>
|
||||
<Checkbox
|
||||
inline
|
||||
|
@ -197,9 +190,8 @@ const CreateShortUrl = (
|
|||
</Checkbox>
|
||||
<UseExistingIfFoundInfoIcon />
|
||||
</p>
|
||||
</SimpleCard>
|
||||
</ForServerVersion>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
|
13
src/utils/SimpleCard.tsx
Normal file
13
src/utils/SimpleCard.tsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { CardProps } from 'reactstrap/lib/Card';
|
||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||
|
||||
interface SimpleCardProps extends CardProps {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export const SimpleCard = ({ title, children, ...rest }: SimpleCardProps) => (
|
||||
<Card {...rest}>
|
||||
{title && <CardHeader>{title}</CardHeader>}
|
||||
<CardBody>{children}</CardBody>
|
||||
</Card>
|
||||
);
|
30
test/utils/SimpleCard.test.tsx
Normal file
30
test/utils/SimpleCard.test.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||
import { SimpleCard } from '../../src/utils/SimpleCard';
|
||||
|
||||
describe('<SimpleCard />', () => {
|
||||
it.each([
|
||||
[{}, 0 ],
|
||||
[{ title: 'Cool title' }, 1 ],
|
||||
])('renders header only if title is provided', (props, expectedAmountOfHeaders) => {
|
||||
const wrapper = shallow(<SimpleCard {...props} />);
|
||||
|
||||
expect(wrapper.find(CardHeader)).toHaveLength(expectedAmountOfHeaders);
|
||||
});
|
||||
|
||||
it('renders children inside body', () => {
|
||||
const wrapper = shallow(<SimpleCard>Hello world</SimpleCard>);
|
||||
const body = wrapper.find(CardBody);
|
||||
|
||||
expect(body).toHaveLength(1);
|
||||
expect(body.html()).toContain('Hello world');
|
||||
});
|
||||
|
||||
it('passes extra props to nested card', () => {
|
||||
const wrapper = shallow(<SimpleCard className="foo" color="primary">Hello world</SimpleCard>);
|
||||
const card = wrapper.find(Card);
|
||||
|
||||
expect(card.prop('className')).toEqual('foo');
|
||||
expect(card.prop('color')).toEqual('primary');
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue