mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-17 13:03:50 +00:00
Merge pull request #444 from acelaya-forks/feature/crawlable-option
Feature/crawlable option
This commit is contained in:
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||||||
* [#432](https://github.com/shlinkio/shlink-web-client/pull/432) Added support to provide the `servers.json` file inside a a `conf.d` folder.
|
* [#432](https://github.com/shlinkio/shlink-web-client/pull/432) Added support to provide the `servers.json` file inside a a `conf.d` folder.
|
||||||
* [#440](https://github.com/shlinkio/shlink-web-client/pull/440) Added hint of what visits come potentially from a bot, in the visits table, when consuming Shlink >=2.7.
|
* [#440](https://github.com/shlinkio/shlink-web-client/pull/440) Added hint of what visits come potentially from a bot, in the visits table, when consuming Shlink >=2.7.
|
||||||
* [#431](https://github.com/shlinkio/shlink-web-client/pull/431) Added support to filter out visits from potential bots in visits sections, when consuming Shlink >=2.7.
|
* [#431](https://github.com/shlinkio/shlink-web-client/pull/431) Added support to filter out visits from potential bots in visits sections, when consuming Shlink >=2.7.
|
||||||
|
* [#430](https://github.com/shlinkio/shlink-web-client/pull/430) Added support to set new and existing short URLs as crawlable, when consuming Shlink >=2.7.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* *Nothing*
|
* *Nothing*
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ const getInitialState = (shortUrl?: ShortUrl, settings?: ShortUrlCreationSetting
|
|||||||
validSince: shortUrl.meta.validSince ?? undefined,
|
validSince: shortUrl.meta.validSince ?? undefined,
|
||||||
validUntil: shortUrl.meta.validUntil ?? undefined,
|
validUntil: shortUrl.meta.validUntil ?? undefined,
|
||||||
maxVisits: shortUrl.meta.maxVisits ?? undefined,
|
maxVisits: shortUrl.meta.maxVisits ?? undefined,
|
||||||
|
crawlable: shortUrl.crawlable,
|
||||||
validateUrl,
|
validateUrl,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import m from 'moment';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import DateInput, { DateInputProps } from '../utils/DateInput';
|
import DateInput, { DateInputProps } from '../utils/DateInput';
|
||||||
import {
|
import {
|
||||||
|
supportsCrawlableVisits,
|
||||||
supportsListingDomains,
|
supportsListingDomains,
|
||||||
supportsSettingShortCodeLength,
|
supportsSettingShortCodeLength,
|
||||||
supportsShortUrlTitle,
|
supportsShortUrlTitle,
|
||||||
@@ -20,6 +21,7 @@ import { DomainSelectorProps } from '../domains/DomainSelector';
|
|||||||
import { formatIsoDate } from '../utils/helpers/date';
|
import { formatIsoDate } from '../utils/helpers/date';
|
||||||
import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
|
import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
|
||||||
import { ShortUrlData } from './data';
|
import { ShortUrlData } from './data';
|
||||||
|
import { ShortUrlFormCheckboxGroup } from './helpers/ShortUrlFormCheckboxGroup';
|
||||||
import './ShortUrlForm.scss';
|
import './ShortUrlForm.scss';
|
||||||
|
|
||||||
export type Mode = 'create' | 'create-basic' | 'edit';
|
export type Mode = 'create' | 'create-basic' | 'edit';
|
||||||
@@ -108,7 +110,8 @@ export const ShortUrlForm = (
|
|||||||
'col-sm-12': !showCustomizeCard,
|
'col-sm-12': !showCustomizeCard,
|
||||||
});
|
});
|
||||||
const showValidateUrl = supportsValidateUrl(selectedServer);
|
const showValidateUrl = supportsValidateUrl(selectedServer);
|
||||||
const showExtraValidationsCard = showValidateUrl || !isEdit;
|
const showCrawlableControl = supportsCrawlableVisits(selectedServer);
|
||||||
|
const showExtraValidationsCard = showValidateUrl || showCrawlableControl || !isEdit;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="short-url-form" onSubmit={submit}>
|
<form className="short-url-form" onSubmit={submit}>
|
||||||
@@ -167,23 +170,24 @@ export const ShortUrlForm = (
|
|||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{showExtraValidationsCard && (
|
{showExtraValidationsCard && (
|
||||||
<SimpleCard title="Extra validations" className="mb-3">
|
<SimpleCard title="Extra checks" className="mb-3">
|
||||||
{!isEdit && (
|
|
||||||
<p>
|
|
||||||
Make sure the long URL is valid, or ensure an existing short URL is returned if it matches all
|
|
||||||
provided data.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{showValidateUrl && (
|
{showValidateUrl && (
|
||||||
<p>
|
<ShortUrlFormCheckboxGroup
|
||||||
<Checkbox
|
infoTooltip="If checked, Shlink will try to reach the long URL, failing in case it's not publicly accessible."
|
||||||
inline
|
checked={shortUrlData.validateUrl}
|
||||||
checked={shortUrlData.validateUrl}
|
onChange={(validateUrl) => setShortUrlData({ ...shortUrlData, validateUrl })}
|
||||||
onChange={(validateUrl) => setShortUrlData({ ...shortUrlData, validateUrl })}
|
>
|
||||||
>
|
Validate URL
|
||||||
Validate URL
|
</ShortUrlFormCheckboxGroup>
|
||||||
</Checkbox>
|
)}
|
||||||
</p>
|
{showCrawlableControl && (
|
||||||
|
<ShortUrlFormCheckboxGroup
|
||||||
|
infoTooltip="This short URL will be included in the robots.txt for your Shlink instance, allowing web crawlers (like Google) to index it."
|
||||||
|
checked={shortUrlData.crawlable}
|
||||||
|
onChange={(crawlable) => setShortUrlData({ ...shortUrlData, crawlable })}
|
||||||
|
>
|
||||||
|
Make it crawlable
|
||||||
|
</ShortUrlFormCheckboxGroup>
|
||||||
)}
|
)}
|
||||||
{!isEdit && (
|
{!isEdit && (
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface EditShortUrlData {
|
|||||||
validUntil?: m.Moment | string | null;
|
validUntil?: m.Moment | string | null;
|
||||||
maxVisits?: number | null;
|
maxVisits?: number | null;
|
||||||
validateUrl?: boolean;
|
validateUrl?: boolean;
|
||||||
|
crawlable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShortUrlData extends EditShortUrlData {
|
export interface ShortUrlData extends EditShortUrlData {
|
||||||
@@ -29,6 +30,7 @@ export interface ShortUrl {
|
|||||||
tags: string[];
|
tags: string[];
|
||||||
domain: string | null;
|
domain: string | null;
|
||||||
title?: string | null;
|
title?: string | null;
|
||||||
|
crawlable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShortUrlMeta {
|
export interface ShortUrlMeta {
|
||||||
|
|||||||
39
src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx
Normal file
39
src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { ChangeEvent, FC, useRef } from 'react';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
|
import Checkbox from '../../utils/Checkbox';
|
||||||
|
|
||||||
|
interface ShortUrlFormCheckboxGroupProps {
|
||||||
|
checked?: boolean;
|
||||||
|
onChange?: (checked: boolean, e: ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
infoTooltip?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InfoTooltip: FC<{ tooltip: string }> = ({ tooltip }) => {
|
||||||
|
const ref = useRef<HTMLElement | null>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span
|
||||||
|
ref={(el) => {
|
||||||
|
ref.current = el;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={infoIcon} />
|
||||||
|
</span>
|
||||||
|
<UncontrolledTooltip target={(() => ref.current) as any} placement="right">{tooltip}</UncontrolledTooltip>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ShortUrlFormCheckboxGroup: FC<ShortUrlFormCheckboxGroupProps> = (
|
||||||
|
{ children, infoTooltip, checked, onChange },
|
||||||
|
) => (
|
||||||
|
<p>
|
||||||
|
<Checkbox inline checked={checked} className={infoTooltip ? 'mr-2' : ''} onChange={onChange}>
|
||||||
|
{children}
|
||||||
|
</Checkbox>
|
||||||
|
{infoTooltip && <InfoTooltip tooltip={infoTooltip} />}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
@@ -25,3 +25,5 @@ export const supportsQrCodeMargin = supportsShortUrlTitle;
|
|||||||
export const supportsTagsInPatch = supportsShortUrlTitle;
|
export const supportsTagsInPatch = supportsShortUrlTitle;
|
||||||
|
|
||||||
export const supportsBotVisits = serverMatchesVersions({ minVersion: '2.7.0' });
|
export const supportsBotVisits = serverMatchesVersions({ minVersion: '2.7.0' });
|
||||||
|
|
||||||
|
export const supportsCrawlableVisits = supportsBotVisits;
|
||||||
|
|||||||
16
test/short-urls/helpers/ShortUrlFormCheckboxGroup.test.tsx
Normal file
16
test/short-urls/helpers/ShortUrlFormCheckboxGroup.test.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { ShortUrlFormCheckboxGroup } from '../../../src/short-urls/helpers/ShortUrlFormCheckboxGroup';
|
||||||
|
import Checkbox from '../../../src/utils/Checkbox';
|
||||||
|
|
||||||
|
describe('<ShortUrlFormCheckboxGroup />', () => {
|
||||||
|
test.each([
|
||||||
|
[ undefined, '', 0 ],
|
||||||
|
[ 'This is the tooltip', 'mr-2', 1 ],
|
||||||
|
])('renders tooltip only when provided', (infoTooltip, expectedClassName, expectedAmountOfTooltips) => {
|
||||||
|
const wrapper = shallow(<ShortUrlFormCheckboxGroup infoTooltip={infoTooltip} />);
|
||||||
|
const checkbox = wrapper.find(Checkbox);
|
||||||
|
|
||||||
|
expect(checkbox.prop('className')).toEqual(expectedClassName);
|
||||||
|
expect(wrapper.find('InfoTooltip')).toHaveLength(expectedAmountOfTooltips);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user