mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Minor changes on tags filtering for short URLs
This commit is contained in:
parent
303900756d
commit
109baef828
12 changed files with 19 additions and 68 deletions
|
@ -13,7 +13,7 @@ import './MenuLayout.scss';
|
|||
|
||||
const MenuLayout = (
|
||||
TagsList: FC,
|
||||
ShortUrls: FC,
|
||||
ShortUrlsList: FC,
|
||||
AsideMenu: FC<AsideMenuProps>,
|
||||
CreateShortUrl: FC,
|
||||
ShortUrlVisits: FC,
|
||||
|
@ -49,7 +49,7 @@ const MenuLayout = (
|
|||
<Switch>
|
||||
<Redirect exact from="/server/:serverId" to="/server/:serverId/overview" />
|
||||
<Route exact path="/server/:serverId/overview" component={Overview} />
|
||||
<Route exact path="/server/:serverId/list-short-urls/:page" component={ShortUrls} />
|
||||
<Route exact path="/server/:serverId/list-short-urls/:page" component={ShortUrlsList} />
|
||||
<Route exact path="/server/:serverId/create-short-url" component={CreateShortUrl} />
|
||||
<Route path="/server/:serverId/short-code/:shortCode/visits" component={ShortUrlVisits} />
|
||||
<Route path="/server/:serverId/short-code/:shortCode/edit" component={EditShortUrl} />
|
||||
|
|
|
@ -35,7 +35,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
|||
'MenuLayout',
|
||||
MenuLayout,
|
||||
'TagsList',
|
||||
'ShortUrls',
|
||||
'ShortUrlsList',
|
||||
'AsideMenu',
|
||||
'CreateShortUrl',
|
||||
'ShortUrlVisits',
|
||||
|
|
|
@ -36,7 +36,7 @@ const connect: ConnectDecorator = (propsFromState: string[] | null, actionServic
|
|||
provideAppServices(bottle, connect);
|
||||
provideCommonServices(bottle, connect, withRouter);
|
||||
provideApiServices(bottle);
|
||||
provideShortUrlsServices(bottle, connect);
|
||||
provideShortUrlsServices(bottle, connect, withRouter);
|
||||
provideServersServices(bottle, connect, withRouter);
|
||||
provideTagsServices(bottle, connect);
|
||||
provideVisitsServices(bottle, connect);
|
||||
|
|
|
@ -107,7 +107,7 @@ export const Overview = (
|
|||
shortUrlsList={shortUrlsList}
|
||||
selectedServer={selectedServer}
|
||||
className="mb-0"
|
||||
onTagClick={(tag) => history.push(`/server/${serverId}/list-short-urls/1?tag=${tag}`)}
|
||||
onTagClick={(tag) => history.push(`/server/${serverId}/list-short-urls/1?tags=${encodeURIComponent(tag)}`)}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import { FC, useEffect, useState } from 'react';
|
||||
import { ShortUrlsListProps } from './ShortUrlsList';
|
||||
|
||||
const ShortUrls = (SearchBar: FC, ShortUrlsList: FC<ShortUrlsListProps>) => (props: ShortUrlsListProps) => {
|
||||
const { match } = props;
|
||||
const { page = '1', serverId = '' } = match?.params ?? {};
|
||||
const [ urlsListKey, setUrlsListKey ] = useState(`${serverId}_${page}`);
|
||||
|
||||
// Using a key on a component makes react to create a new instance every time the key changes
|
||||
// Without it, pagination on the URL will not make the component to be refreshed
|
||||
useEffect(() => {
|
||||
setUrlsListKey(`${serverId}_${page}`);
|
||||
}, [ serverId, page ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="form-group"><SearchBar /></div>
|
||||
<ShortUrlsList {...props} key={urlsListKey} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShortUrls;
|
|
@ -1,5 +1,4 @@
|
|||
import Bottle from 'bottlejs';
|
||||
import ShortUrls from '../ShortUrls';
|
||||
import Bottle, { Decorator } from 'bottlejs';
|
||||
import SearchBar from '../SearchBar';
|
||||
import ShortUrlsList from '../ShortUrlsList';
|
||||
import ShortUrlsRow from '../helpers/ShortUrlsRow';
|
||||
|
@ -19,14 +18,11 @@ import { ShortUrlForm } from '../ShortUrlForm';
|
|||
import { EditShortUrl } from '../EditShortUrl';
|
||||
import { getShortUrlDetail } from '../reducers/shortUrlDetail';
|
||||
|
||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter: Decorator) => {
|
||||
// Components
|
||||
bottle.serviceFactory('ShortUrls', ShortUrls, 'SearchBar', 'ShortUrlsList');
|
||||
bottle.decorator('ShortUrls', connect([ 'shortUrlsList' ]));
|
||||
|
||||
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable');
|
||||
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable', 'SearchBar');
|
||||
bottle.decorator('ShortUrlsList', connect(
|
||||
[ 'selectedServer', 'shortUrlsListParams', 'mercureInfo' ],
|
||||
[ 'selectedServer', 'shortUrlsListParams', 'mercureInfo', 'shortUrlsList' ],
|
||||
[ 'listShortUrls', 'resetShortUrlParams', 'createNewVisits', 'loadMercureInfo' ],
|
||||
));
|
||||
|
||||
|
@ -57,6 +53,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
|||
// Services
|
||||
bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator');
|
||||
bottle.decorator('SearchBar', connect([ 'shortUrlsListParams' ], [ 'listShortUrls' ]));
|
||||
bottle.decorator('SearchBar', withRouter);
|
||||
|
||||
// Actions
|
||||
bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient');
|
||||
|
|
|
@ -61,7 +61,7 @@ const TagCard = (
|
|||
<Collapse isOpen={displayed}>
|
||||
<CardBody className="tag-card__body">
|
||||
<Link
|
||||
to={`/server/${serverId}/list-short-urls/1?tag=${encodeURIComponent(tag.tag)}`}
|
||||
to={`/server/${serverId}/list-short-urls/1?tags=${encodeURIComponent(tag.tag)}`}
|
||||
className="btn btn-outline-secondary btn-block d-flex justify-content-between align-items-center mb-1"
|
||||
>
|
||||
<span className="text-ellipsis"><FontAwesomeIcon icon={faLink} className="mr-2" />Short URLs</span>
|
||||
|
|
|
@ -32,7 +32,7 @@ export const TagsTableRow = (
|
|||
<TagBullet tag={tag.tag} colorGenerator={colorGenerator} /> {tag.tag}
|
||||
</th>
|
||||
<td className="responsive-table__cell text-lg-right" data-th="Short URLs">
|
||||
<Link to={`/server/${serverId}/list-short-urls/1?tag=${encodeURIComponent(tag.tag)}`}>
|
||||
<Link to={`/server/${serverId}/list-short-urls/1?tags=${encodeURIComponent(tag.tag)}`}>
|
||||
{prettify(tag.shortUrls)}
|
||||
</Link>
|
||||
</td>
|
||||
|
|
|
@ -12,10 +12,11 @@ interface SearchFieldProps {
|
|||
className?: string;
|
||||
large?: boolean;
|
||||
noBorder?: boolean;
|
||||
initialValue?: string;
|
||||
}
|
||||
|
||||
const SearchField = ({ onChange, className, large = true, noBorder = false }: SearchFieldProps) => {
|
||||
const [ searchTerm, setSearchTerm ] = useState('');
|
||||
const SearchField = ({ onChange, className, large = true, noBorder = false, initialValue = '' }: SearchFieldProps) => {
|
||||
const [ searchTerm, setSearchTerm ] = useState(initialValue);
|
||||
|
||||
const resetTimer = () => {
|
||||
timer && clearTimeout(timer);
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import shortUrlsCreator from '../../src/short-urls/ShortUrls';
|
||||
import { ShortUrlsListProps } from '../../src/short-urls/ShortUrlsList';
|
||||
|
||||
describe('<ShortUrls />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const SearchBar = () => null;
|
||||
const ShortUrlsList = () => null;
|
||||
|
||||
beforeEach(() => {
|
||||
const ShortUrls = shortUrlsCreator(SearchBar, ShortUrlsList);
|
||||
|
||||
wrapper = shallow(
|
||||
<ShortUrls {...Mock.all<ShortUrlsListProps>()} />,
|
||||
);
|
||||
});
|
||||
afterEach(() => wrapper.unmount());
|
||||
|
||||
it('wraps a SearchBar and ShortUrlsList', () => {
|
||||
expect(wrapper.find(SearchBar)).toHaveLength(1);
|
||||
expect(wrapper.find(ShortUrlsList)).toHaveLength(1);
|
||||
});
|
||||
});
|
|
@ -30,8 +30,8 @@ describe('<TagCard />', () => {
|
|||
afterEach(jest.resetAllMocks);
|
||||
|
||||
it.each([
|
||||
[ 'ssr', '/server/1/list-short-urls/1?tag=ssr' ],
|
||||
[ 'ssr-&-foo', '/server/1/list-short-urls/1?tag=ssr-%26-foo' ],
|
||||
[ 'ssr', '/server/1/list-short-urls/1?tags=ssr' ],
|
||||
[ 'ssr-&-foo', '/server/1/list-short-urls/1?tags=ssr-%26-foo' ],
|
||||
])('shows a TagBullet and a link to the list filtering by the tag', (tag, expectedLink) => {
|
||||
const wrapper = createWrapper(tag);
|
||||
const links = wrapper.find(Link);
|
||||
|
@ -61,7 +61,7 @@ describe('<TagCard />', () => {
|
|||
const links = wrapper.find(Link);
|
||||
|
||||
expect(links).toHaveLength(2);
|
||||
expect(links.at(0).prop('to')).toEqual('/server/1/list-short-urls/1?tag=ssr');
|
||||
expect(links.at(0).prop('to')).toEqual('/server/1/list-short-urls/1?tags=ssr');
|
||||
expect(links.at(0).text()).toContain('48');
|
||||
expect(links.at(1).prop('to')).toEqual('/server/1/tag/ssr/visits');
|
||||
expect(links.at(1).text()).toContain('23,257');
|
||||
|
|
|
@ -35,7 +35,7 @@ describe('<TagsTableRow />', () => {
|
|||
const visitsLink = links.last();
|
||||
|
||||
expect(shortUrlsLink.prop('children')).toEqual(expectedShortUrls);
|
||||
expect(shortUrlsLink.prop('to')).toEqual(`/server/abc123/list-short-urls/1?tag=${encodeURIComponent('foo&bar')}`);
|
||||
expect(shortUrlsLink.prop('to')).toEqual(`/server/abc123/list-short-urls/1?tags=${encodeURIComponent('foo&bar')}`);
|
||||
expect(visitsLink.prop('children')).toEqual(expectedVisits);
|
||||
expect(visitsLink.prop('to')).toEqual('/server/abc123/tag/foo&bar/visits');
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue