mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 17:57:26 +03:00
Renamed constants holding orderable fields for short URLs and tags
This commit is contained in:
parent
2bf5f276f5
commit
76fb45c97e
11 changed files with 41 additions and 32 deletions
|
@ -1,7 +1,7 @@
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { FormGroup } from 'reactstrap';
|
import { FormGroup } from 'reactstrap';
|
||||||
import SortingDropdown from '../utils/SortingDropdown';
|
import SortingDropdown from '../utils/SortingDropdown';
|
||||||
import { SORTABLE_FIELDS } from '../short-urls/data';
|
import { SHORT_URLS_ORDERABLE_FIELDS } from '../short-urls/data';
|
||||||
import { SimpleCard } from '../utils/SimpleCard';
|
import { SimpleCard } from '../utils/SimpleCard';
|
||||||
import { DEFAULT_SHORT_URLS_ORDERING, Settings, ShortUrlsListSettings } from './reducers/settings';
|
import { DEFAULT_SHORT_URLS_ORDERING, Settings, ShortUrlsListSettings } from './reducers/settings';
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export const ShortUrlsList: FC<ShortUrlsListProps> = ({ settings: { shortUrlsLis
|
||||||
<FormGroup className="mb-0">
|
<FormGroup className="mb-0">
|
||||||
<label>Default ordering for short URLs list:</label>
|
<label>Default ordering for short URLs list:</label>
|
||||||
<SortingDropdown
|
<SortingDropdown
|
||||||
items={SORTABLE_FIELDS}
|
items={SHORT_URLS_ORDERABLE_FIELDS}
|
||||||
order={shortUrlsList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING}
|
order={shortUrlsList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING}
|
||||||
onChange={(field, dir) => setShortUrlsListSettings({ defaultOrdering: { field, dir } })}
|
onChange={(field, dir) => setShortUrlsListSettings({ defaultOrdering: { field, dir } })}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { SimpleCard } from '../utils/SimpleCard';
|
||||||
import { TagsModeDropdown } from '../tags/TagsModeDropdown';
|
import { TagsModeDropdown } from '../tags/TagsModeDropdown';
|
||||||
import { capitalize } from '../utils/utils';
|
import { capitalize } from '../utils/utils';
|
||||||
import SortingDropdown from '../utils/SortingDropdown';
|
import SortingDropdown from '../utils/SortingDropdown';
|
||||||
import { SORTABLE_FIELDS } from '../tags/data/TagsListChildrenProps';
|
import { TAGS_ORDERABLE_FIELDS } from '../tags/data/TagsListChildrenProps';
|
||||||
import { Settings, TagsSettings } from './reducers/settings';
|
import { Settings, TagsSettings } from './reducers/settings';
|
||||||
|
|
||||||
interface TagsProps {
|
interface TagsProps {
|
||||||
|
@ -26,7 +26,7 @@ export const Tags: FC<TagsProps> = ({ settings: { tags }, setTagsSettings }) =>
|
||||||
<FormGroup className="mb-0">
|
<FormGroup className="mb-0">
|
||||||
<label>Default ordering for tags list:</label>
|
<label>Default ordering for tags list:</label>
|
||||||
<SortingDropdown
|
<SortingDropdown
|
||||||
items={SORTABLE_FIELDS}
|
items={TAGS_ORDERABLE_FIELDS}
|
||||||
order={tags?.defaultOrdering ?? {}}
|
order={tags?.defaultOrdering ?? {}}
|
||||||
onChange={(field, dir) => setTagsSettings({ ...tags, defaultOrdering: { field, dir } })}
|
onChange={(field, dir) => setTagsSettings({ ...tags, defaultOrdering: { field, dir } })}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
||||||
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
||||||
import Paginator from './Paginator';
|
import Paginator from './Paginator';
|
||||||
import { ShortUrlListRouteParams, useShortUrlsQuery } from './helpers/hooks';
|
import { ShortUrlListRouteParams, useShortUrlsQuery } from './helpers/hooks';
|
||||||
import { OrderableFields, ShortUrlsOrder, SORTABLE_FIELDS } from './data';
|
import { ShortUrlsOrderableFields, ShortUrlsOrder, SHORT_URLS_ORDERABLE_FIELDS } from './data';
|
||||||
|
|
||||||
interface ShortUrlsListProps extends RouteComponentProps<ShortUrlListRouteParams> {
|
interface ShortUrlsListProps extends RouteComponentProps<ShortUrlListRouteParams> {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
|
@ -39,10 +39,10 @@ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) =
|
||||||
const selectedTags = useMemo(() => tags?.split(',') ?? [], [ tags ]);
|
const selectedTags = useMemo(() => tags?.split(',') ?? [], [ tags ]);
|
||||||
const { pagination } = shortUrlsList?.shortUrls ?? {};
|
const { pagination } = shortUrlsList?.shortUrls ?? {};
|
||||||
|
|
||||||
const handleOrderBy = (field?: OrderableFields, dir?: OrderDir) => setOrder({ field, dir });
|
const handleOrderBy = (field?: ShortUrlsOrderableFields, dir?: OrderDir) => setOrder({ field, dir });
|
||||||
const orderByColumn = (field: OrderableFields) => () =>
|
const orderByColumn = (field: ShortUrlsOrderableFields) => () =>
|
||||||
handleOrderBy(field, determineOrderDir(field, order.field, order.dir));
|
handleOrderBy(field, determineOrderDir(field, order.field, order.dir));
|
||||||
const renderOrderIcon = (field: OrderableFields) => <TableOrderIcon currentOrder={order} field={field} />;
|
const renderOrderIcon = (field: ShortUrlsOrderableFields) => <TableOrderIcon currentOrder={order} field={field} />;
|
||||||
const addTag = pipe(
|
const addTag = pipe(
|
||||||
(newTag: string) => [ ...new Set([ ...selectedTags, newTag ]) ].join(','),
|
(newTag: string) => [ ...new Set([ ...selectedTags, newTag ]) ].join(','),
|
||||||
(tags) => toFirstPage({ tags }),
|
(tags) => toFirstPage({ tags }),
|
||||||
|
@ -64,7 +64,7 @@ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) =
|
||||||
<>
|
<>
|
||||||
<div className="mb-3"><SearchBar /></div>
|
<div className="mb-3"><SearchBar /></div>
|
||||||
<div className="d-block d-lg-none mb-3">
|
<div className="d-block d-lg-none mb-3">
|
||||||
<SortingDropdown items={SORTABLE_FIELDS} order={order} onChange={handleOrderBy} />
|
<SortingDropdown items={SHORT_URLS_ORDERABLE_FIELDS} order={order} onChange={handleOrderBy} />
|
||||||
</div>
|
</div>
|
||||||
<Card body className="pb-1">
|
<Card body className="pb-1">
|
||||||
<ShortUrlsTable
|
<ShortUrlsTable
|
||||||
|
|
|
@ -5,12 +5,12 @@ import { SelectedServer } from '../servers/data';
|
||||||
import { supportsShortUrlTitle } from '../utils/helpers/features';
|
import { supportsShortUrlTitle } from '../utils/helpers/features';
|
||||||
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
||||||
import { ShortUrlsRowProps } from './helpers/ShortUrlsRow';
|
import { ShortUrlsRowProps } from './helpers/ShortUrlsRow';
|
||||||
import { OrderableFields } from './data';
|
import { ShortUrlsOrderableFields } from './data';
|
||||||
import './ShortUrlsTable.scss';
|
import './ShortUrlsTable.scss';
|
||||||
|
|
||||||
export interface ShortUrlsTableProps {
|
export interface ShortUrlsTableProps {
|
||||||
orderByColumn?: (column: OrderableFields) => () => void;
|
orderByColumn?: (column: ShortUrlsOrderableFields) => () => void;
|
||||||
renderOrderIcon?: (column: OrderableFields) => ReactNode;
|
renderOrderIcon?: (column: ShortUrlsOrderableFields) => ReactNode;
|
||||||
shortUrlsList: ShortUrlsListState;
|
shortUrlsList: ShortUrlsListState;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
onTagClick?: (tag: string) => void;
|
onTagClick?: (tag: string) => void;
|
||||||
|
|
|
@ -52,7 +52,7 @@ export interface ShortUrlIdentifier {
|
||||||
domain: OptionalString;
|
domain: OptionalString;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SORTABLE_FIELDS = {
|
export const SHORT_URLS_ORDERABLE_FIELDS = {
|
||||||
dateCreated: 'Created at',
|
dateCreated: 'Created at',
|
||||||
shortCode: 'Short URL',
|
shortCode: 'Short URL',
|
||||||
longUrl: 'Long URL',
|
longUrl: 'Long URL',
|
||||||
|
@ -60,6 +60,6 @@ export const SORTABLE_FIELDS = {
|
||||||
visits: 'Visits',
|
visits: 'Visits',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OrderableFields = keyof typeof SORTABLE_FIELDS;
|
export type ShortUrlsOrderableFields = keyof typeof SHORT_URLS_ORDERABLE_FIELDS;
|
||||||
|
|
||||||
export type ShortUrlsOrder = Order<OrderableFields>;
|
export type ShortUrlsOrder = Order<ShortUrlsOrderableFields>;
|
||||||
|
|
|
@ -12,7 +12,12 @@ import { Settings, TagsMode } from '../settings/reducers/settings';
|
||||||
import { determineOrderDir, sortList } from '../utils/helpers/ordering';
|
import { determineOrderDir, sortList } from '../utils/helpers/ordering';
|
||||||
import SortingDropdown from '../utils/SortingDropdown';
|
import SortingDropdown from '../utils/SortingDropdown';
|
||||||
import { TagsList as TagsListState } from './reducers/tagsList';
|
import { TagsList as TagsListState } from './reducers/tagsList';
|
||||||
import { OrderableFields, SORTABLE_FIELDS, TagsListChildrenProps, TagsOrder } from './data/TagsListChildrenProps';
|
import {
|
||||||
|
TagsOrderableFields,
|
||||||
|
TAGS_ORDERABLE_FIELDS,
|
||||||
|
TagsListChildrenProps,
|
||||||
|
TagsOrder,
|
||||||
|
} from './data/TagsListChildrenProps';
|
||||||
import { TagsModeDropdown } from './TagsModeDropdown';
|
import { TagsModeDropdown } from './TagsModeDropdown';
|
||||||
import { NormalizedTag } from './data';
|
import { NormalizedTag } from './data';
|
||||||
import { TagsTableProps } from './TagsTable';
|
import { TagsTableProps } from './TagsTable';
|
||||||
|
@ -55,7 +60,7 @@ const TagsList = (TagsCards: FC<TagsListChildrenProps>, TagsTable: FC<TagsTableP
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const orderByColumn = (field: OrderableFields) => () => {
|
const orderByColumn = (field: TagsOrderableFields) => () => {
|
||||||
const dir = determineOrderDir(field, order.field, order.dir);
|
const dir = determineOrderDir(field, order.field, order.dir);
|
||||||
|
|
||||||
setOrder({ field: dir ? field : undefined, dir });
|
setOrder({ field: dir ? field : undefined, dir });
|
||||||
|
@ -88,7 +93,11 @@ const TagsList = (TagsCards: FC<TagsListChildrenProps>, TagsTable: FC<TagsTableP
|
||||||
<TagsModeDropdown mode={mode} onChange={setMode} />
|
<TagsModeDropdown mode={mode} onChange={setMode} />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6 mt-3 mt-lg-0">
|
<div className="col-lg-6 mt-3 mt-lg-0">
|
||||||
<SortingDropdown items={SORTABLE_FIELDS} order={order} onChange={(field, dir) => setOrder({ field, dir })} />
|
<SortingDropdown
|
||||||
|
items={TAGS_ORDERABLE_FIELDS}
|
||||||
|
order={order}
|
||||||
|
onChange={(field, dir) => setOrder({ field, dir })}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
|
|
|
@ -6,12 +6,12 @@ import SimplePaginator from '../common/SimplePaginator';
|
||||||
import { useQueryState } from '../utils/helpers/hooks';
|
import { useQueryState } from '../utils/helpers/hooks';
|
||||||
import { parseQuery } from '../utils/helpers/query';
|
import { parseQuery } from '../utils/helpers/query';
|
||||||
import { TableOrderIcon } from '../utils/table/TableOrderIcon';
|
import { TableOrderIcon } from '../utils/table/TableOrderIcon';
|
||||||
import { OrderableFields, TagsListChildrenProps, TagsOrder } from './data/TagsListChildrenProps';
|
import { TagsOrderableFields, TagsListChildrenProps, TagsOrder } from './data/TagsListChildrenProps';
|
||||||
import { TagsTableRowProps } from './TagsTableRow';
|
import { TagsTableRowProps } from './TagsTableRow';
|
||||||
import './TagsTable.scss';
|
import './TagsTable.scss';
|
||||||
|
|
||||||
export interface TagsTableProps extends TagsListChildrenProps {
|
export interface TagsTableProps extends TagsListChildrenProps {
|
||||||
orderByColumn: (field: OrderableFields) => () => void;
|
orderByColumn: (field: TagsOrderableFields) => () => void;
|
||||||
currentOrder: TagsOrder;
|
currentOrder: TagsOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,15 @@ import { SelectedServer } from '../../servers/data';
|
||||||
import { Order } from '../../utils/helpers/ordering';
|
import { Order } from '../../utils/helpers/ordering';
|
||||||
import { NormalizedTag } from './index';
|
import { NormalizedTag } from './index';
|
||||||
|
|
||||||
export const SORTABLE_FIELDS = {
|
export const TAGS_ORDERABLE_FIELDS = {
|
||||||
tag: 'Tag',
|
tag: 'Tag',
|
||||||
shortUrls: 'Short URLs',
|
shortUrls: 'Short URLs',
|
||||||
visits: 'Visits',
|
visits: 'Visits',
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OrderableFields = keyof typeof SORTABLE_FIELDS;
|
export type TagsOrderableFields = keyof typeof TAGS_ORDERABLE_FIELDS;
|
||||||
|
|
||||||
export type TagsOrder = Order<OrderableFields>;
|
export type TagsOrder = Order<TagsOrderableFields>;
|
||||||
|
|
||||||
export interface TagsListChildrenProps {
|
export interface TagsListChildrenProps {
|
||||||
sortedTags: NormalizedTag[];
|
sortedTags: NormalizedTag[];
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Mock } from 'ts-mockery';
|
||||||
import { History, Location } from 'history';
|
import { History, Location } from 'history';
|
||||||
import { match } from 'react-router';
|
import { match } from 'react-router';
|
||||||
import shortUrlsListCreator from '../../src/short-urls/ShortUrlsList';
|
import shortUrlsListCreator from '../../src/short-urls/ShortUrlsList';
|
||||||
import { OrderableFields, ShortUrl, ShortUrlsOrder } from '../../src/short-urls/data';
|
import { ShortUrlsOrderableFields, ShortUrl, ShortUrlsOrder } from '../../src/short-urls/data';
|
||||||
import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub';
|
import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub';
|
||||||
import { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListModel } from '../../src/short-urls/reducers/shortUrlsList';
|
||||||
import SortingDropdown from '../../src/utils/SortingDropdown';
|
import SortingDropdown from '../../src/utils/SortingDropdown';
|
||||||
|
@ -75,8 +75,8 @@ describe('<ShortUrlsList />', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invokes order icon rendering', () => {
|
it('invokes order icon rendering', () => {
|
||||||
const renderIcon = (field: OrderableFields) =>
|
const renderIcon = (field: ShortUrlsOrderableFields) =>
|
||||||
(wrapper.find(ShortUrlsTable).prop('renderOrderIcon') as (field: OrderableFields) => ReactElement)(field);
|
(wrapper.find(ShortUrlsTable).prop('renderOrderIcon') as (field: ShortUrlsOrderableFields) => ReactElement)(field);
|
||||||
|
|
||||||
expect(renderIcon('visits').props.currentOrder).toEqual({});
|
expect(renderIcon('visits').props.currentOrder).toEqual({});
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ describe('<ShortUrlsList />', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles order through table', () => {
|
it('handles order through table', () => {
|
||||||
const orderByColumn: (field: OrderableFields) => Function = wrapper.find(ShortUrlsTable).prop('orderByColumn');
|
const orderByColumn: (field: ShortUrlsOrderableFields) => Function = wrapper.find(ShortUrlsTable).prop('orderByColumn');
|
||||||
|
|
||||||
expect(wrapper.find(SortingDropdown).prop('order')).toEqual({});
|
expect(wrapper.find(SortingDropdown).prop('order')).toEqual({});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { ShortUrlsTable as shortUrlsTableCreator } from '../../src/short-urls/Sh
|
||||||
import { ShortUrlsList } from '../../src/short-urls/reducers/shortUrlsList';
|
import { ShortUrlsList } from '../../src/short-urls/reducers/shortUrlsList';
|
||||||
import { ReachableServer, SelectedServer } from '../../src/servers/data';
|
import { ReachableServer, SelectedServer } from '../../src/servers/data';
|
||||||
import { SemVer } from '../../src/utils/helpers/version';
|
import { SemVer } from '../../src/utils/helpers/version';
|
||||||
import { OrderableFields, SORTABLE_FIELDS } from '../../src/short-urls/data';
|
import { ShortUrlsOrderableFields, SHORT_URLS_ORDERABLE_FIELDS } from '../../src/short-urls/data';
|
||||||
|
|
||||||
describe('<ShortUrlsTable />', () => {
|
describe('<ShortUrlsTable />', () => {
|
||||||
let wrapper: ShallowWrapper;
|
let wrapper: ShallowWrapper;
|
||||||
|
@ -51,8 +51,8 @@ describe('<ShortUrlsTable />', () => {
|
||||||
.find('thead')
|
.find('thead')
|
||||||
.find('tr')
|
.find('tr')
|
||||||
.find('th')
|
.find('th')
|
||||||
.filterWhere((e) => e.text().includes(SORTABLE_FIELDS[orderableField as OrderableFields]));
|
.filterWhere((e) => e.text().includes(SHORT_URLS_ORDERABLE_FIELDS[orderableField as ShortUrlsOrderableFields]));
|
||||||
const sortableFields = Object.keys(SORTABLE_FIELDS).filter((sortableField) => sortableField !== 'title');
|
const sortableFields = Object.keys(SHORT_URLS_ORDERABLE_FIELDS).filter((sortableField) => sortableField !== 'title');
|
||||||
|
|
||||||
expect.assertions(sortableFields.length);
|
expect.assertions(sortableFields.length);
|
||||||
sortableFields.forEach((sortableField) => {
|
sortableFields.forEach((sortableField) => {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { Result } from '../../src/utils/Result';
|
||||||
import { TagsModeDropdown } from '../../src/tags/TagsModeDropdown';
|
import { TagsModeDropdown } from '../../src/tags/TagsModeDropdown';
|
||||||
import SearchField from '../../src/utils/SearchField';
|
import SearchField from '../../src/utils/SearchField';
|
||||||
import { Settings } from '../../src/settings/reducers/settings';
|
import { Settings } from '../../src/settings/reducers/settings';
|
||||||
import { OrderableFields } from '../../src/tags/data/TagsListChildrenProps';
|
import { TagsOrderableFields } from '../../src/tags/data/TagsListChildrenProps';
|
||||||
import SortingDropdown from '../../src/utils/SortingDropdown';
|
import SortingDropdown from '../../src/utils/SortingDropdown';
|
||||||
|
|
||||||
describe('<TagsList />', () => {
|
describe('<TagsList />', () => {
|
||||||
|
@ -98,7 +98,7 @@ describe('<TagsList />', () => {
|
||||||
|
|
||||||
it('can update current order via orderByColumn from table component', () => {
|
it('can update current order via orderByColumn from table component', () => {
|
||||||
const wrapper = createWrapper({ filteredTags: [ 'foo', 'bar' ], stats: {} });
|
const wrapper = createWrapper({ filteredTags: [ 'foo', 'bar' ], stats: {} });
|
||||||
const callOrderBy = (field: OrderableFields) => {
|
const callOrderBy = (field: TagsOrderableFields) => {
|
||||||
((wrapper.find(TagsTable).prop('orderByColumn') as Function)(field) as Function)();
|
((wrapper.find(TagsTable).prop('orderByColumn') as Function)(field) as Function)();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue