2020-08-30 20:45:17 +03:00
|
|
|
import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
2020-12-07 13:17:19 +03:00
|
|
|
import { head, keys, values } from 'ramda';
|
2020-11-14 00:44:26 +03:00
|
|
|
import { FC, useEffect, useState } from 'react';
|
2020-09-04 20:05:41 +03:00
|
|
|
import { RouteComponentProps } from 'react-router';
|
2020-08-30 20:45:17 +03:00
|
|
|
import SortingDropdown from '../utils/SortingDropdown';
|
|
|
|
import { determineOrderDir, OrderDir } from '../utils/utils';
|
|
|
|
import { SelectedServer } from '../servers/data';
|
2020-09-06 20:41:15 +03:00
|
|
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
2020-12-20 21:28:09 +03:00
|
|
|
import { parseQuery } from '../utils/helpers/query';
|
2020-08-30 20:45:17 +03:00
|
|
|
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
2020-09-12 18:59:58 +03:00
|
|
|
import { OrderableFields, ShortUrlsListParams, SORTABLE_FIELDS } from './reducers/shortUrlsListParams';
|
2020-12-07 13:17:19 +03:00
|
|
|
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
2020-08-30 20:45:17 +03:00
|
|
|
import './ShortUrlsList.scss';
|
|
|
|
|
|
|
|
interface RouteParams {
|
|
|
|
page: string;
|
|
|
|
serverId: string;
|
|
|
|
}
|
|
|
|
|
2020-12-07 13:17:19 +03:00
|
|
|
export interface ShortUrlsListProps extends RouteComponentProps<RouteParams> {
|
2020-08-30 20:45:17 +03:00
|
|
|
selectedServer: SelectedServer;
|
2020-12-07 13:17:19 +03:00
|
|
|
shortUrlsList: ShortUrlsListState;
|
2020-08-30 20:45:17 +03:00
|
|
|
listShortUrls: (params: ShortUrlsListParams) => void;
|
|
|
|
shortUrlsListParams: ShortUrlsListParams;
|
|
|
|
resetShortUrlParams: () => void;
|
|
|
|
}
|
|
|
|
|
2020-12-07 13:17:19 +03:00
|
|
|
const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>) => boundToMercureHub(({
|
2020-08-30 20:45:17 +03:00
|
|
|
listShortUrls,
|
|
|
|
resetShortUrlParams,
|
|
|
|
shortUrlsListParams,
|
|
|
|
match,
|
|
|
|
location,
|
|
|
|
shortUrlsList,
|
|
|
|
selectedServer,
|
2020-12-07 13:17:19 +03:00
|
|
|
}: ShortUrlsListProps) => {
|
2020-08-30 20:45:17 +03:00
|
|
|
const { orderBy } = shortUrlsListParams;
|
|
|
|
const [ order, setOrder ] = useState<{ orderField?: OrderableFields; orderDir?: OrderDir }>({
|
|
|
|
orderField: orderBy && (head(keys(orderBy)) as OrderableFields),
|
|
|
|
orderDir: orderBy && head(values(orderBy)),
|
|
|
|
});
|
|
|
|
const refreshList = (extraParams: ShortUrlsListParams) => listShortUrls({ ...shortUrlsListParams, ...extraParams });
|
2020-08-31 19:38:27 +03:00
|
|
|
const handleOrderBy = (orderField?: OrderableFields, orderDir?: OrderDir) => {
|
2020-08-30 20:45:17 +03:00
|
|
|
setOrder({ orderField, orderDir });
|
2020-08-31 19:38:27 +03:00
|
|
|
refreshList({ orderBy: orderField ? { [orderField]: orderDir } : undefined });
|
2020-08-30 20:45:17 +03:00
|
|
|
};
|
|
|
|
const orderByColumn = (field: OrderableFields) => () =>
|
|
|
|
handleOrderBy(field, determineOrderDir(field, order.orderField, order.orderDir));
|
|
|
|
const renderOrderIcon = (field: OrderableFields) => {
|
|
|
|
if (order.orderField !== field) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!order.orderDir) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<FontAwesomeIcon
|
|
|
|
icon={order.orderDir === 'ASC' ? caretUpIcon : caretDownIcon}
|
|
|
|
className="short-urls-list__header-icon"
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
2020-12-20 21:28:09 +03:00
|
|
|
const { tag } = parseQuery<{ tag?: string }>(location.search);
|
|
|
|
const tags = tag ? [ tag ] : shortUrlsListParams.tags;
|
2020-08-30 20:45:17 +03:00
|
|
|
|
2020-12-07 13:17:19 +03:00
|
|
|
refreshList({ page: match.params.page, tags, itemsPerPage: undefined });
|
2020-08-30 20:45:17 +03:00
|
|
|
|
|
|
|
return resetShortUrlParams;
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return (
|
2020-11-14 00:44:26 +03:00
|
|
|
<>
|
2020-08-30 20:45:17 +03:00
|
|
|
<div className="d-block d-md-none mb-3">
|
|
|
|
<SortingDropdown
|
|
|
|
items={SORTABLE_FIELDS}
|
|
|
|
orderField={order.orderField}
|
|
|
|
orderDir={order.orderDir}
|
|
|
|
onChange={handleOrderBy}
|
|
|
|
/>
|
|
|
|
</div>
|
2020-12-07 13:17:19 +03:00
|
|
|
<ShortUrlsTable
|
|
|
|
orderByColumn={orderByColumn}
|
|
|
|
renderOrderIcon={renderOrderIcon}
|
|
|
|
selectedServer={selectedServer}
|
|
|
|
shortUrlsList={shortUrlsList}
|
2020-12-20 11:09:22 +03:00
|
|
|
onTagClick={(tag) => refreshList({ tags: [ ...shortUrlsListParams.tags ?? [], tag ] })}
|
2020-12-07 13:17:19 +03:00
|
|
|
/>
|
2020-11-14 00:44:26 +03:00
|
|
|
</>
|
2020-08-30 20:45:17 +03:00
|
|
|
);
|
2020-09-06 20:41:15 +03:00
|
|
|
}, () => 'https://shlink.io/new-visit');
|
2020-08-30 20:45:17 +03:00
|
|
|
|
|
|
|
export default ShortUrlsList;
|