* feat: update prettier configuration for print width * chore: apply code formatting to entire repository * fix: remove build files * fix: format issue --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
130 lines
4.0 KiB
TypeScript
130 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
import { useRef, useState } from "react";
|
|
import { Alert, Anchor, Group, Loader } from "@mantine/core";
|
|
import { IconCheck, IconInfoCircle, IconX } from "@tabler/icons-react";
|
|
|
|
import type { RouterInputs } from "@homarr/api";
|
|
import { clientApi } from "@homarr/api/client";
|
|
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
|
|
import { useI18n, useScopedI18n } from "@homarr/translation/client";
|
|
|
|
interface UseTestConnectionDirtyProps {
|
|
defaultDirty: boolean;
|
|
initialFormValue: {
|
|
url: string;
|
|
secrets: { kind: string; value: string | null }[];
|
|
};
|
|
}
|
|
|
|
export const useTestConnectionDirty = ({ defaultDirty, initialFormValue }: UseTestConnectionDirtyProps) => {
|
|
const [isDirty, setIsDirty] = useState(defaultDirty);
|
|
const prevFormValueRef = useRef(initialFormValue);
|
|
|
|
return {
|
|
onValuesChange: (values: typeof initialFormValue) => {
|
|
if (isDirty) return;
|
|
|
|
// If relevant values changed, set dirty
|
|
if (
|
|
prevFormValueRef.current.url !== values.url ||
|
|
!prevFormValueRef.current.secrets
|
|
.map((secret) => secret.value)
|
|
.every((secretValue, index) => values.secrets[index]?.value === secretValue)
|
|
) {
|
|
setIsDirty(true);
|
|
return;
|
|
}
|
|
|
|
// If relevant values changed back to last tested, set not dirty
|
|
setIsDirty(false);
|
|
},
|
|
isDirty,
|
|
removeDirty: () => {
|
|
prevFormValueRef.current = initialFormValue;
|
|
setIsDirty(false);
|
|
},
|
|
};
|
|
};
|
|
|
|
interface TestConnectionProps {
|
|
isDirty: boolean;
|
|
removeDirty: () => void;
|
|
integration: RouterInputs["integration"]["testConnection"] & { name: string };
|
|
}
|
|
|
|
export const TestConnection = ({ integration, removeDirty, isDirty }: TestConnectionProps) => {
|
|
const t = useScopedI18n("integration.testConnection");
|
|
const { mutateAsync, ...mutation } = clientApi.integration.testConnection.useMutation();
|
|
|
|
return (
|
|
<Group>
|
|
<Anchor
|
|
type="button"
|
|
component="button"
|
|
onClick={async () => {
|
|
await mutateAsync(integration, {
|
|
onSuccess: () => {
|
|
removeDirty();
|
|
showSuccessNotification({
|
|
title: t("notification.success.title"),
|
|
message: t("notification.success.message"),
|
|
});
|
|
},
|
|
onError: (error) => {
|
|
if (error.data?.zodError?.fieldErrors.url) {
|
|
showErrorNotification({
|
|
title: t("notification.invalidUrl.title"),
|
|
message: t("notification.invalidUrl.message"),
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (error.message === "SECRETS_NOT_DEFINED") {
|
|
showErrorNotification({
|
|
title: t("notification.notAllSecretsProvided.title"),
|
|
message: t("notification.notAllSecretsProvided.message"),
|
|
});
|
|
return;
|
|
}
|
|
|
|
showErrorNotification({
|
|
title: t("notification.commonError.title"),
|
|
message: t("notification.commonError.message"),
|
|
});
|
|
},
|
|
});
|
|
}}
|
|
>
|
|
{t("action")}
|
|
</Anchor>
|
|
<TestConnectionIcon isDirty={isDirty} {...mutation} size={20} />
|
|
</Group>
|
|
);
|
|
};
|
|
|
|
interface TestConnectionIconProps {
|
|
isDirty: boolean;
|
|
isPending: boolean;
|
|
isSuccess: boolean;
|
|
isError: boolean;
|
|
size: number;
|
|
}
|
|
|
|
const TestConnectionIcon = ({ isDirty, isPending, isSuccess, isError, size }: TestConnectionIconProps) => {
|
|
if (isPending) return <Loader color="blue" size={size} />;
|
|
if (isDirty) return null;
|
|
if (isSuccess) return <IconCheck size={size} stroke={1.5} color="green" />;
|
|
if (isError) return <IconX size={size} stroke={1.5} color="red" />;
|
|
return null;
|
|
};
|
|
|
|
export const TestConnectionNoticeAlert = () => {
|
|
const t = useI18n();
|
|
return (
|
|
<Alert variant="light" color="yellow" title="Test Connection" icon={<IconInfoCircle />}>
|
|
{t("integration.testConnection.alertNotice")}
|
|
</Alert>
|
|
);
|
|
};
|