mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Ensured filter for bots does not show for Shlink older than 2.7.0
This commit is contained in:
parent
638ce89780
commit
affe2309b0
5 changed files with 39 additions and 10 deletions
|
@ -16,6 +16,7 @@ import { Result } from '../utils/Result';
|
||||||
import { ShlinkApiError } from '../api/ShlinkApiError';
|
import { ShlinkApiError } from '../api/ShlinkApiError';
|
||||||
import { Settings } from '../settings/reducers/settings';
|
import { Settings } from '../settings/reducers/settings';
|
||||||
import { SelectedServer } from '../servers/data';
|
import { SelectedServer } from '../servers/data';
|
||||||
|
import { supportsBotVisits } from '../utils/helpers/features';
|
||||||
import SortableBarGraph from './helpers/SortableBarGraph';
|
import SortableBarGraph from './helpers/SortableBarGraph';
|
||||||
import GraphCard from './helpers/GraphCard';
|
import GraphCard from './helpers/GraphCard';
|
||||||
import LineChartCard from './helpers/LineChartCard';
|
import LineChartCard from './helpers/LineChartCard';
|
||||||
|
@ -86,6 +87,7 @@ const VisitsStats: FC<VisitsStatsProps> = ({
|
||||||
const [ highlightedVisits, setHighlightedVisits ] = useState<NormalizedVisit[]>([]);
|
const [ highlightedVisits, setHighlightedVisits ] = useState<NormalizedVisit[]>([]);
|
||||||
const [ highlightedLabel, setHighlightedLabel ] = useState<string | undefined>();
|
const [ highlightedLabel, setHighlightedLabel ] = useState<string | undefined>();
|
||||||
const [ visitsFilter, setVisitsFilter ] = useState<VisitsFilter>({});
|
const [ visitsFilter, setVisitsFilter ] = useState<VisitsFilter>({});
|
||||||
|
const botsSupported = supportsBotVisits(selectedServer);
|
||||||
|
|
||||||
const buildSectionUrl = (subPath?: string) => {
|
const buildSectionUrl = (subPath?: string) => {
|
||||||
const query = domain ? `?domain=${domain}` : '';
|
const query = domain ? `?domain=${domain}` : '';
|
||||||
|
@ -282,6 +284,7 @@ const VisitsStats: FC<VisitsStatsProps> = ({
|
||||||
<VisitsFilterDropdown
|
<VisitsFilterDropdown
|
||||||
className="ml-0 ml-md-2 mt-3 mt-md-0"
|
className="ml-0 ml-md-2 mt-3 mt-md-0"
|
||||||
isOrphanVisits={isOrphanVisits}
|
isOrphanVisits={isOrphanVisits}
|
||||||
|
botsSupported={botsSupported}
|
||||||
selected={visitsFilter}
|
selected={visitsFilter}
|
||||||
onChange={setVisitsFilter}
|
onChange={setVisitsFilter}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -13,28 +13,36 @@ interface VisitsFilterDropdownProps {
|
||||||
selected?: VisitsFilter;
|
selected?: VisitsFilter;
|
||||||
className?: string;
|
className?: string;
|
||||||
isOrphanVisits: boolean;
|
isOrphanVisits: boolean;
|
||||||
|
botsSupported: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VisitsFilterDropdown = (
|
export const VisitsFilterDropdown = (
|
||||||
{ onChange, selected = {}, className, isOrphanVisits }: VisitsFilterDropdownProps,
|
{ onChange, selected = {}, className, isOrphanVisits, botsSupported }: VisitsFilterDropdownProps,
|
||||||
) => {
|
) => {
|
||||||
|
if (!botsSupported && !isOrphanVisits) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { orphanVisitsType, excludeBots = false } = selected;
|
const { orphanVisitsType, excludeBots = false } = selected;
|
||||||
const propsForOrphanVisitsTypeItem = (type: OrphanVisitType): DropdownItemProps => ({
|
const propsForOrphanVisitsTypeItem = (type: OrphanVisitType): DropdownItemProps => ({
|
||||||
active: orphanVisitsType === type,
|
active: orphanVisitsType === type,
|
||||||
onClick: () => onChange({ ...selected, orphanVisitsType: type }),
|
onClick: () => onChange({ ...selected, orphanVisitsType: type }),
|
||||||
});
|
});
|
||||||
|
const onBotsClick = () => onChange({ ...selected, excludeBots: !selected?.excludeBots });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownBtn text="Filters" dropdownClassName={className} className="mr-3" right minWidth={250}>
|
<DropdownBtn text="Filters" dropdownClassName={className} className="mr-3" right minWidth={250}>
|
||||||
<DropdownItem header>Bots:</DropdownItem>
|
{botsSupported && (
|
||||||
<DropdownItem active={excludeBots} onClick={() => onChange({ ...selected, excludeBots: !selected?.excludeBots })}>
|
<>
|
||||||
Exclude potential bots
|
<DropdownItem header>Bots:</DropdownItem>
|
||||||
</DropdownItem>
|
<DropdownItem active={excludeBots} onClick={onBotsClick}>Exclude potential bots</DropdownItem>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{botsSupported && isOrphanVisits && <DropdownItem divider />}
|
||||||
|
|
||||||
{isOrphanVisits && (
|
{isOrphanVisits && (
|
||||||
<>
|
<>
|
||||||
<DropdownItem divider />
|
|
||||||
|
|
||||||
<DropdownItem header>Orphan visits type:</DropdownItem>
|
<DropdownItem header>Orphan visits type:</DropdownItem>
|
||||||
<DropdownItem {...propsForOrphanVisitsTypeItem('base_url')}>Base URL</DropdownItem>
|
<DropdownItem {...propsForOrphanVisitsTypeItem('base_url')}>Base URL</DropdownItem>
|
||||||
<DropdownItem {...propsForOrphanVisitsTypeItem('invalid_short_url')}>Invalid short URL</DropdownItem>
|
<DropdownItem {...propsForOrphanVisitsTypeItem('invalid_short_url')}>Invalid short URL</DropdownItem>
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('<EditShortUrl />', () => {
|
||||||
const ShortUrlForm = () => null;
|
const ShortUrlForm = () => null;
|
||||||
const goBack = jest.fn();
|
const goBack = jest.fn();
|
||||||
const getShortUrlDetail = jest.fn();
|
const getShortUrlDetail = jest.fn();
|
||||||
const editShortUrl = jest.fn();
|
const editShortUrl = jest.fn(async () => Promise.resolve());
|
||||||
const shortUrlCreation = { validateUrls: true };
|
const shortUrlCreation = { validateUrls: true };
|
||||||
const createWrapper = (detail: Partial<ShortUrlDetail> = {}, edition: Partial<ShortUrlEdition> = {}) => {
|
const createWrapper = (detail: Partial<ShortUrlDetail> = {}, edition: Partial<ShortUrlEdition> = {}) => {
|
||||||
const EditSHortUrl = createEditShortUrl(ShortUrlForm);
|
const EditSHortUrl = createEditShortUrl(ShortUrlForm);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { SimpleCard } from '../../src/utils/SimpleCard';
|
||||||
describe('<ShortUrlForm />', () => {
|
describe('<ShortUrlForm />', () => {
|
||||||
let wrapper: ShallowWrapper;
|
let wrapper: ShallowWrapper;
|
||||||
const TagsSelector = () => null;
|
const TagsSelector = () => null;
|
||||||
const createShortUrl = jest.fn();
|
const createShortUrl = jest.fn(async () => Promise.resolve());
|
||||||
const createWrapper = (selectedServer: SelectedServer = null, mode: Mode = 'create') => {
|
const createWrapper = (selectedServer: SelectedServer = null, mode: Mode = 'create') => {
|
||||||
const ShortUrlForm = createShortUrlForm(TagsSelector, () => null);
|
const ShortUrlForm = createShortUrlForm(TagsSelector, () => null);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,12 @@ describe('<VisitsFilterDropdown />', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const createWrapper = (selected: VisitsFilter = {}, isOrphanVisits = true) => {
|
const createWrapper = (selected: VisitsFilter = {}, isOrphanVisits = true) => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<VisitsFilterDropdown isOrphanVisits={isOrphanVisits} selected={selected} onChange={onChange} />,
|
<VisitsFilterDropdown
|
||||||
|
isOrphanVisits={isOrphanVisits}
|
||||||
|
botsSupported={true}
|
||||||
|
selected={selected}
|
||||||
|
onChange={onChange}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -68,4 +73,17 @@ describe('<VisitsFilterDropdown />', () => {
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalledWith(expectedSelection);
|
expect(onChange).toHaveBeenCalledWith(expectedSelection);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not render the component when neither orphan visits or bots filtering will be displayed', () => {
|
||||||
|
const wrapper = shallow(
|
||||||
|
<VisitsFilterDropdown
|
||||||
|
isOrphanVisits={false}
|
||||||
|
botsSupported={false}
|
||||||
|
selected={{}}
|
||||||
|
onChange={onChange}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(wrapper.text()).toEqual('');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue