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

87 lines
3.6 KiB
TypeScript
Raw Normal View History

import { pipe } from 'ramda';
2021-11-09 01:41:17 +03:00
import { FC, useEffect, useMemo, useState } from 'react';
import { Card } from 'reactstrap';
import { useLocation, useParams } from 'react-router-dom';
import { OrderingDropdown } from '../utils/OrderingDropdown';
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 } from '../api/types';
import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings';
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
import { ShortUrlsTableProps } from './ShortUrlsTable';
import Paginator from './Paginator';
2022-02-06 22:07:18 +03:00
import { useShortUrlsQuery } from './helpers/hooks';
import { ShortUrlsOrderableFields, SHORT_URLS_ORDERABLE_FIELDS } from './data';
import { ShortUrlsFilteringProps } from './ShortUrlsFilteringBar';
2022-02-06 22:07:18 +03:00
interface ShortUrlsListProps {
selectedServer: SelectedServer;
shortUrlsList: ShortUrlsListState;
listShortUrls: (params: ShlinkShortUrlsListParams) => void;
settings: Settings;
}
const ShortUrlsList = (
ShortUrlsTable: FC<ShortUrlsTableProps>,
ShortUrlsFilteringBar: FC<ShortUrlsFilteringProps>,
) => 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();
2022-02-08 21:40:51 +03:00
const [{ tags, search, startDate, endDate, orderBy, tagsMode }, toFirstPage ] = useShortUrlsQuery();
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 selectedTags = useMemo(() => tags?.split(',') ?? [], [ tags ]);
const { pagination } = shortUrlsList?.shortUrls ?? {};
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(
(newTag: string) => [ ...new Set([ ...selectedTags, newTag ]) ].join(','),
2021-11-09 01:41:17 +03:00
(tags) => toFirstPage({ tags }),
);
useEffect(() => {
listShortUrls({
2022-02-06 22:07:18 +03:00
page,
searchTerm: search,
tags: selectedTags,
startDate,
endDate,
orderBy: actualOrderBy,
tagsMode,
});
2022-02-08 21:40:51 +03:00
}, [ page, search, selectedTags, startDate, endDate, actualOrderBy, tagsMode ]);
return (
2020-11-14 00:44:26 +03:00
<>
<ShortUrlsFilteringBar selectedServer={selectedServer} className="mb-3" />
<div className="d-block d-lg-none mb-3">
<OrderingDropdown items={SHORT_URLS_ORDERABLE_FIELDS} order={actualOrderBy} onChange={handleOrderBy} />
</div>
<Card body className="pb-1">
<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
</>
);
}, () => [ Topics.visits ]);
export default ShortUrlsList;