chore: update prettier configuration for print width (#519)

* 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>
This commit is contained in:
Thomas Camlong
2024-05-19 22:38:39 +02:00
committed by GitHub
parent 919161798e
commit f1b1ec59ec
234 changed files with 2444 additions and 5375 deletions

View File

@@ -6,10 +6,7 @@ import { IconTrash } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client";
import { useConfirmModal } from "@homarr/modals";
import {
showErrorNotification,
showSuccessNotification,
} from "@homarr/notifications";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { revalidatePathActionAsync } from "../../../revalidatePathAction";
@@ -19,10 +16,7 @@ interface DeleteIntegrationActionButtonProps {
integration: { id: string; name: string };
}
export const DeleteIntegrationActionButton = ({
count,
integration,
}: DeleteIntegrationActionButtonProps) => {
export const DeleteIntegrationActionButton = ({ count, integration }: DeleteIntegrationActionButtonProps) => {
const t = useScopedI18n("integration.page.delete");
const router = useRouter();
const { openConfirmModal } = useConfirmModal();

View File

@@ -2,17 +2,7 @@
import { useState } from "react";
import { useParams } from "next/navigation";
import {
ActionIcon,
Avatar,
Button,
Card,
Collapse,
Group,
Kbd,
Stack,
Text,
} from "@mantine/core";
import { ActionIcon, Avatar, Button, Card, Collapse, Group, Kbd, Stack, Text } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { IconEye, IconEyeOff } from "@tabler/icons-react";
import dayjs from "dayjs";
@@ -36,8 +26,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => {
const params = useParams<{ locale: string }>();
const t = useI18n();
const { isPublic } = integrationSecretKindObject[secret.kind];
const [publicSecretDisplayOpened, { toggle: togglePublicSecretDisplay }] =
useDisclosure(false);
const [publicSecretDisplayOpened, { toggle: togglePublicSecretDisplay }] = useDisclosure(false);
const [editMode, setEditMode] = useState(false);
const DisplayIcon = publicSecretDisplayOpened ? IconEye : IconEyeOff;
const KindIcon = integrationSecretIcons[secret.kind];
@@ -50,9 +39,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => {
<Avatar>
<KindIcon size={16} />
</Avatar>
<Text fw={500}>
{t(`integration.secrets.kind.${secret.kind}.label`)}
</Text>
<Text fw={500}>{t(`integration.secrets.kind.${secret.kind}.label`)}</Text>
{publicSecretDisplayOpened ? <Kbd>{secret.value}</Kbd> : null}
</Group>
<Group>
@@ -62,11 +49,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => {
})}
</Text>
{isPublic ? (
<ActionIcon
color="gray"
variant="subtle"
onClick={togglePublicSecretDisplay}
>
<ActionIcon color="gray" variant="subtle" onClick={togglePublicSecretDisplay}>
<DisplayIcon size={16} stroke={1.5} />
</ActionIcon>
) : null}

View File

@@ -42,10 +42,7 @@ const PublicSecretInput = ({ kind, ...props }: IntegrationSecretInputProps) => {
);
};
const PrivateSecretInput = ({
kind,
...props
}: IntegrationSecretInputProps) => {
const PrivateSecretInput = ({ kind, ...props }: IntegrationSecretInputProps) => {
const t = useI18n();
const Icon = integrationSecretIcons[kind];

View File

@@ -6,10 +6,7 @@ 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 { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
interface UseTestConnectionDirtyProps {
@@ -20,10 +17,7 @@ interface UseTestConnectionDirtyProps {
};
}
export const useTestConnectionDirty = ({
defaultDirty,
initialFormValue,
}: UseTestConnectionDirtyProps) => {
export const useTestConnectionDirty = ({ defaultDirty, initialFormValue }: UseTestConnectionDirtyProps) => {
const [isDirty, setIsDirty] = useState(defaultDirty);
const prevFormValueRef = useRef(initialFormValue);
@@ -36,10 +30,7 @@ export const useTestConnectionDirty = ({
prevFormValueRef.current.url !== values.url ||
!prevFormValueRef.current.secrets
.map((secret) => secret.value)
.every(
(secretValue, index) =>
values.secrets[index]?.value === secretValue,
)
.every((secretValue, index) => values.secrets[index]?.value === secretValue)
) {
setIsDirty(true);
return;
@@ -62,14 +53,9 @@ interface TestConnectionProps {
integration: RouterInputs["integration"]["testConnection"] & { name: string };
}
export const TestConnection = ({
integration,
removeDirty,
isDirty,
}: TestConnectionProps) => {
export const TestConnection = ({ integration, removeDirty, isDirty }: TestConnectionProps) => {
const t = useScopedI18n("integration.testConnection");
const { mutateAsync, ...mutation } =
clientApi.integration.testConnection.useMutation();
const { mutateAsync, ...mutation } = clientApi.integration.testConnection.useMutation();
return (
<Group>
@@ -125,13 +111,7 @@ interface TestConnectionIconProps {
size: number;
}
const TestConnectionIcon = ({
isDirty,
isPending,
isSuccess,
isError,
size,
}: TestConnectionIconProps) => {
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" />;
@@ -142,12 +122,7 @@ const TestConnectionIcon = ({
export const TestConnectionNoticeAlert = () => {
const t = useI18n();
return (
<Alert
variant="light"
color="yellow"
title="Test Connection"
icon={<IconInfoCircle />}
>
<Alert variant="light" color="yellow" title="Test Connection" icon={<IconInfoCircle />}>
{t("integration.testConnection.alertNotice")}
</Alert>
);

View File

@@ -6,16 +6,10 @@ import { Button, Fieldset, Group, Stack, TextInput } from "@mantine/core";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import {
getAllSecretKindOptions,
getDefaultSecretKinds,
} from "@homarr/definitions";
import { getAllSecretKindOptions, getDefaultSecretKinds } from "@homarr/definitions";
import { useZodForm } from "@homarr/form";
import { useConfirmModal } from "@homarr/modals";
import {
showErrorNotification,
showSuccessNotification,
} from "@homarr/notifications";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
@@ -23,11 +17,7 @@ import { validation } from "@homarr/validation";
import { revalidatePathActionAsync } from "~/app/revalidatePathAction";
import { SecretCard } from "../../_integration-secret-card";
import { IntegrationSecretInput } from "../../_integration-secret-inputs";
import {
TestConnection,
TestConnectionNoticeAlert,
useTestConnectionDirty,
} from "../../_integration-test-connection";
import { TestConnection, TestConnectionNoticeAlert, useTestConnectionDirty } from "../../_integration-test-connection";
interface EditIntegrationForm {
integration: RouterOutputs["integration"]["byId"];
@@ -45,8 +35,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
url: integration.url,
secrets: secretsKinds.map((kind) => ({
kind,
value:
integration.secrets.find((secret) => secret.kind === kind)?.value ?? "",
value: integration.secrets.find((secret) => secret.kind === kind)?.value ?? "",
})),
};
const { isDirty, onValuesChange, removeDirty } = useTestConnectionDirty({
@@ -61,9 +50,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
});
const { mutateAsync, isPending } = clientApi.integration.update.useMutation();
const secretsMap = new Map(
integration.secrets.map((secret) => [secret.kind, secret]),
);
const secretsMap = new Map(integration.secrets.map((secret) => [secret.kind, secret]));
const handleSubmitAsync = async (values: FormType) => {
if (isDirty) return;
@@ -82,9 +69,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
title: t("integration.page.edit.notification.success.title"),
message: t("integration.page.edit.notification.success.message"),
});
void revalidatePathActionAsync("/manage/integrations").then(() =>
router.push("/manage/integrations"),
);
void revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError: () => {
showErrorNotification({
@@ -101,17 +86,9 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
<Stack>
<TestConnectionNoticeAlert />
<TextInput
withAsterisk
label={t("integration.field.name.label")}
{...form.getInputProps("name")}
/>
<TextInput withAsterisk label={t("integration.field.name.label")} {...form.getInputProps("name")} />
<TextInput
withAsterisk
label={t("integration.field.url.label")}
{...form.getInputProps("url")}
/>
<TextInput withAsterisk label={t("integration.field.url.label")} {...form.getInputProps("url")} />
<Fieldset legend={t("integration.secrets.title")}>
<Stack gap="sm">
@@ -122,10 +99,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
onCancel={() =>
new Promise((res) => {
// When nothing changed, just close the secret card
if (
(form.values.secrets[index]?.value ?? "") ===
(secretsMap.get(kind)?.value ?? "")
) {
if ((form.values.secrets[index]?.value ?? "") === (secretsMap.get(kind)?.value ?? "")) {
return res(true);
}
openConfirmModal({
@@ -133,10 +107,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
children: t("integration.secrets.reset.message"),
onCancel: () => res(false),
onConfirm: () => {
form.setFieldValue(
`secrets.${index}.value`,
secretsMap.get(kind)!.value ?? "",
);
form.setFieldValue(`secrets.${index}.value`, secretsMap.get(kind)!.value ?? "");
res(true);
},
});
@@ -165,11 +136,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
}}
/>
<Group>
<Button
variant="default"
component={Link}
href="/manage/integrations"
>
<Button variant="default" component={Link} href="/manage/integrations">
{t("common.action.backToOverview")}
</Button>
<Button type="submit" loading={isPending} disabled={isDirty}>

View File

@@ -11,9 +11,7 @@ interface EditIntegrationPageProps {
params: { id: string };
}
export default async function EditIntegrationPage({
params,
}: EditIntegrationPageProps) {
export default async function EditIntegrationPage({ params }: EditIntegrationPageProps) {
const t = await getScopedI18n("integration.page.edit");
const integration = await api.integration.byId({ id: params.id });
@@ -22,9 +20,7 @@ export default async function EditIntegrationPage({
<Stack>
<Group align="center">
<IntegrationAvatar kind={integration.kind} size="md" />
<Title>
{t("title", { name: getIntegrationName(integration.kind) })}
</Title>
<Title>{t("title", { name: getIntegrationName(integration.kind) })}</Title>
</Group>
<EditIntegrationForm integration={integration} />
</Stack>

View File

@@ -16,9 +16,7 @@ export const IntegrationCreateDropdownContent = () => {
const [search, setSearch] = useState("");
const filteredKinds = useMemo(() => {
return integrationKinds.filter((kind) =>
kind.includes(search.toLowerCase()),
);
return integrationKinds.filter((kind) => kind.includes(search.toLowerCase()));
}, [search]);
const handleSearch = React.useCallback(
@@ -38,11 +36,7 @@ export const IntegrationCreateDropdownContent = () => {
{filteredKinds.length > 0 ? (
<ScrollArea.Autosize mah={384}>
{filteredKinds.map((kind) => (
<Menu.Item
component={Link}
href={`/manage/integrations/new?kind=${kind}`}
key={kind}
>
<Menu.Item component={Link} href={`/manage/integrations/new?kind=${kind}`} key={kind}>
<Group>
<IntegrationAvatar kind={kind} size="sm" />
<Text size="sm">{getIntegrationName(kind)}</Text>

View File

@@ -3,37 +3,20 @@
import { useCallback } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import {
Button,
Fieldset,
Group,
SegmentedControl,
Stack,
TextInput,
} from "@mantine/core";
import { Button, Fieldset, Group, SegmentedControl, Stack, TextInput } from "@mantine/core";
import { clientApi } from "@homarr/api/client";
import type {
IntegrationKind,
IntegrationSecretKind,
} from "@homarr/definitions";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import { getAllSecretKindOptions } from "@homarr/definitions";
import type { UseFormReturnType } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import {
showErrorNotification,
showSuccessNotification,
} from "@homarr/notifications";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { IntegrationSecretInput } from "../_integration-secret-inputs";
import {
TestConnection,
TestConnectionNoticeAlert,
useTestConnectionDirty,
} from "../_integration-test-connection";
import { TestConnection, TestConnectionNoticeAlert, useTestConnectionDirty } from "../_integration-test-connection";
import { revalidatePathActionAsync } from "../../../../revalidatePathAction";
interface NewIntegrationFormProps {
@@ -42,9 +25,7 @@ interface NewIntegrationFormProps {
};
}
export const NewIntegrationForm = ({
searchParams,
}: NewIntegrationFormProps) => {
export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => {
const t = useI18n();
const secretKinds = getAllSecretKindOptions(searchParams.kind);
const initialFormValues = {
@@ -79,9 +60,7 @@ export const NewIntegrationForm = ({
title: t("integration.page.create.notification.success.title"),
message: t("integration.page.create.notification.success.message"),
});
void revalidatePathActionAsync("/manage/integrations").then(() =>
router.push("/manage/integrations"),
);
void revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError: () => {
showErrorNotification({
@@ -98,26 +77,13 @@ export const NewIntegrationForm = ({
<Stack>
<TestConnectionNoticeAlert />
<TextInput
withAsterisk
label={t("integration.field.name.label")}
{...form.getInputProps("name")}
/>
<TextInput withAsterisk label={t("integration.field.name.label")} {...form.getInputProps("name")} />
<TextInput
withAsterisk
label={t("integration.field.url.label")}
{...form.getInputProps("url")}
/>
<TextInput withAsterisk label={t("integration.field.url.label")} {...form.getInputProps("url")} />
<Fieldset legend={t("integration.secrets.title")}>
<Stack gap="sm">
{secretKinds.length > 1 && (
<SecretKindsSegmentedControl
secretKinds={secretKinds}
form={form}
/>
)}
{secretKinds.length > 1 && <SecretKindsSegmentedControl secretKinds={secretKinds} form={form} />}
{form.values.secrets.map(({ kind }, index) => (
<IntegrationSecretInput
withAsterisk
@@ -141,11 +107,7 @@ export const NewIntegrationForm = ({
/>
<Group>
<Button
variant="default"
component={Link}
href="/manage/integrations"
>
<Button variant="default" component={Link} href="/manage/integrations">
{t("common.action.backToOverview")}
</Button>
<Button type="submit" loading={isPending} disabled={isDirty}>
@@ -163,10 +125,7 @@ interface SecretKindsSegmentedControlProps {
form: UseFormReturnType<FormType, (values: FormType) => FormType>;
}
const SecretKindsSegmentedControl = ({
secretKinds,
form,
}: SecretKindsSegmentedControlProps) => {
const SecretKindsSegmentedControl = ({ secretKinds, form }: SecretKindsSegmentedControlProps) => {
const t = useScopedI18n("integration.secrets");
const secretKindGroups = secretKinds.map((kinds) => ({
@@ -186,13 +145,7 @@ const SecretKindsSegmentedControl = ({
[form],
);
return (
<SegmentedControl
fullWidth
data={secretKindGroups}
onChange={onChange}
></SegmentedControl>
);
return <SegmentedControl fullWidth data={secretKindGroups} onChange={onChange}></SegmentedControl>;
};
type FormType = Omit<z.infer<typeof validation.integration.create>, "kind">;

View File

@@ -16,12 +16,8 @@ interface NewIntegrationPageProps {
};
}
export default async function IntegrationsNewPage({
searchParams,
}: NewIntegrationPageProps) {
const result = z
.enum([integrationKinds[0]!, ...integrationKinds.slice(1)])
.safeParse(searchParams.kind);
export default async function IntegrationsNewPage({ searchParams }: NewIntegrationPageProps) {
const result = z.enum([integrationKinds[0]!, ...integrationKinds.slice(1)]).safeParse(searchParams.kind);
if (!result.success) {
notFound();
}

View File

@@ -43,9 +43,7 @@ interface IntegrationsPageProps {
};
}
export default async function IntegrationsPage({
searchParams,
}: IntegrationsPageProps) {
export default async function IntegrationsPage({ searchParams }: IntegrationsPageProps) {
const integrations = await api.integration.all();
const t = await getScopedI18n("integration");
@@ -54,18 +52,9 @@ export default async function IntegrationsPage({
<Stack>
<Group justify="space-between" align="center">
<Title>{t("page.list.title")}</Title>
<Menu
width={256}
trapFocus
position="bottom-start"
withinPortal
shadow="md"
keepMounted={false}
>
<Menu width={256} trapFocus position="bottom-start" withinPortal shadow="md" keepMounted={false}>
<MenuTarget>
<Button rightSection={<IconChevronDown size={16} stroke={1.5} />}>
{t("action.create")}
</Button>
<Button rightSection={<IconChevronDown size={16} stroke={1.5} />}>{t("action.create")}</Button>
</MenuTarget>
<MenuDropdown>
<IntegrationCreateDropdownContent />
@@ -73,10 +62,7 @@ export default async function IntegrationsPage({
</Menu>
</Group>
<IntegrationList
integrations={integrations}
activeTab={searchParams.tab}
/>
<IntegrationList integrations={integrations} activeTab={searchParams.tab} />
</Stack>
</Container>
);
@@ -87,10 +73,7 @@ interface IntegrationListProps {
activeTab?: IntegrationKind;
}
const IntegrationList = async ({
integrations,
activeTab,
}: IntegrationListProps) => {
const IntegrationList = async ({ integrations, activeTab }: IntegrationListProps) => {
const t = await getScopedI18n("integration");
if (integrations.length === 0) {
@@ -134,12 +117,7 @@ const IntegrationList = async ({
<TableTr key={integration.id}>
<TableTd>{integration.name}</TableTd>
<TableTd>
<Anchor
href={integration.url}
target="_blank"
rel="noreferrer"
size="sm"
>
<Anchor href={integration.url} target="_blank" rel="noreferrer" size="sm">
{integration.url}
</Anchor>
</TableTd>
@@ -155,10 +133,7 @@ const IntegrationList = async ({
>
<IconPencil size={16} stroke={1.5} />
</ActionIcon>
<DeleteIntegrationActionButton
integration={integration}
count={integrations.length}
/>
<DeleteIntegrationActionButton integration={integration} count={integrations.length} />
</ActionIconGroup>
</Group>
</TableTd>