Skip to content

[ACM-17770] Add labels column and filtering to Application table#5720

Open
Ginxo wants to merge 12 commits intostolostron:mainfrom
Ginxo:ACM-17770
Open

[ACM-17770] Add labels column and filtering to Application table#5720
Ginxo wants to merge 12 commits intostolostron:mainfrom
Ginxo:ACM-17770

Conversation

@Ginxo
Copy link
Contributor

@Ginxo Ginxo commented Feb 18, 2026

📝 Summary

Evidences

Video_2026-02-18_10-30-02.mp4

Ticket Summary (Title):
Add labels column and filtering to Application table

Ticket Link:
https://issues.redhat.com/browse/ACM-17770

Type of Change:

  • 🐞 Bug Fix
  • ✨ Feature
  • 🔧 Refactor
  • 💸 Tech Debt
  • 🧪 Test-related
  • 📄 Docs

✅ Checklist

General

  • PR title follows the convention (e.g. ACM-12340 Fix bug with...)
  • Code builds and runs locally without errors
  • No console logs, commented-out code, or unnecessary files
  • All commits are meaningful and well-labeled
  • All new display strings are externalized for localization (English only)
  • (Nice to have) JSDoc comments added for new functions and interfaces

If Feature

  • UI/UX reviewed (if applicable)
  • All acceptance criteria met
  • Unit test coverage added or updated
  • Relevant documentation or comments included

If Bugfix

  • Root cause and fix summary are documented in the ticket (for future reference / errata)
  • Fix tested thoroughly and resolves the issue
  • Test(s) added to prevent regression

🗒️ Notes for Reviewers

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
@openshift-ci
Copy link

openshift-ci bot commented Feb 18, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link

openshift-ci bot commented Feb 18, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Ginxo

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
const getApplicationId = (resource: IResource, clusters: string[]): string => {
const stringified = JSON.stringify(clusters)
const hash = sha256(stringified)
return `${resource.metadata?.name}-${resource.metadata?.namespace}-${hash}`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not able to see a better way to uniquely identify a single application, so name+ns+clusters (as hash)

import { sha256 } from 'js-sha256'
import { IResource } from '../../resources'

const isOCPAppResource = (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

old method moved here as it is needed by the new useFetchApplicationLabels hook

import { IResource, OCPAppResource } from '../../../resources'
import { ApplicationStatus } from './application-status'

export type IApplicationResource = (IResource<ApplicationStatus> | OCPAppResource<ApplicationStatus>) & { id: string }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

old type moved here as it is needed by the new utils.ts
id property also added to identify Application (for the LabelMap)

@@ -0,0 +1,6 @@
/* Copyright Contributors to the Open Cluster Management project */

export type ApplicationStatus = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

old type moved here as it is needed by the new utils.ts and useFetchApplicationLabels hook

Comment on lines 128 to 130
const LabelCell = ({ labels }: { labels: string[] | Record<string, string> }) => (
<AcmLabels labels={labels} isCompact={true} />
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

new inner component for rendering label

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
// Cannot add properties directly to objects in typescript
return { ...tableItem, ...transformedObject }
return {
id: getApplicationId(tableItem, clusters),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

new id for table elements, it is needed for label filtering

return items.map((app) => generateTransformData(app))
}, [allApplications, deletedApps, generateTransformData, resultCounts])

const { labelOptions, labelMap } = useFetchApplicationLabels(tableItems)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the different labelOptions for the filter
the LabelMap representing application.id: labels

Comment on lines 13 to 29
if (applicationData && applicationData.length !== storedApplicationData?.length) {
const allLabels = new Set<string>()
const labelMap: LabelMap = {}
applicationData.filter(isOCPAppResource).forEach((resource) => {
const labels: string[] = []
const pairs: Record<string, string> = {}
resource.label?.split(';').forEach((label) => {
labels.push(label.trim())
const [key, value] = label.split('=').map((seg) => seg.trim())
pairs[key] = value
allLabels.add(label.trim())
})
labelMap[resource.id] = { pairs, labels }
})
setLabelMap(labelMap)
setLabelOptions(Array.from(allLabels).map((label) => ({ label, value: label })))
setStoredApplicationData(applicationData)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
@Ginxo Ginxo marked this pull request as ready for review February 18, 2026 09:31
@Ginxo
Copy link
Contributor Author

Ginxo commented Feb 18, 2026

/retest

@Ginxo
Copy link
Contributor Author

Ginxo commented Feb 18, 2026

/test unit-tests-sonarcloud

@Ginxo
Copy link
Contributor Author

Ginxo commented Feb 18, 2026

/retest

{
header: t('table.labels'),
cell: (resource) => (
<AcmLabels labels={getLabels(resource as OCPAppResource<ApplicationStatus>)} isCompact={true} />
Copy link
Contributor

Choose a reason for hiding this comment

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

@Ginxo I think this looks great! One issue I see is that only OCP apps are supported. There are also other app types that we need to support ie. ArgoCD, Application Set. For Subscription apps we can probably skip since that's deprecated. Thanks!

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would like to do so but according to the object contract just OCP applications contain label, check this for instance.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok that's a good point. In that case can you add a tooltip for the Labels column and just explain that only OCP and Flux apps have labels. It might be confusing to users why some apps have labels and other don't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've checked again the different objects coming from multicloud/aggregate/applications request and ApplicationSet is also containing labels at

{
            "apiVersion": "argoproj.io/v1alpha1",
            "kind": "ApplicationSet",
            "metadata": {
                "name": "kikes",
                "namespace": "openshift-gitops",
                 ...
            },
            "spec": {
                "template": {
                    "metadata": {
                        "name": "kikes-{{name}}",
                        "labels": {
                            "apps.open-cluster-management.io/pull-to-ocm-managed-cluster": "true",
                            "velero.io/exclude-from-backup": "true"
                        }
                        ...
                    },
                   ...

I'm not able to check ArgoCD kind of applications, could you please guide me on creating one @fxiang1 ? thanks for your help here 😊

Copy link
Contributor

@fxiang1 fxiang1 Feb 24, 2026

Choose a reason for hiding this comment

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

Yes, the ArgoCD apps are actually created from the ArgoCD console

image

You will need to click Log In with OpenShift, use the kubeadmin creds.

Click New App

image

Fill in all the fields

image

You can take a look at the example app I have in the console weekly cluster to see what values to use
https://openshift-gitops-server-openshift-gitops.apps.cs-aws-420-4mccv.dev02.red-chesterfield.com/applications/openshift-gitops/feng-standalone-argo?view=tree&resource=
image

Once the app is created it should get discovered in the ACM Applications page.

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
@Ginxo
Copy link
Contributor Author

Ginxo commented Feb 23, 2026

/retest

Signed-off-by: Enrique Mingorance Cano <emingora@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants