diff --git a/src/container/index.js b/src/container/index.js
index 3450796a..483c8acd 100644
--- a/src/container/index.js
+++ b/src/container/index.js
@@ -20,7 +20,7 @@ const mapActionService = (map, actionName) => ({
// Wrap actual action service in a function so that it is lazily created the first time it is called
[actionName]: lazyService(container, actionName),
});
-const connect = (propsFromState, actionServiceNames) =>
+const connect = (propsFromState, actionServiceNames = []) =>
reduxConnect(
propsFromState ? pick(propsFromState) : null,
actionServiceNames.reduce(mapActionService, {})
diff --git a/src/servers/helpers/ForServerVersion.js b/src/servers/helpers/ForServerVersion.js
new file mode 100644
index 00000000..e89eacfc
--- /dev/null
+++ b/src/servers/helpers/ForServerVersion.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { compareVersions } from '../../utils/utils';
+import { serverType } from '../prop-types';
+
+const propTypes = {
+ minVersion: PropTypes.string,
+ maxVersion: PropTypes.string,
+ selectedServer: serverType,
+ children: PropTypes.node.isRequired,
+};
+
+const ForServerVersion = ({ minVersion, maxVersion, selectedServer, children }) => {
+ if (!selectedServer) {
+ return null;
+ }
+
+ const { version } = selectedServer;
+ const matchesMinVersion = !minVersion || compareVersions(version, '>=', minVersion);
+ const matchesMaxVersion = !maxVersion || compareVersions(version, '<=', maxVersion);
+
+ if (!matchesMinVersion || !matchesMaxVersion) {
+ return null;
+ }
+
+ return {children};
+};
+
+ForServerVersion.propTypes = propTypes;
+
+export default ForServerVersion;
diff --git a/src/servers/prop-types/index.js b/src/servers/prop-types/index.js
index 8beba60f..35d43e49 100644
--- a/src/servers/prop-types/index.js
+++ b/src/servers/prop-types/index.js
@@ -5,4 +5,5 @@ export const serverType = PropTypes.shape({
name: PropTypes.string,
url: PropTypes.string,
apiKey: PropTypes.string,
+ version: PropTypes.string,
});
diff --git a/src/servers/services/provideServices.js b/src/servers/services/provideServices.js
index 7c87157a..e4231e87 100644
--- a/src/servers/services/provideServices.js
+++ b/src/servers/services/provideServices.js
@@ -6,6 +6,7 @@ import DeleteServerButton from '../DeleteServerButton';
import ImportServersBtn from '../helpers/ImportServersBtn';
import { resetSelectedServer, selectServer } from '../reducers/selectedServer';
import { createServer, createServers, deleteServer, listServers } from '../reducers/server';
+import ForServerVersion from '../helpers/ForServerVersion';
import ServersImporter from './ServersImporter';
import ServersService from './ServersService';
import ServersExporter from './ServersExporter';
@@ -28,6 +29,9 @@ const provideServices = (bottle, connect, withRouter) => {
bottle.serviceFactory('ImportServersBtn', ImportServersBtn, 'ServersImporter');
bottle.decorator('ImportServersBtn', connect(null, [ 'createServers' ]));
+ bottle.serviceFactory('ForServerVersion', () => ForServerVersion);
+ bottle.decorator('ForServerVersion', connect([ 'selectedServer' ]));
+
// Services
bottle.constant('csvjson', csvjson);
bottle.service('ServersImporter', ServersImporter, 'csvjson');
diff --git a/src/short-urls/CreateShortUrl.js b/src/short-urls/CreateShortUrl.js
index 1a07065e..d1ace683 100644
--- a/src/short-urls/CreateShortUrl.js
+++ b/src/short-urls/CreateShortUrl.js
@@ -6,7 +6,6 @@ import { Collapse, FormGroup, Input } from 'reactstrap';
import * as PropTypes from 'prop-types';
import DateInput from '../utils/DateInput';
import Checkbox from '../utils/Checkbox';
-import ForVersion from '../utils/ForVersion';
import { serverType } from '../servers/prop-types';
import { compareVersions } from '../utils/utils';
import { createShortUrlResultType } from './reducers/shortUrlCreation';
@@ -15,7 +14,11 @@ import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
const normalizeTag = pipe(trim, replace(/ /g, '-'));
const formatDate = (date) => isNil(date) ? date : date.format();
-const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShortUrl extends React.Component {
+const CreateShortUrl = (
+ TagsSelector,
+ CreateShortUrlResult,
+ ForServerVersion
+) => class CreateShortUrl extends React.Component {
static propTypes = {
createShortUrl: PropTypes.func,
shortUrlCreationResult: createShortUrlResultType,
@@ -116,7 +119,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShort
-
+
class CreateShort
-
+
diff --git a/src/short-urls/SearchBar.js b/src/short-urls/SearchBar.js
index 3c75178a..ea1c698e 100644
--- a/src/short-urls/SearchBar.js
+++ b/src/short-urls/SearchBar.js
@@ -7,23 +7,19 @@ import moment from 'moment';
import SearchField from '../utils/SearchField';
import Tag from '../tags/helpers/Tag';
import DateRangeRow from '../utils/DateRangeRow';
-import { compareVersions, formatDate } from '../utils/utils';
-import { serverType } from '../servers/prop-types';
+import { formatDate } from '../utils/utils';
import { shortUrlsListParamsType } from './reducers/shortUrlsListParams';
import './SearchBar.scss';
const propTypes = {
listShortUrls: PropTypes.func,
shortUrlsListParams: shortUrlsListParamsType,
- selectedServer: serverType,
};
const dateOrUndefined = (date) => date ? moment(date) : undefined;
-const SearchBar = (colorGenerator) => {
- const SearchBar = ({ listShortUrls, shortUrlsListParams, selectedServer }) => {
- const currentServerVersion = selectedServer ? selectedServer.version : '';
- const enableDateFiltering = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.21.0');
+const SearchBar = (colorGenerator, ForServerVersion) => {
+ const SearchBar = ({ listShortUrls, shortUrlsListParams }) => {
const selectedTags = shortUrlsListParams.tags || [];
const setDate = (dateName) => pipe(
formatDate(),
@@ -38,7 +34,7 @@ const SearchBar = (colorGenerator) => {
}
/>
- {enableDateFiltering && (
+
{
onEndDateChange={setDate('endDate')}
/>
- )}
+
{!isEmpty(selectedTags) && (
diff --git a/src/short-urls/helpers/ShortUrlsRowMenu.js b/src/short-urls/helpers/ShortUrlsRowMenu.js
index 29d67d43..dde64ad3 100644
--- a/src/short-urls/helpers/ShortUrlsRowMenu.js
+++ b/src/short-urls/helpers/ShortUrlsRowMenu.js
@@ -13,9 +13,7 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Link } from 'react-router-dom';
import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
import PropTypes from 'prop-types';
-import { isEmpty } from 'ramda';
import { serverType } from '../../servers/prop-types';
-import { compareVersions } from '../../utils/utils';
import { shortUrlType } from '../reducers/shortUrlsList';
import PreviewModal from './PreviewModal';
import QrCodeModal from './QrCodeModal';
@@ -24,7 +22,8 @@ import './ShortUrlsRowMenu.scss';
const ShortUrlsRowMenu = (
DeleteShortUrlModal,
EditTagsModal,
- EditMetaModal
+ EditMetaModal,
+ ForServerVersion
) => class ShortUrlsRowMenu extends React.Component {
static propTypes = {
onCopyToClipboard: PropTypes.func,
@@ -45,9 +44,6 @@ const ShortUrlsRowMenu = (
render() {
const { onCopyToClipboard, shortUrl, selectedServer } = this.props;
const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : '';
- const currentServerVersion = selectedServer ? selectedServer.version : '';
- const showEditMetaBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.18.0');
- const showPreviewBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '<', '2.0.0');
const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] }));
const toggleQrCode = toggleModal('isQrModalOpen');
const togglePreview = toggleModal('isPreviewModalOpen');
@@ -70,14 +66,12 @@ const ShortUrlsRowMenu = (
- {showEditMetaBtn && (
-
-
- Edit metadata
-
-
-
- )}
+
+
+ Edit metadata
+
+
+
Delete short URL
@@ -86,21 +80,21 @@ const ShortUrlsRowMenu = (
- {showPreviewBtn && (
-
-
- Preview
-
-
-
- )}
+
+
+ Preview
+
+
+
QR code
- {showPreviewBtn && }
+
+
+
diff --git a/src/short-urls/services/provideServices.js b/src/short-urls/services/provideServices.js
index 610d3e08..33c1ec26 100644
--- a/src/short-urls/services/provideServices.js
+++ b/src/short-urls/services/provideServices.js
@@ -24,8 +24,8 @@ const provideServices = (bottle, connect) => {
(state) => assoc('shortUrlsList', state.shortUrlsList.shortUrls, state.shortUrlsList)
));
- bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator');
- bottle.decorator('SearchBar', connect([ 'shortUrlsListParams', 'selectedServer' ], [ 'listShortUrls' ]));
+ bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator', 'ForServerVersion');
+ bottle.decorator('SearchBar', connect([ 'shortUrlsListParams' ], [ 'listShortUrls' ]));
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow');
bottle.decorator('ShortUrlsList', connect(
@@ -35,10 +35,17 @@ const provideServices = (bottle, connect) => {
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator', 'stateFlagTimeout');
- bottle.serviceFactory('ShortUrlsRowMenu', ShortUrlsRowMenu, 'DeleteShortUrlModal', 'EditTagsModal', 'EditMetaModal');
+ bottle.serviceFactory(
+ 'ShortUrlsRowMenu',
+ ShortUrlsRowMenu,
+ 'DeleteShortUrlModal',
+ 'EditTagsModal',
+ 'EditMetaModal',
+ 'ForServerVersion'
+ );
bottle.serviceFactory('CreateShortUrlResult', CreateShortUrlResult, 'stateFlagTimeout');
- bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector', 'CreateShortUrlResult');
+ bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector', 'CreateShortUrlResult', 'ForServerVersion');
bottle.decorator(
'CreateShortUrl',
connect([ 'shortUrlCreationResult', 'selectedServer' ], [ 'createShortUrl', 'resetCreateShortUrl' ])
diff --git a/src/utils/ForVersion.js b/src/utils/ForVersion.js
deleted file mode 100644
index 7ed39890..00000000
--- a/src/utils/ForVersion.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { isEmpty } from 'ramda';
-import { compareVersions } from './utils';
-
-const propTypes = {
- minVersion: PropTypes.string.isRequired,
- currentServerVersion: PropTypes.string.isRequired,
- children: PropTypes.node.isRequired,
-};
-
-const ForVersion = ({ minVersion, currentServerVersion, children }) =>
- isEmpty(currentServerVersion) || compareVersions(currentServerVersion, '<', minVersion)
- ? null
- : {children};
-
-ForVersion.propTypes = propTypes;
-
-export default ForVersion;
diff --git a/test/servers/helpers/ForServerVersion.test.js b/test/servers/helpers/ForServerVersion.test.js
new file mode 100644
index 00000000..c229642a
--- /dev/null
+++ b/test/servers/helpers/ForServerVersion.test.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import each from 'jest-each';
+import ForServerVersion from '../../../src/servers/helpers/ForServerVersion';
+
+describe('', () => {
+ let wrapped;
+
+ const renderComponent = (minVersion, maxVersion, selectedServer) => {
+ wrapped = mount(
+
+ Hello
+
+ );
+
+ return wrapped;
+ };
+
+ afterEach(() => wrapped && wrapped.unmount());
+
+ it('does not render children when current server is empty', () => {
+ const wrapped = renderComponent('1');
+
+ expect(wrapped.html()).toBeNull();
+ });
+
+ each([
+ [ '2.0.0', undefined, '1.8.3' ],
+ [ undefined, '1.8.0', '1.8.3' ],
+ [ '1.7.0', '1.8.0', '1.8.3' ],
+ ]).it('does not render children when current version does not match requirements', (min, max, version) => {
+ const wrapped = renderComponent(min, max, { version });
+
+ expect(wrapped.html()).toBeNull();
+ });
+
+ each([
+ [ '2.0.0', undefined, '2.8.3' ],
+ [ '2.0.0', undefined, '2.0.0' ],
+ [ undefined, '1.8.0', '1.8.0' ],
+ [ undefined, '1.8.0', '1.7.1' ],
+ [ '1.7.0', '1.8.0', '1.7.3' ],
+ ]).it('renders children when current version matches requirements', (min, max, version) => {
+ const wrapped = renderComponent(min, max, { version });
+
+ expect(wrapped.html()).toContain('Hello');
+ });
+});
diff --git a/test/short-urls/SearchBar.test.js b/test/short-urls/SearchBar.test.js
index 172b8189..423af3cd 100644
--- a/test/short-urls/SearchBar.test.js
+++ b/test/short-urls/SearchBar.test.js
@@ -22,15 +22,10 @@ describe('', () => {
expect(wrapper.find(SearchField)).toHaveLength(1);
});
- each([
- [ '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();
+ it('renders a DateRangeRow', () => {
+ wrapper = shallow();
- expect(wrapper.find(DateRangeRow)).toHaveLength(expectedLength);
+ expect(wrapper.find(DateRangeRow)).toHaveLength(1);
});
it('renders no tags when the list of tags is empty', () => {
@@ -69,7 +64,7 @@ describe('', () => {
each([ 'startDateChange', 'endDateChange' ]).it('updates short URLs list when date range changes', (event) => {
wrapper = shallow(
-
+
);
const dateRange = wrapper.find(DateRangeRow);
diff --git a/test/short-urls/helpers/ShortUrlsRowMenu.test.js b/test/short-urls/helpers/ShortUrlsRowMenu.test.js
index 362d61e5..38d1db67 100644
--- a/test/short-urls/helpers/ShortUrlsRowMenu.test.js
+++ b/test/short-urls/helpers/ShortUrlsRowMenu.test.js
@@ -1,7 +1,6 @@
import React from 'react';
import { shallow } from 'enzyme';
import { ButtonDropdown, DropdownItem } from 'reactstrap';
-import each from 'jest-each';
import createShortUrlsRowMenu from '../../../src/short-urls/helpers/ShortUrlsRowMenu';
import PreviewModal from '../../../src/short-urls/helpers/PreviewModal';
import QrCodeModal from '../../../src/short-urls/helpers/QrCodeModal';
@@ -17,12 +16,12 @@ describe('', () => {
shortCode: 'abc123',
shortUrl: 'https://doma.in/abc123',
};
- const createWrapper = (serverVersion = '1.21.1') => {
+ const createWrapper = () => {
const ShortUrlsRowMenu = createShortUrlsRowMenu(DeleteShortUrlModal, EditTagsModal, EditMetaModal);
wrapper = shallow(
@@ -46,24 +45,12 @@ describe('', () => {
expect(qrCodeModal).toHaveLength(1);
});
- 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.21.0', 7, 2 ],
- [ '1.21.1', 7, 2 ],
- [ '2.0.0', 6, 1 ],
- [ '2.0.1', 6, 1 ],
- [ '2.1.0', 6, 1 ],
- ]).it('renders correct amount of menu items depending on the version', (version, expectedNonDividerItems, expectedDividerItems) => {
- const wrapper = createWrapper(version);
+ it('renders correct amount of menu items', () => {
+ const wrapper = createWrapper();
const items = wrapper.find(DropdownItem);
- expect(items).toHaveLength(expectedNonDividerItems + expectedDividerItems);
- expect(items.find('[divider]')).toHaveLength(expectedDividerItems);
+ expect(items).toHaveLength(9);
+ expect(items.find('[divider]')).toHaveLength(2);
});
describe('toggles state when toggling modal windows', () => {
diff --git a/test/utils/ForVersion.test.js b/test/utils/ForVersion.test.js
deleted file mode 100644
index 83be6fc5..00000000
--- a/test/utils/ForVersion.test.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { mount } from 'enzyme';
-import ForVersion from '../../src/utils/ForVersion';
-
-describe('', () => {
- let wrapped;
-
- const renderComponent = (minVersion, currentServerVersion) => {
- wrapped = mount(
-
- Hello
-
- );
-
- return wrapped;
- };
-
- afterEach(() => wrapped && wrapped.unmount());
-
- it('does not render children when current version is empty', () => {
- const wrapped = renderComponent('1', '');
-
- expect(wrapped.html()).toBeNull();
- });
-
- it('does not render children when current version is lower than min version', () => {
- const wrapped = renderComponent('2.0.0', '1.8.3');
-
- expect(wrapped.html()).toBeNull();
- });
-
- it('renders children when current version is equal min version', () => {
- const wrapped = renderComponent('2.0.0', '2.0.0');
-
- expect(wrapped.html()).toContain('Hello');
- });
-
- it('renders children when current version is higher than min version', () => {
- const wrapped = renderComponent('2.0.0', '2.1.0');
-
- expect(wrapped.html()).toContain('Hello');
- });
-});