@@ -15,12 +15,14 @@ import {
15
15
GridRenderCellParams ,
16
16
GridTreeNodeWithRender ,
17
17
} from "@mui/x-data-grid" ;
18
+ import CopyLink from "components/common/CopyLink" ;
18
19
import LoadingPage from "components/common/LoadingPage" ;
19
20
import RegexButton from "components/common/RegexButton" ;
20
21
import { durationDisplay } from "components/common/TimeUtils" ;
21
22
import dayjs from "dayjs" ;
22
23
import isoWeek from "dayjs/plugin/isoWeek" ;
23
24
import ReactECharts from "echarts-for-react" ;
25
+ import { encodeParams } from "lib/GeneralUtils" ;
24
26
import _ from "lodash" ;
25
27
import { useRouter } from "next/router" ;
26
28
import { useEffect , useRef , useState } from "react" ;
@@ -857,6 +859,7 @@ export default function Page() {
857
859
const fileInputRef = useRef < HTMLInputElement > ( null ) ;
858
860
const jobInputRef = useRef < HTMLInputElement > ( null ) ;
859
861
const labelInputRef = useRef < HTMLInputElement > ( null ) ;
862
+ const [ baseUrl , setBaseUrl ] = useState < string > ( "" ) ;
860
863
861
864
// Keep input fields in sync when filters are set programmatically
862
865
useEffect ( ( ) => {
@@ -893,10 +896,24 @@ export default function Page() {
893
896
} , [ commitMetadata , headShaIndex ] ) ;
894
897
895
898
useEffect ( ( ) => {
896
- if ( router . query . label ) {
897
- setLabelFilter ( router . query . label as string ) ;
898
- }
899
- } , [ router . query . label ] ) ;
899
+ // Sync filters from the router query params in one effect to avoid
900
+ // repeating similar hooks. Only update when the specific query keys
901
+ // are present.
902
+ const q = router . query ;
903
+ if ( q . label ) setLabelFilter ( q . label as string ) ;
904
+ if ( q . job ) setJobFilter ( q . job as string ) ;
905
+ if ( q . file ) setFileFilter ( q . file as string ) ;
906
+
907
+ if ( q . labelRegex !== undefined ) setLabelRegex ( q . labelRegex === "true" ) ;
908
+ if ( q . fileRegex !== undefined ) setFileRegex ( q . fileRegex === "true" ) ;
909
+ if ( q . jobRegex !== undefined ) setJobRegex ( q . jobRegex === "true" ) ;
910
+
911
+ setBaseUrl (
912
+ `${ window . location . protocol } //${
913
+ window . location . host
914
+ } ${ router . asPath . replace ( / \? .+ / , "" ) } `
915
+ ) ;
916
+ } , [ router . query ] ) ;
900
917
901
918
if ( ! router . isReady ) {
902
919
return < LoadingPage /> ;
@@ -912,7 +929,21 @@ export default function Page() {
912
929
913
930
return (
914
931
< Stack spacing = { 4 } >
915
- < Typography variant = "h4" > Test Reports</ Typography >
932
+ < Stack direction = "row" spacing = { 2 } >
933
+ < Typography variant = "h4" > Test Reports</ Typography >
934
+ { /* Permalink */ }
935
+ < CopyLink
936
+ textToCopy = { `${ baseUrl } ?${ encodeParams ( {
937
+ file : fileFilter ,
938
+ job : jobFilter ,
939
+ label : labelFilter ,
940
+ fileRegex : fileRegex ? "true" : "false" ,
941
+ jobRegex : jobRegex ? "true" : "false" ,
942
+ labelRegex : labelRegex ? "true" : "false" ,
943
+ } ) } `}
944
+ />
945
+ </ Stack >
946
+
916
947
< Stack spacing = { 2 } >
917
948
< Typography variant = "body1" >
918
949
This provides insights into the test files executed over recent
0 commit comments