feat(widgets): add embedded app edit form for in-place app editing

Add EmbeddedAppEditForm component that allows editing app properties
(name, icon, URL, description) directly from the widget edit modal
without navigating to the management pages.
This commit is contained in:
Thomas Camlong committed 2026-05-28 14:51:23 +02:00
1 parent f7ea1b33a0
commit d83e9b2611
1 file changed
+80
@@ -0,0 +1,80 @@
"use client";
import { useImperativeHandle, useRef } from "react";
import { Alert, Center, Loader, Stack } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client";
import type { AppFormHandle } from "@homarr/forms-collection";
import { AppForm } from "@homarr/forms-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
export interface EmbeddedAppEditFormHandle {
submitIfDirty: () => void;
}
interface EmbeddedAppEditFormProps {
appId: string;
handleRef: React.Ref<EmbeddedAppEditFormHandle>;
}
export const EmbeddedAppEditForm = ({ appId, handleRef }: EmbeddedAppEditFormProps) => {
const t = useI18n();
const appFormRef = useRef<AppFormHandle>(null);
const { data: app, isPending: isLoadingApp } = clientApi.app.byId.useQuery({ id: appId });
const { mutate, isPending: isMutating } = clientApi.app.update.useMutation({
onSuccess: () => {
showSuccessNotification({
title: t("app.page.edit.notification.success.title"),
message: t("app.page.edit.notification.success.message"),
});
},
onError: () => {
showErrorNotification({
title: t("app.page.edit.notification.error.title"),
message: t("app.page.edit.notification.error.message"),
});
},
});
useImperativeHandle(
handleRef,
() => ({
submitIfDirty: () => {
if (appFormRef.current?.isDirty()) {
appFormRef.current.submit();
}
},
}),
[],
);
if (isLoadingApp || !app) {
return (
<Center py="xl">
<Loader />
</Center>
);
}
return (
<Stack>
<Alert icon={<IconInfoCircle size={16} />} color="blue" variant="light">
{t("item.edit.app.propagationNotice")}
</Alert>
<AppForm
formRef={appFormRef}
hideButtons
showBackToOverview={false}
buttonLabels={{ submit: "" }}
initialValues={app}
handleSubmit={(values) => {
mutate({ id: appId, ...values });
}}
isPending={isMutating}
/>
</Stack>
);
};