diff --git a/src/servers/helpers/ForServerVersion.js b/src/servers/helpers/ForServerVersion.js index 0c51b22a..0b3c6fba 100644 --- a/src/servers/helpers/ForServerVersion.js +++ b/src/servers/helpers/ForServerVersion.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { serverType } from '../prop-types'; -import { compareVersions } from '../../utils/helpers/version'; +import { versionMatch } from '../../utils/helpers/version'; const propTypes = { minVersion: PropTypes.string, @@ -16,10 +16,9 @@ const ForServerVersion = ({ minVersion, maxVersion, selectedServer, children }) } const { version } = selectedServer; - const matchesMinVersion = !minVersion || compareVersions(version, '>=', minVersion); - const matchesMaxVersion = !maxVersion || compareVersions(version, '<=', maxVersion); + const matchesVersion = versionMatch(version, { maxVersion, minVersion }); - if (!matchesMinVersion || !matchesMaxVersion) { + if (!matchesVersion) { return null; } diff --git a/src/short-urls/CreateShortUrl.js b/src/short-urls/CreateShortUrl.js index e1719fe3..aa1926df 100644 --- a/src/short-urls/CreateShortUrl.js +++ b/src/short-urls/CreateShortUrl.js @@ -7,7 +7,8 @@ import * as PropTypes from 'prop-types'; import DateInput from '../utils/DateInput'; import Checkbox from '../utils/Checkbox'; import { serverType } from '../servers/prop-types'; -import { compareVersions } from '../utils/helpers/version'; +import { versionMatch } from '../utils/helpers/version'; +import { hasValue } from '../utils/utils'; import { createShortUrlResultType } from './reducers/shortUrlCreation'; import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon'; @@ -30,6 +31,7 @@ const CreateShortUrl = ( longUrl: '', tags: [], customSlug: undefined, + shortCodeLength: undefined, domain: undefined, validSince: undefined, validUntil: undefined, @@ -73,8 +75,9 @@ const CreateShortUrl = ( assoc('validUntil', formatDate(this.state.validUntil)) )(this.state)); }; - const currentServerVersion = this.props.selectedServer ? this.props.selectedServer.version : ''; - const disableDomain = isEmpty(currentServerVersion) || compareVersions(currentServerVersion, '<', '1.19.0-beta.1'); + const currentServerVersion = this.props.selectedServer && this.props.selectedServer.version; + const disableDomain = !versionMatch(currentServerVersion, { minVersion: '1.19.0-beta.1' }); + const disableShortCodeLength = !versionMatch(currentServerVersion, { minVersion: '2.1.0' }); return (
@@ -95,10 +98,19 @@ const CreateShortUrl = (
-
+
{renderOptionalInput('customSlug', 'Custom slug')}
-
+
+ {renderOptionalInput('shortCodeLength', 'Short code length', 'number', { + min: 4, + disabled: disableShortCodeLength || hasValue(this.state.customSlug), + ...disableShortCodeLength && { + title: 'Shlink 2.1.0 or higher is required to be able to provide the short code length', + }, + })} +
+
{renderOptionalInput('domain', 'Domain', 'text', { disabled: disableDomain, ...disableDomain && { title: 'Shlink 1.19.0 or higher is required to be able to provide the domain' }, @@ -107,13 +119,13 @@ const CreateShortUrl = (
-
+
{renderOptionalInput('maxVisits', 'Maximum number of visits allowed', 'number', { min: 1 })}
-
+
{renderDateInput('validSince', 'Enabled since...', { maxDate: this.state.validUntil })}
-
+
{renderDateInput('validUntil', 'Enabled until...', { minDate: this.state.validSince })}
diff --git a/src/utils/helpers/version.js b/src/utils/helpers/version.js index 92867939..5d62603a 100644 --- a/src/utils/helpers/version.js +++ b/src/utils/helpers/version.js @@ -1,15 +1,21 @@ import { compare } from 'compare-versions'; import { identity, memoizeWith } from 'ramda'; +import { hasValue } from '../utils'; -export const compareVersions = (firstVersion, operator, secondVersion) => compare( - firstVersion, - secondVersion, - operator, -); +export const versionMatch = (versionToMatch, { maxVersion, minVersion }) => { + if (!hasValue(versionToMatch)) { + return false; + } + + const matchesMinVersion = !minVersion || compare(versionToMatch, minVersion, '>='); + const matchesMaxVersion = !maxVersion || compare(versionToMatch, maxVersion, '<='); + + return !!(matchesMaxVersion && matchesMinVersion); +}; const versionIsValidSemVer = memoizeWith(identity, (version) => { try { - return compareVersions(version, '=', version); + return compare(version, version, '='); } catch (e) { return false; } diff --git a/src/utils/utils.js b/src/utils/utils.js index 0abda883..ee2ee170 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -2,7 +2,7 @@ import L from 'leaflet'; import marker2x from 'leaflet/dist/images/marker-icon-2x.png'; import marker from 'leaflet/dist/images/marker-icon.png'; import markerShadow from 'leaflet/dist/images/marker-shadow.png'; -import { range } from 'ramda'; +import { isEmpty, isNil, range } from 'ramda'; const TEN_ROUNDING_NUMBER = 10; const DEFAULT_TIMEOUT_DELAY = 2000; @@ -45,3 +45,4 @@ export const rangeOf = (size, mappingFn, startAt = 1) => range(startAt, size + 1 export const roundTen = (number) => ceil(number / TEN_ROUNDING_NUMBER) * TEN_ROUNDING_NUMBER; +export const hasValue = (value) => !isNil(value) && !isEmpty(value); diff --git a/test/utils/helpers/version.test.js b/test/utils/helpers/version.test.js new file mode 100644 index 00000000..adcfdee9 --- /dev/null +++ b/test/utils/helpers/version.test.js @@ -0,0 +1,23 @@ +import { versionMatch } from '../../../src/utils/helpers/version'; + +describe('version', () => { + describe('versionMatch', () => { + it.each([ + [ undefined, {}, false ], + [ null, {}, false ], + [ '', {}, false ], + [[], {}, false ], + [ '2.8.3', {}, true ], + [ '2.8.3', { minVersion: '2.0.0' }, true ], + [ '2.0.0', { minVersion: '2.0.0' }, true ], + [ '1.8.0', { maxVersion: '1.8.0' }, true ], + [ '1.7.1', { maxVersion: '1.8.0' }, true ], + [ '1.7.3', { minVersion: '1.7.0', maxVersion: '1.8.0' }, true ], + [ '1.8.3', { minVersion: '2.0.0' }, false ], + [ '1.8.3', { maxVersion: '1.8.0' }, false ], + [ '1.8.3', { minVersion: '1.7.0', maxVersion: '1.8.0' }, false ], + ])('properly matches versions based on what is provided', (version, versionConstraints, expected) => { + expect(versionMatch(version, versionConstraints)).toEqual(expected); + }); + }); +});