@@ -2,12 +2,12 @@ import * as React from 'react';
22import { useK8sWatchResource , Timestamp } from '@openshift-console/dynamic-plugin-sdk' ;
33import { useParams } from 'react-router-dom-v5-compat' ;
44import { ApplicationSetKind , ApplicationSetModel } from '../../models/ApplicationSetModel' ;
5- import {
6- Card ,
7- CardBody ,
5+ import {
6+ Card ,
7+ CardBody ,
88 CardTitle ,
99 CardHeader ,
10- Spinner ,
10+ Spinner ,
1111 Badge ,
1212 Label ,
1313 LabelGroup ,
@@ -16,12 +16,14 @@ import {
1616 Tab ,
1717 TabTitleText ,
1818 Button ,
19- ButtonVariant
2019} from '@patternfly/react-core' ;
2120import { PencilAltIcon } from '@patternfly/react-icons' ;
2221import * as _ from 'lodash' ;
2322import { useApplicationSetActionsProvider } from '../../hooks/useApplicationSetActionsProvider' ;
2423import ApplicationDetailsTitle from './ApplicationDetailsTitle' ;
24+ import { useLabelsModal , useAnnotationsModal } from '@openshift-console/dynamic-plugin-sdk' ;
25+
26+ import { ResourceLink } from '@openshift-console/dynamic-plugin-sdk' ;
2527
2628const ApplicationSetDetailsPage : React . FC = ( ) => {
2729 const { name, ns } = useParams < { name : string ; ns : string } > ( ) ;
@@ -38,6 +40,8 @@ const ApplicationSetDetailsPage: React.FC = () => {
3840 } ) ;
3941
4042 const [ actions ] = useApplicationSetActionsProvider ( appSet ) ;
43+ const launchLabelsModal = useLabelsModal ( appSet ) ;
44+ const launchAnnotationsModal = useAnnotationsModal ( appSet ) ;
4145
4246 if ( loadError ) return < div > Error loading ApplicationSet details.</ div > ;
4347 if ( ! loaded || ! appSet ) return < Spinner /> ;
@@ -50,6 +54,9 @@ const ApplicationSetDetailsPage: React.FC = () => {
5054 } ;
5155
5256 const labelItems = metadata . labels || { } ;
57+ const annotationItems = metadata . annotations || { } ;
58+ // Helper to count object keys
59+ const countAnnotations = Object . keys ( annotationItems ) . length ;
5360
5461 return (
5562 < div className = "pf-v6-c-page__main-section pf-m-no-padding pf-m-fill pf-v6-c-page__main-section--no-gap pf-v6-u-flex-shrink-1" >
@@ -98,45 +105,124 @@ const ApplicationSetDetailsPage: React.FC = () => {
98105 < dd className = "pf-v6-c-description-list__description" >
99106 < div className = "pf-v6-l-split pf-v6-u-w-100" >
100107 < div className = "pf-v6-l-split__item pf-m-fill" >
101- < Badge isRead color = "green" > NS </ Badge > { metadata . namespace }
108+ < ResourceLink kind = "Namespace" name = { metadata . namespace } />
102109 </ div >
103110 </ div >
104111 </ dd >
105112 </ div >
106113
107114 < div className = "pf-v6-c-description-list__group" >
108- < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_Labels" >
109- < div className = "pf-v6-l-split pf-v6-u-w-100" >
110- < div className = "pf-v6-l-split__item pf-m-fill" > Labels</ div >
111- </ div >
115+ < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_Labels" style = { { margin : 0 } } >
116+ < span > Labels</ span >
112117 </ dt >
113- < dd className = "pf-v6-c-description-list__description" >
114- < div className = "pf-v6-l-split pf-v6-u-w-100" >
115- < div className = "pf-v6-l-split__item pf-m-fill" >
118+ < dd className = "pf-v6-c-description-list__description" style = { { padding : 0 , marginTop : 0 } } >
119+ < div style = { { display : 'inline-block' } } >
120+ < div style = { { display : 'flex' , justifyContent : 'flex-end' , alignItems : 'center' , marginBottom : 4 , width : '100%' } } >
121+ < a
122+ style = { {
123+ fontSize : 13 ,
124+ color : '#73bcf7' ,
125+ textDecoration : 'underline' ,
126+ cursor : 'pointer' ,
127+ display : 'inline-flex' ,
128+ alignItems : 'center' ,
129+ } }
130+ tabIndex = { 0 }
131+ role = "button"
132+ onClick = { launchLabelsModal }
133+ onKeyPress = { e => { if ( e . key === 'Enter' || e . key === ' ' ) launchLabelsModal ( ) ; } }
134+ aria-label = "Edit labels"
135+ >
136+ Edit < PencilAltIcon style = { { marginLeft : 4 , fontSize : 13 , color : '#73bcf7' } } />
137+ </ a >
138+ </ div >
139+ < div
140+ style = { {
141+ display : 'flex' ,
142+ flexDirection : 'row' ,
143+ alignItems : 'center' ,
144+ border : '1px solid #8a8d90' ,
145+ borderRadius : 8 ,
146+ padding : '6px 10px' ,
147+ background : 'none' ,
148+ boxSizing : 'border-box' ,
149+ width : 'fit-content' ,
150+ maxWidth : '100%' ,
151+ gap : 8 ,
152+ } }
153+ >
116154 { _ . isEmpty ( labelItems ) ? (
117155 < span className = "text-muted" > No labels</ span >
118156 ) : (
119- < div style = { { display : 'flex' , alignItems : 'center' , gap : '8px' } } >
120- < LabelGroup >
121- { Object . entries ( labelItems ) . map ( ( [ key , value ] ) => (
122- < Label key = { key } color = "grey" >
123- { key } ={ value }
124- </ Label >
125- ) ) }
126- </ LabelGroup >
127- < Button variant = { ButtonVariant . link } icon = { < PencilAltIcon /> } >
128- Edit
129- </ Button >
130- </ div >
157+ < LabelGroup
158+ style = { {
159+ display : 'flex' ,
160+ flexDirection : 'row' ,
161+ gap : '8px' ,
162+ margin : 0 ,
163+ } }
164+ >
165+ { Object . entries ( labelItems ) . map ( ( [ key , value ] ) => (
166+ < Label key = { key } color = "grey" >
167+ { key } ={ value }
168+ </ Label >
169+ ) ) }
170+ </ LabelGroup >
131171 ) }
132172 </ div >
133173 </ div >
134174 </ dd >
135175 </ div >
136176
177+ { /* Annotations Section - matches Console style */ }
178+ < div className = "pf-v6-c-description-list__group" >
179+ < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_Annotations" style = { { margin : 0 } } >
180+ < span > Annotations</ span >
181+ </ dt >
182+ < dd className = "pf-v6-c-description-list__description" style = { { padding : 0 , marginTop : 0 } } >
183+ < div style = { { display : 'inline-block' } } >
184+ < div style = { { display : 'flex' , alignItems : 'center' , marginBottom : 4 , width : '100%' } } >
185+ < a
186+ style = { {
187+ fontSize : 15 ,
188+ color : '#73bcf7' ,
189+ textDecoration : 'underline' ,
190+ cursor : 'pointer' ,
191+ display : 'inline-flex' ,
192+ alignItems : 'center' ,
193+ } }
194+ tabIndex = { 0 }
195+ role = "button"
196+ onClick = { launchAnnotationsModal }
197+ onKeyPress = { e => { if ( e . key === 'Enter' || e . key === ' ' ) launchAnnotationsModal ( ) ; } }
198+ aria-label = "Edit annotations"
199+ >
200+ { countAnnotations } annotation{ countAnnotations !== 1 ? 's' : '' }
201+ < PencilAltIcon style = { { marginLeft : 6 , fontSize : 15 , color : '#73bcf7' } } />
202+ </ a >
203+ </ div >
204+ </ div >
205+ </ dd >
206+ </ div >
207+
137208 < div className = "pf-v6-c-description-list__group" >
138209 < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_Created" >
139210 < div className = "pf-v6-l-split pf-v6-u-w-100" >
211+ < Button
212+ variant = "link"
213+ icon = { < PencilAltIcon /> }
214+ onClick = { launchLabelsModal }
215+ style = { {
216+ padding : 0 ,
217+ position : 'absolute' ,
218+ top : - 24 ,
219+ right : 0 ,
220+ fontSize : 13 ,
221+ } }
222+ aria-label = "Edit labels"
223+ >
224+ Edit
225+ </ Button >
140226 < div className = "pf-v6-l-split__item pf-m-fill" > Created at</ div >
141227 </ div >
142228 </ dt >
@@ -179,6 +265,7 @@ const ApplicationSetDetailsPage: React.FC = () => {
179265 </ dd >
180266 </ div >
181267
268+ { /* Generators Section */ }
182269 < div className = "pf-v6-c-description-list__group" >
183270 < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_Generators" >
184271 < div className = "pf-v6-l-split pf-v6-u-w-100" >
@@ -188,12 +275,13 @@ const ApplicationSetDetailsPage: React.FC = () => {
188275 < dd className = "pf-v6-c-description-list__description" >
189276 < div className = "pf-v6-l-split pf-v6-u-w-100" >
190277 < div className = "pf-v6-l-split__item pf-m-fill" >
191- < Badge isRead color = "blue " > 1 generators</ Badge >
278+ < Badge isRead color = "grey " > 1 generators</ Badge >
192279 </ div >
193280 </ div >
194281 </ dd >
195282 </ div >
196283
284+ { /* App Project Section (blue badge, no extra Created at) */ }
197285 < div className = "pf-v6-c-description-list__group" >
198286 < dt className = "pf-v6-c-description-list__term" data-test-selector = "details-item-label_AppProject" >
199287 < div className = "pf-v6-l-split pf-v6-u-w-100" >
@@ -203,7 +291,7 @@ const ApplicationSetDetailsPage: React.FC = () => {
203291 < dd className = "pf-v6-c-description-list__description" >
204292 < div className = "pf-v6-l-split pf-v6-u-w-100" >
205293 < div className = "pf-v6-l-split__item pf-m-fill" >
206- < Badge isRead color = "blue" > AP</ Badge > default
294+ < Badge isRead color = "blue" style = { { backgroundColor : '#73bcf7' , color : '#003a70' } } > AP</ Badge > default
207295 </ div >
208296 </ div >
209297 </ dd >
@@ -229,38 +317,35 @@ const ApplicationSetDetailsPage: React.FC = () => {
229317
230318 { /* Conditions Section */ }
231319 { status . conditions && status . conditions . length > 0 && (
232- < div className = "co-m-pane__body" >
233- < h2 data-test-section-heading = "Conditions" className = "pf-v6-c-title pf-m-h2 co-section-heading" >
234- < span > Conditions</ span >
235- </ h2 >
236- < table role = "grid" className = "pf-v6-c-table" >
237- < thead >
238- < tr >
239- < th > Type</ th >
240- < th > Status</ th >
241- < th > Updated</ th >
242- < th > Reason</ th >
243- < th > Message</ th >
244- </ tr >
245- </ thead >
246- < tbody >
247- { status . conditions . map ( ( condition : any , index : number ) => (
248- < tr key = { index } >
249- < td > { condition . type } </ td >
250- < td >
251- < Badge isRead color = { condition . status === 'True' ? 'green' : 'grey' } >
252- { condition . status }
253- </ Badge >
254- </ td >
255- < td >
320+ < div className = "co-m-pane__body" style = { { marginTop : 32 } } >
321+ < div style = { { fontWeight : 700 , fontSize : 24 , marginBottom : 20 , marginTop : 8 } } > Conditions</ div >
322+ < div style = { { borderTop : '1px solid #393F44' , marginBottom : 0 } } />
323+ < div style = { { width : '100%' } } >
324+ < div style = { { display : 'flex' , fontWeight : 600 , fontSize : 16 , padding : '16px 0 8px 0' } } >
325+ < div style = { { flex : 2 , textAlign : 'left' , paddingLeft : 0 } } > Type</ div >
326+ < div style = { { flex : 1 , textAlign : 'left' } } > Status</ div >
327+ < div style = { { flex : 2 , textAlign : 'left' } } > Updated</ div >
328+ < div style = { { flex : 2 , textAlign : 'left' } } > Reason</ div >
329+ < div style = { { flex : 4 , textAlign : 'left' } } > Message</ div >
330+ </ div >
331+ < div style = { { borderTop : '1px solid #393F44' } } />
332+ { status . conditions . map ( ( condition : any , index : number ) => (
333+ < React . Fragment key = { index } >
334+ < div style = { { display : 'flex' , fontSize : 15 , padding : '16px 0' , alignItems : 'flex-start' } } >
335+ < div style = { { flex : 2 , textAlign : 'left' , paddingLeft : 0 } } > { condition . type } </ div >
336+ < div style = { { flex : 1 , textAlign : 'left' } } > { condition . status } </ div >
337+ < div style = { { flex : 2 , textAlign : 'left' , display : 'flex' , alignItems : 'center' } } >
256338 < Timestamp timestamp = { condition . lastTransitionTime } />
257- </ td >
258- < td > { condition . reason || '' } </ td >
259- < td > { condition . message || '' } </ td >
260- </ tr >
261- ) ) }
262- </ tbody >
263- </ table >
339+ </ div >
340+ < div style = { { flex : 2 , textAlign : 'left' } } > { condition . reason || '' } </ div >
341+ < div style = { { flex : 4 , textAlign : 'left' } } > { condition . message || '' } </ div >
342+ </ div >
343+ { index !== status . conditions . length - 1 && (
344+ < div style = { { borderTop : '1px solid #393F44' } } />
345+ ) }
346+ </ React . Fragment >
347+ ) ) }
348+ </ div >
264349 </ div >
265350 ) }
266351 </ CardBody >
0 commit comments