feat: consolidate per-step config buttons into a single Configure dialog - #908
Conversation
Addresses kubeflow#894. The cell metadata editor had a separate button + dialog per config option (IMAGE, GPU, CACHE), and reviewers on kubeflow#889 and kubeflow#891 pointed out this doesn't scale - each new option adds another button, which was already about to become five with those two PRs pending. Replace the three standalone dialogs (BaseImageDialog, GpuDialog, CacheDialog) with a single StepConfigDialog behind one gear-icon "Configure step" button, using tabs (Base Image / GPU / Caching) instead of separate buttons. Tabs are wired through a `{label, render}[]` array that Tabs/DialogContent map over, so adding a new per-step option going forward means appending one entry to that array, not adding another button/dialog pair or a fourth hardcoded tab index. No backend or tag-format changes - this is a pure UI reorganization. Updated the Playwright e2e assertion that checked for the three separate button titles to check for the new button's aria-label. Tested manually end-to-end in a running JupyterLab: - Opened the Configure dialog and confirmed all three tabs render their original content, pre-populated correctly from existing limit:/cache:/image: tags. - Confirmed Base Image, GPU, and Caching each write the correct notebook tag when changed (verified via live React state and, for GPU, a round trip to the saved .ipynb). - Confirmed the "Reset to Default" button both clears the value and closes the dialog. - Confirmed the dialog always reopens on the Base Image tab, even after being left on a different tab in a previous session, by resetting activeTab whenever the dialog opens. - Confirmed Caching shows the correct radio immediately with no flash of the wrong value, since its value is derived directly from the enableCaching prop instead of synced into local state. - Confirmed the dialog's aria-labelledby/aria-describedby are present (parity with the original GPU dialog's accessibility wiring). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Pedro Sbaraini Cordeiro <pedro.sbarainicordeiro@gmail.com>
ada333
left a comment
There was a problem hiding this comment.
hi @cordeirops, I really like this feature, the implementation is already very strong, I just left few nitpick comments.
Split BaseImageSection/GpuSection/CacheSection out of StepConfigDialog.tsx
into their own files under dialogs/sections/, one component per file. Stop
closing the whole dialog when Base Image is reset to default. Fix Tab
label color contrast in dark mode.
Also fixes two bugs found while chasing the dark-mode contrast issue,
scoped to the same files:
- Input.tsx discarded any caller-supplied sx prop whenever the field
had no validation error, since the error-state sx was assigned after
spreading {...rest} in the same JSX element. This silently broke
GpuSection's disabledFieldSx on the GPU Count field.
- GpuSection's disabledFieldSx hardcoded a dark-theme-only white text
color instead of a --jp-* variable, and now also covers the label
and border colors for the disabled GPU Count/GPU Type fields.
Signed-off-by: Pedro Sbaraini Cordeiro <pedro.sbarainicordeiro@gmail.com>
|
Hey @ada333, thanks for the review. Addressed all three:
While debugging the tab contrast I also found two bugs in the same area, fixed them too:
Nothing outside this dialog changed, Input/Select/theme are untouched. Pushed to the same branch.
|
|
Hello @cordeirops My PR was merged and it led to conflicts in yours. Would you please solve the conflict? Thanks! |
…-panel # Conflicts: # labextension/src/widgets/cell-metadata/CellMetadataEditor.tsx
|
Hello @jesuino I'd resolved the conflicts! |
ada333
left a comment
There was a problem hiding this comment.
@cordeirops looks great thanks! I did not find anything wrong in the code and tested the feature JL - confirmed that the tags get into DSL.
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ederign The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |

Summary
Closes #894 - consolidates the per-step config buttons (Base Image,
GPU, Caching) into a single "Configure step" gear-icon button and
dialog, instead of one button + one dialog per option.
This was flagged during review of #891 (Secrets): with #889 (Report)
and #891 both adding their own button/dialog, the cell toolbar was
about to have five separate config buttons. This PR gives both of
those a single tabbed dialog to plug into instead.
Note: #891 depends on this PR and is blocked until it merges.
Changes
StepConfigDialog.tsx: one Dialog with tabs (Base Image / GPU /Caching), replacing
BaseImageDialog.tsx,GpuDialog.tsx, andCacheDialog.tsx(all deleted). Each tab's content is unchanged fromits original dialog, just extracted into a section component.
{label, render}[]array thatTabs/DialogContentmap over. Adding a new option going forward (e.g.Report from feat: Allow users to hide the HTML Report #889, Secrets from feat: add Kubernetes Secrets as environment variables to pipeline steps #891) means appending one entry to
that array, not adding another button/dialog pair or a hardcoded tab
index.
CellMetadataEditor.tsx: the three buttons + three open-statevariables became one gear-icon
IconButton(aria-label="Configure step") + one open-state, matching the existing icon-button stylealready used for close/clear-metadata in the same toolbar.
separate button titles to check for the new button's aria-label.
No backend or notebook-tag-format changes - this is a pure UI
reorganization.
Fixed during self-review
Caught and fixed before opening this PR:
useEffectthatfired on remount (since inactive tabs unmount), causing a one-frame
flash of the wrong radio selection when switching tabs. Removed the
local state entirely - the value is now derived directly from the
enableCachingprop.onClose()call the original dialog made alongside the reset.
reopen on whichever tab was last viewed (e.g. for a different step).
aria-labelledby/aria-describedbyaccessibility attributes.Test plan
make test-labextension(typecheck, eslint, jest)all three tabs render pre-populated from existing tags
(
limit:,cache:,image:), verified each tab writes thecorrect tag on change, verified Reset to Default closes the
dialog, verified the dialog reopens on Base Image after being
left on another tab, verified no flash on the Caching tab, and
verified
aria-labelledby/aria-describedbyare present.🤖 Generated with Claude Code, reviewed by @cordeirops