Skip to content

feat(heureka): add Mitigate Manually action to vulnerability rows#1703

Open
hodanoori wants to merge 14 commits into
mainfrom
hoda-heureka-manual-mitigation
Open

feat(heureka): add Mitigate Manually action to vulnerability rows#1703
hodanoori wants to merge 14 commits into
mainfrom
hoda-heureka-manual-mitigation

Conversation

@hodanoori
Copy link
Copy Markdown
Contributor

@hodanoori hodanoori commented May 19, 2026

Summary

Adds a Mitigate Manually action to both the Active and Remediated vulnerability tabs, completing the remediation epic. Users can now mark a CVE as manually mitigated directly from the popup menu on any vulnerability row. The CVE moves to the Remediated tab immediately (optimistic cache update), and can be reverted via the Remediation History Panel.

Changes Made

  • Added MitigateManuallyModal component (mirrors FalsePositiveModal, submits type: RemediationTypeValues.Mitigation)
  • Added "Mitigate Manually" popup menu item to IssuesDataRow (Active tab) with handleMitigateManuallyConfirm handler
  • Added "Mitigate Manually" popup menu item to RemediatedIssueDataRow (Remediated tab) reusing existing handleRemediationConfirm
  • Threaded onMitigateManuallySuccess callback through IssuesDataRowsVulnerabilitiesTabContentImageIssuesList
  • Added success banner: "Vulnerability <CVE> has been manually mitigated and moved to the Remediated list."
  • Updated handleRemediatedTabRemediationSuccess to produce correct label for Mitigation type

Related Issues

Screenshots (if applicable)

EE6B722D-9BAC-4E2D-A3C4-8CA13ABACD85 CE2547AB-A89C-4C66-B7E5-9397FCD3621B E096C89E-275A-4F74-B3E5-F935A3284307

Testing Instructions

  1. pnpm i
  2. pnpm TASK

Checklist

  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have made corresponding changes to the documentation (if applicable).
  • My changes generate no new warnings or errors.
  • I have created a changeset for my changes.

PR Manifesto

Review the PR Manifesto for best practises.

hodanoori added 2 commits May 19, 2026 19:04
Add a new "Mitigate Manually" popup action to both the active and
remediated vulnerability tabs. Opens a modal (same shape as False
Positive) that creates a remediation with type=mitigation. Revert
works automatically via the existing RemediationHistoryPanel flow.

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
Signed-off-by: Hoda Noori <hoda.noori@sap.com>
Copilot AI review requested due to automatic review settings May 19, 2026 17:10
@hodanoori hodanoori requested a review from a team as a code owner May 19, 2026 17:10
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 19, 2026

🦋 Changeset detected

Latest commit: 0b916e1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@cloudoperators/juno-app-heureka Patch
@cloudoperators/juno-app-greenhouse Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
@hodanoori hodanoori changed the title Hoda heureka manual mitigation feat(heureka): add Mitigate Manually action to vulnerability rows May 19, 2026
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 first-class UI support in Heureka’s Image Details vulnerabilities list for creating Manual Mitigation remediations from both the Active and Remediated tabs, including optimistic React Query cache updates and user-facing success banners.

Changes:

  • Introduces MitigateManuallyModal to create remediations with type: RemediationTypeValues.Mitigation.
  • Adds a “Mitigate Manually” action to row popup menus in both Active (IssuesDataRow) and Remediated (RemediatedIssueDataRow) tables.
  • Threads a new success callback through the Active tab rendering chain and updates remediated-tab success messaging to include Mitigation.

Reviewed changes

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

Show a summary per file
File Description
apps/heureka/src/components/Service/ImageDetails/MitigateManuallyModal/index.tsx New modal component for creating mitigation remediations (description/user/expiration + submit).
apps/heureka/src/components/Service/ImageDetails/ImageIssuesList/RemediatedIssuesDataRows/RemediatedIssueDataRow/index.tsx Adds mitigation action + modal in the Remediated tab, reusing existing remediation creation handler.
apps/heureka/src/components/Service/ImageDetails/ImageIssuesList/IssuesDataRows/IssuesDataRows.test.tsx Updates tests to pass the newly required onMitigateManuallySuccess prop.
apps/heureka/src/components/Service/ImageDetails/ImageIssuesList/IssuesDataRows/IssuesDataRow/index.tsx Adds mitigation action + modal in the Active tab, plus optimistic remediations cache update and success callback.
apps/heureka/src/components/Service/ImageDetails/ImageIssuesList/IssuesDataRows/index.tsx Threads onMitigateManuallySuccess down to IssuesDataRow.
apps/heureka/src/components/Service/ImageDetails/ImageIssuesList/index.tsx Wires mitigation success banner for Active tab and extends remediated success labeling to include Mitigation.
Comments suppressed due to low confidence (1)

