2021-12-24 15:14:13 +03:00
|
|
|
import { pipe } from 'ramda';
|
2022-12-18 12:12:34 +03:00
|
|
|
import { useEffect, useState } from 'react';
|
2022-02-08 00:17:57 +03:00
|
|
|
import { useLocation, useParams } from 'react-router-dom';
|
2023-02-18 13:11:01 +03:00
|
|
|
import { Card } from 'reactstrap';
|
2023-07-16 09:47:10 +03:00
|
|
|
import type { ShlinkShortUrlsListParams, ShlinkShortUrlsOrder } from '../../api/types';
|
|
|
|
import type { SelectedServer } from '../../servers/data';
|
|
|
|
import { getServerId } from '../../servers/data';
|
|
|
|
import type { Settings } from '../../settings/reducers/settings';
|
|
|
|
import { DEFAULT_SHORT_URLS_ORDERING } from '../../settings/reducers/settings';
|
|
|
|
import type { OrderDir } from '../../utils/helpers/ordering';
|
|
|
|
import { determineOrderDir } from '../../utils/helpers/ordering';
|
|
|
|
import { TableOrderIcon } from '../../utils/table/TableOrderIcon';
|
2023-07-23 11:14:58 +03:00
|
|
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
|
|
|
import { Topics } from '../mercure/helpers/Topics';
|
2023-07-16 23:54:49 +03:00
|
|
|
import { useFeature } from '../utils/features';
|
2023-02-18 12:40:37 +03:00
|
|
|
import type { ShortUrlsOrder, ShortUrlsOrderableFields } from './data';
|
2023-02-18 13:11:01 +03:00
|
|
|
import { useShortUrlsQuery } from './helpers/hooks';
|
|
|
|
import { Paginator } from './Paginator';
|
|
|
|
import type { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
2023-02-18 12:40:37 +03:00
|
|
|
import type { ShortUrlsFilteringBarType } from './ShortUrlsFilteringBar';
|
2023-02-18 13:11:01 +03:00
|
|
|
import type { ShortUrlsTableType } from './ShortUrlsTable';
|
2020-08-30 20:45:17 +03:00
|
|
|
|
2022-02-06 22:07:18 +03:00
|
|
|
interface ShortUrlsListProps {
|
2020-08-30 20:45:17 +03:00
|
|
|
selectedServer: SelectedServer;
|
2020-12-07 13:17:19 +03:00
|
|
|
shortUrlsList: ShortUrlsListState;
|
2021-12-24 15:14:13 +03:00
|
|
|
listShortUrls: (params: ShlinkShortUrlsListParams) => void;
|
|
|
|
settings: Settings;
|
2020-08-30 20:45:17 +03:00
|
|
|
}
|
|
|
|
|
2022-05-28 12:16:59 +03:00
|
|
|
export const ShortUrlsList = (
|
2022-12-18 12:12:34 +03:00
|
|
|
ShortUrlsTable: ShortUrlsTableType,
|
|
|
|
ShortUrlsFilteringBar: ShortUrlsFilteringBarType,
|
2022-03-12 22:51:30 +03:00
|
|
|
) => 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();
|
2022-02-08 00:17:57 +03:00
|
|
|
const location = useLocation();
|
2022-12-29 21:03:17 +03:00
|
|
|
const [filter, toFirstPage] = useShortUrlsQuery();
|
|
|
|
const {
|
|
|
|
tags,
|
|
|
|
search,
|
|
|
|
startDate,
|
|
|
|
endDate,
|
|
|
|
orderBy,
|
|
|
|
tagsMode,
|
|
|
|
excludeBots,
|
|
|
|
excludePastValidUntil,
|
|
|
|
excludeMaxVisitsReached,
|
|
|
|
} = filter;
|
2022-03-26 14:17:42 +03:00
|
|
|
const [actualOrderBy, setActualOrderBy] = useState(
|
2021-12-25 21:51:25 +03:00
|
|
|
// 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,
|
|
|
|
);
|
2020-12-25 13:15:49 +03:00
|
|
|
const { pagination } = shortUrlsList?.shortUrls ?? {};
|
2022-12-23 22:15:52 +03:00
|
|
|
const doExcludeBots = excludeBots ?? settings.visits?.excludeBots;
|
2023-07-16 23:54:49 +03:00
|
|
|
const supportsExcludingBots = useFeature('excludeBotsOnShortUrls');
|
2021-12-25 21:51:25 +03:00
|
|
|
const handleOrderBy = (field?: ShortUrlsOrderableFields, dir?: OrderDir) => {
|
|
|
|
toFirstPage({ orderBy: { field, dir } });
|
|
|
|
setActualOrderBy({ field, dir });
|
|
|
|
};
|
2021-12-25 12:24:37 +03:00
|
|
|
const orderByColumn = (field: ShortUrlsOrderableFields) => () =>
|
2021-12-25 21:51:25 +03:00
|
|
|
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])],
|
2022-03-13 13:14:30 +03:00
|
|
|
(updatedTags) => toFirstPage({ tags: updatedTags }),
|
2021-11-09 01:41:17 +03:00
|
|
|
);
|
2022-12-22 20:07:44 +03:00
|
|
|
const parseOrderByForShlink = ({ field, dir }: ShortUrlsOrder): ShlinkShortUrlsOrder => {
|
2023-03-11 12:33:03 +03:00
|
|
|
if (supportsExcludingBots && doExcludeBots && field === 'visits') {
|
2022-12-22 20:07:44 +03:00
|
|
|
return { field: 'nonBotVisits', dir };
|
|
|
|
}
|
|
|
|
|
|
|
|
return { field, dir };
|
|
|
|
};
|
2020-08-30 20:45:17 +03:00
|
|
|
|
|
|
|
useEffect(() => {
|
2021-12-24 15:14:13 +03:00
|
|
|
listShortUrls({
|
2022-02-06 22:07:18 +03:00
|
|
|
page,
|
2021-12-24 15:14:13 +03:00
|
|
|
searchTerm: search,
|
2022-03-13 13:14:30 +03:00
|
|
|
tags,
|
2021-12-24 15:14:13 +03:00
|
|
|
startDate,
|
|
|
|
endDate,
|
2022-12-22 20:07:44 +03:00
|
|
|
orderBy: parseOrderByForShlink(actualOrderBy),
|
2022-01-31 12:15:25 +03:00
|
|
|
tagsMode,
|
2022-12-29 21:03:17 +03:00
|
|
|
excludePastValidUntil,
|
|
|
|
excludeMaxVisitsReached,
|
2021-12-24 15:14:13 +03:00
|
|
|
});
|
2022-12-29 21:03:17 +03:00
|
|
|
}, [
|
|
|
|
page,
|
|
|
|
search,
|
|
|
|
tags,
|
|
|
|
startDate,
|
|
|
|
endDate,
|
|
|
|
actualOrderBy.field,
|
|
|
|
actualOrderBy.dir,
|
|
|
|
tagsMode,
|
|
|
|
excludePastValidUntil,
|
|
|
|
excludeMaxVisitsReached,
|
|
|
|
]);
|
2020-08-30 20:45:17 +03:00
|
|
|
|
|
|
|
return (
|
2020-11-14 00:44:26 +03:00
|
|
|
<>
|
2022-03-13 12:32:27 +03:00
|
|
|
<ShortUrlsFilteringBar
|
2022-03-13 20:56:42 +03:00
|
|
|
shortUrlsAmount={shortUrlsList.shortUrls?.pagination.totalItems}
|
2022-03-13 12:32:27 +03:00
|
|
|
order={actualOrderBy}
|
|
|
|
handleOrderBy={handleOrderBy}
|
2022-12-23 22:15:52 +03:00
|
|
|
settings={settings}
|
2022-03-13 12:32:27 +03:00
|
|
|
className="mb-3"
|
|
|
|
/>
|
2022-12-18 12:12:34 +03:00
|
|
|
<Card body className="pb-0">
|
2020-12-25 13:15:49 +03:00
|
|
|
<ShortUrlsTable
|
|
|
|
selectedServer={selectedServer}
|
|
|
|
shortUrlsList={shortUrlsList}
|
2021-11-09 01:41:17 +03:00
|
|
|
orderByColumn={orderByColumn}
|
|
|
|
renderOrderIcon={renderOrderIcon}
|
|
|
|
onTagClick={addTag}
|
2020-12-25 13:15:49 +03:00
|
|
|
/>
|
2021-11-09 01:41:17 +03:00
|
|
|
<Paginator paginator={pagination} serverId={serverId} currentQueryString={location.search} />
|
2020-12-25 13:15:49 +03:00
|
|
|
</Card>
|
2020-11-14 00:44:26 +03:00
|
|
|
</>
|
2020-08-30 20:45:17 +03:00
|
|
|
);
|
2022-03-26 14:17:42 +03:00
|
|
|
}, () => [Topics.visits]);
|