Skip to content

feat(widgets): add in-place app editing in widget edit modal#5809

Open
ajnart wants to merge 9 commits into
devfrom
feat/inline-app-edit-modal
Open

feat(widgets): add in-place app editing in widget edit modal#5809
ajnart wants to merge 9 commits into
devfrom
feat/inline-app-edit-modal

Conversation

@ajnart
Copy link
Copy Markdown
Member

@ajnart ajnart commented May 28, 2026


Homarr

Thank you for your contribution. Please ensure that your pull request meets the following pull request:

  • Builds without warnings or errors (pnpm build, autofix with pnpm format:fix)
  • Pull request targets dev branch
  • Commits follow the conventional commits guideline
  • No shorthand variable names are used (eg. x, y, i or any abbrevation)
  • Documentation is up to date. Create a pull request here.

Summary

Adds the ability to edit app properties (name, icon, URL, description, ping URL) directly from the dashboard's "Edit item - App" modal, removing the need to navigate to /manage/apps/edit/[id].

  • New EmbeddedAppEditForm component that fetches the app by ID and renders the shared AppForm in headless mode (no buttons, no <form> wrapper)
  • Calls clientApi.app.update on save, gated by form.isDirty() so untouched apps are never mutated
  • Permission-gated: the "Edit app" tab only appears for users with app-modify-all
  • Informational alert explains that changes propagate across all dashboards

Screenshots

Edit widget tab Edit app tab
CleanShot 2026-05-28 at 14 48 51 CleanShot 2026-05-28 at 14 48 56

Changes

  • AppForm: added hideButtons and formRef props for external submission control
  • WidgetEditModal: Mantine Tabs wrapping "Edit widget" / "Edit app" panels
  • EmbeddedAppEditForm: new component for in-place app editing
  • BoardItemMenu: passes appId from widget options to the modal
  • Translation keys for tab labels and propagation notice

ajnart added 2 commits May 28, 2026 14:51
Add EmbeddedAppEditForm component that allows editing app properties
(name, icon, URL, description) directly from the widget edit modal
without navigating to the management pages.
- Add hideButtons/formRef props to AppForm for headless embedding
- Add Mantine Tabs to WidgetEditModal for app widgets (permission-gated)
- Pass appId from BoardItemMenu to the modal
- Add translation keys for tab labels and propagation notice
@ajnart ajnart force-pushed the feat/inline-app-edit-modal branch 2 times, most recently from 6c90572 to 3d1bb2f Compare May 28, 2026 12:55
@ajnart ajnart marked this pull request as ready for review May 28, 2026 12:59
@ajnart ajnart requested a review from a team as a code owner May 28, 2026 12:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds in-place editing of an app’s shared properties directly from the dashboard’s “Edit item – App” modal by introducing an embedded app edit form and splitting the modal UI into widget/app tabs (permission-gated).

Changes:

  • Add Mantine Tabs to the widget edit modal to switch between “Edit widget” and “Edit app” for app widgets (only for app-modify-all users).
  • Introduce EmbeddedAppEditForm that loads an app by id and renders the shared AppForm in a headless/embedded mode, submitting updates via clientApi.app.update.
  • Extend AppForm to support external submission (formRef) and an option to hide its internal buttons/form wrapper (hideButtons).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/widgets/src/modals/widget-edit-modal.tsx Adds tabbed modal layout and triggers embedded app submission from the widget modal submit flow.
packages/widgets/src/modals/embedded-app-edit-form.tsx New embedded app edit component (fetch + update + notifications) rendered inside the widget edit modal.
packages/translation/src/lang/en.json Adds new translation keys for tab labels and the propagation notice.
packages/forms-collection/src/new-app/_form.tsx Adds imperative handle + headless rendering mode to reuse AppForm in embedded contexts.
apps/nextjs/src/components/board/items/item-menu.tsx Passes appId from app widget options into the edit modal props.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/widgets/src/modals/widget-edit-modal.tsx Outdated
Comment thread packages/widgets/src/modals/embedded-app-edit-form.tsx Outdated
manuel-rw
manuel-rw previously approved these changes May 28, 2026
Comment thread packages/widgets/src/modals/widget-edit-modal.tsx Outdated
@manuel-rw manuel-rw requested a review from Meierschlumpf May 28, 2026 18:39
Copy link
Copy Markdown
Member

@Meierschlumpf Meierschlumpf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how you guys feel about this, but IMO it's bad UX that the app is saved when we close the modal (see also issue from copilot regarding validation etc.)

IMO it would be best to have an edit button within the app input and open a second modal to edit the app, similar to the existing create modal

),
integrationSupport: "supportedIntegrations" in currentDefinition,
settings,
appId: item.kind === "app" ? (item.options.appId as string | undefined) : undefined,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we deal with bookmarks?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't thought about this, I guess we don't for now ?

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 });
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the app does no longer exist?

Copy link
Copy Markdown
Member Author

@ajnart ajnart May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't considered this edge case, in what way do you think we can edit an app that doesn't exist anymore ?

@ajnart
Copy link
Copy Markdown
Member Author

ajnart commented May 29, 2026

Not sure how you guys feel about this, but IMO it's bad UX that the app is saved when we close the modal (see also issue from copilot regarding validation etc.)

IMO it would be best to have an edit button within the app input and open a second modal to edit the app, similar to the existing create modal

I believe comment is more about error handling, as soon as the form is dirty then the save will trigger when pressing the save button and directly close the modal, so it's bypassing the form validation for the app change. The user could be in a not-authorized app modification state, press save expecting this change to propagate but saving would error silently.

I wouldn't want to save any changes without the user pressing save manually either

@ajnart ajnart added the needs-demo This PR needs a demo deployment label May 29, 2026
@dokploy-homarr-labs
Copy link
Copy Markdown

dokploy-homarr-labs Bot commented May 29, 2026

Dokploy Preview Deployment

Name Status Preview Updated (UTC)
homarr ✅ Done Preview URL 2026-05-29T10:11:15.608Z

ajnart and others added 3 commits May 29, 2026 11:46
Invalidate app queries on update so board widgets reflect changes.
Sync AppForm with refetched initialValues and reset after submit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-demo This PR needs a demo deployment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants