feat(feeds): torznab add test button (#347)

This commit is contained in:
Ludvig Lundgren 2022-07-10 15:54:56 +02:00 committed by GitHub
parent c1df9c817f
commit ebba72ec1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 804 additions and 186 deletions

View file

@ -98,7 +98,8 @@ export const APIClient = {
create: (feed: FeedCreate) => appClient.Post("api/feeds", feed),
toggleEnable: (id: number, enabled: boolean) => appClient.Patch(`api/feeds/${id}/enabled`, { enabled }),
update: (feed: Feed) => appClient.Put(`api/feeds/${feed.id}`, feed),
delete: (id: number) => appClient.Delete(`api/feeds/${id}`)
delete: (id: number) => appClient.Delete(`api/feeds/${id}`),
test: (feed: Feed) => appClient.Post("api/feeds/test", feed),
},
indexers: {
// returns indexer options for all currently present/enabled indexers

View file

@ -18,6 +18,9 @@ interface SlideOverProps<DataType> {
deleteAction?: () => void;
type: "CREATE" | "UPDATE";
testFn?: (data: unknown) => void;
isTesting?: boolean;
isTestSuccessful?: boolean;
isTestError?: boolean;
}
function SlideOver<DataType>({
@ -30,7 +33,10 @@ function SlideOver<DataType>({
toggle,
type,
children,
testFn
testFn,
isTesting,
isTestSuccessful,
isTestError,
}: SlideOverProps<DataType>): React.ReactElement {
const cancelModalButtonRef = useRef<HTMLInputElement | null>(null);
const [deleteModalIsOpen, toggleDeleteModal] = useToggle(false);
@ -121,10 +127,46 @@ function SlideOver<DataType>({
{testFn && (
<button
type="button"
className="mr-2 bg-white dark:bg-gray-700 py-2 px-4 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-blue-500"
className={classNames(
isTestSuccessful
? "text-green-500 border-green-500 bg-green-50"
: isTestError
? "text-red-500 border-red-500 bg-red-50"
: "border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-400 bg-white dark:bg-gray-700 hover:bg-gray-50 focus:border-rose-700 active:bg-rose-700",
isTesting ? "cursor-not-allowed" : "",
"mr-2 inline-flex items-center px-4 py-2 border font-medium rounded-md shadow-sm text-sm transition ease-in-out duration-150 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-blue-500"
)}
disabled={isTesting}
onClick={() => test(values)}
>
Test
{isTesting ? (
<svg
className="animate-spin h-5 w-5 text-green-500"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
) : isTestSuccessful ? (
"OK!"
) : isTestError ? (
"ERROR"
) : (
"Test"
)}
</button>
)}

View file

@ -7,6 +7,8 @@ import { SlideOver } from "../../components/panels";
import { NumberFieldWide, PasswordFieldWide, SwitchGroupWide, TextFieldWide } from "../../components/inputs";
import { ImplementationMap } from "../../screens/settings/Feed";
import { componentMapType } from "./DownloadClientForms";
import { sleep } from "../../utils";
import { useState } from "react";
interface UpdateProps {
isOpen: boolean;
@ -15,6 +17,10 @@ interface UpdateProps {
}
export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
const [isTesting, setIsTesting] = useState(false);
const [isTestSuccessful, setIsSuccessfulTest] = useState(false);
const [isTestError, setIsErrorTest] = useState(false);
const mutation = useMutation(
(feed: Feed) => APIClient.feeds.update(feed),
{
@ -26,6 +32,10 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
}
);
const onSubmit = (formData: unknown) => {
mutation.mutate(formData as Feed);
};
const deleteMutation = useMutation(
(feedID: number) => APIClient.feeds.delete(feedID),
{
@ -36,14 +46,45 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
}
);
const onSubmit = (formData: unknown) => {
mutation.mutate(formData as Feed);
};
const deleteAction = () => {
deleteMutation.mutate(feed.id);
};
const testFeedMutation = useMutation(
(feed: Feed) => APIClient.feeds.test(feed),
{
onMutate: () => {
setIsTesting(true);
setIsErrorTest(false);
setIsSuccessfulTest(false);
},
onSuccess: () => {
sleep(1000)
.then(() => {
setIsTesting(false);
setIsSuccessfulTest(true);
})
.then(() => {
sleep(2500).then(() => {
setIsSuccessfulTest(false);
});
});
},
onError: () => {
setIsTesting(false);
setIsErrorTest(true);
sleep(2500).then(() => {
setIsErrorTest(false);
});
}
}
);
const testFeed = (data: unknown) => {
testFeedMutation.mutate(data as Feed);
};
const initialValues = {
id: feed.id,
indexer: feed.indexer,
@ -64,6 +105,10 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
onSubmit={onSubmit}
deleteAction={deleteAction}
initialValues={initialValues}
testFn={testFeed}
isTesting={isTesting}
isTestSuccessful={isTestSuccessful}
isTestError={isTestError}
>
{(values) => (
<div>