import { isEmpty, pipe, replace, trim } from 'ramda'; import { FC, useState } from 'react'; import { Button, FormGroup, Input } from 'reactstrap'; import { InputType } from 'reactstrap/lib/Input'; import * as m from 'moment'; import DateInput, { DateInputProps } from '../utils/DateInput'; import Checkbox from '../utils/Checkbox'; import { versionMatch, Versions } from '../utils/helpers/version'; import { handleEventPreventingDefault, hasValue } from '../utils/utils'; import { isReachableServer, SelectedServer } from '../servers/data'; import { formatIsoDate } from '../utils/helpers/date'; import { TagsSelectorProps } from '../tags/helpers/TagsSelector'; import { DomainSelectorProps } from '../domains/DomainSelector'; import { SimpleCard } from '../utils/SimpleCard'; import { ShortUrlData } from './data'; import { ShortUrlCreation } from './reducers/shortUrlCreation'; import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon'; import { CreateShortUrlResultProps } from './helpers/CreateShortUrlResult'; import './CreateShortUrl.scss'; export interface CreateShortUrlProps { basicMode?: boolean; } interface CreateShortUrlConnectProps extends CreateShortUrlProps { shortUrlCreationResult: ShortUrlCreation; selectedServer: SelectedServer; createShortUrl: (data: ShortUrlData) => Promise; resetCreateShortUrl: () => void; } export const normalizeTag = pipe(trim, replace(/ /g, '-')); const initialState: ShortUrlData = { longUrl: '', tags: [], customSlug: '', shortCodeLength: undefined, domain: '', validSince: undefined, validUntil: undefined, maxVisits: undefined, findIfExists: false, validateUrl: true, }; type NonDateFields = 'longUrl' | 'customSlug' | 'shortCodeLength' | 'domain' | 'maxVisits'; type DateFields = 'validSince' | 'validUntil'; const CreateShortUrl = ( TagsSelector: FC, CreateShortUrlResult: FC, ForServerVersion: FC, DomainSelector: FC, ) => ({ createShortUrl, shortUrlCreationResult, resetCreateShortUrl, selectedServer, basicMode = false, }: CreateShortUrlConnectProps) => { const [ shortUrlCreation, setShortUrlCreation ] = useState(initialState); const changeTags = (tags: string[]) => setShortUrlCreation({ ...shortUrlCreation, tags: tags.map(normalizeTag) }); const reset = () => setShortUrlCreation(initialState); const save = handleEventPreventingDefault(() => { const shortUrlData = { ...shortUrlCreation, validSince: formatIsoDate(shortUrlCreation.validSince) ?? undefined, validUntil: formatIsoDate(shortUrlCreation.validUntil) ?? undefined, }; createShortUrl(shortUrlData).then(reset).catch(() => {}); }); const renderOptionalInput = (id: NonDateFields, placeholder: string, type: InputType = 'text', props = {}) => ( setShortUrlCreation({ ...shortUrlCreation, [id]: e.target.value })} {...props} /> ); const renderDateInput = (id: DateFields, placeholder: string, props: Partial = {}) => (
setShortUrlCreation({ ...shortUrlCreation, [id]: date })} {...props} />
); const basicComponents = ( <> setShortUrlCreation({ ...shortUrlCreation, longUrl: e.target.value })} /> ); const currentServerVersion = isReachableServer(selectedServer) ? selectedServer.version : ''; const disableDomain = !versionMatch(currentServerVersion, { minVersion: '1.19.0-beta.1' }); const showDomainSelector = versionMatch(currentServerVersion, { minVersion: '2.4.0' }); const disableShortCodeLength = !versionMatch(currentServerVersion, { minVersion: '2.1.0' }); return (
{basicMode && basicComponents} {!basicMode && ( <> {basicComponents}
{renderOptionalInput('customSlug', 'Custom slug', 'text', { disabled: hasValue(shortUrlCreation.shortCodeLength), })} {renderOptionalInput('shortCodeLength', 'Short code length', 'number', { min: 4, disabled: disableShortCodeLength || hasValue(shortUrlCreation.customSlug), ...disableShortCodeLength && { title: 'Shlink 2.1.0 or higher is required to be able to provide the short code length', }, })} {!showDomainSelector && renderOptionalInput('domain', 'Domain', 'text', { disabled: disableDomain, ...disableDomain && { title: 'Shlink 1.19.0 or higher is required to be able to provide the domain' }, })} {showDomainSelector && ( setShortUrlCreation({ ...shortUrlCreation, domain })} /> )}
{renderOptionalInput('maxVisits', 'Maximum number of visits allowed', 'number', { min: 1 })} {renderDateInput('validSince', 'Enabled since...', { maxDate: shortUrlCreation.validUntil as m.Moment | undefined })} {renderDateInput('validUntil', 'Enabled until...', { minDate: shortUrlCreation.validSince as m.Moment | undefined })}

Make sure the long URL is valid, or ensure an existing short URL is returned if it matches all provided data.

setShortUrlCreation({ ...shortUrlCreation, validateUrl })} > Validate URL

setShortUrlCreation({ ...shortUrlCreation, findIfExists })} > Use existing URL if found

)}
); }; export default CreateShortUrl;