11// Copyright 2018-2023 contributors to the Marquez project
22// SPDX-License-Identifier: Apache-2.0
33
4+ import * as Redux from 'redux'
45import { ArrowBackIosRounded } from '@mui/icons-material'
56import {
67 Box ,
78 Chip ,
9+ CircularProgress ,
810 IconButton ,
911 Table ,
1012 TableBody ,
1113 TableCell ,
1214 TableHead ,
1315 TableRow ,
1416} from '@mui/material'
17+ import { IState } from '../../store/reducers'
1518import { Run } from '../../types/api'
1619import { alpha , createTheme } from '@mui/material/styles'
20+ import { bindActionCreators } from 'redux'
21+ import { connect } from 'react-redux'
22+ import { fetchRuns } from '../../store/actionCreators'
1723import { formatUpdatedAt } from '../../helpers'
1824import { runStateColor } from '../../helpers/nodes'
1925import { stopWatchDuration } from '../../helpers/time'
2026import { useTheme } from '@emotion/react'
2127import MqCode from '../core/code/MqCode'
2228import MqCopy from '../core/copy/MqCopy'
2329import MqEmpty from '../core/empty/MqEmpty'
30+ import MqPaging from '../paging/MqPaging'
2431import MqStatus from '../core/status/MqStatus'
2532import MqText from '../core/text/MqText'
2633import React , { FunctionComponent , SetStateAction } from 'react'
2734import RunInfo from './RunInfo'
2835
36+ interface DispatchProps {
37+ fetchRuns : typeof fetchRuns
38+ }
39+
2940interface RunsProps {
3041 runs : Run [ ]
3142 facets ?: object
43+ totalCount : number
44+ runsLoading : boolean
45+ jobName : string
46+ jobNamespace : string
47+ }
48+
49+ interface RunsState {
50+ page : number
3251}
3352
34- const Runs : FunctionComponent < RunsProps > = ( props ) => {
35- const { runs, facets } = props
53+ const PAGE_SIZE = 10
54+
55+ const Runs : FunctionComponent < RunsProps & DispatchProps > = ( props ) => {
56+ const { runs, facets, totalCount, runsLoading, fetchRuns, jobName, jobNamespace } = props
3657 const i18next = require ( 'i18next' )
37- if ( runs . length === 0 ) {
38- return < MqEmpty title = { i18next . t ( 'jobs.empty_title' ) } body = { i18next . t ( 'jobs.empty_body' ) } />
39- }
58+
59+ const [ state , setState ] = React . useState < RunsState > ( {
60+ page : 0 ,
61+ } )
4062
4163 const [ infoView , setInfoView ] = React . useState < Run | null > ( null )
4264 const handleClick = ( newValue : SetStateAction < Run | null > ) => {
4365 setInfoView ( newValue )
4466 }
4567
68+ const handleClickPage = ( direction : 'prev' | 'next' ) => {
69+ const directionPage = direction === 'next' ? state . page + 1 : state . page - 1
70+ window . scrollTo ( 0 , 0 )
71+ setState ( { ...state , page : directionPage } )
72+ }
73+
74+ React . useEffect ( ( ) => {
75+ fetchRuns ( jobName , jobNamespace , PAGE_SIZE , state . page * PAGE_SIZE )
76+ } , [ state . page ] )
77+
4678 const theme = createTheme ( useTheme ( ) )
4779
80+ if ( runs . length === 0 ) {
81+ return < MqEmpty title = { i18next . t ( 'jobs.empty_title' ) } body = { i18next . t ( 'jobs.empty_body' ) } />
82+ }
83+
84+ if ( runsLoading ) {
85+ return (
86+ < Box display = { 'flex' } justifyContent = { 'center' } mt = { 2 } >
87+ < CircularProgress color = 'primary' />
88+ </ Box >
89+ )
90+ }
91+
4892 if ( infoView ) {
4993 return (
5094 < >
@@ -148,12 +192,23 @@ const Runs: FunctionComponent<RunsProps> = (props) => {
148192 < TableCell align = 'left' > { formatUpdatedAt ( run . createdAt ) } </ TableCell >
149193 < TableCell align = 'left' > { formatUpdatedAt ( run . startedAt ) } </ TableCell >
150194 < TableCell align = 'left' > N/A</ TableCell >
151- < TableCell align = 'left' > { stopWatchDuration ( run . durationMs ) } </ TableCell >
195+ < TableCell align = 'left' >
196+ { run . state === 'RUNNING' || run . state === 'NEW'
197+ ? 'N/A'
198+ : stopWatchDuration ( run . durationMs ) } { ' ' }
199+ </ TableCell >
152200 </ TableRow >
153201 )
154202 } ) }
155203 </ TableBody >
156204 </ Table >
205+ < MqPaging
206+ pageSize = { PAGE_SIZE }
207+ currentPage = { state . page }
208+ totalCount = { totalCount }
209+ incrementPage = { ( ) => handleClickPage ( 'next' ) }
210+ decrementPage = { ( ) => handleClickPage ( 'prev' ) }
211+ />
157212 { facets && (
158213 < Box mt = { 2 } >
159214 < Box mb = { 1 } >
@@ -166,4 +221,18 @@ const Runs: FunctionComponent<RunsProps> = (props) => {
166221 )
167222}
168223
169- export default Runs
224+ const mapStateToProps = ( state : IState ) => ( {
225+ runs : state . runs . result ,
226+ totalCount : state . runs . totalCount ,
227+ runsLoading : state . runs . isLoading ,
228+ } )
229+
230+ const mapDispatchToProps = ( dispatch : Redux . Dispatch ) =>
231+ bindActionCreators (
232+ {
233+ fetchRuns : fetchRuns ,
234+ } ,
235+ dispatch
236+ )
237+
238+ export default connect ( mapStateToProps , mapDispatchToProps ) ( Runs )
0 commit comments