mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Fixed links and some form styles
This commit is contained in:
parent
f4fa1582a7
commit
ec403d7b1f
10 changed files with 38 additions and 25 deletions
|
@ -19,6 +19,13 @@ body,
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.bg-main {
|
.bg-main {
|
||||||
background-color: $mainColor !important;
|
background-color: $mainColor !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { FormGroup, Input } from 'reactstrap';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import ToggleSwitch from '../utils/ToggleSwitch';
|
import ToggleSwitch from '../utils/ToggleSwitch';
|
||||||
import { SimpleCard } from '../utils/SimpleCard';
|
import { SimpleCard } from '../utils/SimpleCard';
|
||||||
|
import { FormText } from '../utils/FormText';
|
||||||
import { Settings } from './reducers/settings';
|
import { Settings } from './reducers/settings';
|
||||||
|
|
||||||
interface RealTimeUpdatesProps {
|
interface RealTimeUpdatesProps {
|
||||||
|
@ -19,9 +20,9 @@ const RealTimeUpdatesSettings = (
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<ToggleSwitch checked={realTimeUpdates.enabled} onChange={toggleRealTimeUpdates}>
|
<ToggleSwitch checked={realTimeUpdates.enabled} onChange={toggleRealTimeUpdates}>
|
||||||
Enable or disable real-time updates.
|
Enable or disable real-time updates.
|
||||||
<small className="form-text text-muted">
|
<FormText>
|
||||||
Real-time updates are currently being <b>{realTimeUpdates.enabled ? 'processed' : 'ignored'}</b>.
|
Real-time updates are currently being <b>{realTimeUpdates.enabled ? 'processed' : 'ignored'}</b>.
|
||||||
</small>
|
</FormText>
|
||||||
</ToggleSwitch>
|
</ToggleSwitch>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup className="mb-0">
|
<FormGroup className="mb-0">
|
||||||
|
@ -37,14 +38,14 @@ const RealTimeUpdatesSettings = (
|
||||||
onChange={({ target }) => setRealTimeUpdatesInterval(Number(target.value))}
|
onChange={({ target }) => setRealTimeUpdatesInterval(Number(target.value))}
|
||||||
/>
|
/>
|
||||||
{realTimeUpdates.enabled && (
|
{realTimeUpdates.enabled && (
|
||||||
<small className="form-text text-muted">
|
<FormText>
|
||||||
{realTimeUpdates.interval !== undefined && realTimeUpdates.interval > 0 && (
|
{realTimeUpdates.interval !== undefined && realTimeUpdates.interval > 0 && (
|
||||||
<span>
|
<span>
|
||||||
Updates will be reflected in the UI every <b>{realTimeUpdates.interval}</b> minute{realTimeUpdates.interval > 1 && 's'}.
|
Updates will be reflected in the UI every <b>{realTimeUpdates.interval}</b> minute{realTimeUpdates.interval > 1 && 's'}.
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{!realTimeUpdates.interval && 'Updates will be reflected in the UI as soon as they happen.'}
|
{!realTimeUpdates.interval && 'Updates will be reflected in the UI as soon as they happen.'}
|
||||||
</small>
|
</FormText>
|
||||||
)}
|
)}
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</SimpleCard>
|
</SimpleCard>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { DropdownItem, FormGroup } from 'reactstrap';
|
||||||
import { SimpleCard } from '../utils/SimpleCard';
|
import { SimpleCard } from '../utils/SimpleCard';
|
||||||
import ToggleSwitch from '../utils/ToggleSwitch';
|
import ToggleSwitch from '../utils/ToggleSwitch';
|
||||||
import { DropdownBtn } from '../utils/DropdownBtn';
|
import { DropdownBtn } from '../utils/DropdownBtn';
|
||||||
|
import { FormText } from '../utils/FormText';
|
||||||
import { Settings, ShortUrlCreationSettings as ShortUrlsSettings, TagFilteringMode } from './reducers/settings';
|
import { Settings, ShortUrlCreationSettings as ShortUrlsSettings, TagFilteringMode } from './reducers/settings';
|
||||||
|
|
||||||
interface ShortUrlCreationProps {
|
interface ShortUrlCreationProps {
|
||||||
|
@ -31,10 +32,10 @@ export const ShortUrlCreationSettings: FC<ShortUrlCreationProps> = ({ settings,
|
||||||
onChange={(validateUrls) => setShortUrlCreationSettings({ ...shortUrlCreation, validateUrls })}
|
onChange={(validateUrls) => setShortUrlCreationSettings({ ...shortUrlCreation, validateUrls })}
|
||||||
>
|
>
|
||||||
Request validation on long URLs when creating new short URLs.
|
Request validation on long URLs when creating new short URLs.
|
||||||
<small className="form-text text-muted">
|
<FormText>
|
||||||
The initial state of the <b>Validate URL</b> checkbox will
|
The initial state of the <b>Validate URL</b> checkbox will
|
||||||
be <b>{shortUrlCreation.validateUrls ? 'checked' : 'unchecked'}</b>.
|
be <b>{shortUrlCreation.validateUrls ? 'checked' : 'unchecked'}</b>.
|
||||||
</small>
|
</FormText>
|
||||||
</ToggleSwitch>
|
</ToggleSwitch>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
|
@ -43,10 +44,10 @@ export const ShortUrlCreationSettings: FC<ShortUrlCreationProps> = ({ settings,
|
||||||
onChange={(forwardQuery) => setShortUrlCreationSettings({ ...shortUrlCreation, forwardQuery })}
|
onChange={(forwardQuery) => setShortUrlCreationSettings({ ...shortUrlCreation, forwardQuery })}
|
||||||
>
|
>
|
||||||
Make all new short URLs forward their query params to the long URL.
|
Make all new short URLs forward their query params to the long URL.
|
||||||
<small className="form-text text-muted">
|
<FormText>
|
||||||
The initial state of the <b>Forward query params on redirect</b> checkbox will
|
The initial state of the <b>Forward query params on redirect</b> checkbox will
|
||||||
be <b>{shortUrlCreation.forwardQuery ?? true ? 'checked' : 'unchecked'}</b>.
|
be <b>{shortUrlCreation.forwardQuery ?? true ? 'checked' : 'unchecked'}</b>.
|
||||||
</small>
|
</FormText>
|
||||||
</ToggleSwitch>
|
</ToggleSwitch>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup className="mb-0">
|
<FormGroup className="mb-0">
|
||||||
|
@ -65,9 +66,7 @@ export const ShortUrlCreationSettings: FC<ShortUrlCreationProps> = ({ settings,
|
||||||
{tagFilteringModeText('includes')}
|
{tagFilteringModeText('includes')}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
</DropdownBtn>
|
</DropdownBtn>
|
||||||
<small className="form-text text-muted">
|
<FormText>{tagFilteringModeHint(shortUrlCreation.tagFilteringMode)}</FormText>
|
||||||
{tagFilteringModeHint(shortUrlCreation.tagFilteringMode)}
|
|
||||||
</small>
|
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</SimpleCard>
|
</SimpleCard>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { TagsModeDropdown } from '../tags/TagsModeDropdown';
|
||||||
import { capitalize } from '../utils/utils';
|
import { capitalize } from '../utils/utils';
|
||||||
import { OrderingDropdown } from '../utils/OrderingDropdown';
|
import { OrderingDropdown } from '../utils/OrderingDropdown';
|
||||||
import { TAGS_ORDERABLE_FIELDS } from '../tags/data/TagsListChildrenProps';
|
import { TAGS_ORDERABLE_FIELDS } from '../tags/data/TagsListChildrenProps';
|
||||||
|
import { FormText } from '../utils/FormText';
|
||||||
import { Settings, TagsSettings as TagsSettingsOptions } from './reducers/settings';
|
import { Settings, TagsSettings as TagsSettingsOptions } from './reducers/settings';
|
||||||
|
|
||||||
interface TagsProps {
|
interface TagsProps {
|
||||||
|
@ -21,7 +22,7 @@ export const TagsSettings: FC<TagsProps> = ({ settings: { tags }, setTagsSetting
|
||||||
renderTitle={(tagsMode) => capitalize(tagsMode)}
|
renderTitle={(tagsMode) => capitalize(tagsMode)}
|
||||||
onChange={(defaultMode) => setTagsSettings({ ...tags, defaultMode })}
|
onChange={(defaultMode) => setTagsSettings({ ...tags, defaultMode })}
|
||||||
/>
|
/>
|
||||||
<small className="form-text text-muted">Tags will be displayed as <b>{tags?.defaultMode ?? 'cards'}</b>.</small>
|
<FormText>Tags will be displayed as <b>{tags?.defaultMode ?? 'cards'}</b>.</FormText>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup className="mb-0">
|
<FormGroup className="mb-0">
|
||||||
<label>Default ordering for tags list:</label>
|
<label>Default ordering for tags list:</label>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag--light-bg {
|
.tag--light-bg {
|
||||||
color: #000;
|
color: #222 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag:not(:last-child) {
|
.tag:not(:last-child) {
|
||||||
|
|
|
@ -20,15 +20,15 @@ const BooleanControl: FC<BooleanControlWithTypeProps> = (
|
||||||
const { current: id } = useRef(uuid());
|
const { current: id } = useRef(uuid());
|
||||||
const onChecked = (e: ChangeEvent<HTMLInputElement>) => onChange(e.target.checked, e);
|
const onChecked = (e: ChangeEvent<HTMLInputElement>) => onChange(e.target.checked, e);
|
||||||
const typeClasses = {
|
const typeClasses = {
|
||||||
'custom-switch': type === 'switch',
|
'form-switch': type === 'switch',
|
||||||
'custom-checkbox': type === 'checkbox',
|
'form-checkbox': type === 'checkbox',
|
||||||
};
|
};
|
||||||
const style = inline ? { display: 'inline-block' } : {};
|
const style = inline ? { display: 'inline-block' } : {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className={classNames('custom-control', typeClasses, className)} style={style}>
|
<span className={classNames('form-check', typeClasses, className)} style={style}>
|
||||||
<input type="checkbox" className="custom-control-input" id={id} checked={checked} onChange={onChecked} />
|
<input type="checkbox" className="form-check-input" id={id} checked={checked} onChange={onChecked} />
|
||||||
<label className="custom-control-label" htmlFor={id}>{children}</label>
|
<label className="form-check-label" htmlFor={id}>{children}</label>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
3
src/utils/FormText.tsx
Normal file
3
src/utils/FormText.tsx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
export const FormText: FC = ({ children }) => <small className="form-text text-muted d-block">{children}</small>;
|
|
@ -6,13 +6,14 @@
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-pills__nav-link {
|
.nav-pills__nav-link.nav-pills__nav-link {
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
padding-bottom: calc(.5rem - 3px) !important;
|
padding-bottom: calc(.5rem - 3px) !important;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent !important;
|
||||||
color: #5d6778;
|
color: #5d6778;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
@media (min-width: $smMin) and (max-width: $mdMax) {
|
@media (min-width: $smMin) and (max-width: $mdMax) {
|
||||||
font-size: 89%;
|
font-size: 89%;
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-pills__nav-link.active {
|
.nav-pills__nav-link.active {
|
||||||
border-color: $mainColor;
|
border-color: $mainColor !important;
|
||||||
background-color: var(--primary-color) !important;
|
background-color: var(--primary-color) !important;
|
||||||
color: $mainColor !important;
|
color: $mainColor !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Mock } from 'ts-mockery';
|
||||||
import { DropdownItem } from 'reactstrap';
|
import { DropdownItem } from 'reactstrap';
|
||||||
import { ShortUrlCreationSettings as ShortUrlsSettings, Settings } from '../../src/settings/reducers/settings';
|
import { ShortUrlCreationSettings as ShortUrlsSettings, Settings } from '../../src/settings/reducers/settings';
|
||||||
import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings';
|
import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings';
|
||||||
|
import { FormText } from '../../src/utils/FormText';
|
||||||
import ToggleSwitch from '../../src/utils/ToggleSwitch';
|
import ToggleSwitch from '../../src/utils/ToggleSwitch';
|
||||||
import { DropdownBtn } from '../../src/utils/DropdownBtn';
|
import { DropdownBtn } from '../../src/utils/DropdownBtn';
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ describe('<ShortUrlCreationSettings />', () => {
|
||||||
[ undefined, 'Validate URL checkbox will be unchecked' ],
|
[ undefined, 'Validate URL checkbox will be unchecked' ],
|
||||||
])('shows expected helper text for URL validation', (shortUrlCreation, expectedText) => {
|
])('shows expected helper text for URL validation', (shortUrlCreation, expectedText) => {
|
||||||
const wrapper = createWrapper(shortUrlCreation);
|
const wrapper = createWrapper(shortUrlCreation);
|
||||||
const validateUrlText = wrapper.find('.form-text').first();
|
const validateUrlText = wrapper.find(FormText).first();
|
||||||
|
|
||||||
expect(validateUrlText.text()).toContain(expectedText);
|
expect(validateUrlText.text()).toContain(expectedText);
|
||||||
});
|
});
|
||||||
|
@ -62,7 +63,7 @@ describe('<ShortUrlCreationSettings />', () => {
|
||||||
[{}, 'Forward query params on redirect checkbox will be checked' ],
|
[{}, 'Forward query params on redirect checkbox will be checked' ],
|
||||||
])('shows expected helper text for query forwarding', (shortUrlCreation, expectedText) => {
|
])('shows expected helper text for query forwarding', (shortUrlCreation, expectedText) => {
|
||||||
const wrapper = createWrapper({ validateUrls: true, ...shortUrlCreation });
|
const wrapper = createWrapper({ validateUrls: true, ...shortUrlCreation });
|
||||||
const forwardQueryText = wrapper.find('.form-text').at(1);
|
const forwardQueryText = wrapper.find(FormText).at(1);
|
||||||
|
|
||||||
expect(forwardQueryText.text()).toContain(expectedText);
|
expect(forwardQueryText.text()).toContain(expectedText);
|
||||||
});
|
});
|
||||||
|
@ -77,7 +78,7 @@ describe('<ShortUrlCreationSettings />', () => {
|
||||||
[ undefined, 'Suggest tags starting with input', 'starting with' ],
|
[ undefined, 'Suggest tags starting with input', 'starting with' ],
|
||||||
])('shows expected texts for tags suggestions', (shortUrlCreation, expectedText, expectedHint) => {
|
])('shows expected texts for tags suggestions', (shortUrlCreation, expectedText, expectedHint) => {
|
||||||
const wrapper = createWrapper(shortUrlCreation);
|
const wrapper = createWrapper(shortUrlCreation);
|
||||||
const hintText = wrapper.find('.form-text').last();
|
const hintText = wrapper.find(FormText).last();
|
||||||
const dropdown = wrapper.find(DropdownBtn);
|
const dropdown = wrapper.find(DropdownBtn);
|
||||||
|
|
||||||
expect(dropdown.prop('text')).toEqual(expectedText);
|
expect(dropdown.prop('text')).toEqual(expectedText);
|
||||||
|
|
|
@ -63,7 +63,7 @@ describe('<Checkbox />', () => {
|
||||||
|
|
||||||
it('allows setting inline rendering', () => {
|
it('allows setting inline rendering', () => {
|
||||||
const wrapped = createComponent({ inline: true });
|
const wrapped = createComponent({ inline: true });
|
||||||
const control = wrapped.find('.custom-control');
|
const control = wrapped.find('.form-check');
|
||||||
|
|
||||||
expect(control.prop('style')).toEqual({ display: 'inline-block' });
|
expect(control.prop('style')).toEqual({ display: 'inline-block' });
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue