1- import React , { useState , useEffect , useCallback , useContext , useMemo } from 'react' ;
1+ import React , { useState , useEffect , useContext , useMemo , useCallback } from 'react' ;
22import PropTypes from 'prop-types' ;
33
44import {
@@ -18,7 +18,7 @@ import {
1818import { InfoCircleIcon , CodeIcon , SearchIcon , FileAltIcon } from '@patternfly/react-icons' ;
1919import { CodeEditor , Language } from '@patternfly/react-code-editor' ;
2020
21- import { Link , useNavigate , useLocation } from 'react-router-dom' ;
21+ import { Link } from 'react-router-dom' ;
2222import Linkify from 'react-linkify' ;
2323
2424import * as http from '../services/http' ;
@@ -30,89 +30,40 @@ import TabTitle from './tabs';
3030import TestHistoryTable from './test-history' ;
3131import ArtifactTab from './artifact-tab' ;
3232import { IbutsuContext } from '../services/context' ;
33+ import { useTabHook } from './tabHook' ;
3334
3435const ResultView = ( {
3536 comparisonResults,
36- defaultTab,
37+ defaultTab= 'summary' ,
3738 hideArtifact= false ,
3839 hideSummary= false ,
3940 hideTestObject= false ,
4041 hideTestHistory= false ,
41- testResult
42+ testResult,
43+ skipHash= false
4244} ) => {
4345 const context = useContext ( IbutsuContext ) ;
4446 const { darkTheme } = context ;
4547
4648 // State
4749 const [ artifacts , setArtifacts ] = useState ( [ ] ) ;
48- const [ testHistoryTable , setTestHistoryTable ] = useState ( null ) ;
4950
50- // Hooks
51- const navigate = useNavigate ( ) ;
52- const location = useLocation ( ) ;
51+ // https://v5-archive.patternfly.org/components/tabs#tabs-linked-to-nav-elements
5352
54- const getDefaultTab = ( ) => {
55- if ( defaultTab ) {
56- return defaultTab ;
57- }
58- else if ( ! hideSummary ) {
59- return 'summary' ;
60- }
61- else if ( ! ! artifactTabs . length > 0 ) {
62- return artifactTabs [ 0 ] . key ;
63- }
64- else {
65- return null ;
66- }
67- } ;
68-
69- const getTabIndex = useCallback ( ( defaultValue ) => ( ! ! location && location . hash !== '' ) ? location . hash . substring ( 1 ) : defaultValue , [ location ] ) ;
70-
71- const getTestHistoryTable = useCallback ( ( ) => {
53+ const testHistoryTable = useMemo ( ( ) => {
7254 if ( comparisonResults !== undefined ) {
73- setTestHistoryTable (
55+ return (
7456 < TestHistoryTable
7557 comparisonResults = { comparisonResults }
7658 testResult = { testResult }
7759 /> ) ;
7860 } else {
79- setTestHistoryTable (
61+ return (
8062 < TestHistoryTable testResult = { testResult } /> ) ;
8163 }
8264
83- } , [ setTestHistoryTable , comparisonResults , testResult ] ) ;
65+ } , [ comparisonResults , testResult ] ) ;
8466
85- const [ activeTab , setActiveTab ] = useState ( getTabIndex ( getDefaultTab ( ) ) ) ;
86-
87-
88- useEffect ( ( ) => {
89- if ( activeTab === 'test-history' ) {
90- getTestHistoryTable ( ) ;
91- }
92- } , [ activeTab , getTestHistoryTable ] ) ;
93-
94- const handlePopState = useCallback ( ( ) => {
95- // Handle browser navigation buttons click
96- const tabIndex = getTabIndex ( 'summary' ) ;
97- setActiveTab ( tabIndex ) ;
98- } , [ getTabIndex , setActiveTab ] ) ;
99-
100- useEffect ( ( ) => {
101- if ( activeTab === 'test-history' ) {
102- getTestHistoryTable ( ) ;
103- }
104- window . addEventListener ( 'popstate' , handlePopState ) ;
105- return ( ) => {
106- window . removeEventListener ( 'popstate' , handlePopState ) ;
107- } ;
108- } , [ activeTab , getTestHistoryTable , handlePopState ] ) ;
109-
110- const onTabSelect = ( _ , tabIndex ) => {
111- if ( location ) {
112- navigate ( `${ location . pathname } ${ location . search } #${ tabIndex } ` ) ;
113- }
114- setActiveTab ( tabIndex ) ;
115- } ;
11667
11768 const artifactTabs = useMemo ( ( ) => artifacts . map ( ( art ) => (
11869 < Tab
@@ -125,6 +76,18 @@ const ResultView = ({
12576 )
12677 ) , [ artifacts ] ) ;
12778
79+ const artifactKeys = useCallback ( ( ) => {
80+ if ( artifactTabs && artifactTabs ?. length !== 0 ) { return ( artifactTabs . map ( ( tab ) => tab . key ) ) ; }
81+ else { return ( [ ] ) ; }
82+ } , [ artifactTabs ] ) ;
83+
84+ // Tab state and navigation hooks/effects
85+ const { activeTab, onTabSelect} = useTabHook (
86+ [ 'summary' , 'testHistory' , 'testObject' , ...artifactKeys ( ) ] ,
87+ defaultTab ,
88+ skipHash
89+ ) ;
90+
12891 useEffect ( ( ) => {
12992 // Get artifacts when the test result changes
13093 if ( testResult ) {
@@ -137,9 +100,6 @@ const ResultView = ({
137100 }
138101 } , [ testResult ] ) ;
139102
140- if ( activeTab === null ) {
141- setActiveTab ( getDefaultTab ( ) ) ;
142- }
143103 let resultIcon = getIconForResult ( 'pending' ) ;
144104 let startTime = new Date ( ) ;
145105 let parameters = < div /> ;
@@ -148,7 +108,7 @@ const ResultView = ({
148108 resultIcon = getIconForResult ( testResult . result ) ;
149109 startTime = new Date ( testResult . start_time ) ;
150110 parameters = Object . keys ( testResult . params ) . map ( ( key ) => < div key = { key } > { key } = { testResult . params [ key ] } </ div > ) ;
151- runLink = < Link to = { `../runs/${ testResult . run_id } ` } relative = "Path" > { testResult . run_id } </ Link > ;
111+ runLink = < Link to = { `../runs/${ testResult . run_id } #summary ` } relative = "Path" > { testResult . run_id } </ Link > ;
152112 }
153113
154114 const testJson = useMemo ( ( ) => JSON . stringify ( testResult , null , '\t' ) , [ testResult ] ) ;
@@ -425,15 +385,15 @@ const ResultView = ({
425385 </ Card >
426386 </ Tab >
427387 }
428- { ! hideArtifact &&
429- artifactTabs }
430388 { ! hideTestHistory &&
431- < Tab key = "test-history " eventKey = "test-history " title = { < TabTitle icon = { < SearchIcon /> } text = "Test History" /> } >
389+ < Tab key = "testHistory " eventKey = "testHistory " title = { < TabTitle icon = { < SearchIcon /> } text = "Test History" /> } >
432390 { testHistoryTable }
433391 </ Tab >
434392 }
393+ { ! hideArtifact &&
394+ artifactTabs }
435395 { ! hideTestObject && testJson &&
436- < Tab key = "test-object " eventKey = "test-object " title = { < TabTitle icon = { < CodeIcon /> } text = "Test Object" /> } >
396+ < Tab key = "testObject " eventKey = "testObject " title = { < TabTitle icon = { < CodeIcon /> } text = "Test Object" /> } >
437397 < Card >
438398 < CardBody id = 'object-card-body' >
439399 < CodeEditor
@@ -461,6 +421,7 @@ ResultView.propTypes = {
461421 hideTestObject : PropTypes . bool ,
462422 hideTestHistory : PropTypes . bool ,
463423 testResult : PropTypes . object ,
424+ skipHash : PropTypes . bool ,
464425} ;
465426
466427export default ResultView ;
0 commit comments