"use client";
import { memo, useMemo } from "react";
import type { SelectProps } from "@mantine/core";
import { Anchor, Button, Group, Loader, Select, SimpleGrid, Text } from "@mantine/core";
import { IconCheck, IconRocket } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client";
import { useModalAction } from "@homarr/modals";
import { QuickAddAppModal } from "@homarr/modals-collection";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import type { CommonWidgetInputProps } from "./common";
import { useWidgetInputTranslation } from "./common";
import { useFormContext } from "./form";
export const WidgetAppInput = ({ property, kind }: CommonWidgetInputProps<"app">) => {
const t = useI18n();
const tInput = useWidgetInputTranslation(kind, property);
const form = useFormContext();
const { data: apps, isPending, refetch } = clientApi.app.selectable.useQuery();
const { data: session } = useSession();
const canCreateApps = session?.user.permissions.includes("app-create") ?? false;
const { openModal } = useModalAction(QuickAddAppModal);
const currentApp = useMemo(
() => apps?.find((app) => app.id === form.values.options.appId),
[apps, form.values.options.appId],
);
return (
}
nothingFoundMessage={t("widget.common.app.noData")}
renderOption={renderSelectOption}
data={
apps?.map((app) => ({
label: app.name,
value: app.id,
iconUrl: app.iconUrl,
})) ?? []
}
inputWrapperOrder={["label", "input", "description", "error"]}
description={
{t.rich("widget.common.app.description", {
here: () => (
{t("common.here")}
),
})}
}
styles={{ root: { flex: "1" } }}
{...form.getInputProps(`options.${property}`)}
/>
{canCreateApps && (
}
variant="default"
onClick={() =>
openModal({
// eslint-disable-next-line no-restricted-syntax
async onClose(createdAppId) {
await refetch();
form.setFieldValue(`options.${property}`, createdAppId);
},
})
}
>
{t("widget.common.app.quickCreate")}
)}
);
};
const iconProps = {
stroke: 1.5,
color: "currentColor",
opacity: 0.6,
size: 18,
};
const renderSelectOption: SelectProps["renderOption"] = ({ option, checked }) => (
{"iconUrl" in option && typeof option.iconUrl === "string" ? (
) : null}
{option.label}
{checked && }
);
interface LeftSectionProps {
isPending: boolean;
currentApp: RouterOutputs["app"]["selectable"][number] | undefined;
}
const size = 20;
const LeftSection = ({ isPending, currentApp }: LeftSectionProps) => {
if (isPending) {
return ;
}
if (currentApp) {
return
;
}
return null;
};
const MemoizedLeftSection = memo(LeftSection);