fix(web): TS typings and always active navbar link (#470)

* fix TS typings since `yarn build` was failing on my machine.
* fixed the dashboard navlink (it was always active on my end)
This commit is contained in:
stacksmash76 2022-09-23 19:03:00 +02:00 committed by GitHub
parent 8a782a5cab
commit 553320bf1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 35 deletions

View file

@ -4,6 +4,7 @@ import { classNames, get } from "../../utils";
import { useToggle } from "../../hooks/hooks";
import { EyeIcon, EyeSlashIcon } from "@heroicons/react/24/solid";
import { ErrorMessage } from "@hookform/error-message";
import type { FieldValues } from "react-hook-form";
export type FormErrorMessageProps = {
className?: string;
@ -81,7 +82,7 @@ export const Input: FC<InputProps> = forwardRef<HTMLInputElement, InputProps>(
export type FormInputProps<TFormValues> = {
name: Path<TFormValues>;
rules?: RegisterOptions;
register?: UseFormRegister<TFormValues>;
register?: UseFormRegister<TFormValues & FieldValues>;
errors?: Partial<DeepMap<TFormValues, FieldError>>;
} & Omit<InputProps, "name">;

View file

@ -1,26 +1,27 @@
import React, {Fragment, useRef} from "react";
import {XMarkIcon} from "@heroicons/react/24/solid";
import {Dialog, Transition} from "@headlessui/react";
import {Form, Formik} from "formik";
import React, { Fragment, useRef } from "react";
import { XMarkIcon } from "@heroicons/react/24/solid";
import { Dialog, Transition } from "@headlessui/react";
import { Form, Formik } from "formik";
import type { FormikValues } from "formik";
import DEBUG from "../debug";
import {useToggle} from "../../hooks/hooks";
import {DeleteModal} from "../modals";
import {classNames} from "../../utils";
import { useToggle } from "../../hooks/hooks";
import { DeleteModal } from "../modals";
import { classNames } from "../../utils";
interface SlideOverProps<DataType> {
title: string;
initialValues: DataType;
validate?: (values: DataType) => void;
onSubmit: (values?: DataType) => void;
isOpen: boolean;
toggle: () => void;
children?: (values: DataType) => React.ReactNode;
deleteAction?: () => void;
type: "CREATE" | "UPDATE";
testFn?: (data: unknown) => void;
isTesting?: boolean;
isTestSuccessful?: boolean;
isTestError?: boolean;
title: string;
initialValues: FormikValues & DataType;
validate?: (values: DataType) => void;
onSubmit: (values?: DataType) => void;
isOpen: boolean;
toggle: () => void;
children?: (values: DataType) => React.ReactNode;
deleteAction?: () => void;
type: "CREATE" | "UPDATE";
testFn?: (data: unknown) => void;
isTesting?: boolean;
isTestSuccessful?: boolean;
isTestError?: boolean;
}
function SlideOver<DataType>({
@ -81,7 +82,7 @@ function SlideOver<DataType>({
onSubmit={onSubmit}
validate={validate}
>
{({ handleSubmit, values }) => (
{({ handleSubmit, values }) => (
<Form className="h-full flex flex-col bg-white dark:bg-gray-800 shadow-xl overflow-y-scroll"
onSubmit={handleSubmit}>

View file

@ -16,6 +16,17 @@ interface UpdateProps {
feed: Feed;
}
interface InitialValues {
id: number;
indexer: string;
enabled: boolean;
type: FeedType;
name: string;
url: string;
api_key: string;
interval: number;
}
export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
const [isTesting, setIsTesting] = useState(false);
const [isTestSuccessful, setIsSuccessfulTest] = useState(false);
@ -26,7 +37,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
{
onSuccess: () => {
queryClient.invalidateQueries(["feeds"]);
toast.custom((t) => <Toast type="success" body={`${feed.name} was updated successfully`} t={t}/>);
toast.custom((t) => <Toast type="success" body={`${feed.name} was updated successfully`} t={t} />);
toggle();
}
}
@ -41,12 +52,11 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
{
onSuccess: () => {
queryClient.invalidateQueries(["feeds"]);
toast.custom((t) => <Toast type="success" body={`${feed.name} was deleted.`} t={t}/>);
toast.custom((t) => <Toast type="success" body={`${feed.name} was deleted.`} t={t} />);
}
}
);
const deleteAction = () => {
deleteMutation.mutate(feed.id);
};
@ -85,7 +95,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
testFeedMutation.mutate(data as Feed);
};
const initialValues = {
const initialValues: InitialValues = {
id: feed.id,
indexer: feed.indexer,
enabled: feed.enabled,
@ -97,7 +107,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
};
return (
<SlideOver
<SlideOver<InitialValues>
type="UPDATE"
title="Feed"
isOpen={isOpen}
@ -112,7 +122,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
>
{(values) => (
<div>
<TextFieldWide name="name" label="Name" required={true}/>
<TextFieldWide name="name" label="Name" required={true} />
<div className="space-y-4 divide-y divide-gray-200 dark:divide-gray-700">
<div
@ -131,7 +141,7 @@ export function FeedUpdateForm({ isOpen, toggle, feed }: UpdateProps) {
</div>
<div className="py-6 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-gray-200">
<SwitchGroupWide name="enabled" label="Enabled"/>
<SwitchGroupWide name="enabled" label="Enabled" />
</div>
</div>
{componentMap[values.type]}
@ -150,10 +160,10 @@ function FormFieldsTorznab() {
help="Torznab url"
/>
<PasswordFieldWide name="api_key" label="API key"/>
<PasswordFieldWide name="api_key" label="API key" />
<NumberFieldWide name="interval" label="Refresh interval"
help="Minutes. Recommended 15-30. Too low and risk ban."/>
help="Minutes. Recommended 15-30. Too low and risk ban." />
</div>
);
}
@ -167,12 +177,12 @@ function FormFieldsRSS() {
help="RSS url"
/>
<NumberFieldWide name="interval" label="Refresh interval" help="Minutes. Recommended 15-30. Too low and risk ban."/>
<NumberFieldWide name="interval" label="Refresh interval" help="Minutes. Recommended 15-30. Too low and risk ban." />
</div>
);
}
const componentMap: componentMapType = {
TORZNAB: <FormFieldsTorznab/>,
TORZNAB: <FormFieldsTorznab />,
RSS: <FormFieldsRSS />
};

View file

@ -394,6 +394,18 @@ interface UpdateProps {
notification: Notification;
}
interface InitialValues {
id: number;
enabled: boolean;
type: NotificationType;
name: string;
webhook?: string;
token?: string;
api_key?: string;
channel?: string;
events: NotificationEvent[];
}
export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateProps) {
const mutation = useMutation(
(notification: Notification) => APIClient.notifications.update(notification),
@ -437,7 +449,7 @@ export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateP
testMutation.mutate(data as Notification);
};
const initialValues = {
const initialValues: InitialValues = {
id: notification.id,
enabled: notification.enabled,
type: notification.type,
@ -450,7 +462,7 @@ export function NotificationUpdateForm({ isOpen, toggle, notification }: UpdateP
};
return (
<SlideOver
<SlideOver<InitialValues>
type="UPDATE"
title="Notification"
isOpen={isOpen}

View file

@ -62,6 +62,7 @@ export default function Base() {
"transition-colors duration-200",
isActive ? "text-black dark:text-gray-50 font-bold" : "text-gray-600 dark:text-gray-500"
)}
end={item.path === "/"}
>
{item.name}
</NavLink>