Removed shortUrlsListParams reducer, as the state is now handled internally in the component

This commit is contained in:
Alejandro Celaya 2021-12-24 13:39:51 +01:00
parent 57075c581d
commit 275aee4de2
9 changed files with 10 additions and 72 deletions

View file

@ -4,7 +4,6 @@ import { Settings } from '../settings/reducers/settings';
import { ShortUrlCreation } from '../short-urls/reducers/shortUrlCreation'; import { ShortUrlCreation } from '../short-urls/reducers/shortUrlCreation';
import { ShortUrlDeletion } from '../short-urls/reducers/shortUrlDeletion'; import { ShortUrlDeletion } from '../short-urls/reducers/shortUrlDeletion';
import { ShortUrlEdition } from '../short-urls/reducers/shortUrlEdition'; import { ShortUrlEdition } from '../short-urls/reducers/shortUrlEdition';
import { ShortUrlsListParams } from '../short-urls/reducers/shortUrlsListParams';
import { ShortUrlsList } from '../short-urls/reducers/shortUrlsList'; import { ShortUrlsList } from '../short-urls/reducers/shortUrlsList';
import { TagDeletion } from '../tags/reducers/tagDelete'; import { TagDeletion } from '../tags/reducers/tagDelete';
import { TagEdition } from '../tags/reducers/tagEdit'; import { TagEdition } from '../tags/reducers/tagEdit';
@ -20,7 +19,6 @@ export interface ShlinkState {
servers: ServersMap; servers: ServersMap;
selectedServer: SelectedServer; selectedServer: SelectedServer;
shortUrlsList: ShortUrlsList; shortUrlsList: ShortUrlsList;
shortUrlsListParams: ShortUrlsListParams;
shortUrlCreationResult: ShortUrlCreation; shortUrlCreationResult: ShortUrlCreation;
shortUrlDeletion: ShortUrlDeletion; shortUrlDeletion: ShortUrlDeletion;
shortUrlEdition: ShortUrlEdition; shortUrlEdition: ShortUrlEdition;

View file

@ -2,7 +2,6 @@ import { combineReducers } from 'redux';
import serversReducer from '../servers/reducers/servers'; import serversReducer from '../servers/reducers/servers';
import selectedServerReducer from '../servers/reducers/selectedServer'; import selectedServerReducer from '../servers/reducers/selectedServer';
import shortUrlsListReducer from '../short-urls/reducers/shortUrlsList'; import shortUrlsListReducer from '../short-urls/reducers/shortUrlsList';
import shortUrlsListParamsReducer from '../short-urls/reducers/shortUrlsListParams';
import shortUrlCreationReducer from '../short-urls/reducers/shortUrlCreation'; import shortUrlCreationReducer from '../short-urls/reducers/shortUrlCreation';
import shortUrlDeletionReducer from '../short-urls/reducers/shortUrlDeletion'; import shortUrlDeletionReducer from '../short-urls/reducers/shortUrlDeletion';
import shortUrlEditionReducer from '../short-urls/reducers/shortUrlEdition'; import shortUrlEditionReducer from '../short-urls/reducers/shortUrlEdition';
@ -24,7 +23,6 @@ export default combineReducers<ShlinkState>({
servers: serversReducer, servers: serversReducer,
selectedServer: selectedServerReducer, selectedServer: selectedServerReducer,
shortUrlsList: shortUrlsListReducer, shortUrlsList: shortUrlsListReducer,
shortUrlsListParams: shortUrlsListParamsReducer,
shortUrlCreationResult: shortUrlCreationReducer, shortUrlCreationResult: shortUrlCreationReducer,
shortUrlDeletion: shortUrlDeletionReducer, shortUrlDeletion: shortUrlDeletionReducer,
shortUrlEdition: shortUrlEditionReducer, shortUrlEdition: shortUrlEditionReducer,

View file

@ -1,6 +1,5 @@
import { identity, memoizeWith, pipe } from 'ramda'; import { identity, memoizeWith, pipe } from 'ramda';
import { Action, Dispatch } from 'redux'; import { Action, Dispatch } from 'redux';
import { resetShortUrlParams } from '../../short-urls/reducers/shortUrlsListParams';
import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version'; import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version';
import { SelectedServer } from '../data'; import { SelectedServer } from '../data';
import { GetState } from '../../container/types'; import { GetState } from '../../container/types';
@ -53,7 +52,6 @@ export const selectServer = (
getState: GetState, getState: GetState,
) => { ) => {
dispatch(resetSelectedServer()); dispatch(resetSelectedServer());
dispatch(resetShortUrlParams());
const { servers } = getState(); const { servers } = getState();
const selectedServer = servers[serverId]; const selectedServer = servers[serverId];

View file

@ -11,7 +11,7 @@ import { TableOrderIcon } from '../utils/table/TableOrderIcon';
import { ShlinkShortUrlsListParams } from '../api/types'; import { ShlinkShortUrlsListParams } from '../api/types';
import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings'; import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/settings';
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList'; import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
import { OrderableFields, ShortUrlsListParams, ShortUrlsOrder, SORTABLE_FIELDS } from './reducers/shortUrlsListParams'; import { OrderableFields, ShortUrlsOrder, SORTABLE_FIELDS } from './reducers/shortUrlsListParams';
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';
@ -20,15 +20,11 @@ interface ShortUrlsListProps extends RouteComponentProps<ShortUrlListRouteParams
selectedServer: SelectedServer; selectedServer: SelectedServer;
shortUrlsList: ShortUrlsListState; shortUrlsList: ShortUrlsListState;
listShortUrls: (params: ShlinkShortUrlsListParams) => void; listShortUrls: (params: ShlinkShortUrlsListParams) => void;
shortUrlsListParams: ShortUrlsListParams;
resetShortUrlParams: () => void;
settings: Settings; settings: Settings;
} }
const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) => boundToMercureHub(({ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) => boundToMercureHub(({
listShortUrls, listShortUrls,
resetShortUrlParams,
shortUrlsListParams,
match, match,
location, location,
history, history,
@ -37,8 +33,7 @@ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) =
settings, settings,
}: ShortUrlsListProps) => { }: ShortUrlsListProps) => {
const serverId = getServerId(selectedServer); const serverId = getServerId(selectedServer);
const { orderBy } = shortUrlsListParams; const initialOrderBy = settings.shortUrlList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING;
const initialOrderBy = orderBy ?? settings.shortUrlList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING;
const [ order, setOrder ] = useState<ShortUrlsOrder>(initialOrderBy); const [ order, setOrder ] = useState<ShortUrlsOrder>(initialOrderBy);
const [{ tags, search, startDate, endDate }, toFirstPage ] = useShortUrlsQuery({ history, match, location }); const [{ tags, search, startDate, endDate }, toFirstPage ] = useShortUrlsQuery({ history, match, location });
const selectedTags = useMemo(() => tags?.split(',') ?? [], [ tags ]); const selectedTags = useMemo(() => tags?.split(',') ?? [], [ tags ]);
@ -53,7 +48,6 @@ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, SearchBar: FC) =
(tags) => toFirstPage({ tags }), (tags) => toFirstPage({ tags }),
); );
useEffect(() => resetShortUrlParams, []);
useEffect(() => { useEffect(() => {
listShortUrls({ listShortUrls({
page: match.params.page, page: match.params.page,

View file

@ -1,8 +1,4 @@
import { buildActionCreator, buildReducer } from '../../utils/helpers/redux';
import { Order } from '../../utils/helpers/ordering'; import { Order } from '../../utils/helpers/ordering';
import { LIST_SHORT_URLS, ListShortUrlsAction } from './shortUrlsList';
export const RESET_SHORT_URL_PARAMS = 'shlink/shortUrlsListParams/RESET_SHORT_URL_PARAMS';
export const SORTABLE_FIELDS = { export const SORTABLE_FIELDS = {
dateCreated: 'Created at', dateCreated: 'Created at',
@ -15,20 +11,3 @@ export const SORTABLE_FIELDS = {
export type OrderableFields = keyof typeof SORTABLE_FIELDS; export type OrderableFields = keyof typeof SORTABLE_FIELDS;
export type ShortUrlsOrder = Order<OrderableFields>; export type ShortUrlsOrder = Order<OrderableFields>;
export interface ShortUrlsListParams {
page?: string;
itemsPerPage?: number;
orderBy?: ShortUrlsOrder;
}
const initialState: ShortUrlsListParams = {
page: '1',
};
export default buildReducer<ShortUrlsListParams, ListShortUrlsAction>({
[LIST_SHORT_URLS]: (state, { params }) => ({ ...state, ...params }),
[RESET_SHORT_URL_PARAMS]: () => initialState,
}, initialState);
export const resetShortUrlParams = buildActionCreator(RESET_SHORT_URL_PARAMS);

View file

@ -9,7 +9,6 @@ import CreateShortUrlResult from '../helpers/CreateShortUrlResult';
import { listShortUrls } from '../reducers/shortUrlsList'; import { listShortUrls } from '../reducers/shortUrlsList';
import { createShortUrl, resetCreateShortUrl } from '../reducers/shortUrlCreation'; import { createShortUrl, resetCreateShortUrl } from '../reducers/shortUrlCreation';
import { deleteShortUrl, resetDeleteShortUrl } from '../reducers/shortUrlDeletion'; import { deleteShortUrl, resetDeleteShortUrl } from '../reducers/shortUrlDeletion';
import { resetShortUrlParams } from '../reducers/shortUrlsListParams';
import { editShortUrl } from '../reducers/shortUrlEdition'; import { editShortUrl } from '../reducers/shortUrlEdition';
import { ConnectDecorator } from '../../container/types'; import { ConnectDecorator } from '../../container/types';
import { ShortUrlsTable } from '../ShortUrlsTable'; import { ShortUrlsTable } from '../ShortUrlsTable';
@ -22,8 +21,8 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
// Components // Components
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable', 'SearchBar'); bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable', 'SearchBar');
bottle.decorator('ShortUrlsList', connect( bottle.decorator('ShortUrlsList', connect(
[ 'selectedServer', 'shortUrlsListParams', 'mercureInfo', 'shortUrlsList', 'settings' ], [ 'selectedServer', 'mercureInfo', 'shortUrlsList', 'settings' ],
[ 'listShortUrls', 'resetShortUrlParams', 'createNewVisits', 'loadMercureInfo' ], [ 'listShortUrls', 'createNewVisits', 'loadMercureInfo' ],
)); ));
bottle.serviceFactory('ShortUrlsTable', ShortUrlsTable, 'ShortUrlsRow'); bottle.serviceFactory('ShortUrlsTable', ShortUrlsTable, 'ShortUrlsRow');
@ -56,7 +55,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
// Actions // Actions
bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient'); bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient');
bottle.serviceFactory('resetShortUrlParams', () => resetShortUrlParams);
bottle.serviceFactory('createShortUrl', createShortUrl, 'buildShlinkApiClient'); bottle.serviceFactory('createShortUrl', createShortUrl, 'buildShlinkApiClient');
bottle.serviceFactory('resetCreateShortUrl', () => resetCreateShortUrl); bottle.serviceFactory('resetCreateShortUrl', () => resetCreateShortUrl);

View file

@ -8,7 +8,6 @@ import reducer, {
MAX_FALLBACK_VERSION, MAX_FALLBACK_VERSION,
MIN_FALLBACK_VERSION, MIN_FALLBACK_VERSION,
} from '../../../src/servers/reducers/selectedServer'; } from '../../../src/servers/reducers/selectedServer';
import { RESET_SHORT_URL_PARAMS } from '../../../src/short-urls/reducers/shortUrlsListParams';
import { ShlinkState } from '../../../src/container/types'; import { ShlinkState } from '../../../src/container/types';
import { NonReachableServer, NotFoundServer, RegularServer } from '../../../src/servers/data'; import { NonReachableServer, NotFoundServer, RegularServer } from '../../../src/servers/data';
@ -62,10 +61,9 @@ describe('selectedServerReducer', () => {
await selectServer(buildApiClient, loadMercureInfo)(id)(dispatch, getState); await selectServer(buildApiClient, loadMercureInfo)(id)(dispatch, getState);
expect(dispatch).toHaveBeenCalledTimes(4); expect(dispatch).toHaveBeenCalledTimes(3);
expect(dispatch).toHaveBeenNthCalledWith(1, { type: RESET_SELECTED_SERVER }); expect(dispatch).toHaveBeenNthCalledWith(1, { type: RESET_SELECTED_SERVER });
expect(dispatch).toHaveBeenNthCalledWith(2, { type: RESET_SHORT_URL_PARAMS }); expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
expect(loadMercureInfo).toHaveBeenCalledTimes(1); expect(loadMercureInfo).toHaveBeenCalledTimes(1);
}); });
@ -89,7 +87,7 @@ describe('selectedServerReducer', () => {
await selectServer(buildApiClient, loadMercureInfo)(id)(dispatch, getState); await selectServer(buildApiClient, loadMercureInfo)(id)(dispatch, getState);
expect(apiClientMock.health).toHaveBeenCalled(); expect(apiClientMock.health).toHaveBeenCalled();
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer }); expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
expect(loadMercureInfo).not.toHaveBeenCalled(); expect(loadMercureInfo).not.toHaveBeenCalled();
}); });
@ -102,7 +100,7 @@ describe('selectedServerReducer', () => {
expect(getState).toHaveBeenCalled(); expect(getState).toHaveBeenCalled();
expect(apiClientMock.health).not.toHaveBeenCalled(); expect(apiClientMock.health).not.toHaveBeenCalled();
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer }); expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
expect(loadMercureInfo).not.toHaveBeenCalled(); expect(loadMercureInfo).not.toHaveBeenCalled();
}); });
}); });

