Merge pull request #300 from acelaya-forks/feature/default-ordering

Feature/default ordering
This commit is contained in:
Alejandro Celaya 2020-09-13 09:54:20 +02:00 committed by GitHub
commit 89e3114ef3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 18 deletions

View file

@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
#### Changed #### Changed
* [#150](https://github.com/shlinkio/shlink-web-client/issues/150) The list of short URLs is now ordered by the creation date, showing newest results first.
* [#40](https://github.com/shlinkio/shlink-web-client/issues/40) Migrated project to TypeScript. * [#40](https://github.com/shlinkio/shlink-web-client/issues/40) Migrated project to TypeScript.
#### Deprecated #### Deprecated

View file

@ -1,7 +1,7 @@
import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons'; import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { head, isEmpty, keys, values } from 'ramda'; import { head, isEmpty, keys, values } from 'ramda';
import React, { useState, useEffect, FC } from 'react'; import React, { FC, useEffect, useState } from 'react';
import qs from 'qs'; import qs from 'qs';
import { RouteComponentProps } from 'react-router'; import { RouteComponentProps } from 'react-router';
import SortingDropdown from '../utils/SortingDropdown'; import SortingDropdown from '../utils/SortingDropdown';
@ -11,17 +11,9 @@ import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
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 { ShortUrl } from './data'; import { ShortUrl } from './data';
import { ShortUrlsListParams } from './reducers/shortUrlsListParams'; import { OrderableFields, ShortUrlsListParams, SORTABLE_FIELDS } from './reducers/shortUrlsListParams';
import './ShortUrlsList.scss'; import './ShortUrlsList.scss';
export const SORTABLE_FIELDS = {
dateCreated: 'Created at',
shortCode: 'Short URL',
longUrl: 'Long URL',
visits: 'Visits',
};
type OrderableFields = keyof typeof SORTABLE_FIELDS;
interface RouteParams { interface RouteParams {
page: string; page: string;
serverId: string; serverId: string;

View file

@ -4,16 +4,28 @@ import { LIST_SHORT_URLS, ListShortUrlsAction } from './shortUrlsList';
export const RESET_SHORT_URL_PARAMS = 'shlink/shortUrlsListParams/RESET_SHORT_URL_PARAMS'; export const RESET_SHORT_URL_PARAMS = 'shlink/shortUrlsListParams/RESET_SHORT_URL_PARAMS';
export const SORTABLE_FIELDS = {
dateCreated: 'Created at',
shortCode: 'Short URL',
longUrl: 'Long URL',
visits: 'Visits',
};
export type OrderableFields = keyof typeof SORTABLE_FIELDS;
export interface ShortUrlsListParams { export interface ShortUrlsListParams {
page?: string; page?: string;
tags?: string[]; tags?: string[];
searchTerm?: string; searchTerm?: string;
startDate?: string; startDate?: string;
endDate?: string; endDate?: string;
orderBy?: Record<string, OrderDir>; orderBy?: Partial<Record<OrderableFields, OrderDir>>;
} }
const initialState: ShortUrlsListParams = { page: '1' }; const initialState: ShortUrlsListParams = {
page: '1',
orderBy: { dateCreated: 'DESC' },
};
export default buildReducer<ShortUrlsListParams, ListShortUrlsAction>({ export default buildReducer<ShortUrlsListParams, ListShortUrlsAction>({
[LIST_SHORT_URLS]: (state, { params }) => ({ ...state, ...params }), [LIST_SHORT_URLS]: (state, { params }) => ({ ...state, ...params }),

View file

@ -3,9 +3,10 @@ import { shallow, ShallowWrapper } from 'enzyme';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons'; import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import shortUrlsListCreator, { ShortUrlsListProps, SORTABLE_FIELDS } from '../../src/short-urls/ShortUrlsList'; import shortUrlsListCreator, { ShortUrlsListProps } from '../../src/short-urls/ShortUrlsList';
import { ShortUrl } from '../../src/short-urls/data'; import { ShortUrl } from '../../src/short-urls/data';
import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub'; import { MercureBoundProps } from '../../src/mercure/helpers/boundToMercureHub';
import { SORTABLE_FIELDS } from '../../src/short-urls/reducers/shortUrlsListParams';
describe('<ShortUrlsList />', () => { describe('<ShortUrlsList />', () => {
let wrapper: ShallowWrapper; let wrapper: ShallowWrapper;

View file

@ -1,22 +1,23 @@
import reducer, { import reducer, {
RESET_SHORT_URL_PARAMS, RESET_SHORT_URL_PARAMS,
resetShortUrlParams, resetShortUrlParams,
ShortUrlsListParams,
} from '../../../src/short-urls/reducers/shortUrlsListParams'; } from '../../../src/short-urls/reducers/shortUrlsListParams';
import { LIST_SHORT_URLS } from '../../../src/short-urls/reducers/shortUrlsList'; import { LIST_SHORT_URLS } from '../../../src/short-urls/reducers/shortUrlsList';
describe('shortUrlsListParamsReducer', () => { describe('shortUrlsListParamsReducer', () => {
describe('reducer', () => { describe('reducer', () => {
const defaultState: ShortUrlsListParams = { page: '1' };
it('returns params when action is LIST_SHORT_URLS', () => it('returns params when action is LIST_SHORT_URLS', () =>
expect(reducer(undefined, { type: LIST_SHORT_URLS, params: { searchTerm: 'foo', page: '2' } })).toEqual({ expect(reducer(undefined, { type: LIST_SHORT_URLS, params: { searchTerm: 'foo', page: '2' } } as any)).toEqual({
page: '2', page: '2',
searchTerm: 'foo', searchTerm: 'foo',
orderBy: { dateCreated: 'DESC' },
})); }));
it('returns default value when action is RESET_SHORT_URL_PARAMS', () => it('returns default value when action is RESET_SHORT_URL_PARAMS', () =>
expect(reducer(undefined, { type: RESET_SHORT_URL_PARAMS, params: defaultState })).toEqual(defaultState)); expect(reducer(undefined, { type: RESET_SHORT_URL_PARAMS } as any)).toEqual({
page: '1',
orderBy: { dateCreated: 'DESC' },
}));
}); });
describe('resetShortUrlParams', () => { describe('resetShortUrlParams', () => {