Skip to content

feat(FR-854): add a reset action for image resource limits - #9487

Draft
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-854-add-ui-for-resetting-image
Draft

feat(FR-854): add a reset action for image resource limits#9487
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-854-add-ui-for-resetting-image

Conversation

@yomybaby

@yomybaby yomybaby commented Sep 7, 2026

Copy link
Copy Markdown
Member

Resolves #3523 (FR-854)

clear_image_custom_resource_limit has been on the manager since 25.6.0, but nothing in the WebUI ever called it. Once an admin set custom minimum resource limits on an image there was no way back to the values the image itself declares — the only image resource-limit UI, ManageImageResourceLimitModal, could only write new limits through modify_image.

This adds a Reset to Default action to that modal's footer.

Design decisions

  • Reversible tier, not the typed-confirm modal. An admin can retype the limits, so the action uses the anchored BAIPopconfirm (.claude/rules/destructive-confirmation.md), not BAIDeleteConfirmModal.
  • Version-gated. The mutation is documented "Added in 25.6.0", so the button is hidden entirely when isManagerVersionCompatibleWith('25.6.0') is false. Permission-wise nothing extra is needed: ClearImageCustomResourceLimit and ModifyImage are both SUPERADMIN-only on the manager, so the reset action has exactly the same reach as the Save button next to it.
  • The key is the canonical string, not the node id. There is no clear_image_custom_resource_limit_by_id field in data/schema.graphql, so the legacy canonical-keyed mutation is the only option. The canonical string is built from the same expression the save path already uses, and the button is disabled when any part of that key (registry / namenamespace / tag) is missing rather than sending a malformed null/null:null.
  • Errors come off the GraphQL errors array. ClearImageCustomResourceLimitPayload returns only image_node — there is no ok/msg pair like the sibling modify_image path has.
  • Store patch + the existing close contract. The payload selects image_node { id resource_limits { … } }, which is exactly what both the list query and the modal fragment read, so Relay patches the normalized record. onRequestClose(true) is still called so the caller's existing handling (ImageList's updateFetchKey(), which the legacy modify_image path genuinely needs) stays truthful.

New i18n keys: environment.ResetImageResourceLimit, environment.DescResetImageResourceLimit, environment.DescImageResourceLimitReset (en + ko written by hand, the other 20 locales carry the __NOT_TRANSLATED__ placeholders make i18n emits).

Tests

  • New react/src/components/ManageImageResourceLimitModal.test.tsx (vitest + relay-test-utils): asserts the clear mutation goes out with the canonical key and architecture of the edited image, and that the action is absent on a manager older than 25.6.0.
  • pnpm exec vitest run src/components/ManageImageResourceLimitModal.test.tsx src/components/ImageList.test.tsx src/pages/EnvironmentPage.test.tsx → 3 files, 21 tests passed.
  • pnpm run relay — generated artifacts committed.
  • No e2e run (needs a live cluster).

Verification

bash scripts/verify.sh:

=== ALL PASS ===

Review notes

  • Admin → Environments → Images, row action "Edit Minimum Image Resource Limit". The modal footer now has a ghost Reset to Default on the left; confirming it clears the custom limits and the row's Resource limit column falls back to the image-declared values.
  • Point the UI at a manager older than 25.6.0 (or stub isManagerVersionCompatibleWith) and confirm the footer collapses back to the plain Cancel/Save pair with no leftover gap.
  • Worth a second pair of eyes: the canonical-key guard. image_canonical is the only handle the mutation takes, so an image whose registry/tag is null must not be resettable — that is what canResetResourceLimit protects.

Checklist: (if applicable)

  • Documentation
  • Minium required manager version — 25.6.0 (the action is hidden below it)
  • Specific setting for review (eg., KB link, endpoint or how to setup)
  • Minimum requirements to check during review — superadmin account; an image with custom resource limits already set
  • Test case(s) to demonstrate the difference of before/after — react/src/components/ManageImageResourceLimitModal.test.tsx

https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

The manager has exposed `clear_image_custom_resource_limit` since 25.6.0,
but nothing in the WebUI called it: once an admin set custom minimum
resource limits on an image there was no way back to the values the image
itself declares.

Add a "Reset to Default" action to the footer of
ManageImageResourceLimitModal. Resetting is reversible - the admin can
retype the limits - so it uses the anchored BAIPopconfirm tier rather than
a typed-confirmation modal.

