Merge pull request #192 from acelaya-forks/feature/version-constraints

Feature/version constraints
This commit is contained in:
Alejandro Celaya
2020-01-19 21:37:56 +01:00
committed by GitHub
6 changed files with 43 additions and 20 deletions

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2018-2019 shlinkio Copyright (c) 2018-2020 shlinkio
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -7,19 +7,23 @@ import moment from 'moment';
import SearchField from '../utils/SearchField'; import SearchField from '../utils/SearchField';
import Tag from '../tags/helpers/Tag'; import Tag from '../tags/helpers/Tag';
import DateRangeRow from '../utils/DateRangeRow'; import DateRangeRow from '../utils/DateRangeRow';
import { formatDate } from '../utils/utils'; import { compareVersions, formatDate } from '../utils/utils';
import { serverType } from '../servers/prop-types';
import { shortUrlsListParamsType } from './reducers/shortUrlsListParams'; import { shortUrlsListParamsType } from './reducers/shortUrlsListParams';
import './SearchBar.scss'; import './SearchBar.scss';
const propTypes = { const propTypes = {
listShortUrls: PropTypes.func, listShortUrls: PropTypes.func,
shortUrlsListParams: shortUrlsListParamsType, shortUrlsListParams: shortUrlsListParamsType,
selectedServer: serverType,
}; };
const dateOrUndefined = (date) => date ? moment(date) : undefined; const dateOrUndefined = (date) => date ? moment(date) : undefined;
const SearchBar = (colorGenerator) => { const SearchBar = (colorGenerator) => {
const SearchBar = ({ listShortUrls, shortUrlsListParams }) => { const SearchBar = ({ listShortUrls, shortUrlsListParams, selectedServer }) => {
const currentServerVersion = selectedServer ? selectedServer.version : '';
const enableDateFiltering = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.21.0');
const selectedTags = shortUrlsListParams.tags || []; const selectedTags = shortUrlsListParams.tags || [];
const setDate = (dateName) => pipe( const setDate = (dateName) => pipe(
formatDate(), formatDate(),
@@ -34,14 +38,16 @@ const SearchBar = (colorGenerator) => {
} }
/> />
<div className="mt-3"> {enableDateFiltering && (
<DateRangeRow <div className="mt-3">
startDate={dateOrUndefined(shortUrlsListParams.startDate)} <DateRangeRow
endDate={dateOrUndefined(shortUrlsListParams.endDate)} startDate={dateOrUndefined(shortUrlsListParams.startDate)}
onStartDateChange={setDate('startDate')} endDate={dateOrUndefined(shortUrlsListParams.endDate)}
onEndDateChange={setDate('endDate')} onStartDateChange={setDate('startDate')}
/> onEndDateChange={setDate('endDate')}
</div> />
</div>
)}
{!isEmpty(selectedTags) && ( {!isEmpty(selectedTags) && (
<h4 className="search-bar__selected-tag mt-3"> <h4 className="search-bar__selected-tag mt-3">

View File

@@ -46,6 +46,7 @@ const ShortUrlsRowMenu = (
const { onCopyToClipboard, shortUrl, selectedServer } = this.props; const { onCopyToClipboard, shortUrl, selectedServer } = this.props;
const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : '';
const currentServerVersion = selectedServer ? selectedServer.version : ''; const currentServerVersion = selectedServer ? selectedServer.version : '';
const showEditMetaBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.18.0');
const showPreviewBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '<', '2.0.0'); const showPreviewBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '<', '2.0.0');
const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] })); const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] }));
const toggleQrCode = toggleModal('isQrModalOpen'); const toggleQrCode = toggleModal('isQrModalOpen');
@@ -69,10 +70,14 @@ const ShortUrlsRowMenu = (
</DropdownItem> </DropdownItem>
<EditTagsModal shortUrl={shortUrl} isOpen={this.state.isTagsModalOpen} toggle={toggleTags} /> <EditTagsModal shortUrl={shortUrl} isOpen={this.state.isTagsModalOpen} toggle={toggleTags} />
<DropdownItem onClick={toggleMeta}> {showEditMetaBtn && (
<FontAwesomeIcon icon={editIcon} fixedWidth /> Edit metadata <React.Fragment>
</DropdownItem> <DropdownItem onClick={toggleMeta}>
<EditMetaModal shortUrl={shortUrl} isOpen={this.state.isMetaModalOpen} toggle={toggleMeta} /> <FontAwesomeIcon icon={editIcon} fixedWidth /> Edit metadata
</DropdownItem>
<EditMetaModal shortUrl={shortUrl} isOpen={this.state.isMetaModalOpen} toggle={toggleMeta} />
</React.Fragment>
)}
<DropdownItem className="short-urls-row-menu__dropdown-item--danger" onClick={toggleDelete}> <DropdownItem className="short-urls-row-menu__dropdown-item--danger" onClick={toggleDelete}>
<FontAwesomeIcon icon={deleteIcon} fixedWidth /> Delete short URL <FontAwesomeIcon icon={deleteIcon} fixedWidth /> Delete short URL

View File

@@ -25,7 +25,7 @@ const provideServices = (bottle, connect) => {
)); ));
bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator'); bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator');
bottle.decorator('SearchBar', connect([ 'shortUrlsListParams' ], [ 'listShortUrls' ])); bottle.decorator('SearchBar', connect([ 'shortUrlsListParams', 'selectedServer' ], [ 'listShortUrls' ]));
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow'); bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow');
bottle.decorator('ShortUrlsList', connect( bottle.decorator('ShortUrlsList', connect(

View File

@@ -22,10 +22,15 @@ describe('<SearchBar />', () => {
expect(wrapper.find(SearchField)).toHaveLength(1); expect(wrapper.find(SearchField)).toHaveLength(1);
}); });
it('renders a DateRangeRow', () => { each([
wrapper = shallow(<SearchBar shortUrlsListParams={{}} />); [ '2.0.0', 1 ],
[ '1.21.2', 1 ],
[ '1.21.0', 1 ],
[ '1.20.0', 0 ],
]).it('renders a DateRangeRow when proper version is run', (version, expectedLength) => {
wrapper = shallow(<SearchBar shortUrlsListParams={{}} selectedServer={{ version }} />);
expect(wrapper.find(DateRangeRow)).toHaveLength(1); expect(wrapper.find(DateRangeRow)).toHaveLength(expectedLength);
}); });
it('renders no tags when the list of tags is empty', () => { it('renders no tags when the list of tags is empty', () => {
@@ -63,7 +68,9 @@ describe('<SearchBar />', () => {
}); });
each([ 'startDateChange', 'endDateChange' ]).it('updates short URLs list when date range changes', (event) => { each([ 'startDateChange', 'endDateChange' ]).it('updates short URLs list when date range changes', (event) => {
wrapper = shallow(<SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} />); wrapper = shallow(
<SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} selectedServer={{ version: '2.0.0' }} />
);
const dateRange = wrapper.find(DateRangeRow); const dateRange = wrapper.find(DateRangeRow);
expect(listShortUrlsMock).not.toHaveBeenCalled(); expect(listShortUrlsMock).not.toHaveBeenCalled();

View File

@@ -47,6 +47,11 @@ describe('<ShortUrlsRowMenu />', () => {
}); });
each([ each([
[ '1.17.0', 6, 2 ],
[ '1.17.2', 6, 2 ],
[ '1.18.0', 7, 2 ],
[ '1.18.1', 7, 2 ],
[ '1.19.0', 7, 2 ],
[ '1.20.3', 7, 2 ], [ '1.20.3', 7, 2 ],
[ '1.21.0', 7, 2 ], [ '1.21.0', 7, 2 ],
[ '1.21.1', 7, 2 ], [ '1.21.1', 7, 2 ],