2021-03-27 20:56:24 +03:00
|
|
|
import { FC, useEffect, useMemo } from 'react';
|
2021-03-27 19:56:46 +03:00
|
|
|
import { Button, Card } from 'reactstrap';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
|
import { faArrowLeft } from '@fortawesome/free-solid-svg-icons';
|
|
|
|
import { ExternalLink } from 'react-external-link';
|
2022-02-06 22:07:18 +03:00
|
|
|
import { useLocation, useParams } from 'react-router-dom';
|
2021-03-20 18:32:12 +03:00
|
|
|
import { SelectedServer } from '../servers/data';
|
|
|
|
import { Settings, ShortUrlCreationSettings } from '../settings/reducers/settings';
|
|
|
|
import { OptionalString } from '../utils/utils';
|
|
|
|
import { parseQuery } from '../utils/helpers/query';
|
|
|
|
import Message from '../utils/Message';
|
|
|
|
import { Result } from '../utils/Result';
|
|
|
|
import { ShlinkApiError } from '../api/ShlinkApiError';
|
2022-02-06 22:07:18 +03:00
|
|
|
import { useGoBack, useToggle } from '../utils/helpers/hooks';
|
2021-03-20 18:32:12 +03:00
|
|
|
import { ShortUrlFormProps } from './ShortUrlForm';
|
|
|
|
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
2021-03-27 11:49:47 +03:00
|
|
|
import { EditShortUrlData, ShortUrl, ShortUrlData } from './data';
|
2021-03-27 12:27:46 +03:00
|
|
|
import { ShortUrlEdition } from './reducers/shortUrlEdition';
|
2021-03-20 18:32:12 +03:00
|
|
|
|
2022-02-06 22:07:18 +03:00
|
|
|
interface EditShortUrlConnectProps {
|
2021-03-20 18:32:12 +03:00
|
|
|
settings: Settings;
|
|
|
|
selectedServer: SelectedServer;
|
|
|
|
shortUrlDetail: ShortUrlDetail;
|
2021-03-27 12:27:46 +03:00
|
|
|
shortUrlEdition: ShortUrlEdition;
|
2021-03-20 18:32:12 +03:00
|
|
|
getShortUrlDetail: (shortCode: string, domain: OptionalString) => void;
|
2021-03-27 11:49:47 +03:00
|
|
|
editShortUrl: (shortUrl: string, domain: OptionalString, data: EditShortUrlData) => Promise<void>;
|
2021-03-20 18:32:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const getInitialState = (shortUrl?: ShortUrl, settings?: ShortUrlCreationSettings): ShortUrlData => {
|
|
|
|
const validateUrl = settings?.validateUrls ?? false;
|
|
|
|
|
|
|
|
if (!shortUrl) {
|
|
|
|
return { longUrl: '', validateUrl };
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
longUrl: shortUrl.longUrl,
|
|
|
|
tags: shortUrl.tags,
|
|
|
|
title: shortUrl.title ?? undefined,
|
|
|
|
domain: shortUrl.domain ?? undefined,
|
|
|
|
validSince: shortUrl.meta.validSince ?? undefined,
|
|
|
|
validUntil: shortUrl.meta.validUntil ?? undefined,
|
|
|
|
maxVisits: shortUrl.meta.maxVisits ?? undefined,
|
2021-06-23 20:52:19 +03:00
|
|
|
crawlable: shortUrl.crawlable,
|
2021-10-13 23:50:48 +03:00
|
|
|
forwardQuery: shortUrl.forwardQuery,
|
2021-03-20 18:32:12 +03:00
|
|
|
validateUrl,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
|
|
|
settings: { shortUrlCreation: shortUrlCreationSettings },
|
|
|
|
selectedServer,
|
|
|
|
shortUrlDetail,
|
|
|
|
getShortUrlDetail,
|
2021-03-27 12:27:46 +03:00
|
|
|
shortUrlEdition,
|
2021-03-27 11:49:47 +03:00
|
|
|
editShortUrl,
|
2021-03-20 18:32:12 +03:00
|
|
|
}: EditShortUrlConnectProps) => {
|
2022-02-06 22:07:18 +03:00
|
|
|
const { search } = useLocation();
|
|
|
|
const params = useParams<{ shortCode: string }>();
|
|
|
|
const goBack = useGoBack();
|
2021-03-20 18:32:12 +03:00
|
|
|
const { loading, error, errorData, shortUrl } = shortUrlDetail;
|
2021-03-27 12:27:46 +03:00
|
|
|
const { saving, error: savingError, errorData: savingErrorData } = shortUrlEdition;
|
2021-03-20 18:32:12 +03:00
|
|
|
const { domain } = parseQuery<{ domain?: string }>(search);
|
2021-03-27 20:56:24 +03:00
|
|
|
const initialState = useMemo(
|
|
|
|
() => getInitialState(shortUrl, shortUrlCreationSettings),
|
|
|
|
[ shortUrl, shortUrlCreationSettings ],
|
|
|
|
);
|
2021-05-08 11:56:20 +03:00
|
|
|
const [ savingSucceeded,, isSuccessful, isNotSuccessful ] = useToggle();
|
2021-03-20 18:32:12 +03:00
|
|
|
|
|
|
|
useEffect(() => {
|
2022-02-06 22:07:18 +03:00
|
|
|
params.shortCode && getShortUrlDetail(params.shortCode, domain);
|
2021-03-20 18:32:12 +03:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
return <Message loading />;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
return (
|
|
|
|
<Result type="error">
|
|
|
|
<ShlinkApiError errorData={errorData} fallbackMessage="An error occurred while loading short URL detail :(" />
|
|
|
|
</Result>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2021-03-27 12:41:13 +03:00
|
|
|
<>
|
2021-03-27 19:56:46 +03:00
|
|
|
<header className="mb-3">
|
|
|
|
<Card body>
|
|
|
|
<h2 className="d-sm-flex justify-content-between align-items-center mb-0">
|
2022-03-05 15:26:28 +03:00
|
|
|
<Button color="link" size="lg" className="p-0 me-3" onClick={goBack}>
|
2021-03-27 19:56:46 +03:00
|
|
|
<FontAwesomeIcon icon={faArrowLeft} />
|
|
|
|
</Button>
|
2021-05-08 11:56:20 +03:00
|
|
|
<span className="text-center">
|
|
|
|
<small>Edit <ExternalLink href={shortUrl?.shortUrl ?? ''} /></small>
|
|
|
|
</span>
|
2021-03-27 19:56:46 +03:00
|
|
|
<span />
|
|
|
|
</h2>
|
|
|
|
</Card>
|
|
|
|
</header>
|
2021-03-27 12:41:13 +03:00
|
|
|
<ShortUrlForm
|
2021-03-27 20:56:24 +03:00
|
|
|
initialState={initialState}
|
2021-03-27 12:41:13 +03:00
|
|
|
saving={saving}
|
|
|
|
selectedServer={selectedServer}
|
|
|
|
mode="edit"
|
2021-05-08 11:56:20 +03:00
|
|
|
onSave={async (shortUrlData) => {
|
|
|
|
if (!shortUrl) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
isNotSuccessful();
|
|
|
|
editShortUrl(shortUrl.shortCode, shortUrl.domain, shortUrlData)
|
|
|
|
.then(isSuccessful)
|
|
|
|
.catch(isNotSuccessful);
|
|
|
|
}}
|
2021-03-27 12:41:13 +03:00
|
|
|
/>
|
2021-03-27 12:27:46 +03:00
|
|
|
{savingError && (
|
|
|
|
<Result type="error" className="mt-3">
|
|
|
|
<ShlinkApiError errorData={savingErrorData} fallbackMessage="An error occurred while updating short URL :(" />
|
|
|
|
</Result>
|
|
|
|
)}
|
2021-05-08 11:56:20 +03:00
|
|
|
{savingSucceeded && <Result type="success" className="mt-3">Short URL properly edited.</Result>}
|
2021-03-27 12:41:13 +03:00
|
|
|
</>
|
2021-03-20 18:32:12 +03:00
|
|
|
);
|
|
|
|
};
|