apps/heureka/src/components/Service/ImageDetails/MitigateManuallyModal/index.tsx:115

  • MitigateManuallyModal is a new remediation flow but currently has no dedicated Vitest coverage (unlike RiskAcceptanceModal). Consider adding tests that assert: (1) required-field validation (description/userId/expirationDate), (2) onConfirm is called with type=Mitigation and the expected fields (remediatedBy from session vs manual entry, expirationDate ISO), and (3) API errors returned from onConfirm are rendered in the Message banner.
  const handleConfirm = async () => {
    if (!descriptionTrimmed) {
      setDescriptionError("Description is required")
      return
    }
    if (!remediatedBy) {
      setUserIdError("User ID is required")
      return
    }
    if (!expirationDate) {
      setExpirationDateError("Expiration date is required")
      return
    }

    setDescriptionError("")
    setUserIdError("")
    setExpirationDateError("")
    setIsSubmitting(true)
    try {
      const severityValue = severity ? toSeverityValue(severity) : undefined
      const input: RemediationInput = {
        type: RemediationTypeValues.Mitigation,
        vulnerability,
        service,
        image,
        description: descriptionTrimmed,
        ...(remediatedBy && { remediatedBy }),
        ...(severityValue !== undefined && { severity: severityValue }),
        expirationDate: expirationDate.toISOString(),
      }

Comment thread apps/heureka/src/components/Service/ImageDetails/MitigateManuallyModal/index.tsx Outdated
hodanoori and others added 4 commits May 20, 2026 09:13
…ngle factory

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
Signed-off-by: Hoda Noori <hoda.noori@sap.com>
…icated modal code

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
@hodanoori hodanoori added the greenhouse-pr-build Set this label to create a preview image which will automatically set the `greenhouse-pr-preview` label May 20, 2026
@github-actions github-actions Bot added the greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. label May 20, 2026
Copy link
Copy Markdown
Collaborator

@ArtieReus ArtieReus left a comment

Choose a reason for hiding this comment

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

The only concern I would have is that the RemediationModal which other actions depends on isn't being tested... What do you think?

@github-actions github-actions Bot added greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. and removed greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. labels May 20, 2026
@github-actions github-actions Bot added greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. and removed greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. labels May 20, 2026
hodanoori added 2 commits May 20, 2026 14:14
Cover rendering, validation, interactions, source-ticket behaviour, and
smoke-test all three wrapper components (FalsePositiveModal,
RiskAcceptanceModal, MitigateManuallyModal).

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
Replace queryClient.fetchQuery (network round-trip) with
queryClient.getQueryData (synchronous read). The panel already holds a
fresh cache entry (staleTime: 0 on open), so we read it directly to
find any remediations created in other sessions and patch the broad
cache. This ensures the CVE stays in the Remediated tab when other
remediations still exist, while avoiding the prior regression where
the deleted entry briefly reappeared due to stale server responses.

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
@github-actions github-actions Bot added greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. and removed greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. labels May 20, 2026
ArtieReus
ArtieReus previously approved these changes May 20, 2026
Copy link
Copy Markdown
Collaborator

@ArtieReus ArtieReus left a comment

Choose a reason for hiding this comment

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

great job! thanks for adding tests!

…lict

Kept the refactored thin-wrapper version of RiskAcceptanceModal (which
delegates to RemediationModal) over the old standalone implementation
that was still on main.

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
@github-actions github-actions Bot added greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. and removed greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. labels May 20, 2026
hodanoori added 2 commits May 20, 2026 15:53
…d as url field

Add `sourceTicketRequired` prop to RemediationModal that:
- Shows the source ticket field as required
- Blocks confirm button until the field is filled
- Validates on submit with an inline error message
- Sends the ticket as the `url` field in RemediationInput (not embedded
  in description, which is the existing optional-ticket behaviour)

RiskAcceptanceModal switches from `showSourceTicket` to
`sourceTicketRequired` so the Jira ticket is treated the same as the
other required fields (description, user ID, expiration date).

Signed-off-by: Hoda Noori <hoda.noori@sap.com>
@github-actions github-actions Bot added greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. and removed greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY. labels May 20, 2026
const [userIdError, setUserIdError] = useState<string>("")
const [sourceTicketError, setSourceTicketError] = useState<string>("")
const [expirationDateError, setExpirationDateError] = useState<string>("")
const [apiError, setApiError] = useState<string | null>(null)
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.

[Optional] I think we can reduce number of useStates by grouping related fields like

const [form, setForm] = useState({
  description: "",
  manualUserId: "",
  sourceTicket: "",
  expirationDate: null as Date | null,
})

const [errors, setErrors] = useState({
  description: "",
  userId: "",
  sourceTicket: "",
  expirationDate: "",
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

greenhouse-pr-build Set this label to create a preview image which will automatically set the `greenhouse-pr-preview` greenhouse-pr-preview THIS LABEL IS SET AUTOMATICALLY.

Projects

None yet

4 participants