mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Exported some specific component types and improved spacing in short URLs list
This commit is contained in:
parent
f4cf4850a3
commit
90837546ab
9 changed files with 33 additions and 22 deletions
|
@ -4,7 +4,7 @@ import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { ITEMS_IN_OVERVIEW_PAGE, ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
|
import { ITEMS_IN_OVERVIEW_PAGE, ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
|
||||||
import { prettify } from '../utils/helpers/numbers';
|
import { prettify } from '../utils/helpers/numbers';
|
||||||
import { TagsList } from '../tags/reducers/tagsList';
|
import { TagsList } from '../tags/reducers/tagsList';
|
||||||
import { ShortUrlsTableProps } from '../short-urls/ShortUrlsTable';
|
import { ShortUrlsTableType } from '../short-urls/ShortUrlsTable';
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import { CreateShortUrlProps } from '../short-urls/CreateShortUrl';
|
import { CreateShortUrlProps } from '../short-urls/CreateShortUrl';
|
||||||
import { VisitsOverview } from '../visits/reducers/visitsOverview';
|
import { VisitsOverview } from '../visits/reducers/visitsOverview';
|
||||||
|
@ -25,7 +25,7 @@ interface OverviewConnectProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Overview = (
|
export const Overview = (
|
||||||
ShortUrlsTable: FC<ShortUrlsTableProps>,
|
ShortUrlsTable: ShortUrlsTableType,
|
||||||
CreateShortUrl: FC<CreateShortUrlProps>,
|
CreateShortUrl: FC<CreateShortUrlProps>,
|
||||||
) => boundToMercureHub(({
|
) => boundToMercureHub(({
|
||||||
shortUrlsList,
|
shortUrlsList,
|
||||||
|
|
|
@ -21,7 +21,7 @@ export const Paginator = ({ paginator, serverId, currentQueryString = '' }: Pagi
|
||||||
`/server/${serverId}/list-short-urls/${pageNumber}${currentQueryString}`;
|
`/server/${serverId}/list-short-urls/${pageNumber}${currentQueryString}`;
|
||||||
|
|
||||||
if (pagesCount <= 1) {
|
if (pagesCount <= 1) {
|
||||||
return null;
|
return <div className="pb-3" />; // Return some space
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderPages = () =>
|
const renderPages = () =>
|
||||||
|
@ -38,7 +38,7 @@ export const Paginator = ({ paginator, serverId, currentQueryString = '' }: Pagi
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pagination className="sticky-card-paginator" listClassName="flex-wrap justify-content-center mb-0">
|
<Pagination className="sticky-card-paginator py-3" listClassName="flex-wrap justify-content-center mb-0">
|
||||||
<PaginationItem disabled={currentPage === 1}>
|
<PaginationItem disabled={currentPage === 1}>
|
||||||
<PaginationLink previous tag={Link} to={urlForPage(currentPage - 1)} />
|
<PaginationLink previous tag={Link} to={urlForPage(currentPage - 1)} />
|
||||||
</PaginationItem>
|
</PaginationItem>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { ExportShortUrlsBtnProps } from './helpers/ExportShortUrlsBtn';
|
||||||
import { TagsSelectorProps } from '../tags/helpers/TagsSelector';
|
import { TagsSelectorProps } from '../tags/helpers/TagsSelector';
|
||||||
import './ShortUrlsFilteringBar.scss';
|
import './ShortUrlsFilteringBar.scss';
|
||||||
|
|
||||||
export interface ShortUrlsFilteringProps {
|
interface ShortUrlsFilteringProps {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
order: ShortUrlsOrder;
|
order: ShortUrlsOrder;
|
||||||
handleOrderBy: (orderField?: ShortUrlsOrderableFields, orderDir?: OrderDir) => void;
|
handleOrderBy: (orderField?: ShortUrlsOrderableFields, orderDir?: OrderDir) => void;
|
||||||
|
@ -90,3 +90,5 @@ export const ShortUrlsFilteringBar = (
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ShortUrlsFilteringBarType = ReturnType<typeof ShortUrlsFilteringBar>;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { pipe } from 'ramda';
|
import { pipe } from 'ramda';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Card } from 'reactstrap';
|
import { Card } from 'reactstrap';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
|
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
|
||||||
|
@ -10,11 +10,11 @@ import { TableOrderIcon } from '../utils/table/TableOrderIcon';
|
||||||
import { ShlinkShortUrlsListParams } from '../api/types';
|
import { ShlinkShortUrlsListParams } from '../api/types';
|
||||||
import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings';
|
import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings';
|
||||||
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
||||||
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
import { ShortUrlsTableType } from './ShortUrlsTable';
|
||||||
import { Paginator } from './Paginator';
|
import { Paginator } from './Paginator';
|
||||||
import { useShortUrlsQuery } from './helpers/hooks';
|
import { useShortUrlsQuery } from './helpers/hooks';
|
||||||
import { ShortUrlsOrderableFields } from './data';
|
import { ShortUrlsOrderableFields } from './data';
|
||||||
import { ShortUrlsFilteringProps } from './ShortUrlsFilteringBar';
|
import { ShortUrlsFilteringBarType } from './ShortUrlsFilteringBar';
|
||||||
|
|
||||||
interface ShortUrlsListProps {
|
interface ShortUrlsListProps {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
|
@ -24,8 +24,8 @@ interface ShortUrlsListProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShortUrlsList = (
|
export const ShortUrlsList = (
|
||||||
ShortUrlsTable: FC<ShortUrlsTableProps>,
|
ShortUrlsTable: ShortUrlsTableType,
|
||||||
ShortUrlsFilteringBar: FC<ShortUrlsFilteringProps>,
|
ShortUrlsFilteringBar: ShortUrlsFilteringBarType,
|
||||||
) => boundToMercureHub(({ listShortUrls, shortUrlsList, selectedServer, settings }: ShortUrlsListProps) => {
|
) => boundToMercureHub(({ listShortUrls, shortUrlsList, selectedServer, settings }: ShortUrlsListProps) => {
|
||||||
const serverId = getServerId(selectedServer);
|
const serverId = getServerId(selectedServer);
|
||||||
const { page } = useParams();
|
const { page } = useParams();
|
||||||
|
@ -70,7 +70,7 @@ export const ShortUrlsList = (
|
||||||
handleOrderBy={handleOrderBy}
|
handleOrderBy={handleOrderBy}
|
||||||
className="mb-3"
|
className="mb-3"
|
||||||
/>
|
/>
|
||||||
<Card body className="pb-1">
|
<Card body className="pb-0">
|
||||||
<ShortUrlsTable
|
<ShortUrlsTable
|
||||||
selectedServer={selectedServer}
|
selectedServer={selectedServer}
|
||||||
shortUrlsList={shortUrlsList}
|
shortUrlsList={shortUrlsList}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
.short-urls-table.short-urls-table {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.short-urls-table__header-cell--with-action {
|
.short-urls-table__header-cell--with-action {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { FC, ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { SelectedServer } from '../servers/data';
|
import { SelectedServer } from '../servers/data';
|
||||||
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
||||||
import { ShortUrlsRowProps } from './helpers/ShortUrlsRow';
|
import { ShortUrlsRowType } from './helpers/ShortUrlsRow';
|
||||||
import { ShortUrlsOrderableFields } from './data';
|
import { ShortUrlsOrderableFields } from './data';
|
||||||
import './ShortUrlsTable.scss';
|
import './ShortUrlsTable.scss';
|
||||||
|
|
||||||
export interface ShortUrlsTableProps {
|
interface ShortUrlsTableProps {
|
||||||
orderByColumn?: (column: ShortUrlsOrderableFields) => () => void;
|
orderByColumn?: (column: ShortUrlsOrderableFields) => () => void;
|
||||||
renderOrderIcon?: (column: ShortUrlsOrderableFields) => ReactNode;
|
renderOrderIcon?: (column: ShortUrlsOrderableFields) => ReactNode;
|
||||||
shortUrlsList: ShortUrlsListState;
|
shortUrlsList: ShortUrlsListState;
|
||||||
|
@ -16,7 +16,7 @@ export interface ShortUrlsTableProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShortUrlsTable = (ShortUrlsRow: FC<ShortUrlsRowProps>) => ({
|
export const ShortUrlsTable = (ShortUrlsRow: ShortUrlsRowType) => ({
|
||||||
orderByColumn,
|
orderByColumn,
|
||||||
renderOrderIcon,
|
renderOrderIcon,
|
||||||
shortUrlsList,
|
shortUrlsList,
|
||||||
|
@ -27,7 +27,7 @@ export const ShortUrlsTable = (ShortUrlsRow: FC<ShortUrlsRowProps>) => ({
|
||||||
const { error, loading, shortUrls } = shortUrlsList;
|
const { error, loading, shortUrls } = shortUrlsList;
|
||||||
const actionableFieldClasses = classNames({ 'short-urls-table__header-cell--with-action': !!orderByColumn });
|
const actionableFieldClasses = classNames({ 'short-urls-table__header-cell--with-action': !!orderByColumn });
|
||||||
const orderableColumnsClasses = classNames('short-urls-table__header-cell', actionableFieldClasses);
|
const orderableColumnsClasses = classNames('short-urls-table__header-cell', actionableFieldClasses);
|
||||||
const tableClasses = classNames('table table-hover responsive-table', className);
|
const tableClasses = classNames('table table-hover responsive-table short-urls-table', className);
|
||||||
|
|
||||||
const renderShortUrls = () => {
|
const renderShortUrls = () => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -90,3 +90,5 @@ export const ShortUrlsTable = (ShortUrlsRow: FC<ShortUrlsRowProps>) => ({
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ShortUrlsTableType = ReturnType<typeof ShortUrlsTable>;
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { ShortUrlVisitsCount } from './ShortUrlVisitsCount';
|
||||||
import { ShortUrlsRowMenuProps } from './ShortUrlsRowMenu';
|
import { ShortUrlsRowMenuProps } from './ShortUrlsRowMenu';
|
||||||
import './ShortUrlsRow.scss';
|
import './ShortUrlsRow.scss';
|
||||||
|
|
||||||
export interface ShortUrlsRowProps {
|
interface ShortUrlsRowProps {
|
||||||
onTagClick?: (tag: string) => void;
|
onTagClick?: (tag: string) => void;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
shortUrl: ShortUrl;
|
shortUrl: ShortUrl;
|
||||||
|
@ -89,3 +89,5 @@ export const ShortUrlsRow = (
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ShortUrlsRowType = ReturnType<typeof ShortUrlsRow>;
|
||||||
|
|
|
@ -18,9 +18,11 @@ describe('<Paginator />', () => {
|
||||||
[buildPaginator()],
|
[buildPaginator()],
|
||||||
[buildPaginator(0)],
|
[buildPaginator(0)],
|
||||||
[buildPaginator(1)],
|
[buildPaginator(1)],
|
||||||
])('renders nothing if the number of pages is below 2', (paginator) => {
|
])('renders an empty gap if the number of pages is below 2', (paginator) => {
|
||||||
const { container } = setUp(paginator);
|
const { container } = setUp(paginator);
|
||||||
expect(container.firstChild).toBeNull();
|
|
||||||
|
expect(container.firstChild).toBeEmpty();
|
||||||
|
expect(container.firstChild).toHaveClass('pb-3');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { screen } from '@testing-library/react';
|
import { screen } from '@testing-library/react';
|
||||||
import { FC } from 'react';
|
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { MemoryRouter, useNavigate } from 'react-router-dom';
|
import { MemoryRouter, useNavigate } from 'react-router-dom';
|
||||||
import { ShortUrlsList as createShortUrlsList } from '../../src/short-urls/ShortUrlsList';
|
import { ShortUrlsList as createShortUrlsList } from '../../src/short-urls/ShortUrlsList';
|
||||||
|
@ -8,7 +7,7 @@ import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub';
|
||||||
import { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList';
|
||||||
import { ReachableServer } from '../../src/servers/data';
|
import { ReachableServer } from '../../src/servers/data';
|
||||||
import { Settings } from '../../src/settings/reducers/settings';
|
import { Settings } from '../../src/settings/reducers/settings';
|
||||||
import { ShortUrlsTableProps } from '../../src/short-urls/ShortUrlsTable';
|
import { ShortUrlsTableType } from '../../src/short-urls/ShortUrlsTable';
|
||||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||||
|
|
||||||
jest.mock('react-router-dom', () => ({
|
jest.mock('react-router-dom', () => ({
|
||||||
|
@ -18,7 +17,7 @@ jest.mock('react-router-dom', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('<ShortUrlsList />', () => {
|
describe('<ShortUrlsList />', () => {
|
||||||
const ShortUrlsTable: FC<ShortUrlsTableProps> = ({ onTagClick }) => <span onClick={() => onTagClick?.('foo')}>ShortUrlsTable</span>;
|
const ShortUrlsTable: ShortUrlsTableType = ({ onTagClick }) => <span onClick={() => onTagClick?.('foo')}>ShortUrlsTable</span>;
|
||||||
const ShortUrlsFilteringBar = () => <span>ShortUrlsFilteringBar</span>;
|
const ShortUrlsFilteringBar = () => <span>ShortUrlsFilteringBar</span>;
|
||||||
const listShortUrlsMock = jest.fn();
|
const listShortUrlsMock = jest.fn();
|
||||||
const navigate = jest.fn();
|
const navigate = jest.fn();
|
||||||
|
|
Loading…
Reference in a new issue