View file

@ -33,18 +33,16 @@ describe('<ShortUrlsList />', () => {
}, },
}); });
const ShortUrlsList = shortUrlsListCreator(ShortUrlsTable, SearchBar); const ShortUrlsList = shortUrlsListCreator(ShortUrlsTable, SearchBar);
const createWrapper = (orderBy: ShortUrlsOrder = {}) => shallow( const createWrapper = (defaultOrdering: ShortUrlsOrder = {}) => shallow(
<ShortUrlsList <ShortUrlsList
{...Mock.of<MercureBoundProps>({ mercureInfo: { loading: true } })} {...Mock.of<MercureBoundProps>({ mercureInfo: { loading: true } })}
listShortUrls={listShortUrlsMock} listShortUrls={listShortUrlsMock}
resetShortUrlParams={jest.fn()}
shortUrlsListParams={{ page: '1', orderBy }}
match={Mock.of<match<ShortUrlListRouteParams>>({ params: {} })} match={Mock.of<match<ShortUrlListRouteParams>>({ params: {} })}
location={Mock.of<Location>({ search: '?tags=test%20tag&search=example.com' })} location={Mock.of<Location>({ search: '?tags=test%20tag&search=example.com' })}
shortUrlsList={shortUrlsList} shortUrlsList={shortUrlsList}
history={Mock.of<History>({ push })} history={Mock.of<History>({ push })}
selectedServer={Mock.of<ReachableServer>({ id: '1' })} selectedServer={Mock.of<ReachableServer>({ id: '1' })}
settings={Mock.all<Settings>()} settings={Mock.of<Settings>({ shortUrlList: { defaultOrdering } })}
/>, />,
).dive(); // Dive is needed as this component is wrapped in a HOC ).dive(); // Dive is needed as this component is wrapped in a HOC

View file

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