Skip to content

feat(ui-rewrite): add prompt edit flow and fix prompt form/card UI#5675

Open
marekdano wants to merge 3 commits into
epic/ui-rewritefrom
5102-edit-prompt
Open

feat(ui-rewrite): add prompt edit flow and fix prompt form/card UI#5675
marekdano wants to merge 3 commits into
epic/ui-rewritefrom
5102-edit-prompt

Conversation

@marekdano

Copy link
Copy Markdown
Collaborator

Summary

Enable editing prompts from the details panel and fix related form, card, and team-scoping issues surfaced along the way.

Features

Edit a prompt from the details panel

  • promptsApi.update(id, data)PUT /prompts/{id} (validated + encoded id)
  • usePromptForm accepts { promptId?, initialValues?, templateRequired? }; with a promptId it updates via PUT instead of creating, tracks isUpdating, keeps the form on success, and uses the prompts.edit.error fallback
  • PromptForm gains a prompt prop → edit mode: prefilled fields (arguments → JSON, tags joined), "Edit prompt" heading, "Save changes" button
  • The Definition-tab Edit action is wired up (success toast + refetch)

Cancel/Back returns to the Definition tab

  • New PromptDetailsPanel initialTab prop, honored on open
  • Canceling the edit form reopens the panel on the tab it was launched from

Template required only for REST prompts

  • Required for local/REST prompts, optional for federated prompts (no local template — resolved upstream on prompts/get); the required asterisk and aria-required follow this

Fixes

  • Card title truncation / kebab visibility (Tools, Resources, Prompts): long gateway/server names pushed the ⋮ menu off the card. Fixed the flex/grid truncation chain and added a title tooltip so the full name stays discoverable on hover.
  • Prompt form styling: inputs/select/textarea and focus ring now match the Tools/Resources forms.
  • Preserve the prompt's team when editing: a team prompt keeps its own team (seeded from prompt.teamId) — no longer blocked without a sidebar selection or reassigned to a different selected team. Create-mode unchanged.

i18n

Added prompts.edit.{pageTitle, button.submit, success, error} to en-US, es-ES, and pt-BR.

Tests

  • Unit (vitest): edit prefill / PUT / no-reset / error, initialTab, cancel→Definition, template required vs optional-for-federated, and team-preservation on edit.
  • E2E (Playwright): new e2e/prompts.spec.ts — truncation, create, edit + see update, preview (Try it tab), add tag; plus truncation tests added to tools.spec.ts and resources.spec.ts.

@marekdano marekdano self-assigned this Jul 17, 2026
@marekdano marekdano added ui User Interface ui-rewrite Tasks for the isolated ui rewrite feature branch labels Jul 17, 2026
@a-effort

Copy link
Copy Markdown
Collaborator

Tested and it seems to work as expected 🙌

LLM feedback on a potentially blocking issue:

Federated prompt edits to description / title / visibility get silently clobbered on next federation refresh.

gateway_service._process_gateway_prompts (gateway_service.py:5493-5527) overwrites description, template, argument_schema, title, and (with update_visibility=True) visibility back to upstream on every re-sync. This means an user edits a federated prompt's description, sees the success toast, then loses the change the next time the gateway polls.

tags, custom_name, display_name, and team_id are preserved, so those edits are safe.

@marekdano

Copy link
Copy Markdown
Collaborator Author

@a-effort - thanks for testing this and for the sharp catch on the federation clobber — I dug into it and you're right, so I've reworked the federated edit behaviour.

Confirmed the finding. _update_or_create_prompts (gateway_service.py) does overwrite description, template, arguments, and title back to upstream on re-sync, so editing those on a federated prompt would be silently lost.

Which fields actually persist across re-sync: tags, name, display_name, and team_id are never touched, so they survive. name also survives

What I changed in this PR (frontend-only):

  • for federated prompts the edit form now keeps only the fields that persist editable - name, visibility/team, tags - and disables description, template, arguments, with a short notice explaining they're managed by the source server.
  • Local/REST prompts are unchanged (fully editable).
  • Tags also remain editable inline in the details panel as before.

Added unit + Playwright coverage for the federated case (disabled fields + notice, plus a rename round-trip)

@vishu-bh vishu-bh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Added inline comments

teamId?: string;
}

export interface PromptFormInitialValues {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could we omit description, template, and arguments entirely when editing a federated prompt? Disabling these inputs prevents user interaction, but getUpdateData() still submits their prefilled values. A rename, visibility, or tag-only edit can therefore overwrite newer upstream data with stale form state; a null template is also converted to "". Please add coverage asserting these properties are absent from federated PUT payloads.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! You're right that disabling the inputs didn't stop getUpdateData() from still submitting their prefilled values, so a name/visibility/tag-only edit could overwrite newer upstream data (and null template → "").

Fixed: the form now passes a federated flag to usePromptForm, and getUpdateData() omits description, template, and arguments entirely for federated prompts — only name, visibility/team, and tags are sent. Added coverage asserting those properties are absent from the federated PUT payload (usePromptForm.test.ts and PromptForm.test.tsx, plus the federated edit case in e2e/prompts.spec.ts).

Comment thread client/src/hooks/usePromptForm.ts Outdated
const { prompt } = schema.parse(getFormValues());
return {
name: prompt.name,
description: prompt.description ?? null,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

An empty description becomes null here, but the backend update service treats null as “field not provided” and only updates descriptions when the value is non-null. The request succeeds while the old description remains. Could we use an explicit supported clear value/operation and add a regression test that edits a non-empty description to empty?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed — the update service only writes the description when it's non-null (prompt_service.py), so an empty description was silently a no-op.

Fixed: for local prompts an empty description is now sent as "" (explicit clear) rather than null. Added a regression test that edits a non-empty description to empty and asserts the PUT carries description: "".

Marek Dano added 3 commits July 20, 2026 18:25
Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
…t form for federated prompts only

Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
…pdates

Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
@marekdano
marekdano requested a review from vishu-bh July 20, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui User Interface ui-rewrite Tasks for the isolated ui rewrite feature branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants