@@ -20,6 +20,8 @@ import AnsiUp from 'ansi_up'
20
20
import DOMPurify from 'dompurify'
21
21
import { ANSI_UP_REGEX , ComponentSizeType } from '@Shared/constants'
22
22
import { escapeRegExp } from '@Shared/Helpers'
23
+ import { ReactComponent as ICExpandAll } from '@Icons/ic-expand-all.svg'
24
+ import { ReactComponent as ICCollapseAll } from '@Icons/ic-collapse-all.svg'
23
25
import {
24
26
Progressing ,
25
27
Host ,
@@ -182,10 +184,16 @@ export const LogsRenderer = ({
182
184
triggerDetails . podStatus && triggerDetails . podStatus !== POD_STATUS . PENDING && logsURL ,
183
185
)
184
186
const [ stageList , setStageList ] = useState < StageDetailType [ ] > ( [ ] )
187
+ const [ openAllStages , setOpenAllStages ] = useState ( false )
185
188
// State for logs list in case no stages are available
186
189
const [ logsList , setLogsList ] = useState < string [ ] > ( [ ] )
187
190
const { searchKey, handleSearch } = useUrlFilters ( )
188
191
192
+ const handleSetStageList = ( list : StageDetailType [ ] ) => {
193
+ setOpenAllStages ( list . every ( ( item ) => item . isOpen ) )
194
+ setStageList ( list )
195
+ }
196
+
189
197
const areStagesAvailable =
190
198
( window . _env_ . FEATURE_STEP_WISE_LOGS_ENABLE && streamDataList [ 0 ] ?. startsWith ( LOGS_STAGE_IDENTIFIER ) ) || false
191
199
@@ -374,27 +382,36 @@ export const LogsRenderer = ({
374
382
}
375
383
376
384
const newStageList = getStageListFromStreamData ( )
377
- setStageList ( newStageList )
385
+ handleSetStageList ( newStageList )
378
386
// NOTE: Not adding searchKey as dependency since on mount we would already have searchKey
379
387
// And for other cases we would use handleSearchEnter
380
388
} , [ streamDataList , areEventsProgressing ] )
381
389
382
390
const handleSearchEnter = ( searchText : string ) => {
383
391
handleSearch ( searchText )
384
392
const newStageList = getStageListFromStreamData ( searchText )
385
- setStageList ( newStageList )
393
+ handleSetStageList ( newStageList )
386
394
}
387
395
388
396
const handleStageClose = ( index : number ) => {
389
397
const newLogs = structuredClone ( stageList )
390
398
newLogs [ index ] . isOpen = false
391
- setStageList ( newLogs )
399
+ handleSetStageList ( newLogs )
392
400
}
393
401
394
402
const handleStageOpen = ( index : number ) => {
395
403
const newLogs = structuredClone ( stageList )
396
404
newLogs [ index ] . isOpen = true
397
- setStageList ( newLogs )
405
+ handleSetStageList ( newLogs )
406
+ }
407
+
408
+ const handleToggleOpenAllStages = ( ) => {
409
+ handleSetStageList (
410
+ stageList . map ( ( stage ) => ( {
411
+ ...stage ,
412
+ isOpen : ! openAllStages ,
413
+ } ) ) ,
414
+ )
398
415
}
399
416
400
417
const renderLogs = ( ) => {
@@ -428,6 +445,18 @@ export const LogsRenderer = ({
428
445
initialSearchText = { searchKey }
429
446
size = { ComponentSizeType . large }
430
447
/>
448
+ < button
449
+ type = "button"
450
+ className = "dc__unset-button-styles px-10 flex dc__bg-n0--opacity-0_2"
451
+ onClick = { handleToggleOpenAllStages }
452
+ aria-label = "Expand all stages"
453
+ >
454
+ { openAllStages ? (
455
+ < ICExpandAll className = "icon-dim-16 dc__no-shrink dc__transition--transform scn-0" />
456
+ ) : (
457
+ < ICCollapseAll className = "icon-dim-16 dc__no-shrink dc__transition--transform scn-0" />
458
+ ) }
459
+ </ button >
431
460
</ div >
432
461
</ div >
433
462
0 commit comments