Fixed links and some form styles

This commit is contained in:
Alejandro Celaya 2022-03-05 14:04:01 +01:00
parent f4fa1582a7
commit ec403d7b1f
10 changed files with 38 additions and 25 deletions

View file

@ -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;
} }

View file

@ -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>

View file

@ -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>
); );

View file

@ -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>

View file

@ -3,7 +3,7 @@
} }
.tag--light-bg { .tag--light-bg {
color: #000; color: #222 !important;
} }
.tag:not(:last-child) { .tag:not(:last-child) {

View file

@ -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
View file

@ -0,0 +1,3 @@
import { FC } from 'react';
export const FormText: FC = ({ children }) => <small className="form-text text-muted d-block">{children}</small>;

View file

@ -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;
} }

View file

@ -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);

View file

@ -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' });
}); });