Skip to content

Conversation

@hodanoori
Copy link
Contributor

@hodanoori hodanoori commented Jan 20, 2026

Summary

Adds false positive remediation to Heureka and introduces an image version details page. Users can mark vulnerabilities as false positive from the image details page, with success/error feedback via the message provider. The image version details page shows occurrences and vulnerabilities for a specific version. SHA256 identifiers are shortened to 7 characters in breadcrumbs and page titles for readabilityin image version details page.

Open Points

The remediated vulnerabilities tab currently does not display severity information, and does not support search or pagination. These features will be implemented once the corresponding API support becomes available.

Changes Made

  • Added False Positive Remediation Action

    • Added false positive action to the vulnerabilities list in the image details page
    • Implemented FalsePositiveModal component with required description field
    • Made description field mandatory (required) with validation
    • Integrated with remediation API to create false positive remediations
  • Implemented Message Provider for User Feedback

    • Integrated @cloudoperators/juno-messages-provider
    • Added MessagesProvider wrapper in App.tsx
    • Added Messages component to root route for global message display
    • Implemented success/error messages for false positive actions in vulnerabilities tab
    • Implemented success/error messages for revert false positive actions in remediated vulnerabilities tab
    • Updated turbo.json to include messages-provider build dependency
  • Added Image Version Details Page

    • Created new route /services/$service/images/$image/versions/$version for image version details
    • Implemented ImageVersionDetails component showing version-specific information
    • Added ImageVersionOccurrences component to display component instances for the version
    • Added ImageVersionIssuesList component to display vulnerabilities for the specific version
    • Integrated with fetchImageVersions API to load version-specific data
  • Enhanced Image Details Page

    • Added image versions list to image details page
    • Implemented navigation to image version details page when clicking on a version
    • Added two separate tabs: "Vulnerabilities" and "Remediated Vulnerabilities"
  • **Image Version Details Page: Improved SHA256 Display in Breadcrumb and Page Title **

    • Created utility function getShortSha256() to extract first 7 characters after "sha256:"
    • Updated breadcrumb in image version details route to show shortened SHA
    • Updated page title/heading to display shortened SHA instead of full hash
    • Full SHA remains in URL for proper routing and identification

Related Issues

Screenshots (if applicable)

FB01DF9E-371A-45BB-B849-2A3902D1A603 006035E0-6626-4A5F-BBF3-D430AE4A5BAE A87DDBF7-0780-4274-8DB7-9823DCD4E4B9 AF4CA75B-DEE4-40CE-A7A4-027D65395AC4 C44C375E-62C6-4B32-A195-484DEE15F453 4AEC5918-881D-44A8-A3AF-5487BE40DEDF

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 and others added 6 commits January 20, 2026 09:18
* feat(heureka): adds image details page

* chore(heureka): removes image details panel

* feat(heureka): navigate from service panel to image details page

* chore(heureka): adds changeset

* chore(heureka): adjusts tests

* chore(heureka): makes navigation checks generic

* chore(heureka): makes navigation checks generic

* fix(heureka): fixes prettier issue

* feat(heureka): improves navigation and url definition

* chore(heureka): adjusts test
@hodanoori hodanoori requested a review from a team as a code owner January 20, 2026 13:38
@changeset-bot
Copy link

changeset-bot bot commented Jan 20, 2026

🦋 Changeset detected

Latest commit: 6325218

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 Major
@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

@hodanoori hodanoori self-assigned this Jan 20, 2026
@hodanoori hodanoori added the heureka Heureka related issues label Jan 20, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

PR Preview Action v1.6.3

🚀 View preview at
https://cloudoperators.github.io/juno/pr-preview/pr-1421/

Built to branch gh-pages at 2026-01-20 15:28 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copy link
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! this PR is quite lorge 😅. Added some comments

.pnpm-store/

# TanStack Router cache directory
.tanstack/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this really needed? This is the first app ignoring this folder...

.env.test.local
.env.production.local

# TanStack Router cache directory
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here. How is this directory being created?

"clean:cache": "rm -rf .turbo"
},
"dependencies": {
"@cloudoperators/juno-messages-provider": "workspace:*",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you want really to introduce the messages provider dependency? We can talk about this.


// Invalidate cache first to ensure queryFn is always called (forces network request)
// Then use ensureQueryData to maintain promise stability (like other fetch functions)
queryClient.invalidateQueries({ queryKey })
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are you always fetching from network? Which benefit gives you then using react-query instead of just fetch?

const { needsExpansion, textRef } = useTextOverflow(remediation.description || "")

const toggleDescription = (e: React.MouseEvent) => {
e.preventDefault()
Copy link
Collaborator

Choose a reason for hiding this comment

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

you don't need the e.stopPropagation() ? If the row has a click/select handler, clicking "Show more" may still propagate and trigger row-level behavior.

))}

<div className="advance-link">
<a href="#" rel="noopener noreferrer" onClick={onShowMoreClicked}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

unnecessary rel attribute rel="noopener noreferrer" on an internal anchor without target="_blank" is unnecessary


const { imageVersions } = getNormalizedImageVersionsResponse(data as GetImageVersionsQuery | undefined)
// Since we're querying for a specific version, we should get exactly one result
const imageVersion = imageVersions[0]
Copy link
Collaborator

Choose a reason for hiding this comment

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

there is a guard if (!imageVersion)


// Normalization function that returns array of image versions (for compatibility with old panel)
export const getNormalizedImageVersionsResponse = (
data: any // Will be GetImageVersionsQuery after codegen
Copy link
Collaborator

Choose a reason for hiding this comment

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

when should this happen?


const imageVersionNode = data.ImageVersions.edges[0].node
const vulnerabilitiesEdges = imageVersionNode.vulnerabilities?.edges || []
const occurrencesEdges = imageVersionNode.occurences?.edges || []
Copy link
Collaborator

Choose a reason for hiding this comment

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

typo in occurences . I should be occurrences ...

const vulnerabilitiesPageInfo = imageVersionNode.vulnerabilities?.pageInfo

const vulnerabilities: ImageVulnerability[] = vulnerabilitiesEdges
.filter((edge: any) => edge !== null && edge.node !== null)
Copy link
Collaborator

Choose a reason for hiding this comment

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

any?

Copy link
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.

What about to add tests for all of those new components?

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

Labels

heureka Heureka related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants