Skip to content

Commit

Permalink
Merge pull request #524 from acelaya-forks/feature/has-rules
Browse files Browse the repository at this point in the history
Add icon in short URLs list indicating if a short URL has redirect rules
  • Loading branch information
acelaya authored Nov 29, 2024
2 parents b869c38 + db3e0d8 commit cef8a9a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
* [#514](https://github.com/shlinkio/shlink-web-component/issues/514) Allow filtering short URLs list by domain, when using Shlink 4.3 or newer.
* [#520](https://github.com/shlinkio/shlink-web-component/issues/520) Allow navigating from domains list to short URLs list filtered by one domain, when using Shlink 4.3 or newer.
* [#517](https://github.com/shlinkio/shlink-web-component/issues/517) Update list of known domains when a short URL is created with a new domain.
* [#292](https://github.com/shlinkio/shlink-web-component/issues/292) Add icon in short URLs list indicating if a short URL has redirect rules.

### Changed
* *Nothing*
Expand Down
6 changes: 3 additions & 3 deletions src/short-urls/helpers/ShortUrlDetailLink.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { FC } from 'react';
import type { FC, PropsWithChildren } from 'react';
import { Link } from 'react-router-dom';
import type { ShlinkShortUrl } from '../../api-contract';
import { useRoutesPrefix } from '../../utils/routesPrefix';
import { urlEncodeShortCode } from './index';

export type LinkSuffix = 'visits' | 'edit' | 'redirect-rules';

export type ShortUrlDetailLinkProps = {
export type ShortUrlDetailLinkProps = Record<string | number, unknown> & PropsWithChildren & {
shortUrl?: ShlinkShortUrl | null;
suffix: LinkSuffix;
asLink?: boolean;
Expand All @@ -17,7 +17,7 @@ const buildUrl = (routePrefix: string, { shortCode, domain }: ShlinkShortUrl, su
return `${routePrefix}/short-code/${urlEncodeShortCode(shortCode)}/${suffix}${query}`;
};

export const ShortUrlDetailLink: FC<ShortUrlDetailLinkProps & Record<string | number, any>> = (
export const ShortUrlDetailLink: FC<ShortUrlDetailLinkProps> = (
{ shortUrl, suffix, asLink, children, ...rest },
) => {
const routePrefix = useRoutesPrefix();
Expand Down
17 changes: 16 additions & 1 deletion src/short-urls/helpers/ShortUrlsRow.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { faArrowsSplitUpAndLeft as rulesIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import type { TimeoutToggle } from '@shlinkio/shlink-frontend-kit';
import { useEffect, useRef } from 'react';
import { ExternalLink } from 'react-external-link';
Expand All @@ -9,6 +11,7 @@ import { CopyToClipboardIcon } from '../../utils/components/CopyToClipboardIcon'
import { Time } from '../../utils/dates/Time';
import type { ColorGenerator } from '../../utils/services/ColorGenerator';
import { useShortUrlsQuery } from './hooks';
import { ShortUrlDetailLink } from './ShortUrlDetailLink';
import type { ShortUrlsRowMenuType } from './ShortUrlsRowMenu';
import { ShortUrlStatus } from './ShortUrlStatus';
import { ShortUrlVisitsCount } from './ShortUrlVisitsCount';
Expand Down Expand Up @@ -92,7 +95,19 @@ const ShortUrlsRow: FCWithDeps<ShortUrlsRowProps, ShortUrlsRowDeps> = ({ shortUr
/>
</td>
<td className="responsive-table__cell short-urls-row__cell" data-th="Status">
<ShortUrlStatus shortUrl={shortUrl} />
<div className="d-flex gap-2">
<ShortUrlStatus shortUrl={shortUrl} />
{shortUrl.hasRedirectRules && (
<ShortUrlDetailLink
asLink
shortUrl={shortUrl}
suffix="redirect-rules"
title="This short URL has dynamic redirect rules"
>
<FontAwesomeIcon icon={rulesIcon} />
</ShortUrlDetailLink>
)}
</div>
</td>
<td className="responsive-table__cell short-urls-row__cell text-end">
<ShortUrlsRowMenu shortUrl={shortUrl} />
Expand Down
25 changes: 22 additions & 3 deletions test/short-urls/helpers/ShortUrlsRow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface SetUpOptions {
meta?: ShlinkShortUrlMeta;
settings?: Partial<Settings>;
search?: string;
hasRedirectRules?: boolean;
}

describe('<ShortUrlsRow />', () => {
Expand Down Expand Up @@ -47,13 +48,15 @@ describe('<ShortUrlsRow />', () => {
useTimeoutToggle,
}));

const setUp = ({ title, tags = [], meta = {}, settings = {}, search }: SetUpOptions = {}) => renderWithEvents(
const setUp = (
{ title, tags = [], meta = {}, settings = {}, search, hasRedirectRules }: SetUpOptions = {},
) => renderWithEvents(
<MemoryRouter initialEntries={search ? [{ search }] : undefined}>
<SettingsProvider value={fromPartial(settings)}>
<table>
<tbody>
<ShortUrlsRow
shortUrl={{ ...shortUrl, title, tags, meta: { ...shortUrl.meta, ...meta } }}
shortUrl={{ ...shortUrl, title, tags, hasRedirectRules, meta: { ...shortUrl.meta, ...meta } }}
onTagClick={() => null}
/>
</tbody>
Expand All @@ -62,7 +65,10 @@ describe('<ShortUrlsRow />', () => {
</MemoryRouter>,
);

it('passes a11y checks', () => checkAccessibility(setUp()));
it.each([
{ hasRedirectRules: true },
{ hasRedirectRules: false },
])('passes a11y checks', (options) => checkAccessibility(setUp(options)));

it.each([
[null, 7],
Expand Down Expand Up @@ -159,4 +165,17 @@ describe('<ShortUrlsRow />', () => {
expectedIconClasses.forEach((expectedClass) => expect(statusIcon).toHaveClass(expectedClass));
expect(statusIcon).toMatchSnapshot();
});

it.each([
{ hasRedirectRules: true },
{ hasRedirectRules: false },
])('shows indicator when a short URL has redirect rules', ({ hasRedirectRules }) => {
setUp({ hasRedirectRules });

if (hasRedirectRules) {
expect(screen.getByTitle('This short URL has dynamic redirect rules')).toBeInTheDocument();
} else {
expect(screen.queryByTitle('This short URL has dynamic redirect rules')).not.toBeInTheDocument();
}
});
});

0 comments on commit cef8a9a

Please sign in to comment.