11import * as React from 'react' ;
22import { useTranslation } from 'react-i18next' ;
33import { useLocation } from 'react-router-dom-v5-compat' ;
4+ import classNames from 'classnames' ;
45import DevPreviewBadge from 'src/components/import/badges/DevPreviewBadge' ;
56
67import ActionsDropdown from '@gitops/utils/components/ActionDropDown/ActionDropDown' ;
7- import { modelToGroupVersionKind , modelToRef } from '@gitops/utils/utils' ;
8+ import {
9+ getSelectorSearchURL ,
10+ kindForReference ,
11+ modelToGroupVersionKind ,
12+ modelToRef ,
13+ } from '@gitops/utils/utils' ;
814import {
915 Action ,
1016 K8sResourceCommon ,
17+ K8sResourceKindReference ,
1118 ListPageBody ,
1219 ListPageCreate ,
1320 ListPageFilter ,
@@ -19,7 +26,8 @@ import {
1926} from '@openshift-console/dynamic-plugin-sdk' ;
2027import { ResourceLink } from '@openshift-console/dynamic-plugin-sdk' ;
2128import { ErrorState } from '@patternfly/react-component-groups' ;
22- import { EmptyState , EmptyStateBody } from '@patternfly/react-core' ;
29+ import { EmptyState , EmptyStateBody , LabelGroup } from '@patternfly/react-core' ;
30+ import { Label as PfLabel } from '@patternfly/react-core' ;
2331import { DataViewTh , DataViewTr } from '@patternfly/react-data-view/dist/esm/DataViewTable' ;
2432import { CubesIcon } from '@patternfly/react-icons' ;
2533import { ThProps } from '@patternfly/react-table' ;
@@ -75,6 +83,7 @@ const ProjectList: React.FC<ProjectListTabProps> = ({
7583 ...( showNamespace ? [ 'namespace' ] : [ ] ) ,
7684 'description' ,
7785 'applications' ,
86+ 'labels' ,
7887 'last-updated' ,
7988 'actions' ,
8089 ] . map ( ( key ) => ( { key } ) ) ;
@@ -182,7 +191,7 @@ const ProjectList: React.FC<ProjectListTabProps> = ({
182191 < div >
183192 { showTitle == undefined && (
184193 < ListPageHeader
185- title = { t ( 'App Projects ' ) }
194+ title = { t ( 'AppProjects ' ) }
186195 badge = {
187196 location ?. pathname ?. includes ( 'openshift-gitops-operator' ) ? null : < DevPreviewBadge />
188197 }
@@ -275,6 +284,10 @@ export const sortData = (
275284 aValue = getApplicationsCount ( a , applications , appsLoaded ) ;
276285 bValue = getApplicationsCount ( b , applications , appsLoaded ) ;
277286 break ;
287+ case 'labels' :
288+ aValue = a . metadata ?. labels || { } ;
289+ bValue = b . metadata ?. labels || { } ;
290+ break ;
278291 case 'last-updated' :
279292 aValue = getLastUpdateTimestamp ( a ) ;
280293 bValue = getLastUpdateTimestamp ( b ) ;
@@ -337,6 +350,13 @@ export const useColumnsDV = (
337350 sort : getSortParams ( 2 + i ) ,
338351 } ,
339352 } ,
353+ {
354+ cell : t ( 'Labels' ) ,
355+ props : {
356+ 'aria-label' : 'labels' ,
357+ className : 'pf-m-width-15' ,
358+ } ,
359+ } ,
340360 {
341361 cell : t ( 'Last Updated' ) ,
342362 props : {
@@ -354,6 +374,53 @@ export const useColumnsDV = (
354374 return columns ;
355375} ;
356376
377+ type MetadataLabelsProps = {
378+ kind : K8sResourceKindReference ;
379+ labels ?: { [ key : string ] : string } ;
380+ } ;
381+
382+ const MetadataLabels : React . FC < MetadataLabelsProps > = ( { kind, labels } ) => {
383+ const { t } = useTranslation ( 'plugin__gitops-plugin' ) ;
384+ return labels && Object . keys ( labels ) . length > 0 ? (
385+ < LabelGroup numLabels = { 10 } className = "co-label-group metadata-labels-group" >
386+ { Object . keys ( labels || { } ) ?. map ( ( key ) => {
387+ return (
388+ < LabelL key = { key } kind = { kind } name = { key } value = { labels [ key ] } expand = { true } >
389+ { labels [ key ] ? `${ key } =${ labels [ key ] } ` : key }
390+ </ LabelL >
391+ ) ;
392+ } ) }
393+ </ LabelGroup >
394+ ) : (
395+ < span className = "metadata-labels-no-labels" > { t ( 'No labels' ) } </ span >
396+ ) ;
397+ } ;
398+
399+ type LabelProps = {
400+ kind : K8sResourceKindReference ;
401+ name : string ;
402+ value : string ;
403+ expand : boolean ;
404+ } ;
405+
406+ const LabelL : React . FC < LabelProps > = ( { kind, name, value, expand } ) => {
407+ const selector = value ? `${ name } =${ value } ` : name ;
408+ const href = getSelectorSearchURL ( '' , kind , selector ) ;
409+ const kindOf = `co-m-${ kindForReference ( kind . toLowerCase ( ) ) } ` ;
410+ const klass = classNames ( kindOf , { 'co-m-expand' : expand } , 'co-label' ) ;
411+ return (
412+ < >
413+ < PfLabel className = { klass } color = { 'blue' } href = { href } >
414+ < span className = "co-label__key" data-test = "label-key" >
415+ { name }
416+ </ span >
417+ { value && < span className = "co-label__eq" > =</ span > }
418+ { value && < span className = "co-label__value" > { value } </ span > }
419+ </ PfLabel >
420+ </ >
421+ ) ;
422+ } ;
423+
357424export const useProjectsRowsDV = (
358425 projectsList : AppProjectKind [ ] ,
359426 namespace : string | undefined ,
@@ -400,6 +467,23 @@ export const useProjectsRowsDV = (
400467 id : 'applications' ,
401468 cell : appsLoaded ? appsCount . toString ( ) : '-' ,
402469 } ,
470+ {
471+ id : 'labels' ,
472+ cell : (
473+ < div className = "pf-m-width-40" >
474+ < MetadataLabels
475+ kind = {
476+ AppProjectModel . apiGroup +
477+ '~' +
478+ AppProjectModel . apiVersion +
479+ '~' +
480+ AppProjectModel . kind
481+ }
482+ labels = { obj ?. metadata ?. labels }
483+ />
484+ </ div >
485+ ) ,
486+ } ,
403487 {
404488 id : 'last-updated' ,
405489 cell : ( ( ) => {
0 commit comments