mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Abstracted logic to parse tags from string to array and back for the query
This commit is contained in:
parent
47d30aaa34
commit
e632c5b04f
3 changed files with 23 additions and 19 deletions
|
@ -34,7 +34,6 @@ const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator): FC<ShortUrlsFilt
|
|||
{ selectedServer, className, order, handleOrderBy },
|
||||
) => {
|
||||
const [{ search, tags, startDate, endDate, tagsMode = 'any' }, toFirstPage ] = useShortUrlsQuery();
|
||||
const selectedTags = tags?.split(',') ?? [];
|
||||
const setDates = pipe(
|
||||
({ startDate, endDate }: DateRange) => ({
|
||||
startDate: formatIsoDate(startDate) ?? undefined,
|
||||
|
@ -47,9 +46,8 @@ const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator): FC<ShortUrlsFilt
|
|||
(search) => toFirstPage({ search }),
|
||||
);
|
||||
const removeTag = pipe(
|
||||
(tag: string) => selectedTags.filter((selectedTag) => selectedTag !== tag),
|
||||
(tagsList) => tagsList.length === 0 ? undefined : tagsList.join(','),
|
||||
(tags) => toFirstPage({ tags }),
|
||||
(tag: string) => tags.filter((selectedTag) => selectedTag !== tag),
|
||||
(updateTags) => toFirstPage({ tags: updateTags }),
|
||||
);
|
||||
const canChangeTagsMode = supportsAllTagsFiltering(selectedServer);
|
||||
const toggleTagsMode = pipe(
|
||||
|
@ -80,9 +78,9 @@ const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator): FC<ShortUrlsFilt
|
|||
</div>
|
||||
</Row>
|
||||
|
||||
{selectedTags.length > 0 && (
|
||||
{tags.length > 0 && (
|
||||
<h4 className="mt-3">
|
||||
{canChangeTagsMode && selectedTags.length > 1 && (
|
||||
{canChangeTagsMode && tags.length > 1 && (
|
||||
<div className="float-end ms-2 mt-1">
|
||||
<TooltipToggleSwitch
|
||||
checked={tagsMode === 'all'}
|
||||
|
@ -94,7 +92,7 @@ const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator): FC<ShortUrlsFilt
|
|||
</div>
|
||||
)}
|
||||
<FontAwesomeIcon icon={tagsIcon} className="short-urls-filtering-bar__tags-icon me-1" />
|
||||
{selectedTags.map((tag) =>
|
||||
{tags.map((tag) =>
|
||||
<Tag colorGenerator={colorGenerator} key={tag} text={tag} clearable onClose={() => removeTag(tag)} />)}
|
||||
</h4>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { pipe } from 'ramda';
|
||||
import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { Card } from 'reactstrap';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
|
||||
|
@ -35,7 +35,6 @@ const ShortUrlsList = (
|
|||
// 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 } });
|
||||
|
@ -46,21 +45,21 @@ const ShortUrlsList = (
|
|||
const renderOrderIcon = (field: ShortUrlsOrderableFields) =>
|
||||
<TableOrderIcon currentOrder={actualOrderBy} field={field} />;
|
||||
const addTag = pipe(
|
||||
(newTag: string) => [ ...new Set([ ...selectedTags, newTag ]) ].join(','),
|
||||
(tags) => toFirstPage({ tags }),
|
||||
(newTag: string) => [ ...new Set([ ...tags, newTag ]) ],
|
||||
(updatedTags) => toFirstPage({ tags: updatedTags }),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
listShortUrls({
|
||||
page,
|
||||
searchTerm: search,
|
||||
tags: selectedTags,
|
||||
tags,
|
||||
startDate,
|
||||
endDate,
|
||||
orderBy: actualOrderBy,
|
||||
tagsMode,
|
||||
});
|
||||
}, [ page, search, selectedTags, startDate, endDate, actualOrderBy, tagsMode ]);
|
||||
}, [ page, search, tags, startDate, endDate, actualOrderBy, tagsMode ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -14,7 +14,6 @@ export interface ShortUrlListRouteParams {
|
|||
}
|
||||
|
||||
interface ShortUrlsQueryCommon {
|
||||
tags?: string;
|
||||
search?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
|
@ -23,10 +22,12 @@ interface ShortUrlsQueryCommon {
|
|||
|
||||
interface ShortUrlsQuery extends ShortUrlsQueryCommon {
|
||||
orderBy?: string;
|
||||
tags?: string;
|
||||
}
|
||||
|
||||
interface ShortUrlsFiltering extends ShortUrlsQueryCommon {
|
||||
orderBy?: ShortUrlsOrder;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export const useShortUrlsQuery = (): [ShortUrlsFiltering, ToFirstPage] => {
|
||||
|
@ -37,16 +38,22 @@ export const useShortUrlsQuery = (): [ShortUrlsFiltering, ToFirstPage] => {
|
|||
const query = useMemo(
|
||||
pipe(
|
||||
() => parseQuery<ShortUrlsQuery>(location.search),
|
||||
({ orderBy, ...rest }: ShortUrlsQuery): ShortUrlsFiltering => !orderBy ? rest : {
|
||||
...rest,
|
||||
orderBy: stringToOrder<ShortUrlsOrderableFields>(orderBy),
|
||||
({ orderBy, tags, ...rest }: ShortUrlsQuery): ShortUrlsFiltering => {
|
||||
const parsedOrderBy = orderBy ? stringToOrder<ShortUrlsOrderableFields>(orderBy) : undefined;
|
||||
const parsedTags = tags?.split(',') ?? [];
|
||||
|
||||
return { ...rest, orderBy: parsedOrderBy, tags: parsedTags };
|
||||
},
|
||||
),
|
||||
[ location.search ],
|
||||
);
|
||||
const toFirstPageWithExtra = (extra: Partial<ShortUrlsFiltering>) => {
|
||||
const { orderBy, ...mergedQuery } = { ...query, ...extra };
|
||||
const normalizedQuery: ShortUrlsQuery = { ...mergedQuery, orderBy: orderBy && orderToString(orderBy) };
|
||||
const { orderBy, tags, ...mergedQuery } = { ...query, ...extra };
|
||||
const normalizedQuery: ShortUrlsQuery = {
|
||||
...mergedQuery,
|
||||
orderBy: orderBy && orderToString(orderBy),
|
||||
tags: tags.length > 0 ? tags.join(',') : undefined,
|
||||
};
|
||||
const evolvedQuery = stringifyQuery(normalizedQuery);
|
||||
const queryString = isEmpty(evolvedQuery) ? '' : `?${evolvedQuery}`;
|
||||
|
||||
|
|
Loading…
Reference in a new issue