shlink-web-client/src/short-urls/ShortUrlsList.tsx

96 lines
3.9 KiB
TypeScript
Raw Normal View History

import { pipe } from 'ramda';
import { useEffect, useState } from 'react';
import { Card } from 'reactstrap';
import { useLocation, useParams } from 'react-router-dom';
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
import { getServerId, SelectedServer } from '../servers/data';
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
import { Topics } from '../mercure/helpers/Topics';
import { TableOrderIcon } from '../utils/table/TableOrderIcon';
import { ShlinkShortUrlsListParams, ShlinkShortUrlsOrder } from '../api/types';
import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings';
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
import { ShortUrlsTableType } from './ShortUrlsTable';
import { Paginator } from './Paginator';
2022-02-06 22:07:18 +03:00
import { useShortUrlsQuery } from './helpers/hooks';
import { ShortUrlsOrder, ShortUrlsOrderableFields } from './data';
import { ShortUrlsFilteringBarType } from './ShortUrlsFilteringBar';
import { supportsExcludeBotsOnShortUrls } from '../utils/helpers/features';
2022-02-06 22:07:18 +03:00
interface ShortUrlsListProps {
selectedServer: SelectedServer;
shortUrlsList: ShortUrlsListState;
listShortUrls: (params: ShlinkShortUrlsListParams) => void;
settings: Settings;
}
export const ShortUrlsList = (
ShortUrlsTable: ShortUrlsTableType,
ShortUrlsFilteringBar: ShortUrlsFilteringBarType,
) => boundToMercureHub(({ listShortUrls, shortUrlsList, selectedServer, settings }: ShortUrlsListProps) => {
2021-11-09 01:41:17 +03:00
const serverId = getServerId(selectedServer);
2022-02-06 22:07:18 +03:00
const { page } = useParams();
const location = useLocation();
const [{ tags, search, startDate, endDate, orderBy, tagsMode, excludeBots }, toFirstPage] = useShortUrlsQuery();
2022-03-26 14:17:42 +03:00
const [actualOrderBy, setActualOrderBy] = useState(
// This separated state handling is needed to be able to fall back to settings value, but only once when loaded
orderBy ?? settings.shortUrlsList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING,
);
const { pagination } = shortUrlsList?.shortUrls ?? {};
const doExcludeBots = excludeBots ?? settings.visits?.excludeBots;
const handleOrderBy = (field?: ShortUrlsOrderableFields, dir?: OrderDir) => {
toFirstPage({ orderBy: { field, dir } });
setActualOrderBy({ field, dir });
};
const orderByColumn = (field: ShortUrlsOrderableFields) => () =>
handleOrderBy(field, determineOrderDir(field, actualOrderBy.field, actualOrderBy.dir));
const renderOrderIcon = (field: ShortUrlsOrderableFields) =>
<TableOrderIcon currentOrder={actualOrderBy} field={field} />;
2021-11-09 01:41:17 +03:00
const addTag = pipe(
2022-03-26 14:17:42 +03:00
(newTag: string) => [...new Set([...tags, newTag])],
(updatedTags) => toFirstPage({ tags: updatedTags }),
2021-11-09 01:41:17 +03:00
);
const parseOrderByForShlink = ({ field, dir }: ShortUrlsOrder): ShlinkShortUrlsOrder => {
if (supportsExcludeBotsOnShortUrls(selectedServer) && doExcludeBots && field === 'visits') {
return { field: 'nonBotVisits', dir };
}
return { field, dir };
};
useEffect(() => {
listShortUrls({
2022-02-06 22:07:18 +03:00
page,
searchTerm: search,
tags,
startDate,
endDate,
orderBy: parseOrderByForShlink(actualOrderBy),
tagsMode,
});
}, [page, search, tags, startDate, endDate, actualOrderBy.field, actualOrderBy.dir, tagsMode]);
return (
2020-11-14 00:44:26 +03:00
<>
<ShortUrlsFilteringBar
selectedServer={selectedServer}
2022-03-13 20:56:42 +03:00
shortUrlsAmount={shortUrlsList.shortUrls?.pagination.totalItems}
order={actualOrderBy}
handleOrderBy={handleOrderBy}
settings={settings}
className="mb-3"
/>
<Card body className="pb-0">
<ShortUrlsTable
selectedServer={selectedServer}
shortUrlsList={shortUrlsList}
2021-11-09 01:41:17 +03:00
orderByColumn={orderByColumn}
renderOrderIcon={renderOrderIcon}
onTagClick={addTag}
/>
2021-11-09 01:41:17 +03:00
<Paginator paginator={pagination} serverId={serverId} currentQueryString={location.search} />
</Card>
2020-11-14 00:44:26 +03:00
</>
);
2022-03-26 14:17:42 +03:00
}, () => [Topics.visits]);