The mutation is keyed on the image canonical string, not the node id, so
the action is disabled when any part of that key is missing, and hidden
entirely on managers older than 25.6.0. Its payload carries only
`image_node`, so failures are read off the GraphQL errors instead of an
ok/msg pair; the selection set returns `resource_limits` so Relay patches
the row in the normalized store.

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ
@github-actions github-actions Bot added area:ux UI / UX issue. area:i18n Localization size:XL 500~ LoC labels Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 15.78% 5750 / 36417
🔵 Statements 13.25% 7014 / 52900
🔵 Functions 13.77% 894 / 6488
🔵 Branches 9.64% 4878 / 50598
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/components/ManageImageResourceLimitModal.tsx 64.8% 61.48% 41.17% 72.83% 116, 129-130, 138-142, 145-187, 195, 201, 202, 230, 239, 262-263, 283-335, 336, 337, 338, 339, 340, 45-158
Generated in workflow #723 for commit cf27592 by the Vitest Coverage Report Action

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The clear and save mutations can overlap, making the resulting resource limits response-order dependent.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a version-gated action for restoring an image’s default resource limits.

Changes:

  • Adds the clear_image_custom_resource_limit mutation and confirmation UI.
  • Adds localized labels and success messages.
  • Adds Relay artifacts and tests for canonical keys and version gating.
File summaries
File Description
react/src/components/ManageImageResourceLimitModal.tsx Adds reset mutation and UI action.
react/src/components/ManageImageResourceLimitModal.test.tsx Tests reset requests and version gating.
react/src/__generated__/ManageImageResourceLimitModalClearMutation.graphql.ts Generated clear-mutation artifact.
react/src/__generated__/ManageImageResourceLimitModalTestQuery.graphql.ts Generated test-query artifact.
resources/i18n/en.json Adds English reset strings.
resources/i18n/ko.json Adds Korean reset strings.
resources/i18n/de.json Adds reset placeholders.
resources/i18n/el.json Adds reset placeholders.
resources/i18n/es.json Adds reset placeholders.
resources/i18n/fi.json Adds reset placeholders.
resources/i18n/fr.json Adds reset placeholders.
resources/i18n/id.json Adds reset placeholders.
resources/i18n/it.json Adds reset placeholders.
resources/i18n/ja.json Adds reset placeholders.
resources/i18n/mn.json Adds reset placeholders.
resources/i18n/ms.json Adds reset placeholders.
resources/i18n/pl.json Adds reset placeholders.
resources/i18n/pt.json Adds reset placeholders.
resources/i18n/pt-BR.json Adds reset placeholders.
resources/i18n/ru.json Adds reset placeholders.
resources/i18n/tr.json Adds reset placeholders.
resources/i18n/vi.json Adds reset placeholders.
resources/i18n/zh-CN.json Adds reset placeholders.
resources/i18n/zh-TW.json Adds reset placeholders.
Review details

Files not reviewed (2)

  • react/src/generated/ManageImageResourceLimitModalClearMutation.graphql.ts: Generated file
  • react/src/generated/ManageImageResourceLimitModalTestQuery.graphql.ts: Generated file
  • Files reviewed: 22/24 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment on lines +133 to +134
message.success(t('environment.DescImageResourceLimitReset'));
onRequestClose(true);
Comment thread react/src/components/ManageImageResourceLimitModal.tsx
Comment thread react/src/components/ManageImageResourceLimitModal.tsx
Guard the Save button while the clear mutation is in flight. The reset
trigger already refused to start while `modify_image` was pending, but the
mirror was missing: `modify_image` could be started from Save while
`clear_image_custom_resource_limit` was still settling, and the two writes
race over the same `resource_limits`.

Cover the canonical-key guard the PR flagged as safety-critical: reset is
disabled when `registry`, `tag`, or both `name`/`namespace` are absent, and
the key falls back to `namespace` when the deprecated `name` is null.

vitest: 6 tests pass. scripts/verify.sh: === ALL PASS ===

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The mutation is invalid against supported pre-26.1 managers, and pending resets can close a subsequently opened modal.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (2)

  • react/src/generated/ManageImageResourceLimitModalClearMutation.graphql.ts: Generated file
  • react/src/generated/ManageImageResourceLimitModalTestQuery.graphql.ts: Generated file

Suppressed comments (1)

react/src/components/ManageImageResourceLimitModal.tsx:134

  • This successful reset already returns image_node { id resource_limits }, so Relay patches the existing row, but onRequestClose(true) makes ImageList call updateFetchKey() and requery the entire list. Preserve truthful success reporting while distinguishing reset from the legacy modify_image path at the caller, and refetch only for the latter.
          onRequestClose(true);
  • Files reviewed: 22/24 changed files
  • Comments generated: 2
  • Review effort level: Balanced

useMutation<ManageImageResourceLimitModalClearMutation>(graphql`
mutation ManageImageResourceLimitModalClearMutation(
$imageCanonical: String!
$architecture: String
Comment on lines +221 to +224
isDisabled={
!canResetResourceLimit || isInFlightModifyImageInput
}
isLoading={isInFlightClearResourceLimit}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n Localization area:ux UI / UX issue. size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add UI for resetting image resource limits

2 participants