feat(onboarding): enhance integration setup with Docker discovery and URL templating (#5607)

This commit is contained in:
Thomas authored and GitHub committed 2026-06-05 16:50:35 +02:00
1 parent 0a6467979a
commit dd7a4908a3
68 files changed
+2922 -434

No files matched your search

@@ -2,13 +2,13 @@
import { memo, useState } from "react";
import type { SelectProps } from "@mantine/core";
import { Button, Group, Loader, Select, Stack } from "@mantine/core";
import { Group, Loader, Select, Stack } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useForm } from "@homarr/form";
import { createModal } from "@homarr/modals";
import { createModal, ModalFormFooter, modalSizeForm } from "@homarr/modals";
import { useI18n } from "@homarr/translation/client";
interface InnerProps {
@@ -47,6 +47,7 @@ export const AppSelectModal = createModal<InnerProps>(({ actions, innerProps })
label={t("app.action.select.label")}
searchable
clearable
data-autofocus
leftSection={<MemoizedLeftSection isPending={isPending} currentApp={currentApp} />}
nothingFoundMessage={t("app.action.select.notFound")}
renderOption={renderSelectOption}
@@ -61,19 +62,13 @@ export const AppSelectModal = createModal<InnerProps>(({ actions, innerProps })
})) ?? []
}
/>
<Group justify="end">
<Button variant="default" onClick={actions.closeModal}>
{t("common.action.cancel")}
</Button>
<Button type="submit" loading={loading}>
{confirmLabel}
</Button>
</Group>
<ModalFormFooter onCancel={actions.closeModal} submitLabel={confirmLabel} loading={loading} />
</Stack>
</form>
);
}).withOptions({
defaultTitle: (t) => t("app.action.select.label"),
size: modalSizeForm,
});
const iconProps = {
@@ -1,9 +1,9 @@
"use client";
import { Button, CloseButton, ColorInput, Group, Input, Stack, TextInput, useMantineTheme } from "@mantine/core";
import { CloseButton, ColorInput, Input, Stack, TextInput, useMantineTheme } from "@mantine/core";
import { useForm } from "@homarr/form";
import { createModal } from "@homarr/modals";
import { createModal, ModalFormFooter, modalSizeForm } from "@homarr/modals";
import { useI18n } from "@homarr/translation/client";
import { TextMultiSelect } from "@homarr/ui";
import type { BoardItemAdvancedOptions } from "@homarr/validation/shared";
@@ -34,6 +34,7 @@ export const WidgetAdvancedOptionsModal = createModal<InnerProps>(({ actions, in
<Stack>
<TextInput
label={t("item.edit.field.title.label")}
data-autofocus
{...form.getInputProps("title")}
rightSection={<Input.ClearButton onClick={() => form.setFieldValue("title", "")} />}
/>
@@ -53,12 +54,7 @@ export const WidgetAdvancedOptionsModal = createModal<InnerProps>(({ actions, in
}
{...form.getInputProps("borderColor")}
/>
<Group justify="end">
<Button onClick={actions.closeModal} variant="subtle" color="gray">
{t("common.action.cancel")}
</Button>
<Button type="submit">{t("common.action.saveChanges")}</Button>
</Group>
<ModalFormFooter onCancel={actions.closeModal} />
</Stack>
</form>
);
@@ -66,7 +62,7 @@ export const WidgetAdvancedOptionsModal = createModal<InnerProps>(({ actions, in
defaultTitle(t) {
return t("item.edit.advancedOptions.title");
},
size: "lg",
size: modalSizeForm,
transitionProps: {
duration: 0,
},
@@ -9,7 +9,7 @@ import { z } from "zod/v4";
import { objectEntries } from "@homarr/common";
import { useSession } from "@homarr/auth/client";
import type { WidgetKind } from "@homarr/definitions";
import { createModal, useModalAction } from "@homarr/modals";
import { createModal, ModalFormFooter, modalSizeForm, useModalAction } from "@homarr/modals";
import type { SettingsContextProps } from "@homarr/settings/creator";
import { useI18n } from "@homarr/translation/client";
import { zodErrorMap } from "@homarr/validation/form/i18n";
@@ -145,9 +145,10 @@ export const WidgetEditModal = createModal<ModalProps<WidgetKind>>(({ actions, i
/>
);
})}
<Group justify="space-between">
{showAppTab ? (
<Button
variant="subtle"
type="button"
onClick={() =>
openModal({
advancedOptions,
@@ -163,17 +164,31 @@ export const WidgetEditModal = createModal<ModalProps<WidgetKind>>(({ actions, i
>
{t("item.edit.advancedOptions.label")}
</Button>
{!showAppTab && (
<Group justify="end" w={{ base: "100%", xs: "auto" }}>
<Button onClick={actions.closeModal} variant="subtle" color="gray">
{t("common.action.cancel")}
) : (
<ModalFormFooter
onCancel={actions.closeModal}
leftSection={
<Button
variant="subtle"
type="button"
onClick={() =>
openModal({
advancedOptions,
onSuccess(options) {
setAdvancedOptions(options);
innerProps.onSuccessfulEdit({
...innerProps.value,
advancedOptions: options,
});
},
})
}
>
{t("item.edit.advancedOptions.label")}
</Button>
<Button type="submit" loading={isSubmitting}>
{t("common.action.saveChanges")}
</Button>
</Group>
)}
</Group>
}
/>
)}
</Stack>
);
@@ -214,5 +229,5 @@ export const WidgetEditModal = createModal<ModalProps<WidgetKind>>(({ actions, i
defaultTitle(t) {
return t("item.edit.title");
},
size: "lg",
size: modalSizeForm